SOLVED Retrieve the World Rotation of a Selected Edge?


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:

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:

Is there a way to retrieve it using Python?

Thank you for looking at the problem

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.


Thanks @mp5gosu for the illustration. Works as expected.


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()

    #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): 
            #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.
    #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__':