Based on the techniques and functionalities described in the previous sections, we now show how to design and implement a subdivision library for a generic CGAL polyhedron. This library is named \emph{C}ombinatorial \emph{S}ubdivision \emph{L}ibrary, short CSL. CSL contains a set of refinement functions and geometry smoothing rules that are user-customizable. Subdivisions in CSL are specialized as a proper combination of the refinement functions and the geometry smoothing rules. %The goal of CSL are the %\emph{generic polyhedron data}, %\emph{user-friendly functional forms}, %\emph{user-customizable subdivisions}, and a %\emph{extendible library}. CSL follows in its desing the ideas of policy-based design \cite{Alexandrescu:2001:MCD}. The policy-based design assembles a class (called \emph{host}) with complex behavior out of many small and generic behaviors (called \emph{policies}). Each policy defines an \emph{interface} for a specific behavior and is customizable by the user. Policies are usually implemented as functions or functors. One gentle example is the \CodeFmt{for\_each} algorithm in STL \footnote{\path|http://www.sgi.com/tech/stl/for_each.html|}. \begin{lstlisting} template UnaryFunction for_each(InputIterator first, InputIterator last, UnaryFunction f); \end{lstlisting} The \CodeFmt{for\_each} is the algorithm host and the \CodeFmt{UnaryFunction f} is the generic behavior customizable by the user. To use it, one has to provide a policy functor or function that meets the interface requirement of an unary function. Based on the policy-based design, CSL is designed to support both \emph{generic types}, i.e.\ the polyhedron, and \emph{generic behaviors}, i.e.\ the subdivisions. %This means users can customize the subdivisions at compile time. The generic type is specified to follow the interface of the \cgalpoly \ that specifies both the connectivity and the geometry interface. The connectivity interface has to support the circulators over primitives, or the adjacency pointers of an halfedge. The geometry interface has to provide the \CodeFmt{Point} type of a vertex item. The operational interface of the \CodeFmt{Point} is not specified by CSL and can be non-CGAL style. For a non-CGAL \CodeFmt{Point} type, users should provide user-defined policies that perform the point operations. A subdivision algorithm has three key behaviors: \emph{refinement}, \emph{smoothing}, and \emph{stencil correspondence}. The refinement is acted as a \CodeFmt{for\_each} algorithm on the source \emph{and} the refined polyhedron while applying the smoothing behaviors. CSL implement the refinements as the host functions with the smoothing rules as the policies. Some major refinement schemes are shown in \figurename\ \ref{fig:RefSchemes}. The tutorial accompanying CSL only provides PQQ, PTQ and DQQ schemes. The refinement configurations also define the stencil correspondences; stencils of PQQ and DQQ schemes are shown in \figurename\ \ref{fig:RefMap}. These stencil correspondences specified the functional interface between the refinement hosts and the geometry smoothing policies. %% \cgalpoly\ provides two %% mechanisms to implement refinements as introduced in the previous %% sections. The geometry smoothing is mixed with the refinement %% in the previous examples and hence implicitly maintain %% the stencil correspondence. CSL extracts the geometry smoothing %% from the refinement as policies and maintain the stencil %% correspondence explicitly. %----------------------------------------------------------------------- \subsubsection*{Primal Quad Quadralization} \begin{figure}[htb] \centering{\includegraphics[width=12.0cm]{figs/TriCube_CC.eps}} \caption{Catmull-Clark subdivision of the box polyhedron.} \label{fig:cc} \end{figure} A subdivision algorithm in CSL is constructed as a \emph{refinement function} parameterized with a set of the \emph{geometry smoothing rules}. The rule set is specified as a template policy class. For example, Catmull-Clark subdivision in CSL is instantiated as the PQQ scheme parameterized with a Catmull-Clark geometry policy class. \begin{lstlisting} void CatmullClark_subdivision(Polyhedron& p, int step = 1) { quad_quadralize_polyhedron(p, CatmullClark_rule(), step); } \end{lstlisting} The \CodeFmt{quad\_quadralize\_polyhedron} is the refinement host that refines the control polyhedron using PQQ scheme and the \CodeFmt{CatmullClark\_rule} is the template geometry policy class. \\ %The refinement host applies the smoothing stencils provided by the %geometry policy class. \noindent \textbf{Geometry policies} are represented as the policy functions of the policy class. Each policy function receive a \emph{primitive handle} of the represented 1-ring submesh of the control polyhedron; and a reference of the smoothing point on the refined polyhedron. The interface of a policy class for a PQQ refinement host is shown below. \begin{lstlisting} template class quadralize_rule { public: void face_point_rule(Facet_handle, Point&) {}; void edge_point_rule(Halfedge_handle, Point&) {}; void vertex_point_rule(Vertex_handle, Point&) {}; }; \end{lstlisting} The interface is defined according to the stencil correspondence of the refinement scheme. A PQQ scheme contains three stencils that are shown in \figurename\ \ref{fig:RefMap} (a--c). Each of them defines a policy function, which of the \CodeFmt{quadralize\_rule} is the \CodeFmt{facet\_rule()}, the \CodeFmt{edge\_rule()}, and the \CodeFmt{vertex\_rule()} respectively. Any customized policy class of the geometry smoothing rules are required to provide the proper functions. To assure the interface consistence, CSL provides a geometry rule class for each refinement scheme. To create a new geometry policy class, the class inheritance is used. \begin{lstlisting} // Specialized a Catmull-Clark rule by inheriting the quadralize_rule. template class CatmullClark_rule : public quadralize_rule<_Poly> {...} \end{lstlisting} The smoothing points of a refined polyhedron is generated by calling the corresponding geometry policies. Inside each policy, applying the stencil is simplified into the mesh traversal of a 1-ring neighborhood. It can be done with a primitive circulator or a simple sequence of the adjacency pointers of the halfedges. The \CodeFmt{face\_point\_rule} for Catmull-Clark subdivision demonstrates the usage of a facet circulator for stenciling. \begin{lstlisting} void face_point_rule(Facet_handle facet, Point& pt) { // Facet circulator is used to traverse the 1-ring of a facet. Halfedge_around_facet_circulator hcir = facet->facet_begin(); int n = 0; Kernel::FT p[] = {0,0,0}; // Apply the stencil while circulating around the facet. do { Point t = hcir->vertex()->point(); p[0] += t[0], p[1] += t[1], p[2] += t[2]; ++n; } while (++hcir != facet->facet_begin()); // Assign the smoothing point. pt = Point(p[0]/n, p[1]/n, p[2]/n); } \end{lstlisting} The facet circulator provides a convenient way to traverse and collect the points. The point calculation use the conventional interface \CodeFmt{[i]} of the point type. For \CodeFmt{Point} not equipped with the index access \CodeFmt{[i]}, a user-implemented policy class need to be provided. The CGAL \CodeFmt{Point\_3}/\CodeFmt{Vector\_3} computation can be used if the \CodeFmt{Point} is the equivalent type of \CodeFmt{Point\_3} which is shown below. \begin{lstlisting} void face_point_rule(Facet_handle facet, Point& pt) { Halfedge_around_facet_circulator hcir = facet->facet_begin(); // Use CGAL::ORIGIN to transform Point into Vector. Vector vec = hcir->vertex()->point() - CGAL::ORIGIN; ++hcir; do { // Vector is a computational class vec = vec + hcir->vertex()->point(); } while (++hcir != facet->facet_begin()); // Use CGAL::ORIGIN to transform Vector back to Point. pt = CGAL::ORIGIN + vec/circulator_size(hcir); } \end{lstlisting} The \CodeFmt{edge\_point\_rule()} of Catmull-Clark subdivision requires the low lever halfedge traversal that is the \CodeFmt{next()}, the \CodeFmt{prev()}, and the \CodeFmt{opposite()} of the halfedge item. \begin{lstlisting} void edge_point_rule(Halfedge_handle edge, Point& pt) { Point p1 = edge->vertex()->point(); Point p2 = edge->opposite()->vertex()->point(); Point f1, f2; face_point_rule(edge->facet(), f1); face_point_rule(edge->opposite()->facet(), 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 ); } \end{lstlisting} The \CodeFmt{edge->opposite()} is used to locate the opposite point and the opposite facet. Instead of using the facet circulator for each facet after obtaining the facet handle, the \CodeFmt{face\_point\_rule} is called to calculate the facet centroids. The smoothing point is then assigned as the centroid of the two opposite points and the two facet centroids. The \CodeFmt{vertex\_point\_rule} for Catmull-Clark subdivision is more complicated than the other two policy functions. Unlike the facet and edge rules, vertex rule is not static in the scenes of the stencil weights. The weights are functions of the vertex valence and it introduces more geometry computations. Nonetheless, the connectivity traversal is still homomorphic to a vertex circulation. \begin{lstlisting} void vertex_point_rule(Vertex_handle vertex, Point& pt) { // Only a vertex circulator is needed to collect the submesh. Halfedge_around_vertex_circulator vcir = vertex->vertex_begin(); // The vertex valence is used to calculate the stencil weights. int n = circulator_size(vcir); float Q[] = {0.0, 0.0, 0.0}, R[] = {0.0, 0.0, 0.0}; Point& S = vertex->point(); // The center vertex Point q; for (int i = 0; i < n; i++, ++vcir) { Point& p2 = vcir->opposite()->vertex()->point(); R[0] += (S[0]+p2[0])/2; R[1] += (S[1]+p2[1])/2; R[2] += (S[2]+p2[2])/2; face_point_rule(vcir->facet(), 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; // Assign the smoothing point. 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 ); } \end{lstlisting} \vspace{0.5cm} \noindent \textbf{Connectivity refinement} in CSL is design as a host function. A refinement host refines the input control polyhedron, maintains the stencil correspondence and assign the smoothed points. The \CodeFmt{quad\_quadralize\_polyhedron} is the refinement host for a PQQ scheme. It redirects the refinement by repeating the \CodeFmt{quad\_quadralize\_1step()} that does one-step polyhedron refinement. \begin{lstlisting} // RULE is a template parameter specifying the geometry stencils. template