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
    • Register
    • Login

    Get edges segments in a polygon object

    Cinema 4D SDK
    python r21
    4
    8
    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.
    • FlavioDinizF
      FlavioDiniz
      last edited by

      Hi!
      I'm trying to find the selected edges segments in a polygon object, like the one below:
      alt text

      I want to get each segment separated, so I can create some functions like the example below:

      for segment in segmentlist:
          MoveInUvSpace()
      

      I've tried a lot of things with BaseSelect, Neighbor and PolygonObject classes, but no success...

      here's my testing code, I was able to get the total edge count, get the ammount of edges selected edges and get the the selected edge with its index.

      import c4d
      
      def main():
          
          op = doc.GetActiveObject()
          
          nb = c4d.utils.Neighbor()
          nb.Init(op)
          
          seledges = op.GetSelectedEdges(nb,c4d.EDGESELECTIONTYPE_SELECTION) #base select
          print seledges.GetSegments()
          print seledges.GetCount()
          print seledges.GetRange(1,nb.GetEdgeCount())
          print "total edges", nb.GetEdgeCount()
          
          
          notselected = []
          selectededge = []
          bs = op.GetEdgeS()
          sel = bs.GetAll(nb.GetEdgeCount())
          for index, selected in enumerate(sel):
              if not selected: continue
              print "Index", index, "is selected"
              selectededge.append(selected)
          print notselected
          print selected
          
      
      if __name__=='__main__':
          main()
          
      

      if anyone have any hint in how I could achieve this, I would be very happy!

      Flavio Diniz

      1 Reply Last reply Reply Quote 0
      • P
        PluginStudent
        last edited by

        I don't think there is such a thing as a "edge segment". There are only individually selected edges. How such single edges are combined to a "segment" is up to you.

        I also think one would probably need the GetOriginalEdgePoints() function of the Modeling class, which is not available in Python.

        FlavioDinizF 1 Reply Last reply Reply Quote 0
        • C4DSC
          C4DS
          last edited by

          As far as I know your only option would be to collect your "segments" yourself. At least, that is how I have been doing it.

          1 Reply Last reply Reply Quote 0
          • FlavioDinizF
            FlavioDiniz @PluginStudent
            last edited by

            @PluginStudent @C4DS
            ah, so I think this is more complex than I thought 🤔

            I guess I have to make a function to compare the edges by using their points...
            if two edges shares the same point, it means these two edges are a single segment. So create a BaseSelect of these edges and use it in a for loop.
            It may cause some bugs depending how the geometry is... but at least is a starting point and a tough one for me xD

            Thank you guys!

            Flavio Diniz

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

              hello,

              i gave it a try and came with that "solution", i just ran some test on a plane but that should give you some idea.
              this would need some polish like ordering the points in the result and it can probably be optimized.

              I've set this thread to "ask a question" please set it as solved if you think your question as been replied (even if there's no solution :p)

              Of course this will consider a "cross" as one single segment

              import c4d
              from c4d import gui
              # Welcome to the world of Python
              
              
              
              class MySegments (object):
                  def __init__(self, op):
                      if op is None:
                          raise ValueError("can't initialize class with a None object")
                      if op.IsInstanceOf(c4d.Opolygon) != True:
                          raise ValueError("class only work with polygon object")
              
                      self.op = op
                      self.nb = c4d.utils.Neighbor()
                      self.nb.Init(op)
                      self.polys = op.GetAllPolygons()
                      self.edgeSelected = op.GetEdgeS()
                      self.ces = self.edgeSelected.GetClone()
                      self.segments = []
              
                  def CreateSegment(self, polyAid, edgeAid):
                      """
                      Recursive function that will check if any neighbor edge is selected
                      If so, it will recurse with the new edge.
                      """
                      # first deselect edge so we are sure we are not adding this edge twice
                      self.DeselectEdge(polyAid, edgeAid)
                      # retrieves the points of this edge
                      points = self.polys[polyAid].EdgePoints(edgeAid)
                      # add this edge to the last segment
                      self.segments[-1].append(points)
                      # for each point, check if any attached edge is selected
                      for point in points:
                          neibPolysIds = self.nb.GetPointPolys(point)
                          for polyBid in neibPolysIds:
                              for edgeBid in xrange(4):
                                  if self.ces.IsSelected(4 * polyBid + edgeBid):
                                      # checks if any point are in common
                                      if self.PointInCommon(polyAid, edgeAid, polyBid, edgeBid):
                                          # this edge must be added to the last segment and check for the next edges.
                                          self.CreateSegment(polyBid, edgeBid)
              
                  def PointInCommon(self, polyAid, edgeAid, polyBid, edgeBid):
                      """ this function check if two edge have some point in common"""
                      polyA = self.op.GetPolygon(polyAid)
                      polyB = self.op.GetPolygon(polyBid)
              
                      edgeAPoints = polyA.EdgePoints(edgeAid)
                      edgeBPoints = polyB.EdgePoints(edgeBid)
                      if edgeAPoints[0] == edgeBPoints[0] or edgeAPoints[0] == edgeBPoints[1]:
                          return True
                      if edgeAPoints[1] == edgeBPoints[0] or edgeAPoints[1] == edgeBPoints[1]:
                          return True
                      return False
              
              
                  def ComparePoints(self, pointsA, pointsB):
                      """
                       This function compare if two array of points are equals
                      """
                      if pointsA[0] == pointsB[0] and pointsA[1] == pointsB[1]:
                          return True
                      if pointsA[1] == pointsB[0] and pointsA[0] == pointsB[1]:
                          return True
                      return False
              
              
                  def DeselectEdge(self, polyAid, edgeAid):
                      """
                      The BaseSelect we got from GetEdgeS will have two entry for one selected edge (on per polygon)
                      we must retrieve the other polygon and find the edge in common to deselect it.
                      """
                      # Deselect the first edge.
                      self.ces.Deselect(4 * polyAid + edgeAid)
                      # Gets the poinfs from edge A id
                      pointsA = self.polys[polyAid].EdgePoints(edgeAid)
                      # Retrieves the polygin ID of the polygon on the other side of the edge
                      polyBid = self.nb.GetNeighbor(pointsA[0], pointsA[1], polyAid)
                      #checks if there's no polygon on the other side
                      if polyBid == -1:
                          return 
                      # Get the polygon Structure
                      polyB = self.op.GetPolygon(polyBid)
                      # Check each edge if it's the same than the firt edge and deselect it.
                      for edgeBid in xrange(4):
                          pointsB = polyB.EdgePoints(edgeBid)
                          if self.ComparePoints(pointsA, pointsB):
                              self.ces.Deselect(4 * polyBid + edgeBid)
              
              
              
                  def Execute(self):
                      segments = []
                      polycnt = self.op.GetPolygonCount()
              
                      for polyid in xrange(polycnt):
                          for edgeid in xrange(4):
                              element = 4 * polyid + edgeid
                              # checks if the edge is selected
                              if self.ces.IsSelected(element):
                                  # create a new segment for this edge
                                  self.segments.append([])
                                  # the function CreateSegment will add this edge and search for any other edge attached to that edge.
                                  self.CreateSegment(polyid, edgeid)
                      print self.segments
              
              
              
              def main():
                  if op is None:
                      raise ValueError("select at least one object")
              
                  mySegments = MySegments(op)
                  mySegments.Execute()
              
              
              # Execute main()
              if __name__=='__main__':
                  main()
              

              cheers,
              Manuel

              MAXON SDK Specialist

              MAXON Registered Developer

              FlavioDinizF 1 Reply Last reply Reply Quote 1
              • FlavioDinizF
                FlavioDiniz @Manuel
                last edited by

                Fantastic @m_magalhaes !
                works very well! and for the use I'm planning, I will always be using parallel selection segments, so cross selections isn't a issue 🙂 !

                there's an small error, I guess it's happening because there's no polygons to the left to be checked.
                alt text

                I haven't had time to fully read your code yet, but it's already very helpful!
                I'll try to solve this error by modifying your code or building another use using you as base.

                Thank you!

                (I'll let it unsolved for today, in case someone wants to post something else, then I'll change to solved)

                Flavio Diniz

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

                  hi,

                  right, if you are at a border there's not polygon on the other side:

                  i've update my code on the other post with this

                   if polyBid == -1:
                              return 
                  

                  Cheers,
                  Manuel

                  MAXON SDK Specialist

                  MAXON Registered Developer

                  FlavioDinizF 1 Reply Last reply Reply Quote 1
                  • FlavioDinizF
                    FlavioDiniz @Manuel
                    last edited by

                    Awesome @m_magalhaes, works perfect now!
                    Thank very much!

                    Flavio

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post