Utility SketchupMAX "SketchUp.3ds v3.3" ( global mmatset global groupsel = "none selected" global incount = 0 global gname global lyrname fn fnCOLLAPSE = ( if selection.count < 1 then ( return 0 ) else ( if selection.count > 1 then ( rawmesh = editable_mesh() rawmesh.name = "sketchup-import-mesh" for i in 1 to selection.count do ( if ((selection[i].baseobject as string) == "Editable Mesh") then ( meshop.attach rawmesh selection[i] attachMat:#IDtoMat condenseMat:true deletesourceNode:false ) ) delete selection select rawmesh ) else ( -- MODEL IMPORTED AS A SINGLE OBJECT ) return 1 ) ) fn fnFACES mesh= -- simply returns a list of faces (as numbers) in a mesh ( k = 0 facelist = #() for i = 1 to (getNumFaces mesh) do ( k = k+1 facelist[k] = i ) return facelist ) fn fnIMP= ( macros.run "Scene Explorer" "SELayerExplorer" (layermanager.getlayer 0).current = true actionMan.executeAction 0 "40043" -- Selection: Select None actionMan.executeAction 0 "40010" cont = fnCOLLAPSE() rawmesh = selection[1] if cont == 1 then ( global multimat = rawmesh.material if (classof multimat) == Multimaterial then ( global mmatset = #() global incount = multimat.count for j = 1 to multimat.count do -- for every material imported ( k = 0 facelist = #() for i = 1 to (getNumFaces rawmesh) do -- find faces for each material ( facematid = getFaceMatID rawmesh i if (facematid == j) then ( k = k+1 facelist[k] = i setFaceMatID rawmesh i 1 ) ) -- below runs once for each material print rawmesh.material[j].name rawmesh.material[j].name = rawmesh.material[j].name + ".skp" newmeshset = meshop.detachfaces rawmesh facelist delete:true asmesh:true newmesh = editable_mesh() newmesh.mesh = newmeshset newmesh.name = multimat[j].name newmesh.material = rawmesh.material[j] append mmatset newmesh ) delete rawmesh return cont ) else ( messagebox "Model contains only one material layer - group options unavailable" return cont ) ) else ( messagebox "Nothing imported" ) ) fn fnISGRP obj = ( if (classof obj == dummy) then true else false ) fn fnDNODES = -- filters for deleted objects after import and updates import set ( i = 0 cnt = mmatset.count while i < cnt do ( i = i+1 nt = isValidNode(mmatset[i]) if nt == false then ( deleteItem mmatset i cnt = cnt-1 i = i-1 ) ) return cnt ) fn fnLYR lyrname = ( for i = 0 to (LayerManager.count - 1) do ( lyr = LayerManager.getlayer i print lyr.name if lyrname == lyr.name then ( return true ) ) return false ) fn fnNEWGROUP = ( if fnDNODES() >0 then ( select mmatset actionMan.executeAction 0 "40140" -- Groups: Group gname = selection[1].parent.name gname = "[" + gname + "]" selection[1].parent.name = gname global gobj = selection[1].parent if gobj == undefined then ( messagebox "nothing selected" actionMan.executeAction 0 "40043" -- Selection: Select None return false ) gname = gobj.name unique = false k = 1 lyrname = (k as string) + "." + gname while fnLYR(lyrname) == true do -- not unique ( k = k + 1 lyrname = (k as string) + "." + gname ) newLayer = LayerManager.newLayerFromName lyrname for n in (selection as array) do ( newLayer.addnode n ) actionMan.executeAction 0 "40142" -- Groups: Group Open return true ) ) fn fnMODREC groupset = -- records modifiers ( global modset = #() cnt = groupset.count for i = 1 to cnt do ( modobj = #() for k = 1 to groupset[i].modifiers.count do ( print groupset[i].modifiers[k].name mod = groupset[i].modifiers[k].enabled append modobj mod ) append modset modobj ) for i = 1 to cnt do ( for k = 1 to groupset[i].modifiers.count do ( groupset[i].modifiers[k].enabled = false ) ) ) fn fnMODRES groupset = -- restores modifiers ( cnt = groupset.count for i = 1 to cnt do ( for k = 1 to groupset[i].modifiers.count do ( state = modset[i][k] groupset[i].modifiers[k].enabled = state ) ) actionMan.executeAction 0 "40043" -- Selection: Select None return "END" ) fn fnREP groupsel = -- replace old geometry with new geometry ( delset = #() j = 0 groupset = groupsel.children for i = 1 to groupset.count do -- this is only to locate any missing objects in the new set ( oldobj = groupset[i] match = false for k = 1 to mmatset.count do -- search newset for matching name ( newobj = mmatset[k] if newobj.name == oldobj.name then ( match = true ) ) if (match == false) then ( text = "existing " + oldobj.name + " is missing from import, delete it?" val = yesnocancelbox text if val == #yes then ( j = j+1 delset[j] = oldobj ) ) ) fnMODREC(groupset) for i = 1 to mmatset.count do ( newobj = mmatset[i] match = false for k = 1 to groupset.count do -- search group for matching name ( oldobj = groupset[k] if oldobj.name == newobj.name then ( tmat = oldobj.material.name print "OLD OBJECT MATERIAL:" print tmat print "NEW OBJECT MATERIAL:" print newobj.material.name mods = oldobj.modifiers match = true print (oldobj as string) facelist = fnFACES oldobj meshop.attach oldobj newobj meshop.deleteFaces oldobj facelist delIsoVerts:true oldobj.material = sceneMaterials[tmat] exit ) ) if (match == false) then ( text = newobj.name + " is a new material object, click yes to ADD it to the group, no to DELETE it, or cancel to LEAVE it" val = yesnocancelbox text if val == #yes then ( attachNodesToGroup newobj groupsel parLayer = groupsel.layer lyrname = groupsel.layer.name parLayer.addnode newobj ) if val == #no then ( delete newobj ) ) ) delete delset fnMODRES(groupset) global mmatset = undefined ) fn fnDSN = -- aborts update if any new objects were deleted after import ( i = 1 cnt = mmatset.count nmatset = #() while i <= cnt do ( print mmatset[i] if IsValidNode mmatset[i] then ( append nmatset mmatset[i] ) else ( print mmatset[i] ) i = i+1 ) mmatset = nmatset ) fn fnGRPS var = -- SEARCHES FOR A SUPPLIED GROUP NAME IN A SCENE ( print "function fnGRPS" groups = for o in helpers where isGroupHead o collect o g = 0 i = 1 while i <= groups.count do ( mssg = groups[i].name --print mssg if groups[i].name == var then ( g = i ) i = i+1 ) if g > 0 then ( return groups[g] ) else ( return undefined ) ) fn fnLYRPUT objset = ( print "function fnLYRPUT" newLayer = layermanager.getlayerfromname lyrname for n in (objset as array) do ( newLayer.addnode n ) ) fn fnCPYGRP var = -- FINDS A SPECIFIC GROUP, COPIES IT, AND TRUNCATES NUMBERS OFF CHILDREN GEOMETRY ( print "function fnCPYGRP" grp = fnGRPS var -- group to copy materials from if grp != undefined then ( i = 1 r = grp.children.count copyset = #() while i <= r do ( copy grp.children[i] i = i + 1 objID = amax (for o in objects collect o.inode.handle) select (maxOps.getNodeByHandle objID) selection[1].parent = tempgrp selection[1].name = (substring selection[1].name 1 (selection[1].name.count - 3)) append copyset selection[1] ) -- gn = getNodeByName "[x]" -- append copyset gn setGroupOpen (fnGRPS (gname)) false explodeGroup (fnGRPS (gname)) group copyset name: gname append copyset (fnGRPS (gname)) fnLYRPUT (copyset) -- move this copy to the layer of the new import gna = #(gn) setGroupOpen (fnGRPS (gname)) true ) else ( print "material group not found" ) groupsel = groupcpy print groupcpy select mmatset ) fn fnCAM = ( delset = #() camset = #() macros.run "Scene Explorer" "SELayerExplorer" (layermanager.getlayer 0).current = true actionMan.executeAction 0 "40043" -- Selection: Select None actionMan.executeAction 0 "40010" global importset = selection for j = 1 to importset.count do ( obj = ((classof importset[j]) as string) objT = (trimleft obj "Target") if obj.count > objT.count then ( append camset importset[j] ) else ( append delset importset[j] ) ) for j = 1 to delset.count do ( delete delset[j] ) camlyr = "cameras" if fnLYR (camlyr) == true then ( camLayer = layermanager.getlayerfromname camlyr ) else ( camLayer = LayerManager.newLayerFromName camlyr ) for n in (camset as array) do ( camLayer.addnode n ) ) group "1." ( label lab1 "Select .3ds file" button btn_import "IMPORT" width:125 height:20 enabled:true button btn_importhelp "help" width: 50 height: 16 enabled:true ) label lab1t "" label labT "then" label labta "" group "A." ( label labA "Create new group" button btn_create "CREATE" width:125 height:20 enabled:false label lab3 "" label labCG "Copy materials / modifiers" pickbutton btn_cgroup "SELECT GROUP" filter:fnISGRP width:125 height:20 enabled:false button btn_createhelp "help" width: 50 height: 16 enabled:true ) label labax "" label labX "or" label labxb "" group "B." ( label labB "Update group" pickbutton btn_group "SELECT GROUP" filter:fnISGRP width:125 height:20 enabled:false label lab6 "" button btn_update "UPDATE" width:125 height:20 enabled:false button btn_updatehelp "help" width: 50 height: 16 enabled:true ) Label labZ "" button btn_reset "reset" width:60 height:20 enabled:true Label labZ2"" group "2." ( label lab2 "Select .3ds file" button btn_importcam "IMPORT CAMERAS" width:125 height:20 enabled:true button btn_importcamhelp "help" width: 50 height: 16 enabled:true ) label lab2x "" group "About" ( label a1 "Sketchup.3ds Import v3.3" label a2 "" label a3 "by Chris Peterson 2017" ) on btn_import pressed do ( cont = fnIMP() if cont == 1 then ( btn_create.enabled = true btn_group.enabled = true btn_import.enabled = false btn_cgroup.enabled = false if groupsel != "none selected" then ( btn_update.enabled = true ) else ( btn_group.text = "none selected" ) ) ) on btn_create pressed do ( cont = fnNEWGROUP() if cont == true then ( btn_import.enabled = true btn_create.enabled = false btn_group.enabled = false btn_update.enabled = false btn_cgroup.enabled = true ) ) on btn_cgroup picked val do ( global groupcpy = val btn_cgroup.text = val.name fnCPYGRP (groupcpy.name) fnREP (fnGRPS (gname)) btn_cgroup.text = "SELECT GROUP" btn_import.enabled = true btn_create.enabled = false btn_cgroup.enabled = false btn_update.enabled = false ) on btn_group picked val do ( global groupsel = val btn_group.text = val.name btn_update.enabled = true print groupsel return groupsel ) on btn_update pressed do ( tst = fnDSN() fnREP(groupsel) btn_create.enabled = false btn_update.enabled = false btn_import.enabled = true ) on btn_reset pressed do ( btn_import.enabled = true btn_create.enabled = false btn_cgroup.enabled = false btn_update.enabled = false ) on btn_importcam pressed do ( fnCAM() ) on btn_importhelp pressed do ( help1 = "1. [Select .3ds file] - locate a .3ds file exported from sketchup and the utility will break the import into objects by material." messagebox help1 ) on btn_createhelp pressed do ( help2 = "A. [Create new group] - Will create a group and put it on a layer of the same name." help3 = " [Copy materials / modifiers] - Will apply materials and modifiers from a selected group with objects of matching names." help4 = " Note that if there are new or missing material objects in the imported .3ds file, the utility will ask if these should be removed" help5 = " from or added to the NEW group, or choose Cancel to leave new material objects on layer 0 (default)." messagebox (help2 + help3 + help4 + help5) ) on btn_updatehelp pressed do ( help6 = "B. [Update group] - Select a group in scene to update with newly imported .3ds geometry." help7 = " Press UPDATE to execute." help8 = " Note that if there are new or missing material objects in the imported .3ds file, the utility will ask if these should be removed" help9 = " from or added to the EXISTING group, or choose Cancel to leave new material objects on layer 0 (default)." messagebox (help6 + help7 + help8 + help9) ) )