[Closed] Pivot z min universal
I need a script that
- will make my object/group(even if it was rescaled/rotated) world oriented
- put the pivot on z.min (for the lowest object in the group) to the group/object
- the object should not change at all- no rotate, no rescaled – only the pivot should move.
- when you choose local – then before applying the script, the orientation may be different, but after applying the script, the orientation should be strictly world oriented!
- very iportant not to add additional modifiers!
- No use of collaps stack.
fn alignPivotToWorld node pos: = if isvalidnode node do
(
tm = node.transform
node.transform = matrix3 1
node.objectoffsetscale = tm.scale
node.objectoffsetrot = tm.rotation
node.objectoffsetpos = tm.pos
node.pivot = if pos == unsupplied then tm.pos else pos
node.children.transform *= tm
tm
)
/*
alignPivotToWorld <group> pos:[.pos.x, .pos.y, .min.z]
*/
Try to create a sphere, scale it and rotate it 45 degrees!
Sphere radius:100 smooth:on segs:32 chop:0 slice:off sliceFrom:0 sliceTo:0 mapcoords:on recenter:off pos:[0,0,0] isSelected:on
scale $ [1.5,1.5,1.5]
rotate $ (angleaxis 45 [1,0,0])
then apply this code. You will see that
- it doesn’t give the min.z of the sphere, but the min.z of bbox corner.
- If you apply this code again, the the sphere changes it’s size.
It means, the code is still not universal
Now create the same sphere again, rescale and rotate it, and create a box, in addition. Group them and apply the script to the group.
- Does not always work for groups
i show the idea. using this idea you can make the solution universal. why the second call of this function doesn’t work right? because after the first call we have ‘offset’ for the object transform. so calling this function next time we have to take new offset into account.
you can calculate mesh bbox… there are several samples on this forum. but you asked about ‘universal’ solution. and not every node has a mesh.
1 But why it doesn’t give the minz of the shpere?
Even after applying the script
selection[1].pivot.z = selection[1].min.z
doesn’t give the min.
- how to take the offset into account? What if the object was offset at one computer yesterday, and I apply the script again today at another computer?
Denis, I know that you can help me. I’m not too smart to solve this issue.
How heavy are your objects, so finding the vert with lower Z pos is too slow for you?
For example on object with 240 000 verts the code below finds the vert with lower Z pos for ~0.3 sec on my PC.
(
function FindLowerZpos obj = if isValidNode obj do
(
t0 = timestamp()
local tempMesh = snapShotAsMesh obj
local minZpos = [0,0,1e9]
-- local minZposVert = undefined
local vertCnt = tempMesh.numverts
for v = 1 to vertCnt do
(
vertPos = getVert tempMesh v
if vertPos.z < minZpos.z do
(
minZpos = vertPos
)
)
delete tempMesh
t1 = timestamp()
format "Time: % sec
" ((t1 - t0)/1000.0)
point pos:minZpos
)
FindLowerZposselection[1]
)
I thought like this. What if we:
-
(copy transform, position, scale, rotation, pivot) - I still don't know if needed.
-
if iskindof node Editable_Mesh or iskindof node Editable_Poly do
-
add Edit Poly modifier (to protect the mesh from destroying after ResetXform)
-
ResetXForm node
-
worldAlignPivot node
-
copy position, orientation, rotation, pivot
-
if iskindof node Editable_Mesh or iskindof node Editable_Poly do
-
remove Edit Poly modifier
-
remove ResetXForm keeping the objects previous position, transform, rotation and scale
-
keep the object's new orientation and new pivot (from point 6)
the code that Neuro69 gave is working great!
tmp=$selection[1].modifiers[1].gizmo.transform
tmp2=$selection[1].position
deletemodifier $selection[1] 1
$selection[1].transform=tmp
$selection[1].position=tmp2
I tried by myself to implement this algorithm but I can’t get it right. Please help me to do it. The most difficult for me now are the last two points.
I think I found a solution! Tell me please, is it possible to find out if an object is world oriented or not?
If yes, then how?
Thank youuu!