Example #1
0
        /// <summary>
        /// Return the custom attributes of a material
        /// </summary>
        /// <param name="materialNode"></param>
        /// <param name="babylonScene"></param>
        /// <param name="excludeAttributes">Attribute names to not export</param>
        public Dictionary <string, object> ExportExtraAttributes(IIGameMaterial gameMaterial, BabylonScene babylonScene, List <string> excludeAttributes = null)
        {
            // Retreive the max object
            ScriptsUtilities.ExecuteMaxScriptCommand("obj = sceneMaterials[\"" + gameMaterial.MaterialName + "\"];");

            return(_ExportExtraAttributes(gameMaterial.IPropertyContainer, babylonScene, excludeAttributes));
        }
Example #2
0
        /// <summary>
        /// Return the custom attributes of a material
        /// </summary>
        /// <param name="materialNode"></param>
        /// <param name="babylonScene"></param>
        /// <param name="excludeAttributes">Attribute names to not export</param>
        public Dictionary <string, object> ExportExtraAttributes(IIGameNode gameNode, BabylonScene babylonScene, List <string> excludeAttributes = null)
        {
            // Retreive the max object
            ScriptsUtilities.ExecuteMaxScriptCommand("obj = execute(\"$'" + gameNode.MaxNode.Handle + "'\");");

            return(_ExportExtraAttributes(gameNode.IGameObject.IPropertyContainer, babylonScene, excludeAttributes));
        }
Example #3
0
        public async void butExport_Click(object sender, EventArgs e)
        {
            treeView.Nodes.Clear();
            exportParameters = GetExportParameters();

            PreExportProcess preExportProcess = new PreExportProcess(exportParameters, logger);
            bool             abort            = false;

            try
            {
                abort = AutosaveWarning();
                if (abort)
                {
                    return;
                }

                if (exportParameters.usePreExportProcess)
                {
                    Loader.Core.FileHold();
                    preExportProcess.ApplyPreExport();
                }
                await DoExport(singleExportItem);
            }
            catch (Exception ex)
            {
                logger.RaiseError(ex.Message);
            }
            finally
            {
                if (exportParameters.usePreExportProcess && !exportParameters.applyPreprocessToScene)
                {
                    ScriptsUtilities.ExecuteMaxScriptCommand("fetchMaxFile quiet:true");
                }
            }
        }
Example #4
0
        /// <summary>
        /// Retrieve current selected material in slate material editor
        /// </summary>
        /// <returns></returns>
        public static IMtl GetSelectedMaterial()
        {
            string mxs = "viewNode = sme.GetView (sme.activeView)";

            mxs += "\r\n" + "smeSelMats = #()";
            mxs += "\r\n" + "if (trackViewNodes[#sme][(sme.activeView)] != undefined) then(";
            mxs += "\r\n" + "for n = 1 to trackViewNodes[#sme][(sme.activeView)].numSubs do (";
            mxs += "\r\n" + "m = trackViewNodes[#sme][(sme.activeView)][n].reference";
            mxs += "\r\n" + "b = viewNode.GetNodeByRef m";
            mxs += "\r\n" + "if b.selected do append smeSelMats m)";
            mxs += "\r\n" + "smeSelMats[1])";

            IFPValue mxsRetVal = Loader.Global.FPValue.Create();

            ScriptsUtilities.ExecuteMAXScriptScript(mxs, true, mxsRetVal);
            IMtl result = null;

            try
            {
                result = mxsRetVal.Mtl;
            }
            catch (Exception e)
            {
                //do nothing ,just retun a null material
            }

            return(result);
        }
Example #5
0
        private async void butMultiExport_Click(object sender, EventArgs e)
        {
            treeView.Nodes.Clear();
            string outputFileExt = comboOutputFormat.SelectedItem.ToString();

            if (outputFileExt.Contains("binary babylon"))
            {
                outputFileExt = "babylon";
            }

            ExportItemList exportItemList = new ExportItemList(outputFileExt);

            exportItemList.LoadFromData();

            int numLoadedItems = exportItemList.Count;

            if (ModifierKeys == Keys.Shift)
            {
                MultiExportForm form = new MultiExportForm(exportItemList);
                form.ShowDialog(this);
            }
            else if (numLoadedItems > 0)
            {
                exportParameters = GetExportParameters();
                PreExportProcess preExportProcess = new PreExportProcess(exportParameters, logger);
                if (logger != null)
                {
                    preExportProcess.logger = logger;
                }
                bool abort = false;
                try
                {
                    abort = AutosaveWarning();
                    if (abort)
                    {
                        return;
                    }

                    if (exportParameters.usePreExportProcess)
                    {
                        Loader.Core.FileHold();
                        preExportProcess.ApplyPreExport();
                    }
                    await DoExport(exportItemList);
                }
                catch (Exception ex)
                {
                    logger.RaiseError(ex.Message);
                }
                finally
                {
                    if (exportParameters.usePreExportProcess && !exportParameters.applyPreprocessToScene)
                    {
                        ScriptsUtilities.ExecuteMaxScriptCommand("fetchMaxFile quiet:true");
                    }
                }
            }
        }
Example #6
0
        public static void FlattenHierarchy(this IINode node)
        {
            ////todo: replace this with C#
            string convertToEditablePoly = $"ConvertTo (maxOps.getNodeByHandle {node.Handle}) Editable_Poly";

            ScriptsUtilities.ExecuteMaxScriptCommand(convertToEditablePoly);

            IPolyObject polyObject   = node.GetPolyObjectFromNode();
            IEPoly      flattenEPoly = (IEPoly)polyObject.GetInterface(Loader.EditablePoly);
            IINodeTab   toflatten    = Loader.Global.NodeTab.Create();

            foreach (IINode n in node.NodeTree())
            {
                toflatten.AppendNode(n, false, 1);
            }

            flattenEPoly.EpfnMultiAttach(toflatten, node, Loader.Core.Time);
        }
Example #7
0
        private void AddCallbacks()
        {
            // Retreive the material just created
            string cmd = "maxMaterial = callbacks.notificationParam();";

            // Easy syntax for a switch/case expression
            cmd += "\r\n" + "if classof maxMaterial == StandardMaterial then";
            cmd += "\r\n" + "(";
            cmd += "\r\n" + BabylonExporter.GetStandardBabylonAttributesDataCA();
            cmd += "\r\n" + "custAttributes.add maxMaterial babylonAttributesDataCA;";
            cmd += "\r\n" + ")";
            cmd += "\r\n" + "else if classof maxMaterial == PhysicalMaterial then";
            cmd += "\r\n" + "(";
            cmd += "\r\n" + BabylonExporter.GetPhysicalBabylonAttributesDataCA();
            cmd += "\r\n" + "custAttributes.add maxMaterial babylonAttributesDataCA;";
            cmd += "\r\n" + ")";
            cmd += "\r\n" + "else if classof maxMaterial == ai_standard_surface then";
            cmd += "\r\n" + "(";
            cmd += "\r\n" + BabylonExporter.GetAiStandardSurfaceBabylonAttributesDataCA();
            cmd += "\r\n" + "custAttributes.add maxMaterial babylonAttributesDataCA;";
            cmd += "\r\n" + ")";

            // Escape cmd
            cmd = cmd.Replace("\"", "\\\"");

            // Create cmd as string
            ScriptsUtilities.ExecuteMaxScriptCommand("cmd = \"" + cmd + "\"");

            // Remove any definition of this callback
            ScriptsUtilities.ExecuteMaxScriptCommand("callbacks.removeScripts id:#BabylonAttributesMaterial;");

            // Add a callback triggered when a new material is created
            // Note:
            // The callback is NOT persistent (default value is false).
            // This means that it is not linked to a specific file.
            // Rather, the callback is active for the current run of 3ds Max.
            // See Autodesk documentation for more info: http://help.autodesk.com/view/3DSMAX/2015/ENU/?guid=__files_GUID_C1F6495F_5831_4FC8_A00C_667C5F2EAE36_htm
            ScriptsUtilities.ExecuteMaxScriptCommand("callbacks.addScript #mtlRefAdded cmd id:#BabylonAttributesMaterial;");
        }
Example #8
0
        private async Task <bool> DoExport(ExportItem exportItem, bool multiExport = false, bool clearLogs = true)
        {
            new BabylonAnimationActionItem().Close();
            SaveOptions();

            //store layer visibility status and force visibility on

            Dictionary <IILayer, bool> layerState = new Dictionary <IILayer, bool>();

            if (exportItem.Layers != null)
            {
                foreach (IILayer layer in exportItem.Layers)
                {
                    List <IILayer> treeLayers = layer.LayerTree().ToList();
                    treeLayers.Add(layer);

                    foreach (IILayer l in treeLayers)
                    {
#if MAX2015
                        layerState.Add(l, l.IsHidden);
#else
                        layerState.Add(l, l.IsHidden(false));
#endif
                        l.Hide(false, false);
                    }
                }
            }

            exporter = new BabylonExporter();

            if (clearLogs)
            {
                treeView.Nodes.Clear();
            }

            exporter.OnExportProgressChanged += progress =>
            {
                progressBar.Value = progress;
                Application.DoEvents();
            };

            exporter.OnWarning += (warning, rank) => CreateWarningMessage(warning, rank);

            exporter.OnError += (error, rank) => CreateErrorMessage(error, rank);

            exporter.OnMessage += (message, color, rank, emphasis) => CreateMessage(message, color, rank, emphasis);

            exporter.OnVerbose += (message, color, rank, emphasis) =>
            {
                try
                {
                    currentNode = CreateTreeNode(rank, message, color);

                    if (emphasis)
                    {
                        currentNode.EnsureVisible();
                    }
                }
                catch
                {
                    //do nothing
                }
                Application.DoEvents();
            };

            butExport.Enabled       = false;
            butExportAndRun.Enabled = false;
            butMultiExport.Enabled  = false;
            butCancel.Enabled       = true;

            bool success = true;
            try
            {
                string modelAbsolutePath = multiExport ? exportItem.ExportFilePathAbsolute : txtModelPath.Text;
                string textureExportPath = multiExport ? exportItem.ExportTexturesesFolderAbsolute : txtTexturesPath.Text;

                var scaleFactorParsed    = 1.0f;
                var textureQualityParsed = 100L;
                try
                {
                    scaleFactorParsed = float.Parse(txtScaleFactor.Text);
                }
                catch (Exception e)
                {
                    throw new InvalidDataException(String.Format("Invalid Scale Factor value: {0}", txtScaleFactor.Text));
                }
                try
                {
                    textureQualityParsed = long.Parse(txtQuality.Text);
                }
                catch (Exception e)
                {
                    throw new InvalidDataException(String.Format("Invalid Texture Quality value: {0}", txtScaleFactor.Text));
                }

                MaxExportParameters exportParameters = new MaxExportParameters
                {
                    outputPath                 = modelAbsolutePath,
                    textureFolder              = textureExportPath,
                    outputFormat               = comboOutputFormat.SelectedItem.ToString(),
                    scaleFactor                = scaleFactorParsed,
                    writeTextures              = chkWriteTextures.Enabled && chkWriteTextures.Checked,
                    overwriteTextures          = chkOverwriteTextures.Enabled && chkOverwriteTextures.Checked,
                    exportHiddenObjects        = chkHidden.Checked,
                    exportOnlySelected         = chkOnlySelected.Checked,
                    generateManifest           = chkManifest.Checked,
                    autoSaveSceneFile          = chkAutoSave.Checked,
                    exportTangents             = chkExportTangents.Checked,
                    exportMorphTangents        = chkExportMorphTangents.Checked,
                    exportMorphNormals         = chkExportMorphNormals.Checked,
                    txtQuality                 = textureQualityParsed,
                    mergeAOwithMR              = chkMergeAOwithMR.Enabled && chkMergeAOwithMR.Checked,
                    bakeAnimationType          = (BakeAnimationType)cmbBakeAnimationOptions.SelectedIndex,
                    dracoCompression           = chkDracoCompression.Enabled && chkDracoCompression.Checked,
                    enableKHRLightsPunctual    = chkKHRLightsPunctual.Checked,
                    enableKHRTextureTransform  = chkKHRTextureTransform.Checked,
                    enableKHRMaterialsUnlit    = chkKHRMaterialsUnlit.Checked,
                    exportMaterials            = chkExportMaterials.Enabled && chkExportMaterials.Checked,
                    exportAnimations           = chkExportAnimations.Checked,
                    exportAnimationsOnly       = chkExportAnimationsOnly.Checked,
                    optimizeAnimations         = !chkDoNotOptimizeAnimations.Checked,
                    animgroupExportNonAnimated = chkAnimgroupExportNonAnimated.Checked,
                    exportNode                 = exportItem?.Node,
                    exportLayers               = exportItem?.Layers,
                    pbrNoLight                 = chkNoAutoLight.Checked,
                    pbrFull                = chkFullPBR.Checked,
                    pbrEnvironment         = txtEnvironmentName.Text,
                    usePreExportProcess    = chkUsePreExportProces.Checked,
                    flattenScene           = chkFlatten.Enabled && chkFlatten.Checked,
                    mergeContainersAndXRef = chkMrgContainersAndXref.Checked,
                    useMultiExporter       = multiExport
                };

                exporter.callerForm = this;

                exporter.Export(exportParameters);
            }
            catch (OperationCanceledException)
            {
                progressBar.Value = 0;
                success           = false;
                ScriptsUtilities.ExecuteMaxScriptCommand(@"global BabylonExporterStatus = ""Available""");
            }
            catch (Exception ex)
            {
                IUTF8Str operationStatus = GlobalInterface.Instance.UTF8Str.Create("BabylonExportAborted");
                Loader.Global.BroadcastNotification(SystemNotificationCode.PreExport, operationStatus);

                currentNode = CreateTreeNode(0, "Export cancelled: " + ex.Message, Color.Red);
                currentNode = CreateTreeNode(1, ex.ToString(), Color.Red);
                currentNode.EnsureVisible();

                progressBar.Value = 0;
                success           = false;
                ScriptsUtilities.ExecuteMaxScriptCommand(@"global BabylonExporterStatus = Available");
            }

            butCancel.Enabled       = false;
            butExport.Enabled       = true;
            butMultiExport.Enabled  = true;
            butExportAndRun.Enabled = WebServer.IsSupported;

            BringToFront();

            //re-store layer visibility status
            if (exportItem.Layers != null)
            {
                foreach (IILayer layer in exportItem.Layers)
                {
                    List <IILayer> treeLayers = layer.LayerTree().ToList();
                    treeLayers.Add(layer);
                    foreach (IILayer l in treeLayers)
                    {
                        bool exist;
                        layerState.TryGetValue(l, out exist);
                        if (exist)
                        {
                            l.Hide(layerState[l], false);
                        }
                    }
                }
            }

            return(success);
        }
Example #9
0
        /// <summary>
        /// Return custom attributes retreive from a max object named "obj"
        /// </summary>
        /// <param name="metadata"></param>
        /// <param name="propertyContainer"></param>
        /// <param name="babylonScene"></param>
        /// <param name="excludeAttributes">Attribute names to not export</param>
        private Dictionary <string, object> _ExportExtraAttributes(IIPropertyContainer propertyContainer, BabylonScene babylonScene, List <string> excludeAttributes = null)
        {
            logger?.RaiseMessage("ExportExtraAttributes", 2);

            // Return a string encoded with 2 separators
            // Parameter separator: _$€PParam_
            // Name/Type separator: _$€PType_
            string cmd = "s = \"\""
                         + "\r\n" + "for objDef in (custAttributes.getDefs obj) do"
                         + "\r\n" + "("
                         + "\r\n" + "pbArray = custAttributes.getPBlockDefs objdef"
                         + "\r\n" + "for indexPBlock = 1 to pbArray.count do"
                         + "\r\n" + "("
                         + "\r\n" + "itms = pbArray[indexPBlock]"
                         + "\r\n" + "for y = 5 to itms.Count do"
                         + "\r\n" + "("
                         + "\r\n" + "s = s + \"_$€PParam_\" + itms[y][1]"
                         + "\r\n" + "for z = 1 to itms[y][2].Count by 2 do"
                         + "\r\n" + "("
                         + "\r\n" + "key = itms[y][2][z] as string"
                         + "\r\n" + "if (findString key \"type\") != undefined then"
                         + "\r\n" + "("
                         + "\r\n" + "s = s + \"_$€PType_\" + itms[y][2][z+1]"
                         + "\r\n" + ")"
                         + "\r\n" + ")"
                         + "\r\n" + ")"
                         + "\r\n" + ")"
                         + "\r\n" + ")"
                         + "\r\n" + "s";
            string result = ScriptsUtilities.ExecuteMaxScriptQuery(cmd);

            if (result == null || result == "")
            {
                return(null);
            }

            // Parse the result into a dictionary
            string[] parameters = result.Split(new string[] { "_$€PParam_" }, StringSplitOptions.RemoveEmptyEntries);
            Dictionary <string, string> customAttributesTypeByName = new Dictionary <string, string>();

            foreach (string parameter in parameters)
            {
                string[] customAttribute = parameter.Split(new string[] { "_$€PType_" }, StringSplitOptions.RemoveEmptyEntries);
                string   key             = customAttribute[0];
                if (customAttributesTypeByName.ContainsKey(key) == false)
                {
                    customAttributesTypeByName.Add(key, customAttribute[1]);
                }
            }

            // Remove preset custom attributes
            customAttributesTypeByName.Remove("presetName_str");
            customAttributesTypeByName.Remove("preset_str");
            customAttributesTypeByName.Remove("rampOn");

            // Remove specified attributes
            if (excludeAttributes != null)
            {
                foreach (string excludeAttribute in excludeAttributes)
                {
                    customAttributesTypeByName.Remove(excludeAttribute);
                }
            }

            // Handle each attribute type
            Dictionary <string, object> metadata = new Dictionary <string, object>();

            foreach (KeyValuePair <string, string> entry in customAttributesTypeByName)
            {
                object obj = null;

                logger?.RaiseMessage(entry.Key + "=" + entry.Value, 2);

                switch (entry.Value.ToLowerInvariant())
                {
                case "float":
                case "angle":     // in rad units
                case "worldunits":
                    obj = propertyContainer.GetFloatProperty(entry.Key);
                    break;

                case "percent":     // in base 1 (80% => 0.8)
                    obj = propertyContainer.GetFloatProperty(entry.Key) / 100f;
                    break;

                case "boolean":
                    obj = propertyContainer.GetBoolProperty(entry.Key);
                    break;

                case "integer":
                case "array":     // selected enum value expressed as int starting from 1
                    obj = propertyContainer.GetIntProperty(entry.Key);
                    break;

                case "string":
                    obj = propertyContainer.GetStringProperty(entry.Key);
                    break;

                case "color":     // Color RGB in base 1 (not 255)
                    obj = propertyContainer.GetPoint3Property(entry.Key).ToArray();
                    break;

                case "frgba":     // Color RGBA in base 1 (not 255)
                    obj = propertyContainer.GetPoint4Property(entry.Key).ToArray();
                    break;

                case "texturemap":
                    IIGameProperty gameProperty = propertyContainer.QueryProperty(entry.Key);
                    ITexmap        texmap       = gameProperty.MaxParamBlock2.GetTexmap(gameProperty.ParamID, 0, 0);
                    obj = ExportTexture(texmap, babylonScene);
                    break;

                case "node":
                    // Currently not exported
                    break;

                case "material":
                    // Currently not exported
                    break;

                default:
                    logger?.RaiseWarning("Unknown type '" + entry.Value + "' for custom attribute named '" + entry.Key + "'", 2);
                    break;
                }

                if (obj != null)
                {
                    metadata.Add(entry.Key, obj);
                }
            }

            // Print all extra attributes
            foreach (KeyValuePair <string, object> entry in metadata)
            {
                logger?.RaiseVerbose(entry.Key + "=" + entry.Value, 2);
            }

            return(metadata);
        }
Example #10
0
        public static IINode FlattenHierarchyMS(this IINode node)
        {
            IILayer nodeLayer = LayerUtilities.GetNodeLayer(node);

            if (nodeLayer != null)
            {
                Loader.Core.LayerManager.SetCurrentLayer(nodeLayer.Name);
            }

            List <IINode> children        = node.NodeTree().ToList();
            List <IINode> nonMeshChildren = children.Where(x => !x.IsMesh()).ToList();

            string groupName = node.Name + Random.Next(1, 100000);

            node.Name = groupName;
            //use the default one in the future. for some reason uv ar broken with C# version
            ScriptsUtilities.ExecuteMaxScriptCommand($@"
            groupNode = maxOps.getNodeByHandle {node.Handle.ToString()}
	        meshChildren = #()	
	        for c in groupNode.children do
	        (
               if superclassof c == GeometryClass then
		        (
			        append meshChildren  c
		        )
	        )
	        obj = mesh vertices:#([0,0,0],[10,0,0],[0,10,0]) faces:#([1,2,3]) name:groupNode.name transform:groupNode.transform
	        converttopoly obj
	        multimat_new=#()
	        for obj_temp in meshChildren do	
	        (
		        obj_temp.parent=undefined
		        converttomesh	obj_temp		
		        resetXform	obj_temp			
		        converttomesh	obj_temp		
		        local save_mat=obj_temp.material			
		        if classof  save_mat == Multimaterial then
		        (
			        ID_true_used=#{{}}
			        T_Faces_matID=#()
			        T_Faces_matID.count=save_mat.count
			        for f=1 to obj_temp.numfaces do	
			        (
				        local face_matID=(getFaceMatID  obj_temp	f)
				        if not(ID_true_used[face_matID]) then 
				        (
					        T_Faces_matID[face_matID]=#{{f}}
					        ID_true_used[face_matID]=true
				        )
				        else
				        (
					        append  (T_Faces_matID[face_matID])	 f
				        )
			        )
			        for index_mat in ID_true_used do
			        (
				        mat_current=save_mat[index_mat]
				
				        matID=finditem multimat_new mat_current
				        if matID==0 then
				        (
					        append multimat_new mat_current
					        new_Id=multimat_new.count

                            for f in (T_Faces_matID[index_mat]) do setFaceMatID obj_temp  f       new_Id
                        )
                        else for f in (T_Faces_matID[index_mat]) do setFaceMatID obj_temp  f       matID
                    )
                )
                else
                (
                    mat_current = save_mat
                    matID = finditem multimat_new mat_current
                    if matID == 0 then
                    (
                        append multimat_new mat_current
                        new_Id = multimat_new.count
                        for f = 1 to obj_temp.numfaces do setFaceMatID obj_temp  f       new_Id
			        )
                    else for f = 1 to obj_temp.numfaces do setFaceMatID obj_temp  f       matID
		        )
		        obj_temp.material = undefined
                with undo off(polyop.attach  obj obj_temp)
	        )
	        final_mat = multimaterial numsubs: (multimat_new.count)
            final_mat.name = obj.name + ""_mat""
            for i = 1 to(multimat_new.count) do
            (
                if multimat_new[i] == undefined
                then(final_mat[i] = FlightSim()     ; final_mat[i].name = ""Newmat""    )
                else final_mat[i] = multimat_new[i]
	        )
	        polyop.deleteFaces obj 1
            obj.material = final_mat
            obj.parent = groupNode.parent");
            Loader.Core.DeleteNode(node, false, false);
            IINode newNode = Loader.Core.GetINodeByName(groupName);

            foreach (IINode n in nonMeshChildren)
            {
                newNode.AttachChild(n, true);
            }
            return(newNode);
        }
Example #11
0
        public static IINode FlattenHierarchy(this IINode node)
        {
            IILayer nodeLayer = LayerUtilities.GetNodeLayer(node);

            if (nodeLayer != null)
            {
                Loader.Core.LayerManager.SetCurrentLayer(nodeLayer.Name);
            }


            List <IINode> children        = node.NodeTree().ToList();
            List <IINode> nonMeshChildren = children.Where(x => !x.IsMesh()).ToList();
            List <IINode> meshChildren    = children.Where(x => x.IsMesh()).ToList();

            IClass_ID cid    = Loader.Global.Class_ID.Create((uint)BuiltInClassIDA.SPHERE_CLASS_ID, 0);
            object    obj    = Loader.Core.CreateInstance(SClass_ID.Geomobject, cid as IClass_ID);
            IINode    result = Loader.Core.CreateObjectNode((IObject)obj);

            result.Name = node.Name;
            result.SetNodeTM(Loader.Core.Time, node.GetNodeTM(Loader.Core.Time, Forever));
            node.ParentNode.AttachChild(result, true);

            string convertToEditablePoly = $"ConvertTo (maxOps.getNodeByHandle {result.Handle}) Editable_Poly";

            ScriptsUtilities.ExecuteMaxScriptCommand(convertToEditablePoly);

            IPolyObject polyObject  = result.GetPolyObjectFromNode();
            IEPoly      nodeEPoly   = (IEPoly)polyObject.GetInterface(Loader.EditablePoly);
            List <IMtl> newMultiMat = new List <IMtl>();

            foreach (IINode n in meshChildren)
            {
                ITriObject triObject = n.GetTriObjectFromNode();
                IMesh      mesh      = triObject.Mesh;
                if (n.Mtl.IsMultiMtl)
                {
                    Dictionary <IMtl, List <IFace> > matIDtoFacesMap = new Dictionary <IMtl, List <IFace> >();
                    ////List<int> matIDsInUse = new List<int>();

                    foreach (IFace face in mesh.Faces)
                    {
                        int  faceMatID = face.MatID;
                        IMtl mat       = n.Mtl.GetSubMtl(faceMatID);
                        if (!matIDtoFacesMap.ContainsKey(mat))
                        {
                            List <IFace> facesOfMat = new List <IFace>();
                            matIDtoFacesMap.Add(mat, facesOfMat);
                        }
                        matIDtoFacesMap[mat].Add(face);
                    }

                    foreach (KeyValuePair <IMtl, List <IFace> > matToFaceKeyValue in matIDtoFacesMap)
                    {
                        IMtl faceMat = matToFaceKeyValue.Key; //get the material from the list of the multimaterial
                        if (!newMultiMat.Contains(faceMat))
                        {
                            newMultiMat.Add(faceMat);
                        }
                        ushort newId = (ushort)(newMultiMat.IndexOf(faceMat));
                        foreach (IFace face in matToFaceKeyValue.Value)
                        {
                            face.MatID = newId;
                        }
                    }
                }
                else
                {
                    //IMtl currentMat = n.Mtl;
                    //int matID = newMultiMat.IndexOf(currentMat);
                    //if (matID == -1)
                    //{
                    //    newMultiMat.Add(currentMat);
                    //    ushort newId = (ushort)newMultiMat.Count;
                    //    for (int fID = 0; fID < mesh.NumFaces; fID++)
                    //    {
                    //        mesh.SetFaceMtlIndex(fID, (ushort)newId);
                    //    }
                    //}
                    //else
                    //{
                    //    for (int fID = 0; fID < mesh.NumFaces; fID++)
                    //    {
                    //        mesh.SetFaceMtlIndex(fID, (ushort)matID);
                    //    }
                    //}
                }

                triObject.Mesh = mesh;
                n.ObjectRef    = triObject;
                //bool undo = false;
                //nodeEPoly.EpfnAttach(n, ref undo,result, Loader.Core.Time);
            }

            IClass_ID matCid   = Loader.Global.Class_ID.Create((uint)BuiltInClassIDA.MULTI_MATERIAL_CLASS_ID, 0);
            IMtl      finalMat = (IMtl)Loader.Core.CreateInstance(SClass_ID.Material, matCid);

            for (int i = 0; i < newMultiMat.Count; i++)
            {
                finalMat.SetSubMtl(i, newMultiMat[i]);
            }
            finalMat.Name = "final mat";
            result.Mtl    = finalMat;

            foreach (IINode n in nonMeshChildren)
            {
                result.AttachChild(n, true);
            }

            Loader.Core.DeleteNode(node, false, false);

            return(result);
        }
        private async Task <bool> DoExport(ExportItem exportItem, bool multiExport = false, bool clearLogs = true)
        {
            new BabylonAnimationActionItem().Close();
            SaveOptions();

            if (multiExport)
            {
                ShowExportItemLayers(exportItem.Layers);
            }

            exporter = new BabylonExporter();

            if (clearLogs)
            {
                treeView.Nodes.Clear();
            }

            exporter.OnExportProgressChanged += progress =>
            {
                progressBar.Value = progress;
                Application.DoEvents();
            };

            exporter.OnWarning += (warning, rank) => CreateWarningMessage(warning, rank);

            exporter.OnError += (error, rank) => CreateErrorMessage(error, rank);

            exporter.OnMessage += (message, color, rank, emphasis) => CreateMessage(message, color, rank, emphasis);

            exporter.OnVerbose += (message, color, rank, emphasis) => CreateMessage(message, color, rank, emphasis);

            exporter.OnPrint += (message, color, rank, emphasis) => CreateMessage(message, color, rank, emphasis);

            butExport.Enabled       = false;
            butExportAndRun.Enabled = false;
            butMultiExport.Enabled  = false;
            butCancel.Enabled       = true;

            bool success = true;

            try
            {
                string modelAbsolutePath = multiExport ? exportItem.ExportFilePathAbsolute : txtModelPath.Text;
                string textureExportPath = multiExport ? exportItem.ExportTexturesesFolderAbsolute : txtTexturesPath.Text;

                var scaleFactorParsed    = 1.0f;
                var textureQualityParsed = 100L;
                try
                {
                    scaleFactorParsed = float.Parse(txtScaleFactor.Text);
                }
                catch (Exception e)
                {
                    throw new InvalidDataException(String.Format("Invalid Scale Factor value: {0}", txtScaleFactor.Text));
                }
                try
                {
                    textureQualityParsed = long.Parse(txtQuality.Text);
                }
                catch (Exception e)
                {
                    throw new InvalidDataException(String.Format("Invalid Texture Quality value: {0}", txtScaleFactor.Text));
                }

                MaxExportParameters exportParameters = new MaxExportParameters
                {
                    outputPath                    = modelAbsolutePath,
                    textureFolder                 = textureExportPath,
                    outputFormat                  = comboOutputFormat.SelectedItem.ToString(),
                    scaleFactor                   = scaleFactorParsed,
                    writeTextures                 = chkWriteTextures.Enabled && chkWriteTextures.Checked,
                    overwriteTextures             = chkOverwriteTextures.Enabled && chkOverwriteTextures.Checked,
                    exportHiddenObjects           = chkHidden.Checked,
                    exportOnlySelected            = chkOnlySelected.Checked,
                    generateManifest              = chkManifest.Checked,
                    autoSaveSceneFile             = chkAutoSave.Checked,
                    exportTangents                = chkExportTangents.Checked,
                    exportMorphTangents           = chkExportMorphTangents.Checked,
                    exportMorphNormals            = chkExportMorphNormals.Checked,
                    txtQuality                    = textureQualityParsed,
                    mergeAOwithMR                 = chkMergeAOwithMR.Enabled && chkMergeAOwithMR.Checked,
                    bakeAnimationType             = (BakeAnimationType)cmbBakeAnimationOptions.SelectedIndex,
                    logLevel                      = (LogLevel)logLevelcmb.SelectedIndex,
                    dracoCompression              = chkDracoCompression.Enabled && chkDracoCompression.Checked,
                    enableKHRLightsPunctual       = chkKHRLightsPunctual.Checked,
                    enableKHRTextureTransform     = chkKHRTextureTransform.Checked,
                    enableKHRMaterialsUnlit       = chkKHRMaterialsUnlit.Checked,
                    exportMaterials               = chkExportMaterials.Enabled && chkExportMaterials.Checked,
                    animationExportType           = (AnimationExportType)cmbExportAnimationType.SelectedIndex,
                    enableASBAnimationRetargeting = chkASBAnimationRetargeting.Checked,
                    optimizeAnimations            = !chkDoNotOptimizeAnimations.Checked,
                    animgroupExportNonAnimated    = chkAnimgroupExportNonAnimated.Checked,
                    exportNode                    = exportItem?.Node,
                    exportLayers                  = exportItem?.Layers,
                    pbrNoLight                    = chkNoAutoLight.Checked,
                    pbrFull                = chkFullPBR.Checked,
                    pbrEnvironment         = txtEnvironmentName.Text,
                    usePreExportProcess    = chkUsePreExportProces.Checked,
                    flattenScene           = chkFlatten.Enabled && chkFlatten.Checked,
                    mergeContainersAndXRef = chkMrgContainersAndXref.Checked,
                    useMultiExporter       = multiExport,
                    tangentSpaceConvention = (TangentSpaceConvention)cmbNormalMapConvention.SelectedIndex,
                    removeLodPrefix        = chk_RemoveLodPrefix.Checked,
                    removeNamespaces       = chkRemoveNamespace.Checked,
                    srcTextureExtension    = txtSrcTextureExt.Text,
                    dstTextureExtension    = txtDstTextureExt.Text
                };

                exporter.callerForm = this;

                exporter.Export(exportParameters);
            }
            catch (OperationCanceledException)
            {
                progressBar.Value = 0;
                success           = false;
                ScriptsUtilities.ExecuteMaxScriptCommand(@"global BabylonExporterStatus = ""Available""");
            }
            catch (Exception ex)
            {
                IUTF8Str operationStatus = GlobalInterface.Instance.UTF8Str.Create("BabylonExportAborted");
                Loader.Global.BroadcastNotification(SystemNotificationCode.PreExport, operationStatus);

                currentNode = CreateTreeNode(0, "Export cancelled: " + ex.Message, Color.Red);
                currentNode = CreateTreeNode(1, ex.ToString(), Color.Red);
                currentNode.EnsureVisible();

                progressBar.Value = 0;
                success           = false;
                ScriptsUtilities.ExecuteMaxScriptCommand(@"global BabylonExporterStatus = Available");
            }

            butCancel.Enabled       = false;
            butExport.Enabled       = true;
            butMultiExport.Enabled  = true;
            butExportAndRun.Enabled = WebServer.IsSupported;

            BringToFront();

            return(success);
        }
Example #13
0
        private static void ResolveMultipleInheritedContainer(IIContainerObject container)
        {
            //resolve container name
            int b = 0;

            if (container.ContainerNode.GetUserPropBool("flightsim_resolved", ref b) && b != 0)
            {
                return;
            }

            List <IINode> containerHierarchy = new List <IINode>()
            {
            };

            containerHierarchy.AddRange(container.ContainerNode.ContainerNodeTree(false));

            string helperPropBuffer = string.Empty;

            container.BabylonContainerHelper().GetUserPropBuffer(ref helperPropBuffer);
            int containerID = 1;

            container.ContainerNode.GetUserPropInt("babylonjs_ContainerID", ref containerID);
            container.ContainerNode.Name = containerID == -1 ? $"{container.ContainerNode.Name}" : $"{container.ContainerNode.Name}_{containerID}";
            // resolve nodes , adding an id at the end
            {
                //manage multiple containers inherited from the same source
                foreach (IINode n in containerHierarchy)
                {
                    if (n.IsBabylonContainerHelper())
                    {
                        continue;
                    }
                    //change the guid of the node
                    //replace the guid in the babylon helper
                    string oldGuid = n.GetStringProperty("babylonjs_GUID", Guid.NewGuid().ToString());
                    n.DeleteProperty("babylonjs_GUID");
                    Guid newGuid = n.GetGuid();
                    helperPropBuffer = helperPropBuffer.Replace(oldGuid, newGuid.ToString());

                    n.Name = containerID == -1 ? $"{n.Name}" : $"{n.Name}_{containerID}";
                    if (n.Mtl != null && FlightSimMaterialUtilities.HasFlightSimMaterials(n.Mtl) && FlightSimMaterialUtilities.HasRuntimeAccess(n.Mtl))
                    {
                        if (n.Mtl.IsMultiMtl)
                        {
                            throw new Exception($@"Material {n.Mtl.Name} has a property ""Unique In Container"" enabled, cannot be child of a multi material");
                        }
                        else
                        {
                            string cmd = $"mNode = maxOps.getNodeByHandle {n.Handle} \r\n" +
                                         $"newMat = copy mNode.material \r\n" +
                                         $"newMat.name = \"{n.Mtl.Name}_{containerID}\" \r\n" +
                                         $"mNode.material = newMat";

                            ScriptsUtilities.ExecuteMaxScriptCommand(cmd);
                        }
                    }
                }
            }



            //replace animationList guid to have distinct list of AnimationGroup for each container
            string animationListStr = string.Empty;
            IINode containerHelper  = container.BabylonContainerHelper();


            containerHelper.GetUserPropString(s_AnimationListPropertyName, ref animationListStr);
            if (!string.IsNullOrEmpty(animationListStr))
            {
                string[] animationGroupGuid = animationListStr.Split(AnimationGroup.s_PropertySeparator);
                foreach (string guidStr in animationGroupGuid)
                {
                    Guid newAnimGroupGuid = Guid.NewGuid();
                    helperPropBuffer = helperPropBuffer.Replace(guidStr, newAnimGroupGuid.ToString());
                }

                containerHelper.SetUserPropBuffer(helperPropBuffer);

                //add ID of container to animationGroup name to identify animation in viewer
                containerHelper.GetUserPropString(s_AnimationListPropertyName, ref animationListStr);
                string[] newAnimationGroupGuid = animationListStr.Split(AnimationGroup.s_PropertySeparator);

                foreach (string guidStr in newAnimationGroupGuid)
                {
                    string propertiesString = string.Empty;
                    if (!containerHelper.GetUserPropString(guidStr, ref propertiesString))
                    {
                        return;
                    }

                    try // new serialization method
                    {
                        SerializableAnimationGroup serialAnimGroup = new SerializableAnimationGroup(propertiesString);
                        serialAnimGroup.name = containerID == -1 ? serialAnimGroup.name : serialAnimGroup.name + $"_{containerID}";
                        string serializedInfo = JsonConvert.SerializeObject(serialAnimGroup);
                        container.BabylonContainerHelper().SetUserPropString(guidStr, serializedInfo);
                    }
                    catch (Exception)
                    {
                        string[] properties = propertiesString.Split(AnimationGroup.s_PropertySeparator);
                        if (properties.Length < 4)
                        {
                            throw new Exception($"Invalid number of properties, can't de-serialize property of {containerHelper.Name} of {container.ContainerNode.Name}.");
                        }

                        string name = properties[0];
                        if (!string.IsNullOrEmpty(name))
                        {
                            propertiesString = propertiesString.Replace(name, name + "_" + containerID);
                            container.BabylonContainerHelper().SetUserPropString(guidStr, propertiesString);
                        }
                    }
                }
            }
            container.ContainerNode.SetUserPropBool("flightsim_resolved", true);
        }