Notifications
Clear all

[Closed] Fast way to set smoothing groups on Edit_Poly modifier?

So typically when I want to set a smoothing group to faces in an Edit_Poly modifier (lets just say smoothing group 1 in this case), I’ll do something like this:

curMod = modpanel.getCurrentObject()
subobjectLevel = 4
curMod.SetSelection #Face #{} node:$
curMod.Select #Face (facesToSmooth as bitarray) node:$
curMod.smoothingGroupsToSet = 0
curMod.smoothingGroupsToClear = -1
curMod.SetOperation #SetSmooth
curMod.smoothingGroupsToSet = 1

While as this works, it requires switching the subobject level if working in vert or edge component modes, which is veeeeery slow. I was wondering if anyone knows a faster method for assigning smoothing groups to faces on an Edit_Poly modifier?

15 Replies

no need to set sub level

The method I posted applies a smoothing group to the selected faces, but in order to select said faces you need to be in a face subobject level.

you can set face selection in any level

How? The above curMod.Select #Face command does nothing when in vert or edge subobject level. If you run it and then switch to face subobject level nothing will have changed.

select Method must in the correct sub level , but setSelection needn’t .
there is a bug with setSelection Method , so lots of mxser didn’t know how to use it , official seems not want to fix it , but with mxs below we can use it yet .

obj = Sphere radius:50 smooth:off segs:32 isSelected:on
addmodifier obj (edit_poly())
max modify mode
sel = #(#{1..100},#{101..200},#{201..300},#{301..400},#{401..500},#{501..511})
smoothsel=#(2,4,6,8,10,12)
last = #(obj.numfaces,0)
EditPolyMod.setSelection obj.modifiers[#Edit_Poly] #Face #{last[1]}
last[3] = getFaceSmoothGroup obj.mesh obj.mesh.selectedfaces[1].index
for i = 1 to sel.count do
(
	if findItem sel[i] last[1] > 0 do
		last[2] += 2^(smoothsel[i]-1)
	EditPolyMod.setSelection obj.modifiers[#Edit_Poly] #Face (sel[i] + #{last[1]})
	EditPolyMod.SetOperation obj.modifiers[#Edit_Poly] #SetSmooth
    obj.modifiers[#Edit_Poly].smoothingGroupsToClear = -1
	obj.modifiers[#Edit_Poly].smoothingGroupsToSet = 2^(smoothsel[i]-1)
)
EditPolyMod.setSelection obj.modifiers[#Edit_Poly] #Face #{last[1]}
obj.modifiers[#Edit_Poly].SetOperation #SetSmooth
obj.modifiers[#Edit_Poly].smoothingGroupsToClear = -1
if last[2] > 0 then
	obj.modifiers[#Edit_Poly].smoothingGroupsToSet = last[2]
else obj.modifiers[#Edit_Poly].smoothingGroupsToSet = last[3]
1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

you set face sm group per face… so, you method is slower than original PolyHertz’s way.

if you don’t believe me try to set ALL faces to sm group 4 for example for a large mesh:

(
	obj = geosphere radius:50 segs:100
        ...
)

i don’t believe it’s possible to set sm groups for an edit_poly faster than:

delete objects 

with redraw off
(
	max create mode

	obj = geosphere radius:50 smooth:off segs:100
	modi = edit_poly()
	
	addmodifier obj modi

	t0 = timestamp()
	h0 = heapfree
	
	modi.setepolysellevel #face

	max modify mode
	modpanel.setcurrentobject modi

	t1 = timestamp()
	h1 = heapfree
	
	modi.select #face #{1..modi.getnumfaces()}
	modi.smoothinggroupstoclear = -1
	modi.setoperation #setsmooth
	modi.smoothinggroupstoset = 2^(4-1) -- 4th smoothing group

	t4 = timestamp()
	h4 = heapfree


	format "time:%(%) heap:%(%)\n" (t4 - t0) (t1 - t0) (h0 - h4) (h0 - h1)	
)

there are unnecessary messages that edit_poly sends on selection changed to validate channels. you probably have to live with it.

Thanks for the help!

I had no idea setSelection actually worked for anything but clearing the selection due to the weird bug it has. After testing it out though I was able to significantly improve performance by using it in this way:


curObj = (selection as array)[1]
curMod = modpanel.getCurrentObject()
allFacs = #(1,7,8,22,5)
theSG  = 2^(4-1) -- 4th smoothing group

--Select faces (due to a glitch in setSelection we need to also select the face with the highest index)
allFacsBIT = allFacs as bitarray
totalFaces = curMod.GetNumFaces node:curObj
curMod.SetSelection #Face #{} node:curObj
EditPolyMod.setSelection curMod #Face (allFacsBIT + #{totalFaces}) node:curObj

--Get smoothing group of the face with the highest index, we might need to change it back later.
highestFacSG = curMod.GetFaceSmoothingGroups totalFaces node:curObj

--Clear old smoothing groups and set new ones
curMod.smoothingGroupsToSet = 0
curMod.smoothingGroupsToClear = -1
curMod.SetOperation #SetSmooth
curMod.smoothingGroupsToSet = theSG

--If highest index face wasn't meant to be changed, revert to its original smoothing group
if allFacsBIT[totalFaces] == false do (
    curMod.SetSelection #Face #{} node:curObj
    EditPolyMod.setSelection curMod #Face #{totalFaces} node:curObj
    curMod.smoothingGroupsToSet = 0
    curMod.smoothingGroupsToClear = -1
    curMod.SetOperation #SetSmooth
    curMod.smoothingGroupsToSet = highestFacSG
)

--Done
curMod.commit()

hmm… i was wrong

The “last bit” trick seems to work. I don’t understand why yet …

Oh! I understood. Here is the right way to set:

delete objects 

with redraw off
(
	max create mode

	obj = geosphere radius:50 smooth:off segs:100
	modi = edit_poly()
	
	addmodifier obj modi

	t0 = timestamp()
	h0 = heapfree
	
	max modify mode
	modpanel.setcurrentobject modi

	t1 = timestamp()
	h1 = heapfree
	
	numfaces = modi.getnumfaces()

	faces = #{1..numfaces/2}
	faces.count = numfaces -- ! ! ! ! ! ! ! ! ! ! !
	
	modi.setselection #face faces
	modi.smoothinggroupstoclear = -1
	modi.setoperation #setsmooth
	modi.smoothinggroupstoset = 2^(4-1) -- 4th smoothing group
	
	modi.commit()

	t4 = timestamp()
	h4 = heapfree


	format "time:%(%) heap:%(%)\n" (t4 - t0) (t1 - t0) (h0 - h4) (h0 - h1)	
)
Page 1 / 2