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
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.
from c4d import gui
# Welcome to the world of Python
# Main function
#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")
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 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()