Example #1
0
        public static IMesh Triangulate2DElements(IMesh mesh)
        {
            IMesh triangulated = new IMesh();

            foreach (ITopologicVertex v in mesh.Vertices)
            {
                triangulated.AddVertex(v.Key, new ITopologicVertex(v));
            }

            ISurfaceElement face;
            int             key = mesh.FindNextVertexKey();

            foreach (IElement e in mesh.Elements)
            {
                if (e.TopologicDimension == 2)
                {
                    if (e.VerticesCount == 3)
                    {
                        face = new ISurfaceElement(e.Vertices[0], e.Vertices[1], e.Vertices[2]);
                        triangulated.AddElement(face);
                    }
                    else if (e.VerticesCount == 4)
                    {
                        face = new ISurfaceElement(e.Vertices[0], e.Vertices[1], e.Vertices[3]);
                        triangulated.AddElement(face);
                        face = new ISurfaceElement(e.Vertices[3], e.Vertices[1], e.Vertices[2]);
                        triangulated.AddElement(face);
                    }
                    else
                    {
                        IPoint3D         pos = ISubdividor.ComputeAveragePosition(e.Vertices, mesh);
                        ITopologicVertex v   = new ITopologicVertex(pos.X, pos.Y, pos.Z, key);
                        triangulated.AddVertex(key, v);
                        for (int i = 1; i <= e.HalfFacetsCount; i++)
                        {
                            int[] hf;
                            e.GetHalfFacet(i, out hf);
                            face = new ISurfaceElement(hf[0], hf[1], key);
                            triangulated.AddElement(face);
                        }
                        key++;
                    }
                }
            }

            triangulated.BuildTopology();

            return(triangulated);
        }
        public void Load(IMesh mesh, string filePath)
        {
            var dxfLoad            = DxfDocument.Load(filePath);
            var vertices           = new List <IVertex>();
            var faces              = new List <IFace>();
            var verticesIndexMap   = new Dictionary <IVertex, int>();
            int currentVertexIndex = 0;

            foreach (var face3D in dxfLoad.Faces3d)
            {
                var v1 = face3D.FirstVertex;
                var v2 = face3D.SecondVertex;
                var v3 = face3D.ThirdVertex;
                var v4 = face3D.FourthVertex;
                currentVertexIndex = CreateTriangleFace(v1, v2, v3, verticesIndexMap, currentVertexIndex, vertices, faces);
                currentVertexIndex = CreateTriangleFace(v3, v4, v1, verticesIndexMap, currentVertexIndex, vertices, faces);
            }
            foreach (var vertex in vertices)
            {
                mesh.AddVertex(vertex);
            }
            foreach (var face in faces)
            {
                mesh.AddFace(face);
            }
        }
Example #3
0
 public void Load(IMesh mesh, string filePath)
 {
   var dxfLoad = DxfDocument.Load(filePath);
   var vertices = new List<IVertex>();
   var faces = new List<IFace>();
   var verticesIndexMap = new Dictionary<IVertex, int>();
   int currentVertexIndex = 0;
   foreach (var face3D in dxfLoad.Faces3d)
   {
     var v1 = face3D.FirstVertex;
     var v2 = face3D.SecondVertex;
     var v3 = face3D.ThirdVertex;
     var v4 = face3D.FourthVertex;
     currentVertexIndex = CreateTriangleFace(v1, v2, v3, verticesIndexMap, currentVertexIndex, vertices, faces);
     currentVertexIndex = CreateTriangleFace(v3, v4, v1, verticesIndexMap, currentVertexIndex, vertices, faces);
   }
   foreach (var vertex in vertices)
   {
     mesh.AddVertex(vertex);
   }
   foreach (var face in faces)
   {
     mesh.AddFace(face);
   }
 }
Example #4
0
        public static IMesh ExtrudeTwoDimensionalElementsEdges(IMesh mesh, IEnumerable <int> eKeys, double length)
        {
            IMesh            dM = mesh.CleanCopy();
            ITopologicVertex v, vv;
            IVector3D        n;
            IElement         e, nE;
            int next_vKey = mesh.FindNextVertexKey();
            int next_eKey = mesh.FindNextElementKey();

            foreach (int eK in eKeys)
            {
                e = mesh.GetElementWithKey(eK);
                if (e.TopologicDimension == 2)
                {
                    List <int> vertices = new List <int>();
                    foreach (int vK in e.Vertices)
                    {
                        v  = mesh.GetVertexWithKey(vK);
                        n  = mesh.Topology.ComputeVertexNormal(vK);
                        vv = new ITopologicVertex(v.Position + n, next_vKey);
                        dM.AddVertex(next_vKey, vv);
                        vertices.Add(next_vKey);
                        next_vKey++;
                    }

                    int[]      hf;
                    List <int> temp;
                    int        next_i, prev_i;
                    for (int i = 1; i <= e.HalfFacetsCount; i++)
                    {
                        e.GetHalfFacet(i, out hf);
                        temp   = new List <int>(hf);
                        next_i = i;
                        if (i == e.HalfFacetsCount)
                        {
                            next_i = 0;
                        }
                        prev_i = i - 1;
                        temp.Add(vertices[next_i]);
                        temp.Add(vertices[prev_i]);

                        nE = new ISurfaceElement(temp.ToArray());
                        dM.AddElement(nE);
                    }
                }
            }

            dM.BuildTopology(true);
            return(dM);
        }
Example #5
0
        public static IMesh ExtrudeTwoDimensionalElements(IMesh mesh, IEnumerable <int> eKeys, double length)
        {
            IMesh            dM = mesh.CleanCopy();
            ITopologicVertex v, vv;
            IVector3D        n, pos;
            IElement         e, nE;
            int next_vKey = mesh.FindNextVertexKey();

            foreach (int eK in eKeys)
            {
                e = mesh.GetElementWithKey(eK);
                if (e.TopologicDimension == 2)
                {
                    dM.DeleteElement(eK, false);
                    nE = null;
                    mesh.Topology.ComputeTwoDimensionalElementNormal(eK, out n, out pos);
                    n *= length;
                    List <int> vertices = new List <int>(e.Vertices);

                    foreach (int vK in e.Vertices)
                    {
                        v  = mesh.GetVertexWithKey(vK);
                        vv = new ITopologicVertex(v.Position + n, next_vKey);
                        dM.AddVertex(next_vKey, vv);
                        vertices.Add(next_vKey);
                        next_vKey++;
                    }

                    if (vertices.Count == 8)
                    {
                        nE = new IHexahedronElement(vertices.ToArray());
                    }
                    else if (vertices.Count == 6)
                    {
                        nE = new IPrismElement(vertices.ToArray());
                    }

                    if (nE != null)
                    {
                        dM.AddElement(nE);
                    }
                }
            }

            dM.BuildTopology(true);
            return(dM);
        }
Example #6
0
        public static IMesh DualMesh(IMesh mesh)
        {
            IMesh nM = new IMesh();

            // Face center points
            foreach (IElement e in mesh.Elements)
            {
                nM.AddVertex(e.Key, new ITopologicVertex(ISubdividor.ComputeAveragePosition(e.Vertices, mesh)));
            }

            int[]      data1, data2;
            PointCloud cloud  = new PointCloud();
            List <int> global = new List <int>();

            int vertexKey = nM.FindNextVertexKey();

            foreach (ITopologicVertex v in mesh.Vertices)
            {
                data1 = mesh.Topology.GetVertexIncidentElementsSorted(v.Key);
                if (!mesh.Topology.IsNakedVertex(v.Key))
                {
                    nM.AddElement(new ISurfaceElement(data1));
                }
                else
                {
                    List <int> local = new List <int>();

                    data2 = mesh.Topology.GetVertexAdjacentVerticesSorted(v.Key);
                    bool flag = false;

                    foreach (int vv in data2)
                    {
                        if (mesh.Topology.IsNakedEdge(vv, v.Key))
                        {
                            Point3d p   = ISubdividor.ComputeAveragePoint(new[] { vv, v.Key }, mesh);
                            int     idx = cloud.ClosestPoint(p);

                            if (idx == -1)
                            {
                                flag = true;
                            }
                            else
                            {
                                if (p.DistanceTo(cloud[idx].Location) > 0.01)
                                {
                                    flag = true;
                                }
                                else
                                {
                                    flag = false;
                                }
                            }

                            if (flag)
                            {
                                cloud.Add(p);
                                nM.AddVertex(vertexKey, new ITopologicVertex(p));
                                global.Add(vertexKey);
                                local.Add(vertexKey);
                                vertexKey++;
                            }
                            else
                            {
                                local.Add(global[idx]);
                            }
                        }
                    }

                    nM.AddVertex(vertexKey, new ITopologicVertex(v));
                    local.Insert(1, vertexKey);
                    local.AddRange(data1.Reverse());
                    vertexKey++;

                    nM.AddElement(new ISurfaceElement(local.ToArray()));
                }
            }

            nM.BuildTopology(true);

            return(nM);
        }
Example #7
0
        public IMesh ApplyModifier(IMesh mesh)
        {
            if (mesh != null)
            {
                this.init(mesh);

                IMesh nMesh = new IMesh();

                for (int iter = 0; iter < MaxInterations; iter++)
                {
                    for (int i = 0; i < count; i++)
                    {
                        //Laplacian calculation
                        double dxA = 0.0;
                        double dxB = 0.0;

                        int   vK     = mesh.VerticesKeys[i];
                        int[] vStart = mesh.Topology.GetVertexAdjacentVertices(vK);

                        for (int j = 0; j < vStart.Length; j++)
                        {
                            int idx = vStart[j];

                            dxA += coef[i][j] * (A[idx] - A[i]) / vStart.Length;
                            dxB += coef[i][j] * (B[idx] - B[i]) / vStart.Length;
                        }

                        //Reaction-diffusion equation
                        double AB2 = A[i] * B[i] * B[i];
                        nextA[i] = A[i] + (DiffusionRateA * dxA - AB2 + FeedFactor * (1 - A[i])) * TimeStep;
                        nextB[i] = B[i] + (DiffusionRateB * dxB + AB2 - (KillFactor + FeedFactor) * B[i]) * TimeStep;
                    }


                    for (int i = 0; i < count; i++)
                    {
                        A[i] = Math.Min(Math.Max(nextA[i], 0.0), 1.0);
                        B[i] = Math.Min(Math.Max(nextB[i], 0.0), 1.0);
                    }
                }

                for (int i = 0; i < count; i++)
                {
                    int vK = mesh.VerticesKeys[i];
                    ITopologicVertex vertex = mesh.GetVertexWithKey(vK);

                    double param = (A[i] - B[i]);

                    IVector3D n = mesh.Topology.ComputeVertexNormal(vK);
                    n *= (A[i] - B[i]);

                    vertex.Position += n;

                    nMesh.AddVertex(vK, vertex);
                }

                nMesh.AddRangeElements(mesh.Elements);

                nMesh.BuildTopology();

                return(nMesh);
            }
            else
            {
                return(null);
            }
        }
Example #8
0
    private void Load(TextReader textReader, IMesh mesh)
    {
      var vertices = new List<IVertex>();
      var faces = new List<IFace>();
      var verticesIndexMap = new Dictionary<IVertex, int>();
      int currentVertexIndex = 0;

      var positions = new List<Vector3>();
      var normals = new List<Vector3>();
      var texCoords = new List<Vector3>();
      
      string line;
      while ((line = textReader.ReadLine()) != null)
      {
        line = line.Trim(_splitCharacters);
        line = line.Replace("  ", " ");

        var parameters = line.Split(_splitCharacters);

        switch (parameters[0])
        {
          case "p": // Point
            break;

          case "v": // Vertex
            var x = float.Parse(parameters[1], CultureInfo.InvariantCulture);
            var y = float.Parse(parameters[2], CultureInfo.InvariantCulture);
            var z = float.Parse(parameters[3], CultureInfo.InvariantCulture);
            positions.Add(new Vector3(x, y, z));
            break;

          case "vt": // TexCoord
            var u = float.Parse(parameters[1], CultureInfo.InvariantCulture);
            var v = float.Parse(parameters[2], CultureInfo.InvariantCulture);
            texCoords.Add(new Vector3(u, v, 0));
            break;

          case "vn": // Normal
            var nx = float.Parse(parameters[1], CultureInfo.InvariantCulture);
            var ny = float.Parse(parameters[2], CultureInfo.InvariantCulture);
            var nz = float.Parse(parameters[3], CultureInfo.InvariantCulture);
            normals.Add(new Vector3(nx, ny, nz).Normalized());
            break;

          case "f":
            var faceVertexIndices = new List<int>();
            for (int i = 0; i < parameters.Length - 1; i++)
            {
              //The definition of what is a vertex in an OBJ file only exists appears when the vertex of each face is being defined
              //We only want to add distinctive vertices to our list of vertices, so we test here if we already have a vertex with the same
              //parameters, in which case we will use the existing vertex, if not we will add the new vertex to our list and increase the vertex
              //index counter
              var candidateVertex = GetVertex(parameters[i + 1], positions, normals, texCoords);
              if (!verticesIndexMap.ContainsKey(candidateVertex))
              {
                verticesIndexMap.Add(candidateVertex, currentVertexIndex);
                vertices.Add(candidateVertex);
                currentVertexIndex++;
              }
              var index = verticesIndexMap[candidateVertex];
              faceVertexIndices.Add(index);
            }
            var face = _faceFactory.CreateFace(faceVertexIndices);
            faces.Add(face);
            break;
        }
      }
      foreach (var vertex in vertices)
      {
        mesh.AddVertex(vertex);
      }
      foreach (var face in faces)
      {
        mesh.AddFace(face);
      }
    }
        public static IMesh CatmullClark(IMesh mesh)
        {
            IMesh sMesh = new IMesh();

            //Old vertices
            foreach (int vK in mesh.VerticesKeys)
            {
                sMesh.AddVertex(vK, new ITopologicVertex(ComputesCatmullClarkVertexPosition(mesh, vK)));
            }

            // Subidvision
            int key = mesh.FindNextVertexKey();

            int[]    hf;
            IElement element_sibling;
            int      elementID_sibling, halfFacetID_sibling;
            Boolean  visited;
            Dictionary <int, int[]> eVertex = new Dictionary <int, int[]>();
            Dictionary <int, int>   fVertex = new Dictionary <int, int>();

            IPoint3D pos;

            int count = mesh.ElementsKeys.Count;

            // Vertices
            foreach (int elementID in mesh.ElementsKeys)
            {
                IElement e = mesh.GetElementWithKey(elementID);

                //Add face vertex
                pos = ComputeAveragePosition(e.Vertices, mesh);
                sMesh.AddVertex(key, new ITopologicVertex(pos.X, pos.Y, pos.Z, key));
                fVertex.Add(elementID, key);
                key++;

                if (!e.Visited)
                {
                    if (e.TopologicDimension == 2)
                    {
                        if (!eVertex.ContainsKey(elementID))
                        {
                            eVertex.Add(elementID, new int[e.HalfFacetsCount]);
                        }

                        for (int halfFacetID = 1; halfFacetID <= e.HalfFacetsCount; halfFacetID++)
                        {
                            e.GetHalfFacet(halfFacetID, out hf);
                            visited = e.IsHalfFacetVisited(halfFacetID);

                            if (!visited)
                            {
                                e.RegisterHalfFacetVisit(halfFacetID);
                                e.GetHalfFacet(halfFacetID, out hf);
                                pos = ComputeAveragePosition(hf, mesh);
                                sMesh.AddVertex(key, new ITopologicVertex(pos.X, pos.Y, pos.Z, key));
                                eVertex[elementID][halfFacetID - 1] = key;

                                if (!e.IsNakedSiblingHalfFacet(halfFacetID))
                                {
                                    while (!visited)
                                    {
                                        e.RegisterHalfFacetVisit(halfFacetID);

                                        //Collect information of siblings
                                        elementID_sibling   = e.GetSiblingElementID(halfFacetID);
                                        halfFacetID_sibling = e.GetSiblingHalfFacetID(halfFacetID);
                                        element_sibling     = mesh.GetElementWithKey(elementID_sibling);

                                        visited = element_sibling.IsHalfFacetVisited(halfFacetID_sibling);

                                        halfFacetID = halfFacetID_sibling;
                                        e           = element_sibling;

                                        if (!eVertex.ContainsKey(elementID_sibling))
                                        {
                                            eVertex.Add(elementID_sibling, new int[e.HalfFacetsCount]);
                                        }
                                        eVertex[elementID_sibling][halfFacetID - 1] = key;
                                    }
                                }

                                key++;
                            }
                        }
                    }
                }
            }
            mesh.CleanElementsVisits();

            //Faces
            int prev;

            int[] data;
            foreach (int elementID in mesh.ElementsKeys)
            {
                IElement e = mesh.GetElementWithKey(elementID);

                if (e.TopologicDimension == 2)
                {
                    int[] eV = eVertex[elementID];
                    for (int i = 0; i < e.Vertices.Length; i++)
                    {
                        prev = i - 1;
                        if (prev < 0)
                        {
                            prev = e.Vertices.Length - 1;
                        }

                        data = new int[] { e.Vertices[i], eV[prev], fVertex[elementID], eV[i] };
                        ISurfaceElement face = new ISurfaceElement(data);
                        sMesh.AddElement(face);
                    }
                }
            }

            // Edge Vertex
            foreach (int eK in eVertex.Keys)
            {
                IElement e = mesh.GetElementWithKey(eK);
                for (int i = 1; i <= e.HalfFacetsCount; i++)
                {
                    int[] hf1;
                    e.GetHalfFacet(i, out hf1);
                    ITopologicVertex v1 = sMesh.GetVertexWithKey(eVertex[eK][i - 1]);
                    v1.Position = ComputeCatmullClarkEdgeVertexPosition(hf1, mesh);
                    sMesh.SetVertex(v1.Key, v1);
                }
            }

            //Build Mesh
            sMesh.BuildTopology();

            return(sMesh);
        }
Example #10
0
        public static IMesh Loop(IMesh mesh)
        {
            IMesh triMesh = IModifier.Triangulate2DElements(mesh);

            IMesh sMesh = new IMesh();

            //Old vertices
            foreach (int vK in triMesh.VerticesKeys)
            {
                sMesh.AddVertex(vK, new ITopologicVertex(ComputeLoopVertexPosition(triMesh, vK)));
            }

            // Subidvision
            int key = triMesh.FindNextVertexKey();

            int[]    hf;
            IElement element_sibling;
            int      elementID_sibling, halfFacetID_sibling;
            Boolean  visited;
            Dictionary <int, int[]> eVertex = new Dictionary <int, int[]>();

            // Vertices
            foreach (int elementID in triMesh.ElementsKeys)
            {
                IElement e = triMesh.GetElementWithKey(elementID);

                if (!e.Visited)
                {
                    if (e.TopologicDimension == 2)
                    {
                        if (!eVertex.ContainsKey(elementID))
                        {
                            eVertex.Add(elementID, new int[e.HalfFacetsCount]);
                        }

                        for (int halfFacetID = 1; halfFacetID <= e.HalfFacetsCount; halfFacetID++)
                        {
                            e.GetHalfFacet(halfFacetID, out hf);
                            visited = e.IsHalfFacetVisited(halfFacetID);

                            if (!visited)
                            {
                                e.RegisterHalfFacetVisit(halfFacetID);
                                e.GetHalfFacet(halfFacetID, out hf);
                                sMesh.AddVertex(key, new ITopologicVertex(ComputeAveragePosition(hf, triMesh)));
                                eVertex[elementID][halfFacetID - 1] = key;

                                if (!e.IsNakedSiblingHalfFacet(halfFacetID))
                                {
                                    while (!visited)
                                    {
                                        e.RegisterHalfFacetVisit(halfFacetID);

                                        //Collect information of siblings
                                        elementID_sibling   = e.GetSiblingElementID(halfFacetID);
                                        halfFacetID_sibling = e.GetSiblingHalfFacetID(halfFacetID);
                                        element_sibling     = triMesh.GetElementWithKey(elementID_sibling);

                                        visited = element_sibling.IsHalfFacetVisited(halfFacetID_sibling);

                                        halfFacetID = halfFacetID_sibling;
                                        e           = element_sibling;

                                        if (!eVertex.ContainsKey(elementID_sibling))
                                        {
                                            eVertex.Add(elementID_sibling, new int[e.HalfFacetsCount]);
                                        }
                                        eVertex[elementID_sibling][halfFacetID - 1] = key;
                                    }
                                }

                                key++;
                            }
                        }
                    }
                }
            }
            triMesh.CleanElementsVisits();

            //Faces
            int prev;

            foreach (int elementID in triMesh.ElementsKeys)
            {
                IElement e = triMesh.GetElementWithKey(elementID);

                if (e.TopologicDimension == 2)
                {
                    int[] eV = eVertex[elementID];
                    for (int i = 0; i < e.Vertices.Length; i++)
                    {
                        prev = i - 1;
                        if (prev < 0)
                        {
                            prev = e.Vertices.Length - 1;
                        }

                        sMesh.AddElement(new ISurfaceElement(new[] { eV[prev], e.Vertices[i], eV[i] }));
                    }
                    sMesh.AddElement(new ISurfaceElement(new[] { eV[0], eV[1], eV[2] }));
                }
            }

            // Edge Vertex
            foreach (int eK in eVertex.Keys)
            {
                IElement e = triMesh.GetElementWithKey(eK);
                for (int i = 1; i <= e.HalfFacetsCount; i++)
                {
                    e.GetHalfFacet(i, out hf);
                    int vK = eVertex[eK][i - 1];
                    sMesh.SetVertexPosition(vK, ComputeLoopEdgeVertexPosition(hf, triMesh));
                }
            }

            //Build Mesh
            sMesh.BuildTopology();

            return(sMesh);
        }
Example #11
0
        private void Load(TextReader textReader, IMesh mesh)
        {
            var vertices           = new List <IVertex>();
            var faces              = new List <IFace>();
            var verticesIndexMap   = new Dictionary <IVertex, int>();
            int currentVertexIndex = 0;

            var positions = new List <Vector3>();
            var normals   = new List <Vector3>();
            var texCoords = new List <Vector3>();

            string line;

            while ((line = textReader.ReadLine()) != null)
            {
                line = line.Trim(_splitCharacters);
                line = line.Replace("  ", " ");

                var parameters = line.Split(_splitCharacters);

                switch (parameters[0])
                {
                case "p": // Point
                    break;

                case "v": // Vertex
                    var x = float.Parse(parameters[1], CultureInfo.InvariantCulture);
                    var y = float.Parse(parameters[2], CultureInfo.InvariantCulture);
                    var z = float.Parse(parameters[3], CultureInfo.InvariantCulture);
                    positions.Add(new Vector3(x, y, z));
                    break;

                case "vt": // TexCoord
                    var u = float.Parse(parameters[1], CultureInfo.InvariantCulture);
                    var v = float.Parse(parameters[2], CultureInfo.InvariantCulture);
                    texCoords.Add(new Vector3(u, v, 0));
                    break;

                case "vn": // Normal
                    var nx = float.Parse(parameters[1], CultureInfo.InvariantCulture);
                    var ny = float.Parse(parameters[2], CultureInfo.InvariantCulture);
                    var nz = float.Parse(parameters[3], CultureInfo.InvariantCulture);
                    normals.Add(new Vector3(nx, ny, nz).Normalized());
                    break;

                case "f":
                    var faceVertexIndices = new List <int>();
                    for (int i = 0; i < parameters.Length - 1; i++)
                    {
                        //The definition of what is a vertex in an OBJ file only exists appears when the vertex of each face is being defined
                        //We only want to add distinctive vertices to our list of vertices, so we test here if we already have a vertex with the same
                        //parameters, in which case we will use the existing vertex, if not we will add the new vertex to our list and increase the vertex
                        //index counter
                        var candidateVertex = GetVertex(parameters[i + 1], positions, normals, texCoords);
                        if (!verticesIndexMap.ContainsKey(candidateVertex))
                        {
                            verticesIndexMap.Add(candidateVertex, currentVertexIndex);
                            vertices.Add(candidateVertex);
                            currentVertexIndex++;
                        }
                        var index = verticesIndexMap[candidateVertex];
                        faceVertexIndices.Add(index);
                    }
                    var face = _faceFactory.CreateFace(faceVertexIndices);
                    faces.Add(face);
                    break;
                }
            }
            foreach (var vertex in vertices)
            {
                mesh.AddVertex(vertex);
            }
            foreach (var face in faces)
            {
                mesh.AddFace(face);
            }
        }