PDA

View Full Version : A script that welds verts but keep groups...?


DarkEdge
04-03-2009, 12:59 PM
Hi all.
Is there a script that will weld identical verts (or a threshold) but will keep the grouping intact? So the polys are still grouped seperately but the mesh is all welded.

Thanks!

ZeBoxx2
04-03-2009, 05:27 PM
when you say 'group', do you mean the Elements? I.e. being able to select them separately by going into element sub-object mode?

If so - 'fraid not. Elements are determined by connectivity.

However, you should be able to store the original elements as named selection sets so that you can still select them separately once the vertices are welded.

Collect each unique element using <meshop|polyop>.getElementsUsingFace, assign each element to a named selection set using <object>.faces["Name"] = <element face list>, then weld.

DarkEdge
04-03-2009, 05:36 PM
ZeBoxx2,

That would work as the modeling would be completely done at that point, so it would be a welded single object but I could select the old poly elements...right?
How would these elements be selected then?

I wouldn't impose on you to write a script just for me I was hoping that there might be something out there that would do this or that there would be a way inside of Max for this to be done???

I am complete idiot at scripting and can barely run a script! lol.

ZeBoxx2
04-03-2009, 06:02 PM
You would select them from the Named Selection Set drop-down, which is typically in the top toolbar in 3ds Max (no idea where it's at in 2010) and also accessible through Edit > Manage Selection Sets.

Not much code, really.. the code to get the elements is the biggie.. I'll paste ofer_z's here as mine's all comment-less:
( source: http://forums.cgsociety.org/showpost.php?p=5260271&postcount=18 )

fn getElements obj faces:#All =
(
-- Check the obj class
local objClass = classOf obj
-- Create a temp function (func) that given the object and a face ID returns
-- the element face IDs.
-- Depending on the class of obj, use the right method to get the element faces.
local func
case objClass of (
Editable_Poly: fn func obj face = polyOp.getElementsUsingFace obj face
PolyMeshObject: fn func obj face = polyOp.getElementsUsingFace obj face
Editable_Mesh: fn func obj face = meshOp.getElementsUsingFace obj face
Edit_Poly: fn func obj face = (local elem = #{}; obj.getElementsUsingFace elem #{face} #{}; elem)
default: undefined
)

-- Initialize some variables
local elements = #() -- The array of the elements
local usedFaces = #{} -- A bitArray to hold all the face IDs that were either checked or were part of elements of other checked faces.

-- Get the number of faces in obj (use the right method based on the class of obj).
local numFaces = case objClass of (
Editable_Poly: obj.numFaces
Editable_Mesh: obj.numFaces
PolyMeshObject: obj.numFaces
Edit_Poly: obj.getNumFaces()
default: 0
)
-- If faces is not a bitArray, make it into a bitArray with all the faces in obj.
if faces == #All then
faces = #{1..numFaces}

-- Loop through all the faces in the faces variable.
-- If the current face ID is already in usedFaces, skip it.
for f in faces where not usedFaces[f] do (
-- Using the temp function func, get the face IDs of the
-- element the current face is in.
local elem = func obj f
-- Append the element's face IDs to the elements array.
append elements elem
-- Add the face IDs in the element to the usedFaces bitArray.
usedFaces += elem
)
-- Return the elements array.
elements
)


After that is evaluated, that function can be called to get the elements as face sets, which in turn can be saved to named selection sets on the object, and the vertices welded:

fn elementsToSelectionSetsAndWeld obj = (
if (not (isValidNode obj)) then (
displayTempPrompt "Please select a single object" 5000
)
else (
allowedClasses = #(Editable_Poly,PolyMeshObject,Editable_Mesh)
objClass = classOf obj
if (findItem allowedClasses objClass == 0) then (
displayTempPrompt "Selected object is not an Editable Poly / Editable Mesh" 5000
)
else (
myElements = getElements obj
for i = 1 to myElements.count do (
obj.faces["Element #" + i as string] = myElements[i]
)
obj.selectedVerts = $.vertices
SetCommandPanelTaskMode #modify
subObjectLevel = 1

case objClass of (
Editable_Poly: (polyOps.weld obj)
PolyMeshObject: (polyOps.weld obj)
Editable_Mesh: (meshOps.weld obj)
)
)
)
)
elementsToSelectionSetsAndWeld $


If you take both pieces of code together, select all the code, and drag&drop that selected text to a toolbar, it should create a button for you that you can then use. Note that it's limited to Editable Mesh and Editable Poly objects, but Edit Poly modifier should be supportable as well.

DarkEdge
04-04-2009, 01:36 PM
Thank you kind soul! :beer:

Sasa3
04-21-2009, 08:45 PM
Hi!

I have a similar problem: I have some MAX files here that have about 800 separate 3D objects each. Each of them with its own texture (UVW). I don't need to keep any groups, I'm just looking for a script or some other way to weld all vertices of each single object at a radius of 0.01.
I'm not very much into scripting and just tried to get the second script part of the above post working for a test scene with two boxes that have vertices at the same positions, but I get a message saying "Call needs function or class, got: undefined".

It would be great if someone could tell me where to get a script that can weld more than one object in one MAX file (without groups) or how to get the above working.
In case there isn't a script: I already got a script that selects the objects one after another, I just need to know what to fill in after the selection part to do the welding.

Bests,
Sasa

ZeBoxx2
04-22-2009, 01:05 AM
I have a similar problem: I have some MAX files here that have about 800 separate 3D objects each. Each of them with its own texture (UVW).
Not sure what happens to mapping when welding, but I suppose it should be fine.

Try the following... note that it doesn't bother with any of the threshold settings.. for editable poly that -could- be done, for editable mesh I'm not seeing a variable for it.. would have to much with more UI code.

Oh, right. There's a bit of UI code - if you have editable meshes and try to weld vertices on those with no vertices within the weld threshold, it will pop up a dialog telling you as much. So that needs to be automatically closed. So if you've got editable meshes, you might hear some beeping when it hits such an object. Annoying :)

fn weldVertsOnObjs_dmo = (
local hwnd = dialogMonitorOps.getWindowHandle()
local dialogTitle = uiAccessor.getWindowText hwnd
if (hwnd != 0) AND (dialogTitle == "Weld") do (
UIAccessor.pressButtonByName hwnd "OK"
)
false
)
fn weldVertsOnObjs = (
objs = getCurrentSelection()
if (objs.count == 0) then (
format "No objects selected\n"
)
else (
format "Welding vertices on selected objects...\n"
SetCommandPanelTaskMode #modify
dialogMonitorOps.registernotification weldVertsOnObjs_dmo id:#weldVertsOnObjs_dmo
dialogMonitorOps.enabled = true
for obj in objs do (
allowedClasses = #(Editable_Poly,PolyMeshObject,Editable_Mesh)
objClass = classOf obj
if (findItem allowedClasses objClass == 0) then (
format "Object '%' is not an Editable Mesh or Editable Poly type. Cannot process.\n" obj.name
)
else (
select obj
format "Processing object '%'...\n" obj.name
obj.selectedVerts = $.vertices
subObjectLevel = 1

case objClass of (
Editable_Poly: (polyOps.weld obj)
PolyMeshObject: (polyOps.weld obj)
Editable_Mesh: (meshOps.weld obj)
)
format "\tDone\n"
)
)
dialogMonitorOps.enabled = false
dialogMonitorOps.unregisternotification id:#weldVertsOnObjs_dmo
format "Done\n"
deselect $*
)
)
weldVertsOnObjs()

Gravey
04-22-2009, 01:28 AM
I'm just looking for a script or some other way to weld all vertices of each single object at a radius of 0.01Maybe I misunderstand your problem but have you tried the vertex weld modifier?

ZeBoxx2
04-22-2009, 02:36 AM
Maybe I misunderstand your problem but have you tried the vertex weld modifier?
d'oh! :banghead:

Sasa3
04-22-2009, 08:04 PM
Maybe I misunderstand your problem but have you tried the vertex weld modifier?

Well... doesn't make much sense so select several thousand objects and weld their vertices by hand...
Richard's Script helped me a lot - THANK YOU! :bowdown:
Is there an option to get a bigger welding radius? I couldn't find anything in your script telling me what radius is used. Anyway: Your script reduced the polycount of my working file from 334000 to 302000 and vertex count from 503000 to 170000!

Bests,
Sasa

ZeBoxx2
04-22-2009, 11:45 PM
I think he meant for you to select -all- the objects, and then apply the Vertex Weld modifier; it will then be applied to all the objects (instanced), and each will use the weld threshold setting you specify there.

If an object needs a larger/smaller one, right-click on the modifier and choose 'make unique'(I think), then dial in the larger/smaller threshold.

Sasa3
04-24-2009, 04:34 PM
Hmm... didn't know that modifier neither. Interesting that the result somehow is still differend because using your script I can still convert everything into MS Flight Simulator format, while using the weld modifier this doesn't work. So your script still helped me a lot. Thanks a million!!!

Bests,
Sasa

CGTalk Moderation
04-24-2009, 04:34 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.