[Closed] Fastest Attach – Collaborative Tool by CGS members
Hi, I think it would be an interesting experiment to see if we here at CGS could try collaborating on making a full “maxscript tool” together, because I was really impressed by the previous thread and the collaborating effort, speed of development and amazing results I think If we would collaborate and use everybody’s different strengths and knowledge, we should be able to create some amazing stuff.
To kick it off I started on making the tool: Fastest Attach (inspired by the previous thread)
Objective:
– Create the fastest attach tool possible
– Have it be stable/reliable
– Easy To use
Rules:
– Anyone can contribute, Ui improvements, speed improvements, streamline of code, etc
I[/I]
V0.11
-- Fastest Attach v0.11
-- Patrik Fröhler
-- 2017-03-08
-- Collaboration script tool
global fastestAttach
global fastestAttachWindow
global fastestAttachDB
if fastestAttachWindow != undefined then (
if fastestAttachWindow.ui != undefined then (
DestroyDialog fastestAttachWindow.ui
)
)
(
DB
sRo
sfn
bfn
struct sDB -- DATABASE
(
targetObj,
attachObj,
tmpMesh,
algorithmSelected
)
struct sRo -- UI
(
Ui,
/* #ui.2 | Main Ui */
fn MainRo = (
rollout uiFastestAttach "Fastest Attach v0.11" width:256 height:275
( -- ! TODO ! >> Fix so bitmaps load from URL
local hBitmap = (openBitMap @"http://www.patan77.com/fastest_attach/fastest_attach_header_03.png")
local m1Bitmap = (openBitMap @"http://www.patan77.com/fastest_attach/fastest_attach_m01.png")
local m1BitmapH = (openBitMap @"http://www.patan77.com/fastest_attach/fastest_attach_m01_hover.png")
local fBitmap = (openBitMap @"http://www.patan77.com/fastest_attach/fastest_attach_footer_01.png")
imgTag img_header bitmap:hBitmap align:#center offset: [0,-5] transparent:[255,0,255]
imgTag img_m1 bitmap:m1Bitmap align:#left offset: [-10,-5] transparent:[255,0,255]
pickbutton pbtn_target "Pick --> Target Object" tooltip:"Select object to attach to" width:256 height:25 offset: [0,0]
button btn_attach "Select [ ] Source Objects" width:256 tooltip:"Select object you want to attach" height:25
radiobuttons rbtn_algorithm labels:#("Pflow", "kFast") default:1
imgTag imgfooter bitmap:fBitmap align:#center transparent:[255,0,255] offset: [0,-5]
label lb_status ""
on pbtn_target picked obj do (
if obj != undefined then (
DB.targetObj = obj
pbtn_target.text = obj.name
pbtn_target.tooltip = "Rightclick to clear."
sfn.fn_setStatusBar "" --> #s.8
)
)
on pbtn_target rightclick do (
DB.targetObj = undefined
pbtn_target.text = "Pick --> Target Object"
pbtn_target.tooltip = "Select main object you want to attach to."
sfn.fn_setStatusBar "" --> #s.8
)
on btn_attach pressed do (
-- selectByName() -- ! TODO ! >> ADD Filter to hide DB.targetObj in the selection list
actionMan.executeAction 0 "50029" -- Selection: Select By Name
if $ != undefined then (
DB.attachObj = (selection as array)
btn_attach.text = ((DB.attachObj[1].name as string) + "...")
btn_attach.tooltip = "Rightclick to clear."
sfn.run() --> #s.1
)
)
on btn_attach rightclick do (
DB.attachObj = undefined
btn_attach.text = "Select [ ] Source Objects"
btn_attach.tooltip = "Select object you want to attach."
)
on img_m1 mouseover do (
img_m1.bitmap = m1BitmapH
)
on img_m1 click do (
ShellLaunch "www.patan77.com" ""
)
on img_m1 mouseout do (
img_m1.bitmap = m1Bitmap
)
on changed state do (
DB.algorithmSelected = state
)
)
),
/* #ui.1 | Create Main Ui */
fn run = (
Ui = sRo.MainRo() --> #ui.2
Createdialog Ui bgcolor:[68,68,68]
)
)
struct sfn -- FUNCTIONS
(
/* #s.10 | Convert To edit poly */
fn fn_convertTOPoly inArr = (
for i in inArr do (
if classof i != Editable_Poly then (
converttopoly i
)
)
return inArr
),
/* #s.9 | Fast attach */
fn fn_kFast_attach inArr = (
sfn.fn_convertTOPoly inArr--> #s.10
local k = 1
attach = polyop.attach
while nodes.count > 1 do
(
k += 1
attach nodes[k-1] nodes[k]
deleteItem nodes k
if k >= nodes.count do k = 1
)
DB.tmpMesh = inArr[1]
),
/* #s.8 | Set StatusBar Text */
fn fn_setStatusBar inString = (
fastestAttachWindow.ui.lb_status.text = inString
),
/* #s.7 | Reset Script */
fn fn_resetScript = (
DB.targetObj = undefined
DB.attachObj = undefined
DB.tmpMesh = undefined
fastestAttachWindow.ui.pbtn_target.text = "Pick --> Target Object"
fastestAttachWindow.ui.pbtn_target.tooltip = "Select object to attach to."
fastestAttachWindow.ui.btn_attach.text = "Select [ ] Source Objects."
fastestAttachWindow.ui.btn_attach.tooltip = "Select object you want to attach."
),
/* #s.6 | Check if Source and Target Object exist*/
fn fn_chk_sourceTarget = (
if DB.targetObj != undefined then (
if DB.attachObj != undefined then (
return true
)else(
messageBox "Please select Source Objects."
sfn.fn_setStatusBar "No Source Objects selected." --> #s.8
)
)
messageBox "Please select Target Object."
sfn.fn_setStatusBar "No Source Objects Taget." --> #s.8
return false
),
/* #s.5 | Create Pflow */
fn fn_pflow = (
local currentSliderTime
-- ! TODO ! >> Fix pCont.particleScale
local pfScript =
("
on ChannelsUsed pCont do
(
pCont.useShape = true
pCont.useScale = true
pCont.usePosition = true
pCont.useOrientation = true
)
on Proceed pCont do
(
count = pCont.NumParticles()
for i in 1 to count do
(
pCont.particleIndex = i
pCont.particleShape = fastestAttachDB.attachObj[ i ].mesh
-- pCont.particleScale = fastestAttachDB.attachObj[ i ].scale
pCont.particlePosition = fastestAttachDB.attachObj[ i ].pos
eR = (quatToEuler fastestAttachDB.attachObj[ i ].rotation)
pCont.particleOrientation = [eR.x,eR.y,eR.z]
)
)
")
local pf = PF_source Quantity_Viewport:100 Particle_Amount_Limit:1000000
ParticleFlow.BeginEdit()
pf.AppendAction (RenderParticles())
local e1 = Event name:"pfTempEvent"
e1.AppendAction (Birth Amount: (DB.attachObj.count) Emit_Start:0 Emit_Stop: 0)
e1.AppendAction (Script_Operator Proceed_Script: pfScript)
e1.AppendAction (DisplayParticles type:6)
ParticleFlow.EndEdit()
pf.appendInitialActionList e1
local m = Mesher()
m.pick = pf
DB.tmpMesh = (snapshot m)
particleFlow.BeginEdit()
particleFlow.delete $'pfTempEvent'
particleFlow.EndEdit()
delete m
delete pf
),
/* #s.4 | Check if object mesh or poly */
fn fn_checkIfMeshPoly inObject = (
if classof inObject != Editable_Poly then (
if classof inObject != Editable_Mesh then (
local alert = (queryBox ("Do you want to convert " + (DB.targetObj.name as string) + " to Edit poly"))
if alert then (
converttopoly DB.targetObj
)else(
return false
)
)
)
return true
),
/* #s.3 | Attach Function */
fn fn_attach = (
if (sfn.fn_checkIfMeshPoly DB.targetObj) then ( --> #s.4
local timeStart = timestamp()
sfn.fn_setStatusBar "Running: Fastest Attach" --> #s.8
case DB.algorithmSelected of
(
1: sfn.fn_pflow() --> #s.5
2: sfn.fn_kFast_attach() --> #s.9
)
if classof DB.targetObj == Editable_Poly then (
polyop.attach DB.targetObj DB.tmpMesh
)else(
meshop.attach DB.targetObj DB.tmpMesh
)
delete DB.attachObj
sfn.fn_setStatusBar ("Done: Fastest Attach " + (((timestamp() - timeStart)/1000.0) as string) + " sec") --> #s.8
sfn.fn_resetScript() --> #s.7
)else(
messageBox "Attach Canceled"
sfn.fn_setStatusBar "Attach Canceled" --> #s.8
)
),
/* #s.2 | sfn Script */
fn script = (
sfn.fn_initiate() --> #s.0
sfn.fn_attach() --> #s.3
),
/* #s.1 | sfn Run */
fn run = (
gc()
with redraw off(
with undo off(
sfn.script() --> #s.2
)
)
gc()
),
/* #s.0 | sfn initiate DB values */
fn fn_initiate = (
DB.algorithmSelected = 1
)
)
/* #1 | Main Build */
struct bfn
(
fn build = (
with undo false
(
fastestAttachWindow.run() --> #ui.1
)
)
)
DB = sDB()
fastestAttach = bfn()
fastestAttachWindow = sRo()
fastestAttachDB = DB
ok
)
fastestAttach.build() --> #1
- Radio-buttons
- kFast attach algorithm
– Older versions:
#0.1
Thanks & good luck.
First obvious thing needed to get fixed are the ability to load the Ui images from web url,
( I think it probably need like dotnet WebRequest or something? )
graphics are missing…but that’s not important.
after I selected the ‘Target’, then to select the Source, the list pops up, it should Exclude the Target itself (if possible)
So if I ‘know’ not to include the Target, it works great…but if I inadvertently include the Target…it won’t work, obviously it can’t attach it to itself…
Thanks again.
have 1 object,
pick that as Target, select Source…pick Target itself
Poooooof…gone !!! Damn fast too !!!
have a closed shape, Circle say…create a few more circles, Rectangles whatever
Target: 1st Circle
Source: rest of shapes
It asks if want to convert to Poly…sure, great, go ahead
Only 1st shape remains (which is now Poly), all others gone.