//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))); } } } }
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); } }
//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"); } } }
//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))); } } } }
//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); } } }
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); } }
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; } }
//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); } } }
//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); } } }
//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; } } } } }