PDA

View Full Version : FFD Transform Script


thatoneguy
03-02-2009, 10:52 PM
Manipulate objects like an FFD cage.


--- FFD Free Transform v0.7 ---
--- Inspired by the UVW editor transform box. But extended. And 3D.... and in no way similar. ---
--- Use: Select a bunch of objects. ---
--- Run Script. ---
--- Manipulate control box (Including at the sub object level) ---
--- Delesect Control Gizmo or delete control Gizmo ---
--- Gavin Greenwalt (Straightface Studios) ---
FFDUpdate = undefined
Global FFD
struct ffdStruct (
Objs, Deltas, ControlGizmo,
fn TransformOp OutPoints DeltaXYZ=
(
centerpoint =
(
(
(
(
(
(OutPoints[1])*(1-deltaXYZ.Y)+(OutPoints[3])*(deltaXYZ.Y)
)*(1-deltaXYZ.X)
) + (
(
(OutPoints[2])*(1-deltaXYZ.Y)+(OutPoints[4])*(deltaXYZ.Y)
)*(deltaXYZ.X)
)
)*(1-deltaXYZ.Z)
) + (
(
(
(
(OutPoints[5])*(1-deltaXYZ.Y)+(OutPoints[7])*(deltaXYZ.Y)
)*(1-deltaXYZ.X)) + (
(
(OutPoints[6])*(1-deltaXYZ.Y)+(OutPoints[8])*(deltaXYZ.Y)
)*(deltaXYZ.X)
)
)*(deltaXYZ.Z)
)
)
centerpoint
),

fn getDelta BoundsObj SubObj =
(
(SubObj.pos - BoundsObj.min)/(BoundsObj.max-BoundsObj.min)
),
fn create2xGizmo =
(
Dims = $.max-$.min
ControlGizmo = box width:Dims.x length:Dims.y height:Dims.Z
ControlGizmo.center = $.center
ControlGizmo.wirecolor = (color 255 90 0)
WireMat = standardmaterial()
Wiremat.diffuse = (color 255 90 0)
Wiremat.wire = true
Wiremat.selfillumination = 100.0
ControlGizmo.Material = WireMat
converttomesh ControlGizmo
ControlGizmo
),

fn handleGeometryChange ev nd =
(
obj = (GetAnimByHandle nd[1])
objMesh = snapShotAsMesh obj
OutPoints = (for j = 1 to 8 collect (getvert objmesh j))
for i=1 to FFD.Objs.count do (FFD.Objs[i].pos = (FFD.TransformOp OutPoints FFD.Deltas[i]))
delete objMesh
gc light:true
),

fn Update Objs Deltas Outpoints =
(
for i=1 to Objs.count do (Objs[i].pos = (FFD.TransformOp OutPoints Deltas[i]))
),

fn deleteGizmo =
(
delete FFD.ControlGizmo
)

)
if $ != undefined do
(
FFD = FFDStruct()
FFD.Objs = (for p in selection as array where (if (isgroupmember p) == true then ((for o in (selection as array) where o == p.parent collect o).count == 0) else true) collect p)
FFD.ControlGizmo = FFD.create2xGizmo()
FFD.Deltas = for o in FFD.Objs collect (FFD.getDelta FFD.ControlGizmo o)
select FFD.ControlGizmo
setcommandpaneltaskmode #modify
--setSelectionLevel ControlGizmo #vertex

rollout deleteGizmoDialog "DeleteGizmo"
(
timer ticktock interval:1
on ticktock tick do
(
try(delete FFD.ControlGizmo)catch()
destroydialog deleteGizmoDialog
)
)

FFDUpdate = nodeEventCallback geometryChanged:FFD.handleGeometryChange
when geometry FFD.ControlGizmo changes id:#FFDUpdate do (FFD.Update FFD.Objs FFD.Deltas (for j = 1 to 8 collect (getvert FFD.ControlGizmo j)))
when select FFD.ControlGizmo changes id:#FFDUpdate do (if $ != FFD.ControlGizmo do (clearselection(); FFDUpdate = undefined; createdialog DeleteGizmoDialog; deleteAllChangeHandlers id:#FFDUpdate; gc light:true))
)

thatoneguy
03-02-2009, 10:59 PM
Thanks Bobo and ZeBoxx.

So the only way I could get the change handler to not crash was to create a rollout to delete it. Any better ideas?

EDIT:
Updated it so that it ignores groupmembers and only manipulates group heads.

EDIT EDIT:

Further refined it so that it only manipulates group heads or sub-groups whose grouphead isn't also selected. (so you can work with groups inside of groups, or open the group and work individually with all of the group components.)

CGTalk Moderation
03-02-2009, 10:59 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.