[Closed] ProOptimizer.VertexCount not updating
I have a script I’m using to run through every mesh in my scene and simplify it using ProOptimizer. The function that gets called on each mesh is
fn decimate obj = (
count1 = (vol_ratio * (meshVolume(obj) ^ vol_power)) as Integer
count2 = (sa_ratio * (meshSurfaceArea(obj) ^ sa_power)) as Integer
local mod_optimizer = ProOptimizer OptimizationMode: 1 LockMat: on KeepVC: on KeepNormals: on PreventFlip: on MergePoints: on MergePointsThreshold: 0.1 MergeFacesAngle: 5.0
addModifier obj mod_optimizer
mod_optimizer.Calculate = on
mod_optimizer.VertexCount = (amin count1 count2)
)
When I run it, the ProOptimizer modifier shows up on each object, but the vertex count is listed as 0 (indicating it never performed the initial calculation, despite my trying to call it in my function). I’ve verified that my count1 and count2 are correct, and if I print mod_optimizer.Calculate before turning it on, it prints false, and after it prints true, but my mod_optimizer.VertexCount is 0 both times. How can I make this code actually apply the new vertex count?
This is also driving me insane because if I enter the exact same commands in the Listener window on any given object, the modifier applies the correct vertex count and keeps it
Try:
addModifier obj mod_optimizer
mod_optimizer.Calculate = on
[b]completeredraw() /* or redrawviews()[/b] */
mod_optimizer.VertexCount = (amin count1 count2)
Make sure you are in modify panel.
(
fn Decimate obj count =
(
select obj
mdf = prooptimizer()
addmodifier obj mdf
mdf.calculate = on
completeredraw() -- or redrawviews()
mdf.vertexcount = count
)
delete objects
max modify mode
t1 = teapot()
t2 = teapot pos:[100,0,0]
Decimate t1 64
Decimate t2 32
)
Still not working, the ProOptimizer modification is applied but never reduces the vertex count. I tried it with both redrawViews() and completeRedraw()
Does the example I posted work?
I just tested it from Max 2010 to 2018 and it does work on my end.
The code you posted does in fact work, which makes me confused why mine isn’t. My full code is below, in case it’s something else causing it.
-- Default
vol_power = 0.5 -- 0.5 DEFAULT
vol_ratio = 6 -- 600 DEFAULT
sa_power = 0.5 -- 0.5 DEFAULT
sa_ratio = 15 -- 1500 DEFAULT
---------Helper functions---------
-- Calculate volume of the mesh
fn meshVolume obj = (
local volume = 0.0
local num_faces = obj.numFaces
for i = 1 to num_faces do (
local Face = getFace obj i
local vert2 = getVert obj face.z
local vert1 = getVert obj face.y
local vert0 = getVert obj face.x
local dV = dot (cross (vert1 - vert0) (vert2 - vert0)) vert0
volume += dV
)
volume / 6
)
-- Calculate surface area of the mesh
fn meshSurfaceArea obj = (
local surface_area = 0.0
local num_faces = obj.numFaces
for i = 1 to num_faces do (
surface_area += meshop.getFaceArea obj i
)
surface_area
)
-- Decimation
fn decimate obj = (
count1 = (vol_ratio * (meshVolume(obj) ^ vol_power)) as Integer
count2 = (sa_ratio * (meshSurfaceArea(obj) ^ sa_power)) as Integer
local count = amin(#(count1, count2)) as integer
local mod_optimizer = ProOptimizer OptimizationMode: 1 \
LockMat: on KeepVC: on KeepNormals: on PreventFlip: on \
MergePoints: on MergePointsThreshold: 0.1 MergeFacesAngle: 5.0
addModifier obj mod_optimizer
mod_optimizer.Calculate = on
completeredraw()
mod_optimizer.VertexCount = (amin count1 count2)
)
undo off (
-- Cleanup the tree
select $*
delete helpers
deselect $*
for obj in $* where classOf obj != Editable_Mesh do convertToMesh obj
del_array = (for obj in $* where classOf obj != Editable_Mesh or obj.numFaces == 0 collect obj)
delete del_array
-- Decimate
max modify mode
for obj in $* do decimate obj
deselect $*
)
You must select each object before applying the modifier.
Just add ‘select obj’ in you Decimate() function, before youcall addModifier().
Ah works perfectly now, thanks. I am curious as to why though, when I did the commands individually in the Listener window, I didn’t have to select the object, plus there’s a separate method to add a modifier to the selection, so I (clearly incorrectly) assumed you wouldn’t need it to selected to use the one I did.
Your assumption is not incorrect. There are two methods for adding a modifier to an object and both are valid.
The problem is that some parameters, in some modifiers, do not update correctly. This could be due to a correct design, a wrong design or a bug. And it depends on the modifier, so you need to try a few different things when they don’t work as you would expect. Even tough, some parameters, in some modifiers, will never work as you would expect.
So when I tried the updated script on my test scene with ~15 objects, it worked fine, but now trying it on one of my real scenes with 500+ objects, it will apply the modifier, it will correctly apply the vertex count, and then later when processing a different object it will reset the previous modifiers somehow and the optimization will disappear. If I check the objects after running the script, they still have the modifier, but it simply says “Optimization Invalid” and has no reduction applied. I tested this with both completeRedraw() and redrawViews() again.
Perhaps someone with more experience using the Pro Optimizer modifier can help you with this.
It seems the modifier does not hold the data for more than 21 instances on the scene in this test
(
fn Decimate obj count =
(
select obj
mdf = prooptimizer()
addmodifier obj mdf
mdf.calculate = on
completeredraw() -- or redrawviews()
mdf.vertexcount = count
)
gc()
delete objects
max modify mode
for j = 1 to 21 do
(
t1 = teapot pos:[j*80,0,0] wirecolor:red
Decimate t1 (j+3)
)
for j = 1 to 21 do
(
t1 = teapot pos:[j*80,80,0] wirecolor:green
Decimate t1 (j+3)
)
)
Try converting the object to either mesh or poly after you optimized it, so you release the modifier instance.
For processing large amount of nodes, there is an interface you could try out “BatchProOptimizer”