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

    Get the normal of a polygon selection

    Scheduled Pinned Locked Moved PYTHON Development
    7 Posts 0 Posters 1.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

      On 26/02/2018 at 03:24, xxxxxxxx wrote:

      How do I get the normal of a polygon selection (more than one polygon selected)?

      - Pim

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

        On 27/02/2018 at 07:12, xxxxxxxx wrote:

        Hi Pim, thanks for writing us.

        With reference to your question I've a doubt: given that more than one polygon is part of the selection set, are you interested to retrieve all the polygon normals belonging to that set or the average value of them?

        In any case getting the normal is pretty trivial once you've accessed points and polygon's indexes of your selection set. The code below briefly shows an attempt without taking in consideration NormalTag. In this latter case the extension would be pretty straightforward.

          
        import c4d  
          
        def EvaluateNormal(poly, points) :  
          res = c4d.Vector  
          if poly.IsTriangle() : # a,b,c  
              # retrieve position of points tagged as a, b, c   
              pointA = points[poly.a]  
              pointB = points[poly.b]  
              pointC = points[poly.c]  
                
              # compute the vectors between B-A and C-A   
              u = pointB - pointA  
              v = pointC - pointA  
                
              # calculate the normal as cross product between A-B and C-B vectors  
              res = u.Cross(v)  
                
              # return as a list  
              return (res.GetNormalized())  
          else: # a,b,c,d  
              # retrieve position of points tagged as a, b, c and d  
              pointA = points[poly.a]  
              pointB = points[poly.b]  
              pointC = points[poly.c]  
              pointD = points[poly.d]  
                
              # compute the vectors between B-A and D-A   
              u = pointB - pointA  
              v = pointD - pointA  
                
              # calculate the normal as cross product between A-B and C-B vectors  
              res1 = u.Cross(v)  
                
              # compute the vectors between A-D and C-D   
              u = pointC - pointA  
              v = pointD - pointA  
                
              # calculate the normal as cross product between A-D and C-D vectors  
              res2 = u.Cross(v)     
              return (res1.GetNormalized(), res2.GetNormalized())  
          
          
        def main() :  
          if op is None or not op.IsInstanceOf(c4d.Opolygon) :  
              print "Select a PolygonObject."  
              return  
          # get the tags  
          tags = op.GetTags()  
          if tags is None:  
              return  
            
          # get the polygons' indexes list  
          polys = op.GetAllPolygons()  
          if polys is None:  
              return  
          print polys  
            
          # get the points' positions list  
          points = op.GetAllPoints()  
          if points is None:  
              return  
          print points  
          
          for i in tags:  
              # iterate over the tags to look for selection tags  
              if i is None:  
                  return  
                
              if i.IsInstanceOf(c4d.Tpolygonselection) :  
                  # get the BaseSelect out of the current selection tag  
                  bs = i.GetBaseSelect()  
                  if bs is None:  
                      retutn  
                  # get the selection status of the polygons  
                  sel = bs.GetAll(op.GetPointCount())  
                  if sel is None:  
                      return  
                  # iterate over the data found in BaseSelect and retrieve face normal data              
                  for index, selected in enumerate(sel) :  
                    if not selected: continue  
                    print "Polygon[", index, "] is selected in", i.GetName(), " and related normals are ",EvaluateNormal(polys[index], points)   
          
        if __name__=='__main__':  
          main()  
        

        Best, Riccardo

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

          On 27/02/2018 at 07:48, xxxxxxxx wrote:

          Hi Ricardo,

          Thanks for the reply.
          I can calculate the normal for one polygon, what what to do for a selection with multiple polygons?

          If I select some polygons of an object, cinema 4d shows me one (1) normal.
          Is that the average of all normals?

          And how to calculate the average of these normals.
          Just add them and divide them by the number of vectors?

          -Pim

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

            On 28/02/2018 at 01:57, xxxxxxxx wrote:

            Hi Pim, I'd say frankly I'm a bit confused by your second answer. Could you please specify what you're actually trying to achieve and the intent of the request? This will help me better address the support effort.

            With regard to average vector, just summing up at component level and dividing by the number of vectors should work properly 😉

            Looking forward hearing from you, give best.

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

              On 01/03/2018 at 01:49, xxxxxxxx wrote:

              Hi Ricardo,

              I want to place an object in the polygon selection of another object.
              Placing should be done according the normal of the polygon selection and the object should be scaled according to the size of the polygon selection.

              But I guess the average normal of all normals of the polygons in the polygon selection will do.

              -Pim

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

                On 01/03/2018 at 09:30, xxxxxxxx wrote:

                For my PolyGnome plugin (inspired by William Vaughan's Polystein kit for MODO) I used to position an object on a polygon selection by calculating the average normal of all selected polygons, using CalcFaceNormal, additioning them all up and dividing by the number of selected polygons.
                Then used a ray collider to detect the position on the surface.

                For the scaling I calculated the bounds of the selected polygons and projected the object from the position onto these bounds. The distance of the projection provided the scaling values, from which I used the smallest value to let the object fit inside the polygon selection.
                Obviously, it will not always provide for a perfect fit, but with the smallest value you at least end up with a scale where the object doesn't intersect with non-selected polygons.

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

                  On 26/03/2018 at 04:50, xxxxxxxx wrote:

                  Hi C4DS,

                  That is exactly the plugin, we had in mind.
                  But it is there already, so I will stop developing.

                  -Pim

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