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

    Retrieve the World Rotation of a Selected Edge?

    Cinema 4D SDK
    r20 python
    3
    4
    943
    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.
    • B
      bentraje
      last edited by

      Hi,

      I'm trying to align a window on a wall. But the wall is angled and I'm having a problem determining the proper orientation.
      You can see an illustration of problem here:
      https://www.dropbox.com/s/j6rqbvokopn3b6h/c4d084_align_angled_rotation_properly.mp4?dl=0

      I was thinking of getting the world rotation of the selected edge, but the coordinate manager does not seem to show anything. You can see the attempt here:
      https://www.dropbox.com/s/z03x7faykja0u9c/c4d084_align_angled_rotation_properly.jpg?dl=0

      Is there a way to retrieve it using Python?

      Thank you for looking at the problem

      1 Reply Last reply Reply Quote 0
      • M
        mp5gosu
        last edited by mp5gosu

        Hi @bentraje,

        do you need that functionality to work in GUI mode? If so, here's an example video showing that Cinema 4D already provides that funtionality - a bit hidden though:

        In P/S/R tool with a selected object, Ctrl+RightClick an axis (or rotation band). Release both to hover over a reference point, edge, axis, etc.
        Left-Click and drag to a target point.

        Another workaround I also use often, are guides. Set a guide to semi-line, so you have start - and end-handles. Snap the guide to the edge or angled wall.
        Now you can either use Guide-Snapping or simply copy/paste the rotation.

        The third solution would be to use dynamic guides.

        Best,
        Robert

        1 Reply Last reply Reply Quote 2
        • B
          bentraje
          last edited by

          Thanks @mp5gosu for the illustration. Works as expected.

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

            hello,

            To answer this question if someone want to do it by code.

            import c4d
            from c4d import gui
            
            # Welcome to the world of Python
            
            
            # Main function
            def main():
                #get the selected object
                op = doc.GetActiveObject()
                if not op:
                    raise TypeError("there's no object selected")
                if not op.IsInstanceOf(c4d.Opolygon):
                    raise TypeError("obj should be a polygon object")
            
                #setup neighbor
                nbr = c4d.utils.Neighbor()
                nbr.Init(op)
            
                #get the selected edge
                bs = op.GetSelectedEdges(nbr,c4d.EDGESELECTIONTYPE_SELECTION)
                
            
                #maximum number of edge should be number of polygon * 4
                sel = bs.GetAll(op.GetPolygonCount() * 4)
                
                #get all polygon
                vadr = op.GetAllPolygons()
                #init point a and b index to -1 for error check
                a = b = -1
                #initialise a counter to check in sel array.
                countEdge = 0
                
                #we can check now every edge to find the corresponding points. So for each polygon
                for i in xrange(op.GetPolygonCount()):
                    #get the polygon information
                    pli = nbr.GetPolyInfo(i)
            
                    for side in xrange(4): # Test all 4 sides of a polygon
                        # Only proceed if edge is marked
                        # and edge really exists (for triangles side 2 from c..d does not exist as c==d)
            
                        if pli["mark"][side] or (side==2 and vadr[i].c == vadr[i].d): 
                            continue 
                        
                        #if the edge is marked as selected in our sel array
                        if sel[countEdge]:
                            if side==0:
                                a=vadr[i].a; b=vadr[i].b
                            elif side==1:
                                a=vadr[i].b; b=vadr[i].c
                            elif side==2:
                                a=vadr[i].c; b=vadr[i].d
                            elif side==3:
                                a=vadr[i].d; b=vadr[i].a
                        countEdge +=1
            
                if a == -1 or b == -1:
                    raise ValueError("points index can't be negatives")
                
                #get all points array 
                points = op.GetAllPoints()
            
                
                #Get the direction of the edge in global coordinate (multiply the points'vector by the matrix of the object)
                opmg = op.GetMg()
                #i've picked a direction from point a to point b so the angle could need to be reverted.
                dirVector = points[b]*opmg - points[a]*opmg
                #normalize a vector is often a good idea.
                dirVector.Normalize()
                
                #transform the vector to hpb note the result is in radian
                hpb = c4d.utils.VectorToHPB(dirVector)
                
                #transform radian to degree
                hpb.x = c4d.utils.RadToDeg(hpb.x)    
                hpb.y = c4d.utils.RadToDeg(hpb.y)
                hpb.z = c4d.utils.RadToDeg(hpb.z)
            
                print "the edge is poiting to",dirVector,"the corresponding angle is", hpb
            
            
            # Execute main()
            if __name__=='__main__':
                main()
            

            Cheers
            Manuel

            MAXON SDK Specialist

            MAXON Registered Developer

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