% subtempl.tex % ------------------------------------------- Policy-based design \cite{Alexandrescu:2001:MCD} assembles a class (called \emph{host}) with complex behavior out of many small behaviors (called \emph{policies}). Each policy defines an interface for a specific behavior. Following this design principle, we implement a generic subdivision solution as a \emph{refinement function\/} parameterized with the \emph{stencils}. The host, i.e., the refinement function, conducts the \tr\ and applies the stencils provided by the policies for the \gm s. We provide different hosts and different policies that can be combined to form subdivision schemes. We demonstrate the principle with the Catmull-Clark and the Doo-Sabin subdivision. A Catmull-Clark subdivision is structured as a primal quadralization function parameterized with a corresponding stencil policy. \begin{lstlisting} void CatmullClark_subdivision(Polyhedron& p) { quadralize_polyhedron>(p); } class CatmullClark_rule { public: void facet_rule( Facet_handle facet, Point& pt); void edge_rule(Halfedge_handle edge, Point& pt); void vertex_rule(Vertex_handle vertex, Point& pt); }; \end{lstlisting}\vspace*{-3mm} \noindent The \CodeFmt{quadralize\_polyhedron<>()} is the host function refining the input mesh and the \CodeFmt{CatmullClark\_rule} is the policy class applying the Catmull-Clark stencils. The \CodeFmt{quadralize\_polyhedron<>()} refines the control mesh while maintaining the correspondence with the stencil, i.e., the submesh centered around the given facet, edge, or vertex, and the smoothing point. The smoothing point is calculated by calling the policies, i.e., the \CodeFmt{facet\_rule()}, the \CodeFmt{edge\_rule()}, and the \CodeFmt{vertex\_rule()} respectively. %Different refinement scheme may require a %different set of stencils. A PQQ scheme needs the %facet-, edge- and vertex-stencils whereas a DQQ scheme %only needs the corner-stencils (Fig.\ref{fig:RefMap}). \noindent\textbf{Geometry Policies}. Inside a policy, applying the stencil is simplified to the mesh traversal of a 1-ring neighborhood. We can use circulators again, as in the following example for the policy of the facet-stencil in the Catmull-Clark subdivision. \begin{lstlisting} void facet_rule(Facet_handle facet, Point& point) { Halfedge_around_facet_circulator hcir = facet->facet_begin(); Vector vec = hcir->vertex()->point() - ORIGIN; ++hcir; do { vec = vec + hcir->vertex()->point(); } while (++hcir != facet->facet_begin()); point = ORIGIN + vec/circulator_size(hcir); } \end{lstlisting}\vspace*{-3mm} \noindent The \CodeFmt{facet} points to the center facet of the stencil and the \CodeFmt{point} specifies the smoothing point. We compute the centroid with a circulator loop over the halfedges surrounding a facet. The \cgal\ geometric kernel is used here, but special computations may be done in user-defined policies. %with point and vector arithmetic. %However, for a specialized kernel, special computations may be %done in user-defined policies. \noindent\textbf{The refinement host based on Euler operations}. Implementing the topology refinement is a complex task. One approach is to encode the refinement into \emph{a sequence of Euler operations}. For Catmull-Clark subdivision, the refinement is encoded as edge-vertex insertions, an edge insertion between two neighboring edge-vertices, a facet-vertex insertion on the inserted edge, and edge insertions between the facet-vertex and the edge-vertices (Fig~.\ref{fig:CCRefinement}). These are Euler operations supported by \cgalpoly. \begin{figure} \centering \epsfig{file=figs/CCRefinement.eps, width=7cm} \caption{A PQQ refinement of a facet is encoded into a sequence of vertex insertions and edge insertions. Red indicates the inserted vertices and edges in each step.} \label{fig:CCRefinement}\vspace*{-2mm} \end{figure} The correspondence between stencil and control mesh is assured in the refinement with a consistent \emph{traversal sequence\/} on the mesh. The refinement host has a two pass algorithm, hence two traversals. The first pass generates the points by calling the policies. The second pass refines the mesh with a sequence of the Euler operations. The points generated in the first pass are stored in a point buffer in the order of the stencil traversal. The sequence of the vertex insertions is consistent to match the stencil traversal, i.e.\ the storage order of the point buffer. % It assures the stencil correspondence of the refinement. \noindent\textbf{Refinement host based on the modifier callback mechanism}. Most primal refinement schemes are easy to express in Euler operations. But dual schemes, e.g.\ Doo-Sabin subdivision, are different. A sequence of Euler operations for a DQQ scheme consists of twice the midedge refinement \cite{Peters:1997:SSS} and results an inefficient implementation. The separation of a subdivision scheme into multipass refinement is called subdivision factorization \cite{Joe:2003:FASS, Denis:2001:UFPDQ}. To support such schemes efficiently, we use the modifier callback mechanism and the incremental builder of \cgalpoly\ to rebuild the mesh connectivity. In addition to the point buffer, we also create a facet list based on the source mesh. Note that in a DQQ scheme, every new facet corresponds to a vertex, edge or facet. The combination of the points buffer and facet list represent a facet-vertex index list which indexes the vertices and enumerates each facet as an index sequence. A modifier creating a polyhedron from such a representation is straightforward, here a sketch using the incremental builder \CodeFmt{pb}. \begin{lstlisting} pb.begin_surface(num_point, num_facet); for (int i = 0; i < num_point; ++i) pb.add_vertex(Point(point_buffer[i*3+0], point_buffer[i*3+1], point_buffer[i*3+2])); for (int i = 0; i < num_facet; ++i) { pb.begin_facet(); for (int n = 0; n < facet_buffer[i][0]; ++n) pb.add_vertex_to_facet(facet_buffer[i][n+1]); pb.end_facet(); } pb.end_surface(); \end{lstlisting}\vspace*{-3mm} \begin{figure} \centering \epsfig{file=figs/plane0.eps, width=2.35cm} \\ \epsfig{file=figs/planeCC1.eps, width=2.35cm} \epsfig{file=figs/planeCC2.eps, width=2.35cm} \epsfig{file=figs/planeCC.eps, width=2.35cm}\\ \epsfig{file=figs/planeDS1.eps, width=2.35cm} \epsfig{file=figs/planeDS2.eps, width=2.35cm} \epsfig{file=figs/planeDS.eps, width=2.35cm} \caption{Catmull-Clark subdivision surfaces ({\itshape second row}) and Doo-Sabin subdivision surfaces ({\itshape third row}) of an aircraft polyhedron ({\itshape first row}). } \label{fig:SubExample}\vspace*{-2mm} \end{figure} \noindent\textbf{The subdivision library.} Our subdivision design solution, decoupling the geometry rules from the refinement, grants users flexible control of the stencils. Variants of subdivisions can be devised by simply combining different refinement hosts and geometric policies. A combinatorial subdivision set is provided within our subdivision library. It includes Catmull-Clark subdivision, Doo-Sabin subdivision, Loop subdivision, Quad-Triangle subdivision and $\sqrt{3}$ subdivision. Since \cgalpoly\ supports non-uniform meshes (in contrast to the quad-tree or patch-based implementation), chains of different refinements are naturally supported. %\begin{lstlisting} %void MySubdivision(Polyhedron& p) { % quadralize_polyhedron>(p); % dualize_polyhedron>(p); %} %\end{lstlisting} Furthermore, our solution is parameterized with the mesh structure and can thus be applied to user-specialized versions of \cgalpoly. Note that no special flag or attribute is required to assist the \tr . This generality makes our solution naturally fit in a modeling pipeline or a multipass modeling environment. %In some applications, efficiency is more %important than flexibility. An efficient implementation %of $\sqrt{3}$ based on \cgalpoly\ is introduced in next %section. %TODO: since the writing memory is not overlapped, multi-threaded %supporting is easily done. %TODO: trade-off between generic and efficient.