def alignToPointsLoop(points=None, loc=None, name=None, *args): """Create space locator align to the plain define by at less 3 vertex Args: points (None or vertex list, optional): The reference vertex to align the ref locator loc (None or dagNode, optional): If none will create a new locator name (None or string, optional): Name of the new locator *args: Description Returns: TYPE: Description """ if not points: oSel = pm.selected(fl=True) checkType = "<class 'pymel.core.general.MeshVertex'>" if (not oSel or len(oSel) < 3 or str(type(oSel[0])) != checkType): pm.displayWarning("We need to select a points loop, with at " "less 3 or more points") return else: points = oSel if not loc: if not name: name = "axisCenterRef" loc = pm.spaceLocator(n=name) oLen = len(points) wPos = [0, 0, 0] for x in points: pos = x.getPosition(space="world") wPos[0] += pos[0] wPos[1] += pos[1] wPos[2] += pos[2] centerPosition = datatypes.Vector([wPos[0] / oLen, wPos[1] / oLen, wPos[2] / oLen]) lookat = datatypes.Vector(points[0].getPosition(space="world")) # NORMAL a = lookat - centerPosition a.normalize() nextV = datatypes.Vector(points[1].getPosition(space="world")) b = nextV - centerPosition b.normalize() normal = pmu.cross(b, a) normal.normalize() trans = transform.getTransformLookingAt( centerPosition, lookat, normal, axis="xy", negate=False) loc.setTransformation(trans)
def alignToPointsLoop(points=None, loc=None, name=None, *args): """ Create space locator align to the plain define by at less 3 vertex """ if not points: oSel = pm.selected(fl=True) if not oSel or len(oSel) < 3 or str(type( oSel[0])) != "<class 'pymel.core.general.MeshVertex'>": pm.displayWarning( "We need to select a points loop, with at less 3 or more points" ) return else: points = oSel if not loc: if not name: name = "axisCenterRef" loc = pm.spaceLocator(n=name) oLen = len(points) wPos = [0, 0, 0] for x in points: pos = x.getPosition(space="world") wPos[0] += pos[0] wPos[1] += pos[1] wPos[2] += pos[2] centerPosition = dt.Vector( [wPos[0] / oLen, wPos[1] / oLen, wPos[2] / oLen]) lookat = dt.Vector(points[0].getPosition(space="world")) # NORMAL a = lookat - centerPosition a.normalize() nextV = dt.Vector(points[1].getPosition(space="world")) b = nextV - centerPosition b.normalize() normal = pmu.cross(b, a) normal.normalize() trans = tra.getTransformLookingAt(centerPosition, lookat, normal, axis="xy", negate=False) loc.setTransformation(trans)
def getTransformLookingAt(pos, lookat, normal, axis="xy", negate=False): """Return a transformation mstrix using vector positions. Return the transformation matrix of the dagNode oriented looking to an specific point. Arguments: pos (vector): The position for the transformation lookat (vector): The aiming position to stablish the orientation normal (vector): The normal control the transformation roll. axis (str): The 2 axis used for lookat and normal. Default "xy" negate (bool): If true, invert the aiming direction. Returns: matrix: The transformation matrix >>> t = tra.getTransformLookingAt(self.guide.pos["heel"], self.guide.apos[-4], self.normal, "xz", self.negate) """ normal.normalize() if negate: a = pos - lookat else: a = lookat - pos a.normalize() c = util.cross(a, normal) c.normalize() b = util.cross(c, a) b.normalize() if axis == "xy": X = a Y = b Z = c elif axis == "xz": X = a Z = b Y = -c elif axis == "x-z": X = a Z = -b Y = c elif axis == "yx": Y = a X = b Z = -c elif axis == "yz": Y = a Z = b X = c elif axis == "zx": Z = a X = b Y = c elif axis == "z-x": Z = a X = -b Y = -c elif axis == "zy": Z = a Y = b X = -c elif axis == "x-y": X = a Y = -b Z = -c elif axis == "-xz": X = -a Z = b Y = c elif axis == "-xy": X = -a Y = b Z = c m = datatypes.Matrix() m[0] = [X[0], X[1], X[2], 0.0] m[1] = [Y[0], Y[1], Y[2], 0.0] m[2] = [Z[0], Z[1], Z[2], 0.0] m[3] = [pos[0], pos[1], pos[2], 1.0] return m