Esempio n. 1
0
        // 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;
            }
            }
        }
Esempio n. 2
0
        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;
            }
        }