How to rotate just the axis?

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 21/03/2011 at 04:09, xxxxxxxx wrote:

Hi,

How can I rotate a polygon?
I think I know how to get the selected polygon(s) from BaseSelect, but how then do I rotate it?

I want to try and recreate the move/rotate object axis functionality, e.g. moving the pivot/object axis independently of the model and I think for this I need to modify the polygon(s) directly and not the local or global matrix.... or is this not the case?

Thanks for reading!

Andre

Edit: And of course the post title should be "How to rotate a polygon?" - apologies for the misspelling.
Edit2: Changed title to "How to rotate just the axis?" because it reflects better on what I was trying to do.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 21/03/2011 at 06:39, xxxxxxxx wrote:

Sorry, what exactly do you want to do ?
To rotate its points positions, or the indieces ?

Here's some code for rotating indieces:

``````import c4d
from c4d import gui
#Welcome to the world of Python
import c4d

def rotate_polygon(poly,rotation) :
if not isinstance(poly,c4d.CPolygon) :
raise TypeError, "CPolygon expected"
if not isinstance(rotation,(int or float)) :
raise TypeError, "int expected"
poly = PolyToList(poly)
ln = len(poly)
rotation = (rotation % ln)
print "rotation = " + str(rotation)
print poly
poly = [poly[((i+rotation) % ln)] for i in range(ln)]
print poly
return ListToPoly(poly)

def PolyToList(p) :
if not isinstance(p,c4d.CPolygon) :
raise TypeError, "CPolygon expected"
if p.c == p.d: return [p.a,p.b,p.c]
return [p.a,p.b,p.c,p.d]

def ListToPoly(l) :
if not isinstance(l,list) : raise TypeError, "list or dict expected"
ln = len(l)
if   ln < 3:
raise IndexError, "lst must have at least 3 indieces"
elif ln == 3:
return c4d.CPolygon(l[0],l[1],l[2])
else:
return c4d.CPolygon(l[0],l[1],l[2],l[3])

def main() :
poly = op.GetAllPolygons()[1]
print poly
poly = rotate_polygon(poly,1)
op.SetPolygon(1,poly)
op.Message(c4d.MSG_UPDATE)

if __name__=='__main__':
main()
``````

CPolygon(1,2,3,4) will be rotated like this, with rotation of 1: CPolygon(2,3,4,1)

Cheers, nux

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 21/03/2011 at 07:28, xxxxxxxx wrote:

I guess it's the point positions, I don't really know.

As I said I am trying to do the same as "Objekt-Ache bearbeiten" / transform object axis tool.

Because SetMg and SetMl didn't seem to do what I want (they rotate the full object and not just the object axis) I figured maybe I need to rotate the points/polygons itself.

But it feels like I am missing something I just don't know what.

Edit: maybe I need to rotate the object using SetMg/SetMl but then rotate/transform back all the point/polygons in the opposite by the same amount so that they points/polygons resume their original position/orientation, thus giving the impression that just the object axis was tranformed.

But then how do I transform points/polygons? I guess I am missing something like SetMg/SetMl for polygons...

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 24/03/2011 at 08:14, xxxxxxxx wrote:

Yay, it seems I am getting somewhere. =)

Here's my implementation so far for a clone of the coordinate manager HPB entry field functionality while having the "Use Object Axis Tool" mode active instead of the "Use Model Tool" mode.

Click here to view the snippet as syntax highlighted pastie.

``````

def SetAxisRotation(obj, rot, local=False, iterations=10, depth=0) :
"""
Set the rotation of the object axis (i.e. keeping points in place).

obj   object
rot   vector
"""
# unfortunately tail recursion and depth guard
# seem needed because of the MatrixToHPB(HPBToMatrix(Rad(angle))
# roundtrip round-off error, so we need to improve
# our solution with each recursion level
depth += 1
if obj is None: return False
if not isinstance(rot, c4d.Vector) :
raise TypeError("expected c4d.Vector, got %s" % type(rot))
if local is False:
getfn = obj.GetMg
setfn = obj.SetMg
else:
getfn = obj.GetMl
setfn = obj.SetMl
mo = getfn()
# calc difference to current orientation
# (we want absolute value opposed to relative increment)
currot = MatrixToHPB(mo)
diff = rot-currot
if VectorEqual(rot, currot) or depth >= iterations:
return False
else:
if DEBUG:
print "%d: rot = %s, currot = %s, diff = %s" % (depth, rot, currot, diff)
mat = HPBToMatrix(diff)
# orient whole object (axis + points)
setfn(mo * mat)
# get inverse rotation matrix for the points
pntsrm = mat.__invert__()
allpnts = obj.GetAllPoints()
newpnts = []
for pnt in allpnts:
# write back points to previous positions
# by applying the inverse matrix
newpnts.append(pntsrm * pnt)
obj.SetAllPoints(newpnts)
obj.Message(c4d.MSG_UPDATE)
if DEBUG:
currot = MatrixToHPB(getfn())
diff = rot-currot
print "%d: rot = %s, currot = %s, diff = %s" % (depth, rot, currot, diff)
return SetAxisRotation(obj, rot, local, iterations, depth)
``````

However, I am wondering, if the recursion solution isn't a bit excessive, although it is more than fast enough for my purposes...