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

    Axis Center Tool - python

    Scheduled Pinned Locked Moved PYTHON Development
    3 Posts 0 Posters 543 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 13/11/2017 at 18:14, xxxxxxxx wrote:

      Hello,

      I was just wondering if someone can explain, how the axis center tool (ACT) functions, its such a useful tool and I would really like to use it in an automated manner on multiple objects. Is it originally a python script?

      e.g. I am especially interested in centering and aligning the object axis to a selected edge.

      Thanks!

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

        On 14/11/2017 at 08:30, xxxxxxxx wrote:

        Hi NNenov, thanks for writing us.

        Actually the Axis Center Tool, does nothing fancy but simply compensate the space position and orientation of the points used in the mesh by a certain amount which is then back-compensated using a transformation matrix which places the mesh in the position it was supposed to be.

        I've prepared below a basic script which make this "wizardry" for selected points or selected edges. Basically from the selection I retrieve the new axis position (I basically compute the centroid starting from all the selected entities), then change the points position by this amount and, in the end, move the object back to the right position to compensate the displace I've forced on the vertexes.

          
        import c4d  
          
        def GetSelectedEdgesList(op) :  
          # check passed parameter  
          if op is None:  
              return None  
            
          # retrieve the polygons  
          polys = op.GetAllPolygons()  
          if polys is None:  
              return None  
            
          # evaluate the total number of polygons  
          polysCnt = len(polys)  
                
          # get the BaseSelect object responsible for  
          # storing the information on selected edges  
          edgeS = op.GetEdgeS()  
          if edgeS is None:  
              return None  
          
          # check the at least one edge is selected  
          if edgeS.GetCount() == 0:  
              return None  
            
          # return the list representing the selection status of an edge  
          return edgeS.GetAll(4 * polysCnt)  
          
        def GetSelectedPointsList(op) :  
          # check passed parameter  
          if op is None:  
              return None  
            
          # retrieve the points   
          points = op.GetAllPoints()  
          if points is None:  
              return None  
          
          # evaluate the total number of points  
          pointsCnt = len(points)  
                
          # get the BaseSelect object responsible for  
          # storing the information on selected points  
          pointS = op.GetPointS()  
          if pointS is None:  
              return None  
            
          # check that at least one point is selected  
          if pointS.GetCount() == 0:  
              return None  
            
          # return the list representing the selection status of a point  
          return pointS.GetAll(pointsCnt)  
          
        def CalcBaryFromSelectedEdges(selEdges, polys, points) :  
            
          # check the passed parameters  
          if selEdges is None or polys is None or points is None:  
              return None  
            
          # initialize samples count to compute the final avarage value and the centroid  
          i = 0  
          bary = c4d.Vector(0)  
            
          for index, poly in enumerate(polys) :  
              for j in range(0,4) :  
                  # check the selected status of the edge  
                  if selEdges[index*4+j] == 0: continue  
                  # and in case sum the points representing the edge extremes   
                  # to the variable used to store the centroid value  
                  bary += points[poly.EdgePoints(j)[0]]  
                  bary += points[poly.EdgePoints(j)[1]]  
                  # increase the sample counter  
                  i += 2       
                    
          # compute the avarage values assuming that each sample has the same weight  
          bary = bary / i  
            
          return bary  
          
        def CalcBaryFromSelectedPoints(selPoints, points) :  
          # check the passed parameters  
          if selPoints is None or points is None:  
              return c4d.Vector(0)  
            
          # initialize samples count to compute the final avarage value and the centroid  
          i = 0  
          bary = c4d.Vector(0)  
                
          # loop through all the points  
          for index, selected in enumerate(selPoints) :  
              # check the selected status of the point  
              if not selected: continue  
              # and in case sum it to the variable used to store the centroid value  
              bary += points[index]  
              # increase the sample counter  
              i += 1  
            
          # compute the avarage values assuming that each sample has the same weight      
          bary = bary / i  
            
          return bary  
          
        def main() :  
          if op is None:  
              return  
            
          # retrieve points, polys and the current transformation matrix  
          points = op.GetAllPoints()      
          polys = op.GetAllPolygons()  
          currentMg = op.GetMg()  
          
          # retrieve the list representing the points selection status   
          selPoints = GetSelectedPointsList(op)  
            
          # retrieve the list representing the edges selection status  
          selEdges = GetSelectedEdgesList(op)  
            
          #init the centroid  
          bary = c4d.Vector(0)  
            
          # if points are selected use them to compute the new axis-position  
          if selPoints is not None:  
              bary = CalcBaryFromSelectedPoints(selPoints, points)  
          elif selEdges is not None:  
              bary = CalcBaryFromSelectedEdges(selEdges, polys, points)      
            
          # move the points by the amount represented by the new axis center  
          for index, point in enumerate(points) :  
              point -= bary  
              op.SetPoint(index, point)  
            
          # notify about the points repositioning  
          op.Message(c4d.MSG_UPDATE)  
                
          # adjust the matrix offset component accordingly  
          currentMg.off += bary  
            
          # reposition the object in the space  
          op.SetMg(currentMg)  
            
          c4d.EventAdd()  
            
            
        if __name__=='__main__':  
          main()  
        

        The code is far from being perfect (for example it doesn't consider re-orienting the axis) but extending the code to make it happen shouldn't be that complex.

        Best, Riccardo

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

          On 14/11/2017 at 20:50, xxxxxxxx wrote:

          Thanks so much Ric,
          This is such a useful bit of code, I actually did something similar a few months ago but forgot it all, I remember you have to transform and then reverse transform as you said.
          What I knew in advance would really stump me is aligning the axis, e.g. getting the orientation( Alignment?) of a selected edge along a specific axis. But as you said I can probably figure it out if I look into it more thoroughly, I'm crap at maths!

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