setVert


#1

I’m using polyOps.setVert to set vertex positions on a selection of objects, targets. I have grabbed the positions from a master object and stored them into an array of structures and then loop through that and setVert for each one saved. This takes for ever and crashes Max if I try and do more then a couple objects at a time. The issue is the undo or theHold, either way it is a killer. I would really like to have an undo and not have to do a hold fetch.

Is there a better way?

	fn pasteVerts objs =
	(
		undo on
		(
			for o in objs do
			(
				if isValidNode o and classOf o==Editable_Poly then
				(
					for x in copiedVertPostions do 
					(
						polyOp.setVert o x.index (x.pos+o.transform.row4)
					)
				)
			)
			completeRedraw()
		)
	),


#2

Hi Paul,
Perhaps you could assign all vertices positions at once. Not sure if it will work for what you need, but here are two slightly modified versions of your function. While both runs faster, one uses less memory and the other is 2X faster.

fn pasteVerts2 objs =
   (
   	poSetVert = polyOp.setVert
   	for o in objs where isValidNode o and classOf o == Editable_Poly do
   	(
   		vIdx = #{}
   		vPos = #()
   		tm = o.transform.row4
   		for v in copiedVertPostions do
   		(
   			append vIdx v.index
   			append vPos (v.pos + tm)
   		)
   		poSetVert o vIdx vPos
   	)
   	completeRedraw()
   )
   
   fn pasteVerts3 objs =
(
	poSetVert = polyOp.setVert
	for o in objs where isValidNode o and classOf o == Editable_Poly do
	(
		vIdx = #{}
		vPos = #()
		tmX = (o.transform.row4).x
		tmY = (o.transform.row4).y
		tmZ = (o.transform.row4).z
		for v in copiedVertPostions do
		(
			append vIdx v.index
			append vPos [v.pos.x+tmX, v.pos.y+tmY, v.pos.z+tmZ]
		)
		poSetVert o vIdx vPos
	)
	completeRedraw()
)

#3

Ah good point, didn’t even think of that. Thanks. I will see if the undo is still an issue.


#4

Why not use the polyop.MoveVert?
It works faster for large amount of verts.
For the Undo problem - did you tried the theHold.begin() and theHold.Accept()/theHold.Cancel()?

[i]

[/i]


#5

polyop.setvert is undoable. you don’t have to do anything to make it “better” undoable…
if you want to be 100% sure that the Hold begun do convert all nodes to poly before a setting verts.

probably the reason of the crash is that you go out of vertex number range for some objects. so you have to check the number before setting some index…

and! don’t collect vertex structures. collect just their positions. if you want to keep the index as well do it with you own structure:

struct VData (index, pos)
 fn collectVerts nodes: =
 (	
 	if nodes == unsupplied do nodes = selection
 	for node in nodes where iskindof node Editable_Poly collect
 	(
 		for v=1 to node.numverts collect VData v (polyop.getvert node v)
 	)
 )
 fn releaseVerts vdata nodes: =
 (	
 	if nodes == unsupplied do nodes = selection
 	for k=1 to vdata.count where iskindof (node = nodes[k]) Editable_Poly do
 	(
 		converttopoly node -- not really necessary
 		for v in vdata[k] where v.index <= node.numverts do (polyop.setvert node v.index (v.pos + node.transform.pos))
 		update node
 	)
 )
 
 delete objects
 s = sphere radius:10 pos:[-40,0,0]
 b = box pos:[40,0,20]
 converttopoly objects
 
 vv = collectVerts nodes:objects
 objects.pos = [0,0,0]
 /*	
 releaseVerts vv nodes:#(b,s) 
 -- or
 releaseVerts vv nodes:#(s,b) 
 */

#6

I believe the crash could be easily produced by a memory leak due to the successive individual calls to the polyop method. Look at the system monitor.

For 4 models 40K polys, it took 1GB of RAM and another 1GB of RAM for the undo process.

I think each call to polyop.setvert adds an entry in the DB thus causing a huge memory leak.

Besides that, setting all vertices at once is between 20 and 45 times faster. Also the undo is much faster and if I am not wrong, I think the undo is by default implicit for this operation.

By the way, there was a bug in my previous code (second function), now fixed.


#7

I could not measure any noticeable difference using polyop.SetVert or polyop.MoveVert in my tests, as far as speed or memory usage when setting multiple vertices at once.
16 models 160K polygons, 75ms 4950456L


#8

we’ve talked many times about the memory leaking on this forum, but this case is probably not about it. to optimize the code is definitely a good idea but the issue is a different. the collection of verts is a set of “alive” objects… when you set new position it automatically updates #pos property of the stored vertex.
try just call something like

for v in <poly>.verts do v.index

you can see that it takes unexpectedly a lot of time. why? because it’s not just returning a stored number, it’s kinda a function that checks(confirms validation) and returns the value.


#9

Thank you for the insight Denis. Yes, I am aware of the verts pos and index properties.

However, I would not be that sure that a memory leak could not be the  cause of the crash in this case. But using the setvert function you can run out of memory  very quickly and that eventually can lead to a crash. But you have  obviously much more experience than me on this, and I can be completely  wrong.

I am not saying it was the cause of the crash, neither can I affirm the  contrary. After all, I have no idea of what Paul was testing so I am  not in a position to radically say what was or what was not the problem.

Also, the setvert function, if I am not wrong, is a protected function,  so if you ask me what could cause a crash: trying to set an out of  index vertex position or a huge memory leak, I would bet 99 to 1 that  the memory leak would most probably be the issue. But that might be me  and my ignorance.

After all, my reply was not an attempt to improve the speed, but to  solve the memory leaking, which is a real problem. The speed gain was an  obvious consequence.

#10

I don’t know if I am getting the same results as you. I’ve tryied the following and I don’t see a big difference:

(
   st = timestamp()
   for v in $.verts do v.index
   format "time:%
" (timestamp()-st)
   )
   time:93
   (
   st = timestamp()
   for v in $.verts do true
   format "time:%
" (timestamp()-st)
   )
   time:80

#11

I wasn’t going out of range on the vert indexes as they are all morph targets and identical.

Thanks for the thoughts here. I will give it an update tomorrow and see what I can get and post with the results if it is worth it.


#12

well… i might forget something… how is about to check

for v in $.verts do v.pos
 

the memory leaking is the BIG problem in the mxs
but it rarely causes a crash… it usually goes slower and slower… crunches but not crashes :slight_smile:


#13

Yes, this one is slower. Tested on 300K vertices model.

(
    st = timestamp()
    for v in $.verts do v.pos
    format "time:%
" (timestamp()-st)
    )
    time:237

Neither the Undo+Leak can crash Max?


#14

you are right… the memory leaking corrupts gc … as a result you would see a message kinda ''blah,blah,blah… if you see this message you suck!"
so… don’t let your memory go wild!


#15

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.