Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python 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

    GetEdgeCount() Bug?

    Scheduled Pinned Locked Moved Bugs
    14 Posts 0 Posters 2.3k Views
    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.
    • H Offline
      Helper
      last edited by

      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

      On 05/02/2012 at 11:49, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:   12 
      Platform:   Windows  ;   
      Language(s) :

      ---------
      I'm not getting the correct results from GetEdgeCount(). It's not returning the correct amount of edges in an object. It always comes up short.
      I'm testing this in Python. But since Python is just wrapping around the C++ API. It might be coming from C++.

      Here's an example:

      import c4d  
      from c4d import utils  
        
      def main() :  
        obj = doc.GetActiveObject()      #A cube object  
        nibr = utils.Neighbor()          #Assigns neighbor to a variable  
        nibr.Init(obj)                   #Instantiates the neighbor class using the "obj"  
        edgecount = nibr.GetEdgeCount()  #Get all the edges in the entire polygon object  
        print edgecount    #Prints 12!? <----This should be 16!!!                  
        
        edges = c4d.BaseSelect() #Create a BaseSelect object  
        
        mylist = [x for x in range(edgecount)] #Creates an array size based on GetEdgeCount()   
        print mylist  
        edges.SetAll(mylist)  
        
        edges.CopyTo(obj.GetEdgeS())  #Makes the edges selected in the scene from memory  
                                      #Only 12 edges are selected because GetEdgeCount() failed!?  
        
        c4d.EventAdd()  
        
      if __name__=='__main__':  
        main()
      

      When I use this on a more complex object. The number of missed edges climbs.
      Is this a bug?

      Update:
      I got a chance to try this is in C++ and got the same wrong edge count results:

          BaseDocument *doc = GetActiveDocument();  
        BaseObject *op = doc->GetActiveObject();  //A cube object  
        if (!op) return FALSE;  
        
        if (op->GetType() == Opolygon)  
        {  
         Neighbor n;  
         if (!n.Init(ToPoly(op)->GetPointCount(),ToPoly(op)->GetPolygonR(),ToPoly(op)->GetPolygonCount(),NULL)) return FALSE;  
        
         LONG ecount = n.GetEdgeCount();    // Count the edges in the object  
         GePrint(LongToString(ecount));     //<---Prints 12!?.......Should be 16!!!
      

      Could someone from Maxon please confirm this as either bug, or user error.
      I can't use it until I know what's really going on with it.

      -ScottA

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

        On 05/02/2012 at 14:59, xxxxxxxx wrote:

        This is very confusing.

        -There are 24 edges in a cube. If you count each polygon as a separate face
        -GetEdgeCount() returns 12 edges. So using that I end up with all but three edges selected
        -If I use an array with 16 elements in it as the source for SetAll(myarray). Every edge of the cube is selected as expected.

        All I want to do is use GetEdgeCount() to get the number of edges in an object. Like the name of the function implies. Then use that number to select them later on.
        But it looks like I can't do that because GetEdgeCount() does not count every single edge as the name implies.

        What it looks like I'm having trouble with. Is figuring out how these various functions determine what an edge is. And when they are/and are not, counting them.

        -If I use edgecount = nibr.GetEdgeCount()*2 it does select all the edges of a cube.
        -If I use edgecount = nibr.GetEdgeCount()*2 on a plane. It selects all but one edge.
        -If I use edgecount = nibr.GetEdgeCount()*2 on a  sphere. I get five unselected  edges at the poles.

        Is this the desired result for GetEdgeCount() ?
        The more I try to use it. The more confused I get. 😵

        -ScottA

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

          On 06/02/2012 at 09:33, xxxxxxxx wrote:

          If you look at PolygonObject.GetSelectedEdges() documentation, it's stated that: "The edges are indexed uniquely by a Neighbor object, so each edge has a single index."
          So there are only 12 edges in a cube. We can see that looking at the information returned by Neighbor.GetPolygonCount() :

          for i in xrange(op.GetPolygonCount()) :
              pli = nbr.GetPolyInfo(i)
              print pli
          

          There's some missing documentation for the information returned by Neighbor.GetPolygonCount() for the Python docs. You can take a look at the C++ docs for this method.
          'mark' indicates if an edge is new or was already built. There are 12 False 'mark' and 12 True 'mark'.

          BaseSelect.SetAll() accepts an array of selection states , 0 or 1 values, not indices. So you should build the edges selection array like this:

          mylist = [1 for x in range(edgecount)]
          

          And to select edges it works as expected calling PolygonObject.SetSelectedEdges().

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

            On 06/02/2012 at 10:51, xxxxxxxx wrote:

            Originally posted by xxxxxxxx

            And to select edges it works as expected calling PolygonObject.SetSelectedEdges().

            Thanks for the help Yannick.
            But I still can't select all edges of a polygon object using that information.
            Example:

            import c4d  
            from c4d import gui,utils  
              
            def main() :  
              
              obj = doc.GetActiveObject()       #A cube object  
              nbr = utils.Neighbor()            #Assigns neighbor to a variable  
              nbr.Init(obj)                     #Instantiates the neighbor class using the "obj"  
              edgecount = nbr.GetEdgeCount()    #Get all the edges in the entire polygon object  
              
              for i in xrange(op.GetPolygonCount()) :  
                  pli = nbr.GetPolyInfo(i)  
                  print pli  
              
              mylist = [1 for x in range(edgecount)] #Set all edges to True  
              
              obj.SetSelectedEdges(nbr,mylist,c4d.EDGESELECTIONTYPE_SELECTION)#<--Error:c4d.PolygonObject has no attribute 'SetSelectedEdges'  
              
            if __name__=='__main__':  
              main()
            

            Any chance of seeing a proper working example of this?

            Thanks,
            -ScottA

            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

              On 06/02/2012 at 11:18, xxxxxxxx wrote:

              Ah... you may be using a pre-R13 version. SetSelectedEdges() was added to the Python SDK in version R13.

              Here's how to do without SetSelectedEdges() :

              import c4d
              from c4d import utils
                
              def main() :
                  nbr = utils.Neighbor()
                  nbr.Init(op)
                  indices = [1 for i in range(nbr.GetEdgeCount()*2)]
                  edges = c4d.BaseSelect()
                  edges.SetAll(indices)
                
                  edges.CopyTo(op.GetEdgeS())
                  c4d.EventAdd()
                
              if __name__=='__main__':
                  main()
              

              SetSelectedEdges() works with unique edges but GetEdgeS() not. I just reversed engineered GetEdgeS() getting the current selection and it's 24 edges when we select all the edges. In R13 with GetSelectedEdges() it's 12 edges. So it's more or less what you tried before 🙂 except the edges array is built with selection states values.

              1 Reply Last reply Reply Quote 0
              • H Offline
                Helper
                last edited by

                THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                On 06/02/2012 at 12:11, xxxxxxxx wrote:

                Lol.
                Isn't it fun trying to troubleshoot these functions when they get updated so often from version to version?😉
                That code you posted brings me back to my original problem.
                *2 works for a cube. But it does not select all edges on a sphere for example.
                I've even tried multiplying nbr.GetEdgeCount() * 3.02 and that still doesn't work in all cases.
                But lets forget about R12 at this point. And call it not supported. And just focus on R13 from now on...OK?
                No sense trying to get the older version to work at this point.

                Can you please post a code example that selects all edges in an object for R13 using the "op.SetSelectedEdges" function?
                But before you post it. Please try it out on both a cube and a sphere.
                I'm still getting the same results in R13 as r12. And I want to see if you get the same results.

                Thanks,
                -ScottA

                1 Reply Last reply Reply Quote 0
                • H Offline
                  Helper
                  last edited by

                  THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                  On 06/02/2012 at 12:27, xxxxxxxx wrote:

                  Originally posted by xxxxxxxx

                  Can you please post a code example that selects all edges in an object for R13 using the "op.SetSelectedEdges" function?
                  But before you post it. Please try it out on both a cube and a sphere.
                  I'm still getting the same results in R13 as r12. And I want to see if you get the same results.

                  Here's the working code for any polygon object in R13 using SetSelectedEdges() :

                  import c4d
                  from c4d import utils
                    
                  def main() :
                      nbr = utils.Neighbor()
                      nbr.Init(op)           # Initialize neighbor with a polygon object
                      
                      selection = [1 for i in range(nbr.GetEdgeCount())] # Select all the edges = set them to 1
                      edges = c4d.BaseSelect()
                      edges.SetAll(selection)                            # Set the edges selection with the selection list
                    
                      op.SetSelectedEdges(nbr, edges, c4d.EDGESELECTIONTYPE_SELECTION) # Select edges from our edges selection
                      c4d.EventAdd() # Update CINEMA
                    
                  if __name__=='__main__':
                      main()
                  
                  1 Reply Last reply Reply Quote 0
                  • H Offline
                    Helper
                    last edited by

                    THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                    On 06/02/2012 at 12:34, xxxxxxxx wrote:

                    Excellent.
                    I think I've got it all sorted out now.

                    Thanks a lot for sticking with me on this one.🍺

                    -ScottA

                    1 Reply Last reply Reply Quote 0
                    • H Offline
                      Helper
                      last edited by

                      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                      On 06/02/2012 at 12:53, xxxxxxxx wrote:

                      If you want to select all edges you should be able to use

                        
                      edges.SelectAll(edgecount)   
                      obj.SetSelectedEdges(nibr,edges,c4d.EDGESELECTIONTYPE_SELECTION)   
                      
                      1 Reply Last reply Reply Quote 0
                      • H Offline
                        Helper
                        last edited by

                        THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                        On 06/02/2012 at 13:16, xxxxxxxx wrote:

                        Yeah. That's true Lennart.

                        I'm using arrays in my examples because it gives me a way to iterate through my selections.
                        AFAIK. BaseSelection is not iterable. That's why I'm using arrays(lists) in my code.

                        Probably a good idea that you pointed that out for the sake of others new to this subject that don't need or want that extra iteration ability.

                        -ScottA

                        1 Reply Last reply Reply Quote 0
                        • H Offline
                          Helper
                          last edited by

                          THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                          On 06/02/2012 at 15:17, xxxxxxxx wrote:

                          You could iterate using enumerate and get a list:

                            
                          # Get Set Edges Test R13   
                          import c4d   
                          from c4d import utils as u   
                            
                          def main() :   
                              obj = doc.GetActiveObject()   
                              if obj is None or not obj.CheckType(c4d.Opolygon) :   
                                  return True   
                              n   = u.Neighbor()   
                              n.Init(obj)   
                              edgecount = n.GetEdgeCount()   
                              print edgecount   
                              edges = obj.GetSelectedEdges(n, c4d.EDGESELECTIONTYPE_SELECTION)   
                              elist = []   
                              for i, sel in enumerate(edges.GetAll(edgecount)) :   
                                  if sel: elist.append(1)   
                                  else:   elist.append(0)   
                              print elist   
                              edges.SetAll(elist)   
                              obj.SetSelectedEdges(n, edges, c4d.EDGESELECTIONTYPE_SELECTION)   
                              c4d.EventAdd()   
                            
                          if __name__=='__main__':   
                              main()   
                          
                          1 Reply Last reply Reply Quote 0
                          • H Offline
                            Helper
                            last edited by

                            THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                            On 06/02/2012 at 17:59, xxxxxxxx wrote:

                            Yeah I know. That's what I've been doing in R12.
                            Although lately I've been using a different method where I iterate from inside of the the lists themselves.
                            Same difference.😉

                            I got hung up on trying to select all edges. GetEdgeCount() didn't work as I expected it to work.
                            I'm good to go now. Except that now I'm forced to use R13. 😠

                            I'm still thinking that this should be possible to do in R12 though.
                            Since we can iterate selections using lists. I would think that we should be able to step through the polygons and get & set every edge that way. But I couldn't make it work.
                            It might  require getting each polygon point(A,B,C,D).
                            Then using that to find all the edges. And putting that into a list.
                            Then using that list to select the edges.

                            That's kind of advanced stuff for me right now. I'm still not very good with polygons & edges.

                            -ScottA

                            1 Reply Last reply Reply Quote 0
                            • H Offline
                              Helper
                              last edited by

                              THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                              On 07/02/2012 at 01:28, xxxxxxxx wrote:

                              Originally posted by xxxxxxxx

                              I got hung up on trying to select all edges. GetEdgeCount() didn't work as I expected it to work.
                              I'm good to go now. Except that now I'm forced to use R13. 
                              I'm still thinking that this should be possible to do in R12 though.

                              Here's the code for R12:

                              import c4d
                              from c4d import utils
                                
                              def main() :  
                                  numEdges = op.GetPolygonCount()*4
                                  
                                  edges = c4d.BaseSelect()
                                  edges.SelectAll(numEdges-1)
                                
                                  edges.CopyTo(op.GetEdgeS())
                                  c4d.EventAdd()
                                
                                
                              if __name__=='__main__':
                                  main()
                              

                              As you can see, the number of edges is the number of polygons multiplied by 4 (4 edges per polygon). GetEdgeS() doesn't work with shared edges, Neighbor and the methods using it (GetSelectedEdges(), SetSelectedEdges()) do.
                              I select all the edges to numEdges-1 and not to numEdges because I found an issue with SelectAll(). The number of selected elements is number+1 the number you pass to the method.

                              1 Reply Last reply Reply Quote 0
                              • H Offline
                                Helper
                                last edited by

                                THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                                On 07/02/2012 at 08:01, xxxxxxxx wrote:

                                Thanks for that Yannick.
                                But I should have mentioned that I needed to be able to select all edges using a list. I'll see if I can use this in my project using lists.

                                This is all based on a bigger project I'm working on. Where I'm trying to select just one side of the outer edges of "shells" (also known as "islands" ) inside of a polygon. And convert them to splines.
                                Maya has tools and functions for working with polygon and UV shells and I'm trying to build my own in C4D.
                                Currently the only way I can do this is to use the ExplodeSegments command. Then select the desired edges on each generated polygon object.
                                This works ok. (I posted the script on CGTalk) But the problem is I have to generate thousands of objects this way(Ouch!). Just to generate those splines. And that's both very slow and very resource hungry. And frankly a bit of a hack.

                                So now I'm trying to use lists to try and cut these shells inside the polygon into groups so I can work with them as if they were individual objects. Sort of like using lists in place of a selection tags.
                                I need to be able to select all edges...But not just simply all edges. All edges per each shell... And not just all edges..But only the edges on one side of all these shells.
                                It's a rather complex problem.

                                I posted about it in another thread in the C++ forum.
                                The source code in the ExplodeSegments command might help me learn how to split up a polygon into groups. I don't even know if my approach is a good one.

                                This is what I've come up with so far.
                                It's almost there(it currently only selects the first shell's edges). But then I ran into selection problems:

                                import c4d  
                                from c4d import utils  
                                  
                                def main() :  
                                  
                                ################## Put polygon shells into an array #####################################  
                                  c4d.CallCommand(12187)  #Polygons Mode  
                                  c4d.CallCommand(13324)  #Deselect All polygons--Start from no polygons selected  
                                  lastsel = 0  
                                  
                                  obj = doc.GetActiveObject()     
                                  polycount = obj.GetPolygonCount()  
                                  selected = obj.GetPolygonS()       #The selected polygons  
                                  selected.Select(0)                 #Select the first polygon  
                                  c4d.CallCommand(12557)             #Select Connected polygons  
                                  selectedcount = selected.GetCount()#How many polygons per shell  
                                  polygons = c4d.BaseSelect()  
                                  polysPerShell = 0                  #The number of polygons per shell  
                                  
                                  polygonlist = []    #The list of shell arrays(contains the individual lists for each shell)   
                                  
                                  for i in xrange(polycount/selectedcount) :  
                                      #print "shells:" ,i  
                                      newpolygonlist = []              #This list will be used to hold the selected polygons  
                                      for i in xrange(polycount) :      #Loop amount = total number of polygons  
                                          if selected.IsSelected(i) :   #Look for selected polygons  
                                               polysPerShell = polysPerShell +1  #The number of polygons per shell                 
                                               newpolygonlist.append(i)#Fill the list with the selected polygons  
                                               lastsel = i             #This is the last selected polygon's Id#  
                                        
                                      polygonlist.append(newpolygonlist)  
                                      c4d.StatusSetSpin()              #Show the spinning staus bar  
                                      c4d.CallCommand(13324)           #Deselect All polygons  
                                      selected.Select(lastsel+1)       #Select the first polygon in the next shell   
                                      c4d.CallCommand(12557)           #Select Connected polygons  
                                ################### Done with loop #################################################  
                                     
                                  pnts = obj.GetAllPoints()  
                                  edges = c4d.BaseSelect()  
                                  pntcount = obj.GetPointCount()  
                                  nibr = utils.Neighbor()          #Assigns neighbor to a variable  
                                  nibr.Init(obj)                   #Instantiates the neighbor class  
                                  edgecount = nibr.GetEdgeCount()  #Get all the edges in the entire polygon object  
                                  #print "total edges:", + edgecount     
                                  #print polysPerShell               
                                   
                                  shellpolylist = []  
                                  
                                  for i in xrange(len(polygonlist)) : #This gives the number of shells  
                                      shells = i                         
                                      #print shells  
                                      for shells in polygonlist:     #For each shell of polygons in the "polygonlist" array  
                                          #print shells  
                                           for j in xrange(0,polysPerShell) : #For each shell element  
                                               #print j                  
                                               selected.Select(j)            #Select each element(polygon)                   
                                               shellpolylist.append(j)       #Add each polygon to the list  
                                  
                                      edges.Select(shellpolylist[1])  
                                      edges.Select(shellpolylist[5])  
                                      edges.Select(shellpolylist[9])  
                                  #print shellpolylist  
                                  edges.CopyTo(obj.GetEdgeS())  
                                  
                                  #Convert selected objects to splines  
                                  utils.SendModelingCommand(c4d.MCOMMAND_EDGE_TO_SPLINE, list = [obj], mode = c4d.MODIFY_ALL, bc = c4d.BaseContainer(), doc = doc)  
                                  
                                  c4d.CallCommand(16351)            #Edges    
                                  c4d.StatusClear()                 #Remove the spinning bar..We're done  
                                  #print edgelist  
                                  c4d.EventAdd()      
                                  
                                if __name__=='__main__':  
                                  main()
                                

                                I'm not sure if I'm on the right track or not.
                                I'm in a little bit over my head. And just looking for advice on doing this.
                                Not really a support issue. Just wanted to let you see what I was trying to do in the bigger picture.

                                -ScottA

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