protected override void CreateMeshBefore()
        {
            base.CreateMeshBefore();

            #region RemoveChunk
            voxelObject.UpdateChunks();
            var chunkObjects = voxelObject.chunks;
            {
                bool   chunkObjectsUpdate = false;
                bool[] enableTale         = new bool[chunkObjects.Length];
                if (!removeAllChunk)
                {
                    for (int i = 0; i < chunkDataList.Count; i++)
                    {
                        for (int j = 0; j < chunkObjects.Length; j++)
                        {
                            if (chunkDataList[i].position == chunkObjects[j].position)
                            {
                                enableTale[j] = true;
                                break;
                            }
                        }
                    }
                }
                else
                {
                    removeAllChunk = false;
                }
                for (int i = 0; i < enableTale.Length; i++)
                {
                    if (!enableTale[i])
                    {
                        var go = chunkObjects[i].gameObject;
                        while (go.transform.childCount > 0)
                        {
                            Undo.SetTransformParent(go.transform.GetChild(0), voxelObject.transform, "Remove Chunk");
                        }
                        Undo.DestroyObjectImmediate(go);
                        chunkObjectsUpdate = true;
                    }
                }
                if (chunkObjectsUpdate)
                {
                    voxelObject.UpdateChunks();
                    chunkObjects = voxelObject.chunks;
                }
            }
            #endregion

            #region AddChunk
            int chunkCount = 0;
            {
                bool chunkObjectsUpdate = false;
                for (int i = 0; i < chunkDataList.Count; i++)
                {
                    GameObject chunkObject = null;
                    for (int j = 0; j < chunkObjects.Length; j++)
                    {
                        if (chunkDataList[i].position == chunkObjects[j].position)
                        {
                            chunkObject = chunkObjects[j].gameObject;
                            break;
                        }
                    }
                    if (chunkObject == null)
                    {
                        chunkObject = new GameObject(chunkDataList[i].name);
                        Undo.RegisterCreatedObjectUndo(chunkObject, "Create Chunk");
                        Undo.SetTransformParent(chunkObject.transform, voxelObject.transform, "Create Chunk");
                        GameObjectUtility.SetStaticEditorFlags(chunkObject, GameObjectUtility.GetStaticEditorFlags(voxelObject.gameObject));
                        chunkObject.transform.localPosition = Vector3.Scale(voxelObject.localOffset + chunkDataList[i].area.centerf, voxelObject.importScale);
                        chunkObject.transform.localRotation = Quaternion.identity;
                        chunkObject.transform.localScale    = Vector3.one;
                        chunkObject.layer  = voxelObject.gameObject.layer;
                        chunkObject.tag    = voxelObject.gameObject.tag;
                        chunkObjectsUpdate = true;
                    }
                    VoxelChunksObjectChunk controller = chunkObject.GetComponent <VoxelChunksObjectChunk>();
                    if (controller == null)
                    {
                        controller = Undo.AddComponent <VoxelChunksObjectChunk>(chunkObject);
                    }
                    controller.position    = chunkDataList[i].position;
                    controller.chunkName   = chunkDataList[i].name;
                    controller.basicOffset = Vector3.Scale(voxelObject.localOffset + chunkDataList[i].area.centerf, voxelObject.importScale);
                    chunkCount++;
                }
                if (chunkObjectsUpdate)
                {
                    voxelObject.UpdateChunks();
                    chunkObjects = voxelObject.chunks;
                }
            }
            #endregion

            #region SortChunk
            {
                List <Transform> objList = new List <Transform>();
                var childCount           = voxelObject.transform.childCount;
                for (int i = 0; i < childCount; i++)
                {
                    objList.Add(voxelObject.transform.GetChild(i));
                }
                objList.Sort((obj1, obj2) => string.Compare(obj1.name, obj2.name));
                for (int i = 0; i < objList.Count; i++)
                {
                    objList[i].SetSiblingIndex(childCount - 1);
                }
                voxelObject.UpdateChunks();
                chunkObjects = voxelObject.chunks;
            }
            #endregion

            #region UpdateChunk
            for (int i = 0; i < chunkObjects.Length; i++)
            {
                for (int j = 0; j < chunkDataList.Count; j++)
                {
                    if (chunkObjects[i].position == chunkDataList[j].position)
                    {
                        chunkDataList[j].chunkObject = chunkObjects[i];
                        break;
                    }
                }
            }
            #endregion
        }
 public VoxelChunksObjectChunkCore(VoxelChunksObjectChunk target)
 {
     voxelChunk  = target;
     voxelObject = target.transform.parent.GetComponent <VoxelChunksObject>();
     objectCore  = new VoxelChunksObjectCore(voxelObject);
 }
        public override void OnImportAsset(AssetImportContext ctx)
        {
            {
                var ext = Path.GetExtension(ctx.assetPath).ToLower();
                if (ext == ".vox")
                {
                    fileType = VoxelBase.FileType.vox;
                }
                else if (ext == ".qb")
                {
                    fileType = VoxelBase.FileType.qb;
                }
                else
                {
                    return;
                }
            }

            #region DefaultScale
            if (dataVersion == 0 &&
                importScale == Vector3.one &&
                AssetDatabase.LoadAssetAtPath <UnityEngine.Object>(ctx.assetPath) == null)
            {
                var x = EditorPrefs.GetFloat("VoxelImporter_DefaultScaleX", 1f);
                var y = EditorPrefs.GetFloat("VoxelImporter_DefaultScaleY", 1f);
                var z = EditorPrefs.GetFloat("VoxelImporter_DefaultScaleZ", 1f);
                importScale = new Vector3(x, y, z);
            }
            #endregion

            #region LegacyAssetNaming
            if (dataVersion > 0 && dataVersion < 6)
            {
                legacyAssetNaming = true;
            }
            #endregion

            Action <string> LogImportError = (log) =>
            {
#if UNITY_2018_1_OR_NEWER
                ctx.LogImportError(log);
#else
                Debug.LogError(log);
#endif
            };
            Action <VoxelBase> SetBasicOptions = (voxelObject) =>
            {
                voxelObject.importMode                    = importMode;
                voxelObject.importScale                   = importScale;
                voxelObject.importOffset                  = importOffset;
                voxelObject.combineFaces                  = combineFaces;
                voxelObject.ignoreCavity                  = ignoreCavity;
                voxelObject.shareSameFace                 = shareSameFace;
                voxelObject.removeUnusedPalettes          = removeUnusedPalettes;
                voxelObject.voxelStructure                = outputStructure ? ScriptableObject.CreateInstance <VoxelStructure>() : null;
                voxelObject.generateLightmapUVs           = generateLightmapUVs;
                voxelObject.generateLightmapUVsAngleError = generateLightmapUVsAngleError;
                voxelObject.generateLightmapUVsAreaError  = generateLightmapUVsAreaError;
                voxelObject.generateLightmapUVsHardAngle  = generateLightmapUVsHardAngle;
                voxelObject.generateLightmapUVsPackMargin = generateLightmapUVsPackMargin;
                voxelObject.generateTangents              = generateTangents;
                voxelObject.meshFaceVertexOffset          = meshFaceVertexOffset;
                voxelObject.loadFromVoxelFile             = loadFromVoxelFile;
                voxelObject.generateMipMaps               = generateMipMaps;
                voxelObject.legacyVoxImport               = legacyVoxImport;
                voxelObject.legacyAssetNaming             = legacyAssetNaming;
            };

            Action <VoxelBaseCore> Export = (core) =>
            {
                if (export)
                {
                    var fullPath = Application.dataPath + ctx.assetPath.Remove(0, "Assets".Length);
                    fullPath = fullPath.Remove(fullPath.LastIndexOf('.')) + ".dae";
                    core.ExportDaeFile(fullPath, false);
                }
            };

            var gameObject = new GameObject(Path.GetFileNameWithoutExtension(ctx.assetPath));
            if (string.IsNullOrEmpty(gameObjectName))
            {
                gameObjectName = gameObject.name;
            }
            if (meshMode == MeshMode.Combine)
            {
                #region Combine
                var voxelObject = gameObject.AddComponent <VoxelObject>();
                SetBasicOptions(voxelObject);
                var objectCore = new VoxelObjectCore(voxelObject);
                try
                {
                    if (!objectCore.Create(ctx.assetPath, null))
                    {
                        LogImportError(string.Format("<color=green>[Voxel Importer]</color> ScriptedImporter error. file:{0}", ctx.assetPath));
                        DestroyImmediate(gameObject);
                        return;
                    }
                }
                catch
                {
                    LogImportError(string.Format("<color=green>[Voxel Importer]</color> ScriptedImporter error. file:{0}", ctx.assetPath));
                    DestroyImmediate(gameObject);
                    return;
                }

                #region Correspondence in Issue ID 947055 Correction in case before correction is applied
                foreach (var material in voxelObject.materials)
                {
                    if (material != null)
                    {
                        material.hideFlags |= HideFlags.NotEditable;
                    }
                }
                if (voxelObject.atlasTexture != null)
                {
                    voxelObject.atlasTexture.hideFlags |= HideFlags.NotEditable;
                }
                if (voxelObject.mesh != null)
                {
                    voxelObject.mesh.hideFlags |= HideFlags.NotEditable;
                }
                #endregion

                #region Material
                {
                    materials     = new Material[voxelObject.materialIndexes.Count];
                    materialNames = new string[voxelObject.materialIndexes.Count];
                    for (int i = 0; i < voxelObject.materialIndexes.Count; i++)
                    {
                        var index    = voxelObject.materialIndexes[i];
                        var material = voxelObject.materials[index];
                        materials[i]     = material;
                        materialNames[i] = material.name;
                    }
                    if (remappedMaterials != null)
                    {
                        remappedMaterials = remappedMaterials.Where(item => item.material != null && materialNames.Contains(item.name)).ToArray();
                    }
                }
                #endregion

                #region Structure
                if (voxelObject.voxelStructure != null)
                {
                    if (legacyAssetNaming)
                    {
                        voxelObject.voxelStructure.name = "structure";
                    }
                    else
                    {
                        voxelObject.voxelStructure.name = Path.GetFileNameWithoutExtension(ctx.assetPath);
                    }
                }
                #endregion

                #region Collider
                switch (colliderType)
                {
                case ColliderType.Box:
                    gameObject.AddComponent <BoxCollider>();
                    break;

                case ColliderType.Sphere:
                    gameObject.AddComponent <SphereCollider>();
                    break;

                case ColliderType.Capsule:
                    gameObject.AddComponent <CapsuleCollider>();
                    break;

                case ColliderType.Mesh:
                    gameObject.AddComponent <MeshCollider>();
                    break;
                }
                #endregion

                Export(objectCore);

#if UNITY_2017_3_OR_NEWER
                ctx.AddObjectToAsset(gameObjectName, gameObject);
                ctx.AddObjectToAsset("mesh", voxelObject.mesh);
                {
                    var list = new List <Material>();
                    for (int i = 0; i < voxelObject.materialIndexes.Count; i++)
                    {
                        var material = voxelObject.materials[voxelObject.materialIndexes[i]];
                        list.Add(material);
                        if (remappedMaterials != null)
                        {
                            var index = ArrayUtility.FindIndex(remappedMaterials, (t) => { return(t.name == material.name); });
                            if (index >= 0)
                            {
                                list[i] = remappedMaterials[index].material;
                                continue;
                            }
                        }
                        ctx.AddObjectToAsset(string.Format("mat{0}", i), material);
                    }
                    gameObject.GetComponent <MeshRenderer>().sharedMaterials = list.ToArray();
                }
                ctx.AddObjectToAsset("tex", voxelObject.atlasTexture);
                if (voxelObject.voxelStructure != null)
                {
                    ctx.AddObjectToAsset("structure", voxelObject.voxelStructure);
                }

                VoxelObject.DestroyImmediate(voxelObject);

                ctx.SetMainObject(gameObject);
#else
                ctx.SetMainAsset(gameObjectName, gameObject);
                ctx.AddSubAsset("mesh", voxelObject.mesh);
                for (int i = 0; i < voxelObject.materialIndexes.Count; i++)
                {
                    var material = voxelObject.materials[voxelObject.materialIndexes[i]];
                    ctx.AddSubAsset(string.Format("mat{0}", i), material);
                }
                ctx.AddSubAsset("tex", voxelObject.atlasTexture);
                if (voxelObject.voxelStructure != null)
                {
                    ctx.AddSubAsset("structure", voxelObject.voxelStructure);
                }

                VoxelObject.DestroyImmediate(voxelObject);
#endif
                #endregion
            }
            else if (meshMode == MeshMode.Individual)
            {
                #region Individual
                var voxelObject = gameObject.AddComponent <VoxelChunksObject>();
                SetBasicOptions(voxelObject);
                {
                    voxelObject.createContactChunkFaces = createContactChunkFaces;
                    voxelObject.materialMode            = materialMode;
                }
                var objectCore = new VoxelChunksObjectCore(voxelObject);
                try
                {
                    if (!objectCore.Create(ctx.assetPath, null))
                    {
                        LogImportError(string.Format("<color=green>[Voxel Importer]</color> ScriptedImporter error. file:{0}", ctx.assetPath));
                        DestroyImmediate(gameObject);
                        return;
                    }
                }
                catch
                {
                    LogImportError(string.Format("<color=green>[Voxel Importer]</color> ScriptedImporter error. file:{0}", ctx.assetPath));
                    DestroyImmediate(gameObject);
                    return;
                }

                #region Correspondence in Issue ID 947055 Correction in case before correction is applied
                if (voxelObject.materials != null)
                {
                    foreach (var material in voxelObject.materials)
                    {
                        if (material != null)
                        {
                            material.hideFlags |= HideFlags.NotEditable;
                        }
                    }
                }
                if (voxelObject.atlasTexture != null)
                {
                    voxelObject.atlasTexture.hideFlags |= HideFlags.NotEditable;
                }
                foreach (var chunk in voxelObject.chunks)
                {
                    if (chunk.materials != null)
                    {
                        foreach (var material in chunk.materials)
                        {
                            if (material != null)
                            {
                                material.hideFlags |= HideFlags.NotEditable;
                            }
                        }
                    }
                    if (chunk.atlasTexture != null)
                    {
                        chunk.atlasTexture.hideFlags |= HideFlags.NotEditable;
                    }
                    if (chunk.mesh != null)
                    {
                        chunk.mesh.hideFlags |= HideFlags.NotEditable;
                    }
                }
                #endregion

                #region Legacy
                if (legacyAssetNaming)
                {
                    foreach (var chunk in voxelObject.chunks)
                    {
                        var oldName = chunk.chunkName;
                        chunk.chunkName       = chunk.chunkName.Replace("Chunk(", "");
                        chunk.chunkName       = chunk.chunkName.Remove(chunk.chunkName.Length - 1, 1);
                        chunk.gameObject.name = chunk.chunkName;
                        chunk.mesh.name       = chunk.mesh.name.Replace(oldName, chunk.chunkName);
                        if (chunk.materials != null)
                        {
                            foreach (var mat in chunk.materials)
                            {
                                if (mat == null)
                                {
                                    continue;
                                }
                                mat.name = mat.name.Replace(oldName, chunk.chunkName);
                            }
                        }
                        if (chunk.atlasTexture != null)
                        {
                            chunk.atlasTexture.name = chunk.atlasTexture.name.Replace(oldName, chunk.chunkName);
                        }
                    }
                }
                #endregion

                #region Material
                {
                    if (materialMode == VoxelChunksObject.MaterialMode.Combine)
                    {
                        materials     = new Material[voxelObject.materialIndexes.Count];
                        materialNames = new string[voxelObject.materialIndexes.Count];
                        for (int i = 0; i < voxelObject.materialIndexes.Count; i++)
                        {
                            var index    = voxelObject.materialIndexes[i];
                            var material = voxelObject.materials[index];
                            materials[i]     = material;
                            materialNames[i] = material.name;
                        }
                    }
                    else if (materialMode == VoxelChunksObject.MaterialMode.Individual)
                    {
                        List <Material> list = new List <Material>();
                        foreach (var chunk in voxelObject.chunks)
                        {
                            for (int i = 0; i < chunk.materialIndexes.Count; i++)
                            {
                                var index    = chunk.materialIndexes[i];
                                var material = chunk.materials[index];
                                if (!list.Contains(material))
                                {
                                    list.Add(material);
                                }
                            }
                        }
                        materials     = list.ToArray();
                        materialNames = new string[list.Count];
                        for (int i = 0; i < list.Count; i++)
                        {
                            materialNames[i] = list[i].name;
                        }
                    }
                    if (remappedMaterials != null)
                    {
                        remappedMaterials = remappedMaterials.Where(item => item.material != null && materialNames.Contains(item.name)).ToArray();
                    }
                }
                #endregion

                #region Structure
                if (voxelObject.voxelStructure != null)
                {
                    if (legacyAssetNaming)
                    {
                        voxelObject.voxelStructure.name = "structure";
                    }
                    else
                    {
                        voxelObject.voxelStructure.name = Path.GetFileNameWithoutExtension(ctx.assetPath);
                    }
                }
                #endregion

                #region Collider
                foreach (var chunk in voxelObject.chunks)
                {
                    switch (colliderType)
                    {
                    case ColliderType.Box:
                        chunk.gameObject.AddComponent <BoxCollider>();
                        break;

                    case ColliderType.Sphere:
                        chunk.gameObject.AddComponent <SphereCollider>();
                        break;

                    case ColliderType.Capsule:
                        chunk.gameObject.AddComponent <CapsuleCollider>();
                        break;

                    case ColliderType.Mesh:
                        chunk.gameObject.AddComponent <MeshCollider>();
                        break;
                    }
                }
                #endregion

                Export(objectCore);

#if UNITY_2017_3_OR_NEWER
                ctx.AddObjectToAsset(gameObjectName, gameObject);
                foreach (var chunk in voxelObject.chunks)
                {
                    ctx.AddObjectToAsset(chunk.chunkName + "_mesh", chunk.mesh);
                }
                {
                    if (materialMode == VoxelChunksObject.MaterialMode.Combine)
                    {
                        var materials = new List <Material>();
                        for (int i = 0; i < voxelObject.materialIndexes.Count; i++)
                        {
                            var material = voxelObject.materials[voxelObject.materialIndexes[i]];
                            materials.Add(material);
                            if (remappedMaterials != null)
                            {
                                var index = ArrayUtility.FindIndex(remappedMaterials, (t) => { return(t.name == material.name); });
                                if (index >= 0)
                                {
                                    materials[i] = remappedMaterials[index].material;
                                    continue;
                                }
                            }
                            ctx.AddObjectToAsset(string.Format("mat{0}", i), material);
                        }
                        foreach (var chunk in voxelObject.chunks)
                        {
                            chunk.gameObject.GetComponent <MeshRenderer>().sharedMaterials = materials.ToArray();
                        }
                        ctx.AddObjectToAsset("tex", voxelObject.atlasTexture);
                    }
                    else if (materialMode == VoxelChunksObject.MaterialMode.Individual)
                    {
                        foreach (var chunk in voxelObject.chunks)
                        {
                            var materials = new List <Material>();
                            for (int i = 0; i < chunk.materialIndexes.Count; i++)
                            {
                                var material = chunk.materials[chunk.materialIndexes[i]];
                                materials.Add(material);
                                if (remappedMaterials != null)
                                {
                                    var index = ArrayUtility.FindIndex(remappedMaterials, (t) => { return(t.name == material.name); });
                                    if (index >= 0)
                                    {
                                        materials[i] = remappedMaterials[index].material;
                                        continue;
                                    }
                                }
                                ctx.AddObjectToAsset(chunk.gameObject.name + string.Format("_mat{0}", i), material);
                            }
                            chunk.gameObject.GetComponent <MeshRenderer>().sharedMaterials = materials.ToArray();
                            ctx.AddObjectToAsset(chunk.gameObject.name + "_tex", chunk.atlasTexture);
                        }
                    }
                }
                if (voxelObject.voxelStructure != null)
                {
                    ctx.AddObjectToAsset("structure", voxelObject.voxelStructure);
                }

                foreach (var chunk in voxelObject.chunks)
                {
                    VoxelChunksObjectChunk.DestroyImmediate(chunk.GetComponent <VoxelChunksObjectChunk>());
                }
                VoxelObject.DestroyImmediate(voxelObject);

                ctx.SetMainObject(gameObject);
#else
                ctx.SetMainAsset(gameObjectName, gameObject);
                foreach (var chunk in voxelObject.chunks)
                {
                    ctx.AddSubAsset(chunk.gameObject.name + "_mesh", chunk.mesh);
                }
                {
                    if (materialMode == VoxelChunksObject.MaterialMode.Combine)
                    {
                        var materials = new List <Material>();
                        for (int i = 0; i < voxelObject.materialIndexes.Count; i++)
                        {
                            var material = voxelObject.materials[voxelObject.materialIndexes[i]];
                            materials.Add(material);
                            if (remappedMaterials != null)
                            {
                                var index = ArrayUtility.FindIndex(remappedMaterials, (t) => { return(t.name == material.name); });
                                if (index >= 0)
                                {
                                    materials[i] = remappedMaterials[index].material;
                                    continue;
                                }
                            }
                            ctx.AddSubAsset(string.Format("mat{0}", i), material, material);
                        }
                        foreach (var chunk in voxelObject.chunks)
                        {
                            chunk.gameObject.GetComponent <MeshRenderer>().sharedMaterials = materials.ToArray();
                        }
                        ctx.AddSubAsset("tex", voxelObject.atlasTexture);
                    }
                    else if (materialMode == VoxelChunksObject.MaterialMode.Individual)
                    {
                        foreach (var chunk in voxelObject.chunks)
                        {
                            var materials = new List <Material>();
                            for (int i = 0; i < chunk.materialIndexes.Count; i++)
                            {
                                var material = chunk.materials[chunk.materialIndexes[i]];
                                materials.Add(material);
                                if (remappedMaterials != null)
                                {
                                    var index = ArrayUtility.FindIndex(remappedMaterials, (t) => { return(t.name == material.name); });
                                    if (index >= 0)
                                    {
                                        materials[i] = remappedMaterials[index].material;
                                        continue;
                                    }
                                }
                                ctx.AddSubAsset(chunk.gameObject.name + string.Format("_mat{0}", i), material);
                            }
                            chunk.gameObject.GetComponent <MeshRenderer>().sharedMaterials = materials.ToArray();
                            ctx.AddSubAsset(chunk.gameObject.name + "_tex", chunk.atlasTexture);
                        }
                    }
                }
                if (voxelObject.voxelStructure != null)
                {
                    ctx.AddSubAsset("structure", voxelObject.voxelStructure);
                }

                foreach (var chunk in voxelObject.chunks)
                {
                    VoxelChunksObjectChunk.DestroyImmediate(chunk.GetComponent <VoxelChunksObjectChunk>());
                }
                VoxelObject.DestroyImmediate(voxelObject);
#endif
                #endregion
            }

            dataVersion = EditorDataVersion;
        }
        protected override bool CreateMesh()
        {
            #region ProgressBar
            const float     MaxProgressCount   = 5f;
            float           ProgressCount      = 0;
            Action <string> DisplayProgressBar = (info) =>
            {
                if (!EditorApplication.isPlaying && voxelBase.voxelData.voxels.Length > 10000)
                {
                    EditorUtility.DisplayProgressBar("Create Mesh...", string.Format("{0} / {1}", ProgressCount, MaxProgressCount), (ProgressCount++ / MaxProgressCount));
                }
            };
            #endregion

            DisplayProgressBar("");

            #region Material
            {
                if (voxelObject.materialData == null)
                {
                    voxelObject.materialData = new List <MaterialData>();
                }
                if (voxelObject.materialData.Count == 0)
                {
                    voxelObject.materialData.Add(null);
                }
                for (int i = 0; i < voxelObject.materialData.Count; i++)
                {
                    if (voxelObject.materialData[i] == null)
                    {
                        voxelObject.materialData[i] = new MaterialData();
                    }
                }
                if (voxelObject.materials == null)
                {
                    voxelObject.materials = new List <Material>();
                }
                if (voxelObject.materials.Count < voxelObject.materialData.Count)
                {
                    for (int i = voxelObject.materials.Count; i < voxelObject.materialData.Count; i++)
                    {
                        voxelObject.materials.Add(null);
                    }
                }
                else if (voxelObject.materials.Count > voxelObject.materialData.Count)
                {
                    voxelObject.materials.RemoveRange(voxelObject.materialData.Count, voxelObject.materials.Count - voxelObject.materialData.Count);
                }
                #region Erase
                for (int i = 0; i < voxelObject.materialData.Count; i++)
                {
                    List <IntVector3> removeList = new List <IntVector3>();
                    voxelObject.materialData[i].AllAction((pos) =>
                    {
                        if (voxelObject.voxelData.VoxelTableContains(pos) < 0)
                        {
                            removeList.Add(pos);
                        }
                    });
                    for (int j = 0; j < removeList.Count; j++)
                    {
                        voxelObject.materialData[i].RemoveMaterial(removeList[j]);
                    }
                }
                #endregion
            }
            #endregion

            CalcDataCreate(voxelBase.voxelData.voxels);

            #region RemoveChunk
            var chunkObjects = FindChunkComponents();
            {
                bool   chunkObjectsUpdate = false;
                bool[] enableTale         = new bool[chunkObjects.Length];
                if (!removeAllChunk)
                {
                    for (int i = 0; i < chunkDataList.Count; i++)
                    {
                        for (int j = 0; j < chunkObjects.Length; j++)
                        {
                            if (chunkDataList[i].position == chunkObjects[j].position)
                            {
                                enableTale[j] = true;
                                break;
                            }
                        }
                    }
                }
                else
                {
                    removeAllChunk = false;
                }
                for (int i = 0; i < enableTale.Length; i++)
                {
                    if (!enableTale[i])
                    {
                        var go = chunkObjects[i].gameObject;
                        while (go.transform.childCount > 0)
                        {
                            Undo.SetTransformParent(go.transform.GetChild(0), voxelObject.transform, "Remove Chunk");
                        }
                        Undo.DestroyObjectImmediate(go);
                        chunkObjectsUpdate = true;
                    }
                }
                if (chunkObjectsUpdate)
                {
                    chunkObjects = FindChunkComponents();
                }
            }
            #endregion

            #region AddChunk
            int chunkCount = 0;
            {
                bool chunkObjectsUpdate = false;
                for (int i = 0; i < chunkDataList.Count; i++)
                {
                    GameObject chunkObject = null;
                    for (int j = 0; j < chunkObjects.Length; j++)
                    {
                        if (chunkDataList[i].position == chunkObjects[j].position)
                        {
                            chunkObject = chunkObjects[j].gameObject;
                            break;
                        }
                    }
                    if (chunkObject == null)
                    {
                        chunkObject = new GameObject(chunkDataList[i].name);
                        Undo.RegisterCreatedObjectUndo(chunkObject, "Create Chunk");
                        Undo.SetTransformParent(chunkObject.transform, voxelObject.transform, "Create Chunk");
                        GameObjectUtility.SetStaticEditorFlags(chunkObject, GameObjectUtility.GetStaticEditorFlags(voxelObject.gameObject));
                        chunkObject.transform.localPosition = Vector3.Scale(voxelObject.localOffset + chunkDataList[i].area.centerf, voxelObject.importScale);
                        chunkObject.transform.localRotation = Quaternion.identity;
                        chunkObject.transform.localScale    = Vector3.one;
                        chunkObject.layer  = voxelObject.gameObject.layer;
                        chunkObject.tag    = voxelObject.gameObject.tag;
                        chunkObjectsUpdate = true;
                    }
                    VoxelChunksObjectChunk controller = chunkObject.GetComponent <VoxelChunksObjectChunk>();
                    if (controller == null)
                    {
                        controller = Undo.AddComponent <VoxelChunksObjectChunk>(chunkObject);
                    }
                    controller.position  = chunkDataList[i].position;
                    controller.chunkName = chunkDataList[i].name;
                    chunkCount++;
                }
                if (chunkObjectsUpdate)
                {
                    chunkObjects = FindChunkComponents();
                }
            }
            #endregion

            #region SortChunk
            {
                List <Transform> objList = new List <Transform>();
                var childCount           = voxelObject.transform.childCount;
                for (int i = 0; i < childCount; i++)
                {
                    objList.Add(voxelObject.transform.GetChild(i));
                }
                objList.Sort((obj1, obj2) => string.Compare(obj1.name, obj2.name));
                for (int i = 0; i < objList.Count; i++)
                {
                    objList[i].SetSiblingIndex(childCount - 1);
                }
                chunkObjects = FindChunkComponents();
            }
            #endregion

            #region UpdateChunk
            for (int i = 0; i < chunkObjects.Length; i++)
            {
                for (int j = 0; j < chunkDataList.Count; j++)
                {
                    if (chunkObjects[i].position == chunkDataList[j].position)
                    {
                        chunkDataList[j].chunkObject = chunkObjects[i];
                        break;
                    }
                }
            }
            #endregion

            #region UpdateVoxelVisibleFlag
            {
                for (int i = 0; i < voxelBase.voxelData.voxels.Length; i++)
                {
                    int            index;
                    VoxelBase.Face faceFlags = (VoxelBase.Face) 0;
                    index = voxelBase.voxelData.VoxelTableContains(voxelBase.voxelData.voxels[i].x, voxelBase.voxelData.voxels[i].y, voxelBase.voxelData.voxels[i].z + 1);
                    if (index < 0)
                    {
                        faceFlags |= VoxelBase.Face.forward;
                    }
                    index = voxelBase.voxelData.VoxelTableContains(voxelBase.voxelData.voxels[i].x, voxelBase.voxelData.voxels[i].y + 1, voxelBase.voxelData.voxels[i].z);
                    if (index < 0)
                    {
                        faceFlags |= VoxelBase.Face.up;
                    }
                    index = voxelBase.voxelData.VoxelTableContains(voxelBase.voxelData.voxels[i].x + 1, voxelBase.voxelData.voxels[i].y, voxelBase.voxelData.voxels[i].z);
                    if (index < 0)
                    {
                        faceFlags |= VoxelBase.Face.right;
                    }
                    index = voxelBase.voxelData.VoxelTableContains(voxelBase.voxelData.voxels[i].x - 1, voxelBase.voxelData.voxels[i].y, voxelBase.voxelData.voxels[i].z);
                    if (index < 0)
                    {
                        faceFlags |= VoxelBase.Face.left;
                    }
                    index = voxelBase.voxelData.VoxelTableContains(voxelBase.voxelData.voxels[i].x, voxelBase.voxelData.voxels[i].y - 1, voxelBase.voxelData.voxels[i].z);
                    if (index < 0)
                    {
                        faceFlags |= VoxelBase.Face.down;
                    }
                    index = voxelBase.voxelData.VoxelTableContains(voxelBase.voxelData.voxels[i].x, voxelBase.voxelData.voxels[i].y, voxelBase.voxelData.voxels[i].z - 1);
                    if (index < 0)
                    {
                        faceFlags |= VoxelBase.Face.back;
                    }
                    voxelBase.voxelData.voxels[i].visible = faceFlags;
                }
            }
            #endregion

            #region CreateFaceAreaTable
            {
                for (int i = 0; i < chunkDataList.Count; i++)
                {
                    var voxels = new VoxelData.Voxel[chunkDataList[i].voxels.Count];
                    for (int j = 0; j < chunkDataList[i].voxels.Count; j++)
                    {
                        voxels[j] = voxelBase.voxelData.voxels[chunkDataList[i].voxels[j]];
                    }
                    chunkDataList[i].faceAreaTable = CreateFaceArea(voxels);
                    //
                    if (voxelObject.materialMode == VoxelChunksObject.MaterialMode.Individual)
                    {
                        var paletteTable = new int[voxelBase.voxelData.palettes.Length];
                        for (int j = 0; j < voxelBase.voxelData.palettes.Length; j++)
                        {
                            int newIndex = -1;
                            for (int k = 0; k < chunkDataList[i].palettes.Length; k++)
                            {
                                if (chunkDataList[i].palettes[k] == voxelBase.voxelData.palettes[j])
                                {
                                    newIndex = k;
                                    break;
                                }
                            }
                            paletteTable[j] = newIndex;
                        }
                        chunkDataList[i].faceAreaTable.ReplacePalette(paletteTable);
                    }
                }
            }
            #endregion

            #region CreateTexture
            if (voxelObject.materialMode == VoxelChunksObject.MaterialMode.Combine)
            {
                #region Combine
                var tmpFaceAreaTable = new VoxelData.FaceAreaTable();
                for (int i = 0; i < chunkDataList.Count; i++)
                {
                    tmpFaceAreaTable.Merge(chunkDataList[i].faceAreaTable);
                }
                {
                    var atlasTextureTmp = voxelObject.atlasTexture;
                    if (!CreateTexture(tmpFaceAreaTable, voxelBase.voxelData.palettes, ref chunkDataList[0].atlasRectTable, ref atlasTextureTmp, ref chunkDataList[0].atlasRects))
                    {
                        EditorUtility.ClearProgressBar();
                        return(false);
                    }
                    voxelObject.atlasTexture = atlasTextureTmp;
                    {
                        if (voxelObject.materialData == null)
                        {
                            voxelObject.materialData = new List <MaterialData>();
                        }
                        if (voxelObject.materialData.Count == 0)
                        {
                            voxelObject.materialData.Add(null);
                        }
                        for (int i = 0; i < voxelObject.materialData.Count; i++)
                        {
                            if (voxelObject.materialData[i] == null)
                            {
                                voxelObject.materialData[i] = new MaterialData();
                            }
                        }
                        if (voxelObject.materials == null)
                        {
                            voxelObject.materials = new List <Material>();
                        }
                        if (voxelObject.materials.Count < voxelObject.materialData.Count)
                        {
                            for (int i = voxelObject.materials.Count; i < voxelObject.materialData.Count; i++)
                            {
                                voxelObject.materials.Add(null);
                            }
                        }
                        else if (voxelObject.materials.Count > voxelObject.materialData.Count)
                        {
                            voxelObject.materials.RemoveRange(voxelObject.materialData.Count, voxelObject.materials.Count - voxelObject.materialData.Count);
                        }
                        for (int i = 0; i < voxelObject.materials.Count; i++)
                        {
                            if (voxelObject.materials[i] == null)
                            {
                                voxelObject.materials[i] = new Material(Shader.Find("Standard"));
                            }
                            voxelObject.materials[i].mainTexture = voxelObject.atlasTexture;
                        }
                    }
                    for (int i = 0; i < chunkDataList.Count; i++)
                    {
                        chunkDataList[i].atlasRects               = chunkDataList[0].atlasRects;
                        chunkDataList[i].atlasRectTable           = chunkDataList[0].atlasRectTable;
                        chunkDataList[i].chunkObject.materials    = null;
                        chunkDataList[i].chunkObject.atlasTexture = null;
                    }
                }
                #endregion
            }
            else if (voxelObject.materialMode == VoxelChunksObject.MaterialMode.Individual)
            {
                #region Individual
                if (voxelObject.materialData == null)
                {
                    voxelObject.materialData = new List <MaterialData>();
                }
                if (voxelObject.materialData.Count == 0)
                {
                    voxelObject.materialData.Add(null);
                }
                for (int i = 0; i < voxelObject.materialData.Count; i++)
                {
                    if (voxelObject.materialData[i] == null)
                    {
                        voxelObject.materialData[i] = new MaterialData();
                    }
                }
                voxelObject.materials    = null;
                voxelObject.atlasTexture = null;
                for (int c = 0; c < chunkDataList.Count; c++)
                {
                    var atlasTextureTmp = chunkDataList[c].chunkObject.atlasTexture;
                    if (!CreateTexture(chunkDataList[c].faceAreaTable, chunkDataList[c].palettes, ref chunkDataList[c].atlasRectTable, ref atlasTextureTmp, ref chunkDataList[c].atlasRects))
                    {
                        EditorUtility.ClearProgressBar();
                        return(false);
                    }
                    chunkDataList[c].chunkObject.atlasTexture = atlasTextureTmp;
                    {
                        if (chunkDataList[c].chunkObject.materials == null)
                        {
                            chunkDataList[c].chunkObject.materials = new List <Material>();
                        }
                        if (chunkDataList[c].chunkObject.materials.Count < voxelObject.materialData.Count)
                        {
                            for (int i = chunkDataList[c].chunkObject.materials.Count; i < voxelObject.materialData.Count; i++)
                            {
                                chunkDataList[c].chunkObject.materials.Add(null);
                            }
                        }
                        else if (chunkDataList[c].chunkObject.materials.Count > voxelObject.materialData.Count)
                        {
                            chunkDataList[c].chunkObject.materials.RemoveRange(voxelObject.materialData.Count, chunkDataList[c].chunkObject.materials.Count - voxelObject.materialData.Count);
                        }
                        for (int i = 0; i < chunkDataList[c].chunkObject.materials.Count; i++)
                        {
                            if (chunkDataList[c].chunkObject.materials[i] == null)
                            {
                                chunkDataList[c].chunkObject.materials[i] = new Material(Shader.Find("Standard"));
                            }
                            chunkDataList[c].chunkObject.materials[i].mainTexture = chunkDataList[c].chunkObject.atlasTexture;
                        }
                    }
                }
                #endregion
            }
            else
            {
                Assert.IsTrue(false);
            }
            #endregion

            #region CreateMesh
            DisplayProgressBar("");
            {
                if (voxelObject.materialMode == VoxelChunksObject.MaterialMode.Combine)
                {
                    #region Combine
                    if (voxelObject.importMode == VoxelBase.ImportMode.LowPoly)
                    {
                        int forward = 0;
                        int up      = 0;
                        int right   = 0;
                        int left    = 0;
                        int down    = 0;
                        int back    = 0;
                        for (int i = 0; i < chunkDataList.Count; i++)
                        {
                            AtlasRectTable atlasRectTable = new AtlasRectTable();
                            {
                                atlasRectTable.forward = chunkDataList[i].atlasRectTable.forward.GetRange(forward, chunkDataList[i].faceAreaTable.forward.Count);
                                forward          += chunkDataList[i].faceAreaTable.forward.Count;
                                atlasRectTable.up = chunkDataList[i].atlasRectTable.up.GetRange(up, chunkDataList[i].faceAreaTable.up.Count);
                                up += chunkDataList[i].faceAreaTable.up.Count;
                                atlasRectTable.right = chunkDataList[i].atlasRectTable.right.GetRange(right, chunkDataList[i].faceAreaTable.right.Count);
                                right += chunkDataList[i].faceAreaTable.right.Count;
                                atlasRectTable.left = chunkDataList[i].atlasRectTable.left.GetRange(left, chunkDataList[i].faceAreaTable.left.Count);
                                left += chunkDataList[i].faceAreaTable.left.Count;
                                atlasRectTable.down = chunkDataList[i].atlasRectTable.down.GetRange(down, chunkDataList[i].faceAreaTable.down.Count);
                                down += chunkDataList[i].faceAreaTable.down.Count;
                                atlasRectTable.back = chunkDataList[i].atlasRectTable.back.GetRange(back, chunkDataList[i].faceAreaTable.back.Count);
                                back += chunkDataList[i].faceAreaTable.back.Count;
                            }
                            chunkDataList[i].chunkObject.mesh = CreateMeshOnly(chunkDataList[i].chunkObject.mesh, chunkDataList[i].faceAreaTable, voxelObject.atlasTexture, chunkDataList[i].atlasRects, atlasRectTable, -(voxelObject.localOffset + chunkDataList[i].area.centerf), out chunkDataList[i].chunkObject.materialIndexes);
                        }
                    }
                    else
                    {
                        for (int i = 0; i < chunkDataList.Count; i++)
                        {
                            var srcMesh = (chunkDataList[i].chunkObject.mesh != null && AssetDatabase.Contains(chunkDataList[i].chunkObject.mesh)) ? chunkDataList[i].chunkObject.mesh : null;
                            chunkDataList[i].chunkObject.mesh = CreateMeshOnly(srcMesh, chunkDataList[i].faceAreaTable, voxelObject.atlasTexture, chunkDataList[i].atlasRects, chunkDataList[i].atlasRectTable, -(voxelObject.localOffset + chunkDataList[i].area.centerf), out chunkDataList[i].chunkObject.materialIndexes);
                        }
                    }
                    #endregion
                }
                else if (voxelObject.materialMode == VoxelChunksObject.MaterialMode.Individual)
                {
                    #region Individual
                    for (int i = 0; i < chunkDataList.Count; i++)
                    {
                        chunkDataList[i].chunkObject.mesh = CreateMeshOnly(chunkDataList[i].chunkObject.mesh, chunkDataList[i].faceAreaTable, chunkDataList[i].chunkObject.atlasTexture, chunkDataList[i].atlasRects, chunkDataList[i].atlasRectTable, -(voxelObject.localOffset + chunkDataList[i].area.centerf), out chunkDataList[i].chunkObject.materialIndexes);
                    }
                    #endregion
                }
                else
                {
                    Assert.IsTrue(false);
                }
            }
            #endregion

            DisplayProgressBar("");
            if (voxelBase.generateLightmapUVs)
            {
                for (int i = 0; i < chunkDataList.Count; i++)
                {
                    if (chunkDataList[i].chunkObject.mesh.uv.Length > 0)
                    {
                        Unwrapping.GenerateSecondaryUVSet(chunkDataList[i].chunkObject.mesh);
                    }
                }
            }

            DisplayProgressBar("");

            SetRendererCompornent();

            CreateMeshAfterFree();

            RefreshCheckerSave();

            EditorUtility.ClearProgressBar();

            return(true);
        }