Exemplo n.º 1
0
        public BfresEditor(bool HasModels)
        {
            InitializeComponent();

            STConsole stConsole = STConsole.Instance;

            stConsole.BorderStyle = BorderStyle.None;
            stConsole.Dock        = DockStyle.Fill;
            tabPage4.Controls.Add(stConsole);

            animationPanel = new AnimationPanel();
            animationPanel.CurrentAnimation = null;
            animationPanel.Dock             = DockStyle.Fill;
            timelineTabPage.Controls.Add(animationPanel);

            stTabControl1.myBackColor = FormThemes.BaseTheme.FormBackColor;
            stTabControl2.myBackColor = FormThemes.BaseTheme.FormBackColor;


            if (viewport == null)
            {
                viewport      = new Viewport();
                viewport.Dock = DockStyle.Fill;
            }

            stPanel5.Controls.Add(viewport);

            OnLoadedTab();

            if (HasModels)
            {
                stTabControl1.SelectedIndex = 1;
            }
        }
Exemplo n.º 2
0
        public void CreateIndexList(STGenericObject ob, FMDL mdl = null)
        {
            BoneIndices = new List <ushort>();

            List <string> boneNames = new List <string>();

            foreach (Vertex v in ob.vertices)
            {
                foreach (string bn in v.boneNames)
                {
                    if (!boneNames.Contains(bn))
                    {
                        boneNames.Add(bn);
                    }
                }
            }

            foreach (STBone bone in mdl.Skeleton.bones)
            {
                foreach (string bnam in boneNames)
                {
                    if (bone.Text == bnam)
                    {
                        int index = boneNames.IndexOf(bone.Text);
                        STConsole.WriteLine($"Adding bone to shape index list! {bone.Text} {index}");

                        BoneIndices.Add((ushort)index);
                    }
                }
            }
        }
Exemplo n.º 3
0
        public Vector3 TransformLocal(Vector3 position, int BoneIndex, bool IsSingleBind, bool IsPos = true)
        {
            try
            {
                var     skel  = GetParentModel().Skeleton;
                Matrix4 trans = Matrix4.Identity;

                if (IsSingleBind)
                {
                    if (BoneIndex >= skel.Node_Array.Length || BoneIndex == -1)
                    {
                        return(position);
                    }

                    var bone = skel.bones[skel.Node_Array[BoneIndex]];
                    trans = bone.invert;
                }
                else
                {
                    var bone = skel.bones[BoneIndex];
                    trans = bone.invert;
                }

                if (IsPos)
                {
                    return(Vector3.TransformPosition(position, trans));
                }
                else
                {
                    return(Vector3.TransformNormal(position, trans));
                }
            }
            catch
            {
                STConsole.WriteLine("Failed to bind bone to mesh " + Text, System.Drawing.Color.Red);
                return(position);
            }
        }
Exemplo n.º 4
0
        public List <ushort> GetIndices(FSKL fskl)
        {
            List <ushort> indices = new List <ushort>();

            List <string> BoneNodes = new List <string>();

            foreach (Vertex vtx in vertices)
            {
                foreach (int index in vtx.boneIds)
                {
                    var bone = fskl.bones[fskl.Node_Array[index]];

                    ushort ind = (ushort)fskl.bones.IndexOf(bone);
                    if (!indices.Contains(ind))
                    {
                        STConsole.WriteLine($"Saving bone index {bone.Name} {index}");
                        indices.Add(ind);
                    }
                }
            }
            STConsole.WriteLine($"Total Indices for {Text}  {indices.Count}");

            return(indices);
        }
        private static string SatisfyFileTables(IFileFormat FileFormat, string FilePath, Stream Data, uint DecompressedSize, uint CompressedSize, bool IsYaz0Compressed)
        {
            string FileLog = "";

            bool IsBotwFile = FilePath.IsSubPathOf(Runtime.BotwGamePath);
            bool IsTPHDFile = FilePath.IsSubPathOf(Runtime.TpGamePath);

            STConsole.WriteLine($"IsTPHDFile {IsTPHDFile}");

            if (Runtime.ResourceTables.BotwTable && IsBotwFile)
            {
                string newFilePath = FilePath.Replace(Runtime.BotwGamePath, string.Empty).Remove(0, 1);
                newFilePath = newFilePath.Replace(".s", ".");
                newFilePath = newFilePath.Replace( @"\", "/");

                string RealExtension = Path.GetExtension(newFilePath).Replace(".s", ".");

                string RstbPath = Path.Combine($"{Runtime.BotwGamePath}",
                    "System", "Resource", "ResourceSizeTable.product.srsizetable");

                RSTB BotwResourceTable = new RSTB();
                BotwResourceTable.LoadFile(RstbPath);

                //Create a backup first if one doesn't exist
                if (!File.Exists($"{RstbPath}.backup"))
                {
                    STConsole.WriteLine($"RSTB File found. Creating backup...");

                    BotwResourceTable.Write(new FileWriter($"{RstbPath}.backup"));
                    File.WriteAllBytes($"{RstbPath}.backup", EveryFileExplorer.YAZ0.Compress($"{RstbPath}.backup"));
                }

                //Now apply the file table then save the table
                if (BotwResourceTable.IsInTable(newFilePath))
                {
                    FileLog += $"File found in resource table! {newFilePath}";
                    STConsole.WriteLine(FileLog, 1);
                }
                else
                {
                    FileLog += $"File NOT found in resource table! {newFilePath}";
                    STConsole.WriteLine(FileLog, 0);

                }

                BotwResourceTable.SetEntry(newFilePath, Data, IsYaz0Compressed);
                BotwResourceTable.Write(new FileWriter(RstbPath));
                File.WriteAllBytes(RstbPath, EveryFileExplorer.YAZ0.Compress(RstbPath));
            }

            if (Runtime.ResourceTables.TpTable && IsTPHDFile)
            {
                string newFilePath = FilePath.Replace(Runtime.TpGamePath, string.Empty).Remove(0, 1);
                newFilePath = newFilePath.Replace(@"\", "/");

                //Read the compressed tables and set the new sizes if paths match
                TPFileSizeTable CompressedFileTbl = new TPFileSizeTable();
                CompressedFileTbl.ReadCompressedTable(new FileReader($"{Runtime.TpGamePath}/FileSizeList.txt"));
                if (CompressedFileTbl.IsInFileSizeList(newFilePath))
                {
                    STConsole.WriteLine("Found matching path in File Size List table! " + newFilePath, 1);
                    CompressedFileTbl.SetFileSizeEntry(newFilePath, CompressedSize);
                }
                else
                    STConsole.WriteLine("Failed to find path in File Size List table! " + newFilePath, 0);

                //Read decompressed file sizes
                TPFileSizeTable DecompressedFileTbl = new TPFileSizeTable();
                DecompressedFileTbl.ReadDecompressedTable(new FileReader($"{Runtime.TpGamePath}/DecompressedSizeList.txt"));

                newFilePath = $"./DVDRoot/{newFilePath}";
                newFilePath = newFilePath.Replace(".gz", string.Empty);

                //Write the decompressed file size
                if (DecompressedFileTbl.IsInDecompressedFileSizeList(newFilePath))
                {
                    STConsole.WriteLine("Found matching path in File Size List table! " + newFilePath, 1);
                    DecompressedFileTbl.SetDecompressedFileSizeEntry(newFilePath, CompressedSize, DecompressedSize);
                }
                else
                    STConsole.WriteLine("Failed to find path in File Size List table! " + newFilePath, 0);

                if (FileFormat == null)
                    return FileLog;

                //Check if archive type
                bool IsArchive = false;
                foreach (var inter in FileFormat.GetType().GetInterfaces())
                {
                    if (inter == typeof(IArchiveFile))
                        IsArchive = true;
                }

                //Write all the file sizes in the archive if it's an archive type
                //Note this seems uneeded atm
                //Todo store both compressed and decompressed sizes in archive info
                /*   if (IsArchive)
                   {
                       IArchiveFile Archive = (IArchiveFile)FileFormat;
                       foreach (var file in Archive.Files)
                       {
                           uint DecompressedArchiveFileSize = (uint)file.FileData.Length;
                           string ArchiveFilePath = $"/DVDRoot/{file.FileName}";

                           if (DecompressedFileTbl.IsInDecompressedFileSizeList(ArchiveFilePath))
                           {
                               STConsole.WriteLine("Found matching path in File Size List table! " + ArchiveFilePath, 1);
                               DecompressedFileTbl.SetDecompressedFileSizeEntry(ArchiveFilePath, DecompressedArchiveFileSize, DecompressedArchiveFileSize);
                           }
                           else
                               STConsole.WriteLine("Failed to find path in File Size List table! " + ArchiveFilePath, 0);
                       }
                   }*/

                CompressedFileTbl.WriteCompressedTable(new FileWriter($"{Runtime.TpGamePath}/FileSizeList.txt"));
                DecompressedFileTbl.WriteDecompressedTable(new FileWriter($"{Runtime.TpGamePath}/DecompressedSizeList.txt"));
            }

            return FileLog;
        }
Exemplo n.º 6
0
        public static void SaveSkeleton(FSKL fskl, List <STBone> Bones)
        {
            fskl.node.Skeleton.Bones.Clear();
            fskl.node.Skeleton.MatrixToBoneList     = new List <ushort>();
            fskl.node.Skeleton.InverseModelMatrices = new List <Syroot.Maths.Matrix3x4>();

            ushort SmoothIndex = 0;

            foreach (STBone genericBone in Bones)
            {
                genericBone.BillboardIndex = ushort.MaxValue;

                STConsole.WriteLine($"Applying bone " + genericBone.Text);

                //Clone a generic bone with the generic data
                BfresBone bn = new BfresBone(fskl);
                bn.CloneBaseInstance(genericBone);

                //Set the bfres bone data
                if (bn.Bone == null)
                {
                    bn.Bone = new Bone();
                }
                bn.GenericToBfresBone();

                if (bn.SmoothMatrixIndex != short.MaxValue)
                {
                    fskl.node.Skeleton.MatrixToBoneList.Add(SmoothIndex++);
                }

                fskl.node.Skeleton.InverseModelMatrices.Add(Syroot.Maths.Matrix3x4.Zero);

                fskl.bones.Add(bn);
            }

            foreach (BfresBone wrapper in fskl.bones)
            {
                //Check duplicated names
                //   List<string> names = fskl.bones.Select(o => o.Text).ToList();
                //   wrapper.Text = Utils.RenameDuplicateString(names, wrapper.Text);

                wrapper.Bone.Name = wrapper.Text;
                fskl.node.Skeleton.Bones.Add(wrapper.Bone);

                //Add bones to tree
                if (wrapper.Parent == null)
                {
                    fskl.node.Nodes.Add(wrapper);
                }
            }

            fskl.update();
            fskl.reset();

            fskl.Node_Array = new int[fskl.node.Skeleton.MatrixToBoneList.Count];
            int nodes = 0;

            foreach (ushort node in fskl.node.Skeleton.MatrixToBoneList)
            {
                fskl.Node_Array[nodes] = node;
                nodes++;
            }
        }
Exemplo n.º 7
0
        //Function addes shapes, vertices and meshes
        public void AddOjects(string FileName, ResFile resFileNX, ResU.ResFile resFileU, bool Replace = true)
        {
            int totalSkinCountLimiter = 0;

            bool IsWiiU = (resFileU != null);

            if (shapes.Count > 0)
            {
                totalSkinCountLimiter = shapes[0].VertexSkinCount;
            }

            int    MatStartIndex = materials.Count;
            string ext           = System.IO.Path.GetExtension(FileName);

            ext = ext.ToLower();

            switch (ext)
            {
            case ".bfobj":
                Cursor.Current = Cursors.WaitCursor;

                if (Replace)
                {
                    shapes.Clear();
                    Nodes["FshpFolder"].Nodes.Clear();
                }
                if (IsWiiU)
                {
                    var shpS          = new ResU.Shape();
                    var vertexBufferU = new ResU.VertexBuffer();
                    shpS.Import(FileName, vertexBufferU, resFileU);

                    FSHP shapeS = new FSHP();
                    shapeS.ShapeU = shpS;
                    BfresWiiU.ReadShapesVertices(shapeS, shpS, vertexBufferU, this);
                    shapes.Add(shapeS);
                    Nodes["FshpFolder"].Nodes.Add(shapeS);
                }
                else
                {
                    Shape        shpS         = new Shape();
                    VertexBuffer vertexBuffer = new VertexBuffer();
                    shpS.Import(FileName, vertexBuffer);

                    FSHP shapeS = new FSHP();
                    shapeS.Shape = shpS;
                    BfresSwitch.ReadShapesVertices(shapeS, shpS, vertexBuffer, this);
                    shapes.Add(shapeS);
                    Nodes["FshpFolder"].Nodes.Add(shapeS);
                }

                IsEdited = true;

                Cursor.Current = Cursors.Default;
                break;

            case ".bfmdl":
                Cursor.Current = Cursors.WaitCursor;

                if (Replace)
                {
                    shapes.Clear();
                    Nodes["FshpFolder"].Nodes.Clear();
                    materials.Clear();
                    Nodes["FmatFolder"].Nodes.Clear();
                }

                if (IsWiiU)
                {
                    var mdlU = new ResU.Model();
                    mdlU.Import(FileName, resFileU);
                    mdlU.Name = Text;
                    BfresWiiU.ReadModel(this, mdlU);
                }
                else
                {
                    Model mdl = new Model();
                    mdl.Import(FileName, resFileNX);
                    mdl.Name = Text;

                    Console.WriteLine(mdl.ShapeCount);
                    Console.WriteLine(mdl.MaterialCount);
                    Console.WriteLine(mdl.VertexBufferCount);
                    Console.WriteLine(mdl.Skeleton.Bones.Count);

                    BfresSwitch.ReadModel(this, mdl);
                }
                IsEdited = true;

                Cursor.Current = Cursors.Default;
                break;

            case ".csv":
                CsvModel csvModel = new CsvModel();
                csvModel.LoadFile(new System.IO.FileStream(FileName, System.IO.FileMode.Open), true);

                if (csvModel.objects.Count == 0)
                {
                    MessageBox.Show("No models found!");
                    return;
                }
                BfresModelImportSettings csvsettings = new BfresModelImportSettings();
                csvsettings.DisableMaterialEdits();
                csvsettings.SkinCountLimit = totalSkinCountLimiter;
                csvsettings.SetModelAttributes(csvModel.objects[0]);
                if (csvsettings.ShowDialog() == DialogResult.OK)
                {
                    if (Replace)
                    {
                        shapes.Clear();
                        Nodes["FshpFolder"].Nodes.Clear();
                    }

                    Cursor.Current = Cursors.WaitCursor;

                    foreach (STGenericObject obj in csvModel.objects)
                    {
                        FSHP shape = new FSHP();
                        Nodes["FshpFolder"].Nodes.Add(shape);
                        shapes.Add(shape);

                        shape.VertexBufferIndex = shapes.Count;
                        shape.vertices          = obj.vertices;
                        shape.MaterialIndex     = 0;
                        shape.vertexAttributes  = csvsettings.CreateNewAttributes();
                        shape.BoneIndex         = 0;
                        shape.Text      = obj.ObjectName;
                        shape.lodMeshes = obj.lodMeshes;
                        shape.CreateNewBoundingBoxes();
                        shape.CreateBoneList(obj, this);
                        shape.CreateIndexList(obj, this);
                        //Todo find better way. Currently uses import settings now
                        shape.ApplyImportSettings(csvsettings, GetMaterial(shape.MaterialIndex));
                        shape.VertexSkinCount = obj.GetMaxSkinInfluenceCount();
                        shape.BoneIndices     = shape.GetIndices(Skeleton);
                        shape.SaveShape(IsWiiU);
                        shape.SaveVertexBuffer();

                        if (IsWiiU)
                        {
                            shape.ShapeU.SubMeshBoundingIndices = new List <ushort>();
                            shape.ShapeU.SubMeshBoundingIndices.Add(0);
                            shape.ShapeU.SubMeshBoundingNodes = new List <ResU.BoundingNode>();
                            shape.ShapeU.SubMeshBoundingNodes.Add(new ResU.BoundingNode()
                            {
                                LeftChildIndex  = 0,
                                NextSibling     = 0,
                                SubMeshIndex    = 0,
                                RightChildIndex = 0,
                                Unknown         = 0,
                                SubMeshCount    = 1,
                            });
                        }

                        if (IsWiiU)
                        {
                            BfresWiiU.ReadShapesVertices(shape, shape.ShapeU, shape.VertexBufferU, this);
                        }
                        else
                        {
                            BfresSwitch.ReadShapesVertices(shape, shape.Shape, shape.VertexBuffer, this);
                        }
                    }
                    Cursor.Current = Cursors.Default;
                }
                IsEdited = true;

                break;

            default:
                AssimpData assimp = new AssimpData();
                assimp.LoadFile(FileName);

                if (assimp.objects.Count == 0)
                {
                    MessageBox.Show("No models found!");
                    return;
                }
                BfresModelImportSettings settings = new BfresModelImportSettings();
                settings.SetModelAttributes(assimp.objects[0]);
                if (settings.ShowDialog() == DialogResult.OK)
                {
                    bool UseMats = settings.ExternalMaterialPath != string.Empty;

                    if (Replace)
                    {
                        shapes.Clear();
                        Nodes["FshpFolder"].Nodes.Clear();
                    }

                    Cursor.Current = Cursors.WaitCursor;
                    if (Replace && UseMats)
                    {
                        materials.Clear();
                        Nodes["FmatFolder"].Nodes.Clear();
                        MatStartIndex = 0;
                    }
                    if (UseMats)
                    {
                        foreach (STGenericMaterial mat in assimp.materials)
                        {
                            FMAT fmat = new FMAT();

                            if (IsWiiU)
                            {
                                fmat.MaterialU = new ResU.Material();
                                fmat.MaterialU.Import(settings.ExternalMaterialPath, resFileU);
                                BfresWiiU.ReadMaterial(fmat, fmat.MaterialU);
                            }
                            else
                            {
                                fmat.Material = new Material();
                                fmat.Material.Import(settings.ExternalMaterialPath);
                                fmat.ReadMaterial(fmat.Material);
                            }

                            fmat.Text = mat.Text;
                            //Setup placeholder textures
                            //Note we can't add/remove samplers so we must fill these slots
                            foreach (var t in fmat.TextureMaps)
                            {
                                t.wrapModeS = 0;
                                t.wrapModeT = 0;

                                switch (t.Type)
                                {
                                case STGenericMatTexture.TextureType.Diffuse:
                                    t.Name = "Basic_Alb";
                                    break;

                                case STGenericMatTexture.TextureType.Emission:
                                    t.Name = "Basic_Emm";
                                    break;

                                case STGenericMatTexture.TextureType.Normal:
                                    t.Name = "Basic_Nrm";
                                    break;

                                case STGenericMatTexture.TextureType.Specular:
                                    t.Name = "Basic_Spm";
                                    break;

                                case STGenericMatTexture.TextureType.SphereMap:
                                    t.Name = "Basic_Sphere";
                                    break;

                                case STGenericMatTexture.TextureType.Metalness:
                                    t.Name = "Basic_Mtl";
                                    break;

                                case STGenericMatTexture.TextureType.Roughness:
                                    t.Name = "Basic_Rgh";
                                    break;

                                case STGenericMatTexture.TextureType.MRA:
                                    t.Name = "Basic_MRA";
                                    break;

                                case STGenericMatTexture.TextureType.Shadow:
                                    t.Name = "Basic_Bake_st0";
                                    break;

                                case STGenericMatTexture.TextureType.Light:
                                    t.Name = "Basic_Bake_st1";
                                    break;
                                }
                            }

                            if (PluginRuntime.bntxContainers.Count > 0 && Parent != null)
                            {
                                foreach (var node in Parent.Parent.Nodes)
                                {
                                    if (node is BNTX)
                                    {
                                        var bntx = (BNTX)node;

                                        bntx.ImportBasicTextures("Basic_Alb");
                                        bntx.ImportBasicTextures("Basic_Nrm");
                                        bntx.ImportBasicTextures("Basic_Spm");
                                        bntx.ImportBasicTextures("Basic_Sphere");
                                        bntx.ImportBasicTextures("Basic_Mtl");
                                        bntx.ImportBasicTextures("Basic_Rgh");
                                        bntx.ImportBasicTextures("Basic_MRA");
                                        bntx.ImportBasicTextures("Basic_Bake_st0");
                                        bntx.ImportBasicTextures("Basic_Bake_st1");
                                        bntx.ImportBasicTextures("Basic_Emm");
                                    }
                                }
                            }
                            if (PluginRuntime.ftexContainers.Count > 0 && Parent != null)
                            {
                                foreach (var node in Parent.Parent.Nodes)
                                {
                                    if (node is BFRESGroupNode)
                                    {
                                        if (((BFRESGroupNode)node).Type == BRESGroupType.Textures)
                                        {
                                            var ftexCont = (BFRESGroupNode)node;

                                            ftexCont.ImportBasicTextures("Basic_Alb");
                                            ftexCont.ImportBasicTextures("Basic_Nrm");
                                            ftexCont.ImportBasicTextures("Basic_Spm");
                                            ftexCont.ImportBasicTextures("Basic_Sphere");
                                            ftexCont.ImportBasicTextures("Basic_Mtl");
                                            ftexCont.ImportBasicTextures("Basic_Rgh");
                                            ftexCont.ImportBasicTextures("Basic_MRA");
                                            ftexCont.ImportBasicTextures("Basic_Bake_st0");
                                            ftexCont.ImportBasicTextures("Basic_Bake_st1");
                                            ftexCont.ImportBasicTextures("Basic_Emm");
                                        }
                                    }
                                }
                            }

                            foreach (var tex in mat.TextureMaps)
                            {
                                foreach (var t in fmat.TextureMaps)
                                {
                                    if (t.Type == tex.Type)
                                    {
                                        t.Name      = tex.Name;
                                        t.wrapModeS = tex.wrapModeS;
                                        t.wrapModeT = tex.wrapModeT;
                                        t.wrapModeW = tex.wrapModeW;
                                        t.Type      = tex.Type;
                                    }
                                }
                            }

                            List <string> keyList = new List <string>(materials.Keys);
                            fmat.Text = Utils.RenameDuplicateString(keyList, fmat.Text);

                            if (IsWiiU)
                            {
                                fmat.MaterialU.Name = Text;
                                fmat.SetMaterial(fmat.MaterialU, resFileU);
                            }
                            else
                            {
                                fmat.Material.Name = Text;
                                fmat.SetMaterial(fmat.Material);
                            }

                            materials.Add(fmat.Text, fmat);
                            Nodes["FmatFolder"].Nodes.Add(fmat);
                        }
                    }

                    if (settings.ImportBones)
                    {
                        if (assimp.skeleton.bones.Count > 0)
                        {
                            Skeleton.bones.Clear();
                            Skeleton.node.Nodes.Clear();

                            if (IsWiiU)
                            {
                                BfresWiiU.SaveSkeleton(Skeleton, assimp.skeleton.bones);
                            }
                            else
                            {
                                BfresSwitch.SaveSkeleton(Skeleton, assimp.skeleton.bones);
                            }
                        }
                    }

                    if (materials.Count <= 0)
                    {
                        //Force material creation if there is none present
                        FMAT fmat = new FMAT();
                        fmat.Text = "NewMaterial";
                        materials.Add(fmat.Text, fmat);
                        Nodes["FmatFolder"].Nodes.Add(fmat);

                        if (IsWiiU)
                        {
                            fmat.MaterialU      = new ResU.Material();
                            fmat.MaterialU.Name = "NewMaterial";
                            BfresWiiU.ReadMaterial(fmat, fmat.MaterialU);
                        }
                        else
                        {
                            fmat.Material      = new Material();
                            fmat.Material.Name = "NewMaterial";
                            fmat.ReadMaterial(fmat.Material);
                        }
                    }

                    foreach (STGenericObject obj in assimp.objects)
                    {
                        FSHP shape = new FSHP();
                        Nodes["FshpFolder"].Nodes.Add(shape);
                        shapes.Add(shape);

                        shape.VertexBufferIndex = shapes.Count;
                        shape.vertices          = obj.vertices;
                        shape.vertexAttributes  = settings.CreateNewAttributes();
                        shape.BoneIndex         = obj.BoneIndex;

                        STConsole.WriteLine(Text + " " + obj.MaterialIndex);

                        if (UseMats)
                        {
                            shape.MaterialIndex = obj.MaterialIndex + MatStartIndex;
                        }
                        else
                        {
                            shape.MaterialIndex = 0;
                        }

                        if (shape.MaterialIndex >= materials.Count)
                        {
                            shape.MaterialIndex = 0;
                        }

                        shape.Text      = obj.ObjectName;
                        shape.lodMeshes = obj.lodMeshes;
                        shape.CreateNewBoundingBoxes();
                        shape.CreateBoneList(obj, this);
                        shape.CreateIndexList(obj, this);
                        shape.ApplyImportSettings(settings, GetMaterial(shape.MaterialIndex));
                        shape.VertexSkinCount = obj.GetMaxSkinInfluenceCount();
                        shape.BoneIndices     = shape.GetIndices(Skeleton);

                        shape.SaveShape(IsWiiU);
                        shape.SaveVertexBuffer();

                        if (IsWiiU)
                        {
                            shape.ShapeU.SubMeshBoundingIndices = new List <ushort>();
                            shape.ShapeU.SubMeshBoundingIndices.Add(0);
                            shape.ShapeU.SubMeshBoundingNodes = new List <ResU.BoundingNode>();
                            shape.ShapeU.SubMeshBoundingNodes.Add(new ResU.BoundingNode()
                            {
                                LeftChildIndex  = 0,
                                NextSibling     = 0,
                                SubMeshIndex    = 0,
                                RightChildIndex = 0,
                                Unknown         = 0,
                                SubMeshCount    = 1,
                            });
                        }

                        List <string> keyList = shapes.Select(o => o.Text).ToList();
                        shape.Text = Utils.RenameDuplicateString(keyList, shape.Text);

                        if (IsWiiU)
                        {
                            BfresWiiU.ReadShapesVertices(shape, shape.ShapeU, shape.VertexBufferU, this);
                        }
                        else
                        {
                            BfresSwitch.ReadShapesVertices(shape, shape.Shape, shape.VertexBuffer, this);
                        }
                    }


                    IsEdited = true;

                    Cursor.Current = Cursors.Default;
                }
                break;
            }

            if (IsEdited)
            {
                UpdateVertexData();
            }
        }