def startup(self, origin): origin.timer.stop() if psVersion == 1: origin.messageParent = MaxPlus.GetQMaxWindow() else: origin.messageParent = MaxPlus.GetQMaxMainWindow() MaxPlus.NotificationManager.Register( MaxPlus.NotificationCodes.FilePostOpenProcess, origin.sceneOpen) origin.startasThread()
def CreateMaterials(y_position): CreateText(MaxPlus.Point3(-45, y_position, 0), "Materials") x_position = 0.0 b = CreateTeapot() for m in GeneratePlugins(MaxPlus.SuperClassIds.Material, MaxPlus.Mtl): print m node = MaxPlus.Factory.CreateNode(b) node.Position = MaxPlus.Point3(x_position, y_position, 0) node.Material = m x_position += 10.0
def Mirror(node, mirrorAxis): scale = None if mirrorAxis == "X": scale = MaxPlus.Point3(-1, 1, 1) elif mirrorAxis == "Y": scale = MaxPlus.Point3(1, -1, 1) elif mirrorAxis == "Z": scale = MaxPlus.Point3(1, 1, -1) else: print("Error axis do not match") node.Scaling = scale
def show(): try: qtwindow = MaxPlus.GetQMaxWindow() except: qtwindow = MaxPlus.GetQMaxMainWindow() se = scriptEditor.scriptEditorClass(parent=qtwindow) #se.installEventFilter(MaxDialogEvents()) se.runCommand('import MaxPlus') #se.MaxEventFilter = MaxDialogEvents() #se.installEventFilter(se.MaxEventFilter) se.show()
def selectCam(self, origin): if self.isNodeValid(origin, origin.curCam): MaxPlus.SelectionManager_ClearNodeSelection() camNode = MaxPlus.INode.GetINodeByHandle(origin.curCam) if camNode.GetTarget().GetUnwrappedPtr() is not None: camNodes = MaxPlus.INodeTab() camNodes.Append(camNode) camNodes.Append(camNode.GetTarget()) MaxPlus.SelectionManager_SelectNodes(camNodes) else: MaxPlus.SelectionManager_SelectNode(camNode)
def CreateHelpers(y_position): CreateText(MaxPlus.Point3(-45, y_position, 0), "Helpers") x_position = 0.0 for obj in GeneratePlugins(MaxPlus.SuperClassIds.Helper, MaxPlus.HelperObject): node = MaxPlus.Factory.CreateNode(obj) node.Position = MaxPlus.Point3(x_position, y_position, 0) x_position += 10.0 if ((x_position % 260.0) < 0.001): x_position = 0.0 y_position += 20 return y_position
def getElements(node): obj = node.GetObject() objTriMesh = obj.AsTriObject() objMesh = objTriMesh.GetMesh() numVerts = objMesh.GetNumVertices() numFaces = objMesh.GetNumFaces() allElements = [] faces = MaxPlus.BitArray(numFaces) faces.SetAll() verts = [[] for i in range(numVerts)] for i in range(0, numFaces): face = objMesh.GetFace(i) for k in range(0, 3): verts[face.GetVert(k)].append(i) for i in range(0, numFaces): if faces[i]: element = [] element.append(i) faceBits = MaxPlus.BitArray(numFaces) vertBits = MaxPlus.BitArray(numVerts) #for j in range(0, len(element)): j = 0 while j < len(element): fi = element[j] j += 1 if not faceBits[fi]: face = objMesh.GetFace(fi) for k in range(0, 3): v = face.GetVert(k) if vertBits[v]: continue for singleFace in range(0, len(verts[v])): element.append(verts[v][singleFace]) vertBits.Set(v, True) faceBits.Set(fi, True) faces.Clear(fi) allElements.append(MaxPlus.BitArray(faceBits)) return allElements
def setKeyPRS(node): """ Set key base on the curreent TrnaformController :param node: :return: None """ transformController = getTransformControl(node) posController = transformController.GetPositionController() rotController = transformController.GetRotationController() scaleController = transformController.GetScaleController() posController.AddNewKey(MaxPlus.Now(), MaxPlus.Constants.AddkeyFlagged) rotController.AddNewKey(MaxPlus.Now(), MaxPlus.Constants.AddkeyFlagged) scaleController.AddNewKey(MaxPlus.Now(), MaxPlus.Constants.AddkeyFlagged)
def main(): obj = MaxPlus.Factory.CreateGeomObject(MaxPlus.ClassIds.Sphere) obj.ParameterBlock.Radius.Value = 50.0 node = MaxPlus.Factory.CreateNode(obj) vp = MaxPlus.ViewportManager.GetActiveViewport() hittype = MaxPlus.Constants.HittypeSolid hitflags = MaxPlus.Constants.HitAnysolid pt = MaxPlus.IPoint2(400, 200) hit = obj.HitTest(node, hittype, 1, hitflags, pt, vp) print 'hit succes', hit, 'for point', pt pt = MaxPlus.IPoint2(0, 0) hit = obj.HitTest(node, hittype, 1, hitflags, pt, vp) print 'hit success', hit, 'for point', pt
def CreateObjects(y_position): CreateText(MaxPlus.Point3(-88, y_position, 0), "Geometric objects") x_position = 0.0 for obj in GeneratePlugins(MaxPlus.SuperClassIds.GeomObject, MaxPlus.GeomObject): node = MaxPlus.Factory.CreateNode(obj) node.Position = MaxPlus.Point3(x_position, y_position, 0) x_position += 10.0 if ((x_position % 260.0) < 0.001): x_position = 0.0 y_position += 20 return y_position
def CreateModifiers(y_position): CreateText(MaxPlus.Point3(-45, y_position, 0), "Modifiers") x_position = 0.0 for m in GeneratePlugins(MaxPlus.SuperClassIds.Osm, MaxPlus.Modifier): b = CreateBox() node = MaxPlus.Factory.CreateNode(b) node.Position = MaxPlus.Point3(x_position, y_position, 0) node.AddModifier(m) x_position += 10.0 if ((x_position % 260.0) < 0.001): x_position = 0.0 y_position += 20 return y_position
def findObjectAndBake(target, dummyroot, suffix, oppositeSuffix, copyDirection): bakeSources = list(sdknode.getChildren(dummyroot)) targetChildrens = list(sdknode.getChildren(target)) targetChildrens.append(target) bakeTargets = sdkutility.findObjectBySuffix(oppositeSuffix, targetChildrens) for bakeTarget in bakeTargets: bakeSource = findBakeSource(bakeTarget, bakeSources, oppositeSuffix, suffix) if bakeSource is not None: sdkutility.RemoveScaleKeys(bakeTarget) sdkutility.AddPositionListAndConstraint(bakeTarget) SetPositionConstraintTarget(bakeSource, bakeTarget) sdkutility.AddRotationListAndConstraint(bakeTarget) SetOrientationConstraintTarget(bakeSource, bakeTarget) selectionTab = MaxPlus.INodeTab() for n in bakeTargets: selectionTab.Append(n) MaxPlus.SelectionManager.SelectNodes(selectionTab) plotFile = os.path.join(os.path.dirname(os.path.abspath(__file__)), "plot.ms") plot = open(plotFile, "r") MaxPlus.Core.EvalMAXScript(plot.read())
def CreateBone(old_node, parent_node=None, newname=None): def maxify_point3(point): return "[{}, {}, {}]".format( point.GetX(), point.GetY(), point.GetZ() ) pos_1 = maxify_point3(old_node.worldpos) pos_2 = pos_1 zaxis = "[0, 0, 1]" if old_node.children: pos_2 = maxify_point3(old_node.children[0].worldpos) if old_node.node_in_max: axis_type = old_node.node_in_max.GetBoneAxis() if axis_type == 0: zaxis = maxify_point3(MaxPlus.Point3(0, 0, 1)) else: raise Exception("Not implemented!") # generate maxscript gen_script = \ "BoneSys.createBone {} {} {}".format(pos_1, pos_2, zaxis) # try to create bone, escape on fail fbnode = MaxPlus.Core.EvalMAXScript(gen_script) if not fbnode: return None maxnode = fbnode.GetNode() maxnode.SetName(newname or old_node.node_name) return maxnode
def main(): MaxPlus.FileManager.Reset(True) w = QtWidgets.QWidget(MaxPlus.GetQMaxMainWindow(), QtCore.Qt.Dialog) _GCProtector.widgets.append(w) w.resize(250, 100) w.setWindowTitle('Spinner Test') main_layout = QtWidgets.QVBoxLayout() label = QtWidgets.QLabel("Click button to create a cylinder in the scene") main_layout.addWidget(label) spinner = QtWidgets.QSpinBox() spinner.setRange(1, 10) spinner.setValue(1) main_layout.addWidget(spinner) #spinner.valueChanged.connect(function) cylinder_btn = QtWidgets.QPushButton("Cylinder") cylinder_btn.clicked.connect(make_cylinder) main_layout.addWidget(cylinder_btn) # textEdit = QtWidgets.QLineEdit() # textEdit.setText("Edit box") # main_layout.addWidget(textEdit) w.setLayout(main_layout) w.show()
def DeleteHierarchy(node): children = GetChildren(node) tab = MaxPlus.INodeTab() for i in children: tab.Append(i) MaxPlus.INode.DeleteNodes(tab) node.Delete()
def createObject(x, y): """Create sphere object in 3dsmax""" boxObject = MaxPlus.Factory.CreateGeomObject(MaxPlus.ClassIds.Sphere) boxObject.ParameterBlock.Radius.Value = resolution / 4 boxNode = MaxPlus.Factory.CreateNode(boxObject) boxNode.Position = MaxPlus.Point3(x, y, 0) return boxNode
def execute(self, operation, in_frame=None, out_frame=None, **kwargs): """ Main hook entry point :operation: String Frame operation to perform :in_frame: int in_frame for the current context (e.g. the current shot, current asset etc) :out_frame: int out_frame for the current context (e.g. the current shot, current asset etc) :returns: Depends on operation: 'set_frame_range' - Returns if the operation was succesfull 'get_frame_range' - Returns the frame range in the form (in_frame, out_frame) """ if operation == "get_frame_range": ticks = MaxPlus.Core.EvalMAXScript("ticksperframe").GetInt() current_in = MaxPlus.Animation.GetAnimRange().Start() / ticks current_out = MaxPlus.Animation.GetAnimRange().End() / ticks return (current_in, current_out) elif operation == "set_frame_range": import MaxPlus ticks = MaxPlus.Core.EvalMAXScript("ticksperframe").GetInt() range = MaxPlus.Interval(in_frame * ticks, out_frame * ticks) MaxPlus.Animation.SetRange(range) return True
def _get_dialog_parent(self): """ Get the QWidget parent for all dialogs created through :meth:`show_dialog` :meth:`show_modal`. :return: QT Parent window (:class:`PySide.QtGui.QWidget`) """ # Older versions of Max make use of special logic in _create_dialog # to handle window parenting. If we can, though, we should go with # the more standard approach to getting the main window. if self._max_version_to_year(self._get_max_version()) > 2020: # getMAXHWND returned a float instead of a long, which was completely # unusable with PySide in 2017 to 2020, but starting 2021 # we can start using it properly. # This logic was taken from # https://help.autodesk.com/view/3DSMAX/2020/ENU/?guid=__developer_creating_python_uis_html import shiboken2 from sgtk.platform.qt import QtGui widget = QtGui.QWidget.find(pymxs.runtime.windows.getMAXHWND()) return shiboken2.wrapInstance( shiboken2.getCppPointer(widget)[0], QtGui.QMainWindow) elif self._max_version_to_year(self._get_max_version()) > 2017: # return MaxPlus.GetQMaxMainWindow() else: return super(MaxEngine, self)._get_dialog_parent()
def show(): se = scriptEditor.scriptEditorClass(parent=MaxPlus.GetQMaxWindow()) se.installEventFilter(MaxDialogEvents()) se.runCommand('import MaxPlus') se.MaxEventFilter = MaxDialogEvents() se.installEventFilter(se.MaxEventFilter) se.show()
def sm_export_exportShotcam(self, origin, startFrame, endFrame, outputName): if startFrame == endFrame: self.setFrameRange(origin, startFrame = startFrame, endFrame = endFrame + 1) else: self.setFrameRange(origin, startFrame = startFrame, endFrame = endFrame) self.executeScript(origin, "AlembicExport.CoordinateSystem = #Maya") self.executeScript(origin, "AlembicExport.CacheTimeRange = #StartEnd") self.executeScript(origin, "AlembicExport.StepFrameTime = 1") self.executeScript(origin, "AlembicExport.StartFrameTime = %s" % startFrame) self.executeScript(origin, "AlembicExport.EndFrameTime = %s" % endFrame) self.executeScript(origin, "AlembicExport.ParticleAsMesh = False") if startFrame == endFrame: self.executeScript(origin, "FbxExporterSetParam \"Animation\" False", returnVal=False) MaxPlus.Animation.SetTime(startFrame*MaxPlus.Animation.GetTicksPerFrame(), False) else: self.executeScript(origin, "FbxExporterSetParam \"Animation\" True", returnVal=False) self.selectCam(origin) MaxPlus.FileManager.ExportSelected(outputName + ".abc", True) exportFBX = self.executeScript(origin, "(classof (maxOps.getNodeByHandle %s)) != Physical" % origin.curCam) if exportFBX: self.selectCam(origin) MaxPlus.FileManager.ExportSelected(outputName + ".fbx", True) if origin.chb_convertExport.isChecked(): outputName = os.path.join(os.path.dirname(os.path.dirname(outputName)), "meter", os.path.basename(outputName)) if not os.path.exists(os.path.dirname(outputName)): os.makedirs(os.path.dirname(outputName)) self.executeScript(origin, """ sHelper = point() sHelper.name = ("SCALEOVERRIDE_%s") for obj in selection do( obj.parent = sHelper ) sVal = 0.01 sHelper.scale = [sVal, sVal, sVal] """ % MaxPlus.INode.GetINodeByHandle(origin.curCam).GetName()) self.selectCam(origin) MaxPlus.FileManager.ExportSelected(outputName + ".abc", True) if exportFBX: self.selectCam(origin) MaxPlus.FileManager.ExportSelected(outputName + ".fbx", True) self.executeScript(origin, """ for obj in selection do( if obj.parent != undefined and obj.parent.name == ("SCALEOVERRIDE_" + obj.name) do ( sVal = 1 sHelper = obj.parent sHelper.scale = [sVal, sVal, sVal] delete sHelper ) ) """) MaxPlus.SelectionManager_ClearNodeSelection(False)
def walk_material_hierarchy(cls, node): """Walks through the material hierarchy through their parameters :param node: :return: """ for p in node.ParameterBlock.Parameters: # decide what to do by looking at the parameter type of the p param param_type_name = MaxPlus.FPTypeGetName(p.GetParamType()) value = p.Value if param_type_name in ['MtlTab', 'TexmapTab']: # it contains multiple materials for i, v in enumerate(value): yield (node, p, v, i) try: v.GetName() for pp in cls.walk_material_hierarchy(v): yield pp except (RuntimeError, AttributeError): pass else: try: value.GetName() yield (node, p, value, -1) if isinstance(value, MaxPlus.MtlBase): for pp in cls.walk_material_hierarchy(value): yield pp except (RuntimeError, AttributeError): pass
def _create_login_menu(): """ Creates and displays a Shotgun user login menu. """ _delete_login_menu() mb = MaxPlus.MenuBuilder(constants.SG_MENU_LABEL) login_action = MaxPlus.ActionFactory.Create( constants.SG_MENU_ITEMS_CATEGORY, "Log In to Shotgun...", _login_user) mb.AddItem(login_action) mb.AddSeparator() jump_to_website_action = MaxPlus.ActionFactory.Create( constants.SG_MENU_ITEMS_CATEGORY, "Learn about Shotgun...", _jump_to_website) mb.AddItem(jump_to_website_action) jump_to_signup_action = MaxPlus.ActionFactory.Create( constants.SG_MENU_ITEMS_CATEGORY, "Try Shotgun for Free...", _jump_to_signup) mb.AddItem(jump_to_signup_action) main_menu = MaxPlus.MenuManager.GetMainMenu() # Add menu item at the second to last position, # which should be before "Help" menu_index = main_menu.GetNumItems() - 1 mb.Create(main_menu, menu_index)
def pywolf_sync_active_layer_models(): return if wolf_version == "": logger.log("PyWolf not available") return #first select nodes of active layer MaxPlus.SelectionManager.ClearNodeSelection() _layer = MaxPlus.LayerManager.GetCurrentLayer() _layer_name = _layer.GetName() if _layer_name == "_Problems_" or _layer_name == "_Boundaries_" or _layer_name == "_Inner_Layers_" or _layer_name == "_Middle_Layers_" or _layer_name == "_Outer_Layers_": logger.log("Could not add following Layers: _Problems_, _Boundaries_, _Inner_Layers_, _Middle_Layers_, _Outer_Layers_") return _selecting_nodes = MaxPlus.INodeTab() for _node in _layer.GetNodes(): _selecting_nodes.Append(_node) if len(_selecting_nodes) != 0: #select MaxPlus.SelectionManager.SelectNodes(_selecting_nodes) #_collada_exp_path = tmp_dir + "\W" + get_unique_name() + ".DAE" #export the scene in the format of OpenCollada _max_sxript_cmd = "exp_classes = exporterPlugin.classes \r\n\ _idx = findItem exp_classes OpenCOLLADAExporter \r\n\ if _idx != 0 do \r\n\ ( \r\n\ file_url = \"c:\\Wolf\\models.DAE\" \r\n\ exportFile (file_url) #noprompt selectedOnly:on using:exp_classes[_idx] \r\n\ )" MaxPlus.Core.EvalMAXScript(_max_sxript_cmd)
def GetMaxMainWindow(): if MAXVERSION() >= MAX2021: import qtmax return qtmax.GetQMaxMainWindow() else: import MaxPlus return MaxPlus.GetQMaxMainWindow()
def __init__(self, parent=None): base_type.__init__(self) ui_type.__init__(self) self.setupUi(self) MaxPlus.AttachQWidgetToMax(self) pb = self.pushButton pb.clicked.connect(buttonClicked)
def add_menu_item(self, menu_node, new_command): if self._NAME == 'maya': import maya.cmds as cmds elif self._NAME == 'max': import MaxPlus else: LOG.debug('CANT find software: {}'.format(self._NAME)) return sub_menu = '' for keys, item in new_command.iteritems(): if isinstance(item, dict) or isinstance(item, list): if self._NAME == 'maya': sub_menu = cmds.menuItem(p=menu_node, l=keys, sm=True) elif self._NAME == 'max': MaxPlus.MenuManager.UnregisterMenu(unicode(keys)) sub_menu = MaxPlus.MenuBuilder(keys) self.add_sub_menu.append(sub_menu) elif self._NAME == 'nuke': sub_menu = menu_node.addMenu(keys) if sub_menu and isinstance(item, list): for it in item: self.add_menu_item(sub_menu, it) elif sub_menu: self.add_menu_item(sub_menu, item) else: if self._NAME == 'maya': eval('cmds.{}'.format(item).format(menu_node)) elif self._NAME == 'max': import max_menu eval('menu_node.{}'.format(item)) elif self._NAME == 'nuke': eval('menu_node.{}'.format(item))
def _loadSpinnerDialog(self): ui_file_name = os.path.join(SubmitWindowController._get_self_dir(), SPINNER_DIALOG_FILE_NAME) SpinnerDialogType, BaseType = MaxPlus.LoadUiType(ui_file_name) class SpinnerDialog(SpinnerDialogType, BaseType): def __init__(self, parent=None): SpinnerDialogType.__init__(self, parent) BaseType.__init__(self, parent) self.setupUi(self) self.setWindowFlags(Qt.Dialog | Qt.FramelessWindowHint | Qt.WindowTitleHint) spinner_filename = os.path.join( SubmitWindowController._get_self_dir(), SPINNER_GIF_FILE_NAME) self.spinner_movie = QMovie(spinner_filename) self.spinner_movie.setScaledSize(QSize(40, 40)) self.spinner_label.setMovie(self.spinner_movie) def show(self): super(SpinnerDialog, self).show() self.spinner_movie.start() SubmitWindowController.spinner_dialog = SpinnerDialog(None)
def setFrameRange(self, origin, startFrame, endFrame): if startFrame == endFrame: QMessageBox.warning(self.core.messageParent, "Warning", "The startframe and the endframe cannot be the same in 3dsMax.") return MaxPlus.Animation.SetRange(MaxPlus.Interval(startFrame*MaxPlus.Animation.GetTicksPerFrame(), endFrame*MaxPlus.Animation.GetTicksPerFrame())) MaxPlus.Animation.SetTime(startFrame*MaxPlus.Animation.GetTicksPerFrame())
def generate_mesh_in_3dsmax(meshatom): """ @param mesh: atom mesh """ meshcls = MaxPlus.ClassIds.TriMeshGeometry geom = MaxPlus.Factory.CreateGeomObject(meshcls) tri = MaxPlus.TriObject._CastFrom(geom) verts = meshatom.verts faces = meshatom.faces mesh = tri.GetMesh() mesh.SetNumVerts(len(verts)) mesh.SetNumFaces(len(faces) / 3) for idx, v in enumerate(verts): mesh.SetVert(idx, MaxPlus.Point3(*v.pos())) for idx in range(0, len(faces), 3): face = mesh.GetFace(idx / 3) face.SetVerts(faces[idx + 0], faces[idx + 1], faces[idx + 2]) mesh.InvalidateGeomCache() mesh.InvalidateTopologyCache() MaxPlus.Factory.CreateNode(tri)
def customMaxMenu(name): if not MaxPlus.MenuManager.MenuExists(name): mb = MaxPlus.MenuBuilder(name) mb.AddItem(action) menu = mb.Create(MaxPlus.MenuManager.GetMainMenu()) else: print 'The menu ', name, ' already exists'