Notifications
Clear all

[Closed] How to get fast different vertices?

Hi,

Could you help me please, how to filter fast vertex differences between two objects?

I’ve built up versions with EditPolyMod.getVert and polyop.getVert but with these it gets slow and especially require to touch the baseobject or add modifier to get vert positions of the full modifier stack, all of that get that much slower.

So as second version I built up the one bellow with getVert *.mesh v . Which seemed to be faster and i don’t need to manipulate with modifiers, butt it is still not fast as I would need. Definetly not on big messhes.

Could you eventually share how people actually do such a filtering in modifiers when manipulating vertices to make it fast?

fn GetDifferentVerts a b treshold:0.0001 = (
	DifferentVerts= #{}
	
	for i = 1 to a.numverts do (
		a_pos = in coordsys a (getVert a.mesh i)
		b_pos = in coordsys b (getVert b.mesh i)
		DifferentVerts[i] = if (distance a_pos b_pos) > treshold then true else false
	)

	return DifferentVerts
)
--execution
try(delete ($mybaby))catch()
try(delete ($mykitty))catch()
a = sphere name:"mybaby" pos:[0,0,0] radius:2.5 segments:64 wirecolor:[250,250,210]
b = sphere name:"mykitty" pos:[0,0,5] radius:2.5 segments:64 wirecolor:[210,250,250]
n = Noisemodifier strength:[50,0,0] fractal:true seed:(random 0 100)
convertToMesh a
addmodifier b n

start = timestamp()
d = GetDifferentVerts a b
format "% vertices took: % ms
" a.numverts (timestamp()-start)
print d
redrawViews()

Thanks
TM

9 Replies

here is probably the fastest way to compare vertex positions:


fn GetDifferentVerts a b threshold:0.001 = 
(
	DifferentVerts= #{}
	amesh = copy a.mesh
	bmesh = copy b.mesh
	for i = 1 to amesh.numverts where distance (getVert amesh i) (getVert bmesh i) > threshold do append DifferentVerts i

	free amesh
	free bmesh
	
	DifferentVerts
)
--execution
delete objects
a = sphere name:"mybaby" pos:[0,0,0] radius:2.5 segments:128 wirecolor:[250,250,210]
b = sphere name:"mykitty" pos:[0,0,5] radius:2.5 segments:128 wirecolor:[210,250,250]
n = Noisemodifier strength:[0.01,0,0] fractal:on seed:(timestamp())
convertToMesh a
addmodifier b n
gc()
t1 = timestamp()
d = GetDifferentVerts a b
format "vertices:% different:% time:%
" a.numverts d.numberset (timestamp() - t1)


now there is some explanation:

when you try to access the mesh by a.mesh property the system creates new instance of the mesh on every call. so we have to use a copy

in coordsys <node> doesn’t make sense in you case because trimesh vertex positions are in the node space

you don’t need to set bit to false in bitarray because all bits are off by default

delete objects
 a = geosphere name:"mybaby" pos:[0,0,0] radius:2.5 segments:124 wirecolor:[250,250,210]
 b = geosphere name:"mykitty" pos:[0,0,5] radius:2.5 segments:124 wirecolor:[210,250,250]
 n = Noisemodifier strength:[0.01,0,0] fractal:on seed:(timestamp())
 convertToMesh a
 addmodifier b n
 gc()
 t1 = timestamp()
 d = GetDifferentVerts a b
 format "vertices:% different:% time:%
" a.numverts d.numberset (timestamp() - t1)

result:
vertices:153762 different:0 time:258
not bad

Very cool, runs great. Thanks for it and for the educational explanation.

With the original code from Denis – time: 325

When I use this:

local moGetVert = getVert
   for i = 1 to amesh.numverts where distance (moGetVert amesh i) (moGetVert bmesh i) > threshold do append DifferentVerts i

time: 266

I did some tests with 3 different ways of getting verts position. Here the results

local moGetVert = getVert
   		for i = 1 to amesh.numverts where distance (moGetVert amesh i)  (moGetVert bmesh i) > threshold do append DifferentVerts i

time: 266

poGetVert = polyop.getVert
  for i = 1 to a.numverts where distance (poGetVert a i) (poGetVert b i) > threshold do append DifferentVerts i

time:583


 for i = 1 to a.numverts where distance (a.verts[i].pos) (b.verts[i].pos) > threshold do append DifferentVerts i

time: 809

usually it doesn’t make a difference. it makes sense to redefine only functions from structures or interfaces. but if it works better… why not to use it

Actually sometimes using this(in your code):
local moGetVert = getVert is faster, sometimes is slower.

trust me, it’s just the same

Using either of them I get the same results:

  170ms (+- 5ms)

Edit: 140ms (± 5ms) on fresh start.

for i = 1 to amesh.numverts where distance (getVert amesh i) (getVert bmesh i) > threshold do append DifferentVerts i
local moGetVert = getVert
   for i = 1 to amesh.numverts where distance (moGetVert amesh i) (moGetVert bmesh i) > threshold do append DifferentVerts i