Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    select edge points with python

    Cinema 4D SDK
    2
    5
    1.3k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • D
      datamilch
      last edited by

      hi there,
      with mech check, there is the option to select all "edge points"
      these are all points that are only connected to two eges. these points can be found on at the border or between two n-gones.

      i'd like to select and delete them with pyhon.

      i was looking into the Neighbor() function. but it seems quite tricky, since neighbor seems to ignore n-gones and dissolves them internally.

      alternatively, is there any chance to send a modeling command to mesh check or simulate a mouse click on the select button?

      any ideas or hints are wellcome!

      1 Reply Last reply Reply Quote 0
      • ManuelM
        Manuel
        last edited by

        Hi,

        Instead of reinventing the wheel, as you said, you can use the already existing function. This can be triggered by sending the right message the the SceneHook that is responsable to this mesh check tool. The only thing you need is to build a DescriptionCommand that just need to have its _descId defined.

        The scenehook ID is not available you have to define it. The message ID that correspond to the button clicked can be found in our documentation.

        As DescriptionCommand is not available in python, it is not possible to do that using Python. I am afraid there is no solution neither checking yourself as ngon management in python is not possible.

        #include "lib_description.h"
        #include "dmodeling.h"
        
        #define ID_MESHCHECK 431000027
        
        static maxon::Result<void> PC14455(BaseDocument* doc)
        {
        	iferr_scope;
        
        	BaseSceneHook* meshHook = doc->FindSceneHook(ID_MESHCHECK);
        	if (meshHook)
        	{
        		DescriptionCommand dcu;
        		dcu._descId = MESH_CHECK_EDGEPOINT_SELECT;
        		meshHook->Message(MSG_DESCRIPTION_COMMAND, &dcu);
        	}
        	return maxon::OK;
        }
        
        

        Cheers,
        Manuel

        MAXON SDK Specialist

        MAXON Registered Developer

        1 Reply Last reply Reply Quote 0
        • D
          datamilch
          last edited by

          hi manuel,
          thanks for the response, the info and the code example!
          sadly i have absolutely no idea how to handle c++ at all 😞

          concerning python and ngons:
          it is possible to select all polygons or edges involved with ngons. it works here.
          i'm struggling to find the specific edge-ids of the hiddn ngone-edges or the point-ids of these hidden edges.
          if i had the point ids i would be able to make it work.
          is there any way to distinguish visible and invisible edges of ngons?
          or is this what you ment with "ngon management in python is not possible"?

          1 Reply Last reply Reply Quote 0
          • ManuelM
            Manuel
            last edited by Manuel

            hi,

            In c4d there is no edge, edges are just defined by being connected between two points.

            After trying a lot of things i finally found something that looks to work.
            It is a combinaison of many ideas. The idea is to count the number of times a point is present on a polygon and the number of times this point is present on a ngon's edge. Make the difference and just keep the point that have a difference of 2 so this point is connected to only two edges.

            from typing import Optional
            import c4d
            
            doc: c4d.documents.BaseDocument  # The active document
            op: Optional[c4d.BaseObject]  # The active object, None if unselected
            
            # Tries to get the points that are only connected to two edge and part of NGons
            
            
            
            def main() -> None:
                polys = op.GetAllPolygons()
                # GetNgonEdgesCompact will give a list of value for each polygon.
                # Those correspond to a binary value where 1 mean the edge is part of an ngon
                # and 0 mean no. Be careful that for Triangle edge 2 must not be taken into account.
            
                # edge                3   2   1   0
                #                     -   -   -   -   =   0
                #                     -   -   -   x   =   1
                #                     -   -   x   -   =   2
                #                     -   -   x   x   =   3
                #                     -   x   -   -   =   4
                #                     -   x   -   x   =   5
                #                     -   x   x   -   =   6
                #                     -   x   x   x   =   7
                #                     x   -   -   -   =   8
                #                     x   -   -   x   =   9    
                #                     x   -   x   -   =   10
                #                     x   -   x   x   =   11
                #                     x   x   -   -   =   12
                #                     x   x   -   x   =   13
                #                     x   x   x   -   =   14
                #                     x   x   x   x   =   15
            
                ngonEC = op.GetNgonEdgesCompact()
                pointCount = op.GetPointCount()
                
            
                # Array allowing to count, for each point,  the number of time this point is present in an polygon
                # and the number of time this point is present in an ngon edge.
            
                pointNgonDict = {}
                pointPolyDict = {}
                answer = []
                
                for index in range(0, pointCount):
                    pointNgonDict[index] = 0
                    pointPolyDict[index] = 0
                
                # Prepare a neighbor object so we can check if the edge is marked or not avoiding
                # to count mutiple time an edge
                nb = c4d.utils.Neighbor()
                nb.Init(op)
                
                # For each polygon
                for polyIndex, cPoly in enumerate(polys):
                    pli = nb.GetPolyInfo(polyIndex)
                    
                    # mark those points as part of the polygon
                    pointPolyDict[cPoly.a] += 1
                    pointPolyDict[cPoly.b] += 1
                    pointPolyDict[cPoly.c] += 1
                    
                    
                    if cPoly.IsTriangle():
                        # here the edge are really 0, 1, 3 we do not use 2.
                        for edgeIndex in [0, 1, 3]:
                            # To avoid counting twice an edge only check those that are marked as false.
                            if pli["mark"][edgeIndex] == False:
                                # If the bit of this edge is set to 1, that mean this edge is on a ngon
                                if ngonEC[polyIndex] & (1 << edgeIndex):
                                    p1, p2 = cPoly.EdgePoints(edgeIndex)
                                    pointNgonDict[p1] += 1
                                    pointNgonDict[p2] += 1
                    else:
                        # we include the fourth point.
                        pointPolyDict[cPoly.d] +=1
                        # same as the triangle but with all index 0, 1, 2, 3
                        for edgeIndex in [0, 1, 2, 3]:
                            if pli["mark"][edgeIndex] == False:
                                if ngonEC[polyIndex] & (1 << edgeIndex):
                                    p1, p2 = cPoly.EdgePoints(edgeIndex)
                                    pointNgonDict[p1] += 1
                                    pointNgonDict[p2] += 1
            
                # We calculate the difference between those two array and put in the result 
                # array only points index that are
                # in 2 more polygons than the number of edge present on a ngon this point is part of.
                
                for i, (j, k) in enumerate(zip(pointPolyDict.values(), pointNgonDict.values())):
                    # Check i the point is at least in one ngon with k > 0
                    if k > 0 andj - k == 2:
                        answer.append(i)
            
                print (pointNgonDict)
                print (pointPolyDict)
                print(answer)
                
            
            if __name__ == '__main__':
                main()
            

            Cheers,
            Manuel

            MAXON SDK Specialist

            MAXON Registered Developer

            1 Reply Last reply Reply Quote 0
            • D
              datamilch
              last edited by

              wohaa, thank you so much for your time an effort!

              i will have a good look at it.

              alos great insight into what the GetNgonEdgesCompact numbers mean. this was a bit mysterious in the sdk, or at least hard to decipher what the description meant.

              1 Reply Last reply Reply Quote 0
              • i_mazlovI i_mazlov referenced this topic on
              • First post
                Last post