Hello, folks.
Doing a bunch of calculations on UV faces and script is pretty slow. What I've noticed is that it works reliably faster if I switch modifier stack from unwrap to one modifier below (epoly in my case). Tried to switch modifiers in script, but it gets confused if there are several unwraps in a row, so I would like to get same speed boost, but without messing around with modifier stack selection.
Tried disabling undo and enclosing main part in disableSceneRedraw() and enableSceneRedraw(), but that didn't help. What other things can I disable to imitate switching to epoly in modifier stack?
Here is stripped down part to demonstrate, it looks horrible and doesn't have all the torture UV faces are going through, but time difference is noticeable.
( Teapot pos:[0.0,0.0,0.0] isSelected:on radius:6 segments:10 max modify mode modPanel.addModToSelection (Uvwmap ()) ui:on $.modifiers[#UVW_Map].maptype = 5 modPanel.addModToSelection (Edit_Poly ()) ui:on modPanel.addModToSelection (Unwrap_UVW ()) ui:on $.modifiers[1].edit() subobjectLevel = 3 local uv = $.modifiers[1] modPanel.setCurrentObject $.modifiers[1] st = timestamp() aaa = (uv.getselectedfaces()).count for faceIndex = 1 to aaa do ( uv.unwrap2.selectFaces #{faceIndex} uv.unwrap2.selectElement() faceNormal = uv.getNormal (faceIndex - 1) myz = acos faceNormal.z uv.unwrap2.moveSelected [2,0,0] ) format "unwrap selected time:%\n" (timestamp()-st) modPanel.setCurrentObject $.modifiers[2] st = timestamp() aaa = (uv.getselectedfaces()).count for faceIndex = 1 to aaa do ( uv.unwrap2.selectFaces #{faceIndex} uv.unwrap2.selectElement() faceNormal = uv.getNormal (faceIndex - 1) myz = acos faceNormal.z uv.unwrap2.moveSelected [2,0,0] ) format "epoly selected time:%\n" (timestamp()-st) )
Replies
Doing a bunch of calculations on UV faces and script is pretty slow.
Technically the calculations are very fast, it's changing selection and moving things inside a loop that is slow. I don't know the full application of your script, but this snippet I sped up with no loss of functionality.
Before
After
Changes:
Thank you.
Some code here is a "placeholder", like moving elements. I need to move them to few different places and use "default" shift in this example just to have overall "weight" of calculations as close to what it will be in the end.
Collecting elements in groups instead of moving each individually every iteration should help, will rewrite that part. Oh and definitely will shove everything in variables.
As for UV element detection I found few methods. One is unavailable since it uses getMapFacesUsingMapVert and getMapVertsUsingMapFace meshops functions and polyops only has getMapFace, but nothing for mapverts or mapedges. I can probably detect element in similar way by running selection conversions in UV editor, but that would defeat the purpose by adding even more selection operations. Expanding to element from first available face in allFaces and excluding resulting array from allFaces seems like a good compromise. Example is for worst case scenario where each face is an element. but still runs expansion to element for reason described above. For now I'll try to move element collection outside of the main processing loop.
If I missed your point, please give a link to dig through.
Meanwhile, found that disableRefMsgs() enableRefMsgs() and suspendEditing() resumeEditing() pairs are making it faster so I'm using both.
UPD: tried using getMapFacesUsingMapVert-getMapVertsUsingMapFace combo on snapshotted mesh. It is insignificantly faster in some cases and much slower in others. Another problem is that UV face IDs are different between mesh and poly and I suspect any time I saved on mesh processing would be lost if I try to transfer it back to poly. Fast way to get shells is a problem I can't solve.
Okay, sometimes you have to select in a loop, but the main issue in your original post was the duplicate work. You can take advantage of subtracting bit arrays to avoid the duplicated work.
Check out these two functions below. The first takes 11 seconds on a default teapot and the second takes 1/10th of a second. The only difference is reducing the bitArray as you find the UV elements and using the
where
context in the loop to skip already removed polys.Output
Got it, thanks.
Element selection is bothering me now =)
Your hint about it being slower than calculation was right and sent me on a journey of poking around with element detection and reorganizing the whole thing. Expanding to element is slow, but does wonders with low amount of shells, say we have million polys unwrapped into just 2 shells. Meshop way works faster with worst case scenario up until ~50k shells, but then starts to decline and gets even slower than element expansion method.
Native functions to works with UV shells would be perfect solution, but max still doesn't have it for some reason and now I'm wondering if there are other ways of element detection I just can't think of.