Example #1
0
 /// <summary>
 ///
 /// </summary>
 /// <typeparam name="V"></typeparam>
 /// <typeparam name="E"></typeparam>
 /// <typeparam name="F"></typeparam>
 /// <param name="mesh"></param>
 /// <param name="position"></param>
 public static void TriSplit <V, E, F>(HeMeshBase <V, E, F> mesh, Property <V, Vec3d> position)
     where V : HeMeshBase <V, E, F> .Vertex
     where E : HeMeshBase <V, E, F> .Halfedge
     where F : HeMeshBase <V, E, F> .Face
 {
     // TODO
 }
Example #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="mesh"></param>
        /// <returns></returns>
        public G CreateFromFaceTopology(HeMeshBase <HeMesh3d.Vertex, HeMesh3d.Halfedge, HeMesh3d.Face> mesh)
        {
            var graph = Create(mesh.Faces.Count, mesh.Halfedges.Count);

            graph.AppendFaceTopology(mesh);
            return(graph);
        }
Example #3
0
 /// <summary>
 ///
 /// </summary>
 /// <typeparam name="V"></typeparam>
 /// <typeparam name="E"></typeparam>
 /// <typeparam name="F"></typeparam>
 /// <param name="mesh"></param>
 /// <param name="first"></param>
 /// <param name="position"></param>
 public static void Unroll <V, E, F>(HeMeshBase <V, E, F> mesh, F first, Property <V, Vec3d> position)
     where V : HeMeshBase <V, E, F> .Vertex
     where E : HeMeshBase <V, E, F> .Halfedge
     where F : HeMeshBase <V, E, F> .Face
 {
     Unroll(mesh, first, position, delegate { });
 }
Example #4
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="V"></typeparam>
        /// <typeparam name="E"></typeparam>
        /// <typeparam name="F"></typeparam>
        /// <param name="mesh"></param>
        /// <param name="position"></param>
        private static void QuadSplitGeometry <V, E, F>(HeMeshBase <V, E, F> mesh, Property <V, Vec3d> position)
            where V : HeMeshBase <V, E, F> .Vertex
            where E : HeMeshBase <V, E, F> .Halfedge
            where F : HeMeshBase <V, E, F> .Face
        {
            // create face vertices
            foreach (var f in mesh.Faces)
            {
                var v = mesh.AddVertex();

                if (!f.IsUnused)
                {
                    position.Set(v, f.Vertices.Mean(position.Get));
                }
            }

            // create edge vertices
            foreach (var he in mesh.Edges)
            {
                var v = mesh.AddVertex();

                if (!he.IsUnused)
                {
                    position.Set(v, he.Lerp(position.Get, 0.5));
                }
            }
        }
Example #5
0
        /// <summary>
        ///
        /// </summary>
        private static void CatmullClarkSmoothFixed <V, E, F>(HeMeshBase <V, E, F> mesh, Property <V, Vec3d> position)
            where V : HeMeshBase <V, E, F> .Vertex
            where E : HeMeshBase <V, E, F> .Halfedge
            where F : HeMeshBase <V, E, F> .Face
        {
            var verts = mesh.Vertices;

            int ev0 = verts.Count - mesh.Edges.Count; // index of first edge vertex
            int fv0 = ev0 - mesh.Faces.Count;         // index of first face vertex

            // set old vertices
            for (int i = 0; i < fv0; i++)
            {
                var v = verts[i];
                if (v.IsUnused || v.IsBoundary)
                {
                    continue;                             // skip boundary verts
                }
                var fsum = new Vec3d();
                var esum = new Vec3d();
                int n    = 0;

                foreach (var he in v.OutgoingHalfedges)
                {
                    fsum += position.Get(verts[he.Face.Index + fv0]);
                    esum += position.Get(verts[(he.Index >> 1) + ev0]);
                    n++;
                }

                var t = 1.0 / n;
                position.Set(v, (position.Get(v) * (n - 3) + fsum * t + 2 * esum * t) * t);
            }
        }
Example #6
0
 /// <summary>
 /// Applies a single iteration of Catmull-Clark subdivision to the given mesh.
 /// If using external buffers to store vertex attributes, the number of vertices after subdivision equals the sum of the number of vertices, edges, and faces in the initial mesh.
 /// </summary>
 /// <typeparam name="V"></typeparam>
 /// <typeparam name="E"></typeparam>
 /// <typeparam name="F"></typeparam>
 /// <param name="mesh"></param>
 /// <param name="position"></param>
 public static void QuadSplit <V, E, F>(HeMeshBase <V, E, F> mesh, Property <V, Vec3d> position)
     where V : HeVertex <V, E, F>
     where E : Halfedge <V, E, F>
     where F : HeFace <V, E, F>
 {
     QuadSplitGeometry(mesh, position);
     QuadSplitTopology(mesh);
 }
Example #7
0
 /// <summary>
 /// Applies a single iteration of Catmull-Clark subdivision to the given mesh.
 /// If using external buffers to store vertex attributes, the number of vertices after subdivision equals the sum of the number of vertices edges and faces in the initial mesh.
 /// http://rosettacode.org/wiki/Catmull%E2%80%93Clark_subdivision_surface
 /// http://w3.impa.br/~lcruz/courses/cma/surfaces.html
 /// </summary>
 /// <typeparam name="V"></typeparam>
 /// <typeparam name="E"></typeparam>
 /// <typeparam name="F"></typeparam>
 /// <param name="mesh"></param>
 /// <param name="position"></param>
 /// <param name="boundaryType"></param>
 public static void CatmullClark <V, E, F>(HeMeshBase <V, E, F> mesh, Property <V, Vec3d> position, SmoothBoundaryType boundaryType)
     where V : HeVertex <V, E, F>
     where E : Halfedge <V, E, F>
     where F : HeFace <V, E, F>
 {
     CatmullClarkGeometry(mesh, position, boundaryType);
     QuadSplitTopology(mesh);
 }
Example #8
0
 /// <summary>
 ///
 /// </summary>
 /// <typeparam name="V"></typeparam>
 /// <typeparam name="E"></typeparam>
 /// <typeparam name="F"></typeparam>
 /// <param name="mesh"></param>
 /// <param name="position"></param>
 public static void Loop <V, E, F>(HeMeshBase <V, E, F> mesh, Property <V, Vec3d> position)
     where V : HeVertex <V, E, F>
     where E : Halfedge <V, E, F>
     where F : HeFace <V, E, F>
 {
     // TODO
     throw new NotImplementedException();
 }
Example #9
0
 /// <summary>
 ///
 /// </summary>
 /// <typeparam name="V"></typeparam>
 /// <typeparam name="E"></typeparam>
 /// <typeparam name="F"></typeparam>
 /// <param name="mesh"></param>
 /// <param name="hedge"></param>
 /// <returns></returns>
 public static HeQuadStrip <V, E, F> GetQuadStrip <V, E, F>(HeMeshBase <V, E, F> mesh, E hedge)
     where V : HeMeshBase <V, E, F> .Vertex
     where E : HeMeshBase <V, E, F> .Halfedge
     where F : HeMeshBase <V, E, F> .Face
 {
     mesh.Halfedges.ContainsCheck(hedge);
     return(GetQuadStrip <V, E, F>(hedge, mesh.Faces.NextTag));
 }
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="V"></typeparam>
        /// <typeparam name="E"></typeparam>
        /// <typeparam name="F"></typeparam>
        /// <param name="mesh"></param>
        /// <param name="first"></param>
        public static void Unroll <V, E, F>(HeMeshBase <V, E, F> mesh, F first)
            where V : HeVertex <V, E, F>, IVertex3d
            where E : Halfedge <V, E, F>
            where F : HeFace <V, E, F>
        {
            var prop = Property.Create <V, Vec3d>(v => v.Position, (v, p) => v.Position = p);

            Unroll(mesh, first, prop, delegate { });
        }
Example #11
0
            /// <summary>
            ///
            /// </summary>
            /// <typeparam name="TV"></typeparam>
            /// <typeparam name="TE"></typeparam>
            /// <typeparam name="TF"></typeparam>
            /// <param name="mesh"></param>
            /// <param name="target"></param>
            /// <param name="features"></param>
            /// <param name="tolerance"></param>
            /// <returns></returns>
            public static Solver Create <TV, TE, TF>(HeMeshBase <TV, TE, TF> mesh, IEnumerable <IFeature> features, double tolerance = 1.0e-4)
                where TV : HeMeshBase <TV, TE, TF> .Vertex, IVertex3d
                where TE : HeMeshBase <TV, TE, TF> .Halfedge
                where TF : HeMeshBase <TV, TE, TF> .Face
            {
                var copy = HeMesh.Factory.CreateCopy(mesh, (v0, v1) => v0.Position = v1.Position, delegate { }, delegate { });

                return(new Solver(copy, features, tolerance));
            }
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="V"></typeparam>
        /// <typeparam name="E"></typeparam>
        /// <typeparam name="F"></typeparam>
        /// <param name="mesh"></param>
        /// <param name="first"></param>
        /// <param name="position"></param>
        /// <param name="setChildIndex"></param>
        public static void Unroll <V, E, F>(HeMeshBase <V, E, F> mesh, F first, Property <V, Vec3d> position, Action <E, int> setChildIndex)
            where V : HeVertex <V, E, F>
            where E : Halfedge <V, E, F>
            where F : HeFace <V, E, F>
        {
            var unroller = new HeMeshUnroller <V, E, F>(mesh, first, position);

            unroller.Unroll(setChildIndex);
        }
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TV"></typeparam>
        /// <typeparam name="TE"></typeparam>
        /// <typeparam name="TF"></typeparam>
        /// <param name="mesh"></param>
        /// <param name="target"></param>
        /// <param name="features"></param>
        /// <param name="tolerance"></param>
        /// <returns></returns>
        public static DynamicRemesher Create <TV, TE, TF>(HeMeshBase <TV, TE, TF> mesh, MeshFeature target, IEnumerable <IFeature> features, double tolerance = 1.0e-4)
            where TV : HeVertex <TV, TE, TF>, IVertex3d
            where TE : Halfedge <TV, TE, TF>
            where TF : HeFace <TV, TE, TF>
        {
            var copy = HeMeshSim.Factory.CreateCopy(mesh, (v0, v1) => v0.Position = v1.Position, delegate { }, delegate { });

            return(new DynamicRemesher(copy, target, features, tolerance));
        }
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="V"></typeparam>
        /// <typeparam name="E"></typeparam>
        /// <typeparam name="F"></typeparam>
        /// <param name="mesh"></param>
        /// <param name="first"></param>
        /// <param name="setChildIndex"></param>
        public static void Unroll <V, E, F>(HeMeshBase <V, E, F> mesh, F first, Action <E, int> setChildIndex)
            where V : HeVertex <V, E, F>, IVertex3d
            where E : Halfedge <V, E, F>
            where F : HeFace <V, E, F>
        {
            var prop = Property.Create <V, Vec3d>(v => v.Position, (v, p) => v.Position = p);

            Unroll(mesh, first, prop, setChildIndex);
        }
Example #15
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="V"></typeparam>
        /// <typeparam name="E"></typeparam>
        /// <typeparam name="F"></typeparam>
        /// <param name="mesh"></param>
        /// <param name="first"></param>
        /// <param name="setChildIndex"></param>
        public static void Unroll <V, E, F>(HeMeshBase <V, E, F> mesh, F first, Func <E, double> getUnrollFactor, Action <E, int> setChildIndex)
            where V : HeMeshBase <V, E, F> .Vertex, IVertex3d
            where E : HeMeshBase <V, E, F> .Halfedge
            where F : HeMeshBase <V, E, F> .Face
        {
            var prop = Property.Create <V, Vec3d>(v => v.Position, (v, p) => v.Position = p);

            Unroll(mesh, first, prop, getUnrollFactor, setChildIndex);
        }
Example #16
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="UV"></typeparam>
        /// <typeparam name="UE"></typeparam>
        /// <typeparam name="UF"></typeparam>
        /// <param name="mesh"></param>
        /// <param name="setHedge"></param>
        /// <param name="setVertex"></param>
        /// <returns></returns>
        public TG CreateFromFaceTopology <UV, UE, UF>(HeMeshBase <UV, UE, UF> mesh, Action <TV, UF> setVertex, Action <TE, UE> setHedge)
            where UV : HeVertex <UV, UE, UF>
            where UE : Halfedge <UV, UE, UF>
            where UF : HeFace <UV, UE, UF>
        {
            var result = Create(mesh.Faces.Count, mesh.Halfedges.Count);

            result.AppendFaceTopology(mesh, setVertex, setHedge);
            return(result);
        }
Example #17
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="UV"></typeparam>
        /// <typeparam name="UE"></typeparam>
        /// <typeparam name="UF"></typeparam>
        /// <param name="mesh"></param>
        /// <param name="setVertex"></param>
        /// <param name="setHedge"></param>
        /// <returns></returns>
        public TG CreateFromVertexTopology <UV, UE, UF>(HeMeshBase <UV, UE, UF> mesh, Action <TV, UV> setVertex = null, Action <TE, UE> setHedge = null)
            where UV : HeMeshBase <UV, UE, UF> .Vertex
            where UE : HeMeshBase <UV, UE, UF> .Halfedge
            where UF : HeMeshBase <UV, UE, UF> .Face
        {
            var result = Create(mesh.Vertices.Count, mesh.Halfedges.Count);

            result.AppendVertexTopology(mesh, setVertex, setHedge);
            return(result);
        }
Example #18
0
        /// <summary>
        /// Action delegates specify how attributes of original elements are mapped to attributes of copied elements.
        /// </summary>
        /// <typeparam name="UV"></typeparam>
        /// <typeparam name="UE"></typeparam>
        /// <typeparam name="UF"></typeparam>
        /// <param name="mesh"></param>
        /// <param name="setVertex"></param>
        /// <param name="setHedge"></param>
        /// <param name="setFace"></param>
        /// <returns></returns>
        public TM CreateCopy <UV, UE, UF>(HeMeshBase <UV, UE, UF> mesh, Action <TV, UV> setVertex, Action <TE, UE> setHedge, Action <TF, UF> setFace)
            where UV : HeVertex <UV, UE, UF>
            where UE : Halfedge <UV, UE, UF>
            where UF : HeFace <UV, UE, UF>
        {
            var copy = Create(mesh.Vertices.Capacity, mesh.Halfedges.Capacity, mesh.Faces.Capacity);

            copy.Append(mesh, setVertex, setHedge, setFace);
            return(copy);
        }
Example #19
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="path"></param>
        /// <param name="graph"></param>
        /// <param name="setVertexAttributes"></param>
        /// <param name="setHedgeAttributes"></param>
        public static void ReadFromJson <TV, TE, TF>(string path, HeMeshBase <TV, TE, TF> mesh, Action <TV, object[]> setVertexAttributes = null, Action <TE, object[]> setHedgeAttributes = null, Action <TF, object[]> setFaceAttributes = null)
            where TV : HeMeshBase <TV, TE, TF> .Vertex
            where TE : HeMeshBase <TV, TE, TF> .Halfedge
            where TF : HeMeshBase <TV, TE, TF> .Face
        {
            //var buffer = CoreIO.DeserializeJson<HeMeshJsonBuffer>(path);
            var buffer = CoreIO.DeserializeJson <HeJsonBuffer>(path);

            buffer.ReadTo(mesh, setVertexAttributes, setHedgeAttributes, setFaceAttributes);
        }
Example #20
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TV"></typeparam>
        /// <typeparam name="TE"></typeparam>
        public static void WriteToJson <TV, TE, TF>(HeMeshBase <TV, TE, TF> mesh, string path, Func <TV, IEnumerable <object> > getVertexAttributes = null, Func <TE, IEnumerable <object> > getHedgeAttributes = null, Func <TF, IEnumerable <object> > getFaceAttributes = null)
            where TV : HeMeshBase <TV, TE, TF> .Vertex
            where TE : HeMeshBase <TV, TE, TF> .Halfedge
            where TF : HeMeshBase <TV, TE, TF> .Face
        {
            var buffer = new HeJsonBuffer();

            buffer.WriteFrom(mesh, getVertexAttributes, getHedgeAttributes, getFaceAttributes);
            CoreIO.SerializeJson(buffer, path);
        }
Example #21
0
        /// <summary>
        /// Returns the dual of the given mesh.
        /// Action delegates specify how attributes of primal elements are mapped to attributes of dual elements.
        /// Note this method preserves indexical correspondance between primal and dual elements.
        /// </summary>
        /// <typeparam name="UV"></typeparam>
        /// <typeparam name="UE"></typeparam>
        /// <typeparam name="UF"></typeparam>
        /// <param name="mesh"></param>
        /// <param name="setVertex"></param>
        /// <param name="setHedge"></param>
        /// <param name="setFace"></param>
        /// <returns></returns>
        public TM CreateDual <UV, UE, UF>(HeMeshBase <UV, UE, UF> mesh, Action <TV, UF> setVertex, Action <TE, UE> setHedge, Action <TF, UV> setFace)
            where UV : HeVertex <UV, UE, UF>
            where UE : Halfedge <UV, UE, UF>
            where UF : HeFace <UV, UE, UF>
        {
            var dual = Create(mesh.Vertices.Capacity, mesh.Halfedges.Capacity, mesh.Faces.Capacity);

            dual.AppendDual(mesh, setVertex, setHedge, setFace);
            return(dual);
        }
Example #22
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="V"></typeparam>
        /// <typeparam name="E"></typeparam>
        /// <typeparam name="F"></typeparam>
        /// <param name="mesh"></param>
        /// <param name="first"></param>
        /// <param name="position"></param>
        /// <param name="setChildIndex"></param>
        public static void Unroll <V, E, F>(HeMeshBase <V, E, F> mesh, F first, Property <V, Vec3d> position, Action <E, int> setChildIndex)
            where V : HeMeshBase <V, E, F> .Vertex
            where E : HeMeshBase <V, E, F> .Halfedge
            where F : HeMeshBase <V, E, F> .Face
        {
            var unroller = new HeMeshUnroller <V, E, F>(mesh, first, position);

            unroller.DetachFaceCycles(setChildIndex);
            unroller.Unroll();
        }
Example #23
0
        /// <summary>
        /// Implementation currently ignores texture coordinates and normals.
        /// </summary>
        /// <typeparam name="TV"></typeparam>
        /// <typeparam name="TE"></typeparam>
        /// <typeparam name="TF"></typeparam>
        /// <param name="path"></param>
        /// <param name="mesh"></param>
        /// <param name="setPosition"></param>
        public static void ReadFromOBJ <TV, TE, TF>(string path, HeMeshBase <TV, TE, TF> mesh, Action <TV, Vec3d> setPosition)
            where TV : HeVertex <TV, TE, TF>
            where TE : Halfedge <TV, TE, TF>
            where TF : HeFace <TV, TE, TF>
        {
            var verts = mesh.Vertices;
            var faces = mesh.Faces;
            var face  = new List <int>();

            using (var reader = new StreamReader(path, Encoding.ASCII))
            {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    // skip empty lines and comments
                    if (line.Length == 0 || line[0] == '#')
                    {
                        continue;
                    }

                    // check the first character
                    var segments = line.Split(_separatorsOBJ, StringSplitOptions.RemoveEmptyEntries);
                    switch (segments[0])
                    {
                    case "v":
                    {
                        // parse vertex
                        double x = double.Parse(segments[1]);
                        double y = double.Parse(segments[2]);
                        double z = double.Parse(segments[3]);

                        var v = mesh.AddVertex();
                        setPosition(v, new Vec3d(x, y, z));
                        break;
                    }

                    case "f":
                    {
                        // parse face
                        for (int i = 1; i < segments.Length; i++)
                        {
                            var ids = segments[i].Split(_faceSeparatorsOBJ);
                            face.Add(int.Parse(ids[0]) - 1);
                        }

                        mesh.AddFace(face);
                        face.Clear();
                        break;
                    }
                    }
                }
            }
        }
Example #24
0
        /// <summary>
        /// If using external buffers to store vertex attributes, the number of vertices in the resulting mesh the equals the sum of the number of vertices and halfedges in the given mesh.
        /// </summary>
        /// <typeparam name="UV"></typeparam>
        /// <typeparam name="UE"></typeparam>
        /// <typeparam name="UF"></typeparam>
        /// <param name="mesh"></param>
        /// <param name="getPosition"></param>
        /// <param name="getScale"></param>
        /// <param name="getCenter"></param>
        /// <param name="setPosition"></param>
        /// <returns></returns>
        public TM CreateFramedDual <UV, UE, UF>(HeMeshBase <UV, UE, UF> mesh, Func <UV, Vec3d> getPosition, Func <UV, double> getScale, Func <UF, Vec3d> getCenter, Action <TV, Vec3d> setPosition)
            where UV : HeVertex <UV, UE, UF>
            where UE : Halfedge <UV, UE, UF>
            where UF : HeFace <UV, UE, UF>
        {
            int ne     = mesh.Edges.Count;
            var result = Create(ne << 3, ne << 4, ne << 3);

            //CreateWeaveGeometry(mesh, result, getPosition, getScale, getNormal, getCenter, setPosition);
            //CreateWeaveTopology(mesh, result);
            return(result);
        }
Example #25
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="UV"></typeparam>
        /// <typeparam name="UE"></typeparam>
        /// <typeparam name="UF"></typeparam>
        /// <param name="mesh"></param>
        /// <param name="setVertex"></param>
        /// <param name="setHedge"></param>
        public void AppendVertexTopology <UV, UE, UF>(HeMeshBase <UV, UE, UF> mesh, Action <TV, UV> setVertex, Action <TE, UE> setHedge)
            where UV : HeVertex <UV, UE, UF>
            where UE : Halfedge <UV, UE, UF>
            where UF : HeFace <UV, UE, UF>
        {
            int nhe = _hedges.Count;
            int nv  = _vertices.Count;

            var meshHedges = mesh.Halfedges;
            var meshVerts  = mesh.Vertices;

            // append new elements
            for (int i = 0; i < meshVerts.Count; i++)
            {
                AddVertex();
            }

            for (int i = 0; i < meshHedges.Count; i += 2)
            {
                AddEdge();
            }

            // link new vertices to new halfedges
            for (int i = 0; i < meshVerts.Count; i++)
            {
                var v0 = meshVerts[i];
                var v1 = _vertices[i + nv];
                setVertex(v1, v0);

                if (v0.IsRemoved)
                {
                    continue;
                }
                v1.FirstOut = _hedges[v0.FirstOut.Index + nhe];
            }

            // link new halfedges to eachother and new vertices
            for (int i = 0; i < meshHedges.Count; i++)
            {
                var he0 = meshHedges[i];
                var he1 = _hedges[i + nhe];
                setHedge(he1, he0);

                if (he0.IsRemoved)
                {
                    continue;
                }
                he1.PrevAtStart = _hedges[he0.PrevAtStart.Index + nhe];
                he1.NextAtStart = _hedges[he0.NextAtStart.Index + nhe];
                he1.Start       = _vertices[he0.Start.Index + nv];
            }
        }
Example #26
0
        /*
         * /// <summary>
         * /// Applies a single iteration of Catmull-Clark subdivision to the given mesh.
         * /// http://rosettacode.org/wiki/Catmull%E2%80%93Clark_subdivision_surface
         * /// http://w3.impa.br/~lcruz/courses/cma/surfaces.html
         * /// </summary>
         * /// <typeparam name="V"></typeparam>
         * /// <typeparam name="E"></typeparam>
         * /// <typeparam name="F"></typeparam>
         * /// <param name="mesh"></param>
         * /// <param name="position"></param>
         * /// <param name="boundaryType"></param>
         * public static void CatmullClark<V, E, F>(HeMesh<V, E, F> mesh, Property<V, Vec3d> position, SmoothBoundaryType boundaryType, bool parallel)
         *  where V : HeVertex<V, E, F>
         *  where E : Halfedge<V, E, F>
         *  where F : HeFace<V, E, F>
         * {
         *  CatmullClarkGeometry(mesh, position, boundaryType, parallel);
         *  QuadSplitTopology(mesh);
         * }
         *
         *
         * /// <summary>
         * ///
         * /// </summary>
         * private static void CatmullClarkGeometry<V, E, F>(HeMesh<V, E, F> mesh, Property<V, Vec3d> position, SmoothBoundaryType boundaryType, bool parallel)
         * where V : HeVertex<V, E, F>
         * where E : Halfedge<V, E, F>
         * where F : HeFace<V, E, F>
         * {
         *  var verts = mesh.Vertices;
         *  var edges = mesh.Edges;
         *  var faces = mesh.Faces;
         *
         *  int fv0 = verts.Count; // index of first face vertex
         *  int ev0 = verts.Count + faces.Count;
         *
         *  // add all new vertices
         *  mesh.AddVertices(faces.Count);
         *  mesh.AddVertices(edges.Count);
         *
         *  // set attributes of face vertices
         *  Action<Tuple<int, int>> setFaceVerts = range =>
         *   {
         *       for (int i = range.Item1; i < range.Item2; i++)
         *       {
         *           var f = faces[i];
         *
         *           if (!f.IsRemoved)
         *               position.Set(verts[i + fv0], f.Vertices.Mean(position.Get));
         *       }
         *   };
         *
         *  // set attributes of edge vertices
         *  Action<Tuple<int, int>> setEdgeVerts = range =>
         *  {
         *      for (int i = range.Item1; i < range.Item2; i++)
         *      {
         *          var he0 = edges[i];
         *          if (he0.IsRemoved) continue;
         *
         *          if (he0.IsBoundary)
         *          {
         *              position.Set(verts[i + ev0], he0.Lerp(position.Get, 0.5));
         *              continue;
         *          }
         *
         *          var he1 = he0.Twin;
         *          var p0 = position.Get(he0.Start);
         *          var p1 = position.Get(he1.Start);
         *          var p2 = position.Get(verts[he0.Face.Index + fv0]);
         *          var p3 = position.Get(verts[he1.Face.Index + fv0]);
         *          position.Set(verts[i + ev0], (p0 + p1 + p2 + p3) * 0.25);
         *      }
         *  };
         *
         *  // set attributes of old vertices
         *  //CatmullClarkSmooth(mesh, position, boundaryType);
         *  Action<Tuple<int, int>> setOldVerts = range =>
         *  {
         *      for (int i = range.Item1; i < range.Item2; i++)
         *      {
         *          var v = verts[i];
         *          if (v.IsRemoved) continue;
         *
         *          if (v.IsBoundary)
         *          {
         *              var he0 = v.FirstOut;
         *              var he1 = he0.PrevInFace;
         *              var p0 = position.Get(verts[(he0.Index >> 1) + ev0]);
         *              var p1 = position.Get(verts[(he1.Index >> 1) + ev0]);
         *              position.Set(v, position.Get(v) * 0.5 + (p0 + p1) * 0.25);
         *          }
         *          else
         *          {
         *              Vec3d fsum = new Vec3d();
         *              Vec3d esum = new Vec3d();
         *              int n = 0;
         *
         *              foreach (var he in v.OutgoingHalfedges)
         *              {
         *                  fsum += position.Get(verts[he.Face.Index + fv0]);
         *                  esum += position.Get(verts[(he.Index >> 1) + ev0]);
         *                  n++;
         *              }
         *
         *              double t = 1.0 / n;
         *              position.Set(v, (position.Get(v) * (n - 3) + fsum * t + 2 * esum * t) * t);
         *          }
         *      }
         *  };
         *
         *
         *  if (parallel)
         *  {
         *      Parallel.ForEach(Partitioner.Create(0, faces.Count), setFaceVerts);
         *      Parallel.ForEach(Partitioner.Create(0, edges.Count), setEdgeVerts);
         *      Parallel.ForEach(Partitioner.Create(0, verts.Count), setOldVerts);
         *  }
         *  else
         *  {
         *      setFaceVerts(Tuple.Create(0, faces.Count));
         *      setEdgeVerts(Tuple.Create(0, edges.Count));
         *      setOldVerts(Tuple.Create(0, verts.Count));
         *  }
         * }
         */

        #endregion


        /// <summary>
        /// If using external buffers to store vertex attributes, the number of vertices after subdivision equals the sum of the number of vertices and faces in the initial mesh.
        /// </summary>
        /// <typeparam name="V"></typeparam>
        /// <typeparam name="E"></typeparam>
        /// <typeparam name="F"></typeparam>
        /// <param name="mesh"></param>
        /// <param name="position"></param>
        /// <param name="skipBoundary"></param>
        public static void Diagonalize <V, E, F>(HeMeshBase <V, E, F> mesh, Property <V, Vec3d> position, bool skipBoundary)
            where V : HeVertex <V, E, F>
            where E : Halfedge <V, E, F>
            where F : HeFace <V, E, F>
        {
            var edges = mesh.Edges;
            var faces = mesh.Faces;

            int ne = edges.Count;
            int nf = faces.Count;

            // stellate faces
            for (int i = 0; i < nf; i++)
            {
                var f = faces[i];
                if (f.IsRemoved)
                {
                    continue;
                }

                var v = mesh.AddVertex();
                position.Set(v, f.GetBarycenter(position.Get));
                mesh.PokeFaceImpl(f.First, v);
            }

            // merge faces
            if (skipBoundary)
            {
                for (int i = 0; i < ne; i++)
                {
                    var he = edges[i];
                    if (he.IsRemoved || he.IsBoundary)
                    {
                        continue;
                    }
                    mesh.MergeFaces(he);
                }
            }
            else
            {
                for (int i = 0; i < ne; i++)
                {
                    var he = edges[i];
                    if (he.IsRemoved)
                    {
                        continue;
                    }
                    mesh.MergeFaces(he);
                }
            }
        }
Example #27
0
        /// <summary>
        ///
        /// </summary>
        private static void CatmullClarkSmoothCornerFixed <V, E, F>(HeMeshBase <V, E, F> mesh, Property <V, Vec3d> position)
            where V : HeVertex <V, E, F>
            where E : Halfedge <V, E, F>
            where F : HeFace <V, E, F>
        {
            var verts = mesh.Vertices;

            int ev0 = verts.Count - mesh.Edges.Count; // index of first edge vertex
            int fv0 = ev0 - mesh.Faces.Count;         // index of first face vertex

            // set old vertices
            for (int i = 0; i < fv0; i++)
            {
                var v = verts[i];
                if (v.IsRemoved)
                {
                    continue;
                }

                if (v.IsBoundary)
                {
                    var he0 = v.FirstOut;
                    if (he0.IsAtDegree2)
                    {
                        continue;                  // skip corner verts
                    }
                    var he1 = he0.PrevInFace;
                    var p0  = position.Get(verts[(he0.Index >> 1) + ev0]);
                    var p1  = position.Get(verts[(he1.Index >> 1) + ev0]);
                    position.Set(v, position.Get(v) * 0.5 + (p0 + p1) * 0.25);
                }
                else
                {
                    Vec3d fsum = new Vec3d();
                    Vec3d esum = new Vec3d();
                    int   n    = 0;

                    foreach (var he in v.OutgoingHalfedges)
                    {
                        fsum += position.Get(verts[he.Face.Index + fv0]);
                        esum += position.Get(verts[(he.Index >> 1) + ev0]);
                        n++;
                    }

                    double t = 1.0 / n;
                    position.Set(v, (position.Get(v) * (n - 3) + fsum * t + 2 * esum * t) * t);
                }
            }
        }
Example #28
0
        /// <summary>
        ///
        /// </summary>
        private void CreateWeaveGeometry <UV, UE, UF>(HeMeshBase <UV, UE, UF> mesh, TM newMesh, Func <UV, Vec3d> getPosition, Func <UE, double> getScale, Func <UE, Vec3d> getNormal, Func <UF, Vec3d> getCenter, Action <TV, Vec3d> setPosition)
            where UV : HeVertex <UV, UE, UF>
            where UE : Halfedge <UV, UE, UF>
            where UF : HeFace <UV, UE, UF>
        {
            var edges = mesh.Edges;
            int ne    = edges.Count;

            // bulk add new vertices
            newMesh.AddVertices(ne << 3);
            var newVerts = newMesh.Vertices;

            // add vertices (8 per halfedge pair in m0)
            for (int i = 0; i < ne; i++)
            {
                var he0 = edges[i];
                var he1 = he0.Twin;

                var f0 = he0.Face;
                var f1 = he1.Face;

                // scale points to mid point of edge
                Vec3d p0 = getPosition(he0.Start);
                Vec3d p1 = getPosition(he1.Start);

                Vec3d p = (p0 + p1) * 0.5;
                var   t = getScale(he0);

                p0 = Vec3d.Lerp(p, p0, t);
                p1 = Vec3d.Lerp(p, p1, t);
                Vec3d p2 = (f0 == null) ? new Vec3d() : Vec3d.Lerp(p, getCenter(f0), t);
                Vec3d p3 = (f1 == null) ? new Vec3d() : Vec3d.Lerp(p, getCenter(f1), t);

                // set vertex positions
                Vec3d d = he0.IsBoundary ? Vec3d.Zero : getNormal(he0);
                int   j = i << 3;

                setPosition(newVerts[j], p0 - d);
                setPosition(newVerts[j + 1], p2 - d);
                setPosition(newVerts[j + 2], p0 + d);
                setPosition(newVerts[j + 3], p2 + d);

                setPosition(newVerts[j + 4], p1 - d);
                setPosition(newVerts[j + 5], p3 - d);
                setPosition(newVerts[j + 6], p1 + d);
                setPosition(newVerts[j + 7], p3 + d);
            }
        }
Example #29
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="UV"></typeparam>
        /// <typeparam name="UE"></typeparam>
        /// <typeparam name="UF"></typeparam>
        /// <param name="mesh"></param>
        /// <param name="setVertex"></param>
        /// <param name="setHedge"></param>
        /// <param name="setFace"></param>
        /// <param name="componentIndices"></param>
        /// <param name="edgeIndices"></param>
        /// <returns></returns>
        public TM[] CreateConnectedComponents <UV, UE, UF>(HeMeshBase <UV, UE, UF> mesh, Action <TV, UV> setVertex, Action <TE, UE> setHedge, Action <TF, UF> setFace, out int[] componentIndices, out int[] edgeIndices)
            where UV : HeVertex <UV, UE, UF>
            where UE : Halfedge <UV, UE, UF>
            where UF : HeFace <UV, UE, UF>
        {
            int ne = mesh.Edges.Count;

            componentIndices = new int[ne];
            edgeIndices      = new int[ne];

            return(CreateConnectedComponents(mesh, setVertex, setHedge, setFace, ToProp(componentIndices), ToProp(edgeIndices)));

            Property <UE, T> ToProp <T>(T[] values)
            {
                return(Property.Create <UE, T>(he => values[he >> 1], (he, i) => values[he >> 1] = i));
            }
        }
Example #30
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="V"></typeparam>
        /// <typeparam name="E"></typeparam>
        /// <typeparam name="F"></typeparam>
        /// <param name="mesh"></param>
        /// <param name="position"></param>
        /// <param name="boundaryType"></param>
        private static void CatmullClarkGeometry <V, E, F>(HeMeshBase <V, E, F> mesh, Property <V, Vec3d> position, SmoothBoundaryType boundaryType)
            where V : HeVertex <V, E, F>
            where E : Halfedge <V, E, F>
            where F : HeFace <V, E, F>
        {
            var verts = mesh.Vertices;
            int fv0   = verts.Count; // index of first face vertex

            // create face vertices
            foreach (var f in mesh.Faces)
            {
                var v = mesh.AddVertex();

                if (!f.IsRemoved)
                {
                    position.Set(v, f.Vertices.Mean(position.Get));
                }
            }

            // create edge vertices
            foreach (var he0 in mesh.Edges)
            {
                var v = mesh.AddVertex();
                if (he0.IsRemoved)
                {
                    continue;
                }

                if (he0.IsBoundary)
                {
                    position.Set(v, he0.Lerp(position.Get, 0.5));
                    continue;
                }

                var he1 = he0.Twin;
                var p0  = position.Get(he0.Start);
                var p1  = position.Get(he1.Start);
                var p2  = position.Get(verts[he0.Face.Index + fv0]);
                var p3  = position.Get(verts[he1.Face.Index + fv0]);
                position.Set(v, (p0 + p1 + p2 + p3) * 0.25);
            }

            // smooth old vertices
            CatmullClarkSmooth(mesh, position, boundaryType);
        }