0
Fixed

CADLink and Solid Edge

Andrew Sherlock 5 years ago in CADLink updated by Support 5 years ago 13

We are having issues with models generated from Solid Edge. Assembly positions and part colours don't always seem to be respected.


I note that the documentation mentions similar issues with NX and that a fix is due soon. Will something similar for Solid Edge available?


Andy

Answer

Answer

Hi Andy, oh sorry. Yes you can remove this line.

Give us a good feedback in the Unity Store if you are happy with our solution. Thanks.


Thomas

Under review

Hi Andrew,

for the color problem (Solidedge has another way to use the ColorGroups) we will release an update soon. You can already replace CADLINK.cs with this file - this should help.

For the Assembly Positions I will need to check. Can you please send me an example exported 3mf from solidworks to info@game4automation.com.

Thanks

// Game4Automation (R) Framework for Automation Concept Design, Virtual Commissioning and 3D-HMI
// (c) 2019 in2Sight GmbH - Usage of this source code only allowed based on License conditions see https://game4automation.com/lizenz  

using System.IO;
using System.Linq;
using UnityEngine;
using NaughtyAttributes;
using ThreeMf;
using UnityEditor;
using System.Collections.Generic;

namespace game4automation
{
    public class CADLink : MonoBehaviour
    {
        [BoxGroup("Import CAD")] public string File;
        [BoxGroup("Import CAD")] public bool DeleteBeforeImporting;

        [BoxGroup("Import CAD")] public bool RemoveTopAssemblyNode = false;
        [BoxGroup("Import CAD")] public bool NameClonesIdentical;
        [BoxGroup("Import CAD")] public float ImportScaleFactor = 0.001f;

        [BoxGroup("Import CAD")] [ReadOnly] public string Status = "";

        [BoxGroup("Advanced")] public bool ImportDistinctVertices = true;
        [BoxGroup("Advanced")] public bool UnityRecalculateNormals = false;
        [BoxGroup("Advanced")] public bool AdvancedRecalculateNormals = true;

        [BoxGroup("Advanced")] [EnableIf("AdvancedRecalculateNormals")]
        public float AdvancedRecalcluateNormalsAngle = 30;

        [BoxGroup("Advanced")] [InfoBox("UV Mapping takes long - just use if needed")]
        public bool CalculateUVS = false;

        [EnableIf("CalculateUVS")] [BoxGroup("Advanced")]
        public float UVScalfactor = 1.0f;

        [BoxGroup("Materials")] public bool SetAndCreateMaterials = true;

        [BoxGroup("Materials")] [EnableIf("SetAndCreateMaterials")]
        public bool OverwriteExistingMaterials = false;

        [BoxGroup("Materials")] [EnableIf("SetAndCreateMaterials")]
        public string NewMaterialPath;

        [BoxGroup("Materials")] [EnableIf("SetAndCreateMaterials")]
        public MaterialMapping MaterialMapping;


        private bool SetPositions = true;

        private float Progress = 0;
        private bool cancel = false;

        private List<Material> newmaterials = new List<Material>();
        private List<CADPart> nosubcomponent = new List<CADPart>();

        [Button("Create New Material Mapping")]
        private void CreateMeaterialMapping()
        {
#if UNITY_EDITOR
            var mapping = CreateAsset<MaterialMapping>();

            MaterialMapping = (MaterialMapping) mapping;
#endif
        }

        [Button("Update Materials")]
        private void SetMaterials()
        {
            newmaterials.Clear();
            // Go through all CAD parts with meshes and check if material is assigned
            // if not assign next material of upper levels
            CADPart[] cadparts = GetComponentsInChildren<CADPart>(this);
            foreach (CADPart cadpart in cadparts)
            {
                MeshFilter meshfilter = cadpart.GetComponent<MeshFilter>();
                Renderer meshrenderer = cadpart.GetComponent<Renderer>();

                if (meshrenderer != null)
                {
                    // Part with Mesh has material assigned
                    if (cadpart.Color != "" || cadpart.Material != "")
                    {
                        meshrenderer.sharedMaterial = Get3mfMaterial(cadpart.Color, cadpart.Material);
                    }
                    else
                        // if not find next CADpart upwards with Material
                    {
                        Component[] uppercadparts = cadpart.GetComponentsInParent(typeof(CADPart), true);
                        foreach (CADPart uppercadpart in uppercadparts)
                        {
                            if (uppercadpart.Color != "")
                            {
                                meshrenderer.sharedMaterial = Get3mfMaterial(uppercadpart.Color, uppercadpart.Material);
                                break;
                            }
                        }
                    }
                }
            }
        }


        [Button("Select CAD Import File")]
        void SelectFile()
        {
#if UNITY_EDITOR
            File = EditorUtility.OpenFilePanel("Select file to import", File, "3mf");
#endif
        }


        [Button("Delete Import")]
        public void DeleteAll()
        {
            CADPart[] children = transform.GetComponentsInChildren<CADPart>();
            foreach (var child in children.ToArray())
            {
                if (child != null)
                    DestroyImmediate(child.gameObject);
            }
        }

        public void Log(string message)
        {
            Debug.Log("Game4Automation CAD Import: " + message);
#if UNITY_EDITOR
            cancel = EditorUtility.DisplayCancelableProgressBar(
                "CAD Livelink - Import",
                message,
                Progress);
#endif
            Status = message;
        }


        [Button("Import CAD File")]
        public void ImportCad()
        {
            cancel = false;
            if (!System.IO.File.Exists(File))
            {
#if UNITY_EDITOR
                EditorUtility.DisplayDialog("ERROR", "3MF File at defined path [" + File + "] not existing.", "OK", "");
                return;
#endif
                Debug.LogError("3MF File at defined path [" + File + "] not existing.");
            }

            if (!Directory.Exists(NewMaterialPath) && SetAndCreateMaterials)
            {
#if UNITY_EDITOR
                EditorUtility.DisplayDialog("ERROR", "New material path [" + NewMaterialPath + "] not existing.", "OK",
                    "");
                return;
#endif
                Debug.LogError("3MF File at defined path [" + File + "] not existing.");
            }

            if (DeleteBeforeImporting)
                DeleteAll();
            Progress = 0.05f;
            var num = 0;
            nosubcomponent.Clear();
            Log("Load 3MF File");

            var test = ThreeMfFile.Load(File, 1);
            Debug.Log("Import 3MF");
            foreach (var model in test.Models)
            {
                foreach (var resource in model.Resources)
                {
                    num++;
                    Progress = (float) num / (float) model.Resources.Count;
                    if (cancel)
                    {
                        Debug.Log("Import Canceled by User");
                        #if UNITY_EDITOR
                            EditorUtility.ClearProgressBar();
                        #endif
                        return;
                    }

                    if (resource.GetType() == typeof(ThreeMfObject))
                    {
                        var obj = (ThreeMfObject) resource;
                        Log("Import Part " + obj.Name + " " + obj.Id.ToString());

                        var part = CreateCadPart(this.gameObject, obj.Name, obj.Id.ToString(), obj);
                        part.File = File;
                        part.LastUpdate = System.DateTime.Now.ToString();
                        // Mesh at Part
                        if (obj.Mesh != null)
                        {
                            CreateMesh(part, obj.Mesh);
                        }
                        
                        // Get Porpertyindex

                        var propindex = obj.PropertyIndex;
                        
                        // Properties at Part
                        if (obj.PropertyResource != null)
                        {
                            if (obj.PropertyResource.PropertyItems != null)
                            {

                                var currindex = 0;
                               foreach (var propertyItem in obj.PropertyResource.PropertyItems)
                                {
                                    if (currindex == propindex)
                                    {
                                        Material material = null;
                                        if (propertyItem.GetType() == typeof(ThreeMfColor))
                                        {
                                            var color = (ThreeMfColor) propertyItem;
                                            part.Color = color.Color.ToString();
                                            part.Material = "";
                                        }

                                        if (propertyItem.GetType() == typeof(ThreeMfBase))
                                        {
                                            var color = (ThreeMfBase) propertyItem;
                                            part.Color = color.Color.ToString();
                                            part.Material = color.Name;
                                        }
                                    }

                                    currindex = currindex + 1;
                                }
                            }
                        }

                        foreach (var component in obj.Components)
                        {
                            MakeAsSubComponent(obj.Id.ToString(), component.Object.Id.ToString(), component);
                        }
                    }
                }
            }

            if (SetAndCreateMaterials)
                SetMaterials();

            if (RemoveTopAssemblyNode)
                RemoveTopAssembly();

            #if UNITY_EDITOR
                 EditorUtility.ClearProgressBar();
            #endif
        }

        private void RemoveTopAssembly()
        {
            var top = nosubcomponent[0];
            List<GameObject> children = new List<GameObject>();
            if (top != null)
            {
                for (int i = 0; i < top.transform.childCount; i++)
                {
                    children.Add(top.transform.GetChild(i).gameObject);
                }
            }

            foreach (var child in children)
            {
                child.transform.parent = this.transform;
            }

            DestroyImmediate(top.gameObject);
        }


        private Material Get3mfMaterial(string colorname, string materialname)
        {
            
            Material newmaterial = null;


            //    colorname.Replace("#", "Hex");
            var tempMaterial = new Material(Shader.Find("Standard"));

            // check if material assignment in material mapping
            // 1st check if color and material combination are defined
            if (MaterialMapping != null)
            {
                foreach (var mapping in MaterialMapping.Mappings)
                {
                    if (mapping.Colorname == colorname && mapping.Materialname == materialname)
                        return mapping.Material;
                }
            }

            // 2nd check if material is defined 
            if (MaterialMapping != null)
            {
                foreach (var mapping in MaterialMapping.Mappings)
                {
                    if (mapping.Materialname == materialname && mapping.Materialname != "")
                        return mapping.Material;
                }
            }

            // 3rd check if color is defined 
            if (MaterialMapping != null)
            {
                foreach (var mapping in MaterialMapping.Mappings)
                {
                    if (mapping.Colorname == colorname && mapping.Colorname != "")
                        return mapping.Material;
                }
            }

            #if UNITY_EDITOR         
            // create new material if not existing
            string[] assets = AssetDatabase.FindAssets(colorname + " t:material");

            bool createnewmaterial = true;

            if (assets.Length != 0 && OverwriteExistingMaterials == false)
            {
                createnewmaterial = false;
            }

            if (assets.Length != 0 && OverwriteExistingMaterials == true)
            {
                newmaterial = AssetDatabase.LoadAssetAtPath<Material>(AssetDatabase.GUIDToAssetPath(assets[0]));

                if (newmaterials.Contains(newmaterial))
                {
                    createnewmaterial = false;
                }
                else
                {
                    createnewmaterial = true;
                    AssetDatabase.DeleteAsset(AssetDatabase.GUIDToAssetPath(assets[0]));
                }
            }

            if (createnewmaterial)
            {
                var path = Path.Combine(NewMaterialPath, colorname + ".mat");
                AssetDatabase.CreateAsset(tempMaterial, path);
                newmaterial = AssetDatabase.LoadAssetAtPath<Material>(path);
                newmaterials.Add(newmaterial);
                var col = new Color();
                ColorUtility.TryParseHtmlString(colorname, out col);
                newmaterial.color = col;
            }
            else
            {
                newmaterial = AssetDatabase.LoadAssetAtPath<Material>(AssetDatabase.GUIDToAssetPath(assets[0]));
            }
            #else
                newmaterial =  new Material(Shader.Find("Standard"));   
                var col = new Color();
                ColorUtility.TryParseHtmlString(colorname, out col);
                newmaterial.color = col;
            #endif
            
            

            return newmaterial;
        }

        private void CreateMesh(CADPart part, ThreeMfMesh mesh)
        {
            MeshFilter meshfilter = part.transform.GetComponent<MeshFilter>();
            if (meshfilter == null)
            {
                meshfilter = part.transform.gameObject.AddComponent<MeshFilter>();
            }

            MeshRenderer meshrenderer = part.transform.GetComponent<MeshRenderer>();
            if (meshrenderer == null)
            {
                meshrenderer = part.transform.gameObject.AddComponent<MeshRenderer>();
            }

            Mesh umesh = new Mesh();

            umesh.name = part.gameObject.name;
            umesh.vertices = mesh.uVertices.ToArray();
            umesh.triangles = mesh.uTriangles.ToArray();

            if (ImportDistinctVertices)
                CADMeshTools.DistinctVertices(ref umesh);
            if (UnityRecalculateNormals)
                umesh.RecalculateNormals();
            if (AdvancedRecalculateNormals)
                CADMeshTools.RecalculateNormals(umesh, AdvancedRecalcluateNormalsAngle);
            if (CalculateUVS)
                CADMeshTools.CalculateUVS(ref umesh, UVScalfactor);
            if (ImportScaleFactor != 1)
                CADMeshTools.ScaleMesh(ref umesh, ImportScaleFactor);


            meshfilter.mesh = umesh;
        }


        private CADPart CreateCadPart(GameObject parent, string name, string Id, ThreeMfObject threemfobject)
        {
            var part = GetCADPart(Id);

            if (part == null)
            {
                // Create new part
                var newobj = new GameObject(name);
                part = newobj.AddComponent<CADPart>();
                newobj.transform.parent = parent.transform;
                newobj.transform.localPosition = new Vector3(0, 0, 0);
                newobj.transform.localEulerAngles = new Vector3(0, 0, 0);
            }

            part.Id = Id;
            part.Name = name;
            part.LastUpdate = System.DateTime.Now.ToString();
            part.Set3MFfObject(threemfobject);
            nosubcomponent.Add(part);
            return part;
        }


        public void MakeAsSubComponent(string idparent, string idchild, ThreeMfComponent component)
        {
            var parent = GetCADPart(idparent);
            var child = GetCADPart(idchild);
            nosubcomponent.Remove(child);
            CADPart comp;

            if (child.AssembledInto == null)
            {
                child.MakeAsSubCompponent(parent);
                comp = child;
            }
            else
            {
                // Is Allready assembled into another component - make copy
                var copy = child.CreateClone(NameClonesIdentical);
                copy.MakeAsSubCompponent(parent);
                comp = copy;
            }

            comp.ImportPos = component.Transform.GetPosition() * ImportScaleFactor;
            comp.ImportRotOriginal = component.Transform.Get3mfAngles();
            comp.ImportScale = component.Transform.GetScale();
            if (SetPositions)
            {
                comp.transform.localPosition = comp.ImportPos;
                comp.transform.localRotation = component.Transform.GetRotationQuaternion();
            }

            comp.ImportRot = comp.transform.localRotation.eulerAngles;
        }

        private CADPart GetCADPart(string id)
        {
            CADPart[] children = transform.GetComponentsInChildren<CADPart>();
            foreach (var child in children)
            {
                if (child.Id == id && child.IsClone == false)
                {
                    return child;
                }
            }

            return null;
        }

        public static object CreateAsset<T>() where T : ScriptableObject
        {
            T asset = ScriptableObject.CreateInstance<T>();
#if UNITY_EDITOR
            var find = AssetDatabase.FindAssets(
                "StandardMaterialMapping t:ScriptableObject");

            string path = AssetDatabase.GUIDToAssetPath(find[0]);
            var theasset = AssetDatabase.LoadAssetAtPath<ScriptableObject>(path);
            if (path == "")
            {
                path = "Assets";
            }
            else if (Path.GetExtension(path) != "")
            {
                path = path.Replace(Path.GetFileName(AssetDatabase.GetAssetPath(theasset)), "");
            }

            string assetPathAndName =
                AssetDatabase.GenerateUniqueAssetPath(path + "/New " + typeof(T).ToString() + ".asset");

            AssetDatabase.CreateAsset(asset, assetPathAndName);

            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
#endif
            return asset;
        }
    }
}

Thanks for the quick response.

I can confirm that fixes the colour problems.

I can't share the assembly we are having problems with as it's confidential. I will try to generate a model that replicates the problem.

Thanks

OK thanks. I am happy that at least the color problem is solved. We will also get solved the rest.  You could delete everything in the parts and just leave some primitives which show me how it should be positioned. You could also additionally send me the Solidedge file - this will allow me to compare both.

You should have received the files.

Further investigation makes me think I am only getting the problem with assembly positions when the data originated in a STEP file (although the 3mf file reads ok into other tools we have that read 3mf). Native Solid Edge models are importing ok.

OK thanks for the files. We received it. We will check it. Because we are nearly starting the weekend now it might take until Monday evening.

I can't open the Solidedge file - can you please send it as a Step file.

Step file sent.

Thanks for your help. Have a good weekend.

Hi Andrew,

this new code for CADLink.cs should fix your issue. Please check and give me feedback.

Thanks

Thomas

// Game4Automation (R) Framework for Automation Concept Design, Virtual Commissioning and 3D-HMI
// (c) 2019 in2Sight GmbH - Usage of this source code only allowed based on License conditions see https://game4automation.com/lizenz  

using System.IO;
using System.Linq;
using UnityEngine;
using NaughtyAttributes;
using ThreeMf;
using UnityEditor;
using System.Collections.Generic;
using UnityEngine.Analytics;
using UnityScript.Steps;

namespace game4automation
{
    public class CADLink : MonoBehaviour
    {
        [BoxGroup("Import CAD")] public string File;
        [BoxGroup("Import CAD")] public bool DeleteBeforeImporting;

        [BoxGroup("Import CAD")] public bool RemoveTopAssemblyNode = false;
        [BoxGroup("Import CAD")] public bool NameClonesIdentical;
        [BoxGroup("Import CAD")] public float ImportScaleFactor = 0.001f;

        [BoxGroup("Import CAD")] [ReadOnly] public string Status = "";

        [BoxGroup("Advanced")] public bool ImportDistinctVertices = true;
        [BoxGroup("Advanced")] public bool UnityRecalculateNormals = false;
        [BoxGroup("Advanced")] public bool AdvancedRecalculateNormals = true;

        [BoxGroup("Advanced")] [EnableIf("AdvancedRecalculateNormals")]
        public float AdvancedRecalcluateNormalsAngle = 30;

        [BoxGroup("Advanced")] [InfoBox("UV Mapping takes long - just use if needed")]
        public bool CalculateUVS = false;

        [EnableIf("CalculateUVS")] [BoxGroup("Advanced")]
        public float UVScalfactor = 1.0f;

        [BoxGroup("Materials")] public bool SetAndCreateMaterials = true;

        [BoxGroup("Materials")] [EnableIf("SetAndCreateMaterials")]
        public bool OverwriteExistingMaterials = false;

        [BoxGroup("Materials")] [EnableIf("SetAndCreateMaterials")]
        public string NewMaterialPath;

        [BoxGroup("Materials")] [EnableIf("SetAndCreateMaterials")]
        public MaterialMapping MaterialMapping;


        private bool SetPositions = true;

        private float Progress = 0;
        private bool cancel = false;

        private List<Material> newmaterials = new List<Material>();
        private List<CADPart> nosubcomponent = new List<CADPart>();

        [Button("Create New Material Mapping")]
        private void CreateMeaterialMapping()
        {
#if UNITY_EDITOR
            var mapping = CreateAsset<MaterialMapping>();

            MaterialMapping = (MaterialMapping) mapping;
#endif
        }

        [Button("Update Materials")]
        private void SetMaterials()
        {
            newmaterials.Clear();
            // Go through all CAD parts with meshes and check if material is assigned
            // if not assign next material of upper levels
            CADPart[] cadparts = GetComponentsInChildren<CADPart>(this);
            foreach (CADPart cadpart in cadparts)
            {
                MeshFilter meshfilter = cadpart.GetComponent<MeshFilter>();
                Renderer meshrenderer = cadpart.GetComponent<Renderer>();

                if (meshrenderer != null)
                {
                    // Part with Mesh has material assigned
                    if (cadpart.Color != "" || cadpart.Material != "")
                    {
                        meshrenderer.sharedMaterial = Get3mfMaterial(cadpart.Color, cadpart.Material);
                    }
                    else
                        // if not find next CADpart upwards with Material
                    {
                        Component[] uppercadparts = cadpart.GetComponentsInParent(typeof(CADPart), true);
                        foreach (CADPart uppercadpart in uppercadparts)
                        {
                            if (uppercadpart.Color != "")
                            {
                                meshrenderer.sharedMaterial = Get3mfMaterial(uppercadpart.Color, uppercadpart.Material);
                                break;
                            }
                        }
                    }
                }
            }
        }


        [Button("Select CAD Import File")]
        void SelectFile()
        {
#if UNITY_EDITOR
            File = EditorUtility.OpenFilePanel("Select file to import", File, "3mf");
#endif
        }


        [Button("Delete Import")]
        public void DeleteAll()
        {
            CADPart[] children = transform.GetComponentsInChildren<CADPart>();
            foreach (var child in children.ToArray())
            {
                if (child != null)
                    DestroyImmediate(child.gameObject);
            }
        }

        public void Log(string message)
        {
            Debug.Log("Game4Automation CAD Import: " + message);
#if UNITY_EDITOR
            cancel = EditorUtility.DisplayCancelableProgressBar(
                "CAD Livelink - Import",
                message,
                Progress);
#endif
            Status = message;
        }


        [Button("Import CAD File")]
        public void ImportCad()
        {
            cancel = false;
            if (!System.IO.File.Exists(File))
            {
#if UNITY_EDITOR
                EditorUtility.DisplayDialog("ERROR", "3MF File at defined path [" + File + "] not existing.", "OK", "");
                return;
#endif
                Debug.LogError("3MF File at defined path [" + File + "] not existing.");
            }

            if (!Directory.Exists(NewMaterialPath) && SetAndCreateMaterials)
            {
#if UNITY_EDITOR
                EditorUtility.DisplayDialog("ERROR", "New material path [" + NewMaterialPath + "] not existing.", "OK",
                    "");
                return;
#endif
                Debug.LogError("3MF File at defined path [" + File + "] not existing.");
            }

            if (DeleteBeforeImporting)
                DeleteAll();
            Progress = 0.05f;
            var num = 0;
            nosubcomponent.Clear();
            Log("Load 3MF File");

            var test = ThreeMfFile.Load(File, 1);
            Debug.Log("Import 3MF");
            // Import Positions and Meshes for all Ressources
            foreach (var model in test.Models)
            {
                foreach (var resource in model.Resources)
                {
                    num++;
                    Progress = (float) num / (float) model.Resources.Count;
                    if (cancel)
                    {
                        Debug.Log("Import Canceled by User");
                        #if UNITY_EDITOR
                            EditorUtility.ClearProgressBar();
                        #endif
                        return;
                    }

                    if (resource.GetType() == typeof(ThreeMfObject))
                    {
                        var obj = (ThreeMfObject) resource;
                        Log("Import Part " + obj.Name + " " + obj.Id.ToString());

                        var part = CreateCadPart(this.gameObject, obj.Name, obj.Id.ToString(), obj);
                        part.File = File;
                        part.LastUpdate = System.DateTime.Now.ToString();
                        // Mesh at Part
                        if (obj.Mesh != null)
                        {
                            CreateMesh(part, obj.Mesh);
                        }
                        
                        // Get Porpertyindex

                        var propindex = obj.PropertyIndex;
                        
                        // Properties at Part
                        if (obj.PropertyResource != null)
                        {
                            if (obj.PropertyResource.PropertyItems != null)
                            {

                                var currindex = 0;
                               foreach (var propertyItem in obj.PropertyResource.PropertyItems)
                                {
                                    if (currindex == propindex)
                                    {
                                        Material material = null;
                                        if (propertyItem.GetType() == typeof(ThreeMfColor))
                                        {
                                            var color = (ThreeMfColor) propertyItem;
                                            part.Color = color.Color.ToString();
                                            part.Material = "";
                                        }

                                        if (propertyItem.GetType() == typeof(ThreeMfBase))
                                        {
                                            var color = (ThreeMfBase) propertyItem;
                                            part.Color = color.Color.ToString();
                                            part.Material = color.Name;
                                        }
                                    }

                                    currindex = currindex + 1;
                                }
                            }
                        }

                        foreach (var component in obj.Components)
                        {
                            MakeAsSubComponent(obj.Id.ToString(), component.Object.Id.ToString(), component);
                        }
                    }
                }

                // Set Positions for Build information
                foreach (var item in model.Items)
                {
                   SetBuildPosition(item);
                }
                

            }
            
       

            if (SetAndCreateMaterials)
                SetMaterials();

            if (RemoveTopAssemblyNode)
                RemoveTopAssembly();

            #if UNITY_EDITOR
                 EditorUtility.ClearProgressBar();
            #endif
        }

        private void RemoveTopAssembly()
        {
            var top = nosubcomponent[0];
            List<GameObject> children = new List<GameObject>();
            if (top != null)
            {
                for (int i = 0; i < top.transform.childCount; i++)
                {
                    children.Add(top.transform.GetChild(i).gameObject);
                }
            }

            foreach (var child in children)
            {
                child.transform.parent = this.transform;
            }

            DestroyImmediate(top.gameObject);
        }


        private Material Get3mfMaterial(string colorname, string materialname)
        {
            
            Material newmaterial = null;


            //    colorname.Replace("#", "Hex");
            var tempMaterial = new Material(Shader.Find("Standard"));

            // check if material assignment in material mapping
            // 1st check if color and material combination are defined
            if (MaterialMapping != null)
            {
                foreach (var mapping in MaterialMapping.Mappings)
                {
                    if (mapping.Colorname == colorname && mapping.Materialname == materialname)
                        return mapping.Material;
                }
            }

            // 2nd check if material is defined 
            if (MaterialMapping != null)
            {
                foreach (var mapping in MaterialMapping.Mappings)
                {
                    if (mapping.Materialname == materialname && mapping.Materialname != "")
                        return mapping.Material;
                }
            }

            // 3rd check if color is defined 
            if (MaterialMapping != null)
            {
                foreach (var mapping in MaterialMapping.Mappings)
                {
                    if (mapping.Colorname == colorname && mapping.Colorname != "")
                        return mapping.Material;
                }
            }

            #if UNITY_EDITOR         
            // create new material if not existing
            string[] assets = AssetDatabase.FindAssets(colorname + " t:material");

            bool createnewmaterial = true;

            if (assets.Length != 0 && OverwriteExistingMaterials == false)
            {
                createnewmaterial = false;
            }

            if (assets.Length != 0 && OverwriteExistingMaterials == true)
            {
                newmaterial = AssetDatabase.LoadAssetAtPath<Material>(AssetDatabase.GUIDToAssetPath(assets[0]));

                if (newmaterials.Contains(newmaterial))
                {
                    createnewmaterial = false;
                }
                else
                {
                    createnewmaterial = true;
                    AssetDatabase.DeleteAsset(AssetDatabase.GUIDToAssetPath(assets[0]));
                }
            }

            if (createnewmaterial)
            {
                var path = Path.Combine(NewMaterialPath, colorname + ".mat");
                AssetDatabase.CreateAsset(tempMaterial, path);
                newmaterial = AssetDatabase.LoadAssetAtPath<Material>(path);
                newmaterials.Add(newmaterial);
                var col = new Color();
                ColorUtility.TryParseHtmlString(colorname, out col);
                newmaterial.color = col;
            }
            else
            {
                newmaterial = AssetDatabase.LoadAssetAtPath<Material>(AssetDatabase.GUIDToAssetPath(assets[0]));
            }
            #else
                newmaterial =  new Material(Shader.Find("Standard"));   
                var col = new Color();
                ColorUtility.TryParseHtmlString(colorname, out col);
                newmaterial.color = col;
            #endif
            
            

            return newmaterial;
        }

        private void CreateMesh(CADPart part, ThreeMfMesh mesh)
        {
            MeshFilter meshfilter = part.transform.GetComponent<MeshFilter>();
            if (meshfilter == null)
            {
                meshfilter = part.transform.gameObject.AddComponent<MeshFilter>();
            }

            MeshRenderer meshrenderer = part.transform.GetComponent<MeshRenderer>();
            if (meshrenderer == null)
            {
                meshrenderer = part.transform.gameObject.AddComponent<MeshRenderer>();
            }

            Mesh umesh = new Mesh();

            umesh.name = part.gameObject.name;
            umesh.vertices = mesh.uVertices.ToArray();
            umesh.triangles = mesh.uTriangles.ToArray();

            if (ImportDistinctVertices)
                CADMeshTools.DistinctVertices(ref umesh);
            if (UnityRecalculateNormals)
                umesh.RecalculateNormals();
            if (AdvancedRecalculateNormals)
                CADMeshTools.RecalculateNormals(umesh, AdvancedRecalcluateNormalsAngle);
            if (CalculateUVS)
                CADMeshTools.CalculateUVS(ref umesh, UVScalfactor);
            if (ImportScaleFactor != 1)
                CADMeshTools.ScaleMesh(ref umesh, ImportScaleFactor);


            meshfilter.mesh = umesh;
        }


        private CADPart CreateCadPart(GameObject parent, string name, string Id, ThreeMfObject threemfobject)
        {
            var part = GetCADPart(Id);

            if (part == null)
            {
                // Create new part
                var newobj = new GameObject(name);
                part = newobj.AddComponent<CADPart>();
                newobj.transform.parent = parent.transform;
                newobj.transform.localPosition = new Vector3(0, 0, 0);
                newobj.transform.localEulerAngles = new Vector3(0, 0, 0);
            }

            part.Id = Id;
            part.Name = name;
            part.LastUpdate = System.DateTime.Now.ToString();
            part.Set3MFfObject(threemfobject);
            nosubcomponent.Add(part);
            return part;
        }


        public void SetBuildPosition(ThreeMfModelItem item)
        {
            var id = item.Object.Id.ToString();
            var comp = GetCADPart(id);
            
            comp.ImportPos = item.Transform.GetPosition() * ImportScaleFactor;
            comp.ImportRotOriginal = item.Transform.Get3mfAngles();
            comp.ImportScale = item.Transform.GetScale();
            if (SetPositions)
            {
                comp.transform.localPosition = comp.ImportPos;
                comp.transform.localRotation = item.Transform.GetRotationQuaternion();
            }

            comp.ImportRot = comp.transform.localRotation.eulerAngles;    
        }
        
        
        public void MakeAsSubComponent(string idparent, string idchild, ThreeMfComponent component)
        {
            var parent = GetCADPart(idparent);
            var child = GetCADPart(idchild);
            nosubcomponent.Remove(child);
            CADPart comp;

            if (child.AssembledInto == null)
            {
                child.MakeAsSubCompponent(parent);
                comp = child;
            }
            else
            {
                // Is Allready assembled into another component - make copy
                var copy = child.CreateClone(NameClonesIdentical);
                copy.MakeAsSubCompponent(parent);
                comp = copy;
            }

            comp.ImportPos = component.Transform.GetPosition() * ImportScaleFactor;
            comp.ImportRotOriginal = component.Transform.Get3mfAngles();
            comp.ImportScale = component.Transform.GetScale();
            if (SetPositions)
            {
                comp.transform.localPosition = comp.ImportPos;
                comp.transform.localRotation = component.Transform.GetRotationQuaternion();
            }

            comp.ImportRot = comp.transform.localRotation.eulerAngles;
        }

        private CADPart GetCADPart(string id)
        {
            CADPart[] children = transform.GetComponentsInChildren<CADPart>();
            foreach (var child in children)
            {
                if (child.Id == id && child.IsClone == false)
                {
                    return child;
                }
            }

            return null;
        }

        public static object CreateAsset<T>() where T : ScriptableObject
        {
            T asset = ScriptableObject.CreateInstance<T>();
#if UNITY_EDITOR
            var find = AssetDatabase.FindAssets(
                "StandardMaterialMapping t:ScriptableObject");

            string path = AssetDatabase.GUIDToAssetPath(find[0]);
            var theasset = AssetDatabase.LoadAssetAtPath<ScriptableObject>(path);
            if (path == "")
            {
                path = "Assets";
            }
            else if (Path.GetExtension(path) != "")
            {
                path = path.Replace(Path.GetFileName(AssetDatabase.GetAssetPath(theasset)), "");
            }

            string assetPathAndName =
                AssetDatabase.GenerateUniqueAssetPath(path + "/New " + typeof(T).ToString() + ".asset");

            AssetDatabase.CreateAsset(asset, assetPathAndName);

            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
#endif
            return asset;
        }
    }
}

If everything is OK it will be included in the next release (which will be available in the Asset Store most probably tomorrow).

Hi.

I was getting:

error CS0246: The type or namespace name 'UnityScript' could not be found (are you missing a using directive or an assembly reference

but it appears that you aren't using UnityScript so I removed this line..

I tried it on our large assembly and it all works well.

Thanks for the excellent support.

Andy

Answer

Hi Andy, oh sorry. Yes you can remove this line.

Give us a good feedback in the Unity Store if you are happy with our solution. Thanks.


Thomas

Review written. Thanks again. Andy