I'm wondering if you could take a peak at what I have so far. If I have one item selected, it works great. It appears to work if I have multiple items selected too, except one crucial step is being ignored for some reason. Before running the code that you created (awesome, can't stress that enough), I apply a ProOptimizer modifier with the settings required to weld and preserve the normals, UVs, etc. Welding vertices seems to destroy the explicit normals, so I'm just falling back to this method... It fails to do poMod.Calculate = true only if there's more than one object selected. It seems to change all of the other settings that I have set, except for that one. I feel like I missed something crucial with my function, and it's not turning on calculate right before collapsing the stack, and right before collapses it into an Editable Mesh that your function then does its magic on. Is this just a possible limitation of ProOptimizer, or did I mess up something simple? Maybe a way to check if it is on before collapsing the stack?
I attached the .max file I'm testing in with a simple imported BREP. If you run the script on a single object, you can select a vertex that is on one of the border edges and move it you'll see that it is welded. If you run the script on multiple objects, then go to one and select that same vertex location, it isn't welded. Which is typical for how 3ds Max changes body objects to meshes, you end up with an element for each trimmed surface.
try (closerolloutfloater MainFloater) catch()
fn weldVertsPreserveNormals obj =
(
-- Weld vertices and preserve explicit normals
-- Check if a ProOptimizer modifier already exists, if not then add one
poMod = undefined
for mod in obj.modifiers do
(
if classOf mod == ProOptimizer then poMod = mod
)
if poMod == undefined do poMod = ProOptimizer()
-- Add the ProOptimizer modifier to the object if it's not already applied
if findItem obj.modifiers poMod == 0 do addModifier obj poMod
-- Set Protect Borders, Keep Material, Texture, and UV Boundaries, Keep Normals as Protected, and Merge Vertices
poMod.OptimizationMode = 1
poMod.LockMat = true
poMod.LockUV = true
poMod.keepTextures = true
poMod.keepNormals = true
poMod.normalMode = 1
poMod.mergeVertices = true
poMod.Calculate = true
maxOps.CollapseNodeTo obj 1 off
)
fn getAdjacentMeshData mesh vis:off sel:on =
(
fn sortbyxy v1 v2 =
(
if (d = v1.x - v2.x) == 0 then (v1.y - v2.y) else d
)
edges = #()
for f=1 to mesh.numfaces do
(
vv = getface mesh f
vv = [vv[1],vv[2],vv[3],vv[1]]
id = (f-1)*3
sm = getFaceSmoothGroup mesh f
for k=1 to 3 do
(
e = [vv[k], vv[k + 1], id + k, sm]
if (e.x > e.y) do swap e.x e.y
append edges e
)
)
qsort edges sortbyxy
edges
borders = #{}
k = 1
while k < edges.count do
(
n = k+1
if edges[k][1] == edges[n][1] and edges[k][2] == edges[n][2] then
(
if edges[k][4] != edges[n][4] do
(
append borders edges[k][3]
append borders edges[n][3]
)
k += 2
)
else
(
append borders edges[k][3]
k += 1
)
)
if vis do
(
for k=1 to edges.count do
(
edge = edges[k][3]
face = (edge - 1) / 3 + 1
index = (mod (edge - 1) 3) + 1
setedgevis mesh face index borders[edge]
)
update mesh
)
if sel do mesh.selectededges = borders
borders
)
Rollout Menu01 "Convert To T-Mesh"
(
button convertTMesh "Convert to T-Mesh" pos:[2,6] width:100 height:20
on convertTMesh pressed do
(
obj = selection[1]
if selection.count == 0 then
(
messagebox "Please select at least one mesh object to convert to T-Mesh"
)
else
(
for obj in selection do
(
if (classOf obj == Editable_Mesh) or (classOf obj.modifiers[#Edit_Mesh] == Edit_Mesh) or (classOf obj == Editable_Poly) or (classOf obj.modifiers[#Edit_Poly] == Edit_Poly) or (classOf obj == Body_Object) then
(
(
--Weld vertices and preserve explicit normals
ff = weldVertsPreserveNormals obj
)
(
--Make only smoothing group borders visible
ee = getAdjacentMeshData obj vis:on sel:off
)
)
else
(
messagebox "Not a valid mesh object"
)
)
)
)
)
Rollout Menu02 "How To Use"
(
label typeH2U01 "1. Select a single mesh or body object that has properly assigned smoothing groups.
Each face should not have more than one smoothing group assigned, it may produce unexpected results. It will use the smoothing groups found in imported CAD or chamfered objects to create the T-Mesh border edges. Copy the object if needed, as this script will convert it to a T-Mesh.
If running the script on an instance, it will update all of them when the script is run on one object."
width:260 height:135 align:#left
label typeH2U02 "2. Click the Convert to T-Mesh button." align:#left
label typeH2U03 "3. The selected mesh or body object should now be an Editable Mesh, with only the trimmed surface edges being visible as if it were a BREP.
As well as having easily selectable surfaces for applying material IDs or unwrapping, the vertices will be joined. Something that converting a body object to a mesh will not do." width:260 height:100 align:#left
)
Rollout Menu03 "About"
(
label typeAbout01 "Convert To T-Mesh v0.25"
)
MainFloater = NewRolloutFloater "Convert To T-Mesh" 300 400
addRollout Menu01 Mainfloater
addRollout Menu02 Mainfloater
addRollout Menu03 Mainfloater