Пример #1
0
def inflateCurveOnMesh(crv, mesh, scale=1):

    newCrv = pm.duplicate(crv)[0]

    sel_list = om.MSelectionList()
    sel_list.add(str(crv))
    sel_list.add(str(mesh))
    sel_list.add(str(newCrv))

    DagPath, _ = sel_list.getComponent(0)

    Curve = om.MFnNurbsCurve(DagPath)
    CurveCVs = Curve.cvPositions(om.MSpace.kWorld)
    newCurveCVs = om.MPointArray()

    DagPath, _ = sel_list.getComponent(1)
    Mesh = om.MFnMesh(DagPath)
    DagPath, _ = sel_list.getComponent(2)
    newCurve = om.MFnNurbsCurve(DagPath)

    for i in range(len(CurveCVs)):
        cv = CurveCVs[i]

        normal, _ = Mesh.getClosestNormal(cv)

        x = cv.x + normal.x * scale
        y = cv.y + normal.y * scale
        z = cv.z + normal.z * scale
        newCurveCV = om.MPoint(x, y, z)

        newCurveCVs.append(newCurveCV)

    newCurve.setCVPositions(newCurveCVs)
    return newCrv
Пример #2
0
def mirrorCurveCvs(curveObj, axis="x", space=None):
    """Mirrors the the curves transform shape cvs by a axis in a specified space

    :param curveObj: The curves transform to mirror
    :type curveObj: mobject
    :param axis: the axis the mirror on, accepts: 'x', 'y', 'z'
    :type axis: str
    :param space: the space to mirror by, accepts: MSpace.kObject, MSpace.kWorld, default: MSpace.kObject
    :type space: int
    Example::
            >>>nurbsCurve = cmds.circle()[0]
            >>>mirrorCurveCvs(api.asMObject(nurbsCurve), axis='y', space=om.MSpace.kObject)
    """
    space = space or om2.MSpace.kObject

    axis = axis.lower()
    axisDict = {'x': 0, 'y': 1, 'z': 2}
    axis = axisDict[axis]

    shapes = nodes.shapes(om2.MFnDagNode(curveObj).getPath())
    for shape in shapes:
        curve = om2.MFnNurbsCurve(shape)
        cvs = curve.getCVs(space=space)
        # invert the cvs MPoints based on the axis
        for i in range(len(cvs)):
            cvs[i][axis] *= -1
        curve.setCvPositions(cvs)
        curve.updateCurve()
Пример #3
0
def find_point_on_curve_to_point_by_distance(curve, to_point, distance, error_threshold = 1.0):

	sl = om.MSelectionList()
	sl.add(curve)
	curve_fn = om.MFnNurbsCurve(sl.getDagPath(0))

	u_begin = curve_fn.getParamAtPoint(om.MPoint(to_point), space = om.MSpace.kWorld)

	max_param = curve_fn.numCVs - curve_fn.degree

	arc_length = curve_fn.findLengthFromParam(max_param)
	u_increase = error_threshold / arc_length

	param_begin = u_begin * max_param

	p_ = curve_fn.getPointAtParam(param_begin, space = om.MSpace.kWorld)
	u_ = u_begin
	while u_ < 1:
		u_param = u_ * max_param
		p = curve_fn.getPointAtParam(u_param, space = om.MSpace.kWorld)
		length = (p - p_).length()
		if abs(length - distance) <= error_threshold:
			return p, u_
		u_ += u_increase

	return p, 1.0
Пример #4
0
def getCurveData(shape, space=om2.MSpace.kObject):
    """From a given NurbsCurve shape node serialize the cvs positions, knots, degree, form rgb colours

    :param shape: MObject that represents the NurbsCurve shape
    :return: dict
    :param space:
    :type space: om2.MSpace

    Example::
        >>>nurbsCurve = cmds.circle()[1]
        # requires an MObject of the shape node
        >>>data = curve_utils.getCurveData(api.asMObject(nurbsCurve))
    """
    if isinstance(shape, om2.MObject):
        shape = om2.MFnDagNode(shape).getPath()
    data = nodes.getNodeColourData(shape.node())
    curve = om2.MFnNurbsCurve(shape)
    # so we can deserialize in world which maya does in to steps
    if space == om2.MSpace.kWorld:
        data["matrix"] = list(nodes.getWorldMatrix(curve.object()))
    data.update({
        "knots": tuple(curve.knots()),
        "cvs": map(tuple, curve.cvPositions(space)),
        "degree": curve.degree,
        "form": curve.form
    })
    return data
Пример #5
0
def iterCurvePoints(dagPath, count, space=om2.MSpace.kObject):
    """Generator Function to iterate and return the position, normal and tangent for the curve with the given point count.

    :param dagPath: the dagPath to the curve shape node
    :type dagPath: om2.MDagPath
    :param count: the point count to generate
    :type count: int
    :param space: the coordinate space to query the point data
    :type space: om2.MSpace
    :return: The first element is the Position, second is the normal, third is the tangent
    :rtype: tuple(MVector, MVector, MVector)
    """
    crvFn = om2.MFnNurbsCurve(dagPath)
    length = crvFn.length()
    dist = length / float(count - 1)  # account for end point
    current = 0.001
    maxParam = crvFn.findParamFromLength(length)
    for i in xrange(count):
        param = crvFn.findParamFromLength(current)
        # maya fails to get the normal when the param is the maxparam so we sample with a slight offset
        if param == maxParam:
            param = maxParam - 0.0001
        point = om2.MVector(crvFn.getPointAtParam(param, space=space))
        yield point, crvFn.normal(param,
                                  space=space), crvFn.tangent(param,
                                                              space=space)
        current += dist
Пример #6
0
    def compute(self, plug, dataBlock):
        if plug not in [self.outTranslate]:
            self.displayWarning(error='Unknown plug: {}'.format(plug))
            return

        curveHandle = dataBlock.inputValue(self.inputCurve)
        curveData = curveHandle.data()
        if curveData.isNull():
            return
        curveFn = om.MFnNurbsCurve(curveData)

        fractionMode = dataBlock.inputValue(self.fractionMode).asBool()
        if fractionMode:
            uValueMult = curveFn.length()
        else:
            uValueMult = 1.0

        output_arrayHandle = dataBlock.outputArrayValue(self.output)
        output_builder = output_arrayHandle.builder()
        uValueArrayHandle = dataBlock.inputArrayValue(self.uValue)
        for i in range(len(uValueArrayHandle)):
            uValueArrayHandle.jumpToPhysicalElement(i)
            index = uValueArrayHandle.elementLogicalIndex()
            outputHandle = output_builder.addElement(index)
            outTranslateHandle = outputHandle.child(self.outTranslate)

            uValue = uValueArrayHandle.inputValue().asFloat() * uValueMult
            parameter = curveFn.findParamFromLength(uValue)

            outTranslate = curveFn.getPointAtParam(parameter, space=om.MSpace.kWorld)
            outTranslateHandle.set3Float(outTranslate[0], outTranslate[1], outTranslate[2])

        output_arrayHandle.set(output_builder)
        output_arrayHandle.setAllClean()
        dataBlock.setClean(plug)
Пример #7
0
    def setScale(self, scale, cvs=False, space=None):
        """Applies the specified scale vector to the transform or the cvs

        :param space: the space to work on, eg. MSpace.kWorld
        :type scale: sequence
        :type space: int
        :param cvs: if True then the scaling vector will be applied to the cv components
        :type cvs: bool
        """
        if self.dagPath is None:
            return
        space = space or om2.MSpace.kObject
        if cvs:
            shapes = nodes.shapes(self.dagPath)
            for shape in shapes:
                curve = om2.MFnNurbsCurve(shape)
                positions = curve.cvPositions(space)
                newPositions = om2.MPointArray()
                for i in positions:
                    newPositions.append(
                        om2.MPoint(i[0] * scale[0], i[1] * scale[1],
                                   i[2] * scale[2]))
                nodes.setCurvePositions(shape.node(),
                                        newPositions,
                                        space=space)
            return

        trans = om2.MFnTransform(self.dagPath)
        trans.setScale(scale)
Пример #8
0
    def linspace_bones(self, curve, bones):
        ''' Provide matrices that are an equal distribution along a curve

        Args:
            curve (str): name of curve to get information from
            bones (list[str]): number of controls to be created for up vec of curve
        '''
        sel = om.MSelectionList()
        sel.add(curve)

        crv = om.MFnNurbsCurve()
        crv.setObject(sel.getDagPath(0))

        curve_length = crv.length()
        lengths = np.linspace(0, curve_length, len(bones))

        # create instance to control pos and rot of controls being attached
        for i, length in enumerate(lengths):
            bone = bones[i]
            poci = cmds.createNode('pointOnCurveInfo', name=bone + '_POCI')

            param = crv.findParamFromLength(length)
            if param == 0:
                param = .001
            if length == lengths[-1]:
                param -= .001

            cmds.connectAttr(curve + '.worldSpace[0]', poci + '.inputCurve')
            cmds.setAttr(poci + '.parameter', param)
            cmds.connectAttr(poci + '.position', bone + '.translate')
Пример #9
0
def iterCurvePoints(dagPath, count, space=om2.MSpace.kObject):
    """Generator Function to iterate and return the position, normal and tangent for the curve with the given point count.

    :param dagPath: the dagPath to the curve shape node
    :type dagPath: om2.MDagPath
    :param count: the point count to generate
    :type count: int
    :param space: the coordinate space to query the point data
    :type space: om2.MSpace
    :return: The first element is the Position, second is the normal, third is the tangent
    :rtype: tuple(MVector, MVector, MVector)
    """
    crvFn = om2.MFnNurbsCurve(dagPath)
    length = crvFn.length()
    dist = length / float(count - 1)  # account for end point
    current = 0.001
    maxParam = crvFn.findParamFromLength(length)
    defaultNormal = [1.0, 0.0, 0.0]
    defaultTangent = [0.0, 1.0, 0.0]
    for i in xrange(count):
        param = crvFn.findParamFromLength(current)
        # maya fails to get the normal when the param is the maxparam so we sample with a slight offset
        if param == maxParam:
            param = maxParam - 0.0001
        point = om2.MVector(crvFn.getPointAtParam(param, space=space))
        # in case where the curve is flat eg. directly up +y
        # this causes a runtimeError in which case the normal is [1.0,0.0,0.0] and tangent [0.0,1.0,0.0]
        try:
            yield point, crvFn.normal(param,
                                      space=space), crvFn.tangent(param,
                                                                  space=space)
        except RuntimeError:
            yield point, defaultNormal, defaultTangent
        current += dist
Пример #10
0
    def create(self, transform):
        """Create the maya curve."""
        curve = om2.MFnNurbsCurve()
        self.mobject = curve.create(
            self.cvs,
            self.knots,
            self.degree,
            self.form,
            False,
            False,
            transform,
        )

        name = curve.name()

        cmds.setAttr("{}.overrideRGBColors".format(name),
                     self.overrideRGBColors)
        cmds.setAttr(
            "{}.overrideColorRGB".format(name),
            self.overrideColorRGB.r,
            self.overrideColorRGB.g,
            self.overrideColorRGB.b,
        )
        cmds.setAttr("{}.overrideEnabled".format(name), self.overrideEnabled)
        cmds.setAttr("{}.useOutlinerColor".format(name), self.useOutlinerColor)
        cmds.setAttr(
            "{}.outlinerColor".format(name),
            self.outlinerColor.r,
            self.outlinerColor.g,
            self.outlinerColor.b,
        )
Пример #11
0
    def initilizeStiffness(self, dataBlock):
        """
        sets up the default stiffness params
        """

        inCurveDataHandle = dataBlock.inputValue(self.inCurve)

        mCurve = inCurveDataHandle.asNurbsCurveTransformed()
        if not mCurve: return

        # stiffness
        mfnCrv = om.MFnNurbsCurve(mCurve)
        stiffnessArrayData = dataBlock.outputArrayValue(self.stiffness)
        stiffnessDataBuilder = om.MArrayDataBuilder(dataBlock, self.stiffness,
                                                    int(mfnCrv.numCVs))

        # outputs
        outputArrayData = dataBlock.outputArrayValue(self.output)
        outputDataBuilder = om.MArrayDataBuilder(dataBlock, self.output,
                                                 int(mfnCrv.numCVs))

        for i in xrange(mfnCrv.numCVs):
            stiffnessHandler = stiffnessDataBuilder.addElement(i)
            stiffnessHandler.setFloat(0.5)
            stiffnessHandler.setClean()

            outputHandler = outputDataBuilder.addElement(i)
            outputHandler.setMVector(om.MVector(0, 0, 0))
            outputHandler.setClean()

        stiffnessArrayData.set(stiffnessDataBuilder)
        outputArrayData.set(outputDataBuilder)

        setInitMode = om.MPlug(self.thisMObject(), self.initilize)
        setInitMode.setShort(2)
Пример #12
0
def makeCurvFromPoints(cvs_array, transform_fn=None):
    """
	Generate a spline from an array of points.
	:param cvs_array:  MPointArray to generate curve from.
	:param transform_fn:  Optional argument for parenting curve under existing transform.
	:return:  TransformFn, NurbsCurveFn
	"""
    knot_vector = om2.MDoubleArray()

    # calculate knot vector
    degree = 2
    nspans = len(cvs_array) - degree
    nknots = nspans + 2 * degree - 1

    for i in range(degree - 1):
        knot_vector.append(0.0)
    for j in range(nknots - (2 * degree) + 2):
        knot_vector.append(j)
    for k in range(degree - 1):
        knot_vector.append(j)

    # create curve
    if transform_fn is None:
        transform_fn = om2.MFnTransform()
        transform_fn.create()
        # transform_fn.setName('%s_input_curv' % name)

    curvFn = om2.MFnNurbsCurve()
    curvFn.create(cvs_array, knot_vector, degree, om2.MFnNurbsCurve.kOpen,
                  False, True, transform_fn.object())

    return transform_fn, curvFn
Пример #13
0
def getPointOnCurveFromPosition(curve, point, space=om.MSpace.kWorld):
    '''
    Gets a curves point at curve from position. It will return a MPoint
    
    :param curve: Curve you want to get paremter for
    :type curve: *str* or *MObject*
    
    :param point: Point in space or Node to get MPoint from
    :type: list | MPoint

    :return: This will return the position in world space on the curve
    :rtype: MPoint
    '''
    #get dag path for curve and assign it a nurbsCurve function object
    dagPath = rigrepo.libs.transform.getDagPath(curve)
    dagPath.extendToShape()
    mFnNurbsCurve = om.MFnNurbsCurve(dagPath)

    #Check to see if point is a list or tuple object
    if not isinstance(point, list) and not isinstance(point, tuple):
        if mc.objExists(point):
            point = mc.xform(point, q=True, ws=True, t=True)

    return mFnNurbsCurve.closestPoint(om.MPoint(point[0], point[1], point[2]),
                                      space=space)[0]
Пример #14
0
    def compute(self, plug, data):

        if plug == Node.aOutCurve:

            matricesHandle = data.inputArrayValue(Node.aMatrices)
            curveHandle = data.outputValue(Node.aOutCurve)
            points = om.MPointArray()
            while True:
                mat = matricesHandle.inputValue().asMatrix()

                p = om.MPoint(0, 0, 0, 1)
                points.append(p*mat)
                p = om.MPoint(0, 0.1, 0, 1)
                points.append(p*mat)

                if not matricesHandle.next():
                    break
            
            print points
            curveDataCreator = om.MFnNurbsCurveData()
            curveData = curveDataCreator.create()
            curveFn = om.MFnNurbsCurve()
            curve = curveFn.create(
                points, range(len(points)), 1,
                om.MFnNurbsCurve.kOpen, False, False, curveData)

            curveHandle.setMObject(curveData)

            data.setClean(plug)
Пример #15
0
	def bind(self, dataBlock, curveFn, internalCurveData):
		"""extends current curve start back along its tangent, ensuring
		a static base to the curve regardless of user modification
		waste a small amount of computation, but it's trivial"""

		# get tangent at start of curve in order to extend properly
		basePoint, baseTan = curveFn.getDerivativesAtParam(0)  # MPoint, MVector

		curveCvs = curveFn.cvPositions()  # MPointArray of starting points
		curveDegree = curveFn.degree  # eventually take this into account for point generation
		curveSpans = curveFn.numSpans

		# add new points to cv array in direction of tangent
		addCvs = []
		for i in range(2 * curveDegree):
			addCvs.insert(0, basePoint + baseTan * -((i + 1) * 0.1))  # MVectors
		addPoints = om.MPointArray()
		for i in addCvs:
			point = om.MPoint(i)
			addPoints.append(point)

		newCvs = addPoints + curveCvs

		# knots
		curveKnots = curveFn.knots()  # MFloatArray
		targetLen = (curveSpans + 2 * curveDegree - 1)
		# print "current knots are {}".format(curveKnots)
		# print "current number knots is {}".format(len(curveKnots))
		# print "target number is {}".format(targetLen)

		# add 4 to existing array, and insert [0,0,0,1,2,3] at beginning
		for i in range(len(curveKnots)):
			curveKnots[i] += float(2 * curveDegree)

		for i in range(curveDegree):
			# chop off first zeroes
			curveKnots.remove(0)

		# for i in [3.0,2.0,1.0,0.0,0.0]:
		# 	curveKnots.insert(i, 0)
		endKnots = [0.0 for i in range(curveDegree)]
		# print "endZeroes are {}".format(endKnots)
		for i in range(2 * curveDegree):
			endKnots.insert(0, float(i + 1))

		for i in endKnots:
			curveKnots.insert(i, 0)

		# print "new knots are {}".format(curveKnots)
		# print "new length is {}".format(len(curveKnots))

		# we now have new points extending away from base of curve
		# second half of these will move with tangent, first half will
		# stay static

		test = om.MFnNurbsCurve()
		return test.create(newCvs, curveKnots, 3, 1, False,
		                   False, parent=internalCurveData.object())
Пример #16
0
def uniformPointsOnCurve(crv, count):
    ''' Returns evenly spaced world points along the given curve.
    '''
    crvFn = OpenMaya.MFnNurbsCurve( capi.asDagPath(crv) )
    
    step = 1.0 / (count - 1)

    points = [ _getPoint(crvFn, step * i) for i in range(count) ]
        
    return points
Пример #17
0
def curveCvs(dagPath, space=om2.MSpace.kObject):
    """Generator Function to iterate and return the position, normal and tangent for the curve with the given point count.

    :param dagPath: the dagPath to the curve shape node
    :type dagPath: om2.MDagPath
    :param space: the coordinate space to query the point data
    :type space: om2.MSpace
    :return: The first element is the Position, second is the normal, third is the tangent
    :rtype: tuple(om2.MPoint)
    """
    return om2.MFnNurbsCurve(dagPath).cvPositions(space=space)
Пример #18
0
def cluster_curve(curve, prefix=""):
    curve_shape_node = cmds.listRelatives(curve, s=True)[0]
    mfn_curve = om2.MFnNurbsCurve(get_mobject(curve_shape_node))
    clusters = []
    for i in xrange(mfn_curve.numCVs):
        cv = '{crv}.cv[{index}]'.format(crv=mfn_curve.partialPathName(),
                                        index=i)
        shape, handle = cmds.cluster(cv)
        handle = cmds.rename(handle, '{}Cluster{}_hdl'.format(prefix, i))
        clusters.append(handle)

    return clusters
Пример #19
0
def getParam(pt=[0, 0, 0], crv=None, tol=0.001):

    if crv is None:
        return

    point = om.MPoint(pt[0], pt[1], pt[2])
    curveFn = om.MFnNurbsCurve(getDag(crv))
    isOnCurve = curveFn.isPointOnCurve(point)

    if isOnCurve:
        return curveFn.getParamAtPoint(point, tol, om.MSpace.kObject)
    else:
        return curveFn.closestPoint(point, tol, om.MSpace.kObject)[1]
Пример #20
0
def get_u_param(point, curve):
    curve_shape = cmds.listRelatives(curve, s=True)[0]
    curve_mobject = get_dag_path(curve_shape)
    m_point = om2.MPoint(point)

    mfn_curve = om2.MFnNurbsCurve(curve_mobject)
    if mfn_curve.isPointOnCurve(m_point):
        parameter = mfn_curve.getParamAtPoint(m_point, space=om2.MSpace.kWorld)
    else:
        closest_point, parameter = mfn_curve.closestPoint(
            m_point, space=om2.MSpace.kWorld)

    return parameter
Пример #21
0
def align_primgen_to_surface(target_obj=None):
    """

    :return:
    """

    if not target_obj or not cmds.objExists(target_obj):
        cmds.warning("Invalid target geo given...")
        return

    source_obj = om.MGlobal.getActiveSelectionList()

    target_obj_sl = om.MSelectionList()
    target_obj_sl.add(target_obj)
    target_path = target_obj_sl.getDagPath(0)

    up_vec = None

    for i in xrange(0, source_obj.length()):

        source_path = source_obj.getDagPath(i)

        if source_path.apiType() == 110:

            source_path_shape = source_path
            source_path_shape.extendToShape()

            if source_path_shape.apiType() == 267:

                mFn_mesh = om.MFnMesh(target_path)
                mFn_curve = om.MFnNurbsCurve(source_path)

                root_cv_p = mFn_curve.cvPosition(0)

                if root_cv_p:
                    closest_n = mFn_mesh.getClosestNormal(root_cv_p)

                    if closest_n:
                        up_vec = om.MVector(closest_n[0])

                if up_vec:

                    conn = cmds.listConnections(
                        source_path_shape.partialPathName() + '.worldSpace',
                        d=True,
                        s=False)

                    if conn:
                        cmds.setAttr(conn[0] + '.firstUpVecX', up_vec[0])
                        cmds.setAttr(conn[0] + '.firstUpVecY', up_vec[1])
                        cmds.setAttr(conn[0] + '.firstUpVecZ', up_vec[2])
Пример #22
0
def linspace_curve(curve, num):
    ''' Provide matrices that are an equal distribution along a curve

    Args:
        curve (str): name of curve to get information from
        num (int): number of matrices to be returned
    Return:
         list[om.MMatrix()]: list of matrices
    '''
    sel = om.MSelectionList()
    sel.add(curve)

    crv = om.MFnNurbsCurve()
    crv.setObject(sel.getDagPath(0))

    curve_length = crv.length()
    lengths = np.linspace(0, curve_length, num)

    matrices = []
    mscs = []

    for length in lengths:
        poci = cmds.createNode('pointOnCurveInfo')
        cm = cmds.createNode('composeMatrix')
        msc = cmds.createNode('millSimpleConstraint')
        mscs.append(msc)

        param = crv.findParamFromLength(length)
        if param == 0:
            param = .001
        if length == lengths[-1]:
            param -= .001

        cmds.connectAttr(curve + '.worldSpace[0]', poci + '.inputCurve')
        cmds.setAttr(poci + '.parameter', param)
        cmds.connectAttr(poci + '.position', cm + '.inputTranslate')
        cmds.connectAttr(cm + '.outputMatrix', msc + '.inMatrix')

        aim_vec = crv.tangent(param)
        side_vec = crv.normal(param)
        up_vec = aim_vec ^ side_vec
        pos = crv.getPointAtParam(param)

        mtx = maths.vectors_to_matrix(row1=aim_vec.normal(),
                                      row2=up_vec.normal(),
                                      row3=side_vec.normal(),
                                      row4=pos)
        matrices.append(mtx)

    return matrices, mscs
Пример #23
0
    def ctrLoadJson(typeController, name, path, SFactor=1, ColorIndex=4):
        """
        Load saved controllers from json
        Args:
            typeController: controller name
            name: file name
            path: path of file
            SFactor: scale factor
            ColorIndex: color index
        Returns: fullPathName of createdController, transform matrix
        """
        controllerFile = ('%s/%s_controllers.json' % (path, name))

        # load json
        with open(controllerFile, 'r') as f:
            # json to dictionary
            controllerDict = json.load(f)

        # list with controller parameters
        ctrParameters = controllerDict[typeController][0]
        transform = OpenMaya.MObject()
        for n, ctrParam in enumerate(ctrParameters):
            curveFn = OpenMaya.MFnNurbsCurve()
            # create controller
            form = curveFn.kOpen if ctrParam[3] == 0 else curveFn.kPeriodic
            # multiplyFactor
            CVPoints = [(i[0] * SFactor, i[1] * SFactor, i[2] * SFactor)
                        for i in ctrParam[0]]
            # create curve
            curveFn.create(
                CVPoints, ctrParam[1], ctrParam[2],
                form, False, True, transform if isinstance(
                    transform, OpenMaya.MObject) else transform.node())
            # set color
            enhableColorsPlug = curveFn.findPlug('overrideEnabled', False)
            enhableColorsPlug.setBool(True)
            colorPlug = curveFn.findPlug('overrideColor', False)
            colorPlug.setInt(ColorIndex)
            newControllerDagPath = OpenMaya.MDagPath.getAPathTo(
                curveFn.object())
            if n == 0:
                transform = OpenMaya.MDagPath.getAPathTo(
                    newControllerDagPath.transform())

        # return controller name, and saved matrix transform
        return transform.fullPathName(), controllerDict[typeController][1]
Пример #24
0
def iterCurveParams(dagPath, count):
    """Generator Function to iterate and return the Parameter

    :param dagPath: the dagPath to the curve shape node
    :type dagPath: om2.MDagPath
    :param count: the Number of params to loop
    :type count: int
    :return: The curve param value
    :rtype: float
    """
    crvFn = om2.MFnNurbsCurve(dagPath)
    length = crvFn.length()
    dist = length / float(count - 1)  # account for end point
    current = 0.001
    for i in xrange(count):
        yield crvFn.findParamFromLength(current)
        current += dist
Пример #25
0
def createCurveShape(parent, data):
    """Create a specified nurbs curves based on the data

    :param parent: The transform that takes ownership of the shapes, if None is supplied then one will be created
    :type parent: MObject
    :param data: {"shapeName": {"cvs": [], "knots":[], "degree": int, "form": int, "matrix": []}}
    :type data: dict
    :return: A 2 tuple the first element is the MObject of the parent and the second is a list /
    of mobjects represents the shapes created.
    :rtype: tuple(MObject, list(MObject))
    """
    parentInverseMatrix = om2.MMatrix()
    if parent is None:
        parent = om2.MObject.kNullObj
    elif parent != om2.MObject.kNullObj:
        parentInverseMatrix = nodes.getWorldInverseMatrix(parent)

    newCurve = om2.MFnNurbsCurve()
    newShapes = []
    for shapeName, curveData in iter(data.items()):
        cvs = om2.MPointArray(
            curveData["cvs"]
        )  # om2 allows a list of lists which converts to om2.Point per element
        knots = curveData["knots"]
        degree = curveData["degree"]
        form = curveData["form"]
        enabled = curveData["overrideEnabled"]
        matrix = curveData.get("matrix")
        if matrix is not None:
            mat = om2.MMatrix(matrix)
            for i in range(len(cvs)):
                cvs[i] *= mat * parentInverseMatrix
        shape = newCurve.create(cvs, knots, degree, form, False, False, parent)
        newShapes.append(shape)
        if parent == om2.MObject.kNullObj and shape.apiType(
        ) == om2.MFn.kTransform:
            parent = shape
        if enabled:
            plugs.setPlugValue(newCurve.findPlug("overrideEnabled", False),
                               int(curveData["overrideEnabled"]))
            colours = curveData["overrideColorRGB"]
            outlinerColour = curveData.get("outlinerColor")
            nodes.setNodeColour(newCurve.object(),
                                colours,
                                outlinerColour=outlinerColour)
    return parent, newShapes
Пример #26
0
def createCurveShape(parent, data):
    """Create a specified nurbs curves based on the data

    :param parent: The transform that takes ownership of the shapes, if None is supplied then one will be created
    :type parent: MObject
    :param data: {"shapeName": {"cvs": [], "knots":[], "degree": int, "form": int, "matrix": []}}
    :type data: dict
    :return: the parent node
    :rtype: MObject
    """
    if parent is None:
        parent = om2.MObject.kNullObj
    newCurve = om2.MFnNurbsCurve()
    cvData = []
    for shapeName, curveData in iter(data.items()):
        cvs = om2.MPointArray(
            curveData["cvs"]
        )  # om2 allows a list of lists which converts to om2.Point per element
        knots = curveData["knots"]
        degree = curveData["degree"]
        form = curveData["form"]
        enabled = curveData["overrideEnabled"]
        shape = newCurve.create(cvs, knots, degree, form, False, False, parent)
        mat = curveData.get("matrix")
        if parent == om2.MObject.kNullObj and shape.apiType(
        ) == om2.MFn.kTransform:
            parent = shape
        if enabled:
            plugs.setPlugValue(newCurve.findPlug("overrideEnabled", False),
                               int(curveData["overrideEnabled"]))
            colours = curveData["overrideColorRGB"]
            nodes.setNodeColour(newCurve.object(), colours)
        if mat:
            cvData.append((newCurve.getPath(), mat, cvs))
    # apparently must use object space to create and calling setCVPosition with the forloop causing an maya error
    # this could be because maya has yet to refresh meaning the MObject is invalid , hence the need to loop
    # back over and multiple the cvs by the worldMatrix
    for p, mat, cvs in cvData:
        mat = om2.MMatrix(mat)
        newCurve.setObject(p)
        for i in range(len(cvs)):
            cvs[i] *= mat
        newCurve.setCVPositions(cvs, om2.MSpace.kWorld)
        newCurve.updateCurve()
    return parent
Пример #27
0
    def get_shape_data(curve):
        """Get all the necessary data to recreate the given curve."""
        if not curve.hasFn(om2.MFn.kNurbsCurve):
            raise TypeError(
                "curve should have the `kNurbsCurve` function set, not {}".
                format(curve.apiTypeStr))

        curve_fn = om2.MFnNurbsCurve(curve)
        name = curve_fn.name()

        knots = curve_fn.knots()
        cvs = curve_fn.cvPositions()
        form = curve_fn.form
        degree = curve_fn.degree
        overrideRGBColors = cmds.getAttr("{}.overrideRGBColors".format(name))
        overrideColorRGB = cmds.getAttr("{}.overrideColorRGB".format(name))[0]
        overrideColorRGB = Color(
            overrideColorRGB[0],
            overrideColorRGB[1],
            overrideColorRGB[2],
        )
        overrideEnabled = cmds.getAttr("{}.overrideEnabled".format(name))
        useOutlinerColor = cmds.getAttr("{}.useOutlinerColor".format(name))

        outlinerColor = cmds.getAttr("{}.outlinerColor".format(name))
        outlinerColor = Color(
            outlinerColor[0],
            outlinerColor[1],
            outlinerColor[2],
        )

        data = {
            "knots": knots,
            "cvs": cvs,
            "form": form,
            "degree": degree,
            "overrideRGBColors": overrideRGBColors,
            "overrideColorRGB": overrideColorRGB,
            "overrideEnabled": overrideEnabled,
            "useOutlinerColor": useOutlinerColor,
            "outlinerColor": outlinerColor,
        }
        return data
Пример #28
0
    def get_shape_data(self):
        """
        Gets the control nurbsCurves shapes data (points, degree, knot and periodic attributes)
        """

        curve_shape = self.get_shape()
        if not isinstance(curve_shape, collections.Iterable):
            curve_shape = (curve_shape, )

        self._shape = dict()
        for i, curve in enumerate(curve_shape):
            self._shape['shape{0}'.format(i)] = dict(degree=1, point=None, knot=None, periodic=True)
            curve_path = om.MGlobal.getSelectionListByName(curve).getDagPath(0)
            curve_fn = om.MFnNurbsCurve(curve_path)

            self._shape['shape{0}'.format(i)]['degree'] = curve_fn.degree
            self._shape['shape{0}'.format(i)]['point'] = component.get_cv_positions_from_curve(curve)
            self._shape['shape{0}'.format(i)]['knot'] = list(curve_fn.knots())
            self._shape['shape{0}'.format(i)]['periodic'] = True if curve_fn.form == curve_fn.kPeriodic else False
Пример #29
0
def applyShapeData(ctrlName,
                   crvData,
                   transOffset=(0, 0, 0),
                   rotOffset=(0, 0, 0),
                   scaleOffset=(1, 1, 1)):
    """ Applies the supplied curve data to the specified control.
    [Args]:
    ctrlName (string) - The name of the control to change
    crvData (string) - The point data to apply
    transOffset (int, int, int) - The translation offset to apply
                                  to the new crv data
    rotOffset (int, int, int) - The rotation offset to apply
                                to the new crv data
    scaleOffset (int, int, int) - The scale offset to apply
                                  to the new crv data
    """
    curveShapes = utils.getShapeNodes(ctrlName)
    ctrlMObj = api.getMObj(ctrlName)
    if curveShapes:
        for each in curveShapes:
            cmds.delete(each)
    for crvShape in crvData.keys():
        nurbsCrv = om.MFnNurbsCurve()
        cvArray = om.MPointArray()
        for i, x in enumerate(crvData[crvShape]['CVs']):
            cvArray.append((x['x'], x['y'], x['z']))
            cvArray[i] = (api.transformMPoint(cvArray[i],
                                              rot=rotOffset,
                                              trans=transOffset,
                                              scale=scaleOffset))
        knotArray = om.MDoubleArray()
        for x in crvData[crvShape]['knots']:
            knotArray.append(x)
        degree = crvData[crvShape]['degree']
        form = crvData[crvShape]['form']
        nurbsCrv.create(cvArray, knotArray, degree, form, 0, 1, ctrlMObj)
        if 'color' in crvData[crvShape].keys():
            utils.setColor(nurbsCrv.name(), color=crvData[crvShape]['color'])

    shapes = utils.getShapeNodes(ctrlName)
    for i, each in enumerate(shapes):
        cmds.rename(each, '{}Shape{}'.format(ctrlName, i + 1))
Пример #30
0
def slice_curve_by_intervals(curve,
                             intervals,
                             error_threshold=0.01,
                             begin_at_param=0,
                             use_arc_length=False):

    sl = om.MSelectionList()
    sl.add(curve)
    curve_fn = om.MFnNurbsCurve(sl.getDagPath(0))

    # use max_param/numSpans to obtain curve length for step size approximation
    # we use half of error_threshold to estimate step size
    max_param = curve_fn.numSpans
    curve_length = curve_fn.findLengthFromParam(max_param)
    u_step = max_param * (0.5 * error_threshold) / curve_length

    # we could use either arc length or linear distane func to compute the distance
    arc_len_func = lambda (s, t): curve_fn.findLengthFromParam(
        t) - curve_fn.findLengthFromParam(s)
    lin_dist_func = lambda (s, t): (curve_fn.getPointAtParam(t) - curve_fn.
                                    getPointAtParam(s)).length()
    dist_func = arc_len_func if use_arc_length else lin_dist_func

    # loop through intervals to find start and end points for each segment
    segments = []
    u_ = begin_at_param
    for distance in intervals:

        u_0 = u_
        u_ += u_step

        while u_ <= max_param:

            if abs(dist_func((u_0, u_)) - distance) < error_threshold:
                segments.append((curve_fn.getPointAtParam(u_0),
                                 curve_fn.getPointAtParam(u_)))
                break

            u_ += u_step

    return segments