// OnPolymesh is called when a tessellated polymesh of a 3D face is being output. // The current material is applied to the polymesh. public void OnPolymesh( PolymeshTopology InPolymeshNode // tessellated polymesh output node ) { if (IgnoreElementGeometry()) { return; } // Retrieve the Datasmith mesh being processed. FDatasmithFacadeMesh CurrentMesh = GetCurrentMesh(); Transform MeshPointsTransform = GetCurrentMeshPointsTransform(); // Retrieve the index of the current material and make the Datasmith mesh keep track of it. int CurrentMaterialIndex = GetCurrentMaterialIndex(); int initialVertexCount = CurrentMesh.GetVertexCount(); // Add the vertex points (in right-handed Z-up coordinates) to the Datasmith mesh. foreach (XYZ Point in InPolymeshNode.GetPoints()) { XYZ FinalPoint = MeshPointsTransform != null?MeshPointsTransform.OfPoint(Point) : Point; CurrentMesh.AddVertex((float)FinalPoint.X, (float)FinalPoint.Y, (float)FinalPoint.Z); } // Add the vertex UV texture coordinates to the Datasmith mesh. foreach (UV uv in InPolymeshNode.GetUVs()) { CurrentMesh.AddUV(0, (float)uv.U, (float)-uv.V); } IList <PolymeshFacet> Facets = InPolymeshNode.GetFacets(); // Add the triangle vertex indexes to the Datasmith mesh. foreach (PolymeshFacet facet in Facets) { CurrentMesh.AddTriangle(initialVertexCount + facet.V1, initialVertexCount + facet.V2, initialVertexCount + facet.V3, CurrentMaterialIndex); } // Add the triangle vertex normals (in right-handed Z-up coordinates) to the Datasmith mesh. // Normals can be associated with either points or facets of the polymesh. switch (InPolymeshNode.DistributionOfNormals) { case DistributionOfNormals.AtEachPoint: { IList <XYZ> normals = InPolymeshNode.GetNormals(); if (MeshPointsTransform != null) { foreach (PolymeshFacet facet in Facets) { XYZ normal1 = MeshPointsTransform.OfVector(normals[facet.V1]); XYZ normal2 = MeshPointsTransform.OfVector(normals[facet.V2]); XYZ normal3 = MeshPointsTransform.OfVector(normals[facet.V3]); CurrentMesh.AddNormal((float)normal1.X, (float)normal1.Y, (float)normal1.Z); CurrentMesh.AddNormal((float)normal2.X, (float)normal2.Y, (float)normal2.Z); CurrentMesh.AddNormal((float)normal3.X, (float)normal3.Y, (float)normal3.Z); } } else { foreach (PolymeshFacet facet in Facets) { XYZ normal1 = normals[facet.V1]; XYZ normal2 = normals[facet.V2]; XYZ normal3 = normals[facet.V3]; CurrentMesh.AddNormal((float)normal1.X, (float)normal1.Y, (float)normal1.Z); CurrentMesh.AddNormal((float)normal2.X, (float)normal2.Y, (float)normal2.Z); CurrentMesh.AddNormal((float)normal3.X, (float)normal3.Y, (float)normal3.Z); } } break; } case DistributionOfNormals.OnePerFace: { XYZ normal = InPolymeshNode.GetNormals()[0]; if (MeshPointsTransform != null) { normal = MeshPointsTransform.OfVector(normal); } for (int i = 0; i < 3 * InPolymeshNode.NumberOfFacets; i++) { CurrentMesh.AddNormal((float)normal.X, (float)normal.Y, (float)normal.Z); } break; } case DistributionOfNormals.OnEachFacet: { if (MeshPointsTransform != null) { foreach (XYZ normal in InPolymeshNode.GetNormals()) { XYZ FinalNormal = MeshPointsTransform.OfVector(normal); CurrentMesh.AddNormal((float)FinalNormal.X, (float)FinalNormal.Y, (float)FinalNormal.Z); CurrentMesh.AddNormal((float)FinalNormal.X, (float)FinalNormal.Y, (float)FinalNormal.Z); CurrentMesh.AddNormal((float)FinalNormal.X, (float)FinalNormal.Y, (float)FinalNormal.Z); } } else { foreach (XYZ normal in InPolymeshNode.GetNormals()) { CurrentMesh.AddNormal((float)normal.X, (float)normal.Y, (float)normal.Z); CurrentMesh.AddNormal((float)normal.X, (float)normal.Y, (float)normal.Z); CurrentMesh.AddNormal((float)normal.X, (float)normal.Y, (float)normal.Z); } } break; } } }
public static void ParseMesh(FDatasmithFacadeMesh DatasmithMesh, List <Mesh> MeshSections, List <RhinoMaterialInfo> MaterialInfos) { int VertexIndexOffset = 0; List <RhinoMaterialInfo> UniqueMaterialInfo = new List <RhinoMaterialInfo>(); for (int MeshIndex = 0; MeshIndex < MeshSections.Count; ++MeshIndex) { Mesh RhinoMesh = MeshSections[MeshIndex]; // Get Material index for the current section. int MaterialIndex = UniqueMaterialInfo.FindIndex((CurrentInfo) => CurrentInfo == MaterialInfos[MeshIndex]); if (MaterialIndex == -1) { MaterialIndex = UniqueMaterialInfo.Count; DatasmithMesh.AddMaterial(MaterialIndex, MaterialInfos[MeshIndex]?.Name); UniqueMaterialInfo.Add(MaterialInfos[MeshIndex]); } // Add all the section vertices to the mesh. for (int VertexIndex = 0; VertexIndex < RhinoMesh.Vertices.Count; ++VertexIndex) { Point3f Vertex = RhinoMesh.Vertices[VertexIndex]; DatasmithMesh.AddVertex(Vertex.X, Vertex.Y, Vertex.Z); } // Try to compute normals if the section doesn't have them if (RhinoMesh.Normals.Count == 0) { RhinoMesh.Normals.ComputeNormals(); } bool bUseFaceNormals = RhinoMesh.Normals.Count != RhinoMesh.Vertices.Count && RhinoMesh.FaceNormals.Count == RhinoMesh.Faces.Count; //Add triangles and normals to the mesh. for (int FaceIndex = 0; FaceIndex < RhinoMesh.Faces.Count; ++FaceIndex) { MeshFace Face = RhinoMesh.Faces[FaceIndex]; DatasmithMesh.AddTriangle(VertexIndexOffset + Face.A, VertexIndexOffset + Face.B, VertexIndexOffset + Face.C, MaterialIndex); if (Face.IsQuad) { DatasmithMesh.AddTriangle(VertexIndexOffset + Face.A, VertexIndexOffset + Face.C, VertexIndexOffset + Face.D, MaterialIndex); } if (bUseFaceNormals) { Vector3f Normal = RhinoMesh.FaceNormals[FaceIndex]; AddNormalsToMesh(DatasmithMesh, Normal); if (Face.IsQuad) { AddNormalsToMesh(DatasmithMesh, Normal); } } else { Vector3f[] Normals = new Vector3f[] { RhinoMesh.Normals[Face.A], RhinoMesh.Normals[Face.B], RhinoMesh.Normals[Face.C] }; AddNormalsToMesh(DatasmithMesh, Normals[0], Normals[1], Normals[2]); if (Face.IsQuad) { Vector3f DNormal = RhinoMesh.Normals[Face.D]; AddNormalsToMesh(DatasmithMesh, Normals[0], Normals[2], DNormal); } } } // Add the UV coordinates for the triangles we just added. int NumberOfUVCoord = RhinoMesh.TextureCoordinates.Count; foreach (var UV in RhinoMesh.TextureCoordinates) { DatasmithMesh.AddUV(0, UV.X, 1 - UV.Y); } VertexIndexOffset += RhinoMesh.Vertices.Count; } }