├── .gitignore
├── .vscode
└── tasks.json
├── MCG
├── HyperClone
│ ├── HyperClone_v2.0.495.mcg
│ ├── Hyperclone_rollout.jpg
│ ├── hyperClone.jpg
│ └── old_version
│ │ └── HyperClone.mcg
└── SphereClone
│ ├── SphereClone.jpg
│ ├── SphereClone.mcg
│ └── SphereClone_rolout.png
├── Max UI
└── BUMP_maxcolors.clrx
├── README.md
├── Snippets
├── Send_Mail.ms
└── Snippets.ms
├── assets
├── Hyperclone_rollout.jpg
├── SphereClone.jpg
├── SphereClone_rolout.png
├── advman.png
├── camtool.PNG
├── hyperClone.jpg
├── panel_cuts_intro.png
├── panel_cuts_logo.png
├── panel_cuts_ui.png
└── random_detach.jpg
├── encryptFile.ms
├── libs
├── easing.ms
├── goldenProportions.ms
└── menu_manager_api
│ ├── menu_man_example.ms
│ └── menu_manager.ms
├── release
├── Adv_path_manager.zip
├── Panel_cuts.zip
├── Photographic_composition_guides.zip
├── Random_detach.zip
├── Viewport_composition_guides.zip
├── align_assets.zip
├── arch_scaler.zip
├── audit_materials.zip
├── cam_manager.zip
├── gamma_adjustment.zip
├── mat_tools.zip
├── plugin
│ └── BUMP_resizer.zip
├── random_select.zip
├── sunblind_cage_calc.zip
├── usericons
│ ├── extratools_16a.bmp
│ ├── extratools_16i.bmp
│ ├── extratools_24a.bmp
│ └── extratools_24i.bmp
├── vertex_scrambler.zip
├── vraymat_populate.zip
└── xref_replace.zip
└── src
├── Adv_path_manager
├── BUMP_AdvPathMngr.mcr
└── BUMP_AdvPathMngr.ms
├── BUMP_ArchScaler.mcr
├── BUMP_Mat_Tools.mcr
├── BUMP_Random_select.mcr
├── BUMP_align_assets.mcr
├── BUMP_audit-materials.ms
├── BUMP_camManager.mcr
├── BUMP_gamma_adjustment.ms
├── BUMP_sunblind_cage_calc.ms
├── BUMP_vertexScrambler.mcr
├── BUMP_viewPortCompositionGuides-v1.mcr
├── BUMP_xref_replace.mcr
├── Panel_cuts
├── example
│ ├── cuts_CUTS REPORT.csv
│ └── panel_cuts_test.max
└── src
│ ├── psd
│ ├── panel_cuts.psd
│ ├── panel_cuts_intro.psd
│ └── panel_cuts_ui.psd
│ ├── scripts
│ └── BUMP_panelCuts.ms
│ ├── usericons
│ ├── panel_cuts_16a.bmp
│ ├── panel_cuts_16i.bmp
│ ├── panel_cuts_24a.bmp
│ └── panel_cuts_24i.bmp
│ └── usermacros
│ └── BUMP_pcuts.mcr
├── Photographic_composition_guides
├── Icons
│ ├── vcomp_24.png
│ ├── vcomp_32.png
│ ├── vcomp_36.png
│ └── vcomp_48.png
├── MacroScripts
│ ├── BUMP_CompositionGuides.mcr
│ └── BUMP_CompositionGuides_DEBUG.mcr
└── Scripts
│ └── vpCompositionGuides.mse
├── Random_detach
├── BUMP_Random_detach.mcr
├── BUMP_Random_detach.ms
└── min
│ └── min_BUMP_Random_detach.ms
├── VrayMtlPopulate
├── BUMP_VrayMtlPopulate.mcr
└── BUMP_VrayMtlPopulate.ms
└── plugin
└── BUMP_resizer.ms
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | #ignore thumbnails created by windows
3 | Thumbs.db
4 | #Ignore files build by vscode and binaries
5 | *.exe
6 | **/min
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | // See https://go.microsoft.com/fwlink/?LinkId=733558
3 | // for the documentation about the tasks.json format
4 | "version": "2.0.0",
5 | "tasks": [
6 | {
7 | "label": "Encrypt file",
8 | "type": "shell",
9 | "command": "3dsmaxbatch.exe",
10 | "args": [
11 | "'${workspaceFolder}\\encryptFile.ms'",
12 | "-mxsString",
13 | "in:'@\"${file}\"'"
14 | ],
15 | "problemMatcher": []
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/MCG/HyperClone/HyperClone_v2.0.495.mcg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/MCG/HyperClone/HyperClone_v2.0.495.mcg
--------------------------------------------------------------------------------
/MCG/HyperClone/Hyperclone_rollout.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/MCG/HyperClone/Hyperclone_rollout.jpg
--------------------------------------------------------------------------------
/MCG/HyperClone/hyperClone.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/MCG/HyperClone/hyperClone.jpg
--------------------------------------------------------------------------------
/MCG/HyperClone/old_version/HyperClone.mcg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/MCG/HyperClone/old_version/HyperClone.mcg
--------------------------------------------------------------------------------
/MCG/SphereClone/SphereClone.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/MCG/SphereClone/SphereClone.jpg
--------------------------------------------------------------------------------
/MCG/SphereClone/SphereClone.mcg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/MCG/SphereClone/SphereClone.mcg
--------------------------------------------------------------------------------
/MCG/SphereClone/SphereClone_rolout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/MCG/SphereClone/SphereClone_rolout.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Free 3ds Max Tools
2 |
3 | ## MaxScript tools
4 |
5 | | File | Name | Description |
6 | | ---- | ---- | ----------- |
7 | | ../Max UI | | 3Ds Max custom dark UI scheme. |
8 | | ./usericons | UI Icons for some of the scripts | Change node XYZ dimensions. |
9 | | adv_path_manager | Advanced Paths Manager | Utility for managing user paths (beta) |
10 | | align_assets | Align assets | Rearrange nodes in a row. |
11 | | arch_scaler | Architecture Scale | Small utility to rescale nodes using an architectural scale factor. |
12 | | Audit_materials | Audit Materials | Filter objects by material |
13 | | cam_manager | Camera tools | Compact interface to manage, review, select cameras. It also can add batch render views, change resolution and aspect ratio per camera. Comes with presets for common aspect ratios. |
14 | | gamma_adjustment | | Convert Normal Maps gamma |
15 | | mat_tools | bumpTo100 | (V-ray) material Bump value to 100.0 |
16 | | mat_tools | FaceSel | Select faces with same material ID |
17 | | mat_tools | FnameToBMap | Change the names of Bitmap Textures to the name of the loaded files. |
18 | | mat_tools | MapLoader | Load multiple bitmapTextures to the slate material editor |
19 | | mat_tools | ObjIDbyCAM | Set objects ID for current camera view |
20 | | mat_tools | QIDSet | Set material IDs for selected faces |
21 | | mat_tools | Remove_mats | Remove material from selection |
22 | | mat_tools | RndIDSet | Set random material IDs for selected faces |
23 | | mat_tools | SelNoMat | Filter nodes without material in current selection. |
24 | | panel_cuts | Panel cuts | Tool for creating panel cuts reports. Useful for furniture or cabinets design. |
25 | | photographic_composition_guides | | Display photographic composition guides overlay in viewport. |
26 | | random_detach | Random Detach | Random detach **editable poly** elements. |
27 | | random_select | Random Select | Random nodes selection. |
28 | | plugin/BUMP_resizer | Resize modifier | Change node XYZ dimensions. |
29 | | vertex_scrambler | Vertex scrambler | Random shift vertex positions in a mesh. |
30 | | vraymat_populate | | Populate material editor slots with VRayMtl |
31 | | xref_replace | Replace with Xref | Replace selected node with Xref Record. |
32 |
33 | ## MCG solutions
34 |
35 | * **HyperClone**: Advanced cloning tool.
36 | * **SphereClone**: Instance objects on a spherical space or in a convex closed mesh.
37 |
38 | ---
39 |
40 | ## Install notes
41 |
42 | 1. Locate **3ds Max user folder**. Usually at: *C:\Users\USER_NAME\AppData\Local\Autodesk\3dsMax\20XX - 64bit\ENU*
43 | 2. Copy **.ms** and **.mse** to *scripts*, *.mcr* files to *usermacros* and Icons (.bmp) to *usericons*
44 | 3. Restart Max if opened
45 | 4. Add the macro to a toolbar. Found under the category "BUMP tools"
46 |
47 | ---
48 |
49 | ## Advanced path manager
50 |
51 | 
52 |
53 | Listview for managing External files User Paths. Listview for managing External files User Paths.
54 | It has several advantages over the the default Max´s dialog, some are:
55 | More useful UI with colors and font effects to indicate directories status, display only invalid paths, remove empty folders paths and more...
56 |
57 | ### Reference
58 |
59 | * Paths to be deleted : Marked by strikeout text.
60 | * Paths to be added : Showed on bold text.
61 | * Paths modified: Text marked with underline.
62 | * Changes are only applied when pressing "Done".
63 |
64 | ---
65 |
66 | ## Panel Cuts
67 |
68 | 
69 |
70 | Tool for creating panel cuts reports. Useful for furniture or kitchen cabinets design.
71 |
72 | ### features
73 |
74 | * Material finish, part type, description, grain orientation properties.
75 | * Sheet use report.
76 | * Export a .csv file with Part quantity, dimensions, finish, grain direction, part and description values; Import the file in a spreadsheet or cut optimization software.
77 |
78 | ### How to use
79 |
80 | 
81 |
82 | >*In order to effectively use the tool, you will need a clean, real scale model, composed of individual objects for each piece of the model.*
83 |
84 | 1. Select the parts (individual objects making a kitchen cabinet, for example) of the model that you want to add the properties that will be used to generate the report. Press the "SELECTION" button to make all the selected objects active in the tool. Alternatively, activate the "Viewport select" toggle button if you want to pick each object alone in the Viewport.
85 |
86 | 2. Start adding properties. Grain direction will swap the piece height and width, in order to accommodate the cuts to the sheet face texture direction. "Finish" indicates the material color, skin, etc. "Part" can be used as indicative of the piece position/function (i.e. Kitchen Module 1 - Lateral stand). Once you are done, press the "commit" Button. Note: Right-click on "Commit" will apply the properties to the entire objects collection. Values entered in the textbox will be added to the below listbox. Double click on an item in the listbox to reutilize it.
87 |
88 | 3. Navigate through the objects in the collection with the previous ("<<") and next (">>") buttons.
89 | * The tool has a visual feedback, displaying as wireframe the objects in the collection and shading the current active one, also a viewport label shows the selected object dimensions.
90 | * Right click on prev. or next buttons to commit properties.
91 |
92 | 4. Utilities.
93 | * Scale units: objects are measured in current Max's active units system and scale. Use the units factor to convert stored dimensions between units. I.e: If the system scale is configured in centimeters, use a factor of 10.0 and scale up to change the measurements to millimeters.
94 | * Sheet dimensions: Generate a report of how much sheets (or sheet area) the pieces will require. Account for wastage.
95 |
96 | 5. Save to file. This is the main functionality of this tool. Export a list of the parts to a .csv file. It can be later imported in a Spreadsheet or cut optimization program.
97 |
98 | ---
99 |
100 | ## Random Detach
101 |
102 | 
103 |
104 | ---
105 |
106 | ## Random Select
107 |
108 | Random node selection. By percent of the selected nodes or "Dot-Gap" pattern.
109 |
110 | ### Modes
111 |
112 | * Percent: Keep a random percentage of the total quantity of nodes in the current selection.
113 | * Step: Performs a skip pattern in the selection.
114 | * Subtract: Same as percent, but inverse: deselect a random percentage within selection.
115 | * Pattern: Not a random mode; Instead it wil unselect nodes following a pattern.
116 |
117 | ### Values
118 |
119 | * Percent: Percentage of nodes quantity to be selected
120 | * Step: Quantity of objects to skip in the selection
121 | * Subtract percent: Percentage of nodes quantity to be un-selected
122 |
123 | >Note: The tool will respect the selection pick order.
124 |
125 | ### Pattern
126 |
127 | * Keep: How much objects the pattern will keep
128 | * Quit: Quantity of objects that will be deselected.
129 |
130 | >Example:
131 | >Keep: 3; Quit: 2
132 |
133 | ---
134 |
--------------------------------------------------------------------------------
/Snippets/Send_Mail.ms:
--------------------------------------------------------------------------------
1 | (
2 | -- WEBMAIL PROTOCOL
3 | struct _comSrv
4 | (
5 | public
6 | fn composeMail body sub FromAdress ToAdress AttachFile:undefined =
7 | (
8 | local MailMessage = dotNetObject "System.Net.Mail.MailMessage"
9 | local MailMessageFrom = dotNetObject "System.Net.Mail.MailAddress" FromAdress
10 | MailMessage.From = (dotNetObject "System.Net.Mail.MailAddress" MAIL_TO)
11 | local MailAdressTo = (dotNet.ValueToDotNetObject ToAdress (dotNetClass "System.String"))
12 | MailMessage.To.Add MailAdressTo
13 | MailMessage.CC.Add FromAdress
14 | MailMessage.Subject = if sub != undefined then sub else "no subject"
15 | MailMessage.Body = if body != undefined then body else " "
16 | if AttachFile != undefined then (
17 | local MailAttachment = dotNetObject "System.Net.Mail.Attachment" AttachFile
18 | MailMessage.Attachments.Add(MailAttachment)
19 | )
20 | return MailMessage
21 | ),
22 | fn MailSender MailMessage Username Password Host port ssl:true =
23 | (
24 | Client = dotNetObject "System.Net.Mail.SmtpClient" --Host Port
25 | NetworkCred = dotNetObject "System.Net.NetworkCredential"
26 | NetworkCred.UserName = Username
27 | NetworkCred.Password = Password
28 | Client.Credentials = NetworkCred
29 | Client.Host = Host
30 | Client.Port = port --25 --587;
31 | Client.EnableSsl = ssl
32 | Client.Send MailMessage
33 | )
34 | )
35 | -- EXAMPLE FORM
36 | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
37 | rollout roll_email "Send Email" width:450
38 | (
39 | fn fullWidth div:1 th:10 =
40 | (
41 | if div > 1 then (
42 | ( (roll_email.width - th) / div ) - (th / div)
43 | ) else (
44 | ( (roll_email.width - th) / div )
45 | )
46 | )
47 | editText txt_dest "Adress" text:"" labelOnTop:true fieldWidth:(fullWidth()-15) align:#left
48 | editText txt_cpt "Caption" text:"Send Email" labelOnTop:true fieldWidth:(fullWidth()-15) align:#left
49 | editText txt_c1 "Email text" text:("Example email body.\n" + localTime) labelOnTop:true fieldWidth:(fullWidth()-15) height:150 align:#left
50 | imgTag sep1 width:(fullWidth()) height:1 bitmap:(bitmap 1 2 color: (color 5 5 5)) align:#center
51 | label lbl_c1 "Email" align:#left across:2
52 | label lbl_c2 "Password" align:#left
53 | editText txt_c3 "" text:"mail@gmail.com" labelOnTop:true align:#left fieldWidth:200 height:20 across:2
54 | dotNetControl txt_c4 "TextBox" text:"PASSWORD" width:200
55 | imgTag sep2 width:(fullWidth()) height:1 bitmap:(bitmap 1 2 color: (color 5 5 5)) align:#center
56 | editText txt_c5 "SMTP Server" labelOnTop:true align:#left fieldWidth:220 offset:[0,5] across:3
57 | editText txt_c6 "Port" text:"587" labelOnTop:true align:#left width:35 offset:[80,5]
58 | CheckBox chk_c1 "USE SSL CONECTION" checked:true offset:[-30,24] align:#right
59 | imgTag sep3 width:(fullWidth()) height:1 bitmap:(bitmap 1 2 color: (color 5 5 5)) align:#center
60 | dotNetControl txt_c7 "label" width:220 height:16 offset:[0,5] across:2
61 | button btn_c1 "SEND" width:120 height:30 align:#right offset:[10,0] enabled:false
62 | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
63 | local SMTP = #("smtp.gmail", "smtp-mail.outlook", "smtp.live", "smtp.mail.yahoo", "smtp.btconnect", "mail.o2online", "outgoing.verizon", "smtp.zoho", "smtp.mail", "smtp.aol", "smtp.gmx")
64 | local fSMTP = for i in SMTP collect (filterString i ".")
65 | local SMTP = "smtp.gmail.com"
66 | local PORT = #("587","25")
67 | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
68 | local compose = StringStream ""
69 | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
70 |
71 | -- Automated HTML email template example.
72 | fn load_data var1 var2 var3 var5 var5 =
73 | (
74 | format "
75 |
Hi;
EXAMPLE TEXT!
76 |
77 |
MORE EXAMPLE TEXT
78 |
VAR1: %
79 |
CONTENT TEXT:
80 | VAR2: %
81 | VAR3: %
82 | VAR4: %
83 | VAR5: %
84 |
85 |
86 |
Regards;
87 |
" VAR1 VAR2 VAR3 VAR4 VAR5 to:compose
88 | txt_c1.text = compose as string
89 | btn_c1.enabled = true
90 | )
91 | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
92 | on roll_email open do (
93 | -- Password of the email account
94 | txt_c4.PasswordChar = "x"; txt_c4.MaxLength = 16
95 | txt_c5.TEXT = SMTP
96 | )
97 | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
98 | -- SSL connection option
99 | on chk_c1 changed state do (if state then txt_c6.text = PORT[1] else txt_c6.text = PORT[2])
100 |
101 | -- email of the sender
102 | on txt_c3 changed args do (
103 | if (MatchPattern args pattern:"*@*") == true then (
104 | local members = filterString args "@"
105 | if members[2] != undefined then (
106 | local
107 | provider = filterString members[2] ".",
108 | lk = _cm.arFind fSMTP (if provider[1] == "hotmail" then "live" else provider[1]),
109 | serv = if lk !=undefined then SMTP[lk],
110 | dom = if serv != undefined then substituteString members[2] provider[1] serv
111 | txt_c5.text = if dom != undefined then dom else ""
112 | )
113 | )
114 | )
115 | -- compose and send the email
116 | on btn_c1 pressed do (
117 | try (
118 | local mailbody = _comSrv.composeMail txt_c1.text txt_cpt.text txt_c3.text txt_dest.text --AttachFile:file_attach --> you can attach a file....
119 |
120 | _comSrv.MailSender mailbody txt_c3.text txt_c4.text txt_c5.text (execute txt_c6.text) ssl:chk_c1.state
121 |
122 | txt_c7.text = "MAIL SENT"
123 | txt_c7.BackColor = ((dotNetClass "System.Drawing.Color").Lightgreen)
124 |
125 | ) catch (
126 | txt_c7.text = getCurrentException()
127 | txt_c7.BackColor = ((dotNetClass "System.Drawing.Color").IndianRed)
128 | )
129 | )
130 | ) -- END ROLLOUT --
131 |
132 | -- load a bunch of values in the template
133 | roll_email.load_data "ONE" "TWO" "THREE" "FOUR" "FIVE"
134 | -- show the dialog
135 | CreateDialog roll_email
136 | )
--------------------------------------------------------------------------------
/Snippets/Snippets.ms:
--------------------------------------------------------------------------------
1 | /* https://atelierbump.com ~ MaxScript Snippets */
2 | --------------------------------------------------------------------------------
3 | /* GET A RAY PERPENDICULAR TO THE CURRENT VIEW */
4 | fn getViewDirectionRay =
5 | (
6 | -- The affine TM transforms from world coords to view coords
7 | -- so we need the inverse of this matrix
8 | local coordSysTM = Inverse(getViewTM())
9 | -- The Z axis of this matrix is the view direction.
10 | local viewDir = -coordSysTM.row3
11 | -- get the view position from this matrix
12 | local viewPt = coordSysTM.row4
13 | return ray viewPt viewDir
14 | )
15 |
16 | --------------------------------------------------------------------------------
17 | /* SELECT ALL NODES INSIDE AN OPEN CONTAINER*/
18 | fn cont_content c =
19 | (
20 | if isKindOf c Container then (
21 | local nd
22 | c.GetContentNodes true &nd
23 | selectMore nd
24 | )
25 | )
26 |
27 | --------------------------------------------------------------------------------
28 | /* LIST NODE PROPERTIES */
29 | fn props_lister obj =
30 | (
31 | ClearListener()
32 | p_names = getPropNames obj
33 | p_str = for i in p_names collect (i as string)
34 | for i in p_str do (format "%\n" i)
35 | )
36 |
37 | --------------------------------------------------------------------------------
38 | /* add new layer and set options */
39 | fn addLay obj layerName:"layer_test_" =
40 | (
41 | if not(LayerManager.getLayerFromName layerName) then
42 | (
43 | local refLay = LayerManager.newLayerFromName layerName
44 | refLay.showFrozenInGray=false
45 | refLay.renderable =false
46 | refLay.lock=true
47 | try (refLay.addNode obj) catch ()
48 | )
49 | )
50 |
51 | --------------------------------------------------------------------------------
52 | /* MATRIX FROM 3 POINTS */
53 | fn getMatrix p1 p2 p3 = (
54 | v1 = normalize (p2 - p1)
55 | v3 = normalize (cross v1 (normalize (p3 - p1)))
56 | v2 = normalize (cross v3 v1)
57 | return matrix3 v1 v2 v3 p1
58 | )
59 | --------------------------------------------------------------------------------
60 | /* RESET ROTATION */
61 | fn resetAxisRot obj axis:x = (
62 | local objTM = obj.transform
63 | local objTR = obj.position
64 | local objRot = objTM.rotationpart
65 | local deg = objRot as EulerAngles
66 | case axis of (
67 | x: deg.x = 0
68 | y: deg.y = 0
69 | z: deg.z = 0
70 | )
71 | local rm = (deg as Quat) as Matrix3
72 | local newTM = rm
73 | newTM.row4 = objTR
74 | obj.transform = newTM
75 | )
76 |
77 | --------------------------------------------------------------------------------
78 | /* set Obj ID relative to camera distance */
79 | fn setObjID =
80 | (
81 | local cam = getActiveCamera()
82 | if cam != undefined then (
83 | local bbx = box2 [0,0] [gw.getWinSizeX(),gw.getWinSizeY()]
84 | local objsel = boxPickNode bbx
85 | local campos = cam.pos
86 | fn compareFN v1 v2 ref: =
87 | (
88 | local a = distance ref v1.pos
89 | local b = distance ref v2.pos
90 | local d = a - b
91 | case of
92 | (
93 | (d < 0.): -1
94 | (d > 0.): 1
95 | default: 0
96 | )
97 | )
98 | qsort objsel compareFN ref:campos
99 | for i=1 to objsel.count do (
100 | objsel[i].gbufferChannel = i
101 | )
102 |
103 | )
104 | )
105 |
106 | --------------------------------------------------------------------------------
107 | /* SELECT ALL NODES WITHOUT MATERIAL*/
108 | fn sel_nomat =
109 | (
110 | local sel = getCurrentSelection()
111 | local nomat = for i in sel where (i.material == undefined and not (isgrouphead i)) collect i
112 | select nomat
113 | )
114 |
115 | --------------------------------------------------------------------------------
116 | /* QUICK ALIGN TO CURRENT COORDINATE SYSTEM */
117 | mapped fn alignToCPTM obj =
118 | (
119 | if isValidNode obj then
120 | (
121 | local tm = obj.transform
122 | local stm = getCPTM()
123 | local irot = ( tm * (inverse stm) ).rotationpart
124 | -- transform
125 | obj.transform = preRotate tm (inverse irot)
126 | --node.transform *= xformmat (scalematrix sc) (inverse spaceTM)
127 | --obj.transform = obj.transform * (inverse spaceTM) * (scalematrix sc) * spaceTM
128 | )
129 | )
130 |
131 | --------------------------------------------------------------------------------
132 |
--------------------------------------------------------------------------------
/assets/Hyperclone_rollout.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/assets/Hyperclone_rollout.jpg
--------------------------------------------------------------------------------
/assets/SphereClone.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/assets/SphereClone.jpg
--------------------------------------------------------------------------------
/assets/SphereClone_rolout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/assets/SphereClone_rolout.png
--------------------------------------------------------------------------------
/assets/advman.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/assets/advman.png
--------------------------------------------------------------------------------
/assets/camtool.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/assets/camtool.PNG
--------------------------------------------------------------------------------
/assets/hyperClone.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/assets/hyperClone.jpg
--------------------------------------------------------------------------------
/assets/panel_cuts_intro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/assets/panel_cuts_intro.png
--------------------------------------------------------------------------------
/assets/panel_cuts_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/assets/panel_cuts_logo.png
--------------------------------------------------------------------------------
/assets/panel_cuts_ui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/assets/panel_cuts_ui.png
--------------------------------------------------------------------------------
/assets/random_detach.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/assets/random_detach.jpg
--------------------------------------------------------------------------------
/encryptFile.ms:
--------------------------------------------------------------------------------
1 | (encryptScript maxOps.mxsCmdLineArgs[#in])
--------------------------------------------------------------------------------
/libs/easing.ms:
--------------------------------------------------------------------------------
1 | -- Ease-In Algorithm in MaxScript
2 | (
3 | struct easing
4 | (
5 | -- Function to calculate ease-in based on a cubic function
6 | fn easeInCubic t = t^3,
7 |
8 | -- Function to calculate ease-in based on a quadratic function
9 | fn easeInQuad t = t^2,
10 |
11 | -- Function to calculate ease-in based on a sinusoidal function
12 | fn easeInSine t =
13 | (
14 | 1 - cos (t * pi / 2.0)
15 | ),
16 |
17 | -- Function to calculate ease-in based on an exponential function
18 | fn easeInExpo t =
19 | (
20 | if t == 0 then 0 else (2.0 ^ (10 * (t - 1)))
21 | ),
22 |
23 | -- Function to calculate ease-in based on a circular function
24 | fn easeInCirc t =
25 | (
26 | if t == (t as integer == 1) then 1 else 1 - sqrt (1 - t * t)
27 | t
28 | ),
29 |
30 | -- Function to calculate ease-in based on a back function
31 | fn easeInBack t s:1.70158 =
32 | (
33 | t^2 * ((s + 1) * t - s)
34 | ),
35 | -- Function to calculate ease-out based on a bounce function (used for ease-in bounce)
36 | fn easeOutBounce t =
37 | (
38 | if t < (1 / 2.75) then
39 | 7.5625 * t^2
40 | else if t < (2 / 2.75) then
41 | (
42 | t = t - (1.5 / 2.75)
43 | 7.5625 * t^2 + 0.75
44 | )
45 | else if t < (2.5 / 2.75) then
46 | (
47 | t = t - (2.25 / 2.75)
48 | 7.5625 * t^2 + 0.9375
49 | )
50 | else
51 | (
52 | t = t - (2.625 / 2.75)
53 | 7.5625 * t^2 + 0.984375
54 | )
55 | ),
56 | -- Function to calculate ease-in based on a bounce function
57 | fn easeInBounce t =
58 | (
59 | 1 - easeOutBounce (1 - t)
60 | ),
61 | -- Function to interpolate between two values using an easing function
62 | fn interpolateEase startValue endValue t easingFunction =
63 | (
64 | local delta = endValue - startValue
65 | local easedT = easingFunction t
66 | startValue + delta * easedT
67 | )
68 |
69 | )
70 | )
71 | ea = easing()
72 | -- Test the ease-in functions
73 | /*
74 | for t = 0.0 to 1.0 by 0.1 do
75 | (
76 | -- format "t: % - EaseInCubic: %\n" t (ea.easeInCubic t)
77 | -- format "t: % - EaseInQuad: %\n" t (ea.easeInQuad t)
78 | -- format "t: % - EaseInSine: %\n" t (ea.easeInSine t)
79 | -- format "t: % - EaseInExpo: %\n" t (ea.easeInExpo t)
80 | -- format "t: % - EaseInCirc: %\n" t (ea.easeInCirc t)
81 | -- format "t: % - EaseInBack: %\n" t (ea.easeInBack t)
82 | -- format "t: % - EaseInBounce: %\n" t (ea.easeInBounce t)
83 | ea.interpolateEase 0.0 1.0 t easeInBounce
84 | )
85 | */
--------------------------------------------------------------------------------
/libs/goldenProportions.ms:
--------------------------------------------------------------------------------
1 | struct goldenProportions
2 | (
3 | private
4 | fn phivalue = phi = (1 + sqrt 5) / 2.0,
5 | rects,
6 | public
7 | phi = phivalue(),
8 | private
9 | -- PhiRectangles bounds: the golden ratio rectangle
10 | fn goldenRectangleBounds viewSize margin_vertical:0.0 margin_horizontal:0.0 =
11 | (
12 | -- the rectangle
13 | local rec = boxmodel()
14 | -- rectangle size
15 | if (viewSize.w > viewSize.h) then
16 | (
17 | -- horizontal rectangle
18 | rec.orient = 0
19 |
20 | if (viewSize.w / viewSize.h as float) > phi then
21 | (
22 | rec.h = viewSize.h
23 | rec.w = viewSize.h * phi
24 | ) else (
25 | rec.w = viewSize.w
26 | rec.h = viewSize.w / phi
27 | )
28 | ) else (
29 | -- vertical rectangle
30 | rec.orient = 1
31 |
32 | if (viewSize.h / viewSize.w as float) > phi then
33 | (
34 | rec.w = viewSize.w
35 | rec.h = viewSize.w * phi
36 | ) else (
37 | rec.h = viewSize.h
38 | rec.w = viewSize.h / phi
39 | )
40 | )
41 | -- margins
42 | rec.h += margin_vertical
43 | rec.w += margin_horizontal
44 | -- center the Rectangle
45 | rec.x = (viewSize.x + (viewSize.w - rec.w) / 2.0) as integer
46 | rec.y = (viewSize.y + (viewSize.h - rec.h) / 2.0) as integer
47 | -- other values
48 | rec.refPoint = [rec.x, rec.y, 0]
49 | rec.basepoint = rec.refPoint
50 | -- the rectangle object
51 | rec
52 | ),
53 | -- PhiRectangles iterator.
54 | fn PhiRectangles &rects limit:1.0 =
55 | (
56 | -- draw the rectangle here ?
57 | -- last value
58 | local last = rects[rects.count]
59 | -- proceed until the rectangle is 1x1px in size...
60 | if (last.w > limit) OR (last.h > limit) then (
61 | local curr = deepCopy last
62 |
63 | case last.orient of (
64 | 0:
65 | (
66 | curr.refpoint = [last.x, last.y + last.h, 0]
67 | curr.x += last.h
68 | curr.w -= last.h
69 | curr.basePoint = [curr.x, curr.y + curr.h,0]
70 | curr.orient = 1
71 | )
72 | 1:
73 | (
74 | curr.refpoint = [last.x, last.y, 0]
75 | curr.y += last.w
76 | curr.h -= last.w
77 | curr.basePoint = [curr.x, curr.y,0]
78 | curr.orient = 2
79 | )
80 | 2:
81 | (
82 | curr.refpoint = [last.x + last.w, last.y, 0]
83 | curr.w -= last.h
84 | curr.basePoint = [curr.x + curr.w, curr.y,0]
85 | curr.orient = 3
86 | )
87 | 3:
88 | (
89 | curr.refpoint = [last.x + last.w, last.y + last.h, 0]
90 | curr.h -= last.w
91 | curr.basePoint = [curr.x+last.w, curr.y+curr.h,0]
92 | curr.orient = 0
93 | )
94 | )
95 | -- add to collection
96 | append rects curr
97 | -- ITERATE
98 | PhiRectangles &rects limit:limit
99 | )
100 | ),
101 | -- interpolate arc points
102 | fn arcGen bp radius start:0 end:360 res:1 =
103 | (
104 | for i=start to end by res collect [(cos i), (sin i), 0.0] * radius + bp
105 | ),
106 | public
107 | -- generate the golden rectangles collection
108 | fn goldenRectangles sizebox margin_vertical:0.0 margin_horizontal:0.0 =
109 | (
110 | if classOf sizebox == Box2 then (
111 | -- start
112 | local rects = #( goldenRectangleBounds sizebox margin_vertical:margin_vertical margin_horizontal:margin_horizontal )
113 | -- iterate
114 | PhiRectangles &rects
115 | -- return
116 | rects
117 | ) else undefined
118 | ),
119 | -- draw rectilinear spiral
120 | fn sqSpiral golden_rects =
121 | (
122 | for r=2 to golden_rects.count collect golden_rects[r].refPoint
123 | ),
124 | -- draw quasi-spiral conformed by arcs
125 | fn arcSpiral golden_rects res:1 =
126 | (
127 | local res = #()
128 | for r=2 to golden_rects.count do (
129 | local radius = distance golden_rects[r].basePoint golden_rects[r].refPoint
130 | local arcpoints =
131 | case golden_rects[r].orient of (
132 | 0:( arcGen (golden_rects[r].basePoint) radius start:90 end:180 )
133 | 1:( arcGen (golden_rects[r].basePoint) radius start:180 end:270 )
134 | 2:( arcGen (golden_rects[r].basePoint) radius start:270 end:360 )
135 | 3:( arcGen (golden_rects[r].basePoint) radius start:0 end:90 )
136 | )
137 | join res arcpoints
138 | )
139 | res
140 | )
141 | )
--------------------------------------------------------------------------------
/libs/menu_manager_api/menu_man_example.ms:
--------------------------------------------------------------------------------
1 | dstlbxMenu = menu_man.generate_menu "DesignToolBox" classid:0x6cc645b8
2 | if dstlbxMenu != undefined then (
3 | --------- refGuides
4 | menu_man.item_create_add dstlbxMenu "BUMP_refGuides_noUI_free_cont" "BUMP refGuides" title:"Reference guide - free space"
5 | menu_man.item_create_add dstlbxMenu "BUMP_refGuides_noUI_ortho_cont" "BUMP refGuides" title:"Reference guide - orhtogonal"
6 | menu_man.item_create_add dstlbxMenu "BUMP_refGuides_noUI_polar_cont" "BUMP refGuides" title:"Reference guide - polar"
7 | menu_man.menu_separator dstlbxMenu
8 | menu_man.item_create_add dstlbxMenu "BUMP_refGuides_Li2" "BUMP refGuides" title:"Display ref. guides units"
9 | menu_man.item_create_add dstlbxMenu "BUMP_refGuides_delete" "BUMP refGuides" title:"Delete all reference objects"
10 | menu_man.menu_separator dstlbxMenu
11 | ---------
12 | local Rg_mnu = menu_man.item_submenu_create "refGuides tools"
13 | menu_man.item_create_add Rg_mnu "BUMP_refGuides_prot_free" "BUMP refGuides" title:"Reference protractor - free space"
14 | menu_man.item_create_add Rg_mnu "BUMP_refGuides_prot_ortho" "BUMP refGuides" title:"Reference protractor - orthogonal"
15 | menu_man.item_create_add Rg_mnu "BUMP_refGuides_prot_polar" "BUMP refGuides" title:"Reference protractor - polar"
16 | menu_man.menu_separator Rg_mnu
17 | menu_man.item_create_add Rg_mnu "BUMP_refGuides_UI_free" "BUMP refGuides" title:"Reference guide - free space - UI"
18 | menu_man.item_create_add Rg_mnu "BUMP_refGuides_UI_ortho" "BUMP refGuides" title:"Reference guide - orthogonal - UI"
19 | menu_man.item_create_add Rg_mnu "BUMP_refGuides_UI_polar" "BUMP refGuides" title:"Reference guide - polar - UI"
20 | menu_man.menu_separator Rg_mnu
21 | menu_man.item_create_add Rg_mnu "rG_ribbon_intPoints" "BUMP refGuides" title:"Enlable intersection points"
22 | menu_man.item_create_add Rg_mnu "rG_ribbon_Prot" "BUMP refGuides" title:"Enable protractor creation"
23 | menu_man.item_create_add Rg_mnu "rG_ribbon_LkGuides" "BUMP refGuides" title:"Lock reference objects"
24 | menu_man.item_create_add Rg_mnu "rG_ribbon_pGrid" "BUMP refGuides" title:"Enable working grid from polar"
25 | menu_man.item_create_add Rg_mnu "rG_ribbon_IntMode" "BUMP refGuides" title:"Intersection points - All vs Current"
26 | menu_man.menu_separator Rg_mnu
27 | menu_man.item_create_add Rg_mnu "BUMP_refGuides_Li" "BUMP refGuides" title:"Display units for selected guide"
28 | menu_man.menu_separator Rg_mnu
29 | menu_man.item_create_add Rg_mnu "BUMP_HGScale" "BUMP refGuides" title:"Display Home Grid units"
30 | menu_man.item_create_add Rg_mnu "BUMP_infotool" "BUMP refGuides" title:"Spatial Info tool"
31 | menu_man.item_create_add Rg_mnu "BUMP_Zpos" "BUMP refGuides" title:"Node Z position Info tool"
32 | menu_man.menu_add_submenu dstlbxMenu Rg_mnu
33 | ---------
34 | menu_man.menu_separator dstlbxMenu
35 | --------- Transform
36 | menu_man.item_create_add dstlbxMenu "BUMP_Lrotator" "BUMP DesignToolbox" title:"Rotation - local reference"
37 | menu_man.item_create_add dstlbxMenu "BUMP_rotator" "BUMP DesignToolbox" title:"Rotation - 3 axis mode"
38 | menu_man.item_create_add dstlbxMenu "BUMP_scale" "BUMP DesignToolbox" title:"Reference scale"
39 | menu_man.item_create_add dstlbxMenu "BUMP_scale_distance" "BUMP DesignToolbox" title:"Scale by dimension"
40 | menu_man.item_create_add dstlbxMenu "BUMP_offset" "BUMP DesignToolbox" title:"Adv. Position Offset"
41 | menu_man.menu_separator dstlbxMenu
42 | ---------
43 | local Tr_mnu = menu_man.item_submenu_create "Transform tools"
44 | menu_man.item_create_add Tr_mnu "BUMP_scale_xform" "BUMP DesignToolbox" title:"Reference scale - xForm mod."
45 | menu_man.item_create_add Tr_mnu "BUMP_moveAround" "BUMP DesignToolbox" title:"Move around and clone"
46 | menu_man.item_create_add Tr_mnu "BUMP_rndTrs" "BUMP tools" title:"Random transform"
47 | menu_man.menu_add_submenu dstlbxMenu Tr_mnu
48 | ---------
49 | menu_man.menu_separator dstlbxMenu
50 | --------- Measure
51 | menu_man.item_create_add dstlbxMenu "BUMP_Qmeasure" "BUMP DesignToolbox" title:"Measure units"
52 | menu_man.item_create_add dstlbxMenu "BUMP_Qmeasure_mult" "BUMP DesignToolbox" title:"Chain measure"
53 | menu_man.menu_separator dstlbxMenu
54 | menu_man.item_create_add dstlbxMenu "BUMP_Divider" "BUMP DesignToolbox" title:"Distance divider"
55 | menu_man.menu_separator dstlbxMenu
56 | ---------
57 | local Ms_mnu = menu_man.item_submenu_create "Measure tools"
58 | menu_man.item_create_add Ms_mnu "BUMP_Qangle" "BUMP DesignToolbox" title:"Angle measure"
59 | menu_man.item_create_add Ms_mnu "BUMP_Qarea" "BUMP DesignToolbox" title:"2D Area measure"
60 | menu_man.item_create_add Ms_mnu "BUMP_Qvolume" "BUMP DesignToolbox" title:"Cubic volume"
61 | menu_man.menu_separator Ms_mnu
62 | menu_man.item_create_add Ms_mnu "BUMP_clonebtwn" "BUMP DesignToolbox" title:"Clone between"
63 | menu_man.item_create_add Ms_mnu "BUMP_Divider_imput" "BUMP DesignToolbox" title:"Distance divider - imput"
64 | menu_man.menu_add_submenu dstlbxMenu Ms_mnu
65 | ---------
66 | menu_man.menu_separator dstlbxMenu
67 | menu_man.item_create_add dstlbxMenu "BUMP_distListener" "BUMP DesignToolbox" title:"Measure listener"
68 | menu_man.menu_separator dstlbxMenu
69 | --------- Eyedropper
70 | menu_man.item_create_add dstlbxMenu "BUMP_replicator" "BUMP DesignToolbox" title:"Replicator"
71 | menu_man.item_create_add dstlbxMenu "BUMP_edrpAll" "BUMP DesignToolbox" title:"Eyedropper"
72 | menu_man.item_create_add dstlbxMenu "BUMP_edrp_flt" "BUMP DesignToolbox" title:"Eyedropper filters"
73 | menu_man.menu_separator dstlbxMenu
74 | ---------
75 | local Rep_mnu = menu_man.item_submenu_create "Replicators"
76 | menu_man.item_create_add Rep_mnu "BUMP_edrpTr" "BUMP DesignToolbox" title:"Eyedropper - Transform"
77 | menu_man.item_create_add Rep_mnu "BUMP_edrpMt" "BUMP DesignToolbox" title:"Eyedropper - Material"
78 | menu_man.item_create_add Rep_mnu "BUMP_edrpMd" "BUMP DesignToolbox" title:"Eyedropper - Modifiers"
79 | menu_man.item_create_add Rep_mnu "BUMP_edrpUV" "BUMP DesignToolbox" title:"Eyedropper - UVW data or modifiers"
80 | menu_man.item_create_add Rep_mnu "BUMP_edrpVis" "BUMP DesignToolbox" title:"Eyedropper - Visual properties"
81 | menu_man.menu_separator Rep_mnu
82 | menu_man.item_create_add Rep_mnu "BUMP_rep_mt" "BUMP DesignToolbox" title:"Replicator - multi target"
83 | menu_man.item_create_add Rep_mnu "BUMP_rep_grp" "BUMP DesignToolbox" title:"Replicator - group replace mode"
84 | menu_man.item_create_add Rep_mnu "BUMP_rep_tm" "BUMP DesignToolbox" title:"Replicate transform"
85 | menu_man.item_create_add Rep_mnu "BUMP_rep_inst" "BUMP DesignToolbox" title:"Propagate instances"
86 | menu_man.item_create_add Rep_mnu "BUMP_edrp_mt" "BUMP DesignToolbox" title:"Eyedropper - multi target"
87 | menu_man.menu_add_submenu dstlbxMenu Rep_mnu
88 | ---------
89 | menu_man.menu_separator dstlbxMenu
90 | --------- Tools
91 | menu_man.item_create_add dstlbxMenu "BUMP_PARR" "BUMP DesignToolbox" title:"Patern array"
92 | menu_man.item_create_add dstlbxMenu "BUMP_IARR" "BUMP DesignToolbox" title:"3D Array"
93 | menu_man.menu_separator dstlbxMenu
94 | menu_man.item_create_add dstlbxMenu "BUMP_unhider" "BUMP DesignToolbox" title:"Unhide by selection"
95 | menu_man.item_create_add dstlbxMenu "BUMP_unfrozer" "BUMP DesignToolbox" title:"Unfreeze by selection"
96 | menu_man.item_create_add dstlbxMenu "BUMP_refIsolate" "BUMP DesignToolbox" title:"Local coords. Isolation"
97 | menu_man.menu_separator dstlbxMenu
98 | --------- Pivot
99 | local Pivot_mnu = menu_man.item_submenu_create "Pivot tools"
100 | menu_man.item_create_add Pivot_mnu "BUMP_QPVT" "BUMP DesignToolbox" title:"Quick pivot UI"
101 | menu_man.menu_separator Pivot_mnu
102 | -- menu_man.item_create_add Pivot_mnu "BUMP_QPVT_pnt" "BUMP DesignToolbox" title:"Pivot to point"
103 | menu_man.item_create_add Pivot_mnu "BUMP_QPVT_btn" "BUMP DesignToolbox" title:"Pivot to bottom"
104 | menu_man.item_create_add Pivot_mnu "BUMP_QPVT_3p" "BUMP DesignToolbox" title:"Pivot from 3 points"
105 | menu_man.item_create_add Pivot_mnu "BUMP_QPVT_3pWP" "BUMP DesignToolbox" title:"Working pivot from 3 points"
106 | menu_man.item_create_add Pivot_mnu "BUMP_QPVT_sf" "BUMP DesignToolbox" title:"Pivot from selected faces"
107 | menu_man.menu_add_submenu dstlbxMenu Pivot_mnu
108 | ---------
109 | menu_man.menu_separator dstlbxMenu
110 | --------- Objects
111 | menu_man.item_create_add dstlbxMenu "BUMP_PN" "BUMP DesignToolbox" title:"Paneling tool"
112 | menu_man.item_create_add dstlbxMenu "BUMP_MMap" "BUMP DesignToolbox" title:"UVW map tool"
113 | ---------
114 | local Util_mnu = menu_man.item_submenu_create "Utilities"
115 | menu_man.item_create_add Util_mnu "BUMP_PNDT" "BUMP DesignToolbox" title:"Add details tool"
116 | menu_man.item_create_add Util_mnu "BUMP_mapTools" "BUMP DesignToolbox" title:"UVW gizmo tools"
117 | menu_man.item_create_add Util_mnu "BUMP_snapSets" "BUMP tools" title:"Save snap states"
118 | menu_man.item_create_add Util_mnu "BUMP_cclp" "BUMP tools" title:"Color clipboard"
119 | menu_man.item_create_add Util_mnu "BUMP_rndTrs" "BUMP tools" title:"Random Transformations"
120 | menu_man.menu_add_submenu dstlbxMenu Util_mnu
121 | ---------
122 | menu_man.menu_separator dstlbxMenu
123 | ---------
124 | local Lks_mnu = menu_man.item_submenu_create "Transform locks"
125 | menu_man.item_create_add Lks_mnu "BUMP_Locks_all" "BUMP DesignToolbox" title:"Lock All"
126 | menu_man.item_create_add Lks_mnu "BUMP_Locks_pos" "BUMP DesignToolbox" title:"Lock position"
127 | menu_man.item_create_add Lks_mnu "BUMP_Locks_rot" "BUMP DesignToolbox" title:"Lock rotation"
128 | menu_man.item_create_add Lks_mnu "BUMP_Locks_scale" "BUMP DesignToolbox" title:"Lock scale"
129 | menu_man.menu_add_submenu dstlbxMenu Lks_mnu
130 | ---------
131 | menu_man.menu_separator dstlbxMenu
132 | --------- Layers
133 | local Layers_mnu = menu_man.item_submenu_create "Layer tools"
134 | menu_man.item_create_add Layers_mnu "BUMP_layIso" "BUMP DesignToolbox" title:"Isolate layer"
135 | menu_man.menu_separator Layers_mnu
136 | menu_man.item_create_add Layers_mnu "BUMP_layProp1" "BUMP DesignToolbox" title:"Layer lock"
137 | menu_man.item_create_add Layers_mnu "BUMP_layProp2" "BUMP DesignToolbox" title:"layer ON/OFF"
138 | menu_man.item_create_add Layers_mnu "BUMP_layProp3" "BUMP DesignToolbox" title:"Layer box mode"
139 | menu_man.item_create_add Layers_mnu "BUMP_layProp4" "BUMP DesignToolbox" title:"Layer backface cull"
140 | menu_man.menu_add_submenu dstlbxMenu Layers_mnu
141 | ---------
142 | menu_man.menu_separator dstlbxMenu
143 | ----------
144 | local cfg_mnu = menu_man.item_submenu_create "Configuration"
145 | menu_man.item_create_add cfg_mnu "BUMP_cfg" "BUMP DesignToolbox" title:"DesignToolBox settings"
146 | menu_man.item_create_add cfg_mnu "BUMP_refGuides_config" "BUMP refGuides" title:"refGuides settings"
147 | menu_man.menu_add_submenu dstlbxMenu cfg_mnu
148 | ---------
149 | menu_man.menu_separator dstlbxMenu
150 | ---------
151 | local help_mnu = menu_man.item_submenu_create "Help"
152 | menu_man.item_create_add help_mnu "DTLBX_ACT" "BUMP DesignToolbox"
153 | menu_man.item_create_add help_mnu "DTLBX_DOCS" "BUMP DesignToolbox"
154 | menu_man.item_create_add help_mnu "DTLBX_ABOUT" "BUMP DesignToolbox"
155 | menu_man.menu_add_submenu dstlbxMenu help_mnu
156 | ---------
157 | -- */
158 |
159 | /*
160 | local flt_mnu = menuMan.createMenu "UI Floaters"
161 | create_add flt_mnu "BUMP_rG_fltUI" "BUMP refGuides" title:"refGuides floater"
162 | create_add flt_mnu "BUMP_dS_fltUI" "BUMP DesignToolbox" title:"DesignToolBox floater"
163 | add_mnu dstlbxMenu ( menuMan.createSubMenuItem "UI Floaters" flt_mnu)
164 | */
165 | -------------------------------------
166 | -- redraw the menu bar with the new item
167 | menuMan.updateMenuBar()
168 | )
169 |
--------------------------------------------------------------------------------
/libs/menu_manager_api/menu_manager.ms:
--------------------------------------------------------------------------------
1 | /*
2 | -------------------------------------------------------------------------------------------------------------
3 | http://help.autodesk.com/view/3DSMAX/2018/ENU/?guid=__files_GUID_258F6015_6B45_4A87_A7F5_BB091A2AE065_htm
4 |
5 | MENU STRUCTURE
6 | ---------------
7 | mainMenubar
8 | -Menu-registered
9 | - Item-action
10 | - Item-action
11 | - Item-submenu
12 | - Item-action
13 | - Item-submenu
14 | - Item-action
15 | - ...
16 | - ...
17 | - ...
18 | -------------------------------------------------------------------------------------------------------------
19 | */
20 | (
21 | struct menuMan_api
22 | (
23 | /*
24 | - if is sucessfull... you can register a new menu in that context
25 | - if fails, either the context can't be registered or has already been defined
26 | - The context is unique for each menu
27 | - Use (genClassID())[1] to genereate a classID
28 | */
29 | fn register_menu_context classid: =
30 | (
31 | local res = false
32 | try (
33 | res = menuMan.registerMenuContext classid
34 | ) catch (
35 | format "%\n" (getCurrentException())
36 | return false
37 | )
38 | res
39 | ),
40 | -- Menu needs to be created to be able to add items to it
41 | fn menu_create_main title =
42 | (
43 | local mainMenuBar = menuMan.getMainMenuBar()
44 | local m = menuMan.createMenu title
45 | -- menu needs to be registered as submenu of the mainMenuBar
46 | local subMenuItem = menuMan.createSubMenuItem title m
47 | local subMenuIndex = mainMenuBar.numItems() - 1
48 | mainMenuBar.addItem subMenuItem subMenuIndex
49 | menuMan.updateMenuBar()
50 | m
51 | ),
52 | fn item_submenu_create title =
53 | (
54 | if title != "" then menuMan.createMenu title
55 | ),
56 | fn item_action_create ms_name ms_cat title: =
57 | (
58 | local item = menuMan.createActionItem ms_name ms_cat
59 | if title != unsupplied and title != "" then (
60 | item.setTitle title
61 | item.setUseCustomTitle true
62 | )
63 | item
64 | ),
65 | -- Items can be either an or a
66 | fn menu_add_item menu item =
67 | (
68 | menu.addItem item (-1)
69 | item
70 | ),
71 | fn menu_add_submenu menu submenu title: =
72 | (
73 | local the_title = if title == unsupplied then submenu.getTitle() else title
74 | this.menu_add_item menu (menuMan.createSubMenuItem the_title submenu)
75 | ),
76 | fn item_create_add menu ms_name ms_cat title: =
77 | (
78 | local item = this.item_action_create ms_name ms_cat title:title
79 | this.menu_add_item menu item
80 | item
81 | ),
82 | fn menu_separator menu =
83 | (
84 | menu.addItem (menuMan.createSeparatorItem()) (-1)
85 | ),
86 | fn menu_find_in_bar title =
87 | (
88 | local mainMenuBar = menuMan.getMainMenuBar()
89 | local counter = mainMenuBar.numItems()
90 | local mnu_in_bar = false
91 | do (
92 | local item = mainMenuBar.getItem counter
93 | local t = item.getTitle()
94 | if t == title then (
95 | mnu_in_bar = true
96 | counter = 0
97 | ) else counter -= 1
98 | ) while (counter > 1)
99 | mnu_in_bar
100 | ),
101 | fn menu_register menu title =
102 | (
103 | -- check if exist in the MainMenu, if not, add it
104 | local menu_in_bar = this.menu_find_in_bar title
105 | if not mnu_in_bar then (
106 | local subMenuItem = menuMan.createSubMenuItem title menu
107 | -- compute the index of the next-to-last menu item in the main menu bar
108 | local subMenuIndex = mainMenuBar.numItems() - 1
109 | -- Add the sub-menu just at the second to last slot
110 | mainMenuBar.addItem subMenuItem subMenuIndex
111 | menuMan.updateMenuBar()
112 | )
113 | mnu_in_bar
114 | ),
115 | fn menu_reset title =
116 | (
117 | local the_menu = menuMan.findMenu title
118 | if the_menu != undefined then (
119 | local menu_itemcount = the_menu.numItems();
120 | if menu_itemcount > 0 then (
121 | -- Remove menu items
122 | for i = menu_itemcount to 1 by -1 do (
123 | local item = the_menu.getItem i
124 | -- if is a submenu... unimplemented
125 | -- local submenu = item.getSubMenu()
126 | the_menu.removeItem item
127 | )
128 | menuMan.updateMenuBar()
129 | )
130 | )
131 | ),
132 | fn menu_remove title =
133 | (
134 | local res = false
135 | local the_menu = menuMan.findMenu title
136 | if the_menu != undefined then
137 | (
138 | local menu_itemcount = the_menu.numItems();
139 | if menu_itemcount > 0 then (
140 | -- Remove menu items
141 | for i = menu_itemcount to 1 by -1 do (
142 | local item = the_menu.getItem i
143 | -- if is a submenu... unimplemented
144 | -- local submenu = item.getSubMenu()
145 | the_menu.removeItem item
146 | )
147 | -- unregister the menu
148 | -- This method allows you to remove a menu form the mananger. Returns false if the menu was not registered, true if successfully unregistered.
149 | -- menu: Points to the menu to unregister.
150 | -- menuMan.unRegisterMenu menu
151 | res = menuMan.unRegisterMenu the_menu
152 | menuMan.updateMenuBar()
153 | )
154 | )
155 | res
156 | ),
157 | fn generate_menu title classid: =
158 | (
159 | local try_to_register = this.register_menu_context classid:classid
160 | local the_menu
161 | if try_to_register then (
162 | -- if context successful...
163 | the_menu = this.menu_create_main title
164 | ) else (
165 | -- context can exist but the menu can be deleted so...
166 | -- Check if menu exists
167 | the_menu = menuMan.findMenu title
168 | if (the_menu != undefined) then (
169 | -- reset the menu or remove the menu
170 | -- this.menu_reset title
171 | this.menu_remove title
172 | -- register menu again
173 | this.register_menu_context classid:classid
174 | the_menu = this.menu_create_main title
175 | ) else (
176 | the_menu = this.menu_create_main title
177 | )
178 | )
179 | menuMan.updateMenuBar()
180 | the_menu
181 | )
182 | )
183 | -- END STRUCT --
184 | menuMan_api()
185 | )
--------------------------------------------------------------------------------
/release/Adv_path_manager.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/Adv_path_manager.zip
--------------------------------------------------------------------------------
/release/Panel_cuts.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/Panel_cuts.zip
--------------------------------------------------------------------------------
/release/Photographic_composition_guides.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/Photographic_composition_guides.zip
--------------------------------------------------------------------------------
/release/Random_detach.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/Random_detach.zip
--------------------------------------------------------------------------------
/release/Viewport_composition_guides.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/Viewport_composition_guides.zip
--------------------------------------------------------------------------------
/release/align_assets.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/align_assets.zip
--------------------------------------------------------------------------------
/release/arch_scaler.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/arch_scaler.zip
--------------------------------------------------------------------------------
/release/audit_materials.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/audit_materials.zip
--------------------------------------------------------------------------------
/release/cam_manager.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/cam_manager.zip
--------------------------------------------------------------------------------
/release/gamma_adjustment.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/gamma_adjustment.zip
--------------------------------------------------------------------------------
/release/mat_tools.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/mat_tools.zip
--------------------------------------------------------------------------------
/release/plugin/BUMP_resizer.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/plugin/BUMP_resizer.zip
--------------------------------------------------------------------------------
/release/random_select.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/random_select.zip
--------------------------------------------------------------------------------
/release/sunblind_cage_calc.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/sunblind_cage_calc.zip
--------------------------------------------------------------------------------
/release/usericons/extratools_16a.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/usericons/extratools_16a.bmp
--------------------------------------------------------------------------------
/release/usericons/extratools_16i.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/usericons/extratools_16i.bmp
--------------------------------------------------------------------------------
/release/usericons/extratools_24a.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/usericons/extratools_24a.bmp
--------------------------------------------------------------------------------
/release/usericons/extratools_24i.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/usericons/extratools_24i.bmp
--------------------------------------------------------------------------------
/release/vertex_scrambler.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/vertex_scrambler.zip
--------------------------------------------------------------------------------
/release/vraymat_populate.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/vraymat_populate.zip
--------------------------------------------------------------------------------
/release/xref_replace.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/release/xref_replace.zip
--------------------------------------------------------------------------------
/src/Adv_path_manager/BUMP_AdvPathMngr.mcr:
--------------------------------------------------------------------------------
1 | macroScript BUMP_AdvPathMngr
2 | category:"BUMP tools"
3 | ButtonText:"APM"
4 | toolTip:"Advanced User Paths manager"
5 | (
6 |
7 | local path_a = "$UserScripts/BUMP_AdvPathMngr.ms"
8 | local path_b = "$scripts/BUMP_AdvPathMngr.ms"
9 |
10 | -- safe execution. Check if script is present in either scripts or userScripts folder
11 | on execute do (
12 | if doesFileExist path_a then
13 | filein path_a
14 | else if doesFileExist path_b then
15 | filein path_b
16 | else
17 | messageBox "Script file missing!"
18 | )
19 | )
20 |
--------------------------------------------------------------------------------
/src/Adv_path_manager/BUMP_AdvPathMngr.ms:
--------------------------------------------------------------------------------
1 | (
2 |
3 | rollout roll_PathEdit "Add Paths" width:500 height:300
4 | (
5 | local owner = if owner != undefined then owner
6 | local stored_values
7 | label lbl1 "Enter a list of paths separated by semicolons (;) or New Lines (\n). Paths can be quoted"
8 | edittext txt1 height:230
9 | button btn1 "Commit" width:150 height:30
10 | fn stringparser str =
11 | (
12 | local stream = str as StringStream
13 | seek stream 0
14 | --readValue stream ignoreStringEscapes:true
15 | local pathsCol = #()
16 | try (
17 | while not eof stream do (
18 | local the_path = readDelimitedString stream ";\n"
19 | -- print the_path
20 | -- sanitize the strings
21 | -- deal with \"\" and "\n"s
22 | --if matchPattern the_path pattern:"\""
23 | if pathConfig.isLegalPath the_path then (
24 | append pathsCol the_path
25 | ) else (
26 | the_path = substituteString the_path "\"" ""
27 | the_path = substituteString the_path "'" ""
28 | -- just in case
29 | the_path = substituteString the_path "\n" ""
30 | -- attemp to validate the path
31 | local resolved_path = pathConfig.resolvePathSymbols the_path
32 | if pathConfig.isLegalPath resolved_path then (
33 | append pathsCol the_path
34 | )
35 | )
36 | )
37 | -- ensure unique paths
38 | pathsCol = makeUniqueArray pathsCol
39 | ) catch (messageBox "Invalid entries!")
40 | -- return the paths
41 | pathsCol
42 | )
43 | on btn1 pressed do (
44 | -- commit paths
45 | local paths = stringparser txt1.text
46 | if paths.count > 0 then stored_values = paths
47 | -- exit dialog
48 | DestroyDialog roll_pathEdit
49 | )
50 | )
51 |
52 | rollout roll_mPath "Advanced External Files (User Paths) Manager" width:1000 --height:400
53 | (
54 | dotNetControl lst_mPath "ListView" height:300
55 | button btn_1 "Change / Resolve" width:150 align:#left across:5
56 | button btn_3 "Brownse..." width:150 align:#left
57 | button btn_8 "Paste..." width:150 align:#left
58 | button btn_2 "Remove" width:150 align:#left
59 | checkbutton btn_4 "Show Only Invalids" align:#right
60 |
61 | checkBox chk_sb "Sub-Directories search filter" align:#left checked:true across:2
62 | editText txt_filter "Pattern: " Text:"#(\"map*\",\"texture*\")" align:#right
63 |
64 | imgTag sep1 width:(roll_mPath.width) height:1 bitmap:(bitmap 1 2 color: (color 5 5 5)) align:#center offset:[0,10]
65 | button btn_7 "Remove ..." width:150 align:#left across:7
66 | checkbox chk_1 "Empty folders" checked:true width:80 align:#right
67 | checkbox chk_dupes "Duplicates" checked:true width:80 align:#right
68 | checkbox chk_2 "Not Images" width:80 align:#right
69 | checkbox chk_3 "Not Models" width:80 align:#right
70 | checkbox chk_4 "Other (specify):" align:#right
71 | editText txt_1 text:"#(\".ies\",\".svg\")" align:#left
72 | imgTag sep2 width:(roll_mPath.width) height:1 bitmap:(bitmap 1 2 color: (color 5 5 5)) align:#center offset:[0,10]
73 | button btn_open "Explore selected" height:30 align:#left across:3
74 | button btn_5 "Done" width:150 height:30 align:#right offset:[160,0]
75 | button btn_6 "Cancel" width:150 height:30 align:#right
76 | ----------------------------------------------------------------------------------------------------------------------------------------------------
77 | local only_invalid = false
78 | --
79 | local
80 | TEMP_PATHS = #(),
81 | ADD_PATHS = #(),
82 | REMOVE_PATHS = #()
83 | --
84 | local temp_listItemsCol
85 | ----------------------------------------------------------------------------------------------------------------------------------------------------
86 | -- file extensions, add as needed
87 | local
88 | img_ext = #(".jpg",".jpeg",".png",".tif",".tiff",".tga",".bmp",".exr",".gif", ".hdr", ".hdri"),
89 | md_ext = #(".3ds",".max",".obj",".fbx",".iges",".dwg",".dxf",".rvt",".skp")
90 | ----------------------------------------------------------------------------------------------------------------------------------------------------
91 | local
92 | alignLeft = (dotNetClass "HorizontalAlignment").Left,
93 | resizeToContent = (dotNetClass "ColumnHeaderAutoResizeStyle").ColumnContent,
94 | resizeToHeader = (dotNetClass "ColumnHeaderAutoResizeStyle").HeaderSize,
95 | dotNetLstViewItemClass = dotNetClass "System.Windows.Forms.ListViewItem",
96 | dotNetLstViewClass = dotNetClass "System.Windows.Forms.ListView",
97 | dotNetColor = dotNetClass "System.Drawing.Color",
98 | dotNetFont = dotNetClass "System.Drawing.Font",
99 | font_underline = (dotNetClass "System.Drawing.FontStyle").Underline,
100 | font_bold = (dotNetClass "System.Drawing.FontStyle").Bold,
101 | font_strk = (dotNetClass "System.Drawing.FontStyle").Strikeout,
102 | font_reg = (dotNetClass "System.Drawing.FontStyle").Regular,
103 | folder_dialog = dotnetobject "FolderBrowserDialog",
104 | dotNetDirectory = dotnetclass "System.IO.Directory",
105 | DirectorySearch = (dotNetClass"System.IO.SearchOption").AllDirectories,
106 | dotNetSort = dotNetClass "System.Windows.Forms.SortOrder"
107 | ----------------------------------------------------------------------------------------------------------------------------------------------------
108 | local
109 | validPathColor = dotNetColor.seagreen,
110 | invalidPathColor = dotNetColor.Crimson,
111 | removedPathColor = dotNetColor.Goldenrod
112 | -- local dotNetContextMenuClass = dotNetClass "System.Windows.Forms.ContextMenu"
113 | ----------------------------------------------------------------------------------------------------------------------------------------------------
114 | -- Compare function used by bsearch:
115 | fn extComparator a b =
116 | (
117 | if a > (toLower b) then 1
118 | else if a < (toLower b) then -1
119 | else 0
120 | )
121 | fn invSort a b =
122 | (
123 | case of (
124 | (a > b):-1
125 | (a < b):1
126 | default:0
127 | )
128 | )
129 | fn ArrayComparator a b =
130 | (
131 | if a > b then 1
132 | else if a < b then -1
133 | else 0
134 | )
135 | -- Retrieve subdirectorries
136 | fn GetAllSubDirs MyDirectory _filter:#("map*","texture*") =
137 | (
138 | local curr_folder =
139 | if _filter != unsupplied then (
140 | local temp = #()
141 | for i in _filter do ( join temp (dotNetDirectory.GetDirectories MyDirectory i DirectorySearch) )
142 | temp
143 | ) else ( dotNetDirectory.GetDirectories MyDirectory "*" DirectorySearch )
144 | curr_folder
145 | /*
146 | local
147 | temp = #(),
148 | s = 1,
149 | folders = getDirectories (MyDirectory + "/*"),
150 | t = folders.count
151 | while s < t do
152 | (
153 | for i = s to t do (
154 | temp = getDirectories (folders[i]+"*")
155 | -- apply filter
156 | for j = 1 to temp.count do folders[folders.count+1] = temp[j]
157 | )
158 | s = t
159 | t = folders.count
160 | )
161 | sort folders
162 | for i=1 to folders.count do (folders[i] = trimRight folders[i] "\\")
163 | folders
164 | -- */
165 | )
166 | ----------------------------------------------------------------------------------------------------------------------------------------------------
167 | -- Re-apply style
168 | fn lst_restyle =
169 | (
170 | local list_items = lst_mPath.Items
171 | for f=0 to (list_items.count) - 1 do (
172 | list_items.Item[f].BackColor = if (bit.get f 1) then dotNetColor.Transparent else dotNetColor.LightGray
173 | )
174 | )
175 | -- Add columns to listView
176 | fn lstV_addColumns lst itms autosize:false =
177 | (
178 | local w = if not autosize then ( (lst.width/itms.count)-1 ) else -2
179 | for x in itms do ( lst.columns.add x w alignLeft )
180 | )
181 | -- Add items to listView
182 | fn lstV_addItem lst itmCol =
183 | (
184 | lst.BeginUpdate()
185 | lst.Items.AddRange itmCol
186 | lst.AutoResizeColumns resizeToContent
187 | lst.AutoResizeColumns resizeToHeader
188 | lst_restyle()
189 | lst.EndUpdate()
190 | )
191 | -- Process paths into ListView items
192 | fn parse_items mP_list font: listView:lst_mPath =
193 | (
194 | local res_list = #()
195 | if mP_list != undefined then (
196 | local ForeColor
197 | local currpath
198 | local subitems
199 | local res_list =
200 | for i=1 to mP_list.count collect (
201 | currpath = mP_list[i]
202 | subitems = #()
203 | subitems[5] = if (pathConfig.isAbsolutePath currpath) then "Absolute" else if (pathConfig.isUncPath currpath) then "UNC" else "-"
204 | subitems[1] = pathConfig.stripPathToLeaf currpath
205 | subitems[2] = currpath
206 | subitems[3] = (getFiles (pathConfig.appendPath currpath "*.*")).count as string
207 | subitems[4] = if (dotNetDirectory.exists currpath) then (ForeColor = validPathColor; "OK") else (ForeColor = invalidPathColor;"MISSING")
208 | -- Initialize Item
209 | local item = dotNetObject dotNetLstViewItemClass subitems
210 | item.tag = currpath
211 | item.ForeColor = ForeColor
212 | item.BackColor = if (bit.get i 1) then dotNetColor.Transparent else dotNetColor.LightGray
213 | if font != unsupplied then item.Font = (dotNetObject dotNetFont (listView.Font) font)
214 | item
215 | )
216 | )
217 | res_list
218 | )
219 | -- Update listView Item
220 | fn update_item the_item new_path =
221 | (
222 | local the_subitems = the_item.subitems
223 | the_item.text = pathConfig.stripPathToLeaf new_path
224 | the_subitems.item[1].text = new_path
225 | the_subitems.item[2].text = (getFiles (pathConfig.appendPath new_path "*.*")).count as string
226 | the_subitems.item[3].text =
227 | if (dotNetDirectory.exists new_path) then (
228 | the_item.ForeColor = validpathColor
229 | "OK"
230 | ) else (
231 | the_item.ForeColor = invalidPathColor
232 | "MISSING"
233 | )
234 | the_subitems.item[4].text = if (pathConfig.isAbsolutePath new_path) then "Absolute" else if (pathConfig.isUncPath new_path) then "UNC" else "-"
235 | )
236 | -- Initialize Collection
237 | fn Init =
238 | (
239 | -- Collect user paths
240 | TEMP_PATHS = for i=1 to (mapPaths.count()) collect (mapPaths.get i)
241 | -- Process paths into ListView items
242 | lstV_addItem lst_mPath (parse_items TEMP_PATHS)
243 | )
244 | -----------------------------------------------------------------------------------------------
245 | -- Commit changes to Paths
246 | fn commit =
247 | (
248 | -- format "%\n" REMOVE_PATHS
249 | -- format "%\n" ADD_PATHS
250 |
251 | if not (queryBox "Commit changes ?. This could take a while to process.") then return false
252 |
253 | -- remove any dupes
254 | REMOVE_PATHS = makeUniqueArray REMOVE_PATHS
255 | ADD_PATHS = makeUniqueArray ADD_PATHS
256 |
257 | -- remove possible delete entry from add entry..
258 | ADD_PATHS = for i=1 to ADD_PATHS.count where (findItem REMOVE_PATHS ADD_PATHS[i] == 0) collect ADD_PATHS[i]
259 |
260 | -- delete entry
261 | format "Removing paths from External files list...\n"
262 | try (
263 | -- collect the indexes to be removed
264 | local rem_idx = for p in REMOVE_PATHS collect findItem TEMP_PATHS p
265 | -- descending sort
266 | qsort rem_idx invSort
267 | -- remove the paths
268 | for i in rem_idx where i != 0 do (
269 | mapPaths.delete i
270 | format "-> %\n" TEMP_PATHS[i]
271 | )
272 | ) catch (messageBox "Unable to remove some paths."; format "%\n" (getCurrentException()) )
273 |
274 | -- add entry
275 | -- /*
276 | format "Adding paths to External files list...\n"
277 | try (
278 | -- progressStart "Adding user paths"
279 | -- do not add duplicated entries
280 | for p in ADD_PATHS where (findItem TEMP_PATHS p) == 0 do (
281 | mapPaths.add p
282 | format "-> %\n" p
283 | )
284 | ) catch (messageBox "unable to add some paths"; format "%\n" (getCurrentException()) )
285 | -- */
286 | -- update the tool
287 | -- Init()
288 | )
289 | -----------------------------------------------------------------------------------------------
290 | -- open explorer
291 | fn openDir =
292 | (
293 | local itms = lst_mPath.SelectedItems.Item
294 | DOSCommand ("explorer " + "\"" + (itms[0].Subitems.Item[1].text) + "\"")
295 | )
296 | -- Add to list
297 | fn path_adder paths =
298 | (
299 | local the_paths = deepcopy paths
300 | local the_filter = if chk_sb.state then (execute txt_filter.text) else unsupplied
301 | if (queryBox "Add subfolders too?") then (
302 | for the_path in paths do (
303 | join the_paths (GetAllSubDirs the_path _filter:the_filter)
304 | )
305 | )
306 | -- add to temp results
307 | join ADD_PATHS the_paths
308 | -- add to list
309 | lstV_addItem lst_mPath (parse_items the_paths font:font_Bold)
310 | silentValue
311 | )
312 | ----------------------------------------------------------------------------------------------------------------------------------------------------
313 | -- Initialize
314 | on roll_mPath open do
315 | (
316 | local HZ = (dotNetClass "HorizontalAlignment").Left
317 | --------------------------------------------------------------------------------------------------------------------------------
318 | --Setup the forms view
319 | lst_mPath.view = (dotNetClass "system.windows.forms.view").details
320 | --Set so full width of listView is selected and not just first column.
321 | lst_mPath.FullRowSelect = true
322 | --Show lines between the items.
323 | lst_mPath.GridLines = true
324 | --Allow for multiple selections.
325 | lst_mPath.MultiSelect = true
326 | -- Allow Label Edit
327 | lst_mPath.LabelEdit = True
328 | -- Allow Column order change
329 | lst_mPath.AllowColumnReorder = True
330 | -- Columns Header additonal options
331 | lst_mPath.HeaderStyle = lst_mPath.HeaderStyle.Nonclickable
332 | -- turn off the grid lines
333 | lst_mPath.gridLines = false
334 | -- When this ListView loses the focus, it will still show what's selected
335 | lst_mPath.HideSelection = false
336 | -- make the border a flat solid color instead of the Windows 3D look
337 | lst_mPath.BorderStyle = lst_mPath.BorderStyle.FixedSingle
338 | -- required in order to implement DotNet drag and drop functionality
339 | lst_mPath.allowDrop = true
340 | -- Items Sort
341 | lst_mPath.Sorting = dotNetSort.Ascending
342 | --------------------------------------------------------------------------------------------------------------------------------
343 | -- Add Columns
344 | lstV_addColumns lst_mPath #("Folder name", "Full path", "Files", "Status", "Type") autosize:True
345 | -- Add Items
346 | Init()
347 | -- lst_mPath.Items.Clear()
348 | )
349 | -- close
350 | on roll_mPath close do ( lst_mPath.Dispose(); gc())
351 | ---------------------------------------------------------------------------------------------------------------------------------------------------- Event handlers
352 | -- Change entry
353 | on btn_1 pressed do
354 | (
355 | local underline = dotNetObject dotNetFont (lst_mPath.Font) font_underline
356 | -- get items list
357 | local itms = lst_mPath.SelectedItems.Item
358 | local itms_count = lst_mPath.SelectedItems.count
359 | for i=0 to itms_count-1 do (
360 | local the_item = itms[i]
361 | folder_dialog.showDialog()
362 | local new_path = folder_dialog.SelectedPath
363 | if new_path != "" then (
364 | -- add old to remove list
365 | appendIfUnique REMOVE_PATHS (the_item.Subitems.Item[1].text)
366 | -- add new to add list
367 | appendIfUnique ADD_PATHS new_path
368 | -- update listview
369 | the_item.Font = underline
370 | update_item the_item new_path
371 | )
372 | )
373 | )
374 | -- Remove entry
375 | on btn_2 pressed do
376 | (
377 | local strikeout = dotNetObject dotNetFont (lst_mPath.Font) font_strk
378 | local regular = dotNetObject dotNetFont (lst_mPath.Font) font_reg
379 | local itms = lst_mPath.SelectedItems.Item
380 | local itms_count = lst_mPath.SelectedItems.count
381 |
382 | for i=0 to itms_count-1 do (
383 | local the_item = itms[i]
384 | local item_path = the_item.Subitems.Item[1].Text
385 | local f_d = findItem REMOVE_PATHS item_path
386 |
387 | local save_color = the_item.ForeColor
388 | local save_Font = the_item.Font
389 | if f_d == 0 then (
390 | the_item.Font = strikeout
391 | the_item.ForeColor = removedPathColor
392 | appendIfUnique REMOVE_PATHS item_path
393 |
394 | ) else (
395 | the_item.Font = save_Font
396 | the_item.ForeColor = save_color
397 | deleteItem REMOVE_PATHS f_d
398 | )
399 | )
400 | -- format "%\n" REMOVE_PATHS
401 | )
402 | -- paste paths string
403 | on btn_8 pressed do (
404 | local roll = roll_PathEdit
405 | createDialog roll modal:true
406 | local response = roll.stored_values
407 | -- print response
408 | if isKindOf response Array then (
409 | -- commit the paths
410 | path_adder response
411 | )
412 | )
413 | -- add entry
414 | on btn_3 pressed do
415 | (
416 | local res = folder_dialog.showDialog()
417 | local the_path = folder_dialog.SelectedPath
418 |
419 | if the_path != "" then path_adder #(the_path)
420 | )
421 | -- invalid paths filter
422 | on btn_4 changed state do
423 | (
424 | if state then (
425 | items_col = lst_mPath.Items
426 | temp_listItemsCol = for i= 0 to (items_col.count)-1 where (items_col.Item[i].Subitems.Item[3].text == "OK") collect items_col.Item[i]
427 | local temp_items =
428 | for i = (items_col.count)-1 to 0 by -1 where (items_col.Item[i].Subitems.Item[3].text != "OK") collect (items_col.Item[i].Clone())
429 | lst_mPath.Items.Clear()
430 | lstV_addItem lst_mPath temp_items
431 | ) else (
432 | lstV_addItem lst_mPath temp_listItemsCol
433 | lst_mPath.Sort()
434 | )
435 | )
436 | -- remove unwanted WIP
437 | on btn_7 pressed do
438 | (
439 | local strikeout = dotNetObject dotNetFont (lst_mPath.Font) font_strk
440 | -- collect filenames
441 | -- local proc_array = TEMP_PATHS + ADD_PATHS REPLACE TEMP PATHS
442 | local origin_paths = deepcopy TEMP_PATHS
443 | join origin_paths ADD_PATHS
444 | -- search for files in folders
445 | local filenames =
446 | for f=1 to origin_paths.count collect (
447 | local temp = getfiles (origin_paths[f] + "\\*.*")
448 | local ext = #()
449 | if temp.count != 0 then (
450 | ext = for i=1 to temp.count where (getFilenameType temp[i]) != ".db" collect (getFilenameType temp[i])
451 | )
452 | ext
453 | )
454 | -- marked will contain indexes
455 | local marked = #()
456 | -- dupes will contain paths
457 | local dupes = #()
458 | -- empty folders
459 | if chk_1.checked then (
460 | local empty_folders = #()
461 | empty_folders = for a=1 to filenames.count where filenames[a].count == 0 collect a
462 | join marked empty_folders
463 | )
464 | -- not images
465 | if chk_2.checked then (
466 | local not_images = #()
467 | not_images = for b=1 to filenames.count collect (
468 | local res = 0
469 | local cnt = 1
470 | do (
471 | bsearch img_ext[cnt] filenames[b] extComparator index:&res
472 | cnt += 1
473 | ) while ((cnt < img_ext.count) and (res == 0))
474 | if res == 0 then b else continue
475 | )
476 | join marked not_images
477 | )
478 | -- not models
479 | if chk_3.checked then (
480 | local not_models = #()
481 | not_models = for c=1 to filenames.count collect (
482 | local res = 0
483 | local cnt = 1
484 | do (
485 | bsearch md_ext[cnt] filenames[c] extComparator index:&res
486 | cnt += 1
487 | ) while ((cnt < md_ext.count) and (res == 0))
488 | if res == 0 then c else continue
489 | )
490 | join marked not_models
491 | )
492 | -- other
493 | if chk_4.checked then (
494 | local ext = execute txt_1.text
495 | if isKindOf ext Array then (
496 | local other_files = #()
497 | other_files = for d=1 to filenames.count collect (
498 | local res = 0
499 | local cnt = 1
500 | do (
501 | bsearch ext[cnt] filenames[d] extComparator index:&res
502 | cnt += 1
503 | ) while ((cnt < ext.count) and (res == 0))
504 | if res == 0 then d else continue
505 | )
506 | join marked other_files
507 | )
508 | )
509 | -- duplicates
510 | if chk_dupes.checked then (
511 | local suspects = deepCopy origin_paths
512 | sort suspects
513 | -- format "suspects: %\n" suspects
514 | dupes = for i=1 to (suspects.count - 1) where (suspects[i] == suspects[i+1]) collect suspects[i]
515 | )
516 | -- process list
517 | -- get paths using collected indexes
518 | local str = dotnetclass "system.string"
519 |
520 | local temp_marked = makeUniqueArray marked
521 | local paths_list = for g=1 to temp_marked.count collect origin_paths[temp_marked[g]]
522 | -- add dupes
523 | join paths_list dupes
524 | -- find item in list, change item font
525 | for i=1 to paths_list.count do (
526 | local f_i = lst_mPath.FindItemWithText (dotNet.ValueToDotNetObject paths_list[i] str) true 0 false
527 |
528 | if f_i != undefined then (
529 | -- format "% || %\n" paths_list[i] f_i.Tag
530 | f_i.Font = strikeout
531 | f_i.ForeColor = removedPathColor
532 | )
533 | )
534 | -- add to deletion array
535 | join REMOVE_PATHS paths_list
536 | )
537 | -- accept
538 | on btn_5 pressed do (commit(); DestroyDialog roll_mPath)
539 | on btn_6 pressed do (DestroyDialog roll_mPath)
540 | on btn_open pressed do (openDir())
541 | )
542 | CreateDialog roll_mPath
543 | )
--------------------------------------------------------------------------------
/src/BUMP_ArchScaler.mcr:
--------------------------------------------------------------------------------
1 | /*
2 | ------------------------------------------------------------------------------------------------------------------------------------
3 | https://atelierbump.com
4 | Small utility to rescale nodes using an architectural scale factor.
5 | 20-22-2020
6 | ------------------------------------------------------------------------------------------------------------------------------------
7 | */
8 |
9 | macroScript BUMP_units
10 | category:"BUMP tools"
11 | buttontext:"ArchScaler"
12 | tooltip:"Small utility to rescale nodes using an architectural scale factor."
13 | (
14 | rollout roll_archsc "ArchScale"
15 | (
16 | group "Units"
17 | (
18 | spinner spn_1 "" range:[1,1000,10] type:#float fieldwidth:50 align:#left across:2
19 | radiobuttons rd_1 labels:#("cm", "inches")
20 | spinner spn_2 "" range:[1,1000,1] type:#float fieldwidth:50 align:#left across:2
21 | label lbl_u "Max units"
22 | button btn_1 "Apply" width:140 height:25
23 | )
24 | group "Factor"
25 | (
26 | spinner spn_3 "" range:[1,1000,1] type:#integer fieldwidth:50 align:#left across:3
27 | label lbl_s1 " : " align:#center
28 | spinner spn_4 "" range:[1,1000,100] type:#integer fieldwidth:50 align:#right
29 | button btn_2 "Apply" width:140 height:25
30 | )
31 | -- Decode a float value to the specified units. Note the extra steps to overcome different decimal separators than "." in wich case, the units.decodeValue will fail.
32 | fn valToUnits n unit =
33 | (
34 | local res = 1
35 | local nrType = ClassOf n
36 | if ((nrType == integer OR nrType == Float) AND ClassOf unit == string) then
37 | (
38 | local nstr = n as string
39 |
40 | if (matchPattern nstr pattern:"*.*") then (
41 | -- get the system decimal separator
42 | local sep = (dotNetClass "System.Threading.Thread").CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator
43 | if sep != "." then nstr = substituteString nstr "." sep
44 | )
45 | res = units.decodeValue (nstr + unit)
46 | )
47 | res
48 | )
49 | -- re-scale funtion. scale is applied relative to the node current scale
50 | fn scaler f =
51 | (
52 | local theScaleTM = ScaleMatrix [f, f, f]
53 | local nodes = getCurrentSelection()
54 | undo "ArchScaler" on (
55 | if nodes.count > 0 then (
56 | for i in nodes do (
57 | -- uncomment this line to reset the scale of the nodes
58 | -- i.scale = [f, f, f]
59 | i.transform = PreScale i.transform [f, f, f]
60 | )
61 | )
62 | )
63 | )
64 |
65 | on btn_1 pressed do (
66 | local unit =
67 | case rd_1.state of
68 | (
69 | 1:"cm"
70 | 2:"\""
71 | )
72 | a = (valToUnits spn_1.value unit )
73 | b = (valToUnits spn_2.value "" )
74 | f = a / b
75 |
76 | scaler (a / b)
77 | )
78 | on btn_2 pressed do (
79 | scaler ( spn_3.value / spn_4.value as float )
80 | )
81 | )
82 | on isEnabled do not roll_archsc.open
83 | on execute do CreateDialog roll_archsc
84 | )
85 |
--------------------------------------------------------------------------------
/src/BUMP_Mat_Tools.mcr:
--------------------------------------------------------------------------------
1 | /*
2 | * -------------------------------------------------------------------------------------------------------
3 | * https://atelierbump.com
4 | * Category: "BUMP tools"
5 | * last updated: 01-05-2023
6 | * MODIFY AT YOUR OWN RISK
7 | * -------------------------------------------------------------------------------------------------------
8 | * BUMP_mapLoader | Load multiple bitmapTextures to the slate material editor
9 | * BUMP_fnameToBMap | Change the names of Bitmap Textures to the name of the loaded files.
10 | * BUMP_remove_mats | Remove material from selection
11 | * BUMP_selNoMat | Filter nodes without material in current selection.
12 | * BUMP_ObjIDbyCAM | Set objects ID for current camera view
13 | * BUMP_faceSel | Select faces with same material ID
14 | * BUMP_RndIDSet | Set random material IDs for selected faces
15 | * BUMP_qIDSet | Set material IDs for selected faces
16 | * BUMP_listMtl | List materials in selection
17 | * BUMP_selByMat | Select objects with the same material as the current selection
18 | */
19 | /* Change mtl bump value */
20 | macroScript DSTLBX_bumpToOneHundred
21 | category: "BUMP tools"
22 | ButtonText: "bumpTo100"
23 | toolTip: "Material Bump value to 100"
24 | (
25 | on execute do (
26 | local warning = messageBox "Warning! this will change the bump amount value of scene materials. Works only with Vray materials for now"
27 | if warning AND VRayMtl != undefined then (
28 | -- for Vray materials only!
29 | -- TODO: Implement physical, standard, Arnold, Corona...
30 | local mats = getClassInstances VRayMtl
31 | mats = makeUniqueArray mats
32 | for m in mats where classOf (m.texmap_bump) == VRayNormalMap do m.texmap_bump_multiplier = 100.0
33 | )
34 | )
35 | )
36 | /* Load texture maps */
37 | macroScript BUMP_mapLoader
38 | category: "BUMP tools"
39 | ButtonText: "Bitmap multi-loader"
40 | toolTip: "Load multiple bitmapTextures to the slate material editor"
41 | (
42 | -- open files dialog
43 | fn GetMultiOpenFilenames caption:"Open" filename:"" types:"image Files (*.*)|*.*" default:1 =
44 | (
45 | local dlg = DotNetObject "System.Windows.Forms.OpenFileDialog"
46 | dlg.multiSelect = true
47 | dlg.title = caption
48 | local p = getFilenamePath filename
49 | if doesFileExist p then dlg.initialDirectory = p
50 | dlg.filter = types
51 | dlg.filterIndex = default
52 | local result = dlg.ShowDialog()
53 | if (result.Equals result.OK) then dlg.filenames else undefined
54 | )
55 | -- load TextureMaps
56 | fn loadTextureMaps files _gamma _basename =
57 | (
58 | for i=1 to files.count do (
59 |
60 | local _path = files[i]
61 | local tx = openBitMap _path gamma:_gamma
62 |
63 | if tx != undefined then (
64 | local map = Bitmaptexture()
65 | map.bitmap = tx
66 | map.name = _basename + (try (getFilenameFile _path ) catch ( uniqueName (getFilenameFile _path) ))
67 |
68 | local smeView = sme.GetView(SME.activeView)
69 | smeView.CreateNode map (smeView.position + [0, 0 + (40 * i - 1)])
70 | )
71 | )
72 | )
73 | rollout roll_loadbitmaps "Load bitmaps"
74 | (
75 | Group "Gamma"
76 | (
77 | radiobuttons rd_1 labels:#("Auto", "Override")
78 | spinner spn_1 "Gamma value:" range:[1.0, 100.0, 1.0] units:#float
79 | )
80 | edittext txt_1 "Name Prefix:" text:"Map_" labelOnTop:true
81 | button btn_1 "Load Maps" width:150 height:30 offset:[0,5]
82 |
83 | local
84 | _gamma, _basename
85 |
86 | on roll_loadbitmaps open do
87 | (
88 | _gamma = #Auto
89 | _basename = "Map_"
90 | )
91 | on roll_loadbitmaps close do updateToolbarButtons()
92 |
93 | on rd_1 changed index do
94 | (
95 | case index of
96 | (
97 | 1: (_gamma = #Auto)
98 | 2: ( _gamma = spn_1.value)
99 | )
100 | )
101 | on spn_1 changed val do
102 | (
103 | if _gamma != #Auto then (
104 | _gamma = val
105 | )
106 | )
107 | on btn_1 pressed do
108 | (
109 | local paths
110 | if (paths = GetMultiOpenFilenames()) != undefined then
111 | (
112 | print paths
113 | loadTextureMaps paths _gamma _basename
114 | )
115 | )
116 | )
117 | on isChecked do roll_loadbitmaps.open
118 | on execute do CreateDialog roll_loadbitmaps style:#(#style_toolwindow,#style_sysmenu)
119 | on CloseDialogs do DestroyDialog roll_loadbitmaps
120 | )
121 | /* Map - Material related tools */
122 | macroScript BUMP_fnameToBMap
123 | category: "BUMP tools"
124 | buttonText: "Map name from file"
125 | toolTip: "Change the names of Bitmap Textures to the name of the loaded files."
126 | (
127 | local msg = "This will rename all Bitmap maps to the filename of the source. Are you sure to continue?"
128 |
129 | fn renameTxtMapFromFileName =
130 | (
131 | undo "Map name from file" on (
132 | for i in (getClassInstances BitmapTexture) do (
133 | i.name = (getFilenameFile i.filename + getFilenameType i.filename)
134 | )
135 | )
136 | )
137 | on execute do
138 | (
139 | if queryBox msg then renameTxtMapFromFileName()
140 | )
141 | )
142 | /* Remove material from selection */
143 | macroScript BUMP_remove_mats
144 | category: "BUMP tools"
145 | buttonText: "Remove materials"
146 | toolTip: "Remove material from selection"
147 | (
148 | on execute do
149 | (
150 | local msg = "This will remove the materials assigned to the node selection. Are you sure to continue?"
151 | if queryBox msg then (
152 | undo "Remove materials" on (
153 | for i in selection where (isValidNode i) do i.material = undefined
154 | CompleteRedraw()
155 | )
156 | )
157 | )
158 | )
159 | /* Filter nodes without material in current selection. */
160 | macroScript BUMP_selNoMat
161 | category: "BUMP tools"
162 | buttonText: "Select nodes without material"
163 | toolTip: "Filter nodes without material in current selection."
164 | (
165 | fn SelectNoMaterial =
166 | (
167 | max create mode
168 | with redraw off
169 | (
170 | local objs = getCurrentSelection()
171 | ClearSelection()
172 | for i in objs where (i.material == undefined) do selectMore i
173 | )
174 | )
175 | on execute do SelectNoMaterial()
176 | )
177 | -- Poly - Node Id related tools
178 | macroScript BUMP_ObjIDbyCAM
179 | category: "BUMP tools"
180 | buttonText: "ID from camera"
181 | toolTip: "Set objects ID for current camera view"
182 | icon: #("Material_Modifiers",2)
183 | (
184 | fn setObjID =
185 | (
186 | local cam = getActiveCamera()
187 | if cam != undefined then (
188 | local bbx = box2 [0,0] [gw.getWinSizeX(),gw.getWinSizeY()]
189 | local objsel = boxPickNode bbx
190 | local campos = cam.pos
191 | fn compareFN v1 v2 ref: =
192 | (
193 | local a = distance ref v1.pos
194 | local b = distance ref v2.pos
195 | local d = a - b
196 | case of
197 | (
198 | (d < 0.): -1
199 | (d > 0.): 1
200 | default: 0
201 | )
202 | )
203 | qsort objsel compareFN ref:campos
204 | for i=1 to objsel.count do (
205 | objsel[i].gbufferChannel = i
206 | )
207 |
208 | )
209 | )
210 | on execute do setObjID()
211 | )
212 | /* Select faces with same material ID */
213 | macroScript BUMP_faceSel
214 | category: "BUMP tools"
215 | buttonText: "Face ID"
216 | toolTip: "Select faces with same material ID"
217 | icon: #("UVWUnwrapSelection",12)
218 | (
219 | fn EPOLY_selectMatID obj =
220 | (
221 | if obj != undefined then (
222 | if ((isKindOf obj Editable_Poly) and (subObjectLevel == 4)) then (
223 |
224 | local faceCount = polyop.getNumFaces obj
225 | local currFace = polyop.getFaceSelection obj
226 | local currFaceArr = currFace as Array
227 |
228 | if currFaceArr[1] != undefined then (
229 | local faceID = polyop.getFaceMatID obj currFaceArr[1]
230 | local tempFaces = for i=1 to faceCount where (polyop.getFaceMatID obj i == faceID) collect i
231 | polyop.setFaceSelection obj tempFaces
232 | redrawViews()
233 | )
234 | )
235 | )
236 | )
237 | On IsEnabled do Filters.Is_EditPoly()
238 | -- On IsVisible do Filters.Is_EditPoly()
239 | on execute do
240 | (
241 | local theObj = if selection[1] != undefined then selection[1] else undefined
242 | EPOLY_selectMatID theObj
243 | )
244 | )
245 | /* Set random material IDs for selected faces */
246 | macroScript BUMP_RndIDSet
247 | category: "BUMP tools"
248 | ButtonText: "Random ID Set"
249 | tooltip: "Set random material IDs for selected faces"
250 | silentErrors: true
251 | (
252 | fn randMatID obj min:1 max:5 =
253 | (
254 | if obj !=undefined then (
255 | if ((isKindOf obj Editable_Poly) and (subObjectLevel == 4)) then (
256 | local faceCount = polyop.getNumFaces obj
257 | local currFace = polyop.getFaceSelection obj
258 | local currFaceArr = currFace as Array
259 | if currFaceArr[1] != undefined then (
260 | for i in currFaceArr do polyop.setFaceMatID obj i (abs (floor (random min max)))
261 | redrawViews()
262 | )
263 | )
264 | )
265 | )
266 | on execute do try (randMatID $) catch ()
267 | )
268 | /* Set material IDs for selected faces */
269 | macroScript BUMP_qIDSet
270 | category: "BUMP tools"
271 | ButtonText: "Quick material ID Set"
272 | tooltip: "Set material IDs for selected faces"
273 | silentErrors: true
274 | (
275 | local roll_qID
276 | rollout roll_qID "Quick polygon ID set" width:200 --*height:300
277 | (
278 | -- label lblCurr "Current ID: " align:#left height:25 across:2
279 | -- label lblCurrID "10" align:#right height:25 offset:[-10,0]
280 | checkbutton utl1 "Set / Select" height:25 align:#left across:2
281 | label lbl1 "SET MODE" offset:[0,5]-- align:#right
282 | button btn1 "1" width:32 height:32 across:5
283 | button btn2 "2" width:32 height:32
284 | button btn3 "3" width:32 height:32
285 | button btn4 "4" width:32 height:32
286 | button btn5 "5" width:32 height:32
287 | button btn6 "6" width:32 height:32 across:5
288 | button btn7 "7" width:32 height:32
289 | button btn8 "8" width:32 height:32
290 | button btn9 "9" width:32 height:32
291 | button btn10 "10" width:32 height:32
292 | button btn11 "Sel. Selected face ID" width:170 height:32 align:#left offset:[0,5] enabled:false
293 |
294 | -- local str1 = "Sel. Selected face ID"
295 |
296 | mapped fn polyID obj id:1 =
297 | (
298 | if obj != undefined then (
299 | if ((isKindOf obj Editable_Poly) and (subObjectLevel == 4 OR subObjectLevel == 5)) then (
300 | local faceCount = polyop.getNumFaces obj
301 | local currFace= polyop.getFaceSelection obj
302 | local currFaceArr = currFace as Array
303 | if currFaceArr[1] != undefined then (
304 | with redraw off for i in currFaceArr do polyop.setFaceMatID obj i id
305 | redrawViews()
306 | )
307 | )
308 | )
309 | )
310 | mapped fn selectMatID obj id:1 =
311 | (
312 | if obj != undefined then (
313 | if ((isKindOf obj Editable_Poly) and (subObjectLevel == 4 OR subObjectLevel == 5)) then (
314 | local faceCount = polyop.getNumFaces obj
315 | local currFace = polyop.getFaceSelection obj
316 | -- accelerator
317 | local _getID = polyop.getFaceMatID
318 | local tempFaces = for i=1 to faceCount where (_getID obj i == id) collect i
319 | polyop.setFaceSelection obj tempFaces
320 | redrawViews()
321 | )
322 | )
323 | )
324 |
325 | fn currFaceMatID obj &faceID =
326 | (
327 | if obj != undefined then (
328 | if ((isKindOf obj Editable_Poly) and (subObjectLevel == 4)) then (
329 | local faceCount = polyop.getNumFaces obj
330 | local currFace = polyop.getFaceSelection obj
331 | local currFaceArr = currFace as Array
332 |
333 | if currFaceArr[1] != undefined then (
334 | faceID = polyop.getFaceMatID obj currFaceArr[1]
335 | local tempFaces = for i=1 to faceCount where (polyop.getFaceMatID obj i == faceID) collect i
336 | polyop.setFaceSelection obj tempFaces
337 | redrawViews()
338 | )
339 | )
340 | )
341 | )
342 |
343 | on utl1 changed state do (
344 | if state then (
345 | lbl1.text = "SELECT MODE"
346 | btn11.enabled = true
347 | ) else (
348 | lbl1.text = "SET MODE"
349 | btn11.enabled = false
350 | )
351 | -- lbl1.text = if state then "SELECT MODE" else "SET MODE"
352 | )
353 | on btn1 pressed do if utl1.checked then selectMatID $ id:1 else polyID $ id:1
354 | on btn2 pressed do if utl1.checked then selectMatID $ id:2 else polyID $ id:2
355 | on btn3 pressed do if utl1.checked then selectMatID $ id:3 else polyID $ id:3
356 | on btn4 pressed do if utl1.checked then selectMatID $ id:4 else polyID $ id:4
357 | on btn5 pressed do if utl1.checked then selectMatID $ id:5 else polyID $ id:5
358 | on btn6 pressed do if utl1.checked then selectMatID $ id:6 else polyID $ id:6
359 | on btn7 pressed do if utl1.checked then selectMatID $ id:7 else polyID $ id:7
360 | on btn8 pressed do if utl1.checked then selectMatID $ id:8 else polyID $ id:8
361 | on btn9 pressed do if utl1.checked then selectMatID $ id:9 else polyID $ id:9
362 | on btn10 pressed do if utl1.checked then selectMatID $ id:10 else polyID $ id:10
363 | on btn11 pressed do currFaceMatID $ &faceID
364 | )
365 |
366 | on isChecked do if roll_qID != undefined then roll_qID.open else false
367 | on execute do (
368 | try (
369 | if not roll_qID.open then CreateDialog roll_qID
370 | ) catch (
371 | DestroyDialog roll_qID
372 | CreateDialog roll_qID
373 | )
374 | )
375 | )
376 | /* Select by material */
377 | macroScript BUMP_selByMat
378 | category: "BUMP tools"
379 | ButtonText: "Select by Material"
380 | tooltip: "Select objects with the same material as the current selection."
381 | silentErrors: true
382 | (
383 | on execute do
384 | (
385 | -- current selection material
386 | local mats = for i in (getCurrentSelection()) where i.material != undefined collect i.material
387 | -- unique array of materials
388 | makeuniquearray mats
389 | -- look for objects with the same material
390 | local sim = for i in objects where findItem mats i.material collect i
391 | -- select the resul
392 | if sim.count > 0 then select sim
393 | )
394 | )
395 | /* List materials in selection */
396 | macroScript BUMP_listMtl
397 | category: "BUMP tools"
398 | ButtonText: "List Materials"
399 | tooltip: "List materials of selected nodes"
400 | silentErrors: true
401 | (
402 | fn listMats sel =
403 | (
404 | local mats = #()
405 | local undef = #()
406 | for i in sel do
407 | (
408 | if i.material != undefined then (
409 | appendIfUnique mats i.material
410 | ) else (
411 | -- print (classof i)
412 | append undef i
413 | )
414 | )
415 | for m in mats do format "% :: %\n" m.name (classof m)
416 | if undef.count > 0 then (
417 | format "Undefined Materials at:\n"
418 | for u in undef do format "% :: %\n" u.name (classof u)
419 | select undef
420 | )
421 | OK
422 | )
423 |
424 | on execute do
425 | (
426 | listMats $
427 | )
428 | )
429 | /*
430 | -- Max UI related tools
431 | macroScript TrackbarToggle
432 | category: "BUMP tools"
433 | buttonText: "Toggle Trackbar"
434 | toolTip: "Toggle Timeslider and Trackbar"
435 | Icon: #("TrackViewStatus",11)
436 | (
437 | on isChecked do not (timeslider.isVisible())
438 | on execute do
439 | (
440 | timeslider.setvisible (not timeslider.isVisible())
441 | )
442 | )
443 | */
--------------------------------------------------------------------------------
/src/BUMP_Random_select.mcr:
--------------------------------------------------------------------------------
1 | /*
2 | ------------------------------------------------------------------------------------------------------------------
3 | Random object selection
4 | ------------------------------------------------------------------------------------------------------------------
5 | */
6 | macroScript BUMP_RndSel
7 | category: "BUMP tools"
8 | ButtonText: "Random Select"
9 | toolTip: "Select random nodes"
10 | silentErrors: true
11 | (
12 | -- Percent: Keep a random percentage of the total quantity of nodes in the current selection.
13 | fn rndItemsPercent c p =
14 | (
15 | local itms_count = floor (c * p) as integer
16 | local res = #()
17 | for i = 1 to itms_count do (
18 | local r = random 1 c
19 | if ((findItem res r) != 0) then
20 | (
21 | do ( r = random 1 c ) while ((findItem res d) != 0)
22 | )
23 | append res r
24 | )
25 | sort res
26 | res
27 | )
28 | -- Subtract: Same as percent, but inverse: deselect a random percentage within selection.
29 | fn rndItemsSubstr c p =
30 | (
31 | local itms_count = c - ( ceil (c * p) as integer )
32 | local res = #()
33 | if ( itms_count > 0) then (
34 | for i = 1 to itms_count do (
35 | local r = random 1 c
36 | if ((findItem res r) != 0) then
37 | (
38 | do ( r = random 1 c ) while ((findItem res d) != 0)
39 | )
40 | append res r
41 | )
42 | )
43 | sort res
44 | res
45 | )
46 | -- Step: Performs a skip pattern in the selection.
47 | fn rndItemsStep c s =
48 | (
49 | local res
50 | if s < (c/2) then (
51 | local bits = #{1..c}
52 | for i = 1 to bits.count by s where ((random 0 1) == 1) do bits[i] = false
53 | res = bits as Array
54 | sort res
55 | ) else ( res = #() )
56 | res
57 | )
58 | -- Pattern: Not a random mode; Instead it wil unselect nodes following a pattern.
59 | fn selPattern sel c st qn =
60 | (
61 | local res = #()
62 | local delta = st + qn
63 | if delta < c then (
64 | for i=1 to (c - delta) by delta do (
65 | local tmp = for f = 1 to st collect sel[i+f]
66 | join res tmp
67 | )
68 | )
69 | res
70 | )
71 | -- main UI
72 | rollout roll_rndSel "Random selection"
73 | (
74 | group "Mode"
75 | (
76 | radioButtons rd_1 labels:#("Percent","Step", "Subtract", "Pattern") columns:2
77 | )
78 | group "Values"
79 | (
80 | spinner spn_1 "Percent" range:[1,100,50] type:#integer fieldWidth:(roll_rndSel.width/2) align:#right
81 | spinner spn_2 "Step" range:[1,1000,1] type:#integer fieldWidth:(roll_rndSel.width/2) align:#right enabled:false
82 | spinner spn_3 "Subtr. %" range:[0,99,50] type:#integer fieldWidth:(roll_rndSel.width/2) align:#right enabled:false
83 | )
84 | group "Pattern"
85 | (
86 | spinner spn_4 "Keep" range:[1,100,1] type:#integer fieldWidth:(roll_rndSel.width/2) align:#right enabled:false
87 | spinner spn_5 "Quit" range:[1,1000,1] type:#integer fieldWidth:(roll_rndSel.width/2) align:#right enabled:false
88 | )
89 | button btn_1 "Select Random" height:30 width:(roll_rndSel.width - 25)
90 | button btn_2 "Re-Select" height:30 width:(roll_rndSel.width - 25)
91 | -- button btn_2 "Done" height:30 width:(roll_rndSel.width - 25)
92 | -----------------------------------------
93 | local mode = 1,
94 | sel, sel_count
95 | -----------------------------------------
96 | fn rndSel s c x mode:1 =
97 | (
98 | local rnd, res
99 | rnd = case mode of
100 | (
101 | 1: ( rndItemsPercent c (x * 0.01) )
102 | 2: ( rndItemsStep c x )
103 | 3: ( rndItemsSubstr c (x * 0.01) )
104 | )
105 | if rnd.count > 0 then (
106 | res = for i = 1 to rnd.count where (isValidNode s[rnd[i]]) collect s[rnd[i]]
107 | ) else (
108 | res = for i = 1 to s.count where (isValidNode s[i]) collect s[i]
109 | )
110 | res
111 | )
112 | fn test_sel =
113 | (
114 | sel = getCurrentSelection()
115 | if sel.count != 0 then
116 | sel_count = sel.count
117 | else
118 | messageBox "Select some nodes!"
119 | OK
120 | )
121 | -----------------------------------------
122 | on roll_rndSel open do (
123 | max create mode
124 | test_sel()
125 | )
126 | on rd_1 changed state do
127 | (
128 | mode = state
129 | case state of (
130 | 1: (
131 | spn_1.enabled = true
132 | spn_2.enabled = false
133 | spn_3.enabled = false
134 | spn_4.enabled = false
135 | spn_5.enabled = false
136 | )
137 | 2: (
138 | spn_1.enabled = false
139 | spn_2.enabled = true
140 | spn_3.enabled = false
141 | spn_4.enabled = false
142 | spn_5.enabled = false
143 | )
144 | 3: (
145 | spn_1.enabled = false
146 | spn_2.enabled = false
147 | spn_3.enabled = true
148 | spn_4.enabled = false
149 | spn_5.enabled = false
150 | )
151 | 4: (
152 | spn_1.enabled = false
153 | spn_2.enabled = false
154 | spn_3.enabled = false
155 | spn_4.enabled = true
156 | spn_5.enabled = true
157 | )
158 | )
159 | )
160 | on spn_1 changed val do
161 | (
162 | if sel.count == 0 then test_sel() else select (rndSel sel sel_count val mode:1)
163 | )
164 | on spn_2 changed val do
165 | (
166 | if sel.count == 0 then test_sel() else select (rndSel sel sel_count val mode:2)
167 | )
168 | on spn_3 changed val do
169 | (
170 | if sel.count == 0 then test_sel() else select (rndSel sel sel_count val mode:3)
171 | )
172 | on spn_4 changed val do
173 | (
174 | if sel.count == 0 then test_sel() else select (selPattern sel sel_count val spn_5.value)
175 | )
176 | on spn_5 changed val do
177 | (
178 | if sel.count == 0 then test_sel() else select (selPattern sel sel_count spn_4.value val)
179 | )
180 | on btn_1 pressed do
181 | (
182 | if sel.count == 0 then test_sel()
183 | else
184 | (
185 | case mode of (
186 | 1: ( select (rndSel sel sel_count spn_1.value mode:1) )
187 | 2: ( select (rndSel sel sel_count spn_2.value mode:2) )
188 | 3: ( select (rndSel sel sel_count spn_3.value mode:3) )
189 | 4: ( select selPattern sel sel_count spn_4.value spn_5.value )
190 | )
191 | )
192 | )
193 | on btn_2 pressed do (
194 | -- DestroyDialog roll_rndSel
195 | test_sel()
196 |
197 | )
198 | )
199 |
200 | on execute do (
201 | CreateDialog roll_rndSel
202 | )
203 | )
--------------------------------------------------------------------------------
/src/BUMP_align_assets.mcr:
--------------------------------------------------------------------------------
1 | /*
2 | * -------------------------------------------------------------------------------------------------------
3 | * Align Assets
4 | * MODIFY AT YOUR OWN RISK
5 | * atelierbump@gmail.com
6 | * Category: "BUMP tools"
7 | * 11-3-2018 - Fixed repostion of Groups and Parented Nodes
8 | * -------------------------------------------------------------------------------------------------------
9 | */
10 | macroscript BUMP_line_assets
11 | category:"BUMP tools"
12 | buttonText:"ALN"
13 | tooltip:"Put assets in line"
14 | Icon:#("AutoGrid",2)
15 | (
16 | fn lineAssets objs gap:20.0 axis:x_axis =
17 | (
18 | if objs != undefined then (
19 | local baseP = pickPoint promt:"Pick reference point"
20 | if isKindOf baseP point3 then (
21 | local wrld_TM = matrix3 1
22 | local prevPoint = [0.0,0.0,0.0]
23 | -- Filter Objs Parent
24 | local obj_col = #()
25 |
26 | for i=1 to objs.count where ( isValidNode objs[i] ) do (
27 | local curr = objs[i]
28 | appendIfUnique obj_col (if curr.parent != undefined then curr.parent else curr)
29 | )
30 |
31 | for i=1 to obj_col.count do (
32 | local
33 | _obj = obj_col[i],
34 | objTM = _obj.objecttransform,
35 | savepivot = _obj.pivot * inverse objTM,
36 | bx = in coordsys _obj nodeLocalBoundingBox _obj,
37 | bx1_abs = [abs bx[1].x, abs bx[1].y, abs bx[1].z],
38 | bx2_abs = [abs bx[2].x, abs bx[2].y, abs bx[2].z]
39 | /*
40 | bx1_abs = [objs[i].min.x, objs[i].min.y, objs[i].min.z],
41 | bx2_abs = [objs[i].max.x, objs[i].max.y, objs[i].max.z]
42 | */
43 | _obj.pivot = [_obj.center.x, _obj.center.y, _obj.min.z]
44 | if i < 2 then (
45 | _obj.pos = baseP
46 | local objNewTM = _obj.objecttransform
47 | _obj.pivot = (savepivot * objNewTM)
48 | prevPoint = bx2_abs + gap
49 | ) else (
50 | local p = baseP + ((prevPoint + bx1_abs) * axis)
51 | _obj.pos = p
52 | local objNewTM = _obj.objecttransform
53 | _obj.pivot = (savepivot * objNewTM)
54 | prevPoint += (bx1_abs + bx2_abs) + gap
55 | )
56 | )
57 | )
58 | )
59 | )
60 | rollout roll_aline "Put assets in line"
61 | (
62 | spinner spn_gap "Separation: " type:#Worldunits range:[-1000000.0,1000000.0,20.0] width:(roll_aline.width - 10.0) align:#center
63 | imgTag sep1 width:(roll_aline.width) height:1 bitmap:(bitmap 1 2 color: (color 5 5 5)) offset:[0,5] align:#center
64 | radiobuttons rd_ax "Direction:" labels:#("X axis","Y axis") width:(roll_aline.width - 10.0) align:#left
65 | imgTag sep2 width:(roll_aline.width) height:1 bitmap:(bitmap 1 2 color: (color 5 5 5)) offset:[0,5] align:#center
66 | button btn_ok "Apply" height:30 width:(roll_aline.width - 10.0) align:#center
67 | on btn_ok pressed do (
68 | if $ != undefined then (
69 | local the_ax = case (rd_ax.state) of
70 | (
71 | 1: x_axis
72 | 2: y_axis
73 | )
74 | undo on ( lineAssets $ axis:the_ax gap:(spn_gap.value) )
75 | )
76 | )
77 | )
78 | on execute do ( createDialog roll_aline )
79 | )
--------------------------------------------------------------------------------
/src/BUMP_audit-materials.ms:
--------------------------------------------------------------------------------
1 | (
2 | /*
3 | FILTER SELECTION BY MATERIAL CLASS
4 | The algortihm will look 1-level deep in MultiMaterials
5 | 1 - Start by selecting the nodes you want to filter
6 | */
7 | clearListener()
8 | local mtlClass = VRayMtl ---> 2 - THE TYPE OF MATERIAL YOU WANT TO EXCLUDE IN THE SEARCH
9 | local listOfObjs = #()
10 | for o in selection where ClassOf o.material != mtlClass do (
11 | if ClassOf o.material == MultiMaterial then (
12 | local hasinvalidMtl = false
13 | for m in o.Material.materialList while ClassOf m != mtlClass do hasinvalidMtl = true
14 | if hasinvalidMtl then (
15 | format "% || %\n" o.name o.material
16 | append listOfObjs o
17 | )
18 | ) else (
19 | format "% || %\n" o.name o.material
20 | append listOfObjs o
21 | )
22 | )
23 | clearSelection()
24 | select listOfObjs
25 | )
26 |
--------------------------------------------------------------------------------
/src/BUMP_camManager.mcr:
--------------------------------------------------------------------------------
1 | /*
2 | * -------------------------------------------------------------------------------------------
3 | * Camera Manager - FREE VERSION. COMPLETE VERSION IS PART OF DESIGTOOLBOX
4 | * htpps://atelierbump.com
5 | * Bump 2019-2022
6 | * rev 1.5 03/06/2019
7 | * 02-2021
8 | * 01-2022
9 | * Added Shutter parameters, reordered parameters, changed presets to common aspect ratios
10 | * -------------------------------------------------------------------------------------------
11 | */
12 | macroScript BUMP_CamMngr
13 | category: "BUMP tools"
14 | ButtonText: "Camera manager"
15 | tooltip: "Manage Cameras and render batch views"
16 | silentErrors: false
17 | icon: #("extratools", 1)
18 | (
19 | struct camManagerTool
20 | (
21 | CamFloater,
22 | dialog_width = 250,
23 | Active_preview = false,
24 | roll_Cams,
25 | roll_Batch,
26 | roll_active,
27 | private
28 | /* CAMS ROLLOUT */
29 | fn ui_cams =
30 | (
31 | rollout roll_Cams "Camera Manager"
32 | (
33 | local roll_w = 250 --roll_Cams.width
34 | local owner = if owner != undefined then owner
35 | --------------------------------
36 | group "Active Camera"
37 | (
38 | label lbl_cam "" align:#left height:25 offset:[0,5]
39 | )
40 |
41 | group "Scene cameras"
42 | (
43 | listbox lst_cams "" height:8
44 | button btn_prev_cam "<<" width:60 align:#left across:3
45 | tooltip:"Previous camera"
46 | button btn_s "Select" width:80 align:#center
47 | tooltip:"Select active camera"
48 | button btn_next_cam ">>" width:60 align:#right
49 | tooltip: "Nex camera"
50 | )
51 |
52 | button btn_1 "Refresh" height:25 width:(roll_w - 25)
53 | tooltip:"Update scene cameras list"
54 |
55 | group "Parameters"
56 | (
57 | --LENS
58 | label lbl_fl "Focal length" align:#left across:2
59 | spinner spn_fl "mm" fieldWidth:70 align:#right
60 | checkbox chk_fov "Use FOV" align:#left across:2
61 | spinner spn_fov "FOV" fieldWidth:70 align:#right
62 | -- APERTURE
63 | checkbox chk_dof "Enable DOF" across:2
64 | spinner spn_f "f-" align:#right fieldWidth:70 align:#right
65 | checkbox chk_tilt "Perspective: Auto Vertical Tilt"
66 | -- EV
67 | label lbl_ex "Exposure:" align:#left
68 | radiobuttons rd_ex labels:#("Manual", "Target") align:#left offsets:#([0,0], [80,0])
69 | -- SHUTTER
70 | dropdownList drp_ev "Shutter" items:#("1 / seconds", "seconds", "degrees", "frames") width:112 align:#left across:2
71 | -- EV
72 | spinner spn_ev "EV" range:[0,1.0E6,6] fieldWidth:80 align:#right offset:[0,20]
73 | -- SHUTTER
74 | spinner spn_sh "Duration" range:[0,1.0E6,100] fieldWidth:60 align:#left
75 | -- SENSOR
76 | spinner spn_iso "ISO" range:[0,1.0E6,100] fieldWidth:60 align:#left offset:[23,0]
77 | )
78 |
79 | group "Output size"
80 | (
81 | spinner spn_w "Width" type:#integer range:[1,1000000,100] fieldwidth:65 align:#right across:2
82 | spinner spn_r "Ratio" type:#float range:[0.0,6.0,1.33] fieldwidth:65 align:#right
83 | spinner spn_h "Height" type:#integer range:[1,1000000,100] fieldwidth:65 align:#right across:2
84 | checkButton chk_ratio "LOCK" height:18 width:75 align:#right
85 | label lbl_presets "Presets" align:#left
86 |
87 | button p1 "9:16" width:40 across:5
88 | button p2 "2:3" width:40
89 | button p3 "4:5" width:40
90 | button p4 "3:4" width:40
91 | button p5 "1:1" width:40
92 | button p6 "4:3" width:40 across:5
93 | button p7 "16:10" width:40
94 | button p8 "16:9" width:40
95 | button p9 "2:1" width:40
96 | button p10 "21:9" width:40
97 | )
98 | --------------------------------
99 | local active_cam
100 | local list_cam
101 | local curr_itm = 1
102 | local ratios = #(0.5625, 0.666667, 0.8, 0.75, 1.0, 1.33333, 1.6, 1.77778, 2.0, 2.37037)
103 | --------------------------------
104 | /* Store Resolution settings in camera */
105 | fn set_cam_res cam w h r =
106 | (
107 | if isValidNode cam then (
108 | setUserProp cam "w_res" w
109 | setUserProp cam "h_res" h
110 | setUserProp cam "aspect_ratio" r
111 | )
112 | )
113 | /* Set default aspect ratio */
114 | -- fn set_def_aspect cam r = ()
115 |
116 | /* Get stored cam resolution */
117 | fn get_cam_res cam &width &height &ratio =
118 | (
119 | if isValidNode cam then (
120 |
121 | local
122 | w = getUserProp cam "w_res",
123 | h = getUserProp cam "h_res",
124 | r = getUserProp cam "aspect_ratio"
125 |
126 | width = if w != undefined then w as integer --else undefined
127 | height = if h != undefined then h as integer --else undefined
128 | ratio = if r != undefined then r as float --else undefined
129 | )
130 | )
131 | /* Physical camera PROPERTIES */
132 | fn shutterType2Values cam =
133 | (
134 | case drp_ev.selection of (
135 | 1: (spn_sh.value = 1.0 / cam.shutter_length_seconds)
136 | 2: (spn_sh.value = cam.shutter_length_seconds)
137 | 3: (spn_sh.value = cam.shutter_length_frames * 360)
138 | 4: (spn_sh.value = cam.shutter_length_frames)
139 | )
140 | )
141 | fn shutterValue cam val =
142 | (
143 | case drp_ev.selection of (
144 | 1: (cam.shutter_length_seconds = val / 1.0)
145 | 2: (cam.shutter_length_seconds = val)
146 | 3: (cam.shutter_length_frames = val / 360)
147 | 4: (cam.shutter_length_frames = val)
148 | )
149 | )
150 | fn get_camprops cam =
151 | (
152 | if classOf cam == Physical then
153 | (
154 | -- Lens
155 | spn_fl.enabled = NOT cam.specify_fov
156 | spn_fov.enabled = cam.specify_fov
157 |
158 | spn_fl.value = cam.focal_length_mm
159 | spn_fov.value = cam.fov
160 | chk_fov.state = cam.specify_fov
161 |
162 | chk_dof.state = cam.use_dof
163 | spn_f.value = cam.f_number
164 | chk_tilt.state = cam.auto_vertical_tilt_correction
165 | --shutter
166 | drp_ev.selection = cam.shutter_unit_type + 1
167 | shutterType2Values cam
168 | -- EV
169 | rd_ex.state = cam.exposure_gain_type + 1
170 | case cam.exposure_gain_type of
171 | (
172 | 0:(spn_iso.enabled = true; spn_ev.enabled = false)
173 | 1:(spn_iso.enabled = false; spn_ev.enabled = true)
174 | )
175 | spn_iso.value = cam.iso
176 | spn_ev.value = cam.exposure_value
177 | )
178 | )
179 | /* DEPRECATED */
180 | fn set_camprops cam =
181 | (
182 | if classOf cam == Physical then
183 | (
184 | -- Lens
185 | cam.specify_fov = chk_fov.state
186 | cam.focal_length_mm = spn_fl.value
187 | cam.fov = spn_fov.value
188 |
189 | cam.use_dof = chk_dof.state
190 | cam.f_number = spn_f.value
191 | cam.auto_vertical_tilt_correction = chk_tilt.state
192 |
193 | -- shutter
194 | cam.shutter_unit_type = drp_ev.selection - 1
195 | shutterValue cam spn_sh.value
196 | -- EV
197 | cam.exposure_gain_type = rd_ex.state - 1
198 | case cam.exposure_gain_type of
199 | (
200 | 0: (cam.iso = spn_iso.value)
201 | 1: (cam.exposure_value = spn_ev.value)
202 | )
203 | spn_iso.value = cam.iso
204 | spn_ev.value = cam.exposure_value
205 | )
206 | )
207 | fn set_camprop cam prop val =
208 | (
209 | if classOf cam == Physical AND isProperty cam prop then (
210 | setProperty cam prop val
211 | )
212 | )
213 | /* GET RENDER RES VALUES */
214 | fn get_output_values =
215 | (
216 | spn_w.value = renderWidth
217 | spn_h.value = renderHeight
218 | spn_r.value = rendImageAspectRatio
219 | )
220 | /* CHANGE RENDER RATIO */
221 | fn set_output_ratio val =
222 | (
223 | if renderSceneDialog.isOpen() then renderSceneDialog.close()
224 | rendImageAspectRatio = val
225 | spn_w.value = renderWidth
226 | spn_h.value = renderHeight
227 | CompleteRedraw()
228 | )
229 | /* CHANGE RENDER RESOLUTION */
230 | fn set_output_res w h =
231 | (
232 | if renderSceneDialog.isOpen() then renderSceneDialog.close()
233 | if w != undefined then renderWidth = w
234 | if h != undefined then renderHeight = h
235 | spn_r.value = rendImageAspectRatio
236 | redrawViews()
237 | )
238 | /* SELECT ACTIVE CAMERA */
239 | fn selCam n =
240 | (
241 | max modify mode
242 | if isValidNode n then select n
243 | )
244 | /* LIST CAMERAS IN SCENE */
245 | fn listCameras =
246 | (
247 | for cam in cameras collect #(cam, cam.name)
248 | )
249 | /* UPDATE CAMERA LIST */
250 | fn relist_cams =
251 | (
252 | list_cam = listCameras()
253 | lst_cams.items = for i in list_cam where (isKindOf i[1] camera) collect i[2]
254 | -- local only_names = for i in list_cam where (isKindOf i[1] camera) collect i[2]
255 | -- local only_cams = for i in list_cam where (isKindOf i[1] camera) collect i[1]
256 | -- lst_cams.items = only_names
257 | )
258 | /* GET THE ACTIVE CAMERA */
259 | fn change_active =
260 | (
261 | if active_cam == undefined then active_cam = getActiveCamera()
262 | --active_cam = getActiveCamera()
263 | if active_cam != undefined then (
264 | -- camera properties
265 | get_camprops active_cam
266 | -- load camera custom resolution AND assign to render settings
267 | get_cam_res active_cam &w &h &r
268 |
269 | if w != undefined AND h != undefined then (
270 | -- Check if active preview is enabled
271 | if NOT owner.Active_preview then (
272 | set_output_res w h
273 | get_output_values()
274 | )
275 | lbl_cam.text = active_cam.name + "(" + w as string + "x" + h as string + ")" + "@" + r as string
276 | ) else (
277 | lbl_cam.text = active_cam.name
278 | )
279 | ) else (
280 | lbl_cam.text = "None"
281 | )
282 | RedrawViews()
283 | )
284 | /* SET ACTIVE CAMERA IN VIEWPORT */
285 | fn setActiveCam n =
286 | (
287 | if n != undefined then (
288 | local cam = if (isKindOf n string) then ( getNodeByName n) else n
289 |
290 | if isValidNode cam AND (isKindOf cam camera) then (
291 | if viewport.CanSetToViewport cam then viewport.SetCamera cam
292 | active_cam = cam
293 | -- update
294 | change_active()
295 | )
296 | )
297 | )
298 | --------------------------------
299 | on roll_Cams open do
300 | (
301 | change_active()
302 | relist_cams()
303 | get_output_values()
304 | chk_ratio.checked = rendLockImageAspectRatio
305 | )
306 | on roll_Cams close do updateToolbarButtons()
307 | /* SELECT CAMERA */
308 | on btn_s pressed do ( selCam active_cam )
309 | /* PREVIOUS CAMERA */
310 | on btn_prev_cam pressed do
311 | (
312 | if curr_itm > 1 then curr_itm -=1
313 | lst_cams.selection = curr_itm
314 | setActiveCam lst_cams.selected
315 |
316 | owner.roll_batch.view_settings()
317 | )
318 | /* NEXT CAMERA */
319 | on btn_next_cam pressed do
320 | (
321 | if curr_itm < lst_cams.items.count then curr_itm +=1
322 | lst_cams.selection = curr_itm
323 | setActiveCam lst_cams.selected
324 |
325 | owner.roll_batch.view_settings()
326 | )
327 | /* CHANGE ACTIVE CAMERA */
328 | on lst_cams selected item do
329 | (
330 | curr_itm = item
331 | setActiveCam lst_cams.selected
332 |
333 | owner.roll_batch.view_settings()
334 | )
335 | /* CAMERA PARAMETERS*/
336 | -- Lens
337 | on chk_fov changed state do
338 | (
339 | spn_fl.enabled = NOT state
340 | spn_fov.enabled = state
341 | set_camprop active_cam #specify_fov state
342 | )
343 | on spn_lf changed val do set_camprop active_cam #focal_length_mm val
344 | on spn_fov changed val do set_camprop active_cam #fov val
345 | on chk_dof changed state do set_camprop active_cam #use_dof state
346 | on chk_tilt changed state do set_camprop active_cam #auto_vertical_tilt_correction state
347 | -- Shutter
348 | on drp_ev selected idx do (
349 | shutterType2Values active_cam
350 | set_camprop active_cam #shutter_unit_type (idx - 1)
351 | )
352 | on spn_sh changed val do shutterValue active_cam val
353 | -- EV
354 | on rd_ex changed state do
355 | (
356 | case state of
357 | (
358 | 1:(spn_iso.enabled = true; spn_ev.enabled = false)
359 | 2:(spn_iso.enabled = false; spn_ev.enabled = true)
360 | )
361 | set_camprop active_cam #exposure_gain_type (state - 1)
362 | )
363 | on spn_iso changed val do set_camprop active_cam #iso val
364 | on spn_ev changed val do set_camprop active_cam #exposure_value val
365 | /* REFRESH CAM LIST */
366 | on btn_1 pressed do (
367 | change_active()
368 | relist_cams()
369 | )
370 | /* LOCK STATUS OF RENDER RATIO */
371 | on chk_ratio changed status do (
372 | rendLockImageAspectRatio = status
373 | )
374 | /* CHANGE RENDER OUTPUT */
375 | on spn_w changed val do (
376 |
377 | if chk_ratio.checked then spn_h.value = floor(val/spn_r.value)
378 | -- set_output_res val undefined
379 | set_output_res val spn_h.value
380 | -- save values in camera
381 | set_cam_res active_cam val spn_h.value spn_r.value
382 | -- change_active()
383 | )
384 | /* CHANGE RENDER HEIGHT */
385 | on spn_h changed val do (
386 | if chk_ratio.checked then spn_w.value = floor(val*spn_r.value)
387 | set_output_res spn_w.value val
388 | -- save values to camera
389 | set_cam_res active_cam spn_w.value val spn_r.value
390 | -- change_active()
391 | )
392 | /* CHANGE RENDER WIDTH */
393 | on spn_r changed val do (
394 | set_output_ratio val
395 | -- save values to camera
396 | set_cam_res active_cam spn_w.value spn_h.value val
397 | -- change_active()
398 | )
399 | /* IMAGE RATIO PRESETS */
400 | fn preset val =
401 | (
402 | set_output_ratio (spn_r.value = val)
403 | -- save values to camera
404 | set_cam_res active_cam spn_w.value spn_h.value spn_r.value
405 | change_active()
406 | )
407 | /* PRESETS */
408 | on p1 pressed do preset ratios[1]
409 | on p2 pressed do preset ratios[2]
410 | on p3 pressed do preset ratios[3]
411 | on p4 pressed do preset ratios[4]
412 | on p5 pressed do preset ratios[5]
413 | on p6 pressed do preset ratios[6]
414 | on p7 pressed do preset ratios[7]
415 | on p8 pressed do preset ratios[8]
416 | on p9 pressed do preset ratios[9]
417 | on p10 pressed do preset ratios[10]
418 | /*------------------------------ ROLLOUT END ------------------------------*/
419 | )
420 | roll_Cams
421 | ),
422 | /* BATCH ROLLOUT */
423 | fn ui_batch =
424 | (
425 | rollout roll_batch "Batch Render"
426 | (
427 | local roll_w = 250
428 | local owner = if owner != undefined then owner
429 | --------------------------------
430 | group "Batch views"
431 | (
432 | listbox lst_views "Batch Views" height:5
433 | edittext txt_1 "View name" fieldWidth:(roll_w - 25) bold:true labelOnTop:true
434 | edittext txt_3 "File name" fieldWidth:(roll_w - 25) labelOnTop:true
435 | edittext txt_2 "Output" fieldWidth:(roll_w - 60) labelOnTop:true across:2
436 | button btn_p "..." align:#right offset:[0,15] tooltip:"Change path"
437 | checkbox chk_1 "Override output size in view" align:#left \
438 | tooltip:"Set active render output size as view override"
439 | button btn_v "Add View to batch" width:(roll_w - 80) height:25 align:#left across:2
440 | button btn_rem "Delete" height:25 align:#right
441 | )
442 | button btn_bup "Refresh" width:(roll_w - 70) height:25 align:#left
443 | tooltip:"Update the views list"
444 | button btn_b "Open Batch window" width:(roll_w - 70) height:25 align:#left
445 | --------------------------------
446 | local batch_view
447 | local view_name = ""
448 | local view_path = undefined
449 | local active_view = undefined
450 | --------------------------------
451 | /* FIND ITEM IN LIST */
452 | fn findItemInList item lst =
453 | (
454 | local idx = FindItem lst.Items item
455 | if idx != 0 then lst.selection = idx
456 | )
457 | /* SET VIEW OUT PATH */
458 | fn SetViewPath the_view =
459 | (
460 | if view_path != undefined then the_view.outputFilename = view_path
461 | )
462 | /* UPDATE BITMAP FILENAME */
463 | fn update_Path cam: =
464 | (
465 | if view_path != undefined then (
466 | txt_2.text = getFilenamePath view_path
467 | txt_3.text = filenameFromPath view_path
468 | ) else (
469 | txt_2.text = ""
470 | txt_3.text = ""
471 | )
472 | )
473 | /* LIST BATCH VIEWS */
474 | fn list_views =
475 | (
476 | local gv = batchRenderMgr.GetView
477 | local num = batchRenderMgr.numViews
478 | local col = for i=1 to num collect (
479 | local the_view = gv i
480 | local st = if the_view.enabled then "[x] " else "[o] "
481 | st+the_view.name
482 | )
483 | lst_views.items = col
484 | )
485 | /* LOAD VIEW PROPS */
486 | fn get_view_params index =
487 | (
488 | local the_view = try (batchRenderMgr.GetView index) catch undefined
489 | if the_view != undefined then (
490 | txt_1.text = the_view.name
491 | local cam = the_view.camera
492 | if isValidNode cam then (
493 | owner.roll_Cams.setActiveCam cam
494 | -- SET CAM IN LIST
495 | findItemInList cam.name owner.roll_Cams.lst_cams
496 | -- Get the view Path
497 | if the_view.outputFilename != undefined then (
498 | txt_2.text = getFilenamePath the_view.outputFilename
499 | txt_3.text = filenameFromPath the_view.outputFilename
500 | )
501 | )
502 | -- SET RENDER OUTPUT TO THE VIEW OVERRIDE, USEFUL TO SEE THE CROP FRAME ETC...
503 | if the_view.overridePreset then (
504 | renderWidth = the_view.width
505 | renderHeight = the_view.height
506 | owner.roll_Cams.get_output_values()
507 | )
508 | CompleteRedraw()
509 | )
510 | the_view
511 | )
512 | /* LOAD VIEW PROPS */
513 | fn view_settings =
514 | (
515 | local temp_cam = owner.roll_Cams.active_cam
516 | if (temp_cam != undefined) then (
517 | txt_1.text = temp_cam.name + "-" + (rendImageAspectRatio as string)
518 | if (view_path != undefined) then (
519 | local root = getFilenamePath view_path
520 | local type = getFilenameType view_path
521 | local filename = filenameFromPath view_path
522 |
523 | local comp_filename = temp_cam.name + type
524 | for i in owner.roll_Cams.list_cam do (
525 | local n = i[2]
526 | local f = matchPattern filename pattern:("*"+n+"*")
527 | if f then (
528 | local filename_parse = findString filename n
529 | comp_filename = replace filename filename_parse (n.count) temp_cam.name
530 | exit
531 | )
532 | )
533 | -- compose Path
534 | view_path = pathConfig.appendPath root comp_filename
535 | )
536 | update_Path()
537 | )
538 | )
539 | /* ADD VIEW */
540 | fn view_add =
541 | (
542 | local temp_cam = owner.roll_Cams.active_cam
543 | if temp_cam != undefined then (
544 | if (batchRenderMgr.FindView txt_1.text) == 0 then (
545 | local new_view = batchRenderMgr.CreateView temp_cam
546 | if (new_view.overridePreset = chk_1.state) then (
547 | new_view.width = renderWidth
548 | new_view.height = renderHeight
549 | )
550 | new_view.name = txt_1.text
551 | new_view.outputFilename = view_path
552 | list_views()
553 | ) else messageBox "View Already exist.\nChange name AND try again."
554 | )
555 | )
556 | --------------------------------
557 | on roll_batch open do
558 | (
559 | view_settings()
560 | list_views()
561 | )
562 |
563 | on roll_batch rolledUp state do (
564 | if NOT state then (
565 | owner.CamFloater.size.y -= roll_batch.height
566 | ) else (
567 | owner.CamFloater.size.y += roll_batch.height
568 | )
569 | )
570 | --------------------------------
571 | /* GET BATCH VIEW PARAMS */
572 | on lst_views selected item do ( active_view = get_view_params item )
573 | /* SET VIEW OUTPUT */
574 | on btn_p pressed do
575 | (
576 | if (view_path = getBitmapSaveFileName()) != undefined then (
577 | update_Path()
578 | if active_view != undefined then (
579 | SetViewPath active_view
580 | )
581 | )
582 | )
583 | /* ADD VIEW */
584 | on btn_v pressed do ( view_add() )
585 | /* DELETE VIEW */
586 | on btn_rem pressed do
587 | (
588 | if (queryBox "Confirm view Deletion?") then (
589 | if active_view != undefined then (
590 | batchRenderMgr.DeleteView lst_views.selection
591 | -- refresh list
592 | batch_view = undefined
593 | view_name = ""
594 | -- view_path = undefined
595 | active_view = undefined
596 | list_views()
597 | )
598 | )
599 | )
600 | /* UPDATE BATCH VIEWS LIST */
601 | on btn_bup pressed do
602 | (
603 | batch_view = undefined
604 | view_name = ""
605 | -- view_path = undefined
606 | active_view = undefined
607 | list_views()
608 | )
609 | /* OPEN RENDER BATCH */
610 | on btn_b pressed do (actionMan.executeAction -43434444 "4096")
611 | /*------------------------------ ROLLOUT END ------------------------------*/
612 | )
613 | roll_batch
614 | ),
615 | public
616 | /* TOOL MAIN UI */
617 | fn showUI =
618 | (
619 | local res = false
620 | -- TODO: LICENSING!
621 | if (CamFloater != undefined AND CamFloater.open) then (
622 | try (closeRolloutFloater CamFloater) catch ()
623 | CamFloater = undefined
624 | updateToolbarButtons()
625 | ) else (
626 | roll_Cams = ui_cams()
627 | roll_Batch = ui_batch()
628 |
629 | roll_Cams.owner = this
630 | roll_Batch.owner = this
631 |
632 | CamFloater = newRolloutFloater "Camera Manager" 270 663 50 50 lockHeight:true lockWidth:true
633 | addRollout roll_Cams CamFloater border:false
634 | addRollout roll_Batch CamFloater
635 | res = true
636 | )
637 | res
638 | )
639 | )
640 | ------------------------------------------------------
641 | cmt = camManagerTool()
642 | ------------------------------------------------------
643 | on execute do (
644 | if cmt == undefined then cmt = camManagerTool()
645 | cmt.showUI()
646 | )
647 | )
--------------------------------------------------------------------------------
/src/BUMP_gamma_adjustment.ms:
--------------------------------------------------------------------------------
1 | /*
2 | Utility for changing the gamma value of bitmap texture maps. Intended to be use on Normal Maps
3 | Note: this is a work-in-progress
4 | 2020 - https://atelierbump.com
5 | */
6 | (
7 | -------------------------------------------------CONFIGURATION
8 | -- RENDERER PRESETS. ADD YOUR OWN FOLOWING THE SAME PATTERN
9 | struct _std
10 | (
11 | mat_filter_class = PhysicalMaterial,
12 | bitmap_filter = #bump_map,
13 | renderer_normalmap = #(#(Normal_Bump, #normal_map)),
14 | rndrBitmapTexture = #()
15 | )
16 | struct _Arnold
17 | (
18 | mat_filter_class = ai_standard_surface,
19 | bitmap_filter = #normal_shader,
20 | renderer_normalmap = #(
21 | #(ai_normal_map, #normal_shader),
22 | #(ai_bump2d, #normal_shader),
23 | #(ai_bump3d, #normal_shader)
24 | ),
25 | rndrBitmapTexture = #()
26 | )
27 | struct _Vray
28 | (
29 | mat_filter_class = VRayMtl,
30 | bitmap_filter = #texmap_bump,
31 | renderer_normalmap = #(#(VRayNormalMap, #normal_map)),
32 | rndrBitmapTexture = #(VRayHDRI, #gamma)
33 | )
34 | struct _Corona
35 | (
36 | mat_filter_class = CoronaMtl,
37 | bitmap_filter = #texmapBump,
38 | renderer_normalmap = #(#(CoronaNormal, #normalMap)),
39 | rndrBitmapTexture = #(CoronaBitmap, #gamma)
40 | )
41 | /*
42 | -- EXAMPLE: ADD SUPPORT FOR OTHER RENDERER
43 | struct _Your_own
44 | (
45 | -- Class of the shader
46 | mat_filter_class = Material_Class,
47 | -- Shader bump/normal property name
48 | bitmap_filter = #texmap_Bump_Property,
49 | -- renderer specific bump/normal map class and property for the normal texturemap.
50 | -- this can be more than one. i.e: look for Arnold implementation
51 | renderer_normalmap = #(#(Shader_Normal_Map, #normal_Map_Property)),
52 | -- renderer specific textureMap implementation and gamma property. Must be a float value
53 | rndrBitmapTexture = #(Renderer_Bitmap, #gamma_property_float)
54 | )
55 | -- */
56 | -- ENABLE - DISABLE RENDER ENGINES, ADD YOUR OWN HERE
57 | local RENDER_ENGINES_OPT =
58 | #(
59 | -- #("Your_own", _Your_own),
60 | #("Physical Material", _std),
61 | #("Arnold", _Arnold),
62 | #("Vray", _Vray),
63 | #("Corona", _Corona)
64 | )
65 | -----------------------------------------------------------------
66 | -- MAIN CODE -- DO NOT MODIFY!
67 | -- change bitmap gamma
68 | fn changeBmpGamma bmpTxt gammavalue:1.0 =
69 | (
70 | try (
71 | local curr_bitmap = bmpTxt.bitmap
72 | local new_bitmap = openBitMap curr_bitmap.filename gamma:gammavalue channels:curr_bitmap.channels
73 | setproperty bmpTxt #bitmap new_bitmap
74 | ) catch (
75 | format "Conversion error: %\m" (getCurrentException())
76 | )
77 | )
78 | -- search function.
79 | -- src parameter is the struct with the render engine parameters
80 | -- if "mats" is unsupplied it defaults to scene materials
81 | fn reassignMaps src _gamma:1.0 mats:unsupplied =
82 | (
83 | -- format "%\n" src
84 | -- get the material collection
85 | local mat_loop = if mats == unsupplied then sceneMaterials else mats
86 | -- handle Multimaterial and filter collection to valid material class
87 | local actual_mat_list = #()
88 |
89 | for mat in mat_loop do (
90 | -- single materials
91 | if (isKindOf mat src.mat_filter_class) then (
92 | append actual_mat_list mat
93 | ) else if (isKindOf mat Multimaterial) then (
94 | local multimat_childerns =
95 | for i in mat where (isKindOf i src.mat_filter_class) collect i
96 | join actual_mat_list multimat_childerns
97 | )
98 | )
99 | -- cleanup
100 | makeUniqueArray actual_mat_list
101 |
102 | -- change the properties
103 | for mat in actual_mat_list where (isKindOf mat src.mat_filter_class) do (
104 |
105 | format "material: %\n" mat
106 |
107 | -- check for shader bitmap
108 | if (isProperty mat src.bitmap_filter) then (
109 | local texturenode = getProperty mat src.bitmap_filter
110 |
111 | format "property: %\n" texturenode
112 |
113 | -- property must not be undefined
114 | if (texturenode != undefined) then (
115 | -- check for Bitmaptexture
116 | if (ClassOf texturenode == Bitmaptexture) then
117 | (
118 | -- CASE_A: standard bitmaptexture
119 | changeBmpGamma texturenode gammavalue:_gamma
120 | )
121 | else
122 | (
123 | -- CASE_B: renderer-specific normalMap. This generally implements some sort of a direct gamma property
124 | for i in src.renderer_normalmap do (
125 | if ClassOf texturenode == i[1] then (
126 | -- get the normalMap property
127 | local thebitmap = getProperty texturenode i[2]
128 | if ClassOf thebitmap == Bitmaptexture then (
129 | -- CASE_B_1: standard bitmap
130 | changeBmpGamma thebitmap gammavalue:_gamma
131 | ) else (
132 | -- CASE_B_2: render specific bitmap
133 | if src.rndrBitmapTexture.count > 1 then (
134 | if ClassOf thebitmap == src.rndrBitmapTexture[1] then (
135 | -- set the new gamma value
136 | -- this works only for float values
137 | if (isKindOf (getProperty thebitmap src.rndrBitmapTexture[2]) float) then (
138 | setProperty thebitmap src.rndrBitmapTexture[2] _gamma
139 | )
140 | )
141 | )
142 | )
143 | )
144 | )
145 | )
146 | )
147 | )
148 | -- format "-----------\n"
149 | )
150 | )
151 | -------------------------------------------------UI
152 | rollout roll_normalGamma "Change Normal Maps gamma"
153 | (
154 | group "Operate on"
155 | (
156 | radiobuttons rd_1 "" labels:#("Scene materials", "Material editor slots", "Selection") align:#left
157 | )
158 | spinner spn_1 "Gamma value: " type:#float range:[-100.0,100.0,1.0] align:#left
159 | label lbl_1 "Render engine" align:#left
160 | Dropdownlist cb_renders ""
161 | label lbl_2 "WARNING!!!\nTHIS OPERATION\nCAN'T BE UNDONE" height:40 align:#left
162 | button btn_change "Change values" height:30
163 | on roll_normalGamma open do
164 | (
165 | -- load render engines
166 | cb_renders.items = for i in RENDER_ENGINES_OPT collect i[1]
167 | -- tooltip
168 | btn_change.tooltip = "If you know some scripting,\nyou can edit this script to add more render engine options.\nLook for the file: "+(getThisScriptFilename())
169 | )
170 | on btn_change pressed do (
171 | -- material collection
172 | local mats_col =
173 | case rd_1.state of
174 | (
175 | 0: (unsupplied)
176 | 1: (unsupplied)
177 | 2: (meditMaterials)
178 | 3: (for i in (getCurrentSelection()) where i.material != undefined collect i.material)
179 | )
180 | -- renderer
181 | local selected_renderer = RENDER_ENGINES_OPT[cb_renders.selection][2]
182 | selected_renderer = selected_renderer()
183 | -- execute
184 | -- single materials
185 | reassignMaps selected_renderer _gamma:spn_1.value mats:mats_col
186 | -- multi-materials?
187 | )
188 | )
189 | -------------------------------------------------EXECUTION - MAUNAL - AUTOMATED IMPLEMENTATION
190 | -- default gamma value to apply
191 | local _gamma_ = 1.0 -- 2.2
192 | -----------------------------------------------------------------
193 | -- change maps gamma on scene materials
194 | -- set the render engine preset.
195 | /*
196 | reassignMaps _Corona _gamma:_gamma_
197 | -- */
198 | -------------------------------------------------
199 | -- change maps in node selection material's
200 | /*
201 | local selection_materials =
202 | (
203 | local sel = getCurrentSelection()
204 | for i in sel where i.material != undefined collect i.material
205 | )
206 | -- set the render engine preset.
207 | reassignMaps _Corona mats:selection_materials _gamma:_gamma_
208 | -- */
209 | ------------------------------------------------- UI IMPLEMENTATION
210 | -- /*
211 | try (DestroyDialog roll_normalGamma) catch ()
212 | CreateDialog roll_normalGamma
213 | -- */
214 | )
--------------------------------------------------------------------------------
/src/BUMP_sunblind_cage_calc.ms:
--------------------------------------------------------------------------------
1 | ----------------------------------------------------
2 | /* https://atelierbump.com */
3 | ----------------------------------------------------
4 | -- Units in Centimeters
5 | (
6 | -- Input data
7 | ----------------------------------------------------
8 | -- Reel axis radius
9 | local r_eje = 5
10 | -- courtain length
11 | local l_total = 230
12 | -- courtain tickness
13 | local esp_cortina = 2
14 | ----------------------------------------------------
15 |
16 | fn sunBlindCageCalc r_eje l_total esp_cortina =
17 | (
18 | -- calc - do not modify
19 | local cant_vueltas = 0
20 | local r_calculo = 0
21 | while l_total > 0 do (
22 | r_calculo = r_eje + ((esp_cortina * cant_vueltas)/2)
23 | perim = (2 * pi * r_calculo)
24 | cant_vueltas += 1
25 | l_total -= perim
26 | )
27 | #(r_calculo, perim, cant_vueltas, l_total)
28 | )
29 |
30 | rollout roll_ui "SunBlindCage" width:300
31 | (
32 | spinner spn_1 "Reel radius" type:#float align:#left
33 | spinner spn_2 "Courtain length" type:#float align:#left
34 | spinner spn_3 "Courtain thickness" type:#float align:#left
35 |
36 | button btn_1 "Calc" width:150
37 | editText txt_1 "" heigth:300
38 |
39 | on btn_1 pressed do (
40 |
41 | local res = sunBlindCageCalc spn_1.value spn_2.value spn_3.length
42 | local res_str = "" as StringStream
43 | -- output
44 | format "-----------DIMENSIONS - IN CM-----------\n" to:res_str
45 | format "FULL REEL DIAMETER: %\n" ((r_calculo*2) as String) to:res_str
46 | format "COURTAIN REVOLUTIONS: %\n" (cant_vueltas as String) to:res_str
47 | format "SQUARE CAGE SIDE: %\n" ((r_calculo * 2 + 10) as String) to:res_str
48 | txt_1.text = res_str as string
49 | )
50 | )
51 | )
52 |
--------------------------------------------------------------------------------
/src/BUMP_vertexScrambler.mcr:
--------------------------------------------------------------------------------
1 | /*
2 | BUMP 2016
3 | 22-05-16
4 | Vertex Scrambler
5 | v. 1.0.0
6 | http://www.scriptspot.com/users/ariel-g
7 | */
8 | macroScript BUMP_vrtxScr
9 | category:"BUMP tools"
10 | ButtonText:"VSC"
11 | toolTip:"Vertex Scrambler"
12 | (
13 | rollout roll_vertScramble "Vertex Scramble" width:200
14 | (
15 | label lbl_1 "OFFSET" align:#left
16 | group ""
17 | (
18 | spinner spn_dwX "X: " type:#worldunits range:[-1000000.0,1000000.0,0.0] fieldWidth:50 across:2
19 | spinner spn_upX "< " type:#worldunits range:[-1000000.0,1000000.0,0.0] fieldWidth:50
20 | spinner spn_dwY "Y: " type:#worldunits range:[-1000000.0,1000000.0,0.0] fieldWidth:50 across:2
21 | spinner spn_upY "< " type:#worldunits range:[-1000000.0,1000000.0,0.0] fieldWidth:50
22 | spinner spn_dwZ "Z: " type:#worldunits range:[-1000000.0,1000000.0,0.0] fieldWidth:50 across:2
23 | spinner spn_upZ "< " type:#worldunits range:[-1000000.0,1000000.0,0.0] fieldWidth:50
24 | checkbox chk_sfts "Use soft selection"
25 | )
26 | button btn_Sc "Scramble" width:190 height:30
27 | button btn_unS "UnScramble" width:190 height:30
28 | checkButton chk_live "Live" width:190 height:20
29 |
30 | local
31 | downlimit,
32 | uplimit,
33 | obj,
34 | vert_sel,
35 | vert_pos
36 |
37 | fn vertScramble o vs d_l u_l soft_s:false =
38 | (
39 | local vc = for i in vs collect random d_l u_l
40 | polyop.moveVert obj vs vc useSoftSel:soft_s
41 | )
42 |
43 | fn vertUnScramble o vs vo =
44 | (
45 | polyop.setVert o vs vo
46 | )
47 |
48 | fn scrambler =
49 | (
50 | undo "vertex scramble" on (
51 | vertUnScramble obj vert_sel vert_pos
52 | vertScramble obj vert_sel downlimit uplimit soft_s:(chk_sfts.state)
53 | )
54 | )
55 | fn vert_sc =
56 | (
57 | obj = $
58 | if isKindOf tempsel Editable_Poly then (
59 | if not (polyop.getVertSelection obj).isEmpty then (
60 | vert_sel = polyop.getVertSelection obj
61 | vert_pos = for i in vert_sel collect ( polyop.getVert obj i)
62 | ) else (messageBox "Select some Vertex!"; DestroyDialog roll_vertScramble)
63 |
64 | ) else (messageBox "Select EditPoly Object!"; DestroyDialog roll_vertScramble)
65 | )
66 |
67 | on roll_vertScramble open do (
68 | vert_sc()
69 |
70 | downlimit = [spn_dwX.value, spn_dwY.value, spn_dwZ.value]
71 | uplimit = [spn_upX.value, spn_upY.value, spn_upZ.value]
72 |
73 | )
74 |
75 | on spn_dwX changed val do (downlimit.x = val; if chk_live.state then ( scrambler() ))
76 | on spn_dwY changed val do (downlimit.y = val; if chk_live.state then ( scrambler() ))
77 | on spn_dwZ changed val do (downlimit.z = val; if chk_live.state then ( scrambler() ))
78 | on spn_upX changed val do (uplimit.x = val; if chk_live.state then ( scrambler() ))
79 | on spn_upY changed val do (uplimit.y = val; if chk_live.state then ( scrambler() ))
80 | on spn_upZ changed val do (uplimit.z = val; if chk_live.state then ( scrambler() ))
81 | on btn_Sc pressed do ( scrambler() )
82 | on btn_unS pressed do ( vertUnScramble obj vert_sel vert_pos )
83 | )
84 | on isEnabled do roll_vertScramble.open
85 | on execute do CreateDialog roll_vertScramble
86 | )
--------------------------------------------------------------------------------
/src/BUMP_viewPortCompositionGuides-v1.mcr:
--------------------------------------------------------------------------------
1 | /*
2 | VIEWPORT COMPOSITION GUIDES
3 | 2020
4 | */
5 | macroscript BUMP_vpComp
6 | category: "BUMP tools"
7 | buttontext: "viewport Composition guides"
8 | tooltip: "viewport Composition guides"
9 | (
10 | rollout compGuide "Composition guides"
11 | (
12 | group "Grid presets"
13 | (
14 | checkbutton p1 "2 x 2" width:65 height:40 across:2
15 | checkbutton p2 "3 x 3" width:65 height:40
16 | )
17 | group "Position Guides"
18 | (
19 | button place1 "Horizontal" width:65 height:40 across:2
20 | button place2 "Vertical" width:65 height:40
21 | button place3 "Cross" width:65 height:40 across:2
22 | button place4 "From Pt" width:65 height:40 \
23 | toolTip: "Position multiple aligned lines from a common base point. Useful to draw perspective lines from a vanishing point"
24 | )
25 | colorPicker c1 "Guides Color" height:20 fieldwidth:30 align:#right default:yellow
26 | ------------------------------
27 | -- store values
28 | local
29 | Guide_Lines, drawingLines,
30 | Grid_Lines, drawingGirds,
31 | Store_Point, Track_point,
32 | guideLine
33 | ------------------------------
34 | /* VIEWPORT INFORMATION FUNCTIONS */
35 | -- viewport data
36 | fn getViewportSafeFrameSize UIScaling:true =
37 | (
38 | local viewSize_x = gw.getWinSizeX applyUIScaling:UIScaling
39 | local viewSize_y = gw.getWinSizeY applyUIScaling:UIScaling
40 |
41 | local viewAspect = viewSize_x as float / viewSize_y
42 | local renderAspect = renderWidth as float / renderHeight
43 |
44 | local x, y, w, h
45 | if (viewAspect > renderAspect) then
46 | (
47 | h = viewSize_y
48 | w = (h * renderAspect) as integer
49 | y = 0
50 | x = (viewSize_x - w) / 2
51 | )
52 | else
53 | (
54 | w = viewSize_x
55 | h = (w / renderAspect) as integer
56 | x = 0
57 | y = (viewSize_y - h) / 2
58 | )
59 | return box2 x y w h
60 | )
61 | -- viewport diagonal size
62 | fn getViewPortDiagonalSize UIScaling:true =
63 | (
64 | (length [gw.getWinSizeX applyUIScaling:UIScaling, gw.getWinSizeY applyUIScaling:UIScaling]) as integer
65 | )
66 | ------------------------------
67 | /* UTILITY FUNCTIONS */
68 | -- get axes from mouse position
69 | fn tracker p2 ref axis:#x =
70 | (
71 | local res
72 | if axis == #x then (
73 | res = #(
74 | #( [p2.x, 0, 0], [p2.x, ref.y, 0] ),
75 | #()
76 | )
77 | ) else if axis == #y then (
78 | res = #(
79 | #(),
80 | #( [0, p2.y, 0], [ref.x , p2.y, 0] )
81 | )
82 | ) else (
83 | res = #(
84 | #( [p2.x, 0, 0], [p2.x, ref.y, 0] ),
85 | #( [0, p2.y, 0], [ref.x , p2.y, 0] )
86 | )
87 | )
88 | res
89 | )
90 | -- construct grid
91 | fn viewPortGrid h v UIScaling:true =
92 | (
93 | local
94 | Hdiv, Vdiv,
95 | resH, resV,
96 | dx, dy,
97 | fx, fy
98 | --local vpSize =
99 | if displaySafeFrames then (
100 | local vpSize = getViewportSafeFrameSize UIScaling:UIScaling
101 | -- Hdiv = floor ((vpSize.h + vpSize.y) / h as float)
102 | -- Vdiv = floor ((vpSize.w + vpSize.x) / v as float)
103 | dx = vpSize.w
104 | dy = vpSize.h
105 | fx = vpSize.x
106 | fy = vpSize.y
107 | ) else (
108 | -- Hdiv = floor (gw.getWinSizeX applyUIScaling:UIScaling / h as float)
109 | -- Vdiv = floor (gw.getWinSizeY applyUIScaling:UIScaling / v as float)
110 | dx = gw.getWinSizeX applyUIScaling:UIScaling
111 | dy = gw.getWinSizeY applyUIScaling:UIScaling
112 | fx = 0
113 | fy = 0
114 | )
115 | Hdiv = floor ( dy / h )
116 | Vdiv = floor ( dx / v )
117 |
118 | resH = for ih=1 to (h - 1) collect (
119 | #(
120 | -- mapScreenToView [0, Hdiv * ih] 1 applyUIScaling:UIScaling,
121 | -- mapScreenToView [dx, Hdiv * ih] 1 applyUIScaling:UIScaling
122 | [0, Hdiv * ih, 0] + [fx, fy, 0],
123 | [dx, Hdiv * ih, 0] + [fx, fy, 0]
124 | )
125 | )
126 | resV = for iv=1 to (v - 1) collect (
127 | #(
128 | -- mapScreenToView [Vdiv * iv, 0] 1 applyUIScaling:UIScaling,
129 | -- mapScreenToView [Vdiv * iv, dy] 1 applyUIScaling:UIScaling
130 | [Vdiv * iv, 0, 0] + [fx, fy, 0],
131 | [Vdiv * iv, dy, 0] + [fx, fy, 0]
132 | )
133 | )
134 | join resH resV
135 | )
136 | ------------------------------
137 | /* MOUSE TRACK FUNCTIONS */
138 | fn TraceMouse msg ir obj faceNum shift ctrl alt args =
139 | (
140 | -- mouse.posUnscaled
141 | Track_point = tracker mouse.pos Store_Point axis:args
142 | redrawViews()
143 |
144 | case msg of
145 | (
146 | #mouseAbort: undefined
147 | #freeMove: #continue
148 | #mouseMove: #continue
149 | #mousePoint: mouse.pos
150 | -- #mousePoint: mouse.posUnscaled
151 | default: msg
152 | )
153 | )
154 | ------------------------------
155 | /* GRAPHIC FUNCTIONS */
156 | fn GW_hline col RGBColor:yellow =
157 | (
158 | if (isKindOf col Array) AND col.count > 0 then (
159 | gw.setTransform (Matrix3 1)
160 | gw.setColor #line RGBColor
161 |
162 | for i in col do gw.hPolyline i false
163 |
164 | gw.enlargeUpdateRect #whole
165 | gw.updateScreen()
166 | )
167 | )
168 | fn GW_wline col RGBColor:yellow =
169 | (
170 | if (isKindOf col Array) AND col.count > 0 then (
171 | gw.setTransform (Matrix3 1)
172 | gw.setColor #line RGBColor
173 |
174 | for i in col do gw.wPolyline i false
175 |
176 | gw.enlargeUpdateRect #whole
177 | gw.updateScreen()
178 | )
179 | )
180 | -- gw callbacks
181 | fn GW_tracker = GW_wline Track_point RGBColor:c1.color
182 | fn GW_GridCallback = GW_hline Grid_Lines RGBColor:c1.color
183 | fn GW_LinesCallback = GW_wline Guide_Lines RGBColor:c1.color
184 | fn GW_GuideCallback = GW_wline guideLine RGBColor:c1.color
185 | ------------------------------
186 | -- utility functions
187 | fn placeGuide axis:#x =
188 | (
189 | local mPoint
190 | local res
191 | -- save resources: store the wp size
192 | Store_Point = [gw.getWinSizeX applyUIScaling:UIScaling, gw.getWinSizeY applyUIScaling:UIScaling]
193 | -- register line track gw
194 | unregisterRedrawViewsCallback GW_tracker
195 | registerRedrawViewsCallback GW_tracker
196 | -- track line
197 | if ( mPoint = mouseTrack snap:#3d trackCallback:#(TraceMouse, axis)) != undefined then
198 | (
199 | -- just return the point
200 | res = Track_point
201 | )
202 | -- unregister the tracker
203 | unregisterRedrawViewsCallback GW_tracker
204 | res
205 | )
206 | fn drawGrids state h v =
207 | (
208 | if state then (
209 | try (
210 | Grid_Lines = viewPortGrid h v
211 | unregisterRedrawViewsCallback GW_GridCallback
212 | registerRedrawViewsCallback GW_GridCallback
213 | redrawViews()
214 | )
215 | catch (
216 | unregisterRedrawViewsCallback GW_GridCallback
217 | format (getCurrentException())
218 | )
219 | ) else (
220 | unregisterRedrawViewsCallback GW_GridCallback
221 | redrawViews()
222 | )
223 | )
224 | fn drawLines theGuide =
225 | (
226 | if not drawingLines then (
227 | drawingLines = true
228 | unregisterRedrawViewsCallback GW_LinesCallback
229 | registerRedrawViewsCallback GW_LinesCallback
230 | )
231 | local res
232 | try (
233 | if (res = theGuide) != undefined then (
234 | -- add to lines collection
235 | join Guide_Lines res
236 | redrawViews()
237 | )
238 | ) catch (
239 | -- unregister gw
240 | unregisterRedrawViewsCallback GW_LinesCallback
241 | format (getCurrentException())
242 | )
243 | )
244 | fn drawRays =
245 | (
246 | -- implemented as a mouseTool
247 | tool raysTool
248 | (
249 | -- base point
250 | local bp
251 | local vpDiagSize = getViewPortDiagonalSize()
252 | -- line function
253 | fn compline p1 p2 ext:1000 =
254 | (
255 | local v = (normalize (p2 - p1)) * ext
256 | #(-v + p1, v + p1)
257 | )
258 | -- events
259 | on start do (
260 | registerRedrawViewsCallback GW_GuideCallback
261 | )
262 | on stop do (
263 | unRegisterRedrawViewsCallback GW_GuideCallback
264 | guideLine = #()
265 | )
266 | -- click event
267 | on mousePoint clickno do (
268 | if clickno == 1 then (
269 | bp = [viewPoint.x, viewPoint.y, 0]
270 | ) else if clickno != 2 then (
271 | -- add guide to display collection
272 | if guideLine[1] != undefined then drawLines guideLine
273 | )
274 | )
275 | -- mouse track event
276 | on mouseMove clickno do (
277 | if bp != undefined then (
278 | guideLine = #(compline bp [viewPoint.x, viewPoint.y, 0] ext:vpDiagSize)
279 | )
280 | redrawViews()
281 | )
282 | -- on mouseAbort ckickno do (...)
283 | )
284 | -- start the tool
285 | startTool raysTool
286 | )
287 | ------------------------------
288 | -- open event
289 | on compGuide open do
290 | (
291 | -- initialize values
292 | Guide_Lines = #()
293 | Grid_Lines = #()
294 | drawingLines = false
295 |
296 | Store_Point = [0, 0, 0]
297 | Track_point = [0, 0, 0]
298 |
299 | guideLine = #()
300 | )
301 | -- close event
302 | on compGuide close do
303 | (
304 | unregisterRedrawViewsCallback GW_tracker
305 | unregisterRedrawViewsCallback GW_GridCallback
306 | unregisterRedrawViewsCallback GW_LinesCallback
307 | unregisterRedrawViewsCallback GW_GuideCallback
308 | redrawViews()
309 | )
310 | ------------------------------
311 | -- draw 2x2 grid
312 | on p1 changed state do (drawGrids state 2 2; if p2.checked then p2.checked = false)
313 | -- draw 3x3 grid
314 | on p2 changed state do (drawGrids state 3 3; if p1.checked then p1.checked = false)
315 | ------------------------------
316 | -- draw horiz lines
317 | on place1 pressed do drawLines (placeGuide axis:#y)
318 | -- draw vert lines
319 | on place2 pressed do drawLines (placeGuide axis:#x)
320 | -- draw cross lines
321 | on place3 pressed do drawLines (placeGuide axis:#xy)
322 | -- draw free position guide
323 | on place4 pressed do drawRays()
324 | )
325 |
326 | on isChecked do if compGuide != undefined then compGuide.open else false
327 |
328 | on execute do (
329 | try (
330 | if not compGuide.open then CreateDialog compGuide
331 | ) catch (
332 | DestroyDialog compGuide
333 | CreateDialog compGuide
334 | )
335 | )
336 | )
--------------------------------------------------------------------------------
/src/BUMP_xref_replace.mcr:
--------------------------------------------------------------------------------
1 | /*
2 | ------------------------------------------------------------------------------------------------------------------
3 | https://atelierbump.com
4 | Xref Object Utilities
5 | ------------------------------------------------------------------------------------------------------------------
6 | */
7 | macroScript BUMP_toXref
8 | category: "BUMP tools"
9 | buttonText: "Replace with Xref"
10 | toolTip: "Replace selected node with Xref Record"
11 | (
12 | fn centroid objs =
13 | (
14 | local sumpoints = [0.0f,0.0f,0.0f]
15 | for i in objs do (
16 | sumpoints += i.pos
17 | )
18 | sumpoints /= objs.count
19 | )
20 | -----------------------------------------
21 | fn place objs ref =
22 | (
23 | local cent = centroid objs
24 | for i in objs where (i.parent == undefined) do (
25 | i.pos = (cent - i.pos) + ref
26 | )
27 | )
28 | -----------------------------------------
29 | fn setXrefRecord obj filename deleteRef:true =
30 | (
31 | if (not (isValidNode obj)) AND (not (doesFileExist filename)) then return false
32 |
33 | local xrefRecord
34 | local the_nodes = #()
35 |
36 | with redraw off (
37 | -- load XrefObject
38 | xrefRecord = objXRefMgr.AddXRefItemsFromFile filename xrefOptions:#(#selectnodes)
39 | if xrefRecord == undefined then return false
40 | -- check for xref existence ?
41 | if (xrefRecord.Update()) then (
42 | format "RECORD LOADED\n"
43 | -- get items
44 | xrefRecord.GetItems #XRefObjectType &xrefItems
45 | if xrefItems == undefined then return false
46 | -- get nodes
47 | for itm in xrefItems where (isKindOf itm XRefObject) do (
48 | itm.getNodes &nodelist
49 | join the_nodes nodelist
50 | )
51 | place the_nodes obj.pos
52 | )
53 | -- delete refnode
54 | if deleteRef then delete obj
55 | )
56 | -- update xrefs
57 | objXRefMgr.UpdateAllRecords()
58 | true
59 | )
60 | -----------------------------------------
61 | fn XrefReplace =
62 | (
63 | local file = getOpenFileName caption:"Xref Object file" types:"Max files (*.max)|*.max" historyCategory:"XREFOPEN"
64 | local obj = (getCurrentSelection())[1]
65 | setXrefRecord obj file
66 | )
67 | -----------------------------------------
68 | on execute do XrefReplace()
69 | -----------------------------------------
70 | )
--------------------------------------------------------------------------------
/src/Panel_cuts/example/cuts_CUTS REPORT.csv:
--------------------------------------------------------------------------------
1 | CUTS REPORT
2 | "QUANT.","HEIGHT","LENGTH","THICKNESS","ORIENTATION","FINISH","PART","DESCRIPTION"
3 | "2","160.0","60.0","1.8","H","MDF PANEL - white finish (melamine)","BODY - roof",""
4 | "2","101.3","52.8333","1.8","H","MDF PANEL - wood texture","Ddoor 2",""
5 | "4","98.2","60.0","1.8","H","MDF PANEL - white finish (melamine)","Body - vert. Divider",""
6 | "1","60.0","50.3333","1.8","H","MDF PANEL - white finish (melamine)","Horiz - Divider",""
7 | "1","60.0","52.1333","1.8","H","MDF PANEL - white finish (melamine)","Horiz - Divider",""
8 | "1","60.0","50.3333","1.8","H","MDF PANEL - white finish (melamine)","Horiz - Divider",""
9 | "1","52.8333","50.5437","1.8","H","MDF PANEL - wood texture","Door 3",""
10 | "1","52.8333","50.3791","1.8","H","MDF PANEL - wood texture","Door 1",""
11 |
--------------------------------------------------------------------------------
/src/Panel_cuts/example/panel_cuts_test.max:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/src/Panel_cuts/example/panel_cuts_test.max
--------------------------------------------------------------------------------
/src/Panel_cuts/src/psd/panel_cuts.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/src/Panel_cuts/src/psd/panel_cuts.psd
--------------------------------------------------------------------------------
/src/Panel_cuts/src/psd/panel_cuts_intro.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/src/Panel_cuts/src/psd/panel_cuts_intro.psd
--------------------------------------------------------------------------------
/src/Panel_cuts/src/psd/panel_cuts_ui.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/src/Panel_cuts/src/psd/panel_cuts_ui.psd
--------------------------------------------------------------------------------
/src/Panel_cuts/src/scripts/BUMP_panelCuts.ms:
--------------------------------------------------------------------------------
1 | (
2 | /*
3 | -------------------------------------------------------------------------------------------------------
4 | BUMP Panel Cuts
5 | BUMP 2016
6 | version 1.0 - 12-16
7 | -------------------------------------------------------------------------------------------------------
8 | */
9 | ---- STRINGS
10 | Local
11 | r_title = "PANEL CUTS",
12 | c_name = "Name:",
13 | c_h = "Height: ",
14 | c_l = "Length: ",
15 | c_w = "Thickness: ",
16 | c_ck_h = "HEIGHT",
17 | c_ck_l = "LENGTH",
18 | c_f = "Finish: ",
19 | c_t = "Part: ",
20 | c_c = "Caption: ",
21 | c_d = "Description: ",
22 | c_ss = "SELECTION",
23 | c_s = "Selected",
24 | c_ps = " > SAVE TO FILE - Current Selection",
25 | c_pa = " > SAVE TO FILE - All Objects",
26 | c_i = "REPORT ",
27 | l_o = "Grain Direction",
28 | l_cp = "-------------- SHEET QNT --------------",
29 | l_dm = "Sheet dimensions: ",
30 | sc_u = "Scale Up",
31 | sc_d = "Scale Down",
32 | ----
33 | drp_itms = #("Vertical","Horizontal"),
34 | ----
35 | strf_p1 = "Estimated Sheets quantity with a wastage of ",
36 | strf_p2 = "taking into account the selected objects",
37 | str_q1 = "This operation will scale up computed dimensions on x% factor. Are you sure?",
38 | str_q2 = "This operation will scale down computed dimensions on x% factor. Are you sure?",
39 | str_cap = "CUTS REPORT",
40 | ----
41 | str_titles = "\"HEIGHT\",\"LENGTH\",\"THICKNESS\",\"ORIENTATION\",\"FINISH\",\"PART\",\"DESCRIPTION\"\n",
42 | str_titles_2 = "\"QUANT.\",\"HEIGHT\",\"LENGTH\",\"THICKNESS\",\"ORIENTATION\",\"FINISH\",\"PART\",\"DESCRIPTION\"\n",
43 | ----
44 | str_ok = "COMMIT",
45 | ---- TOOLTIPS
46 | t1 = "Commit changes, right click on button to change all objects in selection.",
47 | t2 = "Set selected objects as active object collection. Use previous and next buttons to navigate through the object collection.",
48 | t3 = "Previuos object. Right click to commit parameter changes.",
49 | t4 = "Next object. Right click to commit parameter changes.",
50 | t5 = "Pick object in viewport and set it as active.",
51 | t6 = "Scale measured object units (not reflected in geometry).",
52 | t7 = "Compute sheet area use.",
53 | t8 = "Conversion factor for units."
54 | ---- DEFAULT VALUES
55 | local vals_to_file = #("h","l","w","orientation","mat","part","description")
56 | ----
57 | struct _props
58 | (
59 | obj,
60 | l,w,h,
61 | orientation,
62 | _name, part, description,
63 | mat
64 | )
65 | struct _gw
66 | (
67 | fn GW_text p txt RGBcolor:(color 8 180 150) =
68 | (
69 | if (p != undefined and txt != undefined) then (
70 | gw.setTransform (matrix3 1)
71 | local _p = gw.hTransPoint p
72 | gw.hText _p txt color:black
73 | local pr = gw.getTextExtent txt
74 | p1 = [_p.x,_p.y] - [2.5,0.0]
75 | p2 = pr + p1 + 5.0
76 | local bx = Box2 p1 p2
77 | gw.hRect bx RGBcolor
78 | gw.enlargeUpdateRect #whole
79 | gw.updateScreen()
80 | )
81 | )
82 | )
83 | struct _cm
84 | (
85 | ------------------------------------------------------------------------------------ Object checking
86 | fn check_obj obj = (if (obj != undefined) and (superClassOf obj == GeometryClass) then obj else undefined),
87 | fn getObjSelect =
88 | (
89 | local tmp = (selection as Array)
90 | local validObjs =
91 | if tmp[1] != undefined then (
92 | for i in tmp where (superClassOf i == GeometryClass) collect i
93 | ) else undefined
94 | ),
95 | fn selector objs indx: =
96 | (
97 | for i in objs do (
98 | if isValidNode i then (
99 | if i.displayByLayer then i.displayByLayer = false
100 | i.boxmode = true
101 | )
102 | )
103 | if indx != unsupplied then objs[indx].boxmode = false
104 | objs[indx]
105 | ),
106 | fn unselector objs =
107 | (
108 | if objs != undefined then (
109 | for i in objs do (
110 | if isValidNode i then (
111 | i.boxmode = false
112 | )
113 | )
114 | )
115 | ),
116 | ------------------------------------------------------------------------------------ Math functions
117 | fn CalculateVolumeAndCenterOfMass obj =
118 | (
119 | if (superclassof obj) == geometryclass then (
120 | local Volume= 0.0
121 | local Center= [0.0, 0.0, 0.0]
122 | local theMesh = snapshotasmesh obj
123 | local numFaces = theMesh.numfaces
124 | for i = 1 to numFaces do
125 | (
126 | local Face= getFace theMesh i
127 | local vert2 = getVert theMesh Face.z
128 | local vert1 = getVert theMesh Face.y
129 | local vert0 = getVert theMesh Face.x
130 | local dV = Dot (Cross (vert1 - vert0) (vert2 - vert0)) vert0
131 | Volume+= dV
132 | Center+= (vert0 + vert1 + vert2) * dV
133 | )
134 | delete theMesh
135 | Volume /= 6
136 | Center /= 24
137 | Center /= Volume
138 | #(Volume,Center)
139 | ) else #(undefined, undefined)
140 | ),
141 | fn changeUnits _objs up:true factor:10.0 =
142 | (
143 | if _objs != undefined then (
144 | for o in _objs do (
145 | local h = getUserProp o "h"
146 | local l = getUserProp o "l"
147 | local w = getUserProp o "w"
148 | ---
149 | if isKindOf h float then setUserProp o "h" (if up then h*factor else h/factor)
150 | if isKindOf l float then setUserProp o "l" (if up then l*factor else l/factor)
151 | if isKindOf w float then setUserProp o "w" (if up then w*factor else w/factor)
152 | )
153 | )
154 | ),
155 | fn ReverseArray arr = (for i=arr.count to 1 by -1 collect arr[i]),
156 | fn sortMax arr1 arr2 maxtomin:true =
157 | (
158 | local first = arr1[1],
159 | second = arr2[1]
160 | if (isKindOf first float) and (isKindOf second float) then (
161 | case of (
162 | (first < second): if maxtomin then 1 else -1
163 | (first > second): if maxtomin then -1 else 1
164 | default:0
165 | )
166 | ) else 0
167 | ),
168 | fn getDims obj =
169 | (
170 | if (obj != undefined) and (superClassOf obj == GeometryClass) then (
171 | local bbx = in coordsys local nodeLocalBoundingBox obj
172 | local dim = bbx[2] - bbx[1]
173 | local coords = _cm.ReverseArray (sort #(dim.x, dim.y, dim.z))
174 | ) else undefined
175 | ),
176 | ------------------------------------------------------------------------------------ userProps functions
177 | fn setUserProps obj getFrom =
178 | (
179 | try(
180 | local prop = getPropNames getFrom
181 | for i in prop do (
182 | local p = getProperty getFrom i
183 | if (getHashValue p 10) != undefined then (
184 | setUserProp obj (toLower (i as string) ) p
185 | )
186 | )
187 | ) catch (displayTempPrompt (getCurrentException()) 6000 )
188 | ),
189 | ------------------------------------------------------------------------------------ file functions
190 | fn saveFile str fname =
191 | (
192 | local fnArr = filterString fname "*.*"
193 | try (
194 | local out_name = GetSaveFileName filename:fname types:("*."+fnArr[2])
195 | if out_name != undefined then (
196 | local out_file = createfile out_name
197 | format (str as String) to:out_file
198 | close out_file
199 | )
200 | return out_name
201 | ) catch (return undefined)
202 | ),
203 | ------------------------------------------------------------------------------------ Save UserProps to file
204 | fn prop_str _objs caption: titles:"" vals:#("h","l","w","orientation","finish","part","description") =
205 | (
206 | if titles != unsupplied and vals != unsupplied then (
207 | -- rows
208 | local obj_v = #()
209 | for o in _objs do (
210 | local temp_v = for i=1 to vals.count collect
211 | (
212 | local v = getUserProp o vals[i]
213 | v = if v != undefined then v else "-"
214 | )
215 | append obj_v temp_v
216 | )
217 | -- sort array
218 | qsort obj_v _cm.sortMax
219 | -- /*
220 | -- add row number
221 | for i in obj_v do ( insertItem 1 i 1 )
222 | -- group similars
223 | local del_sim = deepCopy obj_v
224 | for i = del_sim.count to 2 by -1 do (
225 | if ( (del_sim[i][2] == del_sim[i-1][2]) and (del_sim[i][3] == del_sim[i-1][3]) ) and (del_sim[i][5] == del_sim[i-1][5]) then (
226 | del_sim[i-1][1] += del_sim[i][1]
227 | deleteItem del_sim i
228 | )
229 | )
230 | -- generate file
231 | local theFile = StringStream ""
232 | if caption != unsupplied do ( append theFile (caption + "\n") )
233 | append theFile titles
234 | for i in del_sim do (
235 | for f=1 to i.count do (
236 | if f < i.count then (
237 | format "\"%\"," i[f] to:theFile
238 | ) else (
239 | format "\"%\"\n" i[f] to:theFile
240 | )
241 | )
242 | )
243 | free obj_v
244 | free del_sim
245 | theFile
246 | -- */
247 | )
248 | )
249 | )
250 | fn PanelCuts =
251 | (
252 | rollout roll_props r_title width:270
253 | (
254 | EditText txt_1 c_name fieldWidth:(roll_props.width - 20) readOnly:true align:#right labelOnTop:true
255 | EditText txt_2_1 c_h fieldWidth:180 readOnly:true align:#right
256 | EditText txt_2_2 c_l fieldWidth:180 readOnly:true align:#right
257 | EditText txt_2_3 c_w fieldWidth:180 readOnly:true align:#right
258 | imgTag sep3 width:(roll_props.width - 30) height:1 bitmap:(bitmap 1 2 color: (color 5 5 5)) offset:[0,5] align:#center
259 | label lbl_sep1 "PROPERTIES" align:#center
260 | dropdownlist drp_1 l_o items:drp_itms
261 | checkBox ck_o1 c_ck_h checked:true across:2 align:#left enabled:false
262 | checkBox ck_o2 c_ck_l align:#left enabled:false
263 | imgTag sep2 width:(roll_props.width - 30) height:1 bitmap:(bitmap 1 2 color: (color 5 5 5)) offset:[0,5] align:#center
264 | editText txt_m c_f fieldWidth:245 labelOnTop:true
265 | listbox lst_m "" height:3 width:245
266 | editText txt_3 c_t fieldWidth:245 labelOnTop:true
267 | listbox lst_t height:5 width:245
268 | editText txt_4 c_d height:50 fieldWidth:245 labelOnTop:true
269 | button btn_1 str_ok height:30 width: 245 tooltip:t1
270 | imgTag sep4 width:(roll_props.width - 30) height:1 bitmap:(bitmap 1 2 color: (color 5 5 5)) offset:[0,5] align:#center
271 | label lbl_sep2 "SELECT PARTS" align:#center
272 | button btn_p "<<" align:#left height:30 across:3 tooltip:t3
273 | button btn_sg c_ss height:30 width:170 tooltip:t2
274 | button btn_n ">>" height:30 align:#right tooltip:t4
275 | checkbutton btn_a "Viewport select" highlightColor:(color 80 120 30) height:25 width:240 align:#center offset:[0,10] tooltip:t5
276 |
277 |
278 | group "UTILITIES"
279 | (
280 | label lbl_sep4 "Scale Units" align:#left offset:[0,10]
281 | imgTag sep6 width:(roll_props.width - 30) height:1 bitmap:(bitmap 1 2 color: (color 5 5 5)) offset:[0,0] align:#center
282 | spinner spn_f "Factor:" type:#float range:[1.0,1000000.0,10.0] width:150 align:#left across:2
283 | button btn_m1 sc_u width:80 align:#right tooltip:t6
284 | button btn_m2 sc_d width:80 align:#right tooltip:t6
285 |
286 | label lbl_sep5 "Sheet use" align:#left
287 | imgTag sep7 width:(roll_props.width - 30) height:1 bitmap:(bitmap 1 2 color: (color 5 5 5)) offset:[0,0] align:#center
288 | label l_dmns l_dm align:#left
289 | spinner spn_p1 "W: " type:#worldunits range:[1.0,1000000.0,183.0] fieldwidth:70 align:#right across:2
290 | spinner spn_p2 "H: " type:#worldunits range:[1.0,1000000.0,260.0] fieldwidth:70 align:#right
291 | spinner spn_p3 "Waste %: " type:#float range:[1.0,100.0,20.0] fieldwidth:70 offset:[0,10] align:#right
292 | spinner spn_p4 "Unit conversion: " type:#float range:[1.0,100.0,1.0] fieldwidth:70 align:#right tooltip:t8
293 | button btn_p1 c_i width:240 height:25 align:#center offset:[0,10] tooltip:t7
294 |
295 | label lbl_sep6 "Save to file" align:#left
296 | imgTag sep8 width:(roll_props.width - 30) height:1 bitmap:(bitmap 1 2 color: (color 5 5 5)) offset:[0,0] align:#center
297 | editText txt_c c_c text:str_cap fieldwidth:240 labelonTop:true
298 | button btn_lst_s c_ps width:240 height:30 align:#center offset:[0,10]
299 | button btn_lst_a c_pa width:240 height:30 align:#center offset:[0,10]
300 | )
301 | ------------------------------------------------------------------------------------ UI VALUES
302 | local dimTxt = #(txt_2_2, txt_2_1, txt_2_3)
303 | local propsTxt = #(txt_3, txt_4)
304 | ------------------------------------------------------------------------------------ COMMON VALUES
305 | local props
306 | local obj
307 | local objs
308 | local index
309 | local tempSel
310 | local callbackItem
311 | local tempPoint, tempText
312 | ------------------------------------------------------------------------------------ Graphic functions
313 | fn GW_txt_callback = (_gw.GW_text tempPoint tempText)
314 | ------------------------------------------------------------------------------------ selection functions
315 | fn startSelector &item call = ( item = NodeEventCallback mouseup:true delay:1000 selectionChanged:call )
316 | fn stopSelector &item = ( item = undefined; gc light:true )
317 | ------------------------------------------------------------------------------------
318 | -- rewrite
319 | fn getValues obj &props =
320 | (
321 | if (obj != undefined) and (superClassOf obj == GeometryClass) then (
322 | props.obj = obj.name
323 | local coords = _cm.getDims obj
324 | props.L = coords[2]; props.H = coords[1]; props.W = coords[3]
325 |
326 | props.orientation = getUserProp obj "orientation"
327 | props.part = getUserProp obj "part"
328 | props.description = getUserProp obj "description"
329 | props.mat = getUserProp obj "mat"
330 | )
331 | )
332 | fn setValues &props val: _props:#("_name","Lenght","Width","Height","Orient","Part","Description","mat") =
333 | (
334 | props.obj = _props[1]
335 | props.orientation = _props[5]
336 | props.part = _props[6]
337 | props.description = _props[7]
338 | props.mat = _props[8]
339 | )
340 | fn set_val_toObj obj objs _update_all:false =
341 | (
342 | if obj != undefined then (
343 | local d = #("V","H")
344 | if _update_all then (
345 | for i in objs do (
346 | getValues i &props
347 | setValues &props _props:#(txt_1.text,"Lenght","Width","Height",d[drp_1.selection],txt_3.text ,txt_4.text,txt_m.text)
348 | _cm.setUserProps i props
349 | )
350 | ) else (
351 | setValues &props _props:#(txt_1.text,"Lenght","Width","Height",d[drp_1.selection],txt_3.text ,txt_4.text,txt_m.text)
352 | _cm.setUserProps obj props
353 | )
354 | )
355 | )
356 | -- UI update
357 | fn loadToUI props =
358 | (
359 | try (
360 | txt_1.text = props.obj
361 | txt_2_1.text = units.formatValue props.H
362 | txt_2_2.text = units.formatValue props.L
363 | txt_2_3.text = units.formatValue props.W
364 | ) catch()
365 |
366 | if props.orientation == "V" then (
367 | drp_1.selection = 1
368 | ck_o1.checked = true; ck_o2.checked = false
369 | ) else (
370 | drp_1.selection = 2
371 | ck_o1.checked = false; ck_o2.checked = true
372 | )
373 | ck_o1.caption = c_ck_h + ": " + txt_2_1.text
374 | ck_o2.caption = c_ck_l + ": " + txt_2_2.text
375 |
376 | txt_3.text = if props.part != undefined then (props.part as string) else ""
377 | txt_4.text = if props.description != undefined then (props.description as string) else ""
378 | txt_m.text = if props.mat != undefined then props.mat else ""
379 | )
380 | fn validate = ( getValues obj &props; loadToUI props )
381 | fn sel_shuffle &i _t _to:#up =
382 | (
383 | case _to of (
384 | #up:(if i < objs.count do i +=1)
385 | #down:(if i > 1 do i -=1)
386 | )
387 | _cm.selector objs indx:i
388 | obj = objs[i]
389 | validate()
390 | tempPoint = (_cm.CalculateVolumeAndCenterOfMass obj)[2]
391 | tempText = (props.l as string)+"x"+(props.h as string)+"x"+(props.w as string)
392 | )
393 | ------------------------------------------------------------------------------------ selector Callback
394 | fn CallBackSel ev nd =
395 | (
396 | obj = _cm.check_obj (selection[1])
397 | if obj != undefined then validate()
398 | tempPoint = (_cm.CalculateVolumeAndCenterOfMass obj)[2]
399 | tempText = (props.l as string)+"x"+(props.h as string)+"x"+(props.w as string)
400 | )
401 | ------------------------------------------------------------------------------------ EVENTS
402 | on roll_props open do ( props = _props() )
403 | on roll_props close do
404 | (
405 | if objs != undefined do ( _cm.unselector objs )
406 | unregisterRedrawViewsCallback GW_txt_callback
407 | )
408 | ------------------------------------------------------------------------------------ objects selection
409 | on btn_sg pressed do
410 | (
411 | if objs != undefined do ( _cm.unselector objs )
412 | unregisterRedrawViewsCallback GW_txt_callback
413 | tempPoint = undefined
414 | btn_sg.caption = c_ss
415 | objs = _cm.getObjSelect()
416 | if objs != undefined do (
417 | index = 1
418 | btn_sg.caption = c_ss + "("+(objs.count as String)+")"
419 | _cm.selector objs indx:index
420 | obj = objs[index]
421 | validate()
422 | tempPoint = (_cm.CalculateVolumeAndCenterOfMass obj)[2]
423 | tempText = (props.l as string)+"x"+(props.h as string)+"x"+(props.w as string)
424 | registerRedrawViewsCallback GW_txt_callback
425 | )
426 | )
427 | ------------------------------------------------------------------------------------ automatic selection
428 | on btn_a changed state do
429 | (
430 | if state then (
431 | registerRedrawViewsCallback GW_txt_callback
432 | startSelector &callbackItem CallBackSel
433 | ) else (
434 | stopSelector &callbackItem
435 | unregisterRedrawViewsCallback GW_txt_callback
436 | )
437 | )
438 | ------------------------------------------------------------------------------------
439 | on txt_m entered val do ( lst_m.items = append (lst_m.items) val )
440 | on lst_m selected itm do (txt_m.text = lst_m.items[itm])
441 | on txt_3 entered val do ( lst_t.items = append (lst_t.items) val )
442 | on lst_t selected itm do (txt_3.text = lst_t.items[itm])
443 | ------------------------------------------------------------------------------------
444 | on drp_1 selected itm do
445 | (
446 | case itm of (
447 | 1:(
448 | props.orientation = "V"
449 | local t = copy props.H
450 | props.H = props.L
451 | props.L = t
452 | )
453 | 2:(
454 | props.orientation = "H"
455 | local t = copy props.L
456 | props.L = props.H
457 | props.H = t
458 | )
459 | )
460 | loadToUI props
461 | )
462 | ------------------------------------------------------------------------------------
463 | on btn_n pressed do (
464 | sel_shuffle &index (objs.count) _to:#up
465 | )
466 | on btn_n rightclick do (
467 | set_val_toObj obj objs _update_all:false
468 | sel_shuffle &index (objs.count) _to:#up
469 | )
470 | -- update option
471 | on btn_p pressed do (
472 | sel_shuffle &index (objs.count) _to:#down
473 | )
474 | on btn_p rightclick do (
475 | set_val_toObj obj objs _update_all:false
476 | sel_shuffle &index (objs.count) _to:#down
477 | )
478 | ------------------------------------------------------------------------------------ establece valores
479 | on btn_1 pressed do (
480 | set_val_toObj obj objs _update_all:false
481 | )
482 | -- apply to all
483 | on btn_1 rightclick do (
484 | set_val_toObj obj objs _update_all:true
485 | )
486 | ------------------------------------------------------------------------------------ Save to file
487 | on btn_lst_s pressed do
488 | (
489 | if objs != undefined then (
490 | local the_caption = (if txt_c.text != "" then txt_c.text else unsupplied)
491 | local f = _cm.prop_str objs caption:the_caption titles:str_titles_2 vals:vals_to_file
492 | if f != "" do _cm.saveFile f ("cuts_"+(txt_c.text)+".csv")
493 | free f
494 | dispose
495 | )
496 | )
497 | on btn_lst_a pressed do
498 | (
499 | local
500 | the_objs = objects,
501 | objs_count = the_objs.count,
502 | temp_nodelist = #()
503 | for i=1 to objs_count do (
504 | local temp_node = the_objs[i]
505 | if isValidNode temp_node then (
506 | if getUserProp temp_node "obj" != undefined then (
507 | append temp_nodelist temp_node
508 | )
509 | )
510 | )
511 | if temp_nodelist != #() then (
512 | local the_caption = (if txt_c.text != "" then txt_c.text else unsupplied)
513 | local f = _cm.prop_str temp_nodelist caption:the_caption titles:str_titles_2 vals:vals_to_file
514 | if f != "" do _cm.saveFile f ("cuts_"+(txt_c.text)+".csv")
515 | free f
516 | dispose
517 | )
518 | )
519 | ------------------------------------------------------------------------------------ report
520 | on btn_p1 pressed do (
521 | local p_area = spn_p4.value * (spn_p1.value * spn_p2.value )
522 | local o_area = 0.0
523 | if objs != undefined then (
524 | for i in objs do (
525 | local coords = _cm.getDims i
526 | local a = coords[2] * coords[1]
527 | o_area += a
528 | )
529 | ) else if obj != undefined then (
530 | local coords = _cm.getDims obj
531 | o_area = coords[2] * coords[1]
532 | )
533 | if o_area > 0.0 then (
534 | local d = spn_p3.value / 100
535 | local c_sheet = (o_area / p_area) + (d * o_area) / p_area
536 | -- (o_area / p_area) + ( (o_area / p_area) * (spn_p3.value /100 ))
537 | local str = StringStream ""
538 | format "% %\% %:-------------------- % u." strf_p1 (spn_p3.value) strf_p2 c_sheet to:str
539 | messageBox str
540 | )
541 | )
542 | ------------------------------------------------------------------------------------ change units
543 | on btn_m1 pressed do
544 | (
545 | local st = "" as stringStream
546 | format str_q1 (spn_f.value) to:st
547 | if (queryBox st) then (
548 | _cm.changeUnits objs factor:spn_f.value
549 | )
550 | )
551 | on btn_m2 pressed do
552 | (
553 | local st = "" as stringStream
554 | format str_q2 (spn_f.value) to:st
555 | if (queryBox st) then (
556 | _cm.changeUnits objs factor:spn_f.value up:false
557 | )
558 | )
559 | )
560 | m_props = newRolloutFloater r_title 280 950
561 | addRollout roll_props m_props border:true
562 | m_props.pos = [100,20]
563 | cui.RegisterDialogBar m_props style:#(#cui_dock_vert,#cui_floatable) parent:(Windows.GetMAXHWND()) minsize:[295,600] maxsize:[295,960]
564 | )
565 | PanelCuts()
566 | )
--------------------------------------------------------------------------------
/src/Panel_cuts/src/usericons/panel_cuts_16a.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/src/Panel_cuts/src/usericons/panel_cuts_16a.bmp
--------------------------------------------------------------------------------
/src/Panel_cuts/src/usericons/panel_cuts_16i.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/src/Panel_cuts/src/usericons/panel_cuts_16i.bmp
--------------------------------------------------------------------------------
/src/Panel_cuts/src/usericons/panel_cuts_24a.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/src/Panel_cuts/src/usericons/panel_cuts_24a.bmp
--------------------------------------------------------------------------------
/src/Panel_cuts/src/usericons/panel_cuts_24i.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/src/Panel_cuts/src/usericons/panel_cuts_24i.bmp
--------------------------------------------------------------------------------
/src/Panel_cuts/src/usermacros/BUMP_pcuts.mcr:
--------------------------------------------------------------------------------
1 | macroScript BUMP_panelcuts
2 | category:"BUMP tools"
3 | ButtonText:"PQT"
4 | toolTip:"Tool for generating wood panel cuts reports."
5 | icon: #("panel_cuts",1)
6 | (
7 | on execute do (
8 | fileIN @"$UserScripts/BUMP_panelCuts.ms"
9 | )
10 | )
--------------------------------------------------------------------------------
/src/Photographic_composition_guides/Icons/vcomp_24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/src/Photographic_composition_guides/Icons/vcomp_24.png
--------------------------------------------------------------------------------
/src/Photographic_composition_guides/Icons/vcomp_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/src/Photographic_composition_guides/Icons/vcomp_32.png
--------------------------------------------------------------------------------
/src/Photographic_composition_guides/Icons/vcomp_36.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/src/Photographic_composition_guides/Icons/vcomp_36.png
--------------------------------------------------------------------------------
/src/Photographic_composition_guides/Icons/vcomp_48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/src/Photographic_composition_guides/Icons/vcomp_48.png
--------------------------------------------------------------------------------
/src/Photographic_composition_guides/MacroScripts/BUMP_CompositionGuides.mcr:
--------------------------------------------------------------------------------
1 | /*
2 | VIEWPORT COMPOSITION GUIDES
3 | 2020
4 | 2022 - Added compatibility with Autodesk Exchange store
5 | */
6 | macroscript DSTLBX_vpComp
7 | category: "BUMP tools"
8 | buttontext: "Photographic composition guides"
9 | tooltip: "Photographic Composition guides"
10 | (
11 | -- this will contain an instance of the tool
12 | local vpCompositionGuides
13 | -- run each time the MacrosCript is executed...
14 | on execute do (
15 | -- vpCompositionGuides = undefined
16 | -- safe load with support for Exchange store
17 | fn loadScriptFile =
18 | (
19 | local ExchangeStorePath = "$publicExchangeStoreInstallPath/Photographic composition guides.bundle/Contents/scripts/vpCompositionGuides.mse"
20 | local LegacyPath = "$Scripts/vpCompositionGuides.mse"
21 |
22 | if doesFileExist ExchangeStorePath
23 | then (filein ExchangeStorePath)()
24 | else if doesFileExist LegacyPath
25 | then (filein LegacyPath)()
26 | else undefined
27 | )
28 |
29 | if vpCompositionGuides == undefined then (
30 | -- load the script file in to memory
31 | vpCompositionGuides = loadScriptFile()
32 | ) else (
33 | -- open the tool UI
34 | vpCompositionGuides.showUI()
35 | )
36 | )
37 | -- check ui button state
38 | on isChecked do if (isProperty vpCompositionGuides #roll_compGuide) then vpCompositionGuides.roll_compGuide != undefined
39 | )
--------------------------------------------------------------------------------
/src/Photographic_composition_guides/MacroScripts/BUMP_CompositionGuides_DEBUG.mcr:
--------------------------------------------------------------------------------
1 | /*
2 | VIEWPORT COMPOSITION GUIDES
3 | 2020
4 | 2022 - Added compatibility with Autodesk Exchange store
5 | */
6 | macroscript DSTLBX_vpComp
7 | category: "BUMP tools"
8 | buttontext: "Photographic composition guides"
9 | tooltip: "Photographic Composition guides"
10 | (
11 | -- this will contain an instance of the tool
12 | local vpCompositionGuides
13 | -- run each time the MacrosCript is executed...
14 | on execute do (
15 | -- vpCompositionGuides = undefined
16 | -- safe load with support for Exchange store
17 | fn loadScriptFile =
18 | (
19 | -- DEBUG ONLY!
20 | local ExchangeStorePath = "$publicExchangeStoreInstallPath/Photographic composition guides.bundle/Contents/scripts/vpCompositionGuides.ms"
21 | local LegacyPath = "$Scripts/vpCompositionGuides.ms"
22 |
23 | -- local ExchangeStorePath = "$publicExchangeStoreInstallPath/Photographic composition guides.bundle/Contents/scripts/vpCompositionGuides.mse"
24 | -- local LegacyPath = "$Scripts/vpCompositionGuides.mse"
25 |
26 | if doesFileExist ExchangeStorePath
27 | then (filein ExchangeStorePath)()
28 | else if doesFileExist LegacyPath
29 | then (filein LegacyPath)()
30 | else undefined
31 | )
32 |
33 | if vpCompositionGuides == undefined then (
34 | -- load the script file in to memory
35 | vpCompositionGuides = loadScriptFile()
36 | ) else (
37 | -- open the tool UI
38 | vpCompositionGuides.showUI()
39 | )
40 | )
41 | -- check ui button state
42 | on isChecked do if (isProperty vpCompositionGuides #roll_compGuide) then vpCompositionGuides.roll_compGuide != undefined
43 | )
--------------------------------------------------------------------------------
/src/Photographic_composition_guides/Scripts/vpCompositionGuides.mse:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HAG87/maxscript-assorted/962c5c5a67dac1201e0878e7f536395d815cd817/src/Photographic_composition_guides/Scripts/vpCompositionGuides.mse
--------------------------------------------------------------------------------
/src/Random_detach/BUMP_Random_detach.mcr:
--------------------------------------------------------------------------------
1 | macroScript BUMP_RndDetach
2 | category:"BUMP tools"
3 | ButtonText:"Rnd Detach"
4 | toolTip:"Random Poly Element Delect & Detach"
5 | (
6 | on execute do (
7 | filein("$userScripts/BUMP_Random_detach.ms");
8 | )
9 | )
10 |
--------------------------------------------------------------------------------
/src/Random_detach/BUMP_Random_detach.ms:
--------------------------------------------------------------------------------
1 | /*
2 | ------------------------------------------------------------------------------------------------------------------------
3 | RANDOM ELEMENTS SELECTOR
4 | ------------------------------------------------------------------------------------------------------------------------
5 | Author: BUMP 2014
6 | Version: 1.4
7 | Date: 07-03-2014
8 | Tested on: 3D Max 2014
9 | */
10 | (
11 | struct Detach (_node,_poly,_selection,_faces)
12 | local _detach = Detach()
13 | local returnElems, flattenArr, EleRandomizer, EleDetacher, setSelection
14 | try(destroyDialog roll_rndElem; cui.UnRegisterDialogBar roll_rndElem)catch()
15 | global roll_rndElem, _dock
16 | rollout roll_rndElem "Random Elements Select/Detach" width:90 height:366
17 | (
18 | button btn_c "CLOSE" width:90 height:20 pos:[0,0] align:#center
19 | GroupBox grp_1 "" width:90 height:5 pos:[0,20] align:#center
20 | label lbl_so "Select Objects" align:#center width:70 height:15
21 | fn pick_filter obj= (classOf obj==Editable_Poly)
22 | pickbutton pk_obj "Pick Poly" width:85 align:#center filter:pick_filter autoDisplay: true
23 | checkbutton chb_copy "Copy Src" width:85 align:#center highlightColor:(color 28 89 177)
24 | group "options"
25 | (
26 | label lbl_s "Seed" align:#left
27 | spinner spn_Seed "" width:70 align:#center range:[0,1000,150]
28 | label lbl_p "Percent" align:#left
29 | spinner spn_Percent "" width:70 height:16 align:#center range:[0,100,50]
30 | label lbl_id "Mat ID's" align:#left
31 | spinner spn_ID "" width:70 height:16 align:#center range:[0,100,1] type:#integer
32 | )
33 | button btn_Select "Select" width:85 height:40 align:#center
34 | button btn_Detach "Detach" width:85 height:25 align:#center offset:[0,5]
35 | button btn_DetachAll "Detach Unique" width:85 height:25 align:#center
36 | progressBar br_p value:0 color:(color 246 151 27) Width:90 height:6 pos:[0,360]align:#center
37 | local prev_pos=[10,10]
38 | local SDrag=false
39 | fn updateUI obj: =(
40 | roll_rndElem.lbl_so.caption= if obj!= unsupplied then "Selected" else "Select Object"
41 | for i=1 to roll_rndElem.controls.count do (if i>4 then roll_rndElem.controls[i].enabled=(if obj== unsupplied then false else true))
42 | )
43 | on roll_rndElem open do updateUI()
44 | on roll_rndElem lbuttondown p do (sDrag=true; prev_pos=p)
45 | on roll_rndElem mouseMove p do (print p; if sDrag==true then (try(SetDialogPos roll_rndElem (mouse.screenpos-prev_pos))catch()))
46 | on roll_rndElem lbuttonup p do sDrag=false
47 | on pk_obj picked obj do updateUI obj:obj
48 | on btn_c pressed do (if roll_rndElem.dialogBar==true then (cui.UnRegisterDialogBar roll_rndElem; destroyDialog roll_rndElem) else destroyDialog roll_rndElem)
49 | on btn_c rightclick do (popUpMenu _dock rollout:roll_rndElem)
50 | on btn_Select pressed do setSelection sel: roll_rndElem.pk_obj.object
51 | on btn_Detach pressed do (if _detach._node!=undefined then EleDetacher _detach._node _detach._poly _detach._selection _detach._faces roll_rndElem.spn_ID.value unit:false)
52 | on btn_DetachAll pressed do (if _detach._node!=undefined then EleDetacher _detach._node _detach._poly _detach._selection _detach._faces roll_rndElem.spn_ID.value unit:true)
53 | )--End Rollout
54 | rcmenu _dock
55 | (
56 | menuitem rc_dl "Dock Left"
57 | menuitem rc_dr "Dock Right"
58 | separator b
59 | menuitem rc_ud "Undock"
60 | on rc_dl picked do(
61 | if roll_rndElem.dialogBar==true then(
62 | cui.DockDialogBar roll_rndElem #cui_dock_left
63 | )else(
64 | cui.RegisterDialogBar roll_rndElem style:#(#cui_dock_vert,#cui_floatable)
65 | cui.DockDialogBar roll_rndElem #cui_dock_left
66 | )
67 | )
68 | on rc_dr picked do(
69 | if roll_rndElem.dialogBar==true then(
70 | cui.DockDialogBar roll_rndElem #cui_dock_right
71 | )else(
72 | cui.RegisterDialogBar roll_rndElem style:#(#cui_dock_vert,#cui_floatable)
73 | cui.DockDialogBar roll_rndElem #cui_dock_right
74 | )
75 | )
76 | on rc_ud picked do(if roll_rndElem.dialogBar==true then cui.UnRegisterDialogBar roll_rndElem)
77 | )--End RC
78 | fn progress val: tot: =(
79 | if val!=unsupplied and tot!=unsupplied then roll_rndElem.br_p.value= ((val*100)/tot) else roll_rndElem.br_p.value=0
80 | )
81 | fn flattenArr arr=(
82 | local tempArr=#()
83 | for i in arr do join tempArr i
84 | tempArr
85 | )
86 | fn returnElems obj=(
87 | try(
88 | local num_faces=polyop.getNumFaces obj
89 | local elem_arr=#()
90 | local done=#()
91 | for f=1 to num_faces do(
92 | if (findItem done f)==0 then (
93 | local faces= (polyop.getElementsUsingFace obj f) as BitArray
94 | append elem_arr faces
95 | join done faces
96 | progress val:f tot:num_faces
97 | )
98 | )
99 | progress()
100 | free done
101 | )catch(return undefined)
102 | elem_arr
103 | )
104 |
105 | fn EleRandomizer obj eles delta: dSeed: sel:false =(
106 | if eles.count>1 then(
107 | if dSeed==unsupplied then (dSeed= eles.count)
108 | seed dSeed
109 | local rands=#()
110 | local umbral = if delta <1 or delta!=unsupplied then floor(eles.count*delta) else eles.count
111 | for r=1 to umbral do(
112 | local rnd=floor(random 1.0 eles.count)
113 | if (findItem rands eles[rnd])==0 then(
114 | append rands eles[rnd]
115 | progress val:r tot:umbral
116 | )
117 | )
118 | progress()
119 | )else rands=eles
120 | local flat=(flattenArr rands)
121 | _detach._faces=flat
122 | polyop.setFaceSelection obj #none
123 | polyop.setFaceSelection obj (flat as BitArray)
124 | if sel==true then (
125 | max modify mode
126 | modPanel.setCurrentObject obj
127 | subobjectlevel = 4
128 | return rands
129 | )else return rands
130 | )
131 | fn EleDetacher nod obj eles faces rID unit:true =(
132 | if eles.count==1 and not (queryBox "WARING! Only one element selected, do you want to continue?") then return undefined
133 | case unit of (
134 | true:(
135 | undo on(
136 | for i=1 to eles.count do(
137 | polyop.setFaceMatID obj eles[i] (floor(random 1 rID))
138 | polyop.detachFaces obj eles[i] name: (uniqueName "Elem_") delete:false asNode:true node:nod
139 | progress val:1 tot:eles.count
140 | )
141 | polyop.deleteFaces obj faces
142 | progress()
143 | )
144 | )
145 | false:(
146 | undo on (polyop.detachFaces obj (faces as BitArray) name:(uniqueName "Elem_") asNode:true node:nod)
147 | )
148 | )
149 | )
150 | fn setSelection sel: =(
151 | if classOf sel.baseobject==Editable_poly then(
152 | if roll_rndElem.chb_copy.checked==true then copy sel
153 | _detach._node= sel
154 | _detach._poly= _detach._node.baseobject
155 | _detach._selection= EleRandomizer _detach._poly (returnElems _detach._poly) delta:((roll_rndElem.spn_Percent.value/100)) dSeed: roll_rndElem.spn_Seed.value sel:true
156 | return true
157 | )else return false
158 | )
159 | createdialog roll_rndElem pos:[100,200] style:#()
160 | )--END OF SCRIPT
--------------------------------------------------------------------------------
/src/Random_detach/min/min_BUMP_Random_detach.ms:
--------------------------------------------------------------------------------
1 | (struct Detach(_node,_poly,_selection,_faces);local _detach=Detach();local returnElems,flattenArr,EleRandomizer,EleDetacher,setSelection;try(destroyDialog roll_rndElem;cui.UnRegisterDialogBar roll_rndElem)catch();global roll_rndElem,_dock;rollout roll_rndElem"Random Elements Select/Detach"width:90 height:366(button btn_c"CLOSE"width:90 height:20 pos:[0,0]align:#center;GroupBox grp_1""width:90 height:5 pos:[0,20]align:#center;label lbl_so"Select Objects"align:#center width:70 height:15;fn pick_filter obj=(classOf obj==Editable_Poly);pickbutton pk_obj"Pick Poly"width:85 align:#center filter:pick_filter autoDisplay:true;checkbutton chb_copy"Copy Src"width:85 align:#center highlightColor:(color 28 89 177);group"options"(label lbl_s"Seed"align:#left;spinner spn_Seed""width:70 align:#center range:[0,1000,150];label lbl_p"Percent"align:#left;spinner spn_Percent""width:70 height:16 align:#center range:[0,100,50];label lbl_id"Mat ID's"align:#left;spinner spn_ID""width:70 height:16 align:#center range:[0,100,1]type:#integer);button btn_Select"Select"width:85 height:40 align:#center;button btn_Detach"Detach"width:85 height:25 align:#center offset:[0,5];button btn_DetachAll"Detach Unique"width:85 height:25 align:#center;progressBar br_p value:0 color:(color 246 151 27)Width:90 height:6 pos:[0,360]align:#center;local prev_pos=[10,10];local SDrag=false;fn updateUI obj: =(roll_rndElem.lbl_so.caption=if obj!=unsupplied then"Selected"else"Select Object";for i=1 to roll_rndElem.controls.count do(if i>4 then roll_rndElem.controls[i].enabled=(if obj==unsupplied then false else true)));on roll_rndElem open do updateUI();on roll_rndElem lbuttondown p do(sDrag=true;prev_pos=p);on roll_rndElem mouseMove p do(print p;if sDrag==true then(try(SetDialogPos roll_rndElem(mouse.screenpos-prev_pos))catch()));on roll_rndElem lbuttonup p do sDrag=false;on pk_obj picked obj do updateUI obj:obj;on btn_c pressed do(if roll_rndElem.dialogBar==true then(cui.UnRegisterDialogBar roll_rndElem;destroyDialog roll_rndElem)else destroyDialog roll_rndElem);on btn_c rightclick do(popUpMenu _dock rollout:roll_rndElem);on btn_Select pressed do setSelection sel:roll_rndElem.pk_obj.object;on btn_Detach pressed do(if _detach._node!=undefined then EleDetacher _detach._node _detach._poly _detach._selection _detach._faces roll_rndElem.spn_ID.value unit:false);on btn_DetachAll pressed do(if _detach._node!=undefined then EleDetacher _detach._node _detach._poly _detach._selection _detach._faces roll_rndElem.spn_ID.value unit:true));rcmenu _dock(menuItem rc_dl"Dock Left";menuItem rc_dr"Dock Right";separator b;menuItem rc_ud"Undock";on rc_dl picked do(if roll_rndElem.dialogBar==true then(cui.DockDialogBar roll_rndElem#cui_dock_left)else(cui.RegisterDialogBar roll_rndElem style:#(#cui_dock_vert,#cui_floatable);cui.DockDialogBar roll_rndElem#cui_dock_left));on rc_dr picked do(if roll_rndElem.dialogBar==true then(cui.DockDialogBar roll_rndElem#cui_dock_right)else(cui.RegisterDialogBar roll_rndElem style:#(#cui_dock_vert,#cui_floatable);cui.DockDialogBar roll_rndElem#cui_dock_right));on rc_ud picked do(if roll_rndElem.dialogBar==true then cui.UnRegisterDialogBar roll_rndElem));fn progress val: tot: =(if val!=unsupplied and tot!=unsupplied then roll_rndElem.br_p.value=((val*100)/tot)else roll_rndElem.br_p.value=0);fn flattenArr arr=(local tempArr=#();for i in arr do join tempArr i;tempArr);fn returnElems obj=(try(local num_faces=polyop.getNumFaces obj;local elem_arr=#();local done=#();for f=1 to num_faces do(if(findItem done f)==0 then(local faces=(polyop.getElementsUsingFace obj f)as BitArray;append elem_arr faces;join done faces;progress val:f tot:num_faces));progress();free done)catch(return undefined);elem_arr);fn EleRandomizer obj eles delta: dSeed:sel:false=(if eles.count>1 then(if dSeed==unsupplied then(dSeed=eles.count);seed dSeed;local rands=#();local umbral=if delta<1 or delta!=unsupplied then floor(eles.count*delta)else eles.count;for r=1 to umbral do(local rnd=floor(random 1.0 eles.count);if(findItem rands eles[rnd])==0 then(append rands eles[rnd];progress val:r tot:umbral));progress())else rands=eles;local flat=(flattenArr rands);_detach._faces=flat;polyop.setFaceSelection obj#none;polyop.setFaceSelection obj(flat as BitArray);if sel==true then(max modify mode;modPanel.setCurrentObject obj;subobjectlevel=4;return rands)else return rands);fn EleDetacher nod obj eles faces rID unit:true=(if eles.count==1 and not(queryBox"WARING! Only one element selected, do you want to continue?")then return undefined;case unit of(true:(undo on(for i=1 to eles.count do(polyop.setFaceMatID obj eles[i](floor(random 1 rID));polyop.detachFaces obj eles[i]name:(uniqueName"Elem_")delete:false asNode:true node:nod;progress val:1 tot:eles.count);polyop.deleteFaces obj faces;progress()));false:(undo on(polyop.detachFaces obj(faces as BitArray)name:(uniqueName"Elem_")asNode:true node:nod))););fn setSelection sel: =(if classOf sel.baseobject==Editable_poly then(if roll_rndElem.chb_copy.checked==true then copy sel;_detach._node=sel;_detach._poly=_detach._node.baseobject;_detach._selection=EleRandomizer _detach._poly(returnElems _detach._poly)delta:((roll_rndElem.spn_Percent.value/100))dSeed:roll_rndElem.spn_Seed.value sel:true;return true)else return false);createdialog roll_rndElem pos:[100,200]style:#())
--------------------------------------------------------------------------------
/src/VrayMtlPopulate/BUMP_VrayMtlPopulate.mcr:
--------------------------------------------------------------------------------
1 | macroScript BUMP_VrayMts_gray
2 | category:"BUMP tools"
3 | ButtonText:"VrayMtl"
4 | toolTip:"Populate Medit Slots with Vray Materials"
5 | (
6 | on execute do (
7 | local setMat = fileIn @"$userScripts/BUMP_VrayMtlPopulate.ms"
8 | setMat.setSlots rndColor:false chk:(queryBox "Conserve scene materials slots?")
9 | )
10 | )
11 | macroScript BUMP_VrayMts_rnd
12 | category:"BUMP tools"
13 | ButtonText:"VrayMtl rnd"
14 | toolTip:"Populate Medit Slots with Vray Materials, apply random diffuse color"
15 | (
16 | on execute do (
17 | local setMat = fileIn @"$userScripts/BUMP_VrayMtlPopulate.ms"
18 | setMat.setSlots rndColor:true chk:(queryBox "Conserve scene materials slots?")
19 | )
20 | )
21 |
--------------------------------------------------------------------------------
/src/VrayMtlPopulate/BUMP_VrayMtlPopulate.ms:
--------------------------------------------------------------------------------
1 | /* Vray Mat Populate v2.4
2 | AUTHOR: BUMP
3 | DATE: 17-09-2017
4 | TESTED ON: 3ds Max 2014+
5 | ----------------------------------------------------------------------------------------------------------
6 | This scipt replaces Medir Slots with (v-ray) materials. options: random color / gray color / retain existing materials
7 | ----------------------------------------------------------------------------------------------------------
8 | */
9 | (
10 | struct matPop
11 | (
12 | /*
13 | * rand: random color true|false
14 | * id Material editor slot [1-24]
15 | * prefix: name prefix
16 | * matClass: material type i.e: vraymtl, CoronaMtl, ...
17 | */
18 | mapped fn assignMat id rand prefix:"VRayMtl_" matClass:vraymtl =
19 | (
20 | if matClass != undefined then (
21 | local mat = matClass ()
22 | -- Name
23 | mat.name = prefix + (abs(random 1 100)) as String
24 | -- Test for unique name
25 | if not (okMtlForScene mat) then (mat.name += "_1")
26 | -- Random color
27 | if rand then (
28 | local
29 | R = abs (random 1 254),
30 | G = abs (random 1 254),
31 | B = abs (random 1 254)
32 | mat.diffuse = color R G B
33 | )
34 | -- assign to material slot
35 | setMeditMaterial id mat
36 | -- options
37 | showTextureMap mat true
38 | setMTLMEditFlags mat #{2..4}
39 | -- return
40 | )
41 | true
42 | ),
43 | fn setSlots rndColor:false chk:true prefix:"VRayMtl_" matClass:vraymtl =
44 | (
45 | local matIndx = #{1..24} as Array
46 | if chk then (
47 | for i=1 to matIndx.count where ((findItem sceneMaterials meditMaterials[i]) == 0) do (
48 | assignMat i rndColor prefix:prefix matClass:matClass
49 | )
50 | ) else (
51 | assignMat matIndx rndColor prefix:prefix matClass:matClass
52 | )
53 | true
54 | )
55 | )
56 | _t = matPop()
57 | )
--------------------------------------------------------------------------------
/src/plugin/BUMP_resizer.ms:
--------------------------------------------------------------------------------
1 | plugin simpleMod resizer
2 | name:"Resize"
3 | classID:#(683325,456281)
4 | version:1.0
5 | (
6 | fn getNode = (refs.dependentnodes this)[1]
7 | fn getLimits obj =
8 | (
9 | local _min = getModContextBBoxMin obj this
10 | local _max = getModContextBBoxMax obj this
11 | _max - _min
12 | )
13 | parameters main rollout:params
14 | (
15 | x_amount type:#worldunits ui:SpinX default:100
16 | y_amount type:#worldunits ui:SpinY default:100
17 | z_amount type:#worldunits ui:SpinZ default:100
18 |
19 | proportion type:#point3 default:[1.0,1.0,1.0]
20 |
21 | newDims type:#point3 default:[100.0,100.0,100.0]
22 |
23 | isProportioned type:#boolean ui:Chk1 default:false
24 |
25 | lk_x type:#boolean ui:clk_x default:true
26 | lk_y type:#boolean ui:clk_y default:true
27 | lk_z type:#boolean ui:clk_z default:true
28 |
29 | on x_amount set val do (if not loading then newDims.x = val)
30 | on y_amount set val do (if not loading then newDims.y = val)
31 | on z_amount set val do (if not loading then newDims.z = val)
32 | )
33 | /*
34 | on attachedToNode nd do (
35 | if nd != undefined then (
36 | proportion = getLimits nd
37 | newDims = proportion
38 | )
39 | )
40 | */
41 | -- on clone nd do ()
42 | rollout params "Resize Parameters"
43 | (
44 | spinner SpinX "X : " type:#worldunits range:[-10000000.0,10000000.0,100.0]
45 | spinner SpinY "Y : " type:#worldunits range:[-10000000.0,10000000.0,100.0]
46 | spinner SpinZ "Z : " type:#worldunits range:[-10000000.0,10000000.0,100.0]
47 | Checkbox Chk1 "Keep proportions"
48 |
49 | group "Link proportions"
50 | (
51 | Checkbox clk_x " X" align:#left across:3
52 | Checkbox clk_y " Y" align:#left
53 | Checkbox clk_z " Z" align:#left
54 | )
55 |
56 | on SpinX changed val do (
57 | if isProportioned then (
58 | proportion = getLimits (getNode())
59 | local delta = proportion.x / val
60 | if lk_y and lk_x then y_amount = proportion.y / delta
61 | if lk_z and lk_x then z_amount = proportion.z / delta
62 | )
63 | )
64 |
65 | on SpinY changed val do (
66 | if isProportioned then (
67 | proportion = getLimits (getNode())
68 | local delta = proportion.y / val
69 | if lk_x and lk_y then x_amount = proportion.x / delta
70 | if lk_z and lk_y then z_amount = proportion.z / delta
71 | )
72 | )
73 |
74 | on SpinZ changed val do (
75 | if isProportioned then (
76 | proportion = getLimits (getNode())
77 | local delta = proportion.z / val
78 | if lk_x and lk_z then x_amount = proportion.x / delta
79 | if lk_y and lk_z then y_amount = proportion.y / delta
80 | )
81 | )
82 | )
83 | rollout help "About" rolledUp:true
84 | (
85 | label lbl_1 "Node Resize modifier"
86 | hyperLink lnk_1 "Atelier Bump" color:(color 200 150 0) address:"https://atelierbump.com" align:#center
87 | )
88 | on map i p do
89 | (
90 | if extent.x != 0.0d0 then p.x = p.x / extent.x * newDims.x
91 | if extent.y != 0.0d0 then p.y = p.y / extent.y * newDims.y
92 | if extent.z != 0.0d0 then p.z = p.z / extent.z * newDims.z
93 | p
94 | )
95 | )
--------------------------------------------------------------------------------