Mesh PickWalker

Become a member of the CGSociety

Connect, Share, and Learn with our Large Growing CG Art Community. It's Free!

 
Thread Tools Display Modes
  04 April 2018
Mesh PickWalker

Recently found myself working with a morphing job where the two pose meshes were of the same topology - but the vertex order was messed up. The meshes had previously been cut up and rejoined. What a pain. Managed to work around it using the project mesh tool - but this would have been a fantastically useful tool:

http://olygraph.com/maya-mesh-reord...-position-tool/

Anyone know of anything similar for C4D?

If not - maybe one of you plugin guys might like to see if you could collaborate with this guy to bring it to C4D. I'd be first in the queue to buy it : )
 
  04 April 2018
I recently had a similar issue. I ended up using the Morph mix plugin from the same developer of Riptide Pro.
One of the functions reorders points of the base or morph targets in C4Ds morph tag.
__________________
www.scientiaviz.com
 
  04 April 2018
Arik,
Thanks for that - I'll definitely be giving that one a try. I wish I'd asked last week !  : )
 
  04 April 2018
Morphmill has a plugin with it called Remap Point order, works a treat.  This also from the makers of Riptide.

https://skinprops.com/morphmill.php

Dan
__________________
C4D R19 Studio, MODO 902, Zbrush 2018, Unfold3D 9,Marvelous Designer 7, Keyshot 6 pro.
 
  04 April 2018
Thanks Dan - I believe this is what Arik was also referring to above. Looks just what I want. I'll be placing an order as soon as I get into the studio this morning : )
 
  04 April 2018
Originally Posted by Mike Abbott: Thanks Dan - I believe this is what Arik was also referring to above. Looks just what I want. I'll be placing an order as soon as I get into the studio this morning : )
Ahh right, yea sounds like it could be. I was hoping there was another one as well as the one I use works well, but if the mesh is deformed slightly, like sculpted to a different shape to the original it wont work.

Dan
__________________
C4D R19 Studio, MODO 902, Zbrush 2018, Unfold3D 9,Marvelous Designer 7, Keyshot 6 pro.
 
  04 April 2018
Hi,

here's a script i have written some month ago for personal use.
Sorry, german comments!


import c4d
from c4d import gui


polygons_calculated = 0


"""
--------------------------------------------------------------------------------------
Skript zum Synchronisieren der Punkt- und Polygonindizes
von zwei Polygonobjekten mit identischer Topologie aber unterschiedlicher Punkt- und
Polygonreihenfolgen.
--------------------------------------------------------------------------------------
v01-01:
Korrektur im Algorithmus für die Markierung der abzuarbeitenden Polygone. Fälschlicherweise
wurden Polygone mehrfach markiert. Nach einer entsprechenden Anpassung ist das Skript nun 
um ein vielfaches schneller.


Peter Notz (nophoto)
2017-10-16




Nach dem Ausführen des Skripten sind die Punkt- und Polygonstrukturen der beiden
Objekte identisch.




Bedienung:
----------
Sowohl im zu bearbeitenden, als auch im Referenzobjekt muss jeweils genau ein Polygon
und ein Punkt ausgewählt sein.
Wobei im Referenzobjekt das dem im zu bearbeitenden Objekte selektierten Polygon topo-
logisch entsprechende Polygon selektiert sein muss.


Die selektierten Punkte müssen sich ebenfalls topologisch entsprechen und zusätzlich zu 
den selektierten Polygonen gehören.


Zusätzlich müssen beide Objekte im Objektmanager ausgewählt sein. Die Reihenfolge der
Auswahl bestimmt, welches der Objekte bearbeitet wird und welches als Referenzobjekt 
dient. Das als erstes ausgewählte Objekt wird bearbeitet, das zweite dient als Referenz.




Bedingungen:
------------
Die Polygonobjekte dürfen keine Ngons enthälten. Dreiecke sind jedoch erlaubt.
Die Normalen müssen ausgerichtet und bei beiden Objekten in die gleiche Richtung zeigen.
Die Objekte sollten 'Optimiert' sein.
Die Objekte dürfen nur aus einem zusammenhängenden Bereich bestehen.




Bemerkung:
----------
Die Übereinstimmung der Topologie der beiden Objekte wird durch das Skript nicht überprüft.
Ebenso wird auch die Plausibilität der nötigen Punkt-, Polygon- und Objektauswahlen nicht
geprüft.


Der Code ist nicht optimiert und soll auch keineswegs als Beispiel für einen guten Programmier-
stil dienen.
Es ging lediglich darum, ein funktionierendes Skript zu erstellen. Ebenso ist die Kommentierung
noch sehr lückenhaft.
"""


def GetRefPolypoints(o_src, i_srcpoly, i_srcpoint, o_ref, i_refpoly, i_refpoint):
    
    srcpoly = o_src.GetPolygon(i_srcpoly)
    src_vertexnum = srcpoly.Find(i_srcpoint)
    
    refpoly = o_ref.GetPolygon(i_refpoly)
    ref_vertexnum = refpoly.Find(i_refpoint)
    
    polygonvertices = [refpoly.a, refpoly.b, refpoly.c, refpoly.d]
    
    if refpoly.c != refpoly.d: # Es handelt sich um ein Quad
        
        offset =  (ref_vertexnum - src_vertexnum)%4
        
        if    offset == 0:
            return refpoly.a, refpoly.b, refpoly.c, refpoly.d
        elif  offset == 1:
            return refpoly.b, refpoly.c, refpoly.d, refpoly.a
        elif  offset == 2:
            return refpoly.c, refpoly.d, refpoly.a, refpoly.b
        elif  offset == 3:
            return refpoly.d, refpoly.a, refpoly.b, refpoly.c
        
    else: # Es handelt sich um ein Tri
        
        if src_vertexnum == 0:
            
            if ref_vertexnum == 0:
                return refpoly.a, refpoly.b, refpoly.c, refpoly.c
            elif ref_vertexnum == 1:
                return refpoly.b, refpoly.c, refpoly.a, refpoly.a
            else:
                return refpoly.c, refpoly.a, refpoly.b, refpoly.b
            
        elif src_vertexnum == 1:
            
            if ref_vertexnum == 0:
                return refpoly.c, refpoly.a, refpoly.b, refpoly.b
            elif ref_vertexnum == 1:
                return refpoly.a, refpoly.b, refpoly.c, refpoly.c
            else:
                return refpoly.b, refpoly.c, refpoly.a, refpoly.a
            
        else:
            
            if ref_vertexnum == 0:
                return refpoly.b, refpoly.c, refpoly.a, refpoly.a
            elif ref_vertexnum == 1:
                return refpoly.c, refpoly.a, refpoly.b, refpoly.b
            else:
                return refpoly.a, refpoly.b, refpoly.c, refpoly.c


    




def main():
    global polygons_calculated
    
    #c4d.CallCommand(13957, 13957) # Clear Console
    
    osel = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_SELE  CTIONORDER | c4d.GETACTIVEOBJECTFLAGS_CHILDREN)
    if len(osel) != 2: return
    
    o_src = osel[0] # Objekt
    o_ref = osel[1] # Referenz-Objekt
    
    #print "Objekte definiert"
    
    src_pointcount = o_src.GetPointCount()
    src_polygoncount = o_src.GetPolygonCount()
    
    ref_pointcount = o_ref.GetPointCount()
    ref_polygoncount = o_ref.GetPolygonCount()
    
    point_map = [-1]*src_pointcount
    polygon_map = [-1]*src_polygoncount
    
    """ Vorbereiten der Startauswahl """
   
    src_bs_point = o_src.GetPointS()
    if src_bs_point.GetCount() != 1: return
    src_pointsel = src_bs_point.GetAll(src_pointcount)
    i_src_point = src_pointsel.index(1)
    #print "src_pointsel:", i_src_point
    
    src_bs_polygon = o_src.GetPolygonS()
    if src_bs_polygon.GetCount() != 1: return
    src_polygonsel = src_bs_polygon.GetAll(src_polygoncount)    
    i_src_polygon = src_polygonsel.index(1)
    #print "src_polygonsel:", i_src_polygon
    
    ref_bs_point = o_ref.GetPointS()
    if ref_bs_point.GetCount() != 1: return
    ref_pointsel = ref_bs_point.GetAll(ref_pointcount)
    i_ref_point = ref_pointsel.index(1)
    #print "ref_pointsel:", i_ref_point
    
    ref_bs_polygon = o_ref.GetPolygonS()
    if ref_bs_polygon.GetCount() != 1: return
    ref_polygonsel = ref_bs_polygon.GetAll(ref_polygoncount)
    i_ref_polygon = ref_polygonsel.index(1)
    #print "ref_polygonsel:", i_ref_polygon
    
    """ Definieren der Liste mit den markierten Polygonen """
    mark = []
    mark.append({"src_pt": i_src_point, "src_pg": i_src_polygon, "ref_pt": i_ref_point, "ref_pg": i_ref_polygon})
    
    """ Anlegen der Neighbor-Klassen """
    src_nbr = c4d.utils.Neighbor()
    src_nbr.Init(o_src)
    
    ref_nbr = c4d.utils.Neighbor()
    ref_nbr.Init(o_ref)
    
    
    """ Abarbeiten der Topologie """
    while len(mark) > 0:
        
        #print "Anzahl der markierten Polygone:", len(mark)
        #print mark
        
        # Bestimmen der korrespondierenden Punktvertices des aktuellen Polygons...
        m = mark.pop(0)
        res = GetRefPolypoints(o_src, m["src_pg"], m["src_pt"], o_ref, m["ref_pg"], m["ref_pt"])
    
        vadr = o_src.GetPolygon(m["src_pg"])
        
        point_map[vadr.a] = res[0]
        point_map[vadr.b] = res[1]
        point_map[vadr.c] = res[2]
        point_map[vadr.d] = res[3]
        
        polygon_map[m["src_pg"]] = m["ref_pg"]
        polygons_calculated += 1
        
        # Bestimmen der benachbarten Polygone und ablegen dieser in der 'mark'-Liste...
        
        if vadr.c != vadr.d: # Quad...
            src = src_nbr.GetNeighbor(vadr.a, vadr.b, m["src_pg"])
            ref = ref_nbr.GetNeighbor(point_map[vadr.a], point_map[vadr.b], m["ref_pg"])
            if src >= 0 and polygon_map[src] == -1:
                polygon_map[src] = -2
                mark.append({"src_pt": vadr.a, "src_pg": src, "ref_pt": point_map[vadr.a], "ref_pg": ref})
            
            src = src_nbr.GetNeighbor(vadr.b, vadr.c, m["src_pg"])
            ref = ref_nbr.GetNeighbor(point_map[vadr.b], point_map[vadr.c], m["ref_pg"])
            if src >= 0 and polygon_map[src] == -1:
                polygon_map[src] = -2
                mark.append({"src_pt": vadr.b, "src_pg": src, "ref_pt": point_map[vadr.b], "ref_pg": ref})
            
            src = src_nbr.GetNeighbor(vadr.c, vadr.d, m["src_pg"])
            ref = ref_nbr.GetNeighbor(point_map[vadr.c], point_map[vadr.d], m["ref_pg"])
            if src >= 0 and polygon_map[src] == -1:
                polygon_map[src] = -2
                mark.append({"src_pt": vadr.c, "src_pg": src, "ref_pt": point_map[vadr.c], "ref_pg": ref})
            
            src = src_nbr.GetNeighbor(vadr.d, vadr.a, m["src_pg"])
            ref = ref_nbr.GetNeighbor(point_map[vadr.d], point_map[vadr.a], m["ref_pg"])
            if src >= 0 and polygon_map[src] == -1:
                polygon_map[src] = -2
                mark.append({"src_pt": vadr.d, "src_pg": src, "ref_pt": point_map[vadr.d], "ref_pg": ref})
                
        else: # Tri...
            src = src_nbr.GetNeighbor(vadr.a, vadr.b, m["src_pg"])
            ref = ref_nbr.GetNeighbor(point_map[vadr.a], point_map[vadr.b], m["ref_pg"])
            if src >= 0 and polygon_map[src] == -1:
                polygon_map[src] = -2
                mark.append({"src_pt": vadr.a, "src_pg": src, "ref_pt": point_map[vadr.a], "ref_pg": ref})
            
            src = src_nbr.GetNeighbor(vadr.b, vadr.c, m["src_pg"])
            ref = ref_nbr.GetNeighbor(point_map[vadr.b], point_map[vadr.c], m["ref_pg"])
            if src >= 0 and polygon_map[src] == -1:
                polygon_map[src] = -2
                mark.append({"src_pt": vadr.b, "src_pg": src, "ref_pt": point_map[vadr.b], "ref_pg": ref})
            
            src = src_nbr.GetNeighbor(vadr.c, vadr.a, m["src_pg"])
            ref = ref_nbr.GetNeighbor(point_map[vadr.c], point_map[vadr.a], m["ref_pg"])
            if src >= 0 and polygon_map[src] == -1:
                polygon_map[src] = -2
                mark.append({"src_pt": vadr.c, "src_pg": src, "ref_pt": point_map[vadr.c], "ref_pg": ref})
                
        
    #print point_map
    #print polygon_map
    
    doc.StartUndo()
    doc.AddUndo(c4d.UNDOTYPE_CHANGE, o_src)
    
    points = o_src.GetAllPoints()
    ref_tpolygon = o_ref.GetTag(c4d.Tpolygon)
    if ref_tpolygon:
        src_tpolygon = ref_tpolygon.GetClone()
        
        for i in xrange(o_src.GetPointCount()):
            o_src.SetPoint(point_map[i], points[i])
            
        o_src.InsertTag(src_tpolygon)
        o_src.Message(c4d.MSG_UPDATE)
        
    doc.EndUndo()
        
    c4d.EventAdd()
    
    #print "polygons_calculated", polygons_calculated
        


if __name__=='__main__':
    main()


How to use?

You need two polygon objects with the same topology (identical point, edge and point count). They do not need to be of the same shape.
Tris are allowed, ngons not. Be sure the normals are aligned in the same way and the mesh is clean and consists of a single island.

Select in both objects one topologically identical polygon and one point belonging to these polygons. These points must be also topologically identical.
After that you have to select the objects in the right order. First the object you want to edit and then the reference object, with the right point and polygon order.

Here's an example how it should look like


Now one can execute the script.
If everything goes well the first selected object now has the same point- und polygonorder as the second.

I hope that everything is clear so far.

Peter
 
  04 April 2018
Peter - thank you for posting that - very generous of you to share. 
 
reply share thread



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
CGSociety
Society of Digital Artists
www.cgsociety.org

Powered by vBulletin
Copyright ©2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump
Miscellaneous

All times are GMT. The time now is 03:20 AM.


Powered by vBulletin
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.