Presuming that the original vertices (below the group) don't have any x-forms on them, this is quite simple. You need to visit each vertex (mgWalk) and translate it (move its coordinate) by the negative of the center point. Here is a function that will translate all the vertices below a given node by some delta:
def TranslateVtx (db, parent, rec, delta):
if (mgGetCode(rec) == fltVertex):
# get current vertex coordinates
b,x,y,z = mgGetVtxCoord (rec)
# translate the current position by delta
x = x + delta.x
y = y + delta.y
z = z + delta.z
# update the vertex coordinates
mgSetVtxCoord (rec, x, y, z)
return MG_TRUE
def TranslateVerts (rec, coord):mgWalk (rec, TranslateVtx, None, delta, MWALK_VERTEX)
To add this to your script, add these two lines after mgEditorAddUndoForCreate
delta = mgCoord3dNegate (coord)
TranslateVerts (rec, delta)
Sorry I left out the Undo stuff, I'll let you sort that out.
Here's an update for the TranslateVtx function that handles mesh nodes. The version from the previous post only worked on polygons:
def TranslateVtx (db, parent, rec, delta):
code = mgGetCode(rec)
if (code == fltVertex):
# get current poly vertex coordinates
b,x,y,z = mgGetVtxCoord (rec)
# translate the current position by delta
x = x + delta.x
y = y + delta.y
z = z + delta.z
# update the poly vertex coordinates
mgSetVtxCoord (rec, x, y, z)
elif (code == fltMesh):
# loop thru each vertex in mesh
numAttr,code,numMeshVtx = mgGetAttList (rec, fltMeshNumVtx)
for i in range(0,numMeshVtx):
# get current poly vertex coordinates
b,x,y,z = mgMeshGetVtxCoord (rec, i)
# translate the current position by delta
x = x + delta.x
y = y + delta.y
z = z + delta.z
# update the mesh vertex coordinates
mgMeshSetVtxCoord (rec, i, x, y, z)
return MG_TRUE
The TranslateVtx def is a bit wonky - I think it should be
def TranslateVtx (rec, delta):
never mind - missed that you had translateverts and translatevtx
It sounds like you figured it out... but to be clear:
TranslateVtx is the mgWalk callback.
TrasnlateVerts is the "root" function you call to process all the verts below the node you specify.
My phase 1 script (for future searches). It detects groups and ignores other nodes (objects etc)
And I didn't tackle the undo part yet. It's all I can do to write scripts like this at the moment without the complexity of the undo functions :-D
#!/usr/local/bin/python
# Set up hex masks for status boxMMBX_OK = 0x00000001
MMBX_OKCANCEL = 0x00000002
MMBX_YESNO = 0x00000004
MMBX_YESNOCANCEL = 0x00000008
MMBX_STATUS = 0x00000100
MMBX_WARNING = 0x00000200
MMBX_ERROR = 0x00000400
MMBX_QUESTION = 0x00000800
def TranslateVtx (db, parent, rec, delta):code = mgGetCode(rec)
if (code == fltVertex):
# get current poly vertex coordinates
b,x,y,z = mgGetVtxCoord (rec)
# translate the current position by delta
x = x + delta.x
y = y + delta.y
z = z + delta.z
# update the poly vertex coordinates
mgSetVtxCoord (rec, x, y, z)
elif (code == fltMesh):
# loop thru each vertex in mesh
numAttr,code,numMeshVtx = mgGetAttList (rec, fltMeshNumVtx)
for i in range(0,numMeshVtx):
# get current poly vertex coordinates
b,x,y,z = mgMeshGetVtxCoord (rec, i)
# translate the current position by delta
x = x + delta.x
y = y + delta.y
z = z + delta.z
# update the mesh vertex coordinates
mgMeshSetVtxCoord (rec, i, x, y, z)
return MG_TRUE
def TranslateVerts (rec, delta):mgWalk (rec, TranslateVtx, None, delta, MWALK_VERTEX)
def CreateTransformedGeometry():toolName = "Create Transformed Geometry"
editorContext = mgNewEditorContext (toolName)
db = mgEditorGetDbRec (editorContext)
selectList = mgGetSelectList (db)
num = mgGetRecListCount (selectList)
if (num == 0):
mgSendMessage (MMSG_ERROR, "Nothing Selected")
else:
totalaltered=0
totalignored=0
for i in range (0, num):
rec,m = mgGetNextRecInList (selectList)
code = mgGetCode(rec)
if (code == fltGroup):
#Only do this if the selected entity is a group node
ok,box = mgGetBounds (rec)
coord = mgBoxGetCenter (box)
vtx = mgNewConstructVertex (editorContext, coord)
#mgEditorAddUndoForCreate (editorContext, toolName, vtx)
delta = mgCoord3dNegate (coord)
TranslateVerts (rec, delta)
rot = mgNewRec (fltXmRotate)
ok = mgSetCoord3d (rot, fltXmRotateCenter, 0.0, 0.0, 0.0)
ok = mgSetVector (rot, fltXmRotateAxis, 0.0, 0.0, 1.0)
ok = mgSetAttList (rot, fltXmRotateAngle, 0.0)
ok = mgAttach (rec, rot)
trans = mgNewRec (fltXmTranslate)
ok = mgSetCoord3d (trans, fltXmTranslateFrom, 0.0, 0.0, 0.0)
ok = mgSetCoord3d (trans, fltXmTranslateDelta, coord.x, coord.y, coord.z)
ok = mgAttach (rec, trans)
else:
totalignored+=1
message = "Changed %d group nodes.\nIgnored %d other nodes" % (totalaltered,totalignored)
mgMessageDialog(None, "Create Transformed Geometry", "%s"% message, MMBX_OK+MMBX_STATUS)
CreateTransformedGeometry ()
Craig
I'm trying to write a script that will take objects (groups actually), figure out their centrepoint, move the group from there to the origin and then insert a transformation matrix to [T] them back to where they were originally.
So far I've been able to put construction verts at the calculated centres, and I've been able to insert tranformation matrices. But I'm stumped as to how to do the bit in between - moving the existing geometry to the origin before applying the [T] to it to put it back.
Right now, I'm applying the [T] without first moving the geometry back so in effect, everything moves away from the origin by the same amount as it's original centrepoint.
Here's where I am so far. Suspicious blank line is where I need to try to move the item back to the origin before applying the transform. Any ideas? Thanks!