The case
- I need to create several object that have almost the same geometry,
so when I modified the master all duplicates will reflect the
changes too. But I also need to have freedom to tweak the duplicates
independently.
- If I use duplicate instance, if I select a component in the
model with show affected region on, it also showing it in all
other duplicates, and it is a bit annoying.
- After creating a blendshape, I can not tweak the model. As soon
as I move the blendshape slider all the tweaks that I have made
was overwritten by the other blendshape target. I need to tweak
all my blendshape target to match the tweak that I want since
I have to use several blendshape slider at once.
|
|
|
Examining how instance works
|
|
When you use Edit->Duplicate Option box and set the option to
instance, in the viewport you what you is similar as set the option
to copy.

But if look at the outliner and display the shape node you will
see that all those duplicate will have same name for the shapenode.
But maybe it doesn't tell anything, names doesn't tell anything.
Maybe it just a coincidence that they have same name.

So let us inspect the hypergraph, with pCube1, pCube2 and pCube3
selected, open the hypergraph and display input and output Connection.

There are only one shape node shown, it is pCubeShape1, but the
colors are not as white/grey color, it has purplish color and several
connection to a shading Engine. If you open the connection (double
clicking on the arrow), connection editor will be opened and you
see those connection is connecting InstObjGroup[] to DagSetMembers[].

Definitely there is only one shape node and all the transform node
using this node, which mean if you change the shape node, all instance
will have the new shape no matter on which object you do the change.
Also if you select one component, all of the instance will show
the selected component.

Definitely we can not solve the first case and second case. We
cannot modify the instance object without affecting other object.
And we need different approach.
|
Passing geometry data.
|
|
Fortunately Maya is developed as a node base application where
user can define their own flow of data into these nodes. There are
several geometry data (attributes) can be used depending of the
type of the geometry itself.
inMesh, outMesh, worldMesh for polyMesh
objects, or
create, local, worldSpace for NURBS curves
and NURBS surface.
Please consult the online manual for description of these attributes.
Let's do an example.
Create polygon Cube and a polygon Sphere, rename the cube to Box
and the sphere to Ball. Arrange it so you can see clearly both Box
and Ball.

Open Hypergraph, select Box and Ball, and display Input and Output
Connection.

From BoxShape is shape node for the Box, and BallShape is shape
node for the Ball, both have input connection from polyCube1 (node
that create a poly Cube) and polySphere1 (node that create a polySphere).
polyCube1 and polySphere1 ".output" attribute is connected
to ".inMesh" of the shape nodes.
Since we have to shape nodes, we can modify the shape (tweaking)
independently, but that still does not solve case 1, we need that
one shape replicate the other shape.
In this case we want Box to follow Sphere shape, so it should not
be a cube anymore but a sphere instead.
In hypergraph drag and drop BallShape (the master) to BoxShape
(the slave), and choose Other... when it ask for connection.
A Connection Editor will be opened, with BallShape in Outputs and
BoxShape in Inputs.
Scroll down in Outputs to find "outMesh" attributes and
scroll down in Inputs to find "inMesh" attributes.
You may find that "inMesh" attributes in Inputs is grey
italic, this show that this attribute has an input connection (from
polyCube1), but thats is OK since we will overwrite this connection.
Select outMesh from Outputs and then select inMesh from Inputs.

As soon as you click on "inMesh" the Box shape now become
a sphere, and also the purple arrow in Hypergraph now pointing from
BallShape to BoxShape, BoxShape does not have input connection from
polyCube1 anymore.

Now we have to check the condition:
- If we change the BallShape, will the BoxShape also changed?
- Can I change the BoxShape without affecting the BallShape?

If both case is true, then we have solved the Case no. 1 and no.
2
Several other thing:
- Remember BallShape is the master, and BoxShape is the slave
(duplicate) in this case
- For NURBS curve and NURBS surface it is the same workflow, just
different attributes.
- If you need to connect hundreds of shape to the master, it may
take sometimes to do manually in the connection editor, use MEL
script to help speed things up.
Command to connect attributes should be `connectAttr`, for example
in our example it could be written as:
- `connectAttr -f BallShape.outMesh BoxShape.inMesh`
- where BallShape is the master (source attribute) and
BoxShape is the slave (destination attribute) and -f was
use to force the connection overwriting old connection
(from polyCube1).
More generic MEL command could be put in a loop, for example we
have an object called as "master" with its shape node
called as "masterShape", and we have 10 other slaves called
as "slave1", "slave2", ...., "slave10"
with its shape node called as "slaveShape1", "slaveShape2",
...., "slaveShape10"
string $master = "masterShape";
string $masterAttr = $master + ".outMesh";
for ($i = 1; $i <= 10; $i++)
{
$slaveAttr = "slaveShape" + $i + ".inMesh";
connectAttr -f $masterAttr $slaveAttr;
}
We can continue to Case no. 3
|
Implementation in blendShape
In some other software, when you do something like blendShape,
and you modify (tweak) the master, all other targets will automatically
reflect the modification. For examples if you have 30 or more target
shape for facial expression, blendshape has been set with all those
Set Driven Key non-sense, and the the director says "Boss,
the cheek bone is to high, I want it to be lower a bit, and those
forehead is to small, make it bigger, and one more thing that chin
is to square, make it round a bit", it would be nice
if you can change one master and every target will follow.
Let's take a look how blendShape works in Hypergraph.
For the example I will try to use a very simple geometry, a cube
with 2 x 2 x 2 division on each axis, with 3 blendshape target :
target1, target2, target3, which is duplicate from the base model
and reshape afterward as below:

When you create a blendShape, in hypergraph you will notice there
are several other nodes involved, an intermediate object (usually
with "Orig" in its name), a tweak node, and ofcourse the
blendShape node.

You can tweak the base model as usual in Maya, by pulling or pushing
the vertices or even with the artisan brush.

However with the default setup, if you do tweaking the base model,
whenever you move any slider in the blendshape editor all the tweak
that has been applied on the base model is overwritten by the shape
of the blendshape target.And it is normal, since with blendshape,
maya will try to reach the target shape when its weight value become
1.0
There is a possibility moving tweak node up to the end of the chain,
so you can tweak the final shape without overwritten by the blendShape
target.
swap to 

This will tell Maya, to calculate first the blendshape node and
applied the tweak on top of the result. But I don't like the workflow,
you can see the effect of the tweak in the blendShape target, which
may not be the shape that you want. It's some sort of predicting
or extrapolating things when you use this method. The picture shown
below is set with blendShape weight for target1 set to 1.0.

Better way, if you tweak the base model and the tweak is carried
on onto the blendShape target, and you can then fine tune the blendShape
target to the shape you want.
In this case we will you the same concept as previously mention,
but we need to connect right attribute in right node.
Assuming we are using polyMesh for base model and its targets, if
you connect the intermediate shape outMesh to the inMesh of each
targets, then the tweak you do to the base model will not propagate
to the targetShape, it's not good.
You should connect the output of the tweak node to the inMesh of
the targetShape instead.

With all connection established, now if we modify (tweak) the base
model you will see that all blendShape target will also modified.
You can see how the tweak will effect the target model, and since
both base model got the same tweak, then when you move the slider
it will reach the target shape at value of 1.0 of the slider.

When you are happy with all the blendShape targets, then you can
simply delete their connection to the tweak node. Since it maintain
exact relationship of the tweak in base model and its target shape,
you can tweak your model independent of the blendShape target weight
value, but it will not obey the weight value for the tweak. It means,
when you move those vertices 2 unit down, it will move those corresponding
vertices in all target shape 2 unit down also no matter of what
value in the blendshape slider. I always try to avoid tweaking the
base model with any value of the blendshape slider other than 0.0
Fine tuning the blendshape target after tweaking the base model
seems to me can not be avoided, but at least most part of the dirty
works have been done by the connection.
|
How do this thing works?
In Maya, when you do tweak on the objects from its creation stage,
Maya will store those information in the shape node. For polyMesh
for instance, Maya will store information into an array attribute
called ".pnts"
- pnts (pt) float3
- This attribute is the array of vertex tweaks (relative movements).
The attribute values are always significant regardless of
whether the object has history or not.
- pntx (px) distance (float) 0.0cm
- Vertex position tweak in x.
- pnty (py) distance (float) 0.0cm
- Vertex position tweak in y.
- pntz (pz) distance (float) 0.0cm
- Vertex position tweak in z.
Tweak outputGeometry is like a layer on top of this information,
which mean as long as you have this information than you can do
the steps above. This should be reflected in your workflow, the
targets are reshape duplicates from the base model. As what the
manual said, it is always significant regardless of whether the
object has history or not.
Values of this attributes could be seen in the channel box,

This value as default is in relative mode, and measure as distance
in each axis.
And next thing to do, how to recover this kind of attribute when
it is gone?, exporting object out as an obj and re-importing is
definitely destroy this information on top of rearrangement of vertex
number which will break the blendshape. It should be possible using
MEL script to calculate distances between vertices of base model
to the target model, and use this value as the pnts attributes,
but it will take sometimes for me to do this. Too bad, I need to
do some other works to pay my bill, but hopefully if I got some
spare time, I can do R&D on this matter.
|
|