diff --git a/Subdivision_method_3/doc/Subdivision_method_3/CGAL/Subdivision_mask_3.h b/Subdivision_method_3/doc/Subdivision_method_3/CGAL/Subdivision_mask_3.h index cfb8252a20e..2501756c30e 100644 --- a/Subdivision_method_3/doc/Subdivision_method_3/CGAL/Subdivision_mask_3.h +++ b/Subdivision_method_3/doc/Subdivision_method_3/CGAL/Subdivision_mask_3.h @@ -9,7 +9,8 @@ whose points contribute to the position of a refined point. The geometry mask of a stencil specifies the computation on the nodes of the stencil. `CatmullClark_mask_3` implements the geometry masks of -Catmull-Clark subdivision on a `CGAL::Polyhedron_3`. +Catmull-Clark subdivision on models of `MutableFaceGraph`, +such as `Polyhedron_3` and `Surface_mesh`. \tparam PolygonMesh must be a model of the concept `MutableFaceGraph`. \tparam VertexPointMap must be a model of `WritablePropertyMap` with value type `Point_3` @@ -32,8 +33,8 @@ public: /*! Constructor. */ - CatmullClark_mask_3(PolygonMesh& pm, - VertexPointMap vpm = get(vertex_point,pm) ); + CatmullClark_mask_3(PolygonMesh& pmesh, + VertexPointMap vpm = get(vertex_point, pmesh) ); /// @} @@ -84,7 +85,8 @@ whose points contribute to the position of a refined point. The geometry mask of a stencil specifies the computation on the nodes of the stencil. `DooSabin_mask_3` implements the geometry masks of -Doo-Sabin subdivision on a `Polyhedron_3`. +Doo-Sabin subdivision on models of `MutableFaceGraph`, +such as `Polyhedron_3` and `Surface_mesh`. \tparam PolygonMesh must be a model of the concept `MutableFaceGraph`. \tparam VertexPointMap must be a model of `WritablePropertyMap` with value type `Point_3` @@ -107,8 +109,8 @@ public: /*! Constructor. */ -DooSabin_mask_3(PolygonMesh& pm, - VertexPointMap vpm = get(vertex_point,pm) ); +DooSabin_mask_3(PolygonMesh& pmesh, + VertexPointMap vpm = get(vertex_point, pmesh) ); /// @} @@ -138,9 +140,10 @@ whose points contribute to the position of a refined point. The geometry mask of a stencil specifies the computation on the nodes of the stencil. `Loop_mask_3` implements the geometry masks of -Loop subdivision on a triangulated `Polyhedron_3`. +Loop subdivision on a triangulated model of `MutableFaceGraph`, +such as `Polyhedron_3` and `Surface_mesh`. -\tparam TriangleMesh must be a model of the concept `MutableFaceGraph`. +\tparam PolygonMesh must be a model of the concept `MutableFaceGraph`. Additionally all faces must be triangles. \tparam VertexPointMap must be a model of `WritablePropertyMap` with value type `Point_3` \image html LoopBorderMask.png @@ -151,7 +154,7 @@ Loop subdivision on a triangulated `Polyhedron_3`. \sa `CGAL::Subdivision_method_3` */ -template< typename TriangleMesh, typename VertexPointMap = typename boost::property_map::type > +template< typename PolygonMesh, typename VertexPointMap = typename boost::property_map::type > class Loop_mask_3 { public: @@ -161,8 +164,8 @@ public: /*! Cnstructor. */ -Loop_mask_3(TriangleMesh& tm, - VertexPointMap vpm = get(vertex_point,tm) ); +Loop_mask_3(PolygonMesh& pmesh, + VertexPointMap vpm = get(vertex_point,pmesh) ); /// @} @@ -207,9 +210,10 @@ The geometry mask of a stencil specifies the computation on the nodes of the stencil. `Sqrt3_mask_3` implements the geometry masks of \f$ \sqrt{3}\f$ subdivision on a triangulated -`CGAL::Polyhedron_3`. +model of `MutableFaceGraph`, +such as `Polyhedron_3` and `Surface_mesh`. -\tparam TriangleMesh must be a model of the concept `MutableFaceGraph`. +\tparam PolygonMesh must be a model of the concept `MutableFaceGraph`. Additionally all faces must be triangles. \tparam VertexPointMap must be a model of `WritablePropertyMap` with value type `Point_3` \cgalModels `Sqrt3Mask_3` @@ -217,7 +221,7 @@ the computation on the nodes of the stencil. \sa `CGAL::Subdivision_method_3` */ -template< typename TriangleMesh, typename VertexPointMap = typename boost::property_map::type > +template< typename PolygonMesh, typename VertexPointMap = typename boost::property_map::type > class Sqrt3_mask_3 { public: @@ -227,8 +231,8 @@ public: /*! Constructor. */ - Sqrt3_mask_3(TriangleMesh& tm, - VertexPointMap vpm = get(vertex_point,tm) ); + Sqrt3_mask_3(PolygonMesh& pmesh, + VertexPointMap vpm = get(vertex_point,pmesh) ); /// @} diff --git a/Subdivision_method_3/doc/Subdivision_method_3/Concepts/DQQMask_3.h b/Subdivision_method_3/doc/Subdivision_method_3/Concepts/DQQMask_3.h index 0679eebb561..f05a4452615 100644 --- a/Subdivision_method_3/doc/Subdivision_method_3/Concepts/DQQMask_3.h +++ b/Subdivision_method_3/doc/Subdivision_method_3/Concepts/DQQMask_3.h @@ -26,13 +26,13 @@ public: /*! Constructor */ - DQQMask_3(PolygonMesh& pm); + DQQMask_3(PolygonMesh& pmesh); /*! computes the subdivided point `pt` based on the neighborhood -of the vertex pointed by the halfedge `he`. +of the vertex pointed by the halfedge `hd`. */ -void corner_node(halfedge_descriptor he, Point& pt); +void corner_node(halfedge_descriptor hd, Point& pt); /// @} diff --git a/Subdivision_method_3/doc/Subdivision_method_3/Concepts/PQQMask_3.h b/Subdivision_method_3/doc/Subdivision_method_3/Concepts/PQQMask_3.h index dbdfaaa53cf..0d7bcfd9755 100644 --- a/Subdivision_method_3/doc/Subdivision_method_3/Concepts/PQQMask_3.h +++ b/Subdivision_method_3/doc/Subdivision_method_3/Concepts/PQQMask_3.h @@ -27,34 +27,34 @@ public: /*! Constructor */ - PQQMask_3(PolygonMesh& pm); + PQQMask_3(PolygonMesh& pmesh); /*! computes the facet-point `pt` based on the neighborhood -of the facet `f`. +of the face `fd`. */ -void facet_node(face_descriptor facet, Point_3& pt); +void facet_node(face_descriptor fd, Point_3& pt); /*! computes the edge-point `pt` based on the neighborhood -of the edge `e`. +of the edge `hd`. */ -void edge_node(halfedge_descriptor e, Point_3& pt); +void edge_node(halfedge_descriptor hd, Point_3& pt); /*! computes the vertex-point `pt` based on the neighborhood -of the vertex `v`. +of the vertex `vd`. */ -void vertex_node(vertex_descriptor v, Point_3& pt); +void vertex_node(vertex_descriptor vd, Point_3& pt); /*! computes the edge-point `ept` and the vertex-point `vpt` -based on the neighborhood of the border edge `e`. +based on the neighborhood of the border edge `hd`. */ -void border_node(halfedge_descriptor e, Point_3& ept, Point_3& vpt); +void border_node(halfedge_descriptor hd, Point_3& ept, Point_3& vpt); /// @} diff --git a/Subdivision_method_3/doc/Subdivision_method_3/Concepts/PTQMask_3.h b/Subdivision_method_3/doc/Subdivision_method_3/Concepts/PTQMask_3.h index f2936056482..c01990be91b 100644 --- a/Subdivision_method_3/doc/Subdivision_method_3/Concepts/PTQMask_3.h +++ b/Subdivision_method_3/doc/Subdivision_method_3/Concepts/PTQMask_3.h @@ -18,33 +18,44 @@ policy concept of geometric computations is used in class PTQMask_3 { public: +/// \name Types +/// @{ + +/*! The polygon mesh must be triangulated. + +*/ + typedef unspecified_type PolygonMesh; + +/// @} + + /// \name Operations /// @{ /*! Constructor */ -PTQMask_3(TriangleMesh& m); +PTQMask_3(PolygonMesh& pmesh); /*! computes the edge-point `pt` based on the neighborhood -of the edge `e`. +of the edge `hd`. */ -void edge_node(Edge_handle e, Point_3& pt); +void edge_node(halfedge_descriptor hd, Point_3& pt); /*! computes the vertex-point `pt` based on the neighborhood -of the vertex `v`. +of the vertex `vd`. */ -void vertex_node(Vertex_handle v, Point_3& pt); +void vertex_node(vertex_descriptor vd, Point_3& pt); /*! computes the edge-point `ept` and the vertex-point `vpt` -based on the neighborhood of the border edge `e`. +based on the neighborhood of the border edge `hd`. */ -void border_node(Halfedge_handle e, Point_3& ept, Point_3& vpt); +void border_node(halfedge_descriptor hd, Point_3& ept, Point_3& vpt); /// @} diff --git a/Subdivision_method_3/doc/Subdivision_method_3/Concepts/Sqrt3Mask_3.h b/Subdivision_method_3/doc/Subdivision_method_3/Concepts/Sqrt3Mask_3.h index f7b8494760b..79ce162b597 100644 --- a/Subdivision_method_3/doc/Subdivision_method_3/Concepts/Sqrt3Mask_3.h +++ b/Subdivision_method_3/doc/Subdivision_method_3/Concepts/Sqrt3Mask_3.h @@ -17,25 +17,36 @@ policy concept of geometric computations is used in class Sqrt3Mask_3 { public: +/// \name Types +/// @{ + +/*! The polygon mesh must be triangulated. + +*/ + typedef unspecified_type PolygonMesh; + +/// @} + + /// \name Operations /// @{ /*! Constructor */ -Sqrt3Mask_3(TriangleMesh& m); +Sqrt3Mask_3(PolygonMesh& pmesh); /*! computes the subdivided point `pt` based on the neighborhood -of the facet `f`. +of the face `fd`. */ -void facet_node(face_descriptor f, Point_3& pt); +void facet_node(face_descriptor fd, Point_3& pt); /*! computes the subdivided point `pt` based on the neighborhood -of the vertex `v`. +of the vertex `vd`. */ -void vertex_node(vertex_descriptor v, Point& pt); +void vertex_node(vertex_descriptor vd, Point& pt); /// @} diff --git a/Subdivision_method_3/doc/Subdivision_method_3/Subdivision_method_3.txt b/Subdivision_method_3/doc/Subdivision_method_3/Subdivision_method_3.txt index b799e094a32..83dbcad578f 100644 --- a/Subdivision_method_3/doc/Subdivision_method_3/Subdivision_method_3.txt +++ b/Subdivision_method_3/doc/Subdivision_method_3/Subdivision_method_3.txt @@ -72,7 +72,7 @@ the subdivision surface. \image latex RefSchemes.png The figure demonstrates these four refinement patterns on -the 1-disk of a valence-5 vertex/facet. +the 1-disk of a valence-5 vertex/face. Refined meshes are shown below the source meshes. Points on the refined mesh are generated by averaging neighbor points on the source mesh. A graph, called stencil, @@ -82,8 +82,8 @@ more than one stencil. For example, the PQQ refinement has a vertex-node stencil, which defines the 1-ring of an input vertex; an edge-node stencil, -which defines the 1-ring of an input edge; and a facet-node stencil, -which defines an input facet. The stencils of the PQQ refinement are +which defines the 1-ring of an input edge; and a face-node stencil, +which defines an input face. The stencils of the PQQ refinement are shown in the following figure. The blue neighborhoods in the top row indicate the corresponding stencils of the refined nodes in red. @@ -104,11 +104,11 @@ below. The weights shown here are unnormalized, and \f$ n\f$ is the valence of the vertex. The generated point, in red, is computed by a summation -of the weighted points. For example, a Catmull-Clark facet-node is +of the weighted points. For example, a Catmull-Clark face-node is computed by the summation of \f$ 1/4\f$ of each point on its stencil. A stencil can have an unlimited number of geometry masks. For example, -a facet-node of PQQ refinement may be computed by +a face-node of PQQ refinement may be computed by the summation of \f$ 1/5\f$ of each stencil node instead of \f$ 1/4\f$. Although it is legal in `Subdivision_method_3` to have any kind of geometry mask, the result surfaces may be odd, @@ -144,21 +144,17 @@ subdivision function. This example shows how to subdivide a simple `Polyhedron_3` with `Subdivision_method_3`. An application-defined polyhedron might use a specialized kernel and/or -a specialized internal container. There are two major restrictions on the +a specialized internal container. There is one major restrictions on the application-defined polyhedron to work with -`Subdivision_method_3`. -
    -
  • `Point_3` is type-defined by the kernel. Without `Point_3` -and the associated operations being defined, `Subdivision_method_3` -can not know how to compute and store the new vertex points. -
  • The primitives (such as vertices, halfedges and facets) +`Subdivision_method_3`: +The primitives (such as vertices, halfedges and faces) in the internal container are sequentially ordered (e.g. `std::vector` and `std::list`). This implies that the iterators traverse the primitives in the order of their creations/insertions. -
-Section \ref secRefHost gives detailed explanations on those + +Section \ref secRefHost gives detailed explanations on this two restrictions. \section secCC Catmull-Clark Subdivision @@ -219,7 +215,7 @@ for the PQQ refinement. template class PQQMask_3 { - void face_node(boost::graph_traits::face_descriptor facet, Point_3& pt); + void face_node(boost::graph_traits::face_descriptor face, Point_3& pt); void edge_node(boost::graph_traits::halfedge_descriptor edge, Point_3& pt); void vertex_node(boost::graph_traits::vertex_descriptor vertex, Point_3& pt); }; @@ -237,65 +233,70 @@ Catmull-Clark subdivision. template class CatmullClark_mask_3 { - void face_node(boost::graph_traits::face_descriptor facet, Point_3& pt) { - Halfedge_around_facet_circulator hcir = facet->facet_begin(); + + typedef boost::graph_traits::face_descriptor face_descriptor; + typedef boost::property_traits::value_type Point; + + Polygonmesh pmesh; + VertexPointMap vpm; + + CatmullClark_mask_3(PolygonMesh &pmesh, VertexPointMap vpm) + : pmesh(pmesh, vpm(vpm) + {} + + void face_node(face_descriptor face, Point& pt) { int n = 0; Point_3 p(0,0,0); - do { - p = p + (hcir->vertex()->point() - ORIGIN); + for(halfedge_descriptor hd : halfedges_around_face(face,pmesh)){ + p = p + get(vpm, (target(hd,pmesh)) - ORIGIN); ++n; - } while (++hcir != facet->facet_begin()); + } pt = ORIGIN + (p - ORIGIN)/FT(n); } - - void edge_node(boost::graph_traits::halfedge_descriptor edge, Point_3& pt) { - Point_3 p1 = edge->vertex()->point(); - Point_3 p2 = edge->opposite()->vertex()->point(); - Point_3 f1, f2; - face_node(edge->facet(), f1); - face_node(edge->opposite()->facet(), f2); - pt = Point_3((p1[0]+p2[0]+f1[0]+f2[0])/4, - (p1[1]+p2[1]+f1[1]+f2[1])/4, - (p1[2]+p2[2]+f1[2]+f2[2])/4 ); +}; + + void edge_node(halfedge_descriptor edge, Point& pt) { + Point p1 = get(vpm,target(edge, pmesh)); + Point p2 = get(vpm,source(edge, pmesh)); + Point f1, f2; + face_node(face(edge,pmesh), f1); + face_node(face(opposite(edge,pmesh),pmesh), f2); + pt = Point((p1[0]+p2[0]+f1[0]+f2[0])/4, + (p1[1]+p2[1]+f1[1]+f2[1])/4, + (p1[2]+p2[2]+f1[2]+f2[2])/4 ); } - void vertex_node(boost::graph_traits::vertex_descriptor vertex, Point_3& pt) { - Halfedge_around_vertex_circulator vcir = vertex->vertex_begin(); - int n = circulator_size(vcir); - + void vertex_node(vertex_descriptor vertex, Point& pt) { + Halfedge_around_target_circulator vcir(vertex,pmesh); + typename boost::graph_traits::degree_size_type n = degree(vertex,pmesh); + FT Q[] = {0.0, 0.0, 0.0}, R[] = {0.0, 0.0, 0.0}; - Point_3& S = vertex->point(); - - Point_3 q; + Point& S = get(vpm,vertex); + + Point q; for (int i = 0; i < n; i++, ++vcir) { - Point_3& p2 = vcir->opposite()->vertex()->point(); + Point& p2 = get(vpm, target(opposite(*vcir,pmesh),pmesh)); R[0] += (S[0]+p2[0])/2; R[1] += (S[1]+p2[1])/2; R[2] += (S[2]+p2[2])/2; - face_node(vcir->facet(), q); - Q[0] += q[0]; - Q[1] += q[1]; + face_node(face(*vcir,pmesh), q); + Q[0] += q[0]; + Q[1] += q[1]; Q[2] += q[2]; } - R[0] /= n; R[1] /= n; R[2] /= n; - Q[0] /= n; Q[1] /= n; Q[2] /= n; - - pt = Point_3((Q[0] + 2*R[0] + S[0]*(n-3))/n, - (Q[1] + 2*R[1] + S[1]*(n-3))/n, - (Q[2] + 2*R[2] + S[2]*(n-3))/n ); + R[0] /= n; R[1] /= n; R[2] /= n; + Q[0] /= n; Q[1] /= n; Q[2] /= n; + + pt = Point((Q[0] + 2*R[0] + S[0]*(n-3))/n, + (Q[1] + 2*R[1] + S[1]*(n-3))/n, + (Q[2] + 2*R[2] + S[2]*(n-3))/n ); } + }; \endcode -This example shows the default implementation of Catmull-Clark -masks in `Subdivision_method_3`. -This default implementation assumes the types -(such as `Point_3` and `face_descriptor`) are defined -within `PolygonMesh`. `CatmullClark_mask_3` -is designed to work on a `PolygonMesh` with the %Cartesian -kernel. You may need to rewrite the geometry computation -to match the kernel geometry of your application. + To invoke the Catmull-Clark subdivision method, we call `PQQ()` with the Catmull-Clark masks we just defined. @@ -331,22 +332,22 @@ and \f$ \sqrt{3}\f$ subdivision. \code{.cpp} namespace Subdivision_method_3 { -template class Mask> -void PQQ(PolygonMesh& p, Mask mask, int step); +template +void PQQ(PolygonMesh& p, Mask mask, int step); -template class Mask> -void PTQ(TriangleMesh& p, Mask mask, int step); +template +void PTQ(PolygonMesh& p, Mask mask, int step); -template class Mask> -void DQQ(PolygonMesh& p, Mask mask, int step) +template +void DQQ(PolygonMesh& p, Mask mask, int step) -template class Mask> -void Sqrt3(TriangleMesh& p, Mask mask, int step) +template +void Sqrt3(PolygonMesh& p, Mask mask, int step) } \endcode -The mesh class is a specialization of +The mesh class must be a model of `MutableFaceGraph` and it must be a triangle mesh or a polygon mesh, and the mask is a policy class realizing the geometry masks of the subdivision method. @@ -373,13 +374,10 @@ can not be used with `Subdivision_method_3`. Although `Subdivision_method_3` does not require flags to support the refinements and the stencils, it still needs to know how to compute and store the geometry -data (i.e.\ the points). `Subdivision_method_3` -expects that the typename `Point_3` is -defined in the geometry kernel of the polyhedron -(i.e.\ the `Polyhedron_3::Traits::Kernel`). -A point of the type `Point_3` is returned by the geometry -policy and is then assigned to the new vertex. -The geometry policy is explained in next section. +data (i.e.\ the points). The classes of `Subdivision_method_3` +have as optional template argument a vertex property map +that provides a mapping between vertices and points. + Refinement hosts `PQQ` and `DQQ` work on a general polyhedron, and `PTQ` and `Sqrt3` work on a triangulated @@ -416,22 +414,28 @@ of a Catmull-Clark geometry policy is in the Section \ref secCC. \code{.cpp} -template +template class CatmullClark_mask_3 { - void face_node(boost::graph_traits::face_descriptor facet, Point_3& pt) { - Halfedge_around_facet_circulator hcir = facet->facet_begin(); + + typedef boost::graph_traits::face_descriptor face_descriptor; + typedef boost::property_traits::value_type Point; + + CatmullClark_mask_3(PolygonMesh &pmesh, VertexPointMap vpm); + + void face_node(face_descriptor face, Point& pt) { int n = 0; Point_3 p(0,0,0); - do { - p = p + (hcir->vertex()->point() - ORIGIN); + for(halfedge_descriptor hd : halfedges_around_face(face,pmesh)){ + p = p + get(vpm, (target(hd,pmesh)) - ORIGIN); ++n; - } while (++hcir != facet->facet_begin()); + } pt = ORIGIN + (p - ORIGIN)/FT(n); } }; \endcode + In this example, the computation is based on the assumption that the `Point_3` is the `CGAL::Point_3`. It is an assumption, but not a restriction. @@ -454,19 +458,20 @@ is listed below, where `ept` returns the new point splitting \code{.cpp} -void border_node(boost::graph_traits::halfedge_descriptor edge, Point_3& ept, Point_3& vpt) { - Point_3& ep1 = edge->vertex()->point(); - Point_3& ep2 = edge->opposite()->vertex()->point(); - ept = Point_3((ep1[0]+ep2[0])/2, (ep1[1]+ep2[1])/2, (ep1[2]+ep2[2])/2); + void border_node(halfedge_descriptor edge, Point& ept, Point& vpt) { + Point& ep1 = get(vpm, target(edge, pmesh)); + Point& ep2 = get(vpm, target(opposite(edge, pmesh), pmesh)); + ept = Point((ep1[0]+ep2[0])/2, (ep1[1]+ep2[1])/2, (ep1[2]+ep2[2])/2); - Halfedge_around_vertex_circulator vcir = edge->vertex_begin(); - Point_3& vp1 = vcir->opposite()->vertex()->point(); - Point_3& vp0 = vcir->vertex()->point(); - Point_3& vp_1 = (--vcir)->opposite()->vertex()->point(); - vpt = Point_3((vp_1[0] + 6*vp0[0] + vp1[0])/8, - (vp_1[1] + 6*vp0[1] + vp1[1])/8, - (vp_1[2] + 6*vp0[2] + vp1[2])/8 ); -} + Halfedge_around_target_circulator vcir(edge, pmesh); + Point& vp1 = get(vpm,target(opposite(*vcir, pmesh ), pmesh)); + Point& vp0 = get(vpm, target(*vcir, pmesh)); + --vcir; + Point& vp_1 = get(vpm, target(opposite(*vcir, pmesh), pmesh)); + vpt = Point((vp_1[0] + 6*vp0[0] + vp1[0])/8, + (vp_1[1] + 6*vp0[1] + vp1[1])/8, + (vp_1[2] + 6*vp0[2] + vp1[2])/8 ); + } \endcode @@ -480,31 +485,31 @@ current release. This might be changed in the future releases. template class PQQMask_3 { - void face_node(boost::graph_traits::face_descriptor, Point_3&); - void edge_node(boost::graph_traits::halfedge_descriptor, Point_3&); - void vertex_node(boost::graph_traits::vertex_descriptor, Point_3&); + void face_node(boost::graph_traits::face_descriptor, Point&); + void edge_node(boost::graph_traits::halfedge_descriptor, Point&); + void vertex_node(boost::graph_traits::vertex_descriptor, Point&); - void border_node(boost::graph_traits::halfedge_descriptor, Point_3&, Point_3&); + void border_node(boost::graph_traits::halfedge_descriptor, Point&, Point&); }; -template +template class PTQMask_3 { - void edge_node(boost::graph_traits::halfedge_descriptor, Point_3&); - void vertex_node(boost::graph_traits::vertex_descriptor, Point_3&); + void edge_node(boost::graph_traits::halfedge_descriptor, Point&); + void vertex_node(boost::graph_traits::vertex_descriptor, Point&); - void border_node(boost::graph_traits::halfedge_descriptor, Point_3&, Point_&); + void border_node(boost::graph_traits::halfedge_descriptor, Point&, Point_&); }; template class DQQMask_3 { public: - void corner_node(boost::graph_traits::halfedge_descriptor edge, Point_3& pt); + void corner_node(boost::graph_traits::halfedge_descriptor edge, Point& pt); }; -template +template class Sqrt3Mask_3 { public: - void vertex_node(boost::graph_traits::vertex_descriptor vertex, Point_3& pt); + void vertex_node(boost::graph_traits::vertex_descriptor vertex, Point& pt); }; \endcode @@ -518,7 +523,8 @@ the best sources of learning these stencil interfaces. `Subdivision_method_3` supports Catmull-Clark, Loop, Doo-Sabin and \f$ \sqrt{3}\f$ subdivisions by specializing their respective refinement hosts. -They are designed to work on a `Polyhedron_3`. If your application +They are designed to work on any model of a `MutableFaceGraph` +such as `Polyhedron_3` and `Surface_mesh`. If your application uses a polyhedron with a specialized geometry kernel, you need to specialize the refinement host with a geometry policy based on that kernel. @@ -527,23 +533,23 @@ based on that kernel. namespace Subdivision_method_3 { template - void CatmullClark_subdivision(PolygonMesh& p, int step = 1) { - PQQ(p, CatmullClark_mask_3(p), step); - } - - template - void Loop_subdivision(TriangleMesh& p, int step = 1) { - PTQ(p, Loop_mask_3(p) , step); + void CatmullClark_subdivision(PolygonMesh& pmesh, int step = 1) { + PQQ(pmesh, CatmullClark_mask_3(pmesh), step); } template - void DooSabin_subdivision(PolygonMesh& p, int step = 1) { - DQQ(p, DooSabin_mask_3(p), step); + void Loop_subdivision(PolygonMesh& pmesh, int step = 1) { + PTQ(pmesh, Loop_mask_3(pmesh) , step); } - template - void Sqrt3_subdivision(TriangleMesh& p, int step = 1) { - Sqrt3(p, Sqrt3_mask_3(p), step); + template + void DooSabin_subdivision(PolygonMesh& pmesh, int step = 1) { + DQQ(pmesh, DooSabin_mask_3(pmesh), step); + } + + template + void Sqrt3_subdivision(PolygonMesh& pmesh, int step = 1) { + Sqrt3(pmesh, Sqrt3_mask_3(pmesh), step); } } diff --git a/Subdivision_method_3/doc/Subdivision_method_3/dependencies b/Subdivision_method_3/doc/Subdivision_method_3/dependencies index a01021f28b7..a29af6711b4 100644 --- a/Subdivision_method_3/doc/Subdivision_method_3/dependencies +++ b/Subdivision_method_3/doc/Subdivision_method_3/dependencies @@ -5,3 +5,4 @@ Algebraic_foundations Circulator Stream_support Polyhedron +Surface_mesh