UVW Seem with GW


#28

These are the results I got using the model I’ve uploaded.

Previous version

Base Model
Found 3920 UV Open Edges in 92ms
Used Memory 3048248L

TurboSmooth 1 iteration
Found 7840 UV Open Edges in 291ms
Used Memory 7275320L

TurboSmooth 2 iterations
Found 15680 UV Open Edges in 990ms
Used Memory 19341568L

Latest version

Base Model
Found 3920 UV Open Edges in 49ms
Used Memory 2769144L

TurboSmooth 1 iteration
Found 7840 UV Open Edges in 107ms
Used Memory 6082848L

TurboSmooth 2 iterations
Found 15680 UV Open Edges in 246ms
Used Memory 14535560L


#29

what max version do you use?


#30

Max 2011 x64 Win7

Edit: Same results in Max 2012+


#31

i have absolutelly different numbers for your code…
that’s what i actually use:


(
  
	  unRegisterRedrawViewsCallback cbDrawOpenEdges
	  
	  global RO_DISPLAY_UV_OE
	  global cbDrawOpenEdges
	  global cbSelectionChanged
	  
	  local vertexPos   = #()
	  local uvChannel   = 1
	  local edgesColor  = [0,255,0]
	  local edgeOffset  = 0.03
	  local forceRedraw = false
	  local polyLine	= gw.polyLine
	  
	  fn cbDrawOpenEdges = (
		  
		  gw.setTransform (Matrix3 1)
		  gw.setColor #line edgesColor
		  
		  for j in vertexPos do polyLine j true
  
		  -- Needed in some Max versions or used dirvers
		  if forceRedraw do (
			  gw.enlargeUpdateRect #whole
			  gw.updateScreen()
		  )
	  )
  
	  fn cbSelectionChanged mForce:false = (
  
		  unRegisterRedrawViewsCallback cbDrawOpenEdges
		  
		  if ($ != undefined) do (
			  
			  setwaitcursor()
  
			  t1 = timeStamp()
			m1 = heapfree
				  
			  cGetMapFace = meshop.getMapFace
  
			  obj = snapshotasmesh selection[1]
  
			  allChannels = for j = 1 to meshop.getNumMaps obj where (meshop.getMapSupport obj j) collect j
			  
			  RO_DISPLAY_UV_OE.ddl_channel.items = for j in allChannels collect j as string
			  
			  if (mForce == false) do (
				  uvChannel = allChannels[1]
				  RO_DISPLAY_UV_OE.ddl_channel.selection = 1
			  )
  
			  numTFaces = meshop.getNumMapFaces obj uvChannel
			  numTVerts = meshop.getNumMapVerts obj uvChannel
			  
			  emesh = trimesh()
			  setMesh emesh numverts:numTVerts numfaces:numTFaces
			  setMesh emesh faces:(for j = 1 to numTFaces collect (cGetMapFace obj uvChannel j))
			  
			  objOpenEdges  = meshop.getOpenEdges obj
			  meshOpenEdges = meshop.getOpenEdges emesh
			  delete emesh
						  
			  sharedFaces = meshop.getFacesUsingEdge obj meshOpenEdges
			  foundEdges = #()
			  vertexPos  = #()
			  
			  for j in sharedFaces do (
				  
				  objFaceVerts = getFace obj j
				  
				  edge1 = j*3 - 2
				  edge2 = j*3 - 1
				  edge3 = j*3
				  
				  v1Idx = objFaceVerts.x
				  v2Idx = objFaceVerts.y
				  v3Idx = objFaceVerts.z
				  
				  v1 = getVert obj v1Idx
				  v2 = getVert obj v2Idx
				  v3 = getVert obj v3Idx
  
				  if meshOpenEdges[edge1] do (
					  found = findItem foundEdges [v1Idx, v2Idx]
					  if (found == 0) then (
						  append vertexPos #(v1,v2)
						  append foundEdges [v2Idx, v1Idx]
					  )else(
						  deleteitem foundEdges found
					  )
				  )
				  if meshOpenEdges[edge2] do (
					  found = findItem foundEdges [v2Idx, v3Idx]
					  if (found == 0) then (
						  append vertexPos #(v2,v3)
						  append foundEdges [v3Idx, v2Idx]
					  )else(
						  deleteitem foundEdges found
					  )
				  )
				  if meshOpenEdges[edge3] do (
					  found = findItem foundEdges [v3Idx, v1Idx]
					  if (found == 0) then (
						  append vertexPos #(v3,v1)
						  append foundEdges [v1Idx, v3Idx]
					  )else(
						  deleteitem foundEdges found
					  )
				  )
					  
			  )
	
			  format "mesh >> open edges:% time:% memory:%
" vertexPos.count (timestamp() - t1) (m1 - heapfree) 
  
			  registerRedrawViewsCallback cbDrawOpenEdges
  
			  delete obj
			  
			  gc light:true
			  
			  setArrowCursor()
			  
		  )
		  
		  forceCompleteRedraw()
		  
	  )
  
	  
	  try(destroyDialog RO_DISPLAY_UV_OE) catch()
	  rollout RO_DISPLAY_UV_OE "UV Open Edges" width:160 height:198
	  (
		  checkbutton bt_enable "Display UV Open Edges" pos:[8,8] width:144 height:32
		  dropdownList ddl_channel "UV Channel:" pos:[8,72] width:120 height:40 enabled:false
		  colorPicker cp1 "" pos:[131,90] width:21 height:21 enabled:true color:edgesColor modal:false
		  checkbox chk_redraw "Force Redraw" pos:[8,46] width:100 height:16 enabled:false
		  spinner spn_width "Edge Width:" pos:[8,120] width:120 height:16 range:[1,100,4] type:#integer fieldwidth:50
		  button bt_update "Update" pos:[8,160] width:144 height:28 enabled:false
  
		  fn destroy = (
			  callbacks.removeScripts #selectionSetChanged
			  unRegisterRedrawViewsCallback cbDrawOpenEdges
			  forceCompleteRedraw()
		  )
		  
		  on RO_DISPLAY_UV_OE close do destroy()
		  
		  on bt_enable changed arg do
		  (
			  bt_update.enabled = arg
			  ddl_channel.enabled = arg
			  chk_redraw.enabled = arg
			  destroy()
			  
			  if (arg == true) do (
				  callbacks.addscript #selectionSetChanged "cbSelectionChanged()"
				  cbSelectionChanged()
			  )
		  )
		  
		  on bt_update pressed do cbSelectionChanged()
		  
		  on ddl_channel selected arg do (
			  uvChannel = (ddl_channel.selected as integer)
			  cbSelectionChanged mForce:true
		  )
		  
		  on cp1 changed arg do edgesColor = arg
			  
		  on spn_width changed arg do edgeOffset = (arg-1)/100.0
		  
		  on chk_redraw changed arg do forceRedraw = arg
  
	  )
  
	  createDialog RO_DISPLAY_UV_OE
	  
  )

for your sample object i have:

with no turbosmooth it’s
mesh >> open edges:3920 time:165 memory:1275784L

with 1 turbosmooth iteration it’s
mesh >> open edges:7840 time:600 memory:3171480L


#32

i’ve tested in with max 2012/64


#33
 With your code I get these results:
  
  [b]Base Model[/b]
  mesh >> open edges:3920 time:69 memory:1291032L
  
  [b]Turbosmooth 1 iteration[/b]
  mesh >> open edges:7840 time:243 memory:3211120L
  
  [b]Turbosmooth 2 iterations[/b]
  mesh >> open edges:15680 time:878 memory:8814776L

With my latest code I get these:

Base Model
mesh >> open edges:3920 time:50 memory:2754200L

Turbosmooth 1 iteration
mesh >> open edges:7840 time:108 memory:6075416L

Turbosmooth 2 iterations
mesh >> open edges:15680 time:245 memory:14534304L

From these results yours uses about half the memory and mine runs about 2.5 times faster.


#34

ok. here is my code:


 try(unregisterRedrawViewsCallback showOpenMapEdgesDialog.drawEdges; completeredraw()) catch() 
try(destroydialog showOpenMapEdgesDialog) catch()

rollout showOpenMapEdgesDialog "Open Map Edges" width:200
(
	fn getOpenMapEdges node channel:1 debug:on = if iskindof node GeometryClass and canconvertto node editable_mesh do
	(
		t1 = timestamp()
		m1 = heapfree
		local mesh = snapshotasmesh node
		local edges = #()

		if meshop.getmapsupport mesh channel do
		(
			numtverts = meshop.getnummapverts mesh channel
			getmapface = meshop.getmapface
			
			tfaces = for f=1 to mesh.numfaces collect (getmapface mesh channel f)
			
			local emesh = TriMesh()
			setmesh emesh numverts:numtverts numfaces:mesh.numfaces 
			setmesh emesh faces:tfaces

			seamed = meshop.getopenedges emesh 
			opened = meshop.getopenedges mesh * seamed
			faces = meshop.getfacesusingedge mesh seamed 
				
			for f in faces do
			(
				vv = getface mesh f
				e = f*3 - 3

				if seamed[e += 1] and (vv[1] < vv[2] or opened[e]) do append edges #(getvert mesh vv.x, getvert mesh vv.y)
				if seamed[e += 1] and (vv[2] < vv[3] or opened[e]) do append edges #(getvert mesh vv.y, getvert mesh vv.z)
				if seamed[e += 1] and (vv[3] < vv[1] or opened[e]) do append edges #(getvert mesh vv.x, getvert mesh vv.z)
			)
			if debug do format "mesh >> open edges:% time:% memory:%
" edges.count (timestamp() - t1) (m1 - heapfree) 
			free mesh
			free emesh
		)
		edges
	)

	local edges
	fn drawEdges = if edges != undefined do
	(
		polyLine = gw.polyLine
		gw.setTransform (matrix3 1)
		gw.setColor #line green
		for e in edges do polyLine e off
		gw.enlargeUpdateRect #whole
		gw.updateScreen()
	)

	checkbutton draw_bt "Show" width:190
	on draw_bt changed state do
	(
		unregisterRedrawViewsCallback drawEdges 
		if state do if (edges = getOpenMapEdges selection[1] debug:on) != undefined do registerRedrawViewsCallback drawEdges 
		gc light:on delayed:on
		completeredraw()	
	)
)
createdialog showOpenMapEdgesDialog
 

what numbers does it make for your sample on your machine?


#35

Max 2014 SP1 64bit + Win8
TS = 0
mesh >> open edges:3920 time:146 memory:1287872L

TS = 1
mesh >> open edges:7840 time:947 memory:3172896L

TS = 2
mesh >> open edges:15680 time:5321 memory:8825488L

Restart Max and the results are:
TS = 0
mesh >> open edges:3920 time:145 memory:1337816L

TS = 1
mesh >> open edges:7840 time:626 memory:3174336L

TS = 2
mesh >> open edges:15680 time:4850 memory:8840056L

Denis code

TS = 0
mesh >> open edges:3920 time:33 memory:1136120L
TS = 1
mesh >> open edges:7840 time:86 memory:2797608L

TS = 2
mesh >> open edges:15680 time:235 memory:8011672L


#36

that’s close to what i have. what does make so huge difference? fast memory?


#37

This approach runs faster and uses less memory than mine.

Base Model
mesh >> open edges:3920 time:20 memory:1137208L

Turbosmooth 1 iteration
mesh >> open edges:7840 time:51 memory:2799352L

Turbosmooth 2 iterations
mesh >> open edges:15680 time:137 memory:7984208L

If I remove the Edge Width from my code, yours still runs faster and uses a bit less memory

These are the numbers I get removing the Edge Width feature

Base Model
mesh >> open edges:3920 time:32 memory:1267368L

Turbosmooth 1 iteration
mesh >> open edges:7840 time:74 memory:3061984L

Turbosmooth 2 iterations
mesh >> open edges:15680 time:182 memory:8510272L


#38

if you are still using finditem, and deleteitem the code can’t work so fast. but it’s very interesting for me why your code on your machine makes so good numbers. i’m absolutely sure that 90% people on this forum will get the numbers closer to mine and miauu’s. i can’t understand what makes you code work so different by performance.


#39

And another interesting thing is that your code (the optimization of mine) makes the same numbers on your end and mine. How could that be explained?

Now, your algorithm (not the optimized version of mine), does definitly run faster.

PS: When others see what you don’t!
Can’t avoid loving the simplicity and logic of this: “vv[1] < vv[2]”


#40

Do you think this test can reveal something?

(
 	local test
 	fn test = (
 		seed 3
 		local st = timeStamp()
 		local arr = for j = 1 to 10000 collect random 0 j
 		for j in arr where (found = (findItem arr (random 0 j))) > 0 do deleteItem arr found
 		format "Time %ms
" (timeStamp() - st)
 		print arr.count
 	)
 	test()
 )
 
 -- Time 158ms

#41

you are first who showed the best way how to find all open map seam edges. i’ve asked several times on this forum for this challenge. and because no one was really interested i didn’t show the answer. so you are the winner! :slight_smile:
there is a little mistake in your code which is corrected in mine. open geo edge is not always open map edge.


#42

you are definitely have to look at XViewChecker suggested first by PiXeL_MoNKeY
that’s the right solution


#43

i will check. but as i said all array performance numbers are too good for an average machine and a max system


#44

If anyone is interested in the xViewChecker version, here is a start.
It works with a single Editable Mesh only so there is a lot of work ahead.

fn geomCheck theTime theNode theResults = (
 	
 	obj = copy theNode.mesh
 	uvChannel = 1
 	
 	numTFaces = meshop.getNumMapFaces obj uvChannel
 	numTVerts = meshop.getNumMapVerts obj uvChannel
 	
 	facesTVertsIdx = for j = 1 to numTFaces collect (meshop.getMapFace obj uvChannel j)
 	
 	setMesh obj numverts:numTVerts
 	setMesh obj faces:facesTVertsIdx
 	
 	objOpenEdges = meshop.getOpenEdges obj
 	
 	for edge in objOpenEdges do append theResults edge
 	
 	delete obj
 	gc light:true
 	
 	2
 )

#45

Minor improvement if only uv channel 1 is required, “gettvface” seems to perform faster than “meshop.getmapface”.

(
 	
 	local test1;test2;it=1000000
 	
 	fn test1 = (
 		mesh = snapshotasmesh $
 		st = timeStamp()
 		getmapface = meshop.getmapface
 		tfaces = for f = 1 to it collect (getmapface mesh 1 1)
 		format "%ms 
" (timestamp() - st)
 		delete mesh
 		gc light:true
 	)
 
 	fn test2 = (
 		mesh = snapshotasmesh $	
 		st = timeStamp()
 		tfaces = for f = 1 to it collect (gettvface mesh 1)
 		format "%ms 
" (timestamp() - st)
 		delete mesh
 		gc light:true
 	)
 
 	test1() -- 454ms
 -- 	test2() -- 401ms
 	
 )

#46

Solved!
gw.polygon is brocken, but gw.triangle and gw.tristrip works well.


#47

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.