[Closed] automatic instancing based on object similarity – how?
hi everyone,
i have a couple of scene files with thousands of objects, many of which are identical but unfortunately just copies, not instances of each other.
i know there are scripts out there to replace selections of objects with instances but it would still take very long to manually identify all the objects that are identical.
so i was wondering if anybody knows a script that does automatic instancing of identical objects.
if not, what would be a fast and economic way to compare objects and identify those that are basically the same.
i could imagine that e.g. if i define three distinct features that have to match (eg. vertex count, shortest edge, longest edge) it would probably work, but also take very long on large scenes
i am sure there is a more elegant solution. any ideas?
thanks
That would probably be the most elegant way… you’re going to have to find at least something for-sure to compare against… then you can narrow it down from there. I would probably go with vertex count first, then the bounding box size… if both match, then it’s probably close enough…
Go ahead and try this… http://www.scriptspot.com/bobo/mxs9/NextPlease/ I believe Bobo already coded many of those comparisons in.
thanks,
I had a look at the compare functions and it will defenitely help.
also I guess bsearch() is the way to go speedwise
There is a select similar feature available in Max, however I don’t think it is exposed to maxscript. This should do the selection for you then you could run something like:
for obj in 2 to selection.count do instancereplace selection[obj] selection[1]
-Eric
good idea, select similar is quite fast also, but not strict enough, I guess.
It also selects objects that are not really identical.
If we suppose to change copies with instances that means we have to search similar geometries taking into account their trimesh vertex positions. To compare against every vertex might be very slow for many node scenes and/or heavy geometries. But to get positions for every verts in a mesh is not a big deal. Let's compare just sums of vert positions for every node. ;) . The probability of coinsidence is very low. It's a trick but it works in 99%.
gc()
with undo off with redraw off
(
delete objects
for k=0 to 999 do
(
b = box lengthsegs:(random 1 3) widthsegs:(random 1 2) heightsegs:100
centerPivot b
scl = random [0.1,0.1,0.1] [1,1,1]
ang = angleaxis (random 0 180) (random [0,0,0] [1,1,1])
b.transform = rotate (scalematrix scl) ang
)
)
gc()
t1 = timestamp()
vvpos = #()
nodes = #()
for obj in geometry do
(
m = copy obj.mesh
s = [0,0,0]
for v=1 to m.numverts do
(
p = getvert m v
-- p = [abs p.x,abs p.y,abs p.z]
s += p*p -- faster
)
if (k = finditem vvpos s) != 0 then append nodes[k] obj else
(
append vvpos s
append nodes #(obj)
)
)
format "time:% nodes:% similar:%
" (timestamp() - t1) geometry.count nodes.count
for n in nodes do format " vert count:%
" n[1].mesh.numverts
wow, a maxscript with room for uncertainty…I bet it creates a parallel universe everytime I run it.
thanks denisT, will try that tonight.