Retrieve the World Rotation of a Selected Edge?
-
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=0I 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=0Is 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.
Best,
Robert -
Thanks @mp5gosu for the illustration. Works as expected.
-
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