Пример #1
0
        //IOpsCommand
        public void Run(OpsContext context, OpsStatement statement)
        {
            AddVDataArguments arguments = statement.Arguments as AddVDataArguments;

            OpsConsole.WriteLine(String.Format("Adding vertex element {0} of type {1}", arguments.FriendlyName, arguments.type));

            foreach (OpsModel model in statement.GetContent(context))
            {
                foreach (OpsMeshContainer meshContainer in model.GetMeshEnumerator())
                {
                    VertexElement[] OldVEs = meshContainer.MeshData.Mesh.Declaration.Clone() as VertexElement[];

                    int iExists;
                    if (false == MeshDeclarationHelper.FindElement(OldVEs, arguments.usage, arguments.usageIdx, out iExists))
                    {
                        int             addedIdx;
                        VertexElement[] VEs = MeshDeclarationHelper.AddElement(OldVEs, arguments.type, arguments.usage, arguments.usageIdx, out addedIdx);

                        Mesh newMesh = meshContainer.MeshData.Mesh.Clone(meshContainer.MeshData.Mesh.Options.Value, VEs, meshContainer.MeshData.Mesh.Device);
                        meshContainer.ReplaceMesh(newMesh);
                    }
                    else
                    {
                        OpsConsole.WriteLine(String.Format("Found existing vertex element {0}{1} on {2}", arguments.usage, arguments.usageIdx, meshContainer.FriendlyName(model)));
                    }
                }
            }
        }
Пример #2
0
            public AddVDataArguments(OpsParsedStatement statement)
            {
                OpsParsedArgument typeArg = statement.FindArgument("type");

                if (typeArg == null)
                {
                    typeArg = statement.FindArgument("");
                    if (typeArg == null)
                    {
                        throw new OpsException("'type' argument argument");
                    }
                }
                type = MeshDeclarationHelper.DecodeType(typeArg.Value);

                OpsParsedArgument usageArg = statement.FindArgument("usage");

                if (usageArg != null)
                {
                    usage = MeshDeclarationHelper.DecodeUsage(usageArg.Value);
                }

                OpsParsedArgument usageIdxArg = statement.FindArgument("usageIdx");

                if (usageIdxArg != null)
                {
                    usageIdx = int.Parse(usageIdxArg.Value);
                }
            }
Пример #3
0
        //IOpsCommand
        public void Run(OpsContext context, OpsStatement statement)
        {
            OpsUVAtlasArguments options = statement.Arguments as OpsUVAtlasArguments;

            OpsConsole.WriteLine("UVAtlasing models.  This might take a while.");

            foreach (OpsModel model in statement.GetContent(context))
            {
                foreach (OpsMeshContainer meshContainer in model.GetMeshEnumerator())
                {
                    OpsConsole.WriteLine("\t\tBeginning " + meshContainer.FriendlyName(model));

                    VertexElement[] VEs = meshContainer.MeshData.Mesh.Declaration;

                    int destinationIdx;
                    if (false == MeshDeclarationHelper.FindElement(VEs, DeclarationUsage.TextureCoordinate, options.TexIdx, out destinationIdx))
                    {
                        throw new OpsException("Cannot generate UVAtlas without texture coordinates (use command AddVData)");
                    }

                    UVAtlasOutput uvout;
                    try
                    {
                        uvout = UVAtlas.Create(
                            meshContainer.MeshData.Mesh,
                            options.MaxCharts,
                            options.Stretch,
                            options.Width,
                            options.Height,
                            options.Gutter,
                            options.TexIdx,
                            meshContainer.GetAdjacencyStream(),
                            null,
                            null,
                            0.0f);
                    }
                    catch (Microsoft.DirectX.Direct3D.InvalidMeshException e)
                    {
                        throw new OpsException("UVAtlas considers this mesh invalid.  This is most likely because the mesh is non-manifold.  Using the clean and optimize commands first to remove some non-manifold properties MAY fix the problem.  Also consider less restrictive argument values.", e);
                    }
                    catch (Exception e)
                    {
                        throw new OpsException("UVAtlas was unable to complete.  Try using more flexible argument values, cleaning, and/or optimizing models first.", e);
                    }

                    meshContainer.ReplaceMesh(uvout.Mesh);
                    meshContainer.RemapSkin(uvout.VertexRemapArray);

                    OpsConsole.WriteLine("\ttCompleted");
                }
            }
        }
Пример #4
0
        //IOpsCommand
        public void Run(OpsContext context, OpsStatement statement)
        {
            DelVDataArguments arguments = statement.Arguments as DelVDataArguments;

            OpsConsole.WriteLine(String.Format("Deleting vertex element {0}", arguments.FriendlyName));

            foreach (OpsModel model in statement.GetContent(context))
            {
                foreach (OpsMeshContainer meshContainer in model.GetMeshEnumerator())
                {
                    VertexElement[] OldVEs = meshContainer.MeshData.Mesh.Declaration.Clone() as VertexElement[];

                    int srcUsageIdx = arguments.usageIdx;
                    if (arguments.hasSrcUsageIdx == false)
                    {
                        for (int i = 0; i < OldVEs.Length; i++)
                        {
                            if (OldVEs[i].DeclarationUsage == arguments.usage)
                            {
                                srcUsageIdx = OldVEs[i].UsageIndex;
                                break;
                            }
                        }
                    }

                    if (srcUsageIdx < 0)
                    {
                        continue;
                    }


                    int iRemove;
                    if (MeshDeclarationHelper.FindElement(OldVEs, arguments.usage, srcUsageIdx, out iRemove))
                    {
                        VertexElement[] VEs = MeshDeclarationHelper.RemoveElement(OldVEs, iRemove);

                        Mesh newMesh = meshContainer.MeshData.Mesh.Clone(meshContainer.MeshData.Mesh.Options.Value, VEs, meshContainer.MeshData.Mesh.Device);
                        meshContainer.ReplaceMesh(newMesh);
                    }
                    else
                    {
                        OpsConsole.WriteLine(String.Format("Could not find vertex element {0}{1} on {2}", arguments.usage, arguments.usageIdx, meshContainer.FriendlyName(model)));
                    }
                }
            }
        }
Пример #5
0
        //IOpsCommand
        public void Run(OpsContext context, OpsStatement statement)
        {
            OpsConsole.WriteLine("Mesh information");

            foreach (OpsModel model in statement.GetContent(context))
            {
                OpsConsole.WriteLine("MODEL: '{0}'", model.Name);
                OpsConsole.WriteLine(format, "Names", "Faces", "Vertices", "Attributes", "Boundings");

                foreach (OpsMeshContainer meshContainer in model.GetMeshEnumerator())
                {
                    float radius = 0;

                    VertexElement[] VEs = meshContainer.MeshData.Mesh.Declaration;
                    int             posIdx;
                    if (MeshDeclarationHelper.FindElement(VEs, DeclarationUsage.Position, 0, out posIdx))
                    {
                        using (VertexBuffer vb = meshContainer.MeshData.Mesh.VertexBuffer)
                        {
                            GraphicsStream vertexData = vb.Lock(VEs[posIdx].Offset, vb.Description.Size - VEs[posIdx].Offset, LockFlags.None);

                            Vector3 center;
                            radius = Geometry.ComputeBoundingSphere(vertexData,
                                                                    meshContainer.MeshData.Mesh.NumberVertices,
                                                                    meshContainer.MeshData.Mesh.NumberBytesPerVertex,
                                                                    out center);

                            vb.Unlock();
                        }
                    }

                    OpsConsole.WriteLine(format,
                                         meshContainer.Name,
                                         meshContainer.MeshData.Mesh.NumberFaces,
                                         meshContainer.MeshData.Mesh.NumberVertices,
                                         meshContainer.MeshData.Mesh.NumberAttributes,
                                         radius);
                }
            }
        }
Пример #6
0
            public DelVDataArguments(OpsParsedStatement statement)
            {
                OpsParsedArgument usageArg = statement.FindArgument("usage");

                if (usageArg == null)
                {
                    usageArg = statement.FindArgument("");
                    if (usageArg == null)
                    {
                        throw OpsException.ArgRequired("usage");
                    }
                }
                usage = MeshDeclarationHelper.DecodeUsage(usageArg.Value);

                OpsParsedArgument usageIdxArg = statement.FindArgument("usageIdx");

                if (usageIdxArg != null)
                {
                    hasSrcUsageIdx = true;
                    usageIdx       = int.Parse(usageIdxArg.Value);
                }
            }
Пример #7
0
            public CloneVDataArguments(OpsParsedStatement statement)
            {
                OpsParsedArgument usageArg = statement.FindArgument("usage");

                if (usageArg == null)
                {
                    usageArg = statement.FindArgument("");
                    if (usageArg == null)
                    {
                        throw OpsException.ArgRequired("usage");
                    }
                }
                srcUsage = MeshDeclarationHelper.DecodeUsage(usageArg.Value);

                OpsParsedArgument usageIdxArg = statement.FindArgument("usageIdx");

                if (usageIdxArg != null)
                {
                    srcUsageIdx    = int.Parse(usageIdxArg.Value);
                    hasSrcUsageIdx = true;
                }

                OpsParsedArgument dstUsageArg = statement.FindArgument("newusage");

                if (dstUsageArg != null)
                {
                    dstUsage = MeshDeclarationHelper.DecodeUsage(dstUsageArg.Value);
                }

                OpsParsedArgument dstUsageIdxArg = statement.FindArgument("newusageIdx");

                if (dstUsageIdxArg != null)
                {
                    dstUsageIdx    = int.Parse(dstUsageIdxArg.Value);
                    hasDstUsageIdx = true;
                }
            }
Пример #8
0
        //IOpsCommand
        public void Run(OpsContext context, OpsStatement statement)
        {
            OpsConsole.WriteLine("Cleaning models");

            foreach (OpsModel model in statement.GetContent(context))
            {
                foreach (OpsMeshContainer meshContainer in model.GetMeshEnumerator())
                {
                    string errorsAndWarnings;
                    meshContainer.MeshData.Mesh.Validate(meshContainer.GetAdjacencyStream(), out errorsAndWarnings);
                    if (errorsAndWarnings == null || errorsAndWarnings.Length == 0)
                    {
                        continue;
                    }
                    else
                    {
                        OpsConsole.WriteLine("Cleaning '{0}'", meshContainer.FriendlyName(model));
                        OpsConsole.WriteLine(errorsAndWarnings);
                    }

                    VertexElement[] OldVEs        = null;
                    int             offsetOfIndex = -1;
                    Mesh            dirtyMesh     = meshContainer.MeshData.Mesh;
                    if (meshContainer.SkinInformation != null)
                    {
                        int psizeUsageIdx = -1;
                        int remapIdx      = -1;
                        OldVEs = meshContainer.MeshData.Mesh.Declaration.Clone() as VertexElement[];

                        if (!MeshDeclarationHelper.FindValidUsageIndex(OldVEs, DeclarationUsage.PointSize, out psizeUsageIdx))
                        {
                            throw new OpsException("Could not add remapping-indexing vertex element to declaration");
                        }

                        VertexElement[] VEs = MeshDeclarationHelper.AddElement(OldVEs, DeclarationType.Float1, DeclarationUsage.PointSize, psizeUsageIdx, out remapIdx);

                        dirtyMesh = meshContainer.MeshData.Mesh.Clone(meshContainer.MeshData.Mesh.Options.Value, VEs, meshContainer.MeshData.Mesh.Device);

                        offsetOfIndex = VEs[remapIdx].Offset;
                        VertexBuffer   vb = dirtyMesh.VertexBuffer;
                        GraphicsStream gs = vb.Lock(0, 0, LockFlags.None);
                        for (int iVertex = 0; iVertex < dirtyMesh.NumberVertices; iVertex++)
                        {
                            gs.Seek(dirtyMesh.NumberBytesPerVertex * iVertex + offsetOfIndex, SeekOrigin.Begin);
                            gs.Write(iVertex);
                        }
                        vb.Unlock();
                        gs = null;
                        vb = null;
                    }

                    int[] adjOut;
                    Mesh  cleanedMesh = Mesh.Clean(CleanType.BackFacing | CleanType.BowTies, dirtyMesh, meshContainer.GetAdjacency(), out adjOut, out errorsAndWarnings);

                    if (errorsAndWarnings != null && errorsAndWarnings.Length != 0)
                    {
                        OpsConsole.WriteLine("Remaining Errors and Warnings:");
                        OpsConsole.WriteLine(errorsAndWarnings);
                    }

                    if (meshContainer.SkinInformation != null)
                    {
                        int[] vertexRemap = new int[cleanedMesh.NumberVertices];

                        VertexBuffer   vb = cleanedMesh.VertexBuffer;
                        GraphicsStream gs = vb.Lock(0, 0, LockFlags.None);
                        for (int iVertex = 0; iVertex < cleanedMesh.NumberVertices; iVertex++)
                        {
                            gs.Seek(cleanedMesh.NumberBytesPerVertex * iVertex + offsetOfIndex, SeekOrigin.Begin);
                            vertexRemap[iVertex] = (int)gs.Read(typeof(int));
                        }
                        vb.Unlock();

                        meshContainer.RemapSkin(vertexRemap);

                        cleanedMesh = cleanedMesh.Clone(cleanedMesh.Options.Value, OldVEs, cleanedMesh.Device);
                    }

                    meshContainer.SetAdjacency(adjOut);


                    meshContainer.ReplaceMesh(cleanedMesh);
                }
            }
        }
Пример #9
0
        //IOpsCommand
        public void Run(OpsContext context, OpsStatement statement)
        {
            CloneVDataArguments arguments = statement.Arguments as CloneVDataArguments;

            OpsConsole.WriteLine(String.Format("Cloning vertex element {0} as {1}", arguments.FriendlySrcName, arguments.FriendlyDstName));

            foreach (OpsModel model in statement.GetContent(context))
            {
                foreach (OpsMeshContainer meshContainer in model.GetMeshEnumerator())
                {
                    int srcIdx;
                    int dstIdx;

                    VertexElement[] OldVEs = meshContainer.MeshData.Mesh.Declaration.Clone() as VertexElement[];


                    int srcUsageIdx = arguments.srcUsageIdx;
                    if (arguments.hasSrcUsageIdx == false)
                    {
                        for (int i = 0; i < OldVEs.Length; i++)
                        {
                            if (OldVEs[i].DeclarationUsage == arguments.srcUsage)
                            {
                                srcUsageIdx = OldVEs[i].UsageIndex;
                                break;
                            }
                        }
                    }

                    if (srcUsageIdx < 0)
                    {
                        continue;
                    }

                    if (!MeshDeclarationHelper.FindElement(OldVEs, arguments.srcUsage, srcUsageIdx, out srcIdx))
                    {
                        throw new OpsException("Could not find source vertex element");
                    }

                    int dstUsageIdxPerMesh = arguments.dstUsageIdx;
                    if (!arguments.hasDstUsageIdx)
                    {
                        if (MeshDeclarationHelper.FindValidUsageIndex(OldVEs, arguments.dstUsage, out dstUsageIdxPerMesh, out dstIdx))
                        {
                            throw new OpsException("Could not find open usage index for destination vertex element");
                        }
                    }

                    int             copyIdx;
                    VertexElement[] VEs = MeshDeclarationHelper.AddElement(OldVEs, OldVEs[srcIdx].DeclarationType, arguments.dstUsage, dstUsageIdxPerMesh, out copyIdx);

                    if (!MeshDeclarationHelper.FindElement(VEs, arguments.srcUsage, srcUsageIdx, out srcIdx))
                    {
                        throw new OpsException("Could not find source vertex element");
                    }

                    if (!MeshDeclarationHelper.FindElement(VEs, arguments.dstUsage, dstUsageIdxPerMesh, out dstIdx))
                    {
                        throw new OpsException("Could not find destination vertex element");
                    }



                    Mesh newMesh = meshContainer.MeshData.Mesh.Clone(meshContainer.MeshData.Mesh.Options.Value, VEs, meshContainer.MeshData.Mesh.Device);

                    int    sizeInBytes = MeshDeclarationHelper.GetTypeSize(VEs[srcIdx].DeclarationType);
                    int    srcOffset   = VEs[srcIdx].Offset;
                    int    dstOffset   = VEs[dstIdx].Offset;
                    byte[] copyBuffer  = new byte[sizeInBytes];

                    VertexBuffer   vb = newMesh.VertexBuffer;
                    GraphicsStream gs = vb.Lock(0, 0, LockFlags.None);
                    for (int iVertex = 0; iVertex < newMesh.NumberVertices; iVertex++)
                    {
                        gs.Seek(newMesh.NumberBytesPerVertex * iVertex + srcOffset, SeekOrigin.Begin);
                        gs.Read(copyBuffer, 0, sizeInBytes);

                        gs.Seek(newMesh.NumberBytesPerVertex * iVertex + dstOffset, SeekOrigin.Begin);
                        gs.Write(copyBuffer, 0, sizeInBytes);
                    }
                    vb.Unlock();
                    gs = null;
                    vb = null;

                    meshContainer.ReplaceMesh(newMesh);
                }
            }
        }
Пример #10
0
        //IOpsCommand
        public void Run(OpsContext context, OpsStatement statement)
        {
            TangentArguments options = statement.Arguments as TangentArguments;

            OpsConsole.WriteLine("Generating tangent frames");

            foreach (OpsModel model in statement.GetContent(context))
            {
                foreach (OpsMeshContainer meshContainer in model.GetMeshEnumerator())
                {
                    VertexElement[] VEs = meshContainer.MeshData.Mesh.Declaration;

                    int texIdx;
                    if (false == MeshDeclarationHelper.FindElement(VEs, DeclarationUsage.TextureCoordinate, 0, out texIdx))
                    {
                        throw new OpsException("Cannot generate tangents without texture coordinates (use command uvatlas)");
                    }

                    int normIdx;
                    if (false == MeshDeclarationHelper.FindElement(VEs, DeclarationUsage.Normal, 0, out normIdx))
                    {
                        throw new OpsException("Cannot generate tangents without normals (use command GenNormals)");
                    }

                    int tanIdx;
                    if (false == MeshDeclarationHelper.FindElement(VEs, DeclarationUsage.Tangent, 0, out tanIdx))
                    {
                        throw new OpsException("Cannot generate tangents without a place to store Tangent0 (use command AddVData)");
                    }

                    int binormIdx;
                    if (false == MeshDeclarationHelper.FindElement(VEs, DeclarationUsage.BiNormal, 0, out binormIdx))
                    {
                        throw new OpsException("Cannot generate tangents without a place to store BiNormal0 (use command AddVData)");
                    }
                    bool success = false;
                    try
                    {
                        GraphicsStream vertexRemapStream = null;


                        Mesh newMesh = Geometry.ComputeTangentFrame(
                            meshContainer.MeshData.Mesh,
                            (int)DeclarationUsage.TextureCoordinate,
                            options.TexIdx,
                            (int)DeclarationUsage.Tangent,
                            0,
                            (int)DeclarationUsage.BiNormal,
                            0,
                            (int)DeclarationUsage.Normal,
                            0,
                            options.Options,
                            meshContainer.GetAdjacencyStream(),
                            options.ThreshPE,
                            options.ThreshSP,
                            options.ThreshNE,
                            out vertexRemapStream);

                        if (newMesh != null)
                        {
                            meshContainer.ReplaceMesh(newMesh);
                            meshContainer.RemapSkin(vertexRemapStream);
                            success = true;
                        }
                        else
                        {
                            success = false;
                            OpsConsole.WriteLine("Failed in 1st attempt to generate tangents on " + meshContainer.FriendlyName(model));
                        }
                    }
                    catch (Exception)
                    {
                        OpsConsole.WriteLine("Failed in 1st attempt to generate tangents on  " + meshContainer.FriendlyName(model));
                        //eating exception
                    }

                    if (!success)
                    {
                        try
                        {
                            meshContainer.MeshData.Mesh.ComputeTangent(
                                options.TexIdx,
                                0,
                                0,
                                0, meshContainer.GetAdjacencyStream());
                        }
                        catch (Exception)
                        {
                            OpsConsole.WriteLine("Failed in final attempt to generate tangents on " + meshContainer.FriendlyName(model));
                            throw;
                        }
                    }
                }
            }
        }