[Closed] Ordered Poly Attach. Trick is wanted
Look at this snipped:
delete objects
global sp0, sp1, sp2, _m
with redraw off
(
sp0 = sphere segments:32 radius:30 wirecolor:green
converttopoly sp0
polyop.detachfaces sp0 #{1..160}
polyop.detachfaces sp0 #{289..512}
update sp0
-- converttomesh sp0
sp1 = copy sp0 pos:[100,0,0] wirecolor:orange
sp2 = copy sp0 pos:[200,0,0] wirecolor:yellow
scale sp1 [0.5, 1.0, 2.0]
scale sp2 [2, 1.0, 0.5]
resetxform sp1
converttopoly sp1
-- converttomesh sp1
resetxform sp2
converttopoly sp2
-- converttomesh sp2
-- meshop.weldVertsByThreshold sp0 #all 0.01
-- meshop.weldVertsByThreshold sp1 #all 0.01
-- meshop.weldVertsByThreshold sp2 #all 0.01
polyop.weldVertsByThreshold sp0 #all
polyop.weldVertsByThreshold sp1 #all
polyop.weldVertsByThreshold sp2 #all
-- converttopoly sp0
-- converttopoly sp1
-- converttopoly sp2
format ">>>>>>> %, %, %\n" sp0.numverts sp1.numverts sp2.numverts
_m = Morpher()
addmodifier sp0 _m
max modify mode
modpanel.setcurrentobject _m
WM3_MC_BuildFromNode _m 1 sp1
WM3_MC_BuildFromNode _m 2 sp2
)
Try changing the weights on the first two channels of the morpher, and you will see that the order of the target meshes is screwed …
This is the result of the poly welding algorithm. Does anyone have any suggestion how to get around this problem?
The mesh welding works better (you can uncomment this part in my code and try). But for more complicated meshes there is the same issue for meshes as well.
Just an idea. It seems to work with the test scene but may well fail with others.
(
fn RebuildMorphTargets node =
(
max modify mode
morph_node = node
morph_mod = modpanel.getcurrentobject()
if not iskindof morph_mod morpher do return()
channels = for j = 1 to 100 where wm3_mc_hastarget morph_mod j collect j
for j in channels do wm3_mc_setvalue morph_mod j 0.0
for j in channels do
(
wm3_mc_setvalue morph_mod j 100.0
target = wm3_mc_gettarget morph_mod j
new_node = converttopoly (copy morph_node wirecolor:red)
new_node.pos = target.pos
for k = 1 to morph_node.numfaces do
(
f1 = polyop.getfaceverts target k
f2 = polyop.getfaceverts new_node k
for i = 1 to f1.count do
(
p1 = polyop.getvert target f1[i]
polyop.setvert new_node f2[i] p1
)
)
wm3_mc_setvalue morph_mod j 0.0
wm3_mc_delete morph_mod j
wm3_mc_buildfromnode morph_mod j new_node
)
)
RebuildMorphTargets $
)
you could convert this too a c++ that works directly with poly
delete objects
global sp0, sp1, sp2, _m
fn sort_verts sobj cobj =
(
visited = #{};
visited.count = getnumverts cobj;
new_vert_indexing = #();
new_vert_indexing.count = getnumverts cobj;
for f = 1 to getNumFaces cobj do
(
cfverts = getface cobj f; -- correct
sfverts = getface sobj f; -- wrong
for v = 1 to 3 where not visited[cfverts[v]] do
(
new_vert_indexing[cfverts[v]] = sfverts[v];
visited[cfverts[v]] = true;
)
setface sobj f cfverts; -- set the face to match the new indexing
)
-- sort the verts
verts = for v in new_vert_indexing collect getvert sobj v;
for v = 1 to verts.count do setvert sobj v verts[v];
)
with redraw off
(
sp0 = sphere segments:32 radius:30 wirecolor:green
converttopoly sp0
polyop.detachfaces sp0 #{1..160}
polyop.detachfaces sp0 #{289..512}
update sp0
-- converttomesh sp0
sp1 = copy sp0 pos:[100,0,0] wirecolor:orange
sp2 = copy sp0 pos:[200,0,0] wirecolor:yellow
scale sp1 [0.5, 1.0, 2.0]
scale sp2 [2, 1.0, 0.5]
resetxform sp1
converttopoly sp1
-- converttomesh sp1
resetxform sp2
converttopoly sp2
-- converttomesh sp2
-- meshop.weldVertsByThreshold sp0 #all 0.01
-- meshop.weldVertsByThreshold sp1 #all 0.01
-- meshop.weldVertsByThreshold sp2 #all 0.01
polyop.weldVertsByThreshold sp0 #all
polyop.weldVertsByThreshold sp1 #all
polyop.weldVertsByThreshold sp2 #all
converttomesh sp0
converttomesh sp1
converttomesh sp2
sort_verts sp1 sp0
sort_verts sp2 sp0
format ">>>>>>> %, %, %\n" sp0.numverts sp1.numverts sp2.numverts
_m = Morpher()
addmodifier sp0 _m
max modify mode
modpanel.setcurrentobject _m
WM3_MC_BuildFromNode _m 1 sp1
WM3_MC_BuildFromNode _m 2 sp2
)
the visited flag is probably doesn’t save anything/ possibly slower than repeating the indexing
Thank you, guys. Yes, it was my first idea too … to rebuild meshes after welding.
But the problem is worse. All channels are screwed the same way – map channels, specified normals, etc.
I’m thinking more about welding process itself. I probably fast and easy can find all vert pairs for welding (kd-tree), and can pass these pairs for welding. But Poly welding mechanics does do it very slow if you weld one-by-one
mapping is easy to fix same as the geometry, copy the specified normals to a map channel before the weld fix as above then restore from the map channel
sure… i’m already working on it
it would be cool to have this feature anyway for Morph targets pipeline
you may well run into similar issues the the built in functiona have when it comes to getting a guaranteed same order
my idea is to pass “Master” shape and rebuild all morph targets based on geometry and topology of the master
after several experiments i found that trimesh welding works OK. there is no the same issue as with poly welding.
there are some issues… but i can put all pair verts in exact same positions, use very small threshold and it works fine in these conditions
the poly welding algorithm screws topology anyway
so what i do now… Using kd-tree I find all vert pairs i need to weld (it’s quick, and doesn’t take any time), put pairs in exact same positions, run trimesh welding for specified vert list with very small threshold. I don’t have any problems. At least I haven’t met them yet
Also i need to weld only border verts (one from one border to one on another). When I make pairs I control it too