Beispiel #1
0
def getTransposedVector(v, position0, position1, inverse=False):

    v0 = XSIMath.CreateVector3()
    v0.Sub(position0[1], position0[0])
    v0.NormalizeInPlace()

    v1 = XSIMath.CreateVector3()
    v1.Sub(position1[1], position1[0])
    v1.NormalizeInPlace()

    ra = v0.Angle(v1)

    if inverse:
        ra = -ra

    axis = XSIMath.CreateVector3()
    #axis.Cross(v, v0)
    axis.Cross(v0, v1)

    r = XSIMath.CreateRotation()
    r.SetFromAxisAngle(axis, ra)

    vector = XSIMath.CreateVector3()
    vector.MulByRotation(v, r)

    # Check if the rotation has been set in the right order
    ra2 = (math.pi * .5) - v1.Angle(vector)
    r.SetFromAxisAngle(axis, -ra2)
    vector.MulByRotationInPlace(r)

    return vector
Beispiel #2
0
    def switchToFk(self):

        # Match Rotation
        tra.matchGlobalTransform(self.fk0, self.jnt0, False, True, True)
        tra.matchGlobalTransform(self.fk1, self.jnt1, False, True, True)

        # Scale
        self.scale.Value = (self.length0 + self.length1) / self.rest

        # Switch to FK
        self.blend.Value = 0

        if self.isleg:
            x = XSIMath.CreateVector3(0, 0, 1)
            y = XSIMath.CreateVector3(0, 1, 0)

            if self.negate:
                x.NegateInPlace()
                y.NegateInPlace()

            x.MulByRotationInPlace(
                self.ik.Kinematics.Global.Transform.Rotation)
            y.MulByRotationInPlace(
                self.ik.Kinematics.Global.Transform.Rotation)

            t = self.ik.Kinematics.Global.Transform
            t.SetRotation(tra.getRotationFromAxis(x, y, "xy"))

            self.fk2.Kinematics.Global.Transform = t
        else:
            tra.matchGlobalTransform(self.fk2, self.ik, False, True, True)
Beispiel #3
0
    def addObjects(self):

        self.root = self.addRoot()
        self.locs = self.addLocMulti("#_loc", self.root)

        centers = [self.root]
        centers.extend(self.locs)
        self.dispcrv = self.addDispCurve("crv", centers)

        # Heel and pivots
        vHeel = XSIMath.CreateVector3(self.root.Kinematics.Global.PosX.Value,
                                      0,
                                      self.root.Kinematics.Global.PosZ.Value)
        vLeftPivot = XSIMath.CreateVector3(
            self.root.Kinematics.Global.PosX.Value + .3, 0,
            self.root.Kinematics.Global.PosZ.Value)
        vRightPivot = XSIMath.CreateVector3(
            self.root.Kinematics.Global.PosX.Value - .3, 0,
            self.root.Kinematics.Global.PosZ.Value)

        self.heel = self.addLoc("heel", self.root, vHeel)
        self.outpivot = self.addLoc("outpivot", self.root, vLeftPivot)
        self.inpivot = self.addLoc("inpivot", self.root, vRightPivot)

        self.dispcrv = self.addDispCurve(
            "1",
            [self.root, self.heel, self.outpivot, self.heel, self.inpivot])
Beispiel #4
0
    def __init__(self, t=XSIMath.CreateTransform()):

        self.transform = t

        self.x = XSIMath.CreateVector3(1, 0, 0)
        self.y = XSIMath.CreateVector3(0, 1, 0)
        self.z = XSIMath.CreateVector3(0, 0, 1)

        self.x.MulByRotationInPlace(t.Rotation)
        self.y.MulByRotationInPlace(t.Rotation)
        self.z.MulByRotationInPlace(t.Rotation)
Beispiel #5
0
def getDistanceToAxe(pos, axe_pos0, axe_pos1):

    axe = XSIMath.CreateVector3()
    axe.Sub(axe_pos1, axe_pos0)

    hyp = XSIMath.CreateVector3()
    hyp.Sub(pos, axe_pos0)

    a = axe.Angle(hyp)

    distance = trigo_adj(hyp.Length(), a)

    return distance
Beispiel #6
0
def getPlaneBiNormal(v0, v1, v2):

    normal = getPlaneNormal(v0, v1, v2)

    vector0 = XSIMath.CreateVector3()
    vector0.Sub(v1, v0)

    biNormal = XSIMath.CreateVector3()

    biNormal.Cross(normal, vector0)
    biNormal.NormalizeInPlace()

    return biNormal
Beispiel #7
0
def getOrthocentreDistances(v0, v1, v2):

    axe = XSIMath.CreateVector3()
    axe.Sub(v2, v0)

    hyp = XSIMath.CreateVector3()
    hyp.Sub(v1, v0)

    a = axe.Angle(hyp)

    distanceA = trigo_opp(hyp.Length(), a)
    distanceB = axe.Length() - distanceA

    return distanceA, distanceB
Beispiel #8
0
def addCubeChain(parent, name, positions, normal, negate=False, size=1, color=[0,0,0]):

    # Name
    if "#" in name:
        name = name.replace("#", "%s")
    else:
        name += "%s"

    # Draw
    bones = []
    for i in range(len(positions)-1):
        v0 = positions[i-1]
        v1 = positions[i]
        v2 = positions[i+1]

        # Normal Offset
        if i > 0:
            normal = vec.getTransposedVector(normal, [v0, v1], [v1, v2])

        t = tra.getTransformLookingAt(v1, v2, normal, "xy", negate)

        # Cube Offset
        d = vec.getDistance(v1, v2)
        offset = XSIMath.CreateVector3(d*.5, 0, 0)

        if negate:
            offset.NegateInPlace()

        # Draw
        bone = icon.cube(parent, name%i, d, size, size, color, t, offset)

        bones.append(bone)
        parent = bone

    return bones
Beispiel #9
0
def getClosestGlobalTransform(position,
                              crv,
                              subcurve=0,
                              tan_axis="x",
                              upv_axis="y",
                              normal=XSIMath.CreateVector3(0, 1, 0)):

    crv_geo = crv.ActivePrimitive.Geometry
    crv_sub = crv_geo.Curves(subcurve)
    crv_tra = crv.Kinematics.Global.Transform

    pos = XSIMath.MapWorldPositionToObjectSpace(crv_tra, position)
    rtn = crv_geo.GetClosestCurvePosition2(pos)
    u = rtn[2]
    pos = rtn[3]
    pos = XSIMath.MapObjectPositionToWorldSpace(crv_tra, pos)
    tan = crv_sub.EvaluatePosition(u)[1]
    r = crv_tra.Rotation
    r.InvertInPlace()
    tan.MulByRotationInPlace(r)
    tan.AddInPlace(pos)

    t = tra.getTransformLookingAt(pos, tan, normal, tan_axis + upv_axis, False)

    return t
Beispiel #10
0
    def addOptionsValues(self):

        # Convert color sliders to list
        for s in ["R_", "L_", "C_"]:
            self.values[s + "color_fk"] = [
                self.values[s + "color_fk_r"], self.values[s + "color_fk_g"],
                self.values[s + "color_fk_b"]
            ]
            self.values[s + "color_ik"] = [
                self.values[s + "color_ik_r"], self.values[s + "color_ik_g"],
                self.values[s + "color_ik_b"]
            ]

        # When not wip, some options are forced
        if self.values["mode"] == 0:
            self.values["setHidden"] = True
            self.values["setUnselectable"] = True
            self.values["setDeformers"] = True
            self.values["setGeometries"] = True
            self.values["popUpControls"] = False
            self.values["isolateResult"] = False

        # Get rig size to adapt size of object to the scale of the character
        maximum = 1
        v = XSIMath.CreateVector3()
        for comp in self.components.values():
            for pos in comp.apos:
                d = vec.getDistance(v, pos)
                maximum = max(d, maximum)

        self.values["size"] = max(maximum * .05, .1)
Beispiel #11
0
def pickPositionMulti(message="Pick position",
                      logWarning=True,
                      minimum=1,
                      maximum=-1):

    pickedPositions = []

    while True:
        rtn = xsi.PickPosition(message, message)
        if not rtn.Value("ButtonPressed"):
            break
        v = XSIMath.CreateVector3(rtn("PosX"), rtn("PosY"), rtn("PosZ"))
        pickedPositions.append(v)
        if addHelpers:
            null = pri.addNullFromPos(xsi.ActiveSceneRoot, "temp_0", v)
            pri.setNullDisplay(null, 1, .5, 2, 0, 0, 0, .5, .5, .5, [0, 1, 0])
            helpers.Add(null)
        if maximum > 0 and len(pickedPositions) >= maximum:
            break

    if len(pickedPositions) < minimum:
        if logWarning:
            xsi.LogMessage("Pick Session Aborded", c.siWarning)
        return False

    return pickedPositions
Beispiel #12
0
def addBoneFromPos(parent, name, position=XSIMath.CreateVector3(), length=1):

     t = XSIMath.CreateTransform()
     t.SetTranslation(position)

     bone = addBone(parent, name, t, length)

     return bone
Beispiel #13
0
def addNullFromPos(parent, name, position=XSIMath.CreateVector3(), size=1, color=[0,0,0]):

    t = XSIMath.CreateTransform()
    t.SetTranslation(position)

    null = addNull(parent, name, t, size, color)

    return null
Beispiel #14
0
def getPlaneNormal(v0, v1, v2):

    vector0 = XSIMath.CreateVector3()
    vector1 = XSIMath.CreateVector3()

    vector0.Sub(v1, v0)
    vector1.Sub(v2, v0)

    vector0.NormalizeInPlace()
    vector1.NormalizeInPlace()

    normal = XSIMath.CreateVector3()

    normal.Cross(vector1, vector0)
    normal.NormalizeInPlace()

    return normal
Beispiel #15
0
def linearlyInterpolate(v0, v1, blend=.5):

    vector = XSIMath.CreateVector3()
    vector.Sub(v1, v0)
    vector.ScaleInPlace(blend)
    vector.AddInPlace(v0)

    return vector
Beispiel #16
0
def getOrthocentre(v0, v1, v2):

    axe = XSIMath.CreateVector3()
    axe.Sub(v2, v0)

    hyp = XSIMath.CreateVector3()
    hyp.Sub(v1, v0)

    a = axe.Angle(hyp)

    distance = trigo_opp(hyp.Length(), a)

    axe.NormalizeInPlace()
    axe.ScaleInPlace(distance)
    axe.AddInPlace(v0)

    return axe
Beispiel #17
0
def gear_SmoothShapeOp_Update(ctxt):

    # Inputs -----------------------------------------------
    shape = ctxt.GetInputValue(0, 0, 0)
    geo = ctxt.GetInputValue(1, 0, 0).Geometry
    cls = ctxt.GetInputValue(2, 0, 0)

    neighbor_depth = ctxt.GetParameterValue("NeighbourDepth")
    blend = ctxt.GetParameterValue("Blend")

    # Process ----------------------------------------------
    shape_tuple = shape.Elements.Array
    shape_array = [
        shape_tuple[j][i] for i in range(len(shape_tuple[0]))
        for j in range(len(shape_tuple))
    ]

    points = cls.Elements.Array
    vSmoothShape = XSIMath.CreateVector3()
    vOriShape = XSIMath.CreateVector3()
    for i in points:

        vertex = geo.Vertices(i)
        cNghbVertices = vertex.NeighborVertices(neighbor_depth)

        vSmoothShape.Set(0, 0, 0)
        vOriShape.Set(shape_array[i * 3 + 0], shape_array[i * 3 + 1],
                      shape_array[i * 3 + 2])
        for oVtx in cNghbVertices:
            index = oVtx.Index

            vSmoothShape.X += shape_array[index * 3 + 0]
            vSmoothShape.Y += shape_array[index * 3 + 1]
            vSmoothShape.Z += shape_array[index * 3 + 2]

        vSmoothShape.ScaleInPlace(blend / cNghbVertices.Count)
        vOriShape.ScaleInPlace(1 - blend)

        shape_array[i * 3 + 0] = vSmoothShape.X + vOriShape.X
        shape_array[i * 3 + 1] = vSmoothShape.Y + vOriShape.Y
        shape_array[i * 3 + 2] = vSmoothShape.Z + vOriShape.Z

    # Output -----------------------------------------------
    Out = ctxt.OutputTarget
    Out.Elements.Array = shape_array
Beispiel #18
0
 def lipVector(X, Y, Z, vectorMultiply):
     x = X * vectorMultiply
     y = Y * vectorMultiply
     z = Z * vectorMultiply
     vLip = XSIMath.CreateVector3(
         self.tongueT.Kinematics.Global.PosX.Value + x,
         self.tongueT.Kinematics.Global.PosY.Value + y,
         self.tongueT.Kinematics.Global.PosZ.Value + z)
     return vLip
Beispiel #19
0
 def addObjects(self):
     self.root = self.addRoot()
     self.locs = self.addLocMulti("#_loc", self.root, False)
     
     
     vTemp = XSIMath.CreateVector3(self.root.Kinematics.Global.PosX.Value  , self.root.Kinematics.Global.PosY.Value +2, self.root.Kinematics.Global.PosZ.Value )
     self.upVector = self.addLoc("upVector", self.root, vTemp )
     
     vTemp = XSIMath.CreateVector3(self.root.Kinematics.Global.PosX.Value  , self.root.Kinematics.Global.PosY.Value , self.root.Kinematics.Global.PosZ.Value +2 )
     self.direction = self.addLoc("direction", self.root, vTemp )
     
     centers = [self.direction, self.root, self.upVector]
     self.dispcrv = self.addDispCurve("crvUp", centers)
     
     self.blade = self.addBlade("blade", self.root, self.upVector)
     
     centers = []
     centers.extend(self.locs)
     self.dispcrv = self.addDispCurve("crv", centers)
Beispiel #20
0
def pickPosition(message="Pick position", logWarning=True):

    rtn = xsi.PickPosition(message, message)

    if rtn("ButtonPressed") == 0:
        if logWarning:
            xsi.LogMessage("Pick Session Aborded", c.siWarning)
        return False

    position = XSIMath.CreateVector3(rtn("PosX"), rtn("PosY"), rtn("PosZ"))
    return position
Beispiel #21
0
def add2DChain(parent,
               name,
               positions,
               normal=None,
               negate=False,
               size=1,
               alignRoot=False):

    if size < 0.05:
        size = 0.05

    # Compute Normal --------
    if normal is None:
        if len(positions) >= 3:
            normal = vector.computePlaneNormal(positions[0], positions[1],
                                               positions[2])
        else:
            normal = XSIMath.CreateVector3(0, 0, -1)

    # Draw -------------------
    root = parent.Add2DChain(positions[0], positions[1], normal,
                             c.si2DChainNormalRadian)
    for i in range(len(positions) - 2):
        root.AddBone(positions[i + 2])

    xChain = Chain(root, name)

    # Negative Scaling -------
    for bone in xChain.bones:

        bone.size.Value = size

        if negate:
            bone.axisz = 180

        #xsi.SetNeutralPose(bone)

    if negate:
        xChain.bones[0].Properties("kinematic chain").Parameters(
            "effori_offz").Value = 180

    # Display ----------------
    xChain.root.Size = size * .25
    xChain.eff.Size = size * .125

    # !!! This can be trouble !!!
    # !!! OUT OF FOCUS BUG !!!
    # Using this command gives weird result when the focus is not on XSI
    # xsi.AlignRootToFirstBone(root)
    if alignRoot:
        alignRootToFirstBone(xChain)

    return xChain
Beispiel #22
0
def getTransformLookingAt(position, lookat, normal, axis="xy", negate=False):

    a = XSIMath.CreateVector3()
    a.Sub(lookat, position)

    r = getRotationFromAxis(a, normal, axis, negate)

    t = XSIMath.CreateTransform()
    t.SetTranslation(position)
    t.SetRotation(r)

    return t
Beispiel #23
0
def getBladeBiNormalFromXml(xml_def):

    xNurbsCurveList = xsixmldom.NurbsCurveList(xml_def)
    t = xNurbsCurveList.globalTransform
    p = xNurbsCurveList.getPointArray()

    points = []

    for i in range(3):
        v = XSIMath.CreateVector3(p[i * 3 + 0], p[i * 3 + 1], p[i * 3 + 2])
        points.append(XSIMath.MapObjectPositionToWorldSpace(t, v))

    normal = getPlaneBiNormal(points[0], points[1], points[2])

    return normal
Beispiel #24
0
def rotateVectorAlongAxis(v, axis, a=0):
    # Angle as to be in radians

    sa = math.sin(a / 2.0)
    ca = math.cos(a / 2.0)

    q1 = XSIMath.CreateQuaternion(0, v.X, v.Y, v.Z)
    q2 = XSIMath.CreateQuaternion(ca, axis.X * sa, axis.Y * sa, axis.Z * sa)
    q2n = XSIMath.CreateQuaternion(ca, -axis.X * sa, -axis.Y * sa,
                                   -axis.Z * sa)

    q = XSIMath.CreateQuaternion()
    q.Mul(q2, q1)
    q.MulInPlace(q2n)

    vector = XSIMath.CreateVector3(q.X, q.Y, q.Z)

    return vector
Beispiel #25
0
    def addObjects(self):

        t = tra.getTransformLookingAt(self.guide.pos["root"],
                                      self.guide.pos["lookat"], self.y_axis,
                                      "zy")

        # Direction cns
        self.dir_cns = pri.addNull(self.root, self.getName("dir_cns"), t,
                                   self.size * .1)
        self.addToGroup(self.dir_cns, "hidden")

        upv_pos = XSIMath.CreateVector3(0, 1, 0)
        upv_pos.MulByTransformationInPlace(t)
        self.upv_cns = pri.addNullFromPos(self.root, self.getName("upv_cns"),
                                          upv_pos, self.size * .1)
        self.addToGroup(self.upv_cns, "hidden")

        # IK Controler
        self.ik_cns = pri.addNull(
            self.root, "ik_cns",
            tra.getTransformFromPosition(self.guide.pos["lookat"]),
            self.size * .1)
        self.addToGroup(self.ik_cns, "hidden")
        self.ik_ctl = self.addCtl(self.ik_cns,
                                  "ik_ctl",
                                  tra.getTransformFromPosition(
                                      self.guide.pos["lookat"]),
                                  self.color_ik,
                                  "cross",
                                  h=self.size * .5)
        par.setKeyableParameters(self.ik_ctl, self.t_params)

        # FK Controler
        self.fk_ctl = self.addCtl(self.dir_cns,
                                  "fk_ctl",
                                  t,
                                  self.color_fk,
                                  "arrow",
                                  h=self.size * .5)
        xsi.SetNeutralPose(self.fk_ctl, c.siTrn)
        par.setKeyableParameters(self.fk_ctl, self.r_params)
        # par.addLocalParamToCollection(self.inv_params, self.fk_ctl, ["posx", "posy", "posz"])

        self.addShadow(self.fk_ctl, 0)
Beispiel #26
0
def getRotationFromAxis(in_a, in_b, axis="xy", negate=False):

    a = XSIMath.CreateVector3(in_a.X, in_a.Y, in_a.Z)
    b = XSIMath.CreateVector3(in_b.X, in_b.Y, in_b.Z)
    c = XSIMath.CreateVector3()

    x = XSIMath.CreateVector3()
    y = XSIMath.CreateVector3()
    z = XSIMath.CreateVector3()

    if negate:
        a.NegateInPlace()

    a.NormalizeInPlace()
    c.Cross(a, b)
    c.NormalizeInPlace()
    b.Cross(c, a)
    b.NormalizeInPlace()

    if axis == "xy":
        x = a
        y = b
        z = c
    elif axis == "xz":
        x = a
        z = b
        y.Negate(c)
    elif axis == "yx":
        y = a
        x = b
        z.Negate(c)
    elif axis == "yz":
        y = a
        z = b
        x = c
    elif axis == "zx":
        z = a
        x = b
        y = c
    elif axis == "zy":
        z = a
        y = b
        x.Negate(c)
    else:
        gear.log("Invalid Input", gear.sev_error)
        return

    r = XSIMath.CreateRotation()
    r.SetFromXYZAxes(x, y, z)

    return r
Beispiel #27
0
    def addObjects(self):

        self.normal = self.getNormalFromPos(self.guide.apos)

        self.length0 = vec.getDistance(self.guide.apos[0], self.guide.apos[1])
        self.length1 = vec.getDistance(self.guide.apos[1], self.guide.apos[2])
        self.length2 = vec.getDistance(self.guide.apos[2], self.guide.apos[3])

        # FK Controlers ------------------------------------
        t = tra.getTransformLookingAt(self.guide.apos[0], self.guide.apos[1], self.normal, "xz", self.negate)
        self.fk0_ctl = self.addCtl(self.root, "fk0_ctl", t, self.color_fk, "cube", h=self.size*.1, w=1, d=self.size*.1, po=XSIMath.CreateVector3(.5*self.n_factor,0,0))
        self.fk0_ctl.Parameters("SclX").Value = self.length0
        tra.setRefPose(self.fk0_ctl, [-90,0,0], self.negate)
        xsi.SetNeutralPose(self.fk0_ctl, c.siSRT)
        par.setKeyableParameters(self.fk0_ctl)
        par.addLocalParamToCollection(self.inv_params, self.fk0_ctl, ["posx", "posy", "posz"])

        t = tra.getTransformLookingAt(self.guide.apos[1], self.guide.apos[2], self.normal, "xz", self.negate)
        self.fk1_ctl = self.addCtl(self.fk0_ctl, "fk1_ctl", t, self.color_fk, "cube", h=self.size*.1, w=1, d=self.size*.1, po=XSIMath.CreateVector3(.5*self.n_factor,0,0))
        self.fk1_ctl.Parameters("SclX").Value = self.length1/self.length0
        xsi.SetNeutralPose(self.fk1_ctl, c.siST)
        par.setKeyableParameters(self.fk1_ctl)
        par.addLocalParamToCollection(self.inv_params, self.fk1_ctl, ["posx", "posy", "posz"])

        t = tra.getTransformLookingAt(self.guide.apos[2], self.guide.apos[3], self.normal, "xz", self.negate)
        self.fk2_ctl = self.addCtl(self.fk1_ctl, "fk2_ctl", t, self.color_fk, "cube", h=self.size*.1, w=self.length2, d=self.size*.1, po=XSIMath.CreateVector3(self.length2*.5*self.n_factor,0,0))
        xsi.SetNeutralPose(self.fk2_ctl, c.siST)
        par.setKeyableParameters(self.fk2_ctl)
        par.addLocalParamToCollection(self.inv_params, self.fk2_ctl, ["posx", "posy", "posz"])

        # IK Controlers ------------------------------------
        self.ik_cns = pri.addNullFromPos(self.root, self.getName("ik_cns"), self.guide.apos[2], self.size*.02)
        self.addToGroup(self.ik_cns, "hidden")

        self.ikcns_ctl = self.addCtl(self.ik_cns, "ikcns_ctl", self.ik_cns.Kinematics.Global.Transform, self.color_ik, "null", h=self.size*.2)
        par.setKeyableParameters(self.ikcns_ctl)
        par.addLocalParamToCollection(self.inv_params, self.ikcns_ctl, ["posx", "rotx", "rotz"])

        t = tra.getTransformLookingAt(self.guide.apos[2], self.guide.apos[3], self.normal, "xz", self.negate)
        self.ik_ctl = self.addCtl(self.ikcns_ctl, "ik_ctl", t, self.color_ik, "cube", h=self.size*.12, w=self.length2, d=self.size*.12, po=XSIMath.CreateVector3(self.length2*.5*self.n_factor,0,0))
        tra.setRefPose(self.ik_ctl, [-90,0,0], self.negate)
        par.setKeyableParameters(self.ik_ctl)
        par.addLocalParamToCollection(self.inv_params, self.ik_ctl, ["posx"])

        v = XSIMath.CreateVector3()
        v.Sub(self.guide.apos[2], self.guide.apos[0])
        v.Cross(self.normal, v)
        v.NormalizeInPlace()
        v.ScaleInPlace(self.size * .5)
        v.AddInPlace(self.guide.apos[1])
        self.upv_cns = pri.addNullFromPos(self.root, self.getName("upv_cns"), v, self.size*.02)
        self.addToGroup(self.upv_cns, "hidden")

        self.upv_ctl = self.addCtl(self.upv_cns, "upv_ctl", self.upv_cns.Kinematics.Global.Transform, self.color_ik, "leash", h=self.size*.05, ap=self.guide.apos[1])
        par.setKeyableParameters(self.upv_ctl, self.t_params)
        par.addLocalParamToCollection(self.inv_params, self.upv_ctl, ["posx"])

        # Chain --------------------------------------------
        self.bone0 = pri.addNull(self.root, self.getName("0_jnt"), self.fk0_ctl.Kinematics.Global.Transform)
        pri.setNullDisplay(self.bone0, 0, 1, 4, self.n_factor*.5, 0, 0, 1, self.size*.01, self.size*.01)
        self.bone0.Kinematics.Global.Parameters("sclx").Value = self.length0
        self.bone1 = pri.addNull(self.bone0, self.getName("1_jnt"), self.fk1_ctl.Kinematics.Global.Transform)
        pri.setNullDisplay(self.bone1, 0, 1, 4, self.n_factor*.5, 0, 0, 1, self.size*.01, self.size*.01)
        self.bone1.Kinematics.Global.Parameters("sclx").Value = self.length1

        self.ctrn_loc = pri.addNullFromPos(self.bone0, self.getName("ctrn_loc"), self.guide.apos[1], self.size*.05)
        self.eff_loc  = pri.addNullFromPos(self.root, self.getName("eff_loc"), self.guide.apos[2], self.size*.05)

        self.addToGroup([self.bone0, self.bone1, self.ctrn_loc, self.eff_loc], "hidden")

        # Mid Controler ------------------------------------
        self.mid_ctl = self.addCtl(self.ctrn_loc, "mid_ctl", self.ctrn_loc.Kinematics.Global.Transform, self.color_ik, "sphere", h=self.size*.05)
        par.addLocalParamToCollection(self.inv_params, self.mid_ctl, ["posx", "posy", "posz"])

        # Membrane -----------------------------------------
        self.memb_loc = pri.addNull(self.mid_ctl, self.getName("memb_loc"), self.mid_ctl.Kinematics.Global.Transform, self.size*.02)
        self.memb_crv = cur.addCnsCurve(self.memb_loc, self.getName("memb_crv"), [self.root, self.memb_loc, self.eff_loc], False, 3)

        # Twist references ---------------------------------
        t = tra.getFilteredTransform(self.fk0_ctl.Kinematics.Global.Transform, True, True, False)
        self.tws0_loc = pri.addNull(self.root, self.getName("tws0_loc"), t, self.size*.05)
        self.tws0_rot = pri.addNull(self.tws0_loc, self.getName("tws0_rot"), t)
        pri.setNullDisplay(self.tws0_rot, 0, self.size*.05, 2, 0, 0, 0, self.size*.01)

        self.tws1_loc = pri.addNull(self.ctrn_loc, self.getName("tws1_loc"), self.ctrn_loc.Kinematics.Global.Transform, self.size*.05)
        self.tws1_rot = pri.addNull(self.tws1_loc, self.getName("tws1_rot"), self.ctrn_loc.Kinematics.Global.Transform)
        pri.setNullDisplay(self.tws1_rot, 0, self.size*.05, 2, 0, 0, 0, self.size*.01)

        t = tra.getFilteredTransform(self.bone1.Kinematics.Global.Transform, True, True, False)
        t.SetTranslation(self.guide.apos[2])
        self.tws2_loc = pri.addNull(self.bone1, self.getName("tws2_loc"), t, self.size*.05)
        self.tws2_rot = pri.addNull(self.tws2_loc, self.getName("tws2_rot"),t)
        self.tws2_rot.Kinematics.Global.Parameters("SclX").Value = .001
        pri.setNullDisplay(self.tws2_rot, 0, self.size*.05, 2, 0, 0, 0, self.size*.01)

        self.addToGroup([self.tws0_loc, self.tws0_rot, self.tws1_loc, self.tws1_rot, self.tws2_loc, self.tws2_rot], "hidden")

        # End reference ------------------------------------
        t = tra.getFilteredTransform(self.tws2_rot.Kinematics.Global.Transform, True, True, False)
        self.end_ref = pri.addNull(self.tws2_rot, self.getName("end_ref"), t, self.size*.2)
        self.addToGroup(self.end_ref, "hidden")
        self.addShadow(self.end_ref, "end")
        
        # Divisions ----------------------------------------
        # We have at least one division at the start, the end and one for the elbow.
        self.divisions = self.settings["div0"] + self.settings["div1"] + 3

        self.div_cns = []
        for i in range(self.divisions):

            div_cns = pri.addNull(self.tws0_loc, self.getName("div%s_loc"%i), XSIMath.CreateTransform())
            pri.setNullDisplay(div_cns, 1, self.size*.02, 10, 0, 0, 0, 1, 1, 2)
            self.addToGroup(div_cns, "hidden")

            self.div_cns.append(div_cns)

            self.addShadow(div_cns, i)
Beispiel #28
0
    def switchToIk(self):

        # Get the distance between Root and effector and compare it to bones total length to define if the chain is bend or not
        vRootEff = XSIMath.CreateVector3()
        vRootEff.Sub(self.jnt0.kinematics.Global.Transform.Translation,
                     self.ik.kinematics.Global.Transform.Translation)

        # We get an approximation of the length otherwise it's sometimes tricky to compare distance
        r = 100000
        dRootEffLength = round((vRootEff.Length() * r)) / r
        dBonesLength = round(((self.length0 + self.length1) * r)) / r

        # xsi.MatchTransform(self.ik, self.eff, c.siRT, None)
        # tra.matchGlobalTransform(self.eff, self.ik, True, True, False)
        tra.matchGlobalTransform(self.ik, self.fk2, True, True, True)
        self.blend.Value = 1
        # tra.matchGlobalTransform(self.fk2, self.ik, False, True, False)

        # Compute Roll
        if dRootEffLength < dBonesLength:
            # Get Vectors to built the plane
            vFKChain0 = XSIMath.CreateVector3()
            vIKChain0 = XSIMath.CreateVector3()
            vRootEff = XSIMath.CreateVector3()

            vFKChain0.Sub(self.fk0.kinematics.Global.Transform.Translation,
                          self.fk1.kinematics.Global.Transform.Translation)
            vIKChain0.Sub(self.jnt0.kinematics.Global.Transform.Translation,
                          self.jnt1.kinematics.Global.Transform.Translation)
            vRootEff.Sub(self.jnt0.kinematics.Global.Transform.Translation,
                         self.ik.kinematics.Global.Transform.Translation)

            # vFKChain0.NormalizeInPlace()
            # vIKChain0.NormalizeInPlace()
            # vRootEff.NormalizeInPlace()

            # Get Plane's Normal
            vNormFKPlane = XSIMath.CreateVector3()
            vNormIKPlane = XSIMath.CreateVector3()

            vNormFKPlane.Cross(vFKChain0, vRootEff)
            vNormIKPlane.Cross(vIKChain0, vRootEff)

            # vNormFKPlane.NormalizeInPlace()
            # vNormIKPlane.NormalizeInPlace()

            # Get the Angle between the two planess
            dAngle = XSIMath.RadiansToDegrees(vNormFKPlane.Angle(vNormIKPlane))

            # Check if we have to remove or add the angle
            vCrossPlane = XSIMath.CreateVector3()
            vCrossPlane.Cross(vNormFKPlane, vNormIKPlane)
            # vCrossPlane.NormalizeInPlace()

            dDirectionDot = vCrossPlane.Dot(vRootEff)

            # Set the new roll Value
            a = self.roll.Value + (dDirectionDot / abs(dDirectionDot)) * dAngle

            # Set the angle in a -180 / 180 range
            if abs(a) > 180:
                a = a % ((-a / abs(a)) * 360)

            # [OLD WAY ]Set the new roll Value --

            # Check if the bone is negated or not
            ## dNegate = self.jnt1.kinematics.Local.posx.Value + self.jnt1.kinematics.Local.nposx.Value
            #dNegate = 1
            # oldAngle = self.roll.Value

            # if (dDirectionDot * dNegate) <  0:
            # newAngle = oldAngle - dAngle
            # else:
            # newAngle = oldAngle + dAngle

            # if newAngle > 180:
            # newAngle -= 360
            # elif newAngle < -180:
            # newAngle += 360
            # [END OLD WAY ] -------------------

            self.roll.Value = a

        # Match Scale Value
        # We remove Soft distances
        self.softik.Value = 0

        if dRootEffLength > dBonesLength:
            if self.scale.Value > self.maxstretch.Value:
                self.maxstretch.Value = self.scale.Value
                self.scale.Value = 1

        if self.isleg:
            z = XSIMath.CreateVector3(1, 0, 0)
            y = XSIMath.CreateVector3(0, 1, 0)

            if self.negate:
                z.NegateInPlace()
                y.NegateInPlace()

            z.MulByRotationInPlace(
                self.fk2.Kinematics.Global.Transform.Rotation)
            y.MulByRotationInPlace(
                self.fk2.Kinematics.Global.Transform.Rotation)

            t = self.fk2.Kinematics.Global.Transform
            t.SetRotation(tra.getRotationFromAxis(z, y, "zy"))

            self.ik.Kinematics.Global.Transform = t
        else:
            tra.matchGlobalTransform(self.ik, self.fk2, False, True, True)
Beispiel #29
0
def getDistance(v0, v1):

    distance = XSIMath.CreateVector3()
    distance.Sub(v0, v1)

    return distance.Length()
Beispiel #30
0
class MainComponent(object):

    steps = ["Objects", "Properties", "Operators", "Connect", "Finalize"]

    local_params = ("posx", "posy", "posz", "rotx", "roty", "rotz", "rotorder",
                    "sclx", "scly", "sclz")
    t_params = ("posx", "posy", "posz")
    r_params = ("rotx", "roty", "rotz", "rotorder")
    s_params = ("sclx", "scly", "sclz")
    tr_params = ("posx", "posy", "posz", "rotx", "roty", "rotz", "rotorder")
    rs_params = ("rotx", "roty", "rotz", "rotorder", "sclx", "scly", "sclz")
    x_axis = XSIMath.CreateVector3(1, 0, 0)
    y_axis = XSIMath.CreateVector3(0, 1, 0)
    z_axis = XSIMath.CreateVector3(0, 0, 1)

    # =====================================================
    ## Init Method.
    # @param self
    # @param rig Rig - The parent Rig of this component.
    # @param guide ComponentGuide - The guide for this component.
    def __init__(self, rig, guide):

        # --------------------------------------------------
        # Main Objects
        self.rig = rig
        self.guide = guide

        self.options = self.rig.options
        self.model = self.rig.model
        self.settings = self.guide.values

        self.name = self.settings["comp_name"]
        self.side = self.settings["comp_side"]
        self.index = self.settings["comp_index"]

        # --------------------------------------------------
        # Shortcut to useful settings
        self.size = self.guide.size

        self.color_fk = self.options[self.side + "_color_fk"]
        self.color_ik = self.options[self.side + "_color_ik"]

        self.negate = self.side == "R"
        if self.negate:
            self.n_sign = "-"
            self.n_factor = -1
        else:
            self.n_sign = ""
            self.n_factor = 1

        # --------------------------------------------------
        # Builder init
        self.groups = {}  ## Dictionary of groups
        self.controlers = []  ## List of all the controlers of the component
        self.inv_params = XSIFactory.CreateObject("XSI.Collection")

        if not self.settings["set_ctl_grp"] or (self.settings["set_ctl_grp"]
                                                and self.settings["ctl_grp"]
                                                == ""):
            self.settings["ctl_grp"] = "01"

        # --------------------------------------------------
        # Property init
        self.anim_layout = ppg.PPGLayout()
        self.anim_logic = ppg.PPGLogic()
        self.setup_layout = ppg.PPGLayout()
        self.setup_logic = ppg.PPGLogic()

        self.ui = None

        # --------------------------------------------------
        # Connector init
        self.connections = {}
        self.connections["standard"] = self.connect_standard

        self.relatives = {}

        # --------------------------------------------------
        # Step
        self.stepMethods = [
            eval("self.step_0%s" % i) for i in range(len(self.steps))
        ]

    # =====================================================
    # BUILDING STEP
    # =====================================================
    ## Step 00. Initial Hierarchy, create objects and set the connection relation.
    # @param self
    def step_00(self):
        self.initialHierarchy()
        self.addObjects()
        self.setRelation()
        return

    ## Step 01. Get the properties host, create parameters and set layout and logic.
    # @param self
    def step_01(self):
        self.getHost()
        self.addParameters()
        self.addLayout()
        self.addLogic()
        self.setUI()
        return

    ## Step 02. Apply all the operators.
    # @param self
    def step_02(self):
        self.addOperators()
        return

    ## Step 03. Connect the component to the rest of the rig.
    # @param self
    def step_03(self):
        self.initConnector()
        self.addConnection()
        self.connect()
        self.postConnect()
        return

    ## Step 04. Finalize the component.
    # @param self
    def step_04(self):
        self.finalize()
        return

    ## NOT YET AVAILABLE
    def step_05(self):
        self.addPostSkin()
        return

    # =====================================================
    # OBJECTS
    # =====================================================
    ## Build the initial hierarchy of the component.\n
    # Add the root and if needed the shadow root
    # @param self
    def initialHierarchy(self):

        # Root -------------------------------
        self.root = pri.addNullFromPos(self.model, self.getName("root"),
                                       self.guide.pos["root"],
                                       self.options["size"] * .1)
        self.addToGroup(self.root, "hidden")

        # Shd --------------------------------
        if self.options["shadowRig"]:
            self.shd_org = self.rig.shd_org.AddNull(self.getName("shd_org"))
            self.addToGroup(self.shd_org, "hidden")

    ## Add all the objects needed to create the component.\n
    # REIMPLEMENT. This method should be reimplemented in each component.\n
    # Try not to apply any constraint, operator, or expression in here. Just X3DObjects.
    # @param self
    def addObjects(self):
        return

    ## Add the object in a collection for later group creation
    # @param self
    # @param objs Single or List of X3DObject - object to put in group
    # @param names Single or List of String - names of the groups to create
    def addToGroup(self, objects, names=["hidden"]):

        if not isinstance(names, list):
            names = [names]

        if not isinstance(objects, list):
            objects = [objects]

        for name in names:
            if name not in self.groups.keys():
                self.groups[name] = []

            self.groups[name].extend(objects)

    def addToCtlGroup(self, objects, names=None):

        if names is None:
            names = [self.settings["ctl_grp"]]
        elif not isinstance(names, list):
            names = [names]

        if not isinstance(objects, list):
            objects = [objects]

        for name in names:
            name = "controlers_" + name
            if name not in self.groups.keys():
                self.groups[name] = []

            self.groups[name].extend(objects)
            self.controlers.extend(objects)

    def addShadow(self, obj, name):

        if self.options["shadowRig"]:
            shd = pri.addImplicite(self.shd_org, "Cube",
                                   self.getName(str(name) + "_shd"),
                                   obj.Kinematics.Global.Transform,
                                   self.options["size"] * .15)
            shd.Kinematics.AddConstraint("Pose", obj, False)
        else:
            shd = pri.addImplicite(obj, "Cube",
                                   self.getName(str(name) + "_shd"),
                                   obj.Kinematics.Global.Transform,
                                   self.options["size"] * .15)

        self.addToGroup(shd, "deformers")

        return shd

    def getNormalFromPos(self, pos):
        if len(pos) < 3:
            gear.log(
                "%s : Not enough references to define normal" % self.fullName,
                gear.sev_error)

        return vec.getPlaneNormal(pos[0], pos[1], pos[2])

    def getBiNormalFromPos(self, pos):
        if len(pos) < 3:
            gear.log(
                "%s : Not enough references to define binormal" %
                self.fullName, gear.sev_error)

        return vec.getPlaneBiNormal(pos[0], pos[1], pos[2])

    # =====================================================
    def addCtl(self, parent, name, t, color, icon, **kwargs):

        prim = None
        if self.getName(name) in self.rig.guide.controlers.keys():
            prim = self.rig.guide.controlers[self.getName(name)]
            #Get color from rig

            try:
                rR = prim.obj.Properties('display').Parameters(12).GetValue2(
                    None)
                rG = prim.obj.Properties('display').Parameters(13).GetValue2(
                    None)
                rB = prim.obj.Properties('display').Parameters(14).GetValue2(
                    None)
                color = [rR, rG, rB]
            except:
                pass

        ctl = ico.primOrIcon(prim,
                             parent,
                             self.getName(name),
                             t,
                             color,
                             icon,
                             kwargs=kwargs)
        self.addToCtlGroup(ctl)
        return ctl

    # =====================================================
    # PROPERTY
    # =====================================================
    ## Get the host for the properties.
    # @param self
    def getHost(self):

        self.uihost = self.rig.findUIHost(self.settings["uiHost"])
        self.anim_prop = self.uihost.anim_prop
        self.setup_prop = self.uihost.setup_prop

    ## Add parameters to the anim and setup properties to control the component.\n
    # REIMPLEMENT. This method should be reimplemented in each component.
    # @param self
    def addParameters(self):
        return

    ## Define the layout of the anim and setup properties.\n
    # REIMPLEMENT. This method should be reimplemented in each component.
    # @param self
    def addLayout(self):
        return

    ## Define the logic of the anim and setup properties.\n
    # REIMPLEMENT. This method should be reimplemented in each component.
    # @param self
    def addLogic(self):
        return

    def setUI(self):

        # Layout
        for source_layout, target_layout in ((self.anim_layout,
                                              self.uihost.anim_layout),
                                             (self.setup_layout,
                                              self.uihost.setup_layout)):

            target_layout.beforeCode.extend(source_layout.beforeCode)
            target_layout.afterCode.extend(source_layout.afterCode)

            for name, tab in source_layout.tabs.items():
                newtab = target_layout.addTab(name)
                if not newtab.items:
                    row = newtab.addRow()
                    r_group = row.addGroup("Right")
                    c_group = row.addGroup("")
                    l_group = row.addGroup("Left")
                else:
                    row = newtab.items[0]
                    r_group = row.items[0]
                    c_group = row.items[1]
                    l_group = row.items[2]

                if self.side == "R":
                    group = r_group
                elif self.side == "C":
                    group = c_group
                elif self.side == "L":
                    group = l_group

                group.items.extend(tab.items)

        # Logic
        self.uihost.anim_logic.addGlobalCode(self.anim_logic.getValue())
        self.uihost.setup_logic.addGlobalCode(self.setup_logic.getValue())

    ## Add a parameter to the animation property.\n
    # Note that animatable and keyable are True per default.
    # @param self
    # @param scriptName String - Parameter scriptname.
    # @param valueType Integer - siVariantType.
    # @param value Variant - Default parameter value.
    # @param minimum Variant - mininum value.
    # @param maximum Variant - maximum value.
    # @param sugMinimum Variant - suggested mininum value.
    # @param sugMaximum Variant - suggested maximum value.
    # @param animatable Boolean - True to make parameter animatable.
    # @param readOnly Boolean - True to make parameter readOnly.
    # @param keyable Boolean - True to make parameter keyable.
    # @return Parameter - The newly created parameter.
    def addAnimParam(self,
                     scriptName,
                     valueType,
                     value,
                     minimum=None,
                     maximum=None,
                     sugMinimum=None,
                     sugMaximum=None,
                     animatable=True,
                     readOnly=False,
                     keyable=True):

        capabilities = 1 * animatable + 2 * readOnly + 4 + 2048 * keyable
        param = self.anim_prop.AddParameter2(self.getName(scriptName),
                                             valueType, value, minimum,
                                             maximum, sugMinimum, sugMaximum,
                                             c.siClassifUnknown, capabilities,
                                             scriptName)

        return param

    ## Add a parameter to the setup property.\n
    # Note that animatable and keyable are false per default.
    # @param self
    # @param scriptName String - Parameter scriptname.
    # @param valueType Integer - siVariantType.
    # @param value Variant - Default parameter value.
    # @param minimum Variant - mininum value.
    # @param maximum Variant - maximum value.
    # @param sugMinimum Variant - suggested mininum value.
    # @param sugMaximum Variant - suggested maximum value.
    # @param animatable Boolean - True to make parameter animatable.
    # @param readOnly Boolean - True to make parameter readOnly.
    # @param keyable Boolean - True to make parameter keyable.
    # @return Parameter - The newly created parameter.
    def addSetupParam(self,
                      scriptName,
                      valueType,
                      value,
                      minimum=None,
                      maximum=None,
                      sugMinimum=None,
                      sugMaximum=None,
                      animatable=False,
                      readOnly=False,
                      keyable=False):

        capabilities = 1 * animatable + 2 * readOnly + 4 + 2048 * keyable
        param = self.setup_prop.AddParameter2(self.getName(scriptName),
                                              valueType, value, minimum,
                                              maximum, sugMinimum, sugMaximum,
                                              c.siClassifUnknown, capabilities,
                                              scriptName)

        return param

    ## Add a parameter to the setup property.\n
    # Note that animatable and keyable are false per default.
    # @param self
    # @param scriptName String - Parameter scriptname.
    # @param valueType Integer - siVariantType.
    # @param value Variant - Default parameter value.
    # @param minimum Variant - mininum value.
    # @param maximum Variant - maximum value.
    # @param sugMinimum Variant - suggested mininum value.
    # @param sugMaximum Variant - suggested maximum value.
    # @param animatable Boolean - True to make parameter animatable.
    # @param readOnly Boolean - True to make parameter readOnly.
    # @param keyable Boolean - True to make parameter keyable.
    # @return Parameter - The newly created parameter.
    def addSetupFCurveParam(self, scriptName, ref_fcv):

        ref_fcv.scriptName = self.getName(scriptName)
        param = ref_fcv.create(self.setup_prop)

        return param

    # =====================================================
    # OPERATORS
    # =====================================================
    ## Apply operators, constraint, expressions to the hierarchy.\n
    # REIMPLEMENT. This method should be reimplemented in each component.\n
    # We shouldn't create any new object in this method.
    # @param self
    def addOperators(self):
        return

    # =====================================================
    # CONNECTOR
    # =====================================================
    ## Add more connection definition to the set.\n
    # REIMPLEMENT. This method should be reimplemented in each component.\n
    # Only if you need to use an new connection (not the standard).
    # @param self
    def addConnection(self):
        return

    ## Set the relation beetween object from guide to rig.\n
    # REIMPLEMENT. This method should be reimplemented in each component.
    # @param self
    def setRelation(self):
        for name in self.guide.objectNames:
            self.relatives[name] = self.root

    ## Return the relational object from guide to rig.
    # @param self
    # @param local name of the guide object.
    def getRelation(self, name):
        if name not in self.relatives.keys():
            gear.log(
                "Can't find reference for object : " + self.fullName + "." +
                name, gear.sev_error)
            return False

        return self.relatives[name]

    def initConnector(self):

        parent_name = "none"
        if self.guide.parentComponent is not None:
            parent_name = self.guide.parentComponent.getName(
                self.guide.parentLocalName)

        self.parent = self.rig.findChild(parent_name)
        self.parent_comp = self.rig.findComponent(parent_name)

    ## Connect the component to the rest of the rig using the defined connection.
    # @param
    def connect(self):

        if self.settings["connector"] not in self.connections.keys():
            gear.log("Unable to connect object", gear.sev_error)
            return False

        self.connections[self.settings["connector"]]()

        return True

    ## standard connection definition. This is a simple parenting of the root.
    # @param self
    def connect_standard(self):
        self.parent.AddChild(self.root)

    ## standard connection definition with ik and upv references.
    # @param self
    def connect_standardWithIkRef(self):
        self.parent.AddChild(self.root)

        # Set the Ik Reference
        if self.settings["ikrefarray"]:
            ref_names = self.settings["ikrefarray"].split(",")
            if len(ref_names) == 1:
                ref = self.rig.findChild(ref_names[0])
                ref.AddChild(self.ik_cns)
            else:
                for i, ref_name in enumerate(ref_names):
                    ref = self.rig.findChild(ref_name)
                    cns = self.ik_cns.Kinematics.AddConstraint(
                        "Pose", ref, True)
                    par.addExpression(cns.Parameters("active"),
                                      self.pIkRef.FullName + " == " + str(i))

        # Set the Upv Reference
        if self.settings["upvrefarray"]:
            ref_names = self.settings["upvrefarray"].split(",")
            if len(ref_names) == 1:
                ref = self.rig.findChild(ref_names[0])
                ref.AddChild(self.upv_cns)
            else:
                for i, ref_name in enumerate(ref_names):
                    ref = self.rig.findChild(ref_name)
                    cns = self.upv_cns.Kinematics.AddConstraint(
                        "Pose", ref, True)
                    par.addExpression(cns.Parameters("active"),
                                      self.pUpvRef.FullName + " == " + str(i))

    ## Post connection actions.
    # REIMPLEMENT. This method should be reimplemented in each component.\n
    # @param self
    def postConnect(self):
        return

    # =====================================================
    # FINALIZE
    # =====================================================
    def finalize(self):

        # Set the layout and logic in the ppg
        if self.ui is not None:
            self.ui.fillLayoutAndLogic()

    # =====================================================
    # MISC
    # =====================================================
    ## Return the name for component element
    # @param self
    # @param name String - Name.
    def getName(self, name="", side=None):

        if side is None:
            side = self.side

        name = str(name)

        if name:
            return self.name + "_" + side + str(self.index) + "_" + name
        else:
            return self.fullName

    # =====================================================
    # PROPERTIES
    # =====================================================
    ## return the fullname of the component
    # @param self
    def getFullName(self):
        return self.guide.fullName

    ## return the type of the component
    # @param self
    def getType(self):
        return self.guide.type

    fullName = property(getFullName)
    type = property(getType)