Esempio n. 1
0
        public override bool doRelease(M3dView view)
        {
            // Scale nodes on the selection list.
            // Simple implementation that does not
            // support undo.
            MSelectionList list = new MSelectionList();

            MGlobal.getActiveSelectionList(list);
            MObject node = new MObject();

            for (MItSelectionList iter = new MItSelectionList(list); !iter.isDone; iter.next())
            {
                iter.getDependNode(node);
                MFnTransform xform;
                try
                {
                    xform = new MFnTransform(node);
                }
                catch (System.Exception)
                {
                    continue;
                }

                double[] newScale = new double[3];
                newScale[0] = mousePointGlName.x + 1;
                newScale[1] = mousePointGlName.y + 1;
                newScale[2] = mousePointGlName.z + 1;
                xform.setScale(newScale);
            }
            return(true);
        }
Esempio n. 2
0
        public void UpdateMeshSelection(TriMesh mesh)
        {
            var selected = MGlobal.activeSelectionList;
            var it       = new MItSelectionList(selected, MFn.Type.kMeshVertComponent);

            MObject vertice = new MObject();

            for (; !it.isDone; it.next())
            {
                var path = new MDagPath();
                it.getDagPath(path, vertice);
                MGlobal.displayInfo(path.fullPathName);

                if (!vertice.isNull)
                {
                    MItMeshVertex itvertex = new MItMeshVertex(path, vertice);

                    for (; !itvertex.isDone; itvertex.next())
                    {
                        int index = itvertex.index();

                        mesh.Vertices[index].Traits.SelectedFlag = 1;
                    }
                }
            }

            TriMeshUtil.GroupVertice(mesh);
        }
Esempio n. 3
0
        public void GetVerticeSelected()
        {
            var selected = MGlobal.activeSelectionList;
            var it       = new MItSelectionList(selected, MFn.Type.kMeshVertComponent);

            MObject vertice = new MObject();

            for (; !it.isDone; it.next())
            {
                var path = new MDagPath();
                it.getDagPath(path, vertice);
                MGlobal.displayInfo(path.fullPathName);

                if (!vertice.isNull)
                {
                    MItMeshVertex itvertex = new MItMeshVertex(path, vertice);

                    for (; !itvertex.isDone; itvertex.next())
                    {
                        int index = itvertex.index();

                        MGlobal.displayInfo(index.ToString() + "\n");
                    }
                }
            }
        }
Esempio n. 4
0
        public static void CreateRelativeCurve(MSelectionList selected = null, ConstantValue.SampleType st = ConstantValue.SampleType.ObjectTrans, bool reOrder = true, bool closedArc = true, string ctlName = null)
        {
            if (selected == null)
            {
                selected = BasicFunc.GetSelectedList();
            }
            List <MVector> positions = new List <MVector>();

            switch (st)
            {
            case ConstantValue.SampleType.Vert:
            {
                MItSelectionList it_selectionList = new MItSelectionList(selected);
                MVector          totalWeight      = MVector.zero;
                for (; !it_selectionList.isDone; it_selectionList.next())
                {
                    MObject  component = new MObject();
                    MDagPath item      = new MDagPath();
                    it_selectionList.getDagPath(item, component);
                    MItMeshVertex it_verts = new MItMeshVertex(item, component);
                    for (; !it_verts.isDone; it_verts.next())
                    {
                        //Debug.Log(it_verts.index().ToString());
                        MPoint  point = it_verts.position(MSpace.Space.kWorld);
                        MVector pos   = new MVector(point.x, point.y, point.z);
                        //BasicFunc.CreateLocator(pos, "vert_" + it_verts.index());
                        positions.Add(pos);
                        totalWeight += pos;
                    }
                }
                break;
            }

            case ConstantValue.SampleType.Edge:
            {
                break;
            }

            case ConstantValue.SampleType.Poly:
            {
                break;
            }

            case ConstantValue.SampleType.ObjectTrans:
            {
                foreach (MDagPath dag in selected.DagPaths())
                {
                    MFnTransform trans = new MFnTransform(dag);
                    positions.Add(trans.getTranslation(MSpace.Space.kWorld));
                }
                break;
            }
            }
            if (ctlName == null)
            {
                ctlName = "samplerCurve_00";
            }
            CreateLoopCircleByPos(positions, reOrder, closedArc, ctlName);
        }
Esempio n. 5
0
        public static void Select(MSelectionList list, bool selectInComponentMode = false)
        {
            MGlobal.setActiveSelectionList(list);

            if (selectInComponentMode)
            {
                Debug.Log("select in component mode");
                List <MSelectionList> facesListToAdd = new List <MSelectionList>();

                MItSelectionList it_selectionList = new MItSelectionList(list);
                Debug.Log("has components:" + it_selectionList.hasComponents);

                for (; !it_selectionList.isDone; it_selectionList.next())
                {
                    MObject  component = new MObject();
                    MDagPath item      = new MDagPath();
                    it_selectionList.getDagPath(item, component);

                    //Debug.Log(item.fullPathName + " has components:" + it_selectionList.hasComponents);
                    //List<int> selectedIndcies = new List<int>();
                    //MItMeshPolygon it_poly = new MItMeshPolygon(item, component);
                    if (!it_selectionList.hasComponents)
                    {
                        //Debug.Log("没有组件被选择,怀疑是一整个物体:" + item.fullPathName);
                        BasicFunc.SelectComponent(item.fullPathName, ConstantValue.PolySelectType.Facet, true);
                        facesListToAdd.Add(BasicFunc.GetSelectedList());
                    }
                    //else
                    //{
                    //    Debug.Log("有组件被选择:" + it_poly.count());
                    //}
                }
                if (facesListToAdd.Count > 0)
                {
                    MGlobal.setActiveSelectionList(list);
                    for (int i = 0; i < facesListToAdd.Count; i++)
                    {
                        MGlobal.setActiveSelectionList(facesListToAdd[i], MGlobal.ListAdjustment.kAddToList);
                    }
                }
            }
            //bool hasDag = false;

            //if (hasDag)
            //{
            //    Debug.Log("has dag length:" + list.length);
            //    foreach (MDagPath dag in list.DagPaths())
            //    {
            //        Debug.Log(dag.fullPathName);
            //    }
            //    MGlobal.setActiveSelectionList(list);
            //}
            //else
            //{
            //    Debug.Log("no dag but length:" + list.length);
            //    MGlobal.setActiveSelectionList(list);
            //}
        }
Esempio n. 6
0
        void parseArgs(MArgList args)
        {
            string         arg          = "";
            MSelectionList list         = new MSelectionList();
            bool           charNameUsed = false;
            string         charName;
            const string   charFlag     = "-c";
            const string   charFlagLong = "-char";

            for (uint i = 0; i < args.length; i++)
            {
                arg = args.asString(i);
                if (arg == charFlag || arg == charFlagLong)
                {
                    // get the char name
                    //
                    if (i == args.length - 1)
                    {
                        arg += ": must specify a character name";
                        throw new ArgumentException(arg, "args");
                    }
                    i++;
                    charName = args.asString(i);
                    list.add(charName);

                    charNameUsed = true;
                }
                else
                {
                    arg += ": unknown argument";
                    throw new ArgumentException(arg, "args");
                }
            }

            if (charNameUsed)
            {
                // get the character corresponding to the node name
                //
                MItSelectionList iter = new MItSelectionList(list);
                for (; iter.isDone; iter.next())
                {
                    MObject node = new MObject();
                    iter.getDependNode(node);
                    if (node.apiType == MFn.Type.kCharacter)
                    {
                        fCharacter = node;
                        break;
                    }
                }

                if (fCharacter.isNull)
                {
                    throw new ApplicationException("Unable to get the character corresponding to the node name.");
                }
            }
        }
Esempio n. 7
0
		void parseArgs(MArgList args)
		{
			string arg = "";
			MSelectionList list = new MSelectionList();
			bool charNameUsed = false;
			string charName;
			const string charFlag = "-c";
			const string charFlagLong = "-char";

			for (uint i = 0; i < args.length; i++)
			{
				arg = args.asString(i);
				if (arg == charFlag || arg == charFlagLong)
				{
					// get the char name
					//
					if (i == args.length - 1)
					{
						arg += ": must specify a character name";
						throw new ArgumentException(arg, "args"); 
					}
					i++;
					charName = args.asString(i);
					list.add(charName);

					charNameUsed = true;
				}
				else
				{
					arg += ": unknown argument";
					throw new ArgumentException(arg, "args"); 
				}
			}

			if (charNameUsed)
			{
				// get the character corresponding to the node name
				//
				MItSelectionList iter = new MItSelectionList(list);
				for (; iter.isDone; iter.next())
				{
					MObject node = new MObject();
					iter.getDependNode(node);
					if (node.apiType == MFn.Type.kCharacter)
					{
						fCharacter = node;
						break;
					}
				}

				if (fCharacter.isNull)
				{
					throw new ApplicationException("Unable to get the character corresponding to the node name.");
				}
			}
		}
        // Switching to 3D preview
        private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            e.Handled = true;
            if (TabControl1.SelectedIndex == 1)                 // If the result view was selected
            {
                if (!ResultGrid.HasItems)
                {
                    SearchButton_Click(null, null);
                }
                return;
            }
            if (TabControl1.SelectedIndex == 2)                 // If the 3D view was selected
            {
                ResetUpAxis();
                ResetCamera();
                ResetLights();

                // Reset the model & transform(s)
                this.model.Children.Clear();
                //var selected = GetFirstSelected ();
                //// The reason why there might not be a selection is if some tool isn't closed
                //// and prevent the previous selection command from going through
                //if ( selected != null ) {
                //    // If it's a mesh, display it
                //    if ( selected.node.apiTypeStr == "kMesh" ) {
                //        var mesh = new MFnMesh (selected);
                //        // This can take some time, so change the cursor
                //        using ( new CursorSwitcher (null) ) {
                //            model.Children.Add (MakeVisualModel (mesh));
                //        }
                //    }
                //}
                using (new CursorSwitcher(null)) {
                    _singleMeshPreviewed = MGlobal.activeSelectionList.length == 1;
                    MItSelectionList it = new MItSelectionList(MGlobal.activeSelectionList);
                    for ( ; !it.isDone; it.next())
                    {
                        MDagPath path = new MDagPath();
                        it.getDagPath(path);
                        if (path.node.apiTypeStr == "kMesh")
                        {
                            model.Children.Add(MakeVisualModel(path));
                        }
                    }
                }
                return;
            }
        }
Esempio n. 9
0
        /*!
         * Callback that creates the manipulator if valid geometry is
         * selected. Also removes the manipulator if no geometry is
         * selected. Handles connecting the manipulator to multiply
         * selected nodes.
         *
         * \param[in] data Pointer to the current context class.
         */
        void updateManipulators()
        {
            deleteManipulators();

            if (!validGeometrySelected())
            {
                return;
            }

            // Clear info
            owner = null;
            firstObjectSelected = MObject.kNullObj;

            MSelectionList list = new MSelectionList();

            MGlobal.getActiveSelectionList(list);
            MItSelectionList iter = new MItSelectionList(list, MFn.Type.kInvalid);

            string             manipName   = "lineManipContainerCSharp";
            MObject            manipObject = new MObject();
            lineManipContainer manipulator = MPxManipContainer.newManipulator(manipName, manipObject) as lineManipContainer;

            if (null != manipulator)
            {
                // Save state
                owner = manipulator;
                // Add the manipulator
                addManipulator(manipObject);
                //
                for (; !iter.isDone; iter.next())
                {
                    MObject dependNode = new MObject();
                    iter.getDependNode(dependNode);
                    MFnDependencyNode dependNodeFn = new MFnDependencyNode(dependNode);
                    // Connect the manipulator to the object in the selection list.
                    manipulator.connectToDependNode(dependNode);
                    //
                    if (MObject.kNullObj == firstObjectSelected)
                    {
                        firstObjectSelected = dependNode;
                    }
                }

                // Allow the manipulator to set initial state
                setInitialState();
            }
        }
Esempio n. 10
0
        //! Ensure that valid geometry is selected
        bool validGeometrySelected()
        {
            MSelectionList list = new MSelectionList();

            MGlobal.getActiveSelectionList(list);
            MItSelectionList iter = new MItSelectionList(list, MFn.Type.kInvalid);

            for (; !iter.isDone; iter.next())
            {
                MObject dependNode = new MObject();
                iter.getDependNode(dependNode);
                if (dependNode.isNull || !dependNode.hasFn(MFn.Type.kTransform))
                {
                    MGlobal.displayWarning("Object in selection list is not right type of node");
                    return(false);
                }

                MFnDependencyNode dependNodeFn   = new MFnDependencyNode(dependNode);
                MStringArray      attributeNames = new MStringArray();
                attributeNames.append("scaleX");
                attributeNames.append("translateX");

                int i;
                for (i = 0; i < attributeNames.length; i++)
                {
                    MPlug plug = dependNodeFn.findPlug(attributeNames[i]);
                    if (plug.isNull)
                    {
                        MGlobal.displayWarning("Object cannot be manipulated: " +
                                               dependNodeFn.name);
                        return(false);
                    }
                }
            }
            return(true);
        }
Esempio n. 11
0
        public static void updateManipulators(RotateManipContext ctx)
        {
            if (ctx == null)
                return;

            ctx.deleteManipulators();

            // Add the rotate manipulator to each selected object.  This produces 
            // behavior different from the default rotate manipulator behavior.  Here,
            // a distinct rotate manipulator is attached to every object.
            // 
            try
            {
                MSelectionList list = MGlobal.activeSelectionList;

                MItSelectionList iter = new MItSelectionList(list, MFn.Type.kInvalid);
                for (; !iter.isDone; iter.next())
                {

                    // Make sure the selection list item is a depend node and has the
                    // required plugs before manipulating it.
                    //
                    MObject dependNode = new MObject();
                    iter.getDependNode(dependNode);
                    if (dependNode.isNull || !dependNode.hasFn(MFn.Type.kDependencyNode))
                    {
                        MGlobal.displayWarning("Object in selection list is not a depend node.");
                        continue;
                    }

                    MFnDependencyNode dependNodeFn = new MFnDependencyNode(dependNode);
                    try
                    {
                        /* MPlug rPlug = */
                        dependNodeFn.findPlug("rotate");
                    }
                    catch (System.Exception)
                    {
                        MGlobal.displayWarning("Object cannot be manipulated: " + dependNodeFn.name);
                        continue;
                    }

                    // Add manipulator to the selected object
                    //
                    MObject manipObject = new MObject();

                    exampleRotateManip manipulator;
                    try
                    {
                        manipulator = exampleRotateManip.newManipulator("exampleRotateManipCSharp", manipObject) as exampleRotateManip;

                        // Add the manipulator
                        //
                        ctx.addManipulator(manipObject);

                        // Connect the manipulator to the object in the selection list.
                        //
                        try
                        {
                            manipulator.connectToDependNode(dependNode);
                        }
                        catch (System.Exception)
                        {
                            MGlobal.displayWarning("Error connecting manipulator to object: " + dependNodeFn.name);
                        }
                    }
                    catch (System.Exception)
                    {

                    }
                }
            }
            catch (System.Exception)
            {

            }

        }
Esempio n. 12
0
        public static void updateManipulators(RotateManipContext ctx)
        {
            if (ctx == null)
            {
                return;
            }

            ctx.deleteManipulators();

            // Add the rotate manipulator to each selected object.  This produces
            // behavior different from the default rotate manipulator behavior.  Here,
            // a distinct rotate manipulator is attached to every object.
            //
            try
            {
                MSelectionList list = MGlobal.activeSelectionList;

                MItSelectionList iter = new MItSelectionList(list, MFn.Type.kInvalid);
                for (; !iter.isDone; iter.next())
                {
                    // Make sure the selection list item is a depend node and has the
                    // required plugs before manipulating it.
                    //
                    MObject dependNode = new MObject();
                    iter.getDependNode(dependNode);
                    if (dependNode.isNull || !dependNode.hasFn(MFn.Type.kDependencyNode))
                    {
                        MGlobal.displayWarning("Object in selection list is not a depend node.");
                        continue;
                    }

                    MFnDependencyNode dependNodeFn = new MFnDependencyNode(dependNode);
                    try
                    {
                        /* MPlug rPlug = */
                        dependNodeFn.findPlug("rotate");
                    }
                    catch (System.Exception)
                    {
                        MGlobal.displayWarning("Object cannot be manipulated: " + dependNodeFn.name);
                        continue;
                    }

                    // Add manipulator to the selected object
                    //
                    MObject manipObject = new MObject();

                    exampleRotateManip manipulator;
                    try
                    {
                        manipulator = exampleRotateManip.newManipulator("exampleRotateManipCSharp", manipObject) as exampleRotateManip;

                        // Add the manipulator
                        //
                        ctx.addManipulator(manipObject);

                        // Connect the manipulator to the object in the selection list.
                        //
                        try
                        {
                            manipulator.connectToDependNode(dependNode);
                        }
                        catch (System.Exception)
                        {
                            MGlobal.displayWarning("Error connecting manipulator to object: " + dependNodeFn.name);
                        }
                    }
                    catch (System.Exception)
                    {
                    }
                }
            }
            catch (System.Exception)
            {
            }
        }
Esempio n. 13
0
		//! Ensure that valid geometry is selected
		bool validGeometrySelected()
		{
			MSelectionList list = new MSelectionList();
			MGlobal.getActiveSelectionList(list);
			MItSelectionList iter = new MItSelectionList(list, MFn.Type.kInvalid);

			for (; !iter.isDone; iter.next())
			{
				MObject dependNode = new MObject();
				iter.getDependNode(dependNode);
				if (dependNode.isNull || !dependNode.hasFn(MFn.Type.kTransform))
				{
					MGlobal.displayWarning("Object in selection list is not right type of node");
					return false;
				}

				MFnDependencyNode dependNodeFn = new MFnDependencyNode(dependNode);
				MStringArray attributeNames = new MStringArray();
				attributeNames.append("scaleX");
				attributeNames.append("translateX");

				int i;
				for ( i = 0; i < attributeNames.length; i++ )
				{
					MPlug plug = dependNodeFn.findPlug(attributeNames[i]);
					if ( plug.isNull )
					{
						MGlobal.displayWarning("Object cannot be manipulated: " +
							dependNodeFn.name);
						return false;
					}
				}
			}
			return true;
		}
Esempio n. 14
0
		/*!
		  Callback that creates the manipulator if valid geometry is
		  selected. Also removes the manipulator if no geometry is
		  selected. Handles connecting the manipulator to multiply
		  selected nodes.

		  \param[in] data Pointer to the current context class.
		*/
		void updateManipulators()
		{
			deleteManipulators();

			if ( ! validGeometrySelected() )
			{
				return;
			}

			// Clear info
			owner = null;
			firstObjectSelected = MObject.kNullObj;

			MSelectionList list = new MSelectionList();
			MGlobal.getActiveSelectionList(list);
			MItSelectionList iter = new MItSelectionList(list, MFn.Type.kInvalid);

			string manipName = "lineManipContainerCSharp";
			MObject manipObject = new MObject();
			lineManipContainer manipulator = MPxManipContainer.newManipulator(manipName, manipObject) as lineManipContainer;

			if (null != manipulator)
			{
				// Save state
				owner = manipulator;
				// Add the manipulator
				addManipulator(manipObject);
				//
				for (; !iter.isDone; iter.next())
				{
					MObject dependNode = new MObject();
					iter.getDependNode(dependNode);
					MFnDependencyNode dependNodeFn = new MFnDependencyNode(dependNode);
					// Connect the manipulator to the object in the selection list.
					manipulator.connectToDependNode(dependNode);
					//
					if (MObject.kNullObj == firstObjectSelected)
					{
						firstObjectSelected = dependNode;
					}
				}

				// Allow the manipulator to set initial state
				setInitialState();
			}
		}
Esempio n. 15
0
        public static StaticObject Create()
        {
            MDagPath         meshDagPath       = new MDagPath();
            MItSelectionList selectionIterator = MayaHelper.GetActiveSelectionListIterator(MFn.Type.kMesh);

            selectionIterator.getDagPath(meshDagPath);
            MFnMesh mesh = new MFnMesh(meshDagPath);

            selectionIterator.next();
            if (!selectionIterator.isDone)
            {
                MGlobal.displayError("StaticObject:Create - More than 1 mesh is selected");
                throw new Exception("StaticObject:Create - More than 1 mesh is selected");
            }

            if (!mesh.IsTriangulated())
            {
                MGlobal.displayError("StaticObject:Create - Mesh isn't triangulated");
                throw new Exception("StaticObject:Create - Mesh isn't triangulated");
            }
            if (mesh.ContainsHoles())
            {
                MGlobal.displayError("StaticObject:Create - Mesh Contains holes");
                throw new Exception("StaticObject:Create - Mesh Contains holes");
            }

            MayaMeshData             meshData    = mesh.GetMeshData();
            Dictionary <int, string> shaderNames = new Dictionary <int, string>();
            List <StaticObjectFace>  faces       = new List <StaticObjectFace>();

            //Build Shader Name map
            for (int i = 0; i < meshData.ShaderIndices.Count; i++)
            {
                int shaderIndex = meshData.ShaderIndices[i];

                if (!shaderNames.ContainsKey(shaderIndex))
                {
                    MPlug      shaderPlug = new MFnDependencyNode(meshData.Shaders[shaderIndex]).findPlug("surfaceShader");
                    MPlugArray plugArray  = new MPlugArray();

                    shaderPlug.connectedTo(plugArray, true, false);

                    MFnDependencyNode material = new MFnDependencyNode(shaderPlug[0].node);

                    shaderNames.Add(shaderIndex, material.name);
                }
            }

            //Construct faces
            int currentIndex = 0;

            for (int polygonIndex = 0; polygonIndex < mesh.numPolygons; polygonIndex++)
            {
                int    shaderIndex = meshData.ShaderIndices[polygonIndex];
                uint[] faceIndices =
                {
                    (uint)meshData.TriangleVertices[currentIndex],
                    (uint)meshData.TriangleVertices[currentIndex + 1],
                    (uint)meshData.TriangleVertices[currentIndex + 2]
                };
                Vector2[] uvs =
                {
                    new Vector2(meshData.UArray[currentIndex],         1 - meshData.VArray[currentIndex]),
                    new Vector2(meshData.UArray[currentIndex + 1], 1 - meshData.VArray[currentIndex + 1]),
                    new Vector2(meshData.UArray[currentIndex + 2], 1 - meshData.VArray[currentIndex + 2])
                };


                faces.Add(new StaticObjectFace(faceIndices, shaderNames[shaderIndex], uvs));
                currentIndex += 3;
            }

            return(new StaticObject(CreateSubmeshes(meshData.VertexArray.ToVector3List(), new List <ColorRGBA4B>(), faces)));
        }
Esempio n. 16
0
		public override bool doRelease(M3dView view)
		{
			// Scale nodes on the selection list.
			// Simple implementation that does not
			// support undo.
			MSelectionList list = new MSelectionList();
			MGlobal.getActiveSelectionList(list);
			MObject node = new MObject();
			for (MItSelectionList iter = new MItSelectionList(list); !iter.isDone; iter.next())
			{
				iter.getDependNode(node);
				MFnTransform xform;
				try
				{
					xform = new MFnTransform(node);
				}
				catch (System.Exception)
				{
					continue;
				}

				double[] newScale = new double[3];
				newScale[0] = mousePointGlName.x + 1;
				newScale[1] = mousePointGlName.y + 1;
				newScale[2] = mousePointGlName.z + 1;
				xform.setScale(newScale);
			}
			return true;
		}
Esempio n. 17
0
        public void UpdateMeshSelection(TriMesh mesh)
        {
            var selected = MGlobal.activeSelectionList;
            var it = new MItSelectionList(selected, MFn.Type.kMeshVertComponent);

            MObject vertice = new MObject();
            for (; !it.isDone; it.next())
            {

                var path = new MDagPath();
                it.getDagPath(path, vertice);
                MGlobal.displayInfo(path.fullPathName);

                if (!vertice.isNull)
                {

                    MItMeshVertex itvertex = new MItMeshVertex(path, vertice);

                    for (; !itvertex.isDone; itvertex.next())
                    {
                        int index = itvertex.index();

                        mesh.Vertices[index].Traits.SelectedFlag = 1;
                    }

                }

            }

            TriMeshUtil.GroupVertice(mesh);

        }
        // Switching to 3D preview
        private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            e.Handled =true ;
            if ( TabControl1.SelectedIndex == 1 ) { // If the result view was selected
                if ( !ResultGrid.HasItems )
                    SearchButton_Click (null, null) ;
                return ;
            }
            if ( TabControl1.SelectedIndex == 2 ) { // If the 3D view was selected
                ResetUpAxis () ;
                ResetCamera () ;
                ResetLights () ;

                // Reset the model & transform(s)
                this.model.Children.Clear () ;
                //var selected = GetFirstSelected ();
                //// The reason why there might not be a selection is if some tool isn't closed
                //// and prevent the previous selection command from going through
                //if ( selected != null ) {
                //    // If it's a mesh, display it
                //    if ( selected.node.apiTypeStr == "kMesh" ) {
                //        var mesh = new MFnMesh (selected);
                //        // This can take some time, so change the cursor
                //        using ( new CursorSwitcher (null) ) {
                //            model.Children.Add (MakeVisualModel (mesh));
                //        }
                //    }
                //}
                using ( new CursorSwitcher (null) ) {
                    _singleMeshPreviewed =MGlobal.activeSelectionList.length == 1 ;
                    MItSelectionList it =new MItSelectionList (MGlobal.activeSelectionList) ;
                    for ( ; !it.isDone ; it.next () ) {
                        MDagPath path =new MDagPath () ;
                        it.getDagPath (path) ;
                        if ( path.node.apiTypeStr == "kMesh" )
                            model.Children.Add (MakeVisualModel (path)) ;
                    }
                }
                return ;
            }
        }
Esempio n. 19
0
       public void GetVerticeSelected()
       { 
           var selected = MGlobal.activeSelectionList;
           var it = new MItSelectionList(selected,MFn.Type.kMeshVertComponent);

           MObject vertice=new MObject();
           for(; !it.isDone; it.next())
		   {
             
                var path = new MDagPath();
                it.getDagPath(path,vertice);
                MGlobal.displayInfo(path.fullPathName);

                if (!vertice.isNull)
                {

                    MItMeshVertex itvertex = new MItMeshVertex(path, vertice);

                    for (; !itvertex.isDone; itvertex.next())
                    {
                           int index=  itvertex.index();

                           MGlobal.displayInfo(index.ToString()+"\n");
                    }

                } 

           }
           
       }
Esempio n. 20
0
        /// <summary>
        /// Export to file
        /// </summary>
        /// <param name="outputDirectory">The directory to store the generated files</param>
        /// <param name="outputFileName">The filename to use for the generated files</param>
        /// <param name="outputFormat">The format to use for the generated files</param>
        /// <param name="generateManifest">Specifies if a manifest file should be generated</param>
        /// <param name="onlySelected">Specifies if only the selected objects should be exported</param>
        /// <param name="autoSaveMayaFile">Specifies if the Maya scene should be auto-saved</param>
        /// <param name="exportHiddenObjects">Specifies if hidden objects should be exported</param>
        /// <param name="copyTexturesToOutput">Specifies if textures should be copied to the output directory</param>
        /// <param name="optimizeVertices">Specifies if vertices should be optimized on export</param>
        /// <param name="exportTangents">Specifies if tangents should be exported</param>
        /// <param name="scaleFactor">Scales the scene by this factor</param>
        /// <param name="exportSkin">Specifies if skins should be exported</param>
        /// <param name="quality">The texture quality</param>
        /// <param name="dracoCompression">Specifies if draco compression should be used</param>
        /// <param name="exportMorphNormal">Specifies if normals should be exported for morph targets</param>
        /// <param name="exportMorphTangent">Specifies if tangents should be exported for morph targets</param>
        /// <param name="exportKHRLightsPunctual">Specifies if the KHR_lights_punctual extension should be enabled</param>
        /// <param name="exportKHRTextureTransform">Specifies if the KHR_texture_transform extension should be enabled</param>
        /// <param name="bakeAnimationFrames">Specifies if animations should be exporting keyframes directly or should manually bake out animations frame by frame</param>
        public void Export(ExportParameters exportParameters)
        {
            this.exportParameters = exportParameters;

            // Check if the animation is running
            MGlobal.executeCommand("play -q - state", out int isPlayed);
            if (isPlayed == 1)
            {
                RaiseError("Stop the animation before exporting.");
                return;
            }

            RaiseMessage("Export started", Color.Blue);
            var progression = 0.0f;

            ReportProgressChanged(progression);

            // Store export options
            this.isBabylonExported = exportParameters.outputFormat == "babylon" || exportParameters.outputFormat == "binary babylon";

            var outputBabylonDirectory = Path.GetDirectoryName(exportParameters.outputPath);

            // Check directory exists
            if (!Directory.Exists(outputBabylonDirectory))
            {
                RaiseError("Export stopped: Output folder does not exist");
                ReportProgressChanged(100);
                return;
            }

            var watch = new Stopwatch();

            watch.Start();


            var babylonScene = new BabylonScene(outputBabylonDirectory);

            // Save scene
            if (exportParameters.autoSaveSceneFile)
            {
                RaiseMessage("Saving Maya file");

                // Query expand file name
                string fileName = MGlobal.executeCommandStringResult($@"file -q -exn;");

                // If scene has already been saved previously
                if (fileName.EndsWith(".ma") || fileName.EndsWith(".mb"))
                {
                    // Name is already specified and this line will not fail
                    MFileIO.save();
                }
                else
                {
                    // Open SaveAs dialog window
                    MGlobal.executeCommand($@"fileDialog2;");
                }
            }

            // Force output file extension to be babylon
            var outputFileName = Path.ChangeExtension(Path.GetFileName(exportParameters.outputPath), "babylon");

            // Store selected nodes
            MSelectionList selectedNodes = new MSelectionList();

            MGlobal.getActiveSelectionList(selectedNodes);
            selectedNodeFullPaths = new List <string>();
            MItSelectionList mItSelectionList = new MItSelectionList(selectedNodes);

            while (!mItSelectionList.isDone)
            {
                MDagPath mDagPath = new MDagPath();
                try
                {
                    mItSelectionList.getDagPath(mDagPath);
                    selectedNodeFullPaths.Add(mDagPath.fullPathName);
                } catch
                {
                    // selected object is not a DAG object
                    // fail silently
                }

                mItSelectionList.next();
            }
            if (selectedNodeFullPaths.Count > 0)
            {
                RaiseMessage("Selected nodes full path");
                foreach (string selectedNodeFullPath in selectedNodeFullPaths)
                {
                    RaiseMessage(selectedNodeFullPath, 1);
                }
            }

            // Producer
            babylonScene.producer = new BabylonProducer
            {
                name             = "Maya",
                version          = "2018",
                exporter_version = exporterVersion,
                file             = outputFileName
            };

            // Global
            babylonScene.autoClear = true;
            // TODO - Retreive colors from Maya
            //babylonScene.clearColor = Loader.Core.GetBackGround(0, Tools.Forever).ToArray();
            //babylonScene.ambientColor = Loader.Core.GetAmbient(0, Tools.Forever).ToArray();

            babylonScene.TimelineStartFrame      = Loader.GetMinTime();
            babylonScene.TimelineEndFrame        = Loader.GetMaxTime();
            babylonScene.TimelineFramesPerSecond = Loader.GetFPS();

            // TODO - Add custom properties
            _exportQuaternionsInsteadOfEulers = true;

            PrintDAG(true);
            PrintDAG(false);

            // Store the current frame. It can be change to find a proper one for the node/bone export
            double currentTime = Loader.GetCurrentTime();

            // --------------------
            // ------ Nodes -------
            // --------------------
            RaiseMessage("Exporting nodes");

            // It makes each morph target manager export starts from id = 0.
            BabylonMorphTargetManager.Reset();

            // Clear materials
            referencedMaterials.Clear();
            multiMaterials.Clear();

            // Get all nodes
            var             dagIterator = new MItDag(MItDag.TraversalType.kDepthFirst, MFn.Type.kTransform);
            List <MDagPath> nodes       = new List <MDagPath>();

            while (!dagIterator.isDone)
            {
                MDagPath mDagPath = new MDagPath();
                dagIterator.getPath(mDagPath);

                // Check if one of its descendant (direct or not) is a mesh/camera/light/locator
                if (isNodeRelevantToExportRec(mDagPath)
                    // Ensure it's not one of the default cameras used as viewports in Maya
                    && defaultCameraNames.Contains(mDagPath.partialPathName) == false)
                {
                    nodes.Add(mDagPath);
                }
                else
                {
                    // Skip descendants
                    dagIterator.prune();
                }

                dagIterator.next();
            }
            // Export all nodes
            var progressionStep = 100.0f / nodes.Count;

            foreach (MDagPath mDagPath in nodes)
            {
                BabylonNode babylonNode = null;

                try
                {
                    switch (getApiTypeOfDirectDescendants(mDagPath))
                    {
                    case MFn.Type.kMesh:
                        babylonNode = ExportMesh(mDagPath, babylonScene);
                        break;

                    case MFn.Type.kCamera:
                        babylonNode = ExportCamera(mDagPath, babylonScene);
                        break;

                    case MFn.Type.kLight:     // Lights api type are actually kPointLight, kSpotLight...
                        babylonNode = ExportLight(mDagPath, babylonScene);
                        break;

                    case MFn.Type.kLocator:     // Camera target
                        babylonNode = ExportDummy(mDagPath, babylonScene);
                        break;
                    }
                }
                catch (Exception e)
                {
                    this.RaiseWarning(String.Format("Exception raised during export. Node will be exported as dummy node. \r\nMessage: \r\n{0} \r\n{1}", e.Message, e.InnerException), 2);
                }

                // If node is not exported successfully
                if (babylonNode == null)
                {
                    // Create a dummy (empty mesh)
                    babylonNode = ExportDummy(mDagPath, babylonScene);
                }
                ;

                // Update progress bar
                progression += progressionStep;
                ReportProgressChanged(progression);

                CheckCancelled();
            }
            RaiseMessage(string.Format("Total meshes: {0}", babylonScene.MeshesList.Count), Color.Gray, 1);


            // if nothing is enlightened, exclude all meshes
            foreach (BabylonLight light in babylonScene.LightsList)
            {
                if (light.includedOnlyMeshesIds.Length == 0)
                {
                    light.excludedMeshesIds = babylonScene.MeshesList.Select(m => m.id).ToArray();
                }
            }

            /*
             * Switch coordinate system at global level
             *
             * Add a root node with negative scaling
             * Pros - It's safer to use a root node
             * Cons - It's cleaner to switch at object level (as it is done now)
             * Use root node method when you want to be 100% sure of the output
             * Don't forget to also inverse winding order of mesh indices
             */
            //// Switch from right to left handed coordinate system
            //MUuid mUuid = new MUuid();
            //mUuid.generate();
            //var rootNode = new BabylonMesh
            //{
            //    name = "root",
            //    id = mUuid.asString(),
            //    scaling = new float[] { 1, 1, -1 }
            //};
            //foreach(var babylonMesh in babylonScene.MeshesList)
            //{
            //    // Add root meshes as child to root node
            //    if (babylonMesh.parentId == null)
            //    {
            //        babylonMesh.parentId = rootNode.id;
            //    }
            //}
            //babylonScene.MeshesList.Add(rootNode);

            // Main camera
            BabylonCamera babylonMainCamera = null;

            if (babylonScene.CamerasList.Count > 0)
            {
                // Set first camera as main one
                babylonMainCamera           = babylonScene.CamerasList[0];
                babylonScene.activeCameraID = babylonMainCamera.id;
                RaiseMessage("Active camera set to " + babylonMainCamera.name, Color.Green, 1, true);
            }

            if (babylonMainCamera == null)
            {
                RaiseWarning("No camera defined", 1);
            }
            else
            {
                RaiseMessage(string.Format("Total cameras: {0}", babylonScene.CamerasList.Count), Color.Gray, 1);
            }

            // Default light
            if (!exportParameters.pbrNoLight && babylonScene.LightsList.Count == 0)
            {
                RaiseWarning("No light defined", 1);
                RaiseWarning("A default ambient light was added for your convenience", 1);
                ExportDefaultLight(babylonScene);
            }
            else
            {
                RaiseMessage(string.Format("Total lights: {0}", babylonScene.LightsList.Count), Color.Gray, 1);
            }

            var sceneScaleFactor = exportParameters.scaleFactor;

            if (exportParameters.scaleFactor != 1.0f)
            {
                RaiseMessage(String.Format("A root node is added to globally scale the scene by {0}", sceneScaleFactor), 1);

                // Create root node for scaling
                BabylonMesh rootNode = new BabylonMesh {
                    name = "root", id = Tools.GenerateUUID()
                };
                rootNode.isDummy = true;
                float rootNodeScale = sceneScaleFactor;
                rootNode.scaling = new float[3] {
                    rootNodeScale, rootNodeScale, rootNodeScale
                };

                if (ExportQuaternionsInsteadOfEulers)
                {
                    rootNode.rotationQuaternion = new float[] { 0, 0, 0, 1 };
                }
                else
                {
                    rootNode.rotation = new float[] { 0, 0, 0 };
                }

                // Update all top nodes
                var babylonNodes = new List <BabylonNode>();
                babylonNodes.AddRange(babylonScene.MeshesList);
                babylonNodes.AddRange(babylonScene.CamerasList);
                babylonNodes.AddRange(babylonScene.LightsList);
                foreach (BabylonNode babylonNode in babylonNodes)
                {
                    if (babylonNode.parentId == null)
                    {
                        babylonNode.parentId = rootNode.id;
                    }
                }

                // Store root node
                babylonScene.MeshesList.Add(rootNode);
            }

            // --------------------
            // ----- Materials ----
            // --------------------
            RaiseMessage("Exporting materials");
            GenerateMaterialDuplicationDatas(babylonScene);
            foreach (var mat in referencedMaterials)
            {
                ExportMaterial(mat, babylonScene, exportParameters.pbrFull);
                CheckCancelled();
            }
            foreach (var mat in multiMaterials)
            {
                ExportMultiMaterial(mat.Key, mat.Value, babylonScene, exportParameters.pbrFull);
                CheckCancelled();
            }
            UpdateMeshesMaterialId(babylonScene);
            RaiseMessage(string.Format("Total: {0}", babylonScene.MaterialsList.Count + babylonScene.MultiMaterialsList.Count), Color.Gray, 1);


            // Export skeletons
            if (exportParameters.exportSkins && skins.Count > 0)
            {
                progressSkin     = 0;
                progressSkinStep = 100 / skins.Count;
                ReportProgressChanged(progressSkin);
                RaiseMessage("Exporting skeletons");
                foreach (var skin in skins)
                {
                    ExportSkin(skin, babylonScene);
                }
            }

            // set back the frame
            Loader.SetCurrentTime(currentTime);

            // ----------------------------
            // ----- Animation groups -----
            // ----------------------------
            RaiseMessage("Export animation groups");
            // add animation groups to the scene
            babylonScene.animationGroups = ExportAnimationGroups(babylonScene);


            if (isBabylonExported)
            {
                // if we are exporting to .Babylon then remove then remove animations from nodes if there are animation groups.
                if (babylonScene.animationGroups.Count > 0)
                {
                    // add animations of each nodes in the animGroup
                    List <BabylonNode> babylonNodes = new List <BabylonNode>();
                    babylonNodes.AddRange(babylonScene.MeshesList);
                    babylonNodes.AddRange(babylonScene.CamerasList);
                    babylonNodes.AddRange(babylonScene.LightsList);

                    foreach (BabylonNode node in babylonNodes)
                    {
                        node.animations = null;
                    }
                    foreach (BabylonSkeleton skel in babylonScene.SkeletonsList)
                    {
                        foreach (BabylonBone bone in skel.bones)
                        {
                            bone.animation = null;
                        }
                    }
                }

                // setup a default skybox for the scene for .Babylon export.
                var sourcePath = exportParameters.pbrEnvironment;
                if (!string.IsNullOrEmpty(sourcePath))
                {
                    babylonScene.createDefaultSkybox = exportParameters.createDefaultSkybox;
                    var fileName = Path.GetFileName(sourcePath);

                    // Allow only dds file format
                    if (!fileName.EndsWith(".dds"))
                    {
                        RaiseWarning("Failed to export defauenvironment texture: only .dds format is supported.");
                    }
                    else
                    {
                        RaiseMessage($"texture id = Max_Babylon_Default_Environment");
                        babylonScene.environmentTexture = fileName;

                        if (exportParameters.writeTextures)
                        {
                            try
                            {
                                var destPath = Path.Combine(babylonScene.OutputPath, fileName);
                                if (File.Exists(sourcePath) && sourcePath != destPath)
                                {
                                    File.Copy(sourcePath, destPath, true);
                                }
                            }
                            catch
                            {
                                // silently fails
                                RaiseMessage($"Fail to export the default env texture", 3);
                            }
                        }
                    }
                }
            }

            // Output
            babylonScene.Prepare(false, false);

            if (isBabylonExported)
            {
                Write(babylonScene, outputBabylonDirectory, outputFileName, exportParameters.outputFormat, exportParameters.generateManifest);
            }

            ReportProgressChanged(100);

            // Export glTF
            if (exportParameters.outputFormat == "gltf" || exportParameters.outputFormat == "glb")
            {
                bool generateBinary = exportParameters.outputFormat == "glb";

                GLTFExporter gltfExporter = new GLTFExporter();
                gltfExporter.ExportGltf(this.exportParameters, babylonScene, outputBabylonDirectory, outputFileName, generateBinary, this);
            }

            watch.Stop();
            RaiseMessage(string.Format("Export done in {0:0.00}s", watch.ElapsedMilliseconds / 1000.0), Color.Blue);
        }
Esempio n. 21
0
        public override void doIt(MArgList args)
        {
            MSelectionList list = new MSelectionList();

            if (args.length > 0)
            {
                // Arg list is > 0 so use objects that were passes in
                //
                uint last = args.length;
                for (uint i = 0; i < last; i++)
                {
                    // Attempt to find all of the objects matched
                    // by the string and add them to the list
                    //
                    string argStr = args.asString(i);
                    list.add(argStr);
                }
            }
            else
            {
                // Get arguments from Maya's selection list.
                MGlobal.getActiveSelectionList(list);
            }

            MObject           node        = new MObject();
            MObjectArray      nodePath    = new MObjectArray();
            MFnDependencyNode nodeFn      = new MFnDependencyNode();
            MFnDependencyNode dgNodeFnSet = new MFnDependencyNode();

            for (MItSelectionList iter = new MItSelectionList(list); !iter.isDone; iter.next())
            {
                iter.getDependNode(node);

                //
                // The following code shows how to navigate the DG manually without
                // using an iterator.  First, find the attribute that you are
                // interested.  Then connect a plug to it and see where the plug
                // connected to.  Once you get all the connections, you can choose
                // which route you want to go.
                //
                // In here, we wanted to get to the nodes that instObjGroups connected
                // to since we know that the shadingEngine connects to the instObjGroup
                // attribute.
                //

                nodeFn.setObject(node);
                MObject iogAttr = null;
                try {
                    iogAttr = nodeFn.attribute("instObjGroups");
                } catch (Exception) {
                    MGlobal.displayInfo(nodeFn.name + ": is not a renderable object, skipping");
                    continue;
                }

                MPlug      iogPlug        = new MPlug(node, iogAttr);
                MPlugArray iogConnections = new MPlugArray();

                //
                // instObjGroups is a multi attribute.  In this example, just the
                // first connection will be tried.
                //
                if (!iogPlug.elementByLogicalIndex(0).connectedTo(iogConnections, false, true))
                {
                    MGlobal.displayInfo(nodeFn.name + ": is not in a shading group, skipping");
                    continue;
                }

                //
                // Now we would like to traverse the DG starting from the shadingEngine
                // since most likely all file texture nodes will be found.  Note the
                // filter used to initialize the DG iterator.  There are lots of filter
                // type available in MF.Type that you can choose to suite your needs.
                //
                bool foundATexture = false;
                for (int i = 0; i < iogConnections.length; i++)
                {
                    MObject currentNode = iogConnections[i].node;

                    //
                    // Note that upon initialization, the current pointer of the
                    // iterator already points to the first valid node.
                    //
                    MItDependencyGraph dgIt = new MItDependencyGraph(currentNode,
                                                                     MFn.Type.kFileTexture,
                                                                     MItDependencyGraph.Direction.kUpstream,
                                                                     MItDependencyGraph.Traversal.kBreadthFirst,
                                                                     MItDependencyGraph.Level.kNodeLevel);
                    if (dgIt == null)
                    {
                        continue;
                    }

                    dgIt.disablePruningOnFilter();

                    for ( ; !dgIt.isDone; dgIt.next())
                    {
                        MObject thisNode = dgIt.thisNode();
                        dgNodeFnSet.setObject(thisNode);
                        try {
                            dgIt.getNodePath(nodePath);
                        } catch (Exception) {
                            MGlobal.displayInfo("getNodePath");
                            continue;
                        }

                        //
                        // append the starting node.
                        //
                        nodePath.append(node);
                        dumpInfo(thisNode, dgNodeFnSet, nodePath);
                        foundATexture = true;
                    }
                }

                if (!foundATexture)
                {
                    MGlobal.displayInfo(nodeFn.name + ": is not connected to a file texture");
                }
            }
            return;
        }
Esempio n. 22
0
        public int[] SetFromSelection(MSelectionList selected = null)
        {
            selectedIndicesList.Clear();
            if (selected == null)
            {
                //
                selected = BasicFunc.GetSelectedList();
            }

            //List<MVector> positions = new List<MVector>();
            MItSelectionList it_selectionList = new MItSelectionList(selected);

            for (; !it_selectionList.isDone; it_selectionList.next())
            {
                MObject  component = new MObject();
                MDagPath item      = new MDagPath();
                it_selectionList.getDagPath(item, component);

                List <int>   selectedIndcies = new List <int>();
                Action <int> xx = (indice) => { selectedIndcies.Add(indice); };

                switch (selectType)
                {
                case SelectType.Edge:
                {
                    MItMeshEdge it_edges = new MItMeshEdge(item, component);
                    for (; !it_edges.isDone; it_edges.next())
                    {
                        selectedIndcies.Add(it_edges.index(0));
                        selectedIndcies.Add(it_edges.index(1));
                    }
                    break;
                }

                case SelectType.Face:
                {
                    MItMeshPolygon it_poly = new MItMeshPolygon(item, component);

                    for (; !it_poly.isDone; it_poly.next())
                    {
                        selectedIndcies.Add((int)it_poly.index());
                    }

                    break;
                }

                case SelectType.Vert:
                {
                    MItMeshVertex it_verts = new MItMeshVertex(item, component);

                    for (; !it_verts.isDone; it_verts.next())
                    {
                        selectedIndcies.Add(it_verts.index());
                    }

                    break;
                }
                }

                selectedIndicesList.Add(selectedIndcies.ToArray());
            }
            int[] resultCount = new int[selectedIndicesList.Count];
            for (int i = 0; i < resultCount.Length; i++)
            {
                resultCount[i] = selectedIndicesList[i].Length;
            }
            return(resultCount);
        }
Esempio n. 23
0
        public void Create(SKLFile skl)
        {
            MSelectionList   currentSelection         = MGlobal.activeSelectionList;
            MItSelectionList currentSelectionIterator = new MItSelectionList(currentSelection, MFn.Type.kMesh);
            MDagPath         meshDagPath = new MDagPath();

            if (currentSelectionIterator.isDone)
            {
                MGlobal.displayError("SKNFile:Create - No mesh selected!");
                throw new Exception("SKNFile:Create - No mesh selected!");
            }
            else
            {
                currentSelectionIterator.getDagPath(meshDagPath);
                currentSelectionIterator.next();

                if (!currentSelectionIterator.isDone)
                {
                    MGlobal.displayError("SKNFile:Create - More than one mesh selected!");
                    throw new Exception("SKNFile:Create - More than one mesh selected!");
                }
            }

            MFnMesh mesh = new MFnMesh(meshDagPath);

            //Find Skin Cluster
            MPlug      inMeshPlug        = mesh.findPlug("inMesh");
            MPlugArray inMeshConnections = new MPlugArray();

            inMeshPlug.connectedTo(inMeshConnections, true, false);
            if (inMeshConnections.length == 0)
            {
                MGlobal.displayError("SKNFile:Create - Failed to find Skin Cluster!");
                throw new Exception("SKNFile:Create - Failed to find Skin Cluster!");
            }

            MPlug          outputGeometryPlug = inMeshConnections[0];
            MFnSkinCluster skinCluster        = new MFnSkinCluster(outputGeometryPlug.node);
            MDagPathArray  influenceDagPaths  = new MDagPathArray();
            uint           influenceCount     = skinCluster.influenceObjects(influenceDagPaths);

            MGlobal.displayInfo("SKNFile:Create - Influence Count: " + influenceCount);

            //Get SKL Influence Indices
            MIntArray sklInfluenceIndices = new MIntArray(influenceCount);

            for (int i = 0; i < influenceCount; i++)
            {
                MDagPath jointDagPath = influenceDagPaths[i];

                MGlobal.displayInfo(jointDagPath.fullPathName);

                //Loop through Joint DAG Paths, if we find a math for the influence, write the index
                for (int j = 0; j < skl.JointDagPaths.Count; j++)
                {
                    if (jointDagPath.equalEqual(skl.JointDagPaths[j]))
                    {
                        MGlobal.displayInfo("Found coresponding DAG path");
                        sklInfluenceIndices[i] = j;
                        break;
                    }
                }
            }

            //Add Influence indices to SKL File
            MIntArray maskInfluenceIndex = new MIntArray(influenceCount);

            for (int i = 0; i < influenceCount; i++)
            {
                maskInfluenceIndex[i] = i;
                skl.Influences.Add((short)sklInfluenceIndices[i]);
            }

            MObjectArray shaders = new MObjectArray();
            MIntArray    polygonShaderIndices = new MIntArray();

            mesh.getConnectedShaders(meshDagPath.isInstanced ? meshDagPath.instanceNumber : 0, shaders, polygonShaderIndices);

            uint shaderCount = shaders.length;

            if (shaderCount > 32) //iirc 32 is the limit of how many submeshes there can be for an SKN file
            {
                MGlobal.displayError("SKNFile:Create - You've exceeded the maximum limit of 32 shaders");
                throw new Exception("SKNFile:Create - You've exceeded the maximum limit of 32 shaders");
            }

            MIntArray vertexShaders = new MIntArray();

            ValidateMeshTopology(mesh, meshDagPath, polygonShaderIndices, ref vertexShaders, shaderCount);

            //Get Weights
            MFnSingleIndexedComponent vertexIndexedComponent = new MFnSingleIndexedComponent();
            MObject   vertexComponent    = vertexIndexedComponent.create(MFn.Type.kMeshVertComponent);
            MIntArray groupVertexIndices = new MIntArray((uint)mesh.numVertices);

            for (int i = 0; i < mesh.numVertices; i++)
            {
                groupVertexIndices[i] = i;
            }
            vertexIndexedComponent.addElements(groupVertexIndices);

            MDoubleArray weights = new MDoubleArray();
            uint         weightsInfluenceCount = 0;

            skinCluster.getWeights(meshDagPath, vertexComponent, weights, ref weightsInfluenceCount);

            //Check if vertices don't have more than 4 influences and normalize weights
            for (int i = 0; i < mesh.numVertices; i++)
            {
                int    vertexInfluenceCount = 0;
                double weightSum            = 0;
                for (int j = 0; j < weightsInfluenceCount; j++)
                {
                    double weight = weights[(int)(i * weightsInfluenceCount) + j];
                    if (weight != 0)
                    {
                        vertexInfluenceCount++;
                        weightSum += weight;
                    }
                }

                if (vertexInfluenceCount > 4)
                {
                    MGlobal.displayError("SKNFile:Create - Mesh contains a vertex with more than 4 influences");
                    throw new Exception("SKNFile:Create - Mesh contains a vertex with more than 4 influences");
                }

                //Normalize weights
                for (int j = 0; j < weightsInfluenceCount; j++)
                {
                    weights[(int)(i * influenceCount) + j] /= weightSum;
                }
            }

            List <MIntArray>         shaderVertexIndices = new List <MIntArray>();
            List <List <SKNVertex> > shaderVertices      = new List <List <SKNVertex> >();
            List <MIntArray>         shaderIndices       = new List <MIntArray>();

            for (int i = 0; i < shaderCount; i++)
            {
                shaderVertexIndices.Add(new MIntArray());
                shaderVertices.Add(new List <SKNVertex>());
                shaderIndices.Add(new MIntArray());
            }

            MItMeshVertex meshVertexIterator = new MItMeshVertex(meshDagPath);

            for (meshVertexIterator.reset(); !meshVertexIterator.isDone; meshVertexIterator.next())
            {
                int index  = meshVertexIterator.index();
                int shader = vertexShaders[index];
                if (shader == -1)
                {
                    MGlobal.displayWarning("SKNFile:Create - Mesh contains a vertex with no shader");
                    continue;
                }

                MPoint       pointPosition = meshVertexIterator.position(MSpace.Space.kWorld);
                Vector3      position      = new Vector3((float)pointPosition.x, (float)pointPosition.y, (float)pointPosition.z);
                MVectorArray normals       = new MVectorArray();
                MIntArray    uvIndices     = new MIntArray();
                Vector3      normal        = new Vector3();
                byte[]       weightIndices = new byte[4];
                float[]      vertexWeights = new float[4];

                meshVertexIterator.getNormals(normals);

                //Normalize normals
                for (int i = 0; i < normals.length; i++)
                {
                    normal.X += (float)normals[i].x;
                    normal.Y += (float)normals[i].y;
                    normal.Z += (float)normals[i].z;
                }

                normal.X /= normals.length;
                normal.Y /= normals.length;
                normal.Z /= normals.length;

                //Get Weight Influences and Weights
                int weightsFound = 0;
                for (int j = 0; j < weightsInfluenceCount && weightsFound < 4; j++)
                {
                    double weight = weights[(int)(index * weightsInfluenceCount) + j];

                    if (weight != 0)
                    {
                        weightIndices[weightsFound] = (byte)maskInfluenceIndex[j];
                        vertexWeights[weightsFound] = (float)weight;
                        weightsFound++;
                    }
                }

                //Get unique UVs
                meshVertexIterator.getUVIndices(uvIndices);
                if (uvIndices.length != 0)
                {
                    List <int> seen = new List <int>();
                    for (int j = 0; j < uvIndices.length; j++)
                    {
                        int uvIndex = uvIndices[j];
                        if (!seen.Contains(uvIndex))
                        {
                            seen.Add(uvIndex);

                            float u = 0;
                            float v = 0;
                            mesh.getUV(uvIndex, ref u, ref v);

                            SKNVertex vertex = new SKNVertex(position, weightIndices, vertexWeights, normal, new Vector2(u, 1 - v));
                            vertex.UVIndex = uvIndex;

                            shaderVertices[shader].Add(vertex);
                            shaderVertexIndices[shader].append(index);
                        }
                    }
                }
                else
                {
                    MGlobal.displayError("SKNFile:Create - Mesh contains a vertex with no UVs");
                    throw new Exception("SKNFile:Create - Mesh contains a vertex with no UVs");
                }
            }

            //Convert from Maya indices to data indices
            int       currentIndex = 0;
            MIntArray dataIndices  = new MIntArray((uint)mesh.numVertices, -1);

            for (int i = 0; i < shaderCount; i++)
            {
                for (int j = 0; j < shaderVertexIndices[i].length; j++)
                {
                    int index = shaderVertexIndices[i][j];
                    if (dataIndices[index] == -1)
                    {
                        dataIndices[index]             = currentIndex;
                        shaderVertices[i][j].DataIndex = currentIndex;
                    }
                    else
                    {
                        shaderVertices[i][j].DataIndex = dataIndices[index];
                    }

                    currentIndex++;
                }

                this.Vertices.AddRange(shaderVertices[i]);
            }

            MItMeshPolygon polygonIterator = new MItMeshPolygon(meshDagPath);

            for (polygonIterator.reset(); !polygonIterator.isDone; polygonIterator.next())
            {
                int polygonIndex = (int)polygonIterator.index();
                int shaderIndex  = polygonShaderIndices[polygonIndex];

                MIntArray   indices = new MIntArray();
                MPointArray points  = new MPointArray();
                polygonIterator.getTriangles(points, indices);

                if (polygonIterator.hasUVsProperty)
                {
                    MIntArray vertices   = new MIntArray();
                    MIntArray newIndices = new MIntArray(indices.length, -1);
                    polygonIterator.getVertices(vertices);

                    for (int i = 0; i < vertices.length; i++)
                    {
                        int dataIndex = dataIndices[vertices[i]];
                        int uvIndex;
                        polygonIterator.getUVIndex(i, out uvIndex);

                        if (dataIndex == -1 || dataIndex >= this.Vertices.Count)
                        {
                            MGlobal.displayError("SKNFIle:Create - Data Index outside of range");
                            throw new Exception("SKNFIle:Create - Data Index outside of range");
                        }

                        for (int j = dataIndex; j < this.Vertices.Count; j++)
                        {
                            if (this.Vertices[j].DataIndex != dataIndex)
                            {
                                MGlobal.displayError("SKNFIle:Create - Can't find corresponding face vertex in data");
                                throw new Exception("SKNFIle:Create - Can't find corresponding face vertex in data");
                            }
                            else if (this.Vertices[j].UVIndex == uvIndex)
                            {
                                for (int k = 0; k < indices.length; k++)
                                {
                                    if (indices[k] == vertices[i])
                                    {
                                        newIndices[k] = j;
                                    }
                                }

                                break;
                            }
                        }
                    }

                    for (int i = 0; i < newIndices.length; i++)
                    {
                        shaderIndices[shaderIndex].append(newIndices[i]);
                    }
                }
                else
                {
                    for (int i = 0; i < indices.length; i++)
                    {
                        shaderIndices[shaderIndex].append(dataIndices[indices[i]]);
                    }
                }
            }

            uint startIndex  = 0;
            uint startVertex = 0;

            for (int i = 0; i < shaderCount; i++)
            {
                MPlug      shaderPlug = new MFnDependencyNode(shaders[i]).findPlug("surfaceShader");
                MPlugArray plugArray  = new MPlugArray();
                shaderPlug.connectedTo(plugArray, true, false);

                string name        = new MFnDependencyNode(plugArray[0].node).name;
                uint   indexCount  = shaderIndices[i].length;
                uint   vertexCount = shaderVertexIndices[i].length;

                //Copy indices to SKLFile
                for (int j = 0; j < indexCount; j++)
                {
                    this.Indices.Add((ushort)shaderIndices[i][j]);
                }

                this.Submeshes.Add(new SKNSubmesh(name, startVertex, vertexCount, startIndex, indexCount));

                startIndex  += indexCount;
                startVertex += vertexCount;
            }

            MGlobal.displayInfo("SKNFile:Create - Created SKN File");
        }
Esempio n. 24
0
        public void Export(string outputDirectory, string outputFileName, string outputFormat, bool generateManifest,
                           bool onlySelected, bool autoSaveMayaFile, bool exportHiddenObjects, bool copyTexturesToOutput,
                           bool optimizeVertices, bool exportTangents, string scaleFactor, bool exportSkin)
        {
            // Chekc if the animation is running
            MGlobal.executeCommand("play -q - state", out int isPlayed);
            if (isPlayed == 1)
            {
                RaiseError("Stop the animation before exporting.");
                return;
            }

            // Check input text is valid
            var scaleFactorFloat = 1.0f;

            try
            {
                scaleFactor      = scaleFactor.Replace(".", System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator);
                scaleFactor      = scaleFactor.Replace(",", System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator);
                scaleFactorFloat = float.Parse(scaleFactor);
            }
            catch
            {
                RaiseError("Scale factor is not a valid number.");
                return;
            }

            RaiseMessage("Exportation started", Color.Blue);
            var progression = 0.0f;

            ReportProgressChanged(progression);

            // Store export options
            _onlySelected        = onlySelected;
            _exportHiddenObjects = exportHiddenObjects;
            _optimizeVertices    = optimizeVertices;
            _exportTangents      = exportTangents;
            CopyTexturesToOutput = copyTexturesToOutput;
            isBabylonExported    = outputFormat == "babylon" || outputFormat == "binary babylon";
            _exportSkin          = exportSkin;

            // Check directory exists
            if (!Directory.Exists(outputDirectory))
            {
                RaiseError("Exportation stopped: Output folder does not exist");
                ReportProgressChanged(100);
                return;
            }

            var watch = new Stopwatch();

            watch.Start();

            var outputBabylonDirectory = outputDirectory;
            var babylonScene           = new BabylonScene(outputBabylonDirectory);

            // Save scene
            if (autoSaveMayaFile)
            {
                RaiseMessage("Saving Maya file");

                // Query expand file name
                string fileName = MGlobal.executeCommandStringResult($@"file -q -exn;");

                // If scene has already been saved previously
                if (fileName.EndsWith(".ma") || fileName.EndsWith(".mb"))
                {
                    // Name is already specified and this line will not fail
                    MFileIO.save();
                }
                else
                {
                    // Open SaveAs dialog window
                    MGlobal.executeCommand($@"fileDialog2;");
                }
            }

            // Force output file extension to be babylon
            outputFileName = Path.ChangeExtension(outputFileName, "babylon");

            // Store selected nodes
            MSelectionList selectedNodes = new MSelectionList();

            MGlobal.getActiveSelectionList(selectedNodes);
            selectedNodeFullPaths = new List <string>();
            MItSelectionList mItSelectionList = new MItSelectionList(selectedNodes);

            while (!mItSelectionList.isDone)
            {
                MDagPath mDagPath = new MDagPath();
                try
                {
                    mItSelectionList.getDagPath(mDagPath);
                    selectedNodeFullPaths.Add(mDagPath.fullPathName);
                } catch
                {
                    // selected object is not a DAG object
                    // fail silently
                }

                mItSelectionList.next();
            }
            if (selectedNodeFullPaths.Count > 0)
            {
                RaiseMessage("Selected nodes full path");
                foreach (string selectedNodeFullPath in selectedNodeFullPaths)
                {
                    RaiseMessage(selectedNodeFullPath, 1);
                }
            }

            // Producer
            babylonScene.producer = new BabylonProducer
            {
                name             = "Maya",
                version          = "2018",
                exporter_version = exporterVersion,
                file             = outputFileName
            };

            // Global
            babylonScene.autoClear = true;
            // TODO - Retreive colors from Maya
            //babylonScene.clearColor = Loader.Core.GetBackGround(0, Tools.Forever).ToArray();
            //babylonScene.ambientColor = Loader.Core.GetAmbient(0, Tools.Forever).ToArray();

            // TODO - Add custom properties
            _exportQuaternionsInsteadOfEulers = true;

            PrintDAG(true);
            PrintDAG(false);

            // --------------------
            // ------ Nodes -------
            // --------------------
            RaiseMessage("Exporting nodes");

            // Clear materials
            referencedMaterials.Clear();
            multiMaterials.Clear();

            // Get all nodes
            var             dagIterator = new MItDag(MItDag.TraversalType.kDepthFirst, MFn.Type.kTransform);
            List <MDagPath> nodes       = new List <MDagPath>();

            while (!dagIterator.isDone)
            {
                MDagPath mDagPath = new MDagPath();
                dagIterator.getPath(mDagPath);

                // Check if one of its descendant (direct or not) is a mesh/camera/light/locator
                if (isNodeRelevantToExportRec(mDagPath)
                    // Ensure it's not one of the default cameras used as viewports in Maya
                    && defaultCameraNames.Contains(mDagPath.partialPathName) == false)
                {
                    nodes.Add(mDagPath);
                }
                else
                {
                    // Skip descendants
                    dagIterator.prune();
                }

                dagIterator.next();
            }
            // Export all nodes
            var progressionStep = 100.0f / nodes.Count;

            foreach (MDagPath mDagPath in nodes)
            {
                BabylonNode babylonNode = null;

                switch (getApiTypeOfDirectDescendants(mDagPath))
                {
                case MFn.Type.kMesh:
                    babylonNode = ExportMesh(mDagPath, babylonScene);
                    break;

                case MFn.Type.kCamera:
                    babylonNode = ExportCamera(mDagPath, babylonScene);
                    break;

                case MFn.Type.kLight:     // Lights api type are actually kPointLight, kSpotLight...
                    babylonNode = ExportLight(mDagPath, babylonScene);
                    break;

                case MFn.Type.kLocator:     // Camera target
                    babylonNode = ExportDummy(mDagPath, babylonScene);
                    break;
                }

                // If node is not exported successfully
                if (babylonNode == null)
                {
                    // Create a dummy (empty mesh)
                    babylonNode = ExportDummy(mDagPath, babylonScene);
                }
                ;

                // Update progress bar
                progression += progressionStep;
                ReportProgressChanged(progression);

                CheckCancelled();
            }
            RaiseMessage(string.Format("Total meshes: {0}", babylonScene.MeshesList.Count), Color.Gray, 1);


            // if nothing is enlightened, exclude all meshes
            foreach (BabylonLight light in babylonScene.LightsList)
            {
                if (light.includedOnlyMeshesIds.Length == 0)
                {
                    light.excludedMeshesIds = babylonScene.MeshesList.Select(m => m.id).ToArray();
                }
            }

            /*
             * Switch coordinate system at global level
             *
             * Add a root node with negative scaling
             * Pros - It's safer to use a root node
             * Cons - It's cleaner to switch at object level (as it is done now)
             * Use root node method when you want to be 100% sure of the output
             * Don't forget to also inverse winding order of mesh indices
             */
            //// Switch from right to left handed coordinate system
            //MUuid mUuid = new MUuid();
            //mUuid.generate();
            //var rootNode = new BabylonMesh
            //{
            //    name = "root",
            //    id = mUuid.asString(),
            //    scaling = new float[] { 1, 1, -1 }
            //};
            //foreach(var babylonMesh in babylonScene.MeshesList)
            //{
            //    // Add root meshes as child to root node
            //    if (babylonMesh.parentId == null)
            //    {
            //        babylonMesh.parentId = rootNode.id;
            //    }
            //}
            //babylonScene.MeshesList.Add(rootNode);

            // Main camera
            BabylonCamera babylonMainCamera = null;

            if (babylonScene.CamerasList.Count > 0)
            {
                // Set first camera as main one
                babylonMainCamera           = babylonScene.CamerasList[0];
                babylonScene.activeCameraID = babylonMainCamera.id;
                RaiseMessage("Active camera set to " + babylonMainCamera.name, Color.Green, 1, true);
            }

            if (babylonMainCamera == null)
            {
                RaiseWarning("No camera defined", 1);
            }
            else
            {
                RaiseMessage(string.Format("Total cameras: {0}", babylonScene.CamerasList.Count), Color.Gray, 1);
            }

            // Default light
            if (babylonScene.LightsList.Count == 0)
            {
                RaiseWarning("No light defined", 1);
                RaiseWarning("A default ambient light was added for your convenience", 1);
                ExportDefaultLight(babylonScene);
            }
            else
            {
                RaiseMessage(string.Format("Total lights: {0}", babylonScene.LightsList.Count), Color.Gray, 1);
            }

            if (scaleFactorFloat != 1.0f)
            {
                RaiseMessage("A root node is added for scaling", 1);

                // Create root node for scaling
                BabylonMesh rootNode = new BabylonMesh {
                    name = "root", id = Tools.GenerateUUID()
                };
                rootNode.isDummy = true;
                float rootNodeScale = 1.0f / scaleFactorFloat;
                rootNode.scaling = new float[3] {
                    rootNodeScale, rootNodeScale, rootNodeScale
                };

                // Update all top nodes
                var babylonNodes = new List <BabylonNode>();
                babylonNodes.AddRange(babylonScene.MeshesList);
                babylonNodes.AddRange(babylonScene.CamerasList);
                babylonNodes.AddRange(babylonScene.LightsList);
                foreach (BabylonNode babylonNode in babylonNodes)
                {
                    if (babylonNode.parentId == null)
                    {
                        babylonNode.parentId = rootNode.id;
                    }
                }

                // Store root node
                babylonScene.MeshesList.Add(rootNode);
            }

            // --------------------
            // ----- Materials ----
            // --------------------
            RaiseMessage("Exporting materials");
            GenerateMaterialDuplicationDatas(babylonScene);
            foreach (var mat in referencedMaterials)
            {
                ExportMaterial(mat, babylonScene);
                CheckCancelled();
            }
            foreach (var mat in multiMaterials)
            {
                ExportMultiMaterial(mat.Key, mat.Value, babylonScene);
                CheckCancelled();
            }
            UpdateMeshesMaterialId(babylonScene);
            RaiseMessage(string.Format("Total: {0}", babylonScene.MaterialsList.Count + babylonScene.MultiMaterialsList.Count), Color.Gray, 1);


            // Export skeletons
            if (_exportSkin && skins.Count > 0)
            {
                progressSkin     = 0;
                progressSkinStep = 100 / skins.Count;
                ReportProgressChanged(progressSkin);
                RaiseMessage("Exporting skeletons");
                foreach (var skin in skins)
                {
                    ExportSkin(skin, babylonScene);
                }
            }

            // Output
            babylonScene.Prepare(false, false);
            if (isBabylonExported)
            {
                Write(babylonScene, outputBabylonDirectory, outputFileName, outputFormat, generateManifest);
            }

            ReportProgressChanged(100);

            // Export glTF
            if (outputFormat == "gltf" || outputFormat == "glb")
            {
                bool generateBinary = outputFormat == "glb";
                ExportGltf(babylonScene, outputDirectory, outputFileName, generateBinary);
            }

            watch.Stop();
            RaiseMessage(string.Format("Exportation done in {0:0.00}s", watch.ElapsedMilliseconds / 1000.0), Color.Blue);
        }
Esempio n. 25
0
		public override void doIt(MArgList args)
		{
			MSelectionList list = new MSelectionList();

			if ( args.length > 0 ) {
				// Arg list is > 0 so use objects that were passes in
				//
				uint last = args.length;
				for ( uint i = 0; i < last; i++ ) {
					// Attempt to find all of the objects matched
					// by the string and add them to the list
					//
					string argStr = args.asString(i);
					list.add(argStr);
				}
			} else {
				// Get arguments from Maya's selection list.
				MGlobal.getActiveSelectionList(list);
			}

			MObject node = new MObject();
			MObjectArray nodePath = new MObjectArray();
			MFnDependencyNode nodeFn = new MFnDependencyNode();
			MFnDependencyNode dgNodeFnSet = new MFnDependencyNode();

			for (MItSelectionList iter = new MItSelectionList(list); !iter.isDone; iter.next()) {

				iter.getDependNode(node);

				//
				// The following code shows how to navigate the DG manually without
				// using an iterator.  First, find the attribute that you are
				// interested.  Then connect a plug to it and see where the plug
				// connected to.  Once you get all the connections, you can choose
				// which route you want to go.
				//
				// In here, we wanted to get to the nodes that instObjGroups connected
				// to since we know that the shadingEngine connects to the instObjGroup
				// attribute.
				//

				nodeFn.setObject( node );
				MObject iogAttr = null;
				try {
					iogAttr = nodeFn.attribute("instObjGroups");
				} catch (Exception) {
					MGlobal.displayInfo(nodeFn.name + ": is not a renderable object, skipping");
					continue;
				}

				MPlug iogPlug = new MPlug(node, iogAttr);
				MPlugArray iogConnections = new MPlugArray();

				//
				// instObjGroups is a multi attribute.  In this example, just the
				// first connection will be tried.
				//
				if (!iogPlug.elementByLogicalIndex(0).connectedTo(iogConnections, false, true)) {
					MGlobal.displayInfo(nodeFn.name + ": is not in a shading group, skipping");
					continue;
				}

				//
				// Now we would like to traverse the DG starting from the shadingEngine
				// since most likely all file texture nodes will be found.  Note the
				// filter used to initialize the DG iterator.  There are lots of filter
				// type available in MF.Type that you can choose to suite your needs.
				//
				bool foundATexture = false;
				for ( int i=0; i < iogConnections.length; i++ ) {

					MObject currentNode = iogConnections[i].node;

					//
					// Note that upon initialization, the current pointer of the
					// iterator already points to the first valid node.
					//
					MItDependencyGraph dgIt = new MItDependencyGraph(currentNode,
																	 MFn.Type.kFileTexture,
																	 MItDependencyGraph.Direction.kUpstream,
																	 MItDependencyGraph.Traversal.kBreadthFirst,
																	 MItDependencyGraph.Level.kNodeLevel);
					if (dgIt == null)
					{
						continue;
					}

					dgIt.disablePruningOnFilter();

					for ( ; !dgIt.isDone; dgIt.next() ) {

						MObject thisNode = dgIt.thisNode();
						dgNodeFnSet.setObject(thisNode);
						try {
							dgIt.getNodePath(nodePath);
						} catch (Exception) {
							MGlobal.displayInfo("getNodePath");
							continue;
						}

						//
						// append the starting node.
						//
						nodePath.append(node);
						dumpInfo( thisNode, dgNodeFnSet, nodePath );
						foundATexture = true;
					}
				}

				if ( !foundATexture ) {
					MGlobal.displayInfo(nodeFn.name + ": is not connected to a file texture");
				}
			}
			return;
		}