PDA

View Full Version : parent in place problem



clintonman
03-16-2012, 10:20 PM
This script creates a null and adds 2 bones to it. It then parents the second bone to the first, but the bone jumps to the first bones position.
The script assumes parent in place is on and that auto key is on. If I remove the line that parents the bones I can do it manually in the scene editor and it works as expected.

Is this a bug in the sdk or a code error? Any ideas?


#! /usr/bin/env python
# -*- Mode: Python -*-
# -*- coding: ascii -*-

"""
This is a LightWave Generic plug-in to test bone parenting
"""

import os
import sys
import math
import lwsdk

__author__ = "Clinton Reese"
__date__ = "Mar 16 2012"
__copyright__ = "Copyright (C) 2012 Clinton's 3D Creations"
__version__ = "1.0"
__maintainer__ = "Clinton Reese"
__email__ = "[email protected]"
__status__ = "Example modified 3"
__lwver__ = "11"


# assume autokey is on
# assume Parent in Place is on
class random_test(lwsdk.IGeneric):
def __init__(self, context):
super(random_test, self).__init__()

def process(self, ga):
#add a null
result = ga.evaluate(ga.data, "AddNull buildNULL")

interface_info = lwsdk.LWInterfaceInfo()
selected_items = interface_info.selected_items()
buildItemID = selected_items[0]

#add the first bone to the null
ga.evaluate(ga.data, "SelectItem %s" % lwsdk.itemid_to_str(buildItemID))
result = ga.evaluate(ga.data, "AddBone firstBone")
interface_info = lwsdk.LWInterfaceInfo()
selected_items = interface_info.selected_items()
firstItemID = selected_items[0]
result = ga.evaluate(ga.data, "Position 1 0 0")

#add the second bone to the null
ga.evaluate(ga.data, "SelectItem %s" % lwsdk.itemid_to_str(buildItemID))
result = ga.evaluate(ga.data, "AddBone secondBone")
interface_info = lwsdk.LWInterfaceInfo()
selected_items = interface_info.selected_items()
secondItemID = selected_items[0]
result = ga.evaluate(ga.data, "Position 0 1 0")

#parent the second bone to the first bone
#parent in place on => second bone jumps to location of first bone
#parent in place off => second bone jumps to offset postion relative to first bone
#if comment out the following lines and manually parent it works as expected - no jumping when parent in place is on
lwcomm = "ParentItem %s" % lwsdk.itemid_to_str(firstItemID)
print lwcomm
ga.evaluate(ga.data, lwcomm)

return lwsdk.AFUNC_OK

# /LightWave11.0/sdk/lwsdk11.0/html/server.html
ServerTagInfo = [
( "Python RandomTest", lwsdk.SRVTAG_USERNAME | lwsdk.LANGID_USENGLISH ),
( "Random Test", lwsdk.SRVTAG_BUTTONNAME | lwsdk.LANGID_USENGLISH ),
( "Utilities/Python", lwsdk.SRVTAG_MENU | lwsdk.LANGID_USENGLISH )
]

ServerRecord = { lwsdk.GenericFactory("LW_PyRandomTest", random_test) : ServerTagInfo }

evenflcw
03-17-2012, 08:13 AM
AddBone adds a top level bone to the last selected object. It's created with zero offset. AddChildBone adds a bone parented to the last selected or created bone and offsets it in Z equivalent to the rest length of it's parent bone. It's thanks to that offset that child bones end up at the tip of their parents. And that's what has been missed.

Either use AddChildBone, or when parenting the second bone also give it an offset in Z equivalent to the rest length of the parent.

PS. Sorry, didn't read through all the code, did not notice the "Position" statements. It does seem odd that LW should throw away the Y offset already set when PiP is on. I will investigate myself.

evenflcw
03-17-2012, 09:09 AM
There seems to be a bug in the "general" LW11 SDK! Well spotted! Many thanks from my behalf! No doubt this could break alot of existing tools and alot of people would be scratching their heads. Imho this must be fixed for the first bug fix release for LW11 as it is essential that basic features like parenting works.

Here's a table of how different versions and architectures evaluate equivalent code. The position value is secondBone's position after the script/plugin has been executed (in local/parent coordinates).


[LWversion] [arch] [pip] [position] [result]
LW9.6 lscript off 0 1 0 Correct!
LW9.6 lscript on -1 1 0 Correct!
LW9.6 c-sdk off 0 1 0 Correct!
LW9.6 c-sdk on -1 1 0 Correct!

LW10.1 lscript off 0 1 0 Correct!
LW10.1 lscript on -1 1 0 Correct!

LW11 lscript off 0 1 0 Correct!
LW11 lscript on 0 0 0 Not correct!
LW11 c-sdk off 0 1 0 Correct!
LW11 c-sdk on 0 0 0 Not correct!
LW11 python off 0 1 0 Correct!
LW11 python on 0 0 0 Not correct!
The lscript and c-sdk code attached below, python is in the fist post.


generic
{
AddNull("buildNull");
AddBone("firstBone");
firstBone = Scene().firstSelect();
Position(1,0,0);
AddBone("secondBone");
Position(0,1,0);
ParentItem(firstBone.id);
}



int Test(int version, GlobalFunc *global, LWLayoutGeneric *local, void *serverData)
{
if (version != LWLAYOUTGENERIC_VERSION)
return AFUNC_BADVERSION;

LWInterfaceInfo* intinfo;
LWItemID firstBone;
char command[128];

local->evaluate(local->data, "AddNull buildNull");
local->evaluate(local->data, "AddBone firstBone");
local->evaluate(local->data, "Position 1 0 0");
intinfo = static_cast<LWInterfaceInfo*>(global(LWINTERFACEINFO_GLOBAL, GFUSE_TRANSIENT));
firstBone = intinfo->selItems[0];
local->evaluate(local->data, "AddBone secondBone");
local->evaluate(local->data, "Position 0 1 0");
sprintf(command, "ParentItem %x", firstBone);
local->evaluate(local->data, command);

return AFUNC_OK;
}

clintonman
03-17-2012, 10:10 AM
Thanks for looking at this. I'll report the bug. I hope they fix soon.

fogbugz case# 45014_rtet9q0e

evenflcw
03-22-2012, 12:36 AM
For anyone following this. I got an answer to my bug report. It's not a bug, but a feature or result of an architectural change. It's for the best reason (improved performance) so it's hard to argue against (and I have wanted similar changed to other parts; notably Modeler selections). It is a pity however that it will break older scripts and new ones will have to issue the command conditionally to be backward compatible.


Issuing a motion command like Position from a script does not guarantee that the position is changed immediately. For performance reasons motion changes tend to be grouped together and deferred until after the script has finished. The ParentItem therefore does not see the change in position.

To force all motion changes to be processed at a point in the script, use the UpdateMotion command. In this case just before the ParentItem command.

--
LightWave Bug Report
[email protected]

clintonman
03-22-2012, 09:19 AM
Thanks for the update. My bug report was closed without comment :( and I never would have known about UpdateMotion. I'll give it a try.