Example #1
0
    def create(self, transform=None, as_controller=True):
        """Create a curve.

        :param transform: Name of the transform to create the curve shape under.
            If the transform does not exist, it will be created.
        :param as_controller: True to mark the curve transform as a controller.
        :return: The transform of the new curve shapes.
        """
        transform = transform or self.transform
        if not cmds.objExists(transform):
            transform = cmds.createNode("transform", name=transform)
        periodic = self.form == 2
        points = self._get_transformed_points()
        points = points + points[:self.degree] if periodic else points
        curve = cmds.curve(degree=self.degree,
                           p=points,
                           per=periodic,
                           k=self.knots)
        shape = shortcuts.get_shape(curve)
        if self.color is not None:
            cmds.setAttr("{}.overrideEnabled".format(shape), True)
            if isinstance(self.color, int):
                cmds.setAttr("{}.overrideColor".format(shape), self.color)
            else:
                cmds.setAttr("{}.overrideRGBColors".format(shape), True)
                cmds.setAttr("{}.overrideColorRGB".format(shape), *self.color)
        cmds.parent(shape, transform, r=True, s=True)
        shape = cmds.rename(shape, "{}Shape".format(transform))
        cmds.delete(curve)
        if as_controller:
            cmds.controller(transform)
        logger.info("Created curve {} for transform {}".format(
            shape, transform))
        return transform
Example #2
0
    def _set_from_curve(self, transform):
        """Store the parameters from an existing curve in the CurveShape object.

        :param transform: Transform
        """
        shape = shortcuts.get_shape(transform)
        if shape and cmds.nodeType(shape) == "nurbsCurve":
            create_attr = "{}.create".format(shape)
            connection = cmds.listConnections(create_attr, plugs=True, d=False)
            if connection:
                cmds.disconnectAttr(connection[0], create_attr)
            self.transform = transform
            self.cvs = cmds.getAttr("{}.cv[*]".format(shape))
            self.degree = cmds.getAttr("{}.degree".format(shape))
            self.form = cmds.getAttr("{}.form".format(shape))
            self.knots = get_knots(shape)
            if cmds.getAttr("{}.overrideEnabled".format(shape)):
                if cmds.getAttr("{}.overrideRGBColors".format(shape)):
                    self.color = cmds.getAttr(
                        "{}.overrideColorRGB".format(shape))[0]
                else:
                    self.color = cmds.getAttr("{}.overrideColor".format(shape))
            else:
                self.color = None
            if connection:
                cmds.connectAttr(connection[0], create_attr)
Example #3
0
def dump(curves=None, stack=False):
    """Get a data dictionary representing all the given curves.

    :param curves: Optional list of curves.
    :return: A json serializable list of dictionaries containing the data required to recreate the curves.
    """
    if curves is None:
        curves = cmds.ls(sl=True) or []
    data = []
    for node in curves:
        shape = shortcuts.get_shape(node)
        if cmds.nodeType(shape) == 'nurbsCurve':
            control = {
                'name': node,
                'cvs': cmds.getAttr('{0}.cv[*]'.format(node)),
                'degree': cmds.getAttr('{0}.degree'.format(node)),
                'form': cmds.getAttr('{0}.form'.format(node)),
                'xform': cmds.xform(node, q=True, ws=True, matrix=True),
                'knots': get_knots(node),
                'pivot': cmds.xform(node, q=True, rp=True),
                'overrideEnabled': cmds.getAttr('{0}.overrideEnabled'.format(node)),
                'overrideRGBColors': cmds.getAttr('{0}.overrideRGBColors'.format(node)),
                'overrideColorRGB': cmds.getAttr('{0}.overrideColorRGB'.format(node))[0],
                'overrideColor': cmds.getAttr('{0}.overrideColor'.format(node)),
            }
            if stack:
                control['stack'] = get_stack_count(node)
                control['parent'] = get_stack_parent(node)
            data.append(control)
    if curves:
        cmds.select(curves)
    return data
Example #4
0
def flatten(mesh=None, uvset=None):
    """Creates a mesh from the UV layout of another mesh.

    I use this to generate flattened versions of meshes from Marvelous Designer to easily use Quad
    Draw to create clean meshes and then Transfer Attributes vertex positions through UVs.

    :param mesh: Mesh to sample.
    :param uvset: UV set name
    """
    if mesh is None:
        mesh = cmds.ls(sl=True)
        if not mesh:
            raise RuntimeError("No mesh selected.")
        mesh = mesh[0]
    o_mesh = shortcuts.get_mobject(shortcuts.get_shape(mesh))
    fn_mesh = OpenMaya.MFnMesh(o_mesh)
    if uvset is None:
        uvset = fn_mesh.currentUVSetName()

    vertex_count = fn_mesh.numUVs(uvset)
    polygon_count = fn_mesh.numPolygons()
    u_array = OpenMaya.MFloatArray()
    v_array = OpenMaya.MFloatArray()
    fn_mesh.getUVs(u_array, v_array, uvset)
    vertex_array = OpenMaya.MPointArray(u_array.length())
    for i in range(u_array.length()):
        vertex_array.set(i, u_array[i], 0, -v_array[i])
    polygon_counts = OpenMaya.MIntArray(polygon_count)

    it_poly = OpenMaya.MItMeshPolygon(o_mesh)
    polygon_connects = OpenMaya.MIntArray(fn_mesh.numFaceVertices())
    face_vertex_index = 0
    while not it_poly.isDone():
        face_index = it_poly.index()
        polygon_counts[face_index] = it_poly.polygonVertexCount()

        for i in range(polygon_counts[face_index]):
            int_ptr = shortcuts.get_int_ptr()
            it_poly.getUVIndex(i, int_ptr)
            uv_index = shortcuts.ptr_to_int(int_ptr)
            polygon_connects[face_vertex_index] = uv_index
            face_vertex_index += 1
        it_poly.next()

    new_mesh = OpenMaya.MFnMesh()
    new_mesh.create(
        vertex_count,
        polygon_count,
        vertex_array,
        polygon_counts,
        polygon_connects,
        u_array,
        v_array,
    )
    new_mesh.assignUVs(polygon_counts, polygon_connects)
Example #5
0
def get_knots(curve):
    """Gets the list of knots of a curve so it can be recreated.

    :param curve: Curve to query.
    :return: A list of knot values that can be passed into the curve creation command.
    """
    curve = shortcuts.get_shape(curve)
    info = cmds.createNode('curveInfo')
    cmds.connectAttr('{0}.worldSpace'.format(curve), '{0}.inputCurve'.format(info))
    knots = cmds.getAttr('{0}.knots[*]'.format(info))
    cmds.delete(info)
    return knots
Example #6
0
def get_knots(curve):
    """Gets the list of knots of a curve so it can be recreated.

    :param curve: Curve to query.
    :return: A list of knot values that can be passed into the curve creation command.
    """
    curve = shortcuts.get_shape(curve)
    info = cmds.createNode('curveInfo')
    cmds.connectAttr('{0}.worldSpace'.format(curve),
                     '{0}.inputCurve'.format(info))
    knots = cmds.getAttr('{0}.knots[*]'.format(info))
    cmds.delete(info)
    return knots
Example #7
0
def get_or_create_blendshape_node(geometry):
    """Get the first blendshape node upstream from the given geometry or create one if
    one does not exist.

    :param geometry: Name of the geometry
    :return: The blendShape node name
    """
    geometry = shortcuts.get_shape(geometry)
    blendshape = get_blendshape_node(geometry)
    if blendshape:
        return blendshape
    else:
        return cmds.blendShape(geometry, foc=True)[0]
Example #8
0
 def set_color(self):
     """Open a dialog to set the override RGB color of the selected nodes."""
     nodes = cmds.ls(sl=True) or []
     if nodes:
         color = cmds.getAttr("{}.overrideColorRGB".format(nodes[0]))[0]
         color = QColor(color[0] * 255, color[1] * 255, color[2] * 255)
         color = QColorDialog.getColor(color, self, "Set Curve Color")
         if color.isValid():
             color = [color.redF(), color.greenF(), color.blueF()]
             for node in nodes:
                 shape = shortcuts.get_shape(node)
                 cmds.setAttr("{}.overrideEnabled".format(shape), True)
                 cmds.setAttr("{}.overrideRGBColors".format(shape), True)
                 cmds.setAttr("{}.overrideColorRGB".format(shape), *color)
Example #9
0
def get_blendshape_node(geometry):
    """Get the first blendshape node upstream from the given geometry.

    :param geometry: Name of the geometry
    :return: The blendShape node name
    """
    geometry = shortcuts.get_shape(geometry)
    history = cmds.listHistory(geometry, il=2, pdo=False) or []
    blendshapes = [
        x for x in history if cmds.nodeType(x) == "blendShape"
        and cmds.blendShape(x, q=True, g=True)[0] == geometry
    ]
    if blendshapes:
        return blendshapes[0]
    else:
        return None
Example #10
0
def get_skin_clusters(nodes):
    """Get the skinClusters attached to the specified node and all nodes in descendents.

    :param nodes: List of dag nodes.
    @return A list of the skinClusters in the hierarchy of the specified root node.
    """
    if isinstance(nodes, basestring):
        nodes = [nodes, ]
    all_skins = []
    for node in nodes:
        relatives = cmds.listRelatives(node, ad=True, path=True) or []
        relatives.insert(0, node)
        relatives = [shortcuts.get_shape(node) for node in relatives]
        for relative in relatives:
            history = cmds.listHistory(relative, pruneDagObjects=True, il=2) or []
            skins = [x for x in history if cmds.nodeType(x) == 'skinCluster']
            if skins:
                all_skins.append(skins[0])
    return list(set(all_skins))
Example #11
0
def dump(curves=None, stack=False):
    """Get a data dictionary representing all the given curves.

    :param curves: Optional list of curves.
    :return: A json serializable list of dictionaries containing the data required to recreate the curves.
    """
    if curves is None:
        curves = cmds.ls(sl=True) or []
    data = []
    for node in curves:
        shape = shortcuts.get_shape(node)
        if cmds.nodeType(shape) == 'nurbsCurve':
            control = {
                'name':
                node,
                'cvs':
                cmds.getAttr('{0}.cv[*]'.format(node)),
                'degree':
                cmds.getAttr('{0}.degree'.format(node)),
                'form':
                cmds.getAttr('{0}.form'.format(node)),
                'xform':
                cmds.xform(node, q=True, ws=True, matrix=True),
                'knots':
                get_knots(node),
                'pivot':
                cmds.xform(node, q=True, rp=True),
                'overrideEnabled':
                cmds.getAttr('{0}.overrideEnabled'.format(node)),
                'overrideRGBColors':
                cmds.getAttr('{0}.overrideRGBColors'.format(node)),
                'overrideColorRGB':
                cmds.getAttr('{0}.overrideColorRGB'.format(node))[0],
                'overrideColor':
                cmds.getAttr('{0}.overrideColor'.format(node)),
            }
            if stack:
                control['stack'] = get_stack_count(node)
                control['parent'] = get_stack_parent(node)
            data.append(control)
    if curves:
        cmds.select(curves)
    return data
Example #12
0
    def on_file_tree_context_menu(self, pos):
        index = self.file_tree_view.indexAt(pos)

        if not index.isValid():
            return

        path = self.file_model.fileInfo(index).absoluteFilePath()
        if not os.path.isfile(path) or not path.lower().endswith(".obj"):
            return

        sel = cmds.ls(sl=True)
        blendshape = bs.get_blendshape_node(sel[0]) if sel else None

        menu = QMenu()
        label = "Import as target" if blendshape else "Import"
        menu.addAction(
            QAction(label, self, triggered=self.import_selected_objs))
        if sel and shortcuts.get_shape(sel[0]):
            menu.addAction(
                QAction("Export selected",
                        self,
                        triggered=partial(export_obj, sel[0], path)))
        menu.exec_(self.file_tree_view.mapToGlobal(pos))
Example #13
0
def get_points(mesh):
    path = shortcuts.get_dag_path2(shortcuts.get_shape(mesh))
    mesh_fn = OpenMaya.MFnMesh(path)
    return mesh_fn.getPoints()
Example #14
0
def set_points(mesh, points):
    path = shortcuts.get_dag_path2(shortcuts.get_shape(mesh))
    mesh_fn = OpenMaya.MFnMesh(path)
    mesh_fn.setPoints(points)