Copying pivot rotation of an object to another object in script

Copying pivot rotation of an object to another object in script

kenc
Advocate Advocate
4,313 Views
18 Replies
Message 1 of 19

Copying pivot rotation of an object to another object in script

kenc
Advocate
Advocate

Hi All

What I need to do is copy the pivot rotation of an object to a second object's rotation without moving the second object. I've been reading the help and googling this, but I don't understand what needs to be done.

I'd really appreciate some help.

 

TIA

Ken

0 Likes
Accepted solutions (2)
4,314 Views
18 Replies
Replies (18)
Message 2 of 19

kenc
Advocate
Advocate

I was able to finally figure it out my self.

0 Likes
Message 3 of 19

denisT.MaxDoctor
Advisor
Advisor

@kenc wrote:

I was able to finally figure it out my self.


Good for you, but it would be nice to share the solution in case anyone else comes across a similar problem.

0 Likes
Message 4 of 19

kenc
Advocate
Advocate

I'm sorry. I realized I didn't share till you replied denisT.

 

All I need to do rotate the second object by the amount and direction of the first. Then position it to the same point as the first object. The objects are symmetrical.

0 Likes
Message 5 of 19

denisT.MaxDoctor
Advisor
Advisor

@kenc wrote:

I'm sorry. I realized I didn't share till you replied denisT.

 

All I need to do rotate the second object by the amount and direction of the first. Then position it to the same point as the first object. The objects are symmetrical.


BTW... this is an interesting and non-trivial task.

try to align the pivots only for two objects in this test scene:

with redraw off, undo off
(
	delete objects
	gc()
	
	--t = random 0 100
	--format ">> %\n" t
	seed 83
	
	size0 = random [4,4,4] [10,10,10]
	size1 = random [4,4,4] [10,10,10]

	rot0 = random -[180,180,180] [180,180,180]
	rot1 = random -[180,180,180] [180,180,180]

	pos0 = random -[10,10,10] [10,10,10]
	pos1 = random -[10,10,10] [10,10,10]

	fn aseuler rot = (eulerangles rot.x rot.y rot.z) 

	s = box name:#source length:size0.x widht:size0.y height:size0.z \
		pos:pos0 rotation:(aseuler rot0) wirecolor:green
	s.objectoffsetrot = aseuler (random rot0 rot1) 
	s.objectoffsetpos = random pos0 pos1
		
	t = box mane:#target length:size1.x widht:size1.y height:size1.z \
		pos:pos1 rotation:(aseuler rot1) wirecolor:orange
	t.objectoffsetrot = aseuler (random rot0 rot1) 
	t.objectoffsetpos = random pos0 pos1
)

 

Let's check how well the problem was solved

😉

 

0 Likes
Message 6 of 19

domo.spaji
Advisor
Advisor

How about: $source.parent = $target

or something similar based on that 🙂

0 Likes
Message 7 of 19

denisT.MaxDoctor
Advisor
Advisor

@domo.spaji wrote:

How about: $source.parent = $target

or something similar based on that 🙂


of course it will not work, only pivot must move!

0 Likes
Message 8 of 19

domo.spaji
Advisor
Advisor

But of course it was not meant to be direct solution to your task.

Rather it is (usual) way for adding new/additional transform (center)

0 Likes
Message 9 of 19

denisT.MaxDoctor
Advisor
Advisor

In MAX, you can align objects pivots using the Align Tool. The original question was how to do this using the max script. As stated above, the problem is solved, and I want to know how to do it for example for my test case. It's all.

0 Likes
Message 10 of 19

kenc
Advocate
Advocate

Sorry people but I am swamped with work right now and haven't had time to reply.

 

The way I did it is I have a chair with pivot rotated because the chair was rotated. I created a point helper and rotated it the same amount and direction as the chair. This of course moved the helper. I then used the chairs position for the helper position. This is a very easy scenario because I'm only using a helper point.

 

In the near future what I need to do (with script) is to clone the chair and have it's pivot rotation the same as the original chair.

 

Again sorry for the lack of replies.

0 Likes
Message 11 of 19

kenc
Advocate
Advocate

I now have some time to expand on this subject.

 

Here is my scenario and must be done by script.

 

1. I have a text file. In the text file is a line to merge a chair made of 4 parts. Next line is the rotation for the chair. Next line is position for the chair. Using script I merge the chair and insertion is at 0,0,0. I then group the 4 parts. I create a point helper and place it at 0,0,0, same as the chair insertion point. I set the group pivot position to the same as point helper pivot position.

 

2. I then rotate the group, example 180. I then position it, example 100,100,100. Then delete point helper and ungroup chair.

 

3. Next line in the text file is to clone the same chair, which I do. Then group it and create a point helper. This clone has the same rotation as the first, 180. But when I rotate it, the whole chair moves along with the point helper. I then apply the position, say 200,0,0. The clone is positioned correctly but rotated by 180.

 

What I need to happen is the chair not to rotate, it should have the rotational position as the first chair. Then place it at 200,0,0.

 

So this is my scenario and I hope I have explained correctly to understand what I am trying to achieve.

0 Likes
Message 12 of 19

denisT.MaxDoctor
Advisor
Advisor

the situation you describe has nothing to do with 'only pivot alignment', you simply need to align a group of nodes to another node or transform value.

so lets say we have a list of object and an orientation and position target. We need to align this list (all nodes) to the target keeping their original relative positions:

 

fn alignNodesToTarget nodes target method:#world = 
(
	origin_tm = case method of
	(
		#center: transmatrix nodes.center
		 #first: nodes[1].transform
		default: matrix3 1 -- WORLD
	)
	
	for node in nodes do (node.transform *= inverse origin_tm * target.transform)
)

delete objects
gc()

nodes = 
(
	b0 = cylinder radius:10 height:2 wirecolor:orange rotation:(eulerangles 0 0 90) isselected:on 
	b1 = cylinder radius:2 height:20 pos:[0,0,1] wirecolor:orange 
	b2 = box width:30 length:20 height:5 pos:[0,0,20] wirecolor:green
	b3 = box width:30 length:30 height:3 rotation:(eulerangles -70 0 0) pos:[0,15,40] wirecolor:green

	#(b0, b1, b2, b3)
)

target =  point name:#target cross:on box:on axistripod:on rotation:(eulerangles 0 0 45) pos:[50,20,20] wirecolor:red

/* run it!
alignNodesToTarget nodes target method:#world
*/

/* or run it!
alignNodesToTarget nodes target method:#first
*/

 

 

0 Likes
Message 13 of 19

denisT.MaxDoctor
Advisor
Advisor

BTW. Of course, for a better pipeline, all imported (merged) objects must be grouped into one, or more correctly, there must be an XREF object or container. In this case we will not have a problem with instancing, and updating.

 

 

0 Likes
Message 14 of 19

kenc
Advocate
Advocate

Hi denisT

 

Sorry for the time length between replies.

 

In the function, what exactly is going on in line

 

for node in nodes do (node.transform *= inverse origin_tm * target.transform)

 on 

0 Likes
Message 15 of 19

denisT.MaxDoctor
Advisor
Advisor

@kenc wrote:

In the function, what exactly is going on in line

 

for node in nodes do (node.transform *= inverse origin_tm * target.transform)

node.transform *= inverse origin_tm * target.transform

It's the same as:

node.transform = node.transform * inverse origin_tm * target.transform

 

now is the same step by step:


it's a transformation of a matrix3 from one coordinate to another where:

origin_tm - source coordinate system
target.transform - destination coordinate system

 

get node's transform in world (zero) coordinates:

tm = node.transform * inverse origin_tm

put transform in target's coordinates where node's transform is ZERO (relative is ZERO)

tm = tm * target.transform

 this means that node's transform is aligned to target's transform:

node.transform = tm

 

0 Likes
Message 16 of 19

kenc
Advocate
Advocate

OK now I understand what is going no and is what (I think) I'm looking for.

 

I won't be able to check this out till the weekend, I'm swapped right now. So I can mark this as 'solution' if OK with you?

0 Likes
Message 17 of 19

denisT.MaxDoctor
Advisor
Advisor

 

fn toMatrix3 tm = case of
(
(iskindof tm Matrix3): tm
 (iskindof tm Point3): transmatrix tm
	 (isvalidnode tm): tm.transform
	   (tm == #world): matrix3 1
			  default: matrix3 1 -- WORLD
)

fn alignNodesToTarget nodes target origin:#world = 
(
	target_tm = toMatrix3 target
	origin_tm = toMatrix3 origin
	
	for node in nodes do (node.transform *= inverse origin_tm * target_tm)
)


/*********************************** EXAMPLE SCENE SETUP *****************************************/

delete objects
gc()


nodes = 
(
	b0 = cylinder radius:10 height:2 wirecolor:orange rotation:(eulerangles 0 0 90) isselected:on 
	b1 = cylinder radius:2 height:20 pos:[0,0,1] wirecolor:orange 
	b2 = box width:30 length:20 height:5 pos:[0,0,20] wirecolor:green
	b3 = box width:30 length:30 height:3 rotation:(eulerangles -70 0 0) pos:[0,15,40] wirecolor:green

	#(b0, b1, b2, b3)
)

target1 =  point name:#target cross:on box:on axistripod:on rotation:(eulerangles 0 0 45) pos:[50,20,20] wirecolor:red
target2 =  point name:#target cross:on box:on axistripod:on rotation:(eulerangles 0 0 -45) pos:[-50,-20,40] wirecolor:orange
target3 =  point name:#target cross:on box:on axistripod:on rotation:(eulerangles 0 0 120) pos:[50,20,60] wirecolor:yellow


origin_first = nodes[1].transform -- THIS IS PROBABLY THE INITIAL TRANSFORM AFTER MERGE



/* run one after another:

alignNodesToTarget nodes target1 origin:origin_first

alignNodesToTarget nodes origin_first origin:target1

alignNodesToTarget nodes target2 origin:nodes[1]

alignNodesToTarget nodes target3 origin:target2

alignNodesToTarget nodes origin_first origin:nodes[1]

*/

 

 

Here is more advanced example

0 Likes
Message 18 of 19

denisT.MaxDoctor
Advisor
Advisor
Accepted solution

@kenc wrote:

So I can mark this as 'solution' if OK with you?


This is your question, and you don't need anyone's permission to mark the answer as a solution. 😉
It just should work for you. 😊

0 Likes
Message 19 of 19

kenc
Advocate
Advocate
Accepted solution

denisT

 

Your explanation is thorough and a quick test confirms it works for me.

 

Sorry again for lengthy time between replies. I appreciate all your help.

 

This an accepted solution.

0 Likes