public void AddGameObject(GameObject go, GameObject bakedBone)
        {
            Mesh mesh = go.GetMesh();

            if (mesh != null)
            {
                Matrix4x4 m_LOCAL_to_WORLD         = go.transform.localToWorldMatrix;
                Matrix4x4 m_LOCAL_to_LOCALCOMBINED = m_WORLD_to_LOCALCOMBINED_ * m_LOCAL_to_WORLD;

                Mesh meshAux;
                CRGeometryUtils.CreateMeshTransformed(mesh, m_LOCAL_to_LOCALCOMBINED, out meshAux);

                Vector3[] arrVertex  = meshAux.vertices;
                Vector3[] arrNormal  = meshAux.normals;
                Vector2[] arrUV      = meshAux.uv;
                Vector4[] arrTangent = meshAux.tangents;

                Renderer rn = go.GetComponent <Renderer>();
                if (rn != null)
                {
                    Material[] arrMaterial = rn.sharedMaterials;
                    AddMaterials(arrMaterial);
                }

                AddMesh(go, bakedBone, meshAux, arrVertex, arrNormal, arrUV, arrTangent);
                goOffset++;

                UnityEngine.Object.DestroyImmediate(meshAux);
            }
        }
        private bool AreFingerprintsValidAnimatedByArrPos()
        {
            bool isValid = true;

            Mesh renderMesh;

            gameObject_.GetBakedMesh(out renderMesh);

            byte[] fingerPrint = new byte[256];
            if (renderFingerprint_ != null)
            {
                if (renderMesh != null)
                {
                    CRGeometryUtils.CalculateFingerprint(renderMesh, fingerPrint);
                    isValid &= CRGeometryUtils.AreFingerprintsEqual(fingerPrint, renderFingerprint_);
                }
                else
                {
                    return(false);
                }
            }

            if (renderMesh != null)
            {
                Object.DestroyImmediate(renderMesh);
            }

            return(true);
        }
        private bool ChopModeGeometry(ChopRequest cr)
        {
            if ((Data.ChopGeometry == null) || !Data.ChopGeometry.HasMesh() || Data.NDesiredPieces <= 0)
            {
                return(false);
            }

            Matrix4x4 m_Local_to_World = Data.ChopGeometry.transform.localToWorldMatrix;

            UnityEngine.Mesh un_chopGeometry = Data.ChopGeometry.GetMesh();

            UnityEngine.Mesh transformedMesh;
            CRGeometryUtils.CreateMeshTransformed(un_chopGeometry, m_Local_to_World, out transformedMesh);

            CaronteSharp.MeshSimple car_chopGeometry = new CaronteSharp.MeshSimple();
            car_chopGeometry.Set(transformedMesh);
            Object.DestroyImmediate(transformedMesh);

            cr.nDesiredPieces_    = (uint)Data.NDesiredPieces;
            cr.meshFocusGeometry_ = car_chopGeometry;
            cr.focusMode_         = (PSBG_FOCUS_MODE)Data.FocusMode;
            cr.gridResolution_    = (uint)Data.GridResolution;
            cr.densityRate_       = Data.DensityRate;
            cr.transitionLength_  = Data.TransitionLength;
            cr.doExtrusionEffect_ = Data.DoExtrusionEffect;
            cr.doCoordinate_      = Data.DoCoordinate;

            return(true);
        }
        public CRCreationData(GameObject go, BodyType bodyType, Mesh renderMesh, Mesh colliderMesh, bool isConvex)
        {
            gameObject_   = go;
            bodyType_     = bodyType;
            isConvexHull_ = isConvex;

            renderFingerprint_   = null;
            colliderFingerprint_ = null;

            if (renderMesh != null)
            {
                renderFingerprint_ = new byte[256];
                CRGeometryUtils.CalculateFingerprint(renderMesh, renderFingerprint_);
            }

            if (colliderMesh != null)
            {
                colliderFingerprint_ = new byte[256];
                CRGeometryUtils.CalculateFingerprint(colliderMesh, colliderFingerprint_);
            }

            position_ = go.transform.position;
            rotation_ = go.transform.rotation;
            scale_    = go.transform.lossyScale;
        }
        //-----------------------------------------------------------------------------------
        private void GetFieldLocators(CNFieldController fieldController, out Vector3[] arrLocations)
        {
            GameObject[] gameObjects = fieldController.GetUnityGameObjects();

            List <Vector3> listLocatorPosition = new List <Vector3>();

            switch (Data.CreationMode)
            {
            case CNJointGroups.CreationModeEnum.AtLocatorsPositions:
                for (int i = 0; i < gameObjects.Length; i++)
                {
                    Transform tr = gameObjects[i].transform;
                    if (tr.childCount == 0)
                    {
                        listLocatorPosition.Add(tr.position);
                    }
                }
                break;

            case CNJointGroups.CreationModeEnum.AtLocatorsBBoxCenters:
                for (int i = 0; i < gameObjects.Length; ++i)
                {
                    Renderer renderer = gameObjects[i].GetComponent <Renderer>();
                    if (renderer != null)
                    {
                        Bounds bbox = renderer.bounds;
                        listLocatorPosition.Add(bbox.center);
                    }
                }
                break;

            case CNJointGroups.CreationModeEnum.AtLocatorsVertexes:
                for (int i = 0; i < gameObjects.Length; ++i)
                {
                    GameObject go         = gameObjects[i];
                    MeshFilter meshFilter = go.GetComponent <MeshFilter>();

                    if (meshFilter != null && meshFilter.sharedMesh != null)
                    {
                        UnityEngine.Mesh mesh = meshFilter.sharedMesh;
                        UnityEngine.Mesh meshTransformed;

                        CRGeometryUtils.CreateMeshTransformed(mesh, go.transform.localToWorldMatrix, out meshTransformed);
                        Vector3[] meshVertices = meshTransformed.vertices;
                        for (int j = 0; j < meshVertices.Length; ++j)
                        {
                            listLocatorPosition.Add(meshVertices[j]);
                        }

                        UnityEngine.Object.DestroyImmediate(meshTransformed);
                    }
                }
                break;

            default:
                break;
            }

            arrLocations = listLocatorPosition.ToArray();
        }
        private WeldRequest GetWeldRequest()
        {
            WeldRequest wr = new WeldRequest();

            GameObject go = Data.CropGeometry;

            if (go != null)
            {
                Mesh mesh = go.GetMesh();

                if (mesh != null)
                {
                    UnityEngine.Mesh transformedMesh;

                    Matrix4x4 m_Local_to_World = go.transform.localToWorldMatrix;
                    CRGeometryUtils.CreateMeshTransformed(mesh, m_Local_to_World, out transformedMesh);

                    MeshSimple cropGeometry = new MeshSimple();
                    cropGeometry.Set(transformedMesh);
                    Object.DestroyImmediate(transformedMesh);

                    wr.meshCropGeometry_ = cropGeometry;
                }
            }

            wr.cropMode_ = (CROP_MODE)Data.CropMode;
            wr.weldAllRemainingsTogether_    = Data.WeldInOnePiece;
            wr.includeBoundary_              = Data.FrontierPieces;
            wr.isAbleToClassifyDisconnected_ = true;

            return(wr);
        }
Ejemplo n.º 7
0
        public static void CreateMeshesFromCaronte(CaronteSharp.MeshComplex[] arrCaronteMesh, out UnityEngine.Mesh[] arrMesh, out Tuple2 <int, int>[] arrSubmeshRange, out int[] meshComplexIndex)
        {
            int numMeshes = arrCaronteMesh.Length;

            List <Mesh> listMesh = new List <Mesh>();
            List <Tuple2 <int, int> > listSubmeshRange = new List <Tuple2 <int, int> >();
            List <int> listMeshComplexIndex            = new List <int>();

            for (int i = 0; i < numMeshes; i++)
            {
                CaronteSharp.MeshComplex caronteMesh = arrCaronteMesh[i];

                Mesh[] arrAuxMesh;
                Tuple2 <int, int>[] arrAuxSubmeshRange;

                CRGeometryUtils.CreateMeshesFromComplex(caronteMesh, out arrAuxMesh, out arrAuxSubmeshRange);
                listMesh.AddRange(arrAuxMesh);
                listSubmeshRange.AddRange(arrAuxSubmeshRange);

                for (int j = 0; j < arrAuxMesh.Length; j++)
                {
                    listMeshComplexIndex.Add(i);
                }
            }

            arrMesh          = listMesh.ToArray();
            arrSubmeshRange  = listSubmeshRange.ToArray();
            meshComplexIndex = listMeshComplexIndex.ToArray();
        }
        private void CreateMeshPiecesUnity(List <GameObject> listChoppedParentGO, CaronteSharp.MeshComplex[] arrMeshPieceCaronte, CaronteSharp.MeshParentInfo[] arrMeshParentInfo, Vector3[] arrMeshPosition,
                                           out UnityEngine.Mesh[] arrMeshPieceUnity, out Tuple2 <int, int>[] arrSubmeshRange, out int[] arrMeshComplexIndex)
        {
            if (arrMeshPieceCaronte.Length == 0)
            {
                arrMeshPieceUnity = new UnityEngine.Mesh[0];
            }

            CRGeometryUtils.CreateMeshesFromCaronte(arrMeshPieceCaronte, out arrMeshPieceUnity, out arrSubmeshRange, out arrMeshComplexIndex);
        }
Ejemplo n.º 9
0
        private static void CreateMeshCollapsedUnity(string name, MeshComplex mesh_COLLAPSED_car, ArrayIndex mesh_COLLAPSED_info, GameObject boundsObject,
                                                     List <Material> listMaterial, out GameObject[] arrGameObject, out Mesh[] arrMesh)
        {
            UnityEngine.Mesh[]  arrMesh_COLLAPSED_un;
            Tuple2 <int, int>[] arrSubmeshRange;

            CRGeometryUtils.CreateMeshesFromComplex(mesh_COLLAPSED_car, out arrMesh_COLLAPSED_un, out arrSubmeshRange);

            int nMeshUnity = arrMesh_COLLAPSED_un.Length;

            List <GameObject> listGameObject = new List <GameObject>();
            List <Mesh>       listMesh       = new List <Mesh>();

            for (int i = 0; i < nMeshUnity; i++)
            {
                Mesh mesh_COLLAPSED_un = arrMesh_COLLAPSED_un[i];
                mesh_COLLAPSED_un.name = name + "_" + i;
                listMesh.Add(mesh_COLLAPSED_un);

                GameObject go = Object.Instantiate(boundsObject);
                go.name = name + "_" + i;
                go.AddMesh(mesh_COLLAPSED_un);
                listGameObject.Add(go);

                Tuple2 <int, int> submeshRange = arrSubmeshRange[i];

                List <Material> collapsedMaterials = new List <Material>();
                uint[]          arrMaterialIdx     = mesh_COLLAPSED_info.arrIdx_;

                for (int j = submeshRange.First; j <= submeshRange.Second; j++)
                {
                    uint materialIdx = arrMaterialIdx[j];
                    if (materialIdx != uint.MaxValue)
                    {
                        Material mat = listMaterial[(int)materialIdx];
                        collapsedMaterials.Add(mat);
                    }
                    else
                    {
                        collapsedMaterials.Add(null);
                    }
                }

                Renderer renderer = go.GetComponent <Renderer>();
                renderer.sharedMaterials = collapsedMaterials.ToArray();
            }

            arrGameObject = listGameObject.ToArray();
            arrMesh       = listMesh.ToArray();
        }
        public void CreateHelperMesh()
        {
            EditorUtility.DisplayProgressBar(Data.Name, "Creating helper mesh...", 1.0f);
            MeshSimple helperMesh_un;

            CaronteSharp.Tools.CreateHelperMesh(Data.RandomSeed, Data.Resolution + 2, Data.NBumps, Data.RadiusMin, Data.RadiusMax, out helperMesh_un);

            Mesh helperMesh;

            CRGeometryUtils.CreateMeshFromSimple(helperMesh_un, out helperMesh);

            helperMesh.name = Data.Name;

            GameObject go = new GameObject();

            go.name = Data.Name;
            MeshFilter mf = go.AddComponent <MeshFilter>();

            mf.sharedMesh = helperMesh;

            MeshRenderer mr = go.AddComponent <MeshRenderer>();

            mr.sharedMaterial = material_;

            if (Data.HelperGO != null)
            {
                go.transform.parent        = Data.HelperGO.transform.parent;
                go.transform.localPosition = Data.HelperGO.transform.localPosition;
                go.transform.localRotation = Data.HelperGO.transform.localRotation;
                go.transform.localScale    = Data.HelperGO.transform.localScale;

                Object.DestroyImmediate(Data.HelperGO);
            }

            if (Data.HelperMesh != null)
            {
                Object.DestroyImmediate(Data.HelperMesh);
            }

            Data.HelperMesh = helperMesh;
            Data.HelperGO   = go;

            UnityEditor.Selection.activeGameObject = go;

            EditorUtility.ClearProgressBar();
        }
Ejemplo n.º 11
0
        public void Weld()
        {
            GameObject[] arrGOtoWeld = FieldController.GetUnityGameObjects();

            int arrGOtoWeld_size = arrGOtoWeld.Length;

            if (arrGOtoWeld_size == 0)
            {
                EditorUtility.DisplayDialog("CaronteFX", "Input objects are mandatory", "Ok");
                return;
            }

            GameObject[] arrWeldedObject;
            Mesh[]       arrWeldedMesh;
            int          interiorMaterialIdx;

            EditorUtility.DisplayProgressBar(Data.Name, "Welding...", 1.0f);
            CRGeometryUtils.WeldObjects(arrGOtoWeld, Data.Name, null, out arrWeldedObject, out arrWeldedMesh, out interiorMaterialIdx);
            EditorUtility.ClearProgressBar();

            if (cnManager.IsFreeVersion() && arrWeldedObject == null)
            {
                EditorUtility.DisplayDialog("CaronteFX - Free version", "CaronteFX Free version can only weld the meshes included in the example scenes and the unity primitives (cube, plane, sphere, etc.).", "Ok");
            }

            if (arrWeldedObject != null)
            {
                List <GameObject> listWeldedObjects = new List <GameObject>();
                listWeldedObjects.AddRange(arrWeldedObject);

                Bounds bounds = CREditorUtils.GetGlobalBoundsWorld(listWeldedObjects);

                GameObject go = new GameObject(Data.Name + "_output");
                go.transform.position = bounds.center;

                foreach (GameObject weldedGO in listWeldedObjects)
                {
                    weldedGO.transform.parent = go.transform;
                }

                Data.WeldGameObject = go;

                UnityEditor.Selection.activeGameObject = go;
            }
        }
        public void Tessellate()
        {
            GameObject[] arrGOtoTessellate = FieldController.GetUnityGameObjects();

            DeleteOldObjects();

            GameObject[] arrGOTessellated;
            Mesh[]       arrMeshTessellated;

            EditorUtility.DisplayProgressBar(Data.Name, "Tessellating...", 1.0f);
            CRGeometryUtils.TessellateObjects(arrGOtoTessellate, Data.MaxEdgeDistance, Data.LimitByMeshDimensions, out arrGOTessellated, out arrMeshTessellated);
            EditorUtility.ClearProgressBar();

            if (cnManager.IsFreeVersion() && arrGOTessellated == null)
            {
                EditorUtility.DisplayDialog("CaronteFX - Free version", "CaronteFX Free version can only tessellate the meshes included in the example scenes and the unity primitives (cube, plane, sphere, etc.).", "Ok");
            }

            if (arrGOTessellated != null)
            {
                List <GameObject> listGameObject = new List <GameObject>();
                listGameObject.AddRange(arrGOTessellated);

                Bounds     bounds = CREditorUtils.GetGlobalBoundsWorld(listGameObject);
                GameObject nodeGO = new GameObject(Data.Name);

                nodeGO.transform.position = bounds.center;

                foreach (GameObject go in arrGOTessellated)
                {
                    go.transform.parent = nodeGO.transform;
                }

                Data.NodeGO             = nodeGO;
                Data.ArrTessellatedGO   = arrGOTessellated;
                Data.ArrTessellatedMesh = arrMeshTessellated;

                Selection.activeGameObject = nodeGO;
            }
        }
Ejemplo n.º 13
0
        public static void TransformListMesh(List <GameObject> listParentGO, List <UnityEngine.Mesh> listMesh_un, Matrix4x4 m_BoundsWorld_to_BoundsLocal, out List <CaronteSharp.MeshComplex> listMesh_car)
        {
            listMesh_car = new List <CaronteSharp.MeshComplex>();
            int numParentGameObjects = listParentGO.Count;

            for (int i = 0; i < numParentGameObjects; ++i)
            {
                UnityEngine.Mesh un_mesh   = listMesh_un[i];
                GameObject       parent_go = listParentGO[i];

                Matrix4x4 m_Local_to_World  = parent_go.transform.localToWorldMatrix;
                Matrix4x4 m_Local_to_Bounds = m_BoundsWorld_to_BoundsLocal * m_Local_to_World;

                UnityEngine.Mesh transformedMesh;
                CRGeometryUtils.CreateMeshTransformed(un_mesh, m_Local_to_Bounds, out transformedMesh);

                CaronteSharp.MeshComplex car_mesh = new CaronteSharp.MeshComplex();
                car_mesh.Set(transformedMesh);

                UnityEngine.Object.DestroyImmediate(transformedMesh);
                listMesh_car.Add(car_mesh);
            }
        }
        private bool AreFingerprintsValidNonAnimatedByArrPos()
        {
            bool isValid = true;

            Mesh renderMesh = gameObject_.GetMesh();

            byte[] fingerPrint = new byte[256];
            if (renderFingerprint_ != null)
            {
                if (renderMesh != null)
                {
                    CRGeometryUtils.CalculateFingerprint(renderMesh, fingerPrint);
                    isValid &= CRGeometryUtils.AreFingerprintsEqual(fingerPrint, renderFingerprint_);
                }
                else
                {
                    return(false);
                }
            }

            if (colliderFingerprint_ != null)
            {
                Caronte_Fx_Body fxBody = gameObject_.GetComponent <Caronte_Fx_Body>();
                if (fxBody != null)
                {
                    if (fxBody.IsConvexHull() != isConvexHull_)
                    {
                        return(false);
                    }

                    if (fxBody.tileMesh_ != null)
                    {
                        CRGeometryUtils.CalculateFingerprint(fxBody.tileMesh_, fingerPrint);
                        isValid &= CRGeometryUtils.AreFingerprintsEqual(fingerPrint, colliderFingerprint_);
                    }
                    else if (fxBody.colliderType_ == Caronte_Fx_Body.ColliderType.MeshFilter)
                    {
                        if (renderMesh != null)
                        {
                            CRGeometryUtils.CalculateFingerprint(renderMesh, fingerPrint);
                            isValid &= CRGeometryUtils.AreFingerprintsEqual(fingerPrint, colliderFingerprint_);
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    else if (fxBody.colliderType_ == Caronte_Fx_Body.ColliderType.MeshFilterConvexHull)
                    {
                        if (renderMesh != null)
                        {
                            CRGeometryUtils.CalculateFingerprint(renderMesh, fingerPrint);
                            isValid &= CRGeometryUtils.AreFingerprintsEqual(fingerPrint, colliderFingerprint_);
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    else if (fxBody.colliderType_ == Caronte_Fx_Body.ColliderType.CustomMesh)
                    {
                        Mesh colliderMesh = fxBody.colliderMesh_;
                        if (colliderMesh != null)
                        {
                            CRGeometryUtils.CalculateFingerprint(colliderMesh, fingerPrint);
                            isValid &= CRGeometryUtils.AreFingerprintsEqual(fingerPrint, colliderFingerprint_);
                        }
                        else if (renderMesh != null)
                        {
                            CRGeometryUtils.CalculateFingerprint(renderMesh, fingerPrint);
                            isValid &= CRGeometryUtils.AreFingerprintsEqual(fingerPrint, colliderFingerprint_);
                        }
                        else
                        {
                            return(false);
                        }
                    }
                }
                else
                {
                    return(false);
                }
            }
            return(isValid);
        }
        public void ClassifySelection()
        {
            GameObject selectorGO = Data.SelectorGO;

            if (selectorGO == null)
            {
                EditorUtility.DisplayDialog("CaronteFX", "A selector geometry is mandatory", "Ok");
                return;
            }

            Mesh selectorMesh = selectorGO.GetMesh();

            if (selectorMesh == null)
            {
                EditorUtility.DisplayDialog("CaronteFX", "A selector geometry is mandatory", "Ok");
                return;
            }

            EditorUtility.DisplayProgressBar(Data.Name, "Selecting...", 1.0f);
            GameObject[] arrGOtoClassify = FieldController.GetUnityGameObjects();

            Mesh auxSelectorMesh;

            CRGeometryUtils.CreateMeshTransformed(selectorMesh, selectorGO.transform.localToWorldMatrix, out auxSelectorMesh);

            MeshSimple auxCropMesh_un = new MeshSimple();

            auxCropMesh_un.Set(auxSelectorMesh);
            Object.DestroyImmediate(auxSelectorMesh);

            int nGameObjectToClassify = arrGOtoClassify.Length;

            List <GameObject> listGOToClassify         = new List <GameObject>();
            List <MeshSimple> listAuxMeshToClassify_un = new List <MeshSimple>();

            for (int i = 0; i < nGameObjectToClassify; i++)
            {
                GameObject go             = arrGOtoClassify[i];
                Mesh       meshToClassify = go.GetMesh();

                if (meshToClassify != null)
                {
                    listGOToClassify.Add(go);

                    Mesh auxMeshToClassify;
                    CRGeometryUtils.CreateMeshTransformed(meshToClassify, go.transform.localToWorldMatrix, out auxMeshToClassify);
                    MeshSimple auxMeshToClassify_un = new MeshSimple();
                    auxMeshToClassify_un.Set(auxMeshToClassify);

                    Object.DestroyImmediate(auxMeshToClassify);
                    listAuxMeshToClassify_un.Add(auxMeshToClassify_un);
                }
            }

            int[] arrIdxClassified;
            CaronteSharp.Tools.SplitInsideOutsideByGeometry(listAuxMeshToClassify_un.ToArray(), auxCropMesh_un, out arrIdxClassified, Data.FrontierPieces, true);

            List <GameObject> listGameObjectOutside = new List <GameObject>();
            List <GameObject> listGameObjectInside  = new List <GameObject>();

            for (int i = 0; i < arrIdxClassified.Length; i++)
            {
                int idxClassified = arrIdxClassified[i];

                GameObject go = listGOToClassify[i];

                if (idxClassified == 0)
                {
                    listGameObjectOutside.Add(go);
                }
                else if (idxClassified == 1)
                {
                    listGameObjectInside.Add(go);
                }
            }

            if (Data.SelectionMode == CNSelector.SELECTION_MODE.OUTSIDE)
            {
                if (Data.Complementary)
                {
                    Selection.objects = listGameObjectInside.ToArray();
                }
                else
                {
                    Selection.objects = listGameObjectOutside.ToArray();
                }
            }
            else if (Data.SelectionMode == CNSelector.SELECTION_MODE.INSIDE)
            {
                if (Data.Complementary)
                {
                    Selection.objects = listGameObjectOutside.ToArray();
                }
                else
                {
                    Selection.objects = listGameObjectInside.ToArray();
                }
            }

            EditorUtility.ClearProgressBar();
        }
        private void CreateNewObjects(Vector3 position, List <GameObject> listParentGO, List <GameObject> listChoppedParentGO, CaronteSharp.MeshParentInfo[] arrMeshParentInfo,
                                      UnityEngine.Mesh[] arrMeshPieceUnity, Tuple2 <int, int>[] arrSubmeshRange, int[] arrMeshComplexIdx, Vector3[] arrMeshPosition, uint[] arrOutsideInsideIdx)
        {
            List <GameObject> listChoppedGO = new List <GameObject>();

            List <Tuple2 <GameObject, GameObject> > listOutsideInsideGOParent = new List <Tuple2 <GameObject, GameObject> >();
            bool hasBeenSplitted = arrOutsideInsideIdx != null;

            // Create InsideOutSidePieces
            for (int i = 0; i < listParentGO.Count; i++)
            {
                GameObject parentGO     = listParentGO[i];
                GameObject chopParentGO = listChoppedParentGO[i];

                if (hasBeenSplitted)
                {
                    GameObject outsideGO = parentGO.CreateDummy(parentGO.name + "_outside");
                    GameObject insideGO  = parentGO.CreateDummy(parentGO.name + "_inside");

                    outsideGO.transform.parent = chopParentGO.transform;
                    insideGO.transform.parent  = chopParentGO.transform;

                    listOutsideInsideGOParent.Add(Tuple2.New(outsideGO, insideGO));
                }

                if (Data.HideParentObjectAuto)
                {
                    Undo.RecordObject(parentGO, "Change activate state - " + parentGO.name);
                    parentGO.SetActive(false);
                    EditorUtility.SetDirty(parentGO);
                }
            }

            //Create Chopped Pieces
            Dictionary <GameObject, int> dictChoppedGOInteriorSubmeshIdx = new Dictionary <GameObject, int>();

            int nMeshPieces = arrMeshPieceUnity.Length;

            for (int i = 0; i < nMeshPieces; i++)
            {
                UnityEngine.Mesh  meshPiece    = arrMeshPieceUnity[i];
                Tuple2 <int, int> submeshRange = arrSubmeshRange[i];
                int     meshComplexIdx         = arrMeshComplexIdx[i];
                Vector3 goPosition             = arrMeshPosition[i];

                MeshParentInfo parentInfo = arrMeshParentInfo[meshComplexIdx];
                int            parentIdx  = (int)parentInfo.parentMeshIdx_;

                GameObject parentGO     = listParentGO[parentIdx];
                GameObject chopParentGO = listChoppedParentGO[parentIdx];

                int        interiorPieceSubmeshIdx;
                GameObject goPiece = CRGeometryUtils.CreatePiece(i, meshPiece, parentInfo, goPosition, submeshRange,
                                                                 Data.InteriorMaterial, parentGO, chopParentGO, out interiorPieceSubmeshIdx);

                if (hasBeenSplitted)
                {
                    Tuple2 <GameObject, GameObject> tupleOutsideInside = listOutsideInsideGOParent[parentIdx];

                    GameObject outsideGO = tupleOutsideInside.First;
                    GameObject insideGO  = tupleOutsideInside.Second;

                    uint outsideInsideIdx = arrOutsideInsideIdx[meshComplexIdx];
                    if (outsideInsideIdx == 0)
                    {
                        goPiece.transform.parent = outsideGO.transform;
                        goPiece.name             = parentGO.name + "_out_" + i;
                    }
                    else if (outsideInsideIdx == 1)
                    {
                        goPiece.transform.parent = insideGO.transform;
                        goPiece.name             = parentGO.name + "_in_" + i;
                    }
                }

                listChoppedGO.Add(goPiece);
                dictChoppedGOInteriorSubmeshIdx.Add(goPiece, interiorPieceSubmeshIdx);
            }



            GameObject chopRoot = new GameObject(Data.Name + "_output");

            chopRoot.transform.position = position;
            Undo.RegisterCreatedObjectUndo(chopRoot, "Created " + Data.Name + "_output");

            Data.GameObjectChoppedRoot = chopRoot;

            for (int i = 0; i < listChoppedParentGO.Count; i++)
            {
                GameObject chopParentGO = listChoppedParentGO[i];

                chopParentGO.transform.parent = Data.GameObjectChoppedRoot.transform;
                chopParentGO.transform.SetAsFirstSibling();
            }

            Selection.activeGameObject = Data.GameObjectChoppedRoot;

            SaveNewChopInfo(dictChoppedGOInteriorSubmeshIdx);
        }