Quick Copy Paste For Blender Maya C4D插件

 在blender和maya之间复制粘贴,但是在作者介绍当中只给与模型的复制。复制的方式只需要在软件当中ctrl+c再到另外软件ctrl+v即可。

在插件包里有4个文件,这4个文件分别为。

1.blender 里有CopyPasteAddonB3D.py

2.Cinema4D

3.maya 里面有idTools.py

4.Readme.md

现在一一粘贴这几个文件里的代码

首先1.blender 里有CopyPasteAddonB3D.py 代码。 --------------------------------------------分割线-------------------------------------------------------

#  ##### BEGIN GPL LICENSE BLOCK #####

#  This program is free software; you can redistribute it and/or

#  modify it under the terms of the GNU General Public License

#  as published by the Free Software Foundation; either version 2

#  of the License, or (at your option) any later version.

#

#  This program is distributed in the hope that it will be useful,

#  but WITHOUT ANY WARRANTY; without even the implied warranty of

#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

#  GNU General Public License for more details.

#

#  You should have received a copy of the GNU General Public License

#  along with this program; if not, write to the Free Software Foundation,

#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

bl_info = {

    "name": "CopyPaste/ExportImport",

    "author": "IgorDmytrenko",

    "version": (1, 0, 8),

    "blender": (2, 93, 2),

    "location": "View3D > Object",

    "description": "import/export object like a copy/paste from dir",

    "warning": "",

    "category": "Object",

}

import bpy

import os

from os.path import join, normpath

import platform

# Get Temp directory --------------------- 

type_os = platform.system()

if type_os == "Windows":

user_home = os.getenv('userprofile')

else:

user_home = os.path.expanduser("~")


copypaste_dir = normpath(join("/idTools/copypaste/temp"))

dirpath = str(user_home) + copypaste_dir + "/"

if not "idTools" in os.listdir(user_home):  

    os.makedirs(dirpath)


#----------------------------------------------

class ExportObject(bpy.types.Operator):

    bl_idname = "object.export_object"

    bl_label = "Copy/Export" 

    bl_options = {'REGISTER', 'UNDO'}

    # >>>>>>>>>>>>>>> Export selected models <<<<<<<<<<<<<<< #

    def execute(self, context):

        sel = bpy.context.selected_objects

        for obj in sel:

            # deselect all meshes

            bpy.ops.object.select_all(action='DESELECT')

            # select the object

            obj.select_set(state = True)

            full_dirpath = normpath(join(dirpath + obj.name + ".obj"))

            # export object

            bpy.ops.export_scene.obj(

                filepath=full_dirpath,

                check_existing=True,

                axis_forward='-Z',

                axis_up='Y',

                filter_glob=".obj;.mtl",

                use_selection=True,

                use_animation=False,

                use_mesh_modifiers=True,

                use_edges=True,

                use_smooth_groups=False,

                use_smooth_groups_bitflags=False,

                use_normals=True,

                use_uvs=True,

                use_materials=True,

                use_triangles=False,

                use_nurbs=False,

                use_vertex_groups=False,

                use_blen_objects=True,

                group_by_object=False,

                group_by_material=False,

                keep_vertex_order=False,

                global_scale=100.0,

                path_mode='AUTO'

                )

        return {"FINISHED"}

class ImportObject(bpy.types.Operator):

    bl_idname = "object.import_object"

    bl_label = "Paste/Import" 

    bl_options = {'REGISTER', 'UNDO'}

    # >>>>>>>>>>>>>>> Import models <<<<<<<<<<<<<<< #

    def execute(self, context):

        files = os.listdir(dirpath)

        imported_list = []

        mats_lib = bpy.data.materials

        if not files:

            self.report({'INFO'}, 'Folder is empty.')

        materials = [ normpath(join(dirpath, file_in)) for file_in in files if file_in.endswith('.mtl')]

        objs = [ normpath(join(dirpath, file_in)) for file_in in files if file_in.endswith('.obj')]

        for obj in objs:

            bpy.ops.import_scene.obj(

                filepath=obj,

                filter_glob="*.obj",

                use_edges=True,

                use_smooth_groups=True,

                use_split_objects=True,

                use_split_groups=True,

                use_groups_as_vgroups=True,

                use_image_search=True,

                split_mode='ON',

                global_clamp_size=0.0,

                axis_forward='-Z',

                axis_up='Y'

                )

            os.remove(obj)


            sel = bpy.context.selected_objects


            for obj in sel:

                bpy.ops.object.select_all(action='DESELECT')

                # select the object

                obj.select_set(state = True)


                # create list for imported objects

                imported_list.append(obj.name)                   

        for mt in materials:

            os.remove(mt)


        for obj in imported_list:

            # select object by name

            sel = bpy.data.objects.get(obj)

            # deselect inside loop                      

            bpy.ops.object.select_all(action='DESELECT')     

            # select object inside loop

            sel.select_set(state=True)

            # convert scale to m

            sel.scale = (0.01, 0.01, 0.01)

            # apply transfoem

            bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)


            # get material name for selected object

            mats = sel.material_slots[0]

            #print(mats)


            if mats.material.name[-3:].isnumeric():

                print(mats.material.name[-3:])

                material_origin = mats.name.rpartition('.')


                if material_origin[0] in mats_lib: 

                    mats.material = mats_lib.get(material_origin[0])


            bpy.context.view_layer.objects.active = sel

            sel.active_material.blend_method = 'OPAQUE'

        return {"FINISHED"}

class Import_Export(bpy.types.Menu):

    # Define the " Copy Paste" menu

    bl_idname = "Import_Export"

    bl_label = "Copy Paste"


    def draw(self, context):

        layout = self.layout

        layout.operator_context = 'INVOKE_REGION_WIN'

        layout.operator("object.export_object", text = "Copy/Export")        

        layout.operator("object.import_object", text = "Paste/Import")

# Register all operators and panels

# Define "Extras" menu

def menu_func(self, context):

    lay_out = self.layout

    lay_out.operator_context = 'INVOKE_REGION_WIN'

    lay_out.separator()

    lay_out.menu("Import_Export", text = "Copy Paste")

# Register

classes = [ 

    ExportObject,

    ImportObject,

    Import_Export,

]

def register():

    from bpy.utils import register_class

    for cls in classes:

        register_class(cls)

    # Add "Extras" menu to the "Object" menu

    bpy.types.VIEW3D_MT_object.append(menu_func)


def unregister():

    bpy.types.VIEW3D_MT_object.remove(menu_func)

    from bpy.utils import unregister_class

    for cls in reversed(classes):

        unregister_class(cls)

if __name__ == "__main__":

register()

然后是3.maya 里面有idTools.py的代码  --------------------------------------------分割线-------------------------------------------------------

# -*- coding: utf-8 -*-

# title: idTools

# author: Ihor Dmytrenko

# version: 2.0.1

# Maya version: 2022+

# python: 3+

# ##### BEGIN GPL LICENSE BLOCK #####

#

#  This program is free software; you can redistribute it and/or

#  modify it under the terms of the GNU General Public License

#  as published by the Free Software Foundation; either version 2

#  of the License, or (at your option) any later version.

#

#  This program is distributed in the hope that it will be useful,

#  but WITHOUT ANY WARRANTY; without even the implied warranty of

#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

#  GNU General Public License for more details.

#

#  You should have received a copy of the GNU General Public License

#  along with this program; if not, write to the Free Software Foundation,

#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

#

# ##### END GPL LICENSE BLOCK #####

# Button for the shelf or you can put to you hotkey

'''

# Button code for idTools which should be placed on shelf or into shortcut code field, 

# if you want use UI.

from idTools import *

if __name__ == "__main__":

    try:

        wtool.deleteLater()

    except:

        pass   


    wtool = MainWindow()


    try:

        wtool.create()

        wtool.show()

    except:

        wtool.deleteLater()

# Two part of code for copy paste shortcuts, separated by # ( comments symbol)

# you should use it, if want to have just shortcut without UI.

# Paste button

from idTools import IdToolSetUtils

import importlib as ilib

tools = IdToolSetUtils()

tools.copyPaste("i")

# Copy button

from idTools import IdToolSetUtils

tools = IdToolSetUtils()

tools.copyPaste("c")

'''

#--------------------------------------------

#              Id Tool Set 

#--------------------------------------------

import os

from os.path import normpath, join

import platform

import maya.cmds as cmds

import maya.mel as mel

from PySide2 import QtCore

from PySide2 import QtWidgets

#--------------------------------------------

#              Id Tool Set FUNCTIONS

#--------------------------------------------

class IdToolSetUtils:

    '''

    utils functions for toolset

    '''

    #---------------------CATEGORY OBJECT MANIPULATION

    def copyPaste(self, a):

        type_os = platform.system()


        if type_os == "Windows":

            user_home = os.getenv('userprofile')

        else:

            user_home = os.path.expanduser("~")  

        copypaste_dir = normpath(join("/idTools/copypaste/temp"))

        dirpath = str(user_home) + copypaste_dir + "/"

        if not "idTools" in os.listdir(user_home):  

            os.makedirs(dirpath)


        pathOfFiles = dirpath  

        list = os.listdir(pathOfFiles)

        def exportObj():

            sel = cmds.ls(sl=1)

            for obj in sel:

                cmds.select(obj)

                shortName = obj.split("|")[-1]

                cmds.file(normpath(join(pathOfFiles, shortName)), type="OBJexport", exportSelected=True)

        def importObj():

            if len(list) == 0:

                cmds.warning("No files found")

            else:

                #import all .obj type files from temp folder

                for f in list:

                    if f.endswith(".obj"):

                        cmds.file(normpath(join(pathOfFiles , f)), i=True, options = 'mo=1', rdn = True)

                        os.remove(normpath(join(pathOfFiles , f)))


            # delete all .mtl type files form folders

            if len(list) != 0:

                for f in list:

                    if f.endswith(".mtl"):

                        os.remove(normpath(join(pathOfFiles, f)))

        if "i" in a: 

            importObj()

        elif "c" in a: 

            exportObj() 

        else: 

            print("Function requaried argument 'i' for import 'c' for copy")

    # copy pivot between objects

    def copyPivot(self, *args):


        sourceObj = cmds.ls(sl=True)[len(cmds.ls(sl=True))-1]

        targetObj = cmds.ls(sl=True)[0:(len(cmds.ls(sl=True))-1)]

        parentList = []


        for obj in targetObj:

            if cmds.listRelatives(obj, parent=True):

                parentList.append(cmds.listRelatives(obj, parent=True)[0])

            else:

                parentList.append('')


        if len(cmds.ls(sl = True))<2:

            cmds.error('select 2 or more objects.')


        pivotTranslate = cmds.xform (sourceObj, q=True, ws=True, rotatePivot=True)

        cmds.parent(targetObj, sourceObj)

        cmds.makeIdentity(targetObj, a=True, t=True, r=True, s=True)

        cmds.xform(targetObj, ws=True, pivots=pivotTranslate)


        for ind in range(len(targetObj)):

            if parentList[ind] != '' : 

                cmds.parent(targetObj[ind], parentList[ind])

            else:

                cmds.parent(targetObj[ind], world=True)


    # align B object by A

    def align_obj_bta(self, *args): 

        sel = cmds.ls(sl = True)

        sel_obj1 = sel[0]

        sel_obj2 = sel[1]

        cmds.parentConstraint(sel_obj1, sel_obj2)

        cmds.parentConstraint(sel_obj1, sel_obj2, e=True, rm=True)


    #---------------------CATEGORY GEOMETRY MANIPULATION


    # fast subdivide objects

    def subdivide(self, x):   

        sel = cmds.ls(sl=1)

        for obj in sel:

            cmds.select(obj)

            cmds.polySmooth(obj+".", sdt=2, dv= x )

    def delete_smooth(self):

        sel = cmds.ls(sl=1)

        for i in sel:

            obj_history = cmds.listHistory()

            for h_elem in obj_history:

                if "polySmoothFace" in h_elem:

                    sel = cmds.select(h_elem)

                    cmds.delete()

                else:

                    print("Object hasn't smooth_node")


    def mirror_object(self, axis, instance=False):

        ''' 

        This is function create mirrior od selected objects like copy or instance


        '''

        if instance is True:

            print("Mirror is Instance")

        else:

            print("Mirror is Copy")

        # нужно забирать текущее положение скейла с обьекта

        sel = cmds.ls(sl=1)

        for i in sel:

            cmds.select(i)

            x = cmds.getAttr(i+".scaleX")

            y = cmds.getAttr(i+".scaleY")

            z = cmds.getAttr(i+".scaleZ")

            if axis is "x":

                if x > 0:

                    x = x * -1

                elif x < 0:

                    x = x * -1

                else:

                    x = x

            elif axis is "y":

                if y > 0:

                    y = y * -1

                elif y < 0:

                    y = y * -1

                else:

                    y = y

            else:

                if z > 0:

                    z = z * -1

                elif z < 0:

                    z = z * -1

                else:

                    z = z  

            if instance is True:

                cmds.duplicate(smartTransform=True, renameChildren=True, instanceLeaf=True)

            else:

                cmds.duplicate(smartTransform=True, renameChildren=True) 

            cmds.scale(x,y,z, absolute=True)

            if instance is True:

                print("freeze transform is not work with instnace")

            else:

                cmds.makeIdentity(apply=True, t=0, r=0, s=1, n=0, pn=1)


    # replace selected object on copy

    def replace_to_copy(self, *args):

        sel = cmds.ls(sl=True)

        src = sel.pop(0)

        for c in sel:

            T = cmds.xform(c, q=True, ws=True, t=True)

            R = cmds.xform(c, q=True, ws=True, ro=True)

            copy = cmds.duplicate(src)[0]

            cmds.xform(copy, ws=True, t=T)

            cmds.xform(copy, ws=True, ro=R)

            cmds.delete(c)


    # replace selected object on instances

    def replace_to_instance(self, *args):


        sel = cmds.ls(sl=True)

        src = sel.pop(0)

        for c in sel:

            T = cmds.xform(c, q=True, ws=True, t=True)

            R = cmds.xform(c, q=True, ws=True, ro=True)

            inst = cmds.instance(src)[0]

            cmds.xform(inst, ws=True, t=T)

            cmds.xform(inst, ws=True, ro=R)

            cmds.delete(c)     

    def attach_detach(self, *args):

        sel = cmds.ls(sl=1) 

        if len(sel) == 1:

            cmds.polySeparate(ch=False)

            cmds.xform(centerPivots)

        else:

            cmds.polyUnite(ch=False)

    #---------------------EDIT MESH

    # edit lattice

    def lock_components(self, *args):

        sel = cmds.ls(sl=1)

        if ".pt" in sel[0]:         

                latticePt = cmds.ls(sl=1)

                for s in latticePt:

                    cmds.setAttr(s+".", c=True, lock=True )                 

        elif ".f" or ".vtx" or ".e" in sel[0]:        

                mel.eval('ConvertSelectionToVertices')

                mel.eval('invertSelection')     

                vertices = cmds.ls(sl=1)                

                for s in vertices:

                    cmds.setAttr(s+".", c=True, lock=True )

                    cmds.polyColorPerVertex(rgb=(0.5,0.1539,0), a=1, rel=0, cdo=1)                          

        else:

            print("false")


    def unlock_components(self, *args):

        sel = cmds.ls(sl=1, st=1)       

        if ".pt" in sel[0]:                         

                latticePt = cmds.ls(sl=1)               

                for s in latticePt:

                    cmds.setAttr(s+".", c=True, lock=False )                        

        elif ".vtx" in sel[0]:       

                mel.eval('ConvertSelectionToVertices')                        

                vertices = cmds.ls(sl=1)

                for s in vertices:

                    cmds.setAttr(s+".", c=True, lock=False )

                    cmds.polyColorPerVertex(rgb=(0.2,0.2,0.2), a=1, rel=0, cdo=1)                                               

        elif ".f" in sel[0]:                

                mel.eval('ConvertSelectionToVertices')                        

                vertices = cmds.ls(sl=1)                

                for s in vertices:

                    cmds.setAttr(s+".", c=True, lock=False )

                    cmds.polyColorPerVertex(rgb=(0.2,0.2,0.2), a=1, rel=0, cdo=1)                                       

        else:

            mel.eval('ConvertSelectionToVertices')

            vertices = cmds.ls(sl=1)

            for s in vertices:

                cmds.setAttr(s+".", c=True, lock=False )

                cmds.polyColorSet(delete=True, colorSet='colorSet1')

    def select_by_angle(self,*args):

        mel.eval('dR_DoCmd("selConstraintAngle")')

        mel.eval('$angleConstrainBool = 1')

        #mel.eval('dR_DoCmd("selConstraintOff")')

    #--------------------CLEAN-UP MESH


    def dell_uvcolor_set(self, *args):

        sel = cmds.ls(sl=True)

        for item in sel:

            cmds.select(item)

            uvset = cmds.polyUVSet( query=True, allUVSets=True )

            if uvset:

                for cSet in uvset[1:]:

                    cmds.polyUVSet( delete = True, uvSet = str(cSet) )

            cmds.polyNormalPerVertex( ufn = True)

            cs = cmds.polyColorSet( q = True , allColorSets = True)

            if cs:

                for cSet in cs:

                    cmds.polyColorSet( d = 1, colorSet = str(cSet) )

    #---------------------CATEGORY DISPLAY MANIPULATION


    def wireframeOnOff(self, *args):

        #check

        viewport = cmds.getPanel(withFocus=True) 

        # If 

        if "modelPanel" in viewport:

            currentState =  cmds.modelEditor(viewport, q=True, selectionHiliteDisplay=True)

        if currentState == True:

            cmds.modelEditor(viewport, edit=True, selectionHiliteDisplay=False)

        else:

            cmds.modelEditor(viewport, edit=True, selectionHiliteDisplay=True)


        return True 

    def test_print(self, *args):

        print("you drag me")

# create utils object

id_utils = IdToolSetUtils()

#--------------------------------------------

#              Id Tool Set UI

#--------------------------------------------

# create python object for maya ui

def maya_main_window():

    """Return Maya's main window"""

    # Update for maya 2020 need replace .qApp to QApplication

    for obj in QtWidgets.QApplication.topLevelWidgets():

        if obj.objectName() == 'MayaWindow':

            return obj

    raise RuntimeError('Could not find MayaWindow instance')


class MainWindow(QtWidgets.QDialog):


    # window

    def __init__( self, parent=maya_main_window()):

        super(MainWindow, self).__init__(parent)


        # set window title

        self.setWindowTitle("ID TOOL SET")

        self.setObjectName('MyWindowObj')

        self.setWindowFlags(QtCore.Qt.Window)

        self.setProperty("saveWindowPref", True)

        self.setWindowFlags(self.windowFlags() ^ QtCore.Qt.WindowContextHelpButtonHint)

        self.create_layout()

        self.create_connections()

        self.resize(210, 540)

        self.setMinimumSize(QtCore.QSize(210, 540))

        # self.setSizeIncrement(QtCore.QSize(210, 520))

        self.setBaseSize(QtCore.QSize(210, 540))

        self.setWindowOpacity(0.95)

    def create_layout(self):

        self.vLayout = QtWidgets.QVBoxLayout(self)

        self.vLayout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)

        self.vLayout.setContentsMargins(4, 4, 4, 4)

        self.vLayout.setSpacing(4)

        self.vLayout.setObjectName("vLayout")

        self.vLayout_2 = QtWidgets.QVBoxLayout()

        self.vLayout_2.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)

        self.vLayout_2.setContentsMargins(1, 1, 1, 1)

        self.vLayout_2.setSpacing(1)

        self.vLayout_2.setObjectName("vLayout_2")

        self.subdivision_lbl = QtWidgets.QGroupBox(self)

        self.subdivision_lbl.setFlat(True)

        self.subdivision_lbl.setObjectName("subdivision_lbl")

        self.vLayout_2.addWidget(self.subdivision_lbl)

        self.formLayout_6 = QtWidgets.QFormLayout()

        self.formLayout_6.setLabelAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignTop)

        self.formLayout_6.setFormAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignTop)

        self.formLayout_6.setContentsMargins(2, 4, 2, 4)

        self.formLayout_6.setObjectName("formLayout_6")

        self.lcdNumber = QtWidgets.QLCDNumber(self)

        self.lcdNumber.setFrameShape(QtWidgets.QFrame.Box)

        self.lcdNumber.setFrameShadow(QtWidgets.QFrame.Plain)

        self.lcdNumber.setLineWidth(1)

        self.lcdNumber.setMidLineWidth(0)

        self.lcdNumber.setSmallDecimalPoint(False)

        self.lcdNumber.setMode(QtWidgets.QLCDNumber.Dec)

        self.lcdNumber.setSegmentStyle(QtWidgets.QLCDNumber.Flat)

        self.lcdNumber.setObjectName("lcdNumber")

        self.formLayout_6.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.lcdNumber)

        self.formLayout_10 = QtWidgets.QFormLayout()

        self.formLayout_10.setFormAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignTop)

        self.formLayout_10.setContentsMargins(1, 0, 0, 1)

        self.formLayout_10.setObjectName("formLayout_10")

        self.subdivide_btn = QtWidgets.QPushButton(self)

        self.subdivide_btn.setLayoutDirection(QtCore.Qt.LeftToRight)

        self.subdivide_btn.setFlat(False)

        self.subdivide_btn.setObjectName("subdivide_btn")

        self.formLayout_10.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.subdivide_btn)


        self.delSmooth_btn = QtWidgets.QPushButton(self)

        self.delSmooth_btn.setLayoutDirection(QtCore.Qt.LeftToRight)

        self.delSmooth_btn.setFlat(False)

        self.delSmooth_btn.setObjectName("delSmooth_btn")

        self.formLayout_10.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.delSmooth_btn)

        self.formLayout_6.setLayout(1, QtWidgets.QFormLayout.FieldRole, self.formLayout_10)

        self.subdslider = QtWidgets.QSlider(self)

        self.subdslider.setMaximum(5)

        self.subdslider.setPageStep(5)

        self.subdslider.setOrientation(QtCore.Qt.Horizontal)

        self.subdslider.setTickPosition(QtWidgets.QSlider.TicksAbove)

        self.subdslider.setTickInterval(1)

        self.subdslider.setObjectName("subdslider")

        self.formLayout_6.setWidget(2, QtWidgets.QFormLayout.SpanningRole, self.subdslider)

        self.vLayout_2.addLayout(self.formLayout_6)

        # Select by agle

        # spacerItem = QtWidgets.QSpacerItem(40, 5, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)

        # self.vLayout_2.addItem(spacerItem)

        # self.selectByAngle = QtWidgets.QGroupBox(self)

        # self.selectByAngle.setObjectName("selectByAngle")

        # self.vLayout_2.addWidget(self.selectByAngle)

        # self.formLayout_9 = QtWidgets.QFormLayout()

        # self.formLayout_9.setContentsMargins(2, 4, 2, 4)

        # self.formLayout_9.setObjectName("formLayout_9")

        # self.angleContraintOn = QtWidgets.QCheckBox(self)

        # self.angleContraintOn.setObjectName("angleContraintOn")

        # self.formLayout_9.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.angleContraintOn)

        # self.angleValue = QtWidgets.QSpinBox(self)

        # self.angleValue.setEnabled(True)

        # self.angleValue.setMinimumSize(QtCore.QSize(150, 0))

        # self.angleValue.setObjectName("angleValue")

        # self.formLayout_9.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.angleValue)

        # self.vLayout_2.addLayout(self.formLayout_9)

        # Lock component

        self.loclcomponent_lbl = QtWidgets.QGroupBox(self)

        self.loclcomponent_lbl.setFlat(True)

        self.loclcomponent_lbl.setObjectName("loclcomponent_lbl")

        self.vLayout_2.addWidget(self.loclcomponent_lbl)

        self.formLayout_5 = QtWidgets.QFormLayout()

        self.formLayout_5.setLabelAlignment(QtCore.Qt.AlignCenter)

        self.formLayout_5.setFormAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignTop)

        self.formLayout_5.setContentsMargins(2, 4, 2, 5)

        self.formLayout_5.setObjectName("formLayout_5")

        self.lock_btn = QtWidgets.QPushButton(self)

        self.lock_btn.setObjectName("lock_btn")

        self.formLayout_5.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.lock_btn)

        self.lock_btn.clicked.connect(id_utils.lock_components)

        self.unlock_btn = QtWidgets.QPushButton(self)

        self.unlock_btn.setObjectName("unlock_btn")

        self.formLayout_5.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.unlock_btn)

        self.unlock_btn.clicked.connect(id_utils.unlock_components)

        self.vLayout_2.addLayout(self.formLayout_5)

        spacerItem1 = QtWidgets.QSpacerItem(40, 5, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)

        self.vLayout_2.addItem(spacerItem1)

        self.mirror_lbl = QtWidgets.QGroupBox(self)

        self.mirror_lbl.setEnabled(True)

        self.mirror_lbl.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu)

        self.mirror_lbl.setAcceptDrops(False)

        self.mirror_lbl.setLayoutDirection(QtCore.Qt.LeftToRight)

        self.mirror_lbl.setAutoFillBackground(False)

        self.mirror_lbl.setFlat(True)

        self.mirror_lbl.setObjectName("mirror_lbl")

        self.vLayout_2.addWidget(self.mirror_lbl)

        self.formLayout = QtWidgets.QFormLayout()

        self.formLayout.setLabelAlignment(QtCore.Qt.AlignCenter)

        self.formLayout.setFormAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignTop)

        self.formLayout.setContentsMargins(2, 4, 2, 4)

        self.formLayout.setObjectName("formLayout")

        self.instance_x_checkBox = QtWidgets.QCheckBox(self)

        self.instance_x_checkBox.setObjectName("instance_x_checkBox")

        self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.instance_x_checkBox)

        self.mirrorx_btn = QtWidgets.QPushButton(self)

        self.mirrorx_btn.setObjectName("mirrorx_btn")

        self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.mirrorx_btn)

        self.instance_y_checkBox = QtWidgets.QCheckBox(self)

        self.instance_y_checkBox.setObjectName("instance_y_checkBox")

        self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.instance_y_checkBox)

        self.mirrory_btn = QtWidgets.QPushButton(self)

        self.mirrory_btn.setObjectName("mirrory_btn")

        self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.mirrory_btn)

        self.instance_z_checkBox = QtWidgets.QCheckBox(self)

        self.instance_z_checkBox.setObjectName("instance_z_checkBox")

        self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.instance_z_checkBox)

        self.mirrorz_btn = QtWidgets.QPushButton(self)

        self.mirrorz_btn.setObjectName("mirrorz_btn")

        self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.mirrorz_btn)

        self.vLayout_2.addLayout(self.formLayout)

        spacerItem2 = QtWidgets.QSpacerItem(40, 5, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)

        self.vLayout_2.addItem(spacerItem2)

        self.objectops_lbl = QtWidgets.QGroupBox(self)

        self.objectops_lbl.setFlat(True)

        self.objectops_lbl.setObjectName("objectops_lbl")

        self.vLayout_2.addWidget(self.objectops_lbl)

        self.vLayout_2_5 = QtWidgets.QVBoxLayout()

        self.vLayout_2_5.setContentsMargins(2, 4, 2, 4)

        self.vLayout_2_5.setObjectName("vLayout_2_5")

        # Align A to B

        self.alignbtoa_btn = QtWidgets.QPushButton(self)

        self.alignbtoa_btn.setObjectName("alignbtoa_btn")

        self.alignbtoa_btn.clicked.connect(id_utils.align_obj_bta)

        self.vLayout_2_5.addWidget(self.alignbtoa_btn)

        # Copy pivot button

        self.copypivot_btn = QtWidgets.QPushButton(self)

        self.copypivot_btn.setObjectName("copypivot_btn")

        self.vLayout_2_5.addWidget(self.copypivot_btn)

        self.copypivot_btn.clicked.connect(id_utils.copyPivot)

        spacerItem3 = QtWidgets.QSpacerItem(40, 5, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)

        self.vLayout_2_5.addItem(spacerItem3)

        self.detachAttach_btn = QtWidgets.QPushButton(self)

        self.detachAttach_btn.setObjectName("detachAttach_btn")

        self.vLayout_2_5.addWidget(self.detachAttach_btn)

        self.vLayout_2.addLayout(self.vLayout_2_5)

        self.replacelbl = QtWidgets.QGroupBox(self)

        self.replacelbl.setFlat(True)

        self.replacelbl.setObjectName("replacelbl")

        self.vLayout_2.addWidget(self.replacelbl)

        self.formLayout_2 = QtWidgets.QFormLayout()

        self.formLayout_2.setSizeConstraint(QtWidgets.QLayout.SetFixedSize)

        self.formLayout_2.setLabelAlignment(QtCore.Qt.AlignCenter)

        self.formLayout_2.setFormAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignTop)

        self.formLayout_2.setContentsMargins(2, 4, 2, 5)

        self.formLayout_2.setObjectName("formLayout_2")

        # Replace to instance

        self.to_intance_btn = QtWidgets.QPushButton(self)

        self.to_intance_btn.setObjectName("to_intance_btn")

        self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.to_intance_btn)

        self.to_intance_btn.clicked.connect(id_utils.replace_to_instance)

        # Replace to copy

        self.to_copy_btn = QtWidgets.QPushButton(self)

        self.to_copy_btn.setObjectName("to_copy_btn")

        self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.to_copy_btn)

        self.to_copy_btn.clicked.connect(id_utils.replace_to_copy)

        self.vLayout_2.addLayout(self.formLayout_2)

        self.displayops_lbl = QtWidgets.QGroupBox(self)

        self.displayops_lbl.setFlat(True)

        self.displayops_lbl.setObjectName("displayops_lbl")

        self.vLayout_2.addWidget(self.displayops_lbl)

        self.vLayout_2_8 = QtWidgets.QVBoxLayout()

        self.vLayout_2_8.setContentsMargins(2, 4, 2, 4)

        self.vLayout_2_8.setObjectName("vLayout_2_8")

        # Selection hihtlight swith

        self.selection_hightlight_btn = QtWidgets.QPushButton(self)

        self.selection_hightlight_btn.setObjectName("selection_hightlight_btn")

        self.selection_hightlight_btn.clicked.connect(id_utils.wireframeOnOff)

        self.vLayout_2_8.addWidget(self.selection_hightlight_btn)

        self.vLayout_2.addLayout(self.vLayout_2_8)

        self.export_lbl = QtWidgets.QGroupBox(self)

        self.export_lbl.setEnabled(True)

        self.export_lbl.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu)

        self.export_lbl.setAcceptDrops(False)

        self.export_lbl.setLayoutDirection(QtCore.Qt.LeftToRight)

        self.export_lbl.setAutoFillBackground(False)

        self.export_lbl.setFlat(True)

        self.export_lbl.setObjectName("export_lbl")

        self.vLayout_2.addWidget(self.export_lbl)

        self.formLayout_8 = QtWidgets.QFormLayout()

        self.formLayout_8.setLabelAlignment(QtCore.Qt.AlignCenter)

        self.formLayout_8.setFormAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignTop)

        self.formLayout_8.setContentsMargins(2, 4, 2, 4)

        self.formLayout_8.setObjectName("formLayout_8")

        self.copy_btn = QtWidgets.QPushButton(self)

        self.copy_btn.setObjectName("copy_btn")

        self.formLayout_8.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.copy_btn)

        self.paste_btn = QtWidgets.QPushButton(self)

        self.paste_btn.setObjectName("paste_btn")

        self.formLayout_8.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.paste_btn)

        self.vLayout_2.addLayout(self.formLayout_8)

        self.vLayout.addLayout(self.vLayout_2)

        self.label_3 = QtWidgets.QLabel(self)

        self.label_3.setScaledContents(True)

        self.label_3.setOpenExternalLinks(True)

        self.label_3.setObjectName("label_3")

        self.vLayout.addWidget(self.label_3)

        self.vLayout.setStretch(1, 7)

        self.retranslateUi()

        self.subdslider.valueChanged['int'].connect(self.lcdNumber.display)

        QtCore.QMetaObject.connectSlotsByName(self)

    def create_connections(self):

        self.subdivide_btn.clicked.connect(self.subd_level)

        self.delSmooth_btn.clicked.connect(self.del_smooth)

        self.mirrorx_btn.clicked.connect(self.mirror_button)

        self.mirrory_btn.clicked.connect(self.mirror_button)

        self.mirrorz_btn.clicked.connect(self.mirror_button)

        self.copy_btn.clicked.connect(self.copyPaste_clicked)

        self.paste_btn.clicked.connect(self.copyPaste_clicked)

        self.detachAttach_btn.clicked.connect(self.attach_detach_clicked)


    def attach_detach_clicked(self):

        id_utils.attach_detach()

    def copyPaste_clicked(self):

        active = button = self.sender().text()

        if "Copy" in active:

            id_utils.copyPaste("c")

        else:

            id_utils.copyPaste("i")


    def subd_level(self, *args):

        subdiv_lvl = self.subdslider.value()

        id_utils.subdivide(subdiv_lvl)

    def del_smooth(self, *args):

        id_utils.delete_smooth()

    def mirror_button(self):

        button = self.sender().text()

        checkbox_x = self.instance_x_checkBox.isChecked()

        checkbox_y = self.instance_y_checkBox.isChecked()

        checkbox_z = self.instance_z_checkBox.isChecked()


        if "Mirror X" in button:

            if checkbox_x is False:

                id_utils.mirror_object("x")

            else:

                id_utils.mirror_object("x", instance=True)

            print("x")

        elif "Mirror Y" in button:

            if checkbox_y is False:

                id_utils.mirror_object("y")

            else:

                id_utils.mirror_object("y", instance=True)

            print("y")

        else:

            if checkbox_z is False: 

                id_utils.mirror_object("z")

            else:

                id_utils.mirror_object("z", instance=True)

            print("z")      

    def retranslateUi(self):

        _translate = QtCore.QCoreApplication.translate

        self.setWindowTitle(_translate("Form", "NGS981"))

        self.subdivision_lbl.setTitle(_translate("Form", "Subdivision level"))

        self.subdivide_btn.setText(_translate("Form", "Subdivide"))

        self.delSmooth_btn.setText(_translate("Form", "Delete"))

        # self.selectByAngle.setTitle(_translate("Form", "Select by Angle"))

        # self.angleContraintOn.setText(_translate("Form", "On"))

        self.loclcomponent_lbl.setTitle(_translate("Form", "Lock component"))

        self.lock_btn.setText(_translate("Form", "Lock"))

        self.unlock_btn.setText(_translate("Form", "Unlock"))

        self.mirror_lbl.setTitle(_translate("Form", "Mirror Object by pivot center"))

        self.instance_x_checkBox.setText(_translate("Form", "instance"))

        self.mirrorx_btn.setText(_translate("Form", "Mirror X"))

        self.instance_y_checkBox.setText(_translate("Form", "instance"))

        self.mirrory_btn.setText(_translate("Form", "Mirror Y"))

        self.instance_z_checkBox.setText(_translate("Form", "instance"))

        self.mirrorz_btn.setText(_translate("Form", "Mirror Z"))

        self.objectops_lbl.setTitle(_translate("Form", "Object ops"))

        self.alignbtoa_btn.setText(_translate("Form", "Align B to A"))

        self.copypivot_btn.setText(_translate("Form", "Copy Pivot"))

        self.detachAttach_btn.setText(_translate("Form", "Detach/Attach"))

        self.replacelbl.setTitle(_translate("Form", "Replace Objects "))

        self.to_intance_btn.setText(_translate("Form", "To Instance"))

        self.to_copy_btn.setText(_translate("Form", "To Copy"))

        self.displayops_lbl.setTitle(_translate("Form", "Display options"))

        self.selection_hightlight_btn.setText(_translate("Form", "Selection Highlight"))

        self.export_lbl.setTitle(_translate("Form", "Blender Copy and Paste"))

        self.copy_btn.setText(_translate("Form", "Copy"))

        self.paste_btn.setText(_translate("Form", "Paste"))

        self.label_3.setText(_translate("Form", ".I.D.©"))


if __name__ == "__main__":

  try:

      wtool.deleteLater()

  except:

      pass   


  wtool = MainWindow()


  try:

      wtool.create()

      wtool.show()

  except:

wtool.deleteLater()

最后是 4.

Readme.md的代码  --------------------------------------------分割线-------------------------------------------------------

# idTools Maya 2022+ ( python 3)

## idTools UI

Button code for idTools which should be placed on shelf or into shortcut code field, if you want use UI:

```python

from idTools import *

if __name__ == "__main__":

    try:

        wtool.deleteLater()

    except:

        pass   


    wtool = MainWindow()


    try:

        wtool.create()

        wtool.show()

    except:

        wtool.deleteLater()

```

## Quick CopyPaste shortcuts

Two part of code for copy paste shortcuts, separated by # ( comments symbol) you should use it, if want to have just shortcut without UI:

```python

# Paste button

from idTools import IdToolSetUtils

tools = IdToolSetUtils()

tools.copyPaste("i")

```

```python

# Copy button

from idTools import IdToolSetUtils

tools = IdToolSetUtils()

tools.copyPaste("c")

```

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351

推荐阅读更多精彩内容