From a503ce19040564e68fcdc0ffc5db901b1b33a9e0 Mon Sep 17 00:00:00 2001 From: Pierre Alliez Date: Thu, 24 Jul 2003 15:59:10 +0000 Subject: [PATCH] updated doc --- .../Tutorial/tutorial/Polyhedron/doc/makefile | 4 +- .../tutorial/Polyhedron/doc/tutorial.pdf | Bin 3326534 -> 3332687 bytes .../tutorial/Polyhedron/doc/tutorial.tex | 428 ++++++++++++++++-- 3 files changed, 394 insertions(+), 38 deletions(-) diff --git a/Packages/Tutorial/tutorial/Polyhedron/doc/makefile b/Packages/Tutorial/tutorial/Polyhedron/doc/makefile index 65b0bca1c06..e3ba8c575dd 100644 --- a/Packages/Tutorial/tutorial/Polyhedron/doc/makefile +++ b/Packages/Tutorial/tutorial/Polyhedron/doc/makefile @@ -14,12 +14,12 @@ all: make ps make pdf make clean - \rm *.ps + \rm *.ps *.tmp clear ls -l clean: - \rm *.aux *.dvi *.log + \rm *.aux *.dvi *.log *.out *.blg *.bbl superclean: \rm *.ps *.pdf *~ diff --git a/Packages/Tutorial/tutorial/Polyhedron/doc/tutorial.pdf b/Packages/Tutorial/tutorial/Polyhedron/doc/tutorial.pdf index 23f591b7d611f59439842735ec46fd95fe164c0c..4f266a92586eb80bcaf4b686efc047f20f1c77a1 100644 GIT binary patch delta 18360 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 Jimocj{{tSUtc3so delta 12624 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 +class CModifierQuadTriangle : public CGAL::Modifier_base +{ +private: + typedef typename kernel::FT FT; + typedef typename HDS::Vertex Vertex; + typedef typename Vertex::Point Point; + typedef typename HDS::Face_handle Face_handle; + typedef typename HDS::Halfedge_handle Halfedge_handle; + typedef typename CGAL::Enriched_polyhedron_incremental_builder_3 builder; + typedef typename Polyhedron::Halfedge_around_vertex_circulator Halfedge_around_vertex_circulator; + typedef typename Polyhedron::Facet_handle Facet_handle; + typedef typename Polyhedron::Vertex_handle Vertex_handle; + + Polyhedron *m_pMesh; + +public: + + // life cycle + CModifierQuadTriangle(Polyhedron *pMesh) + { + CGAL_assertion(pMesh != NULL); + m_pMesh = pMesh; + } + ~CModifierQuadTriangle() {} + + // subdivision + void operator()( HDS& hds) + { + builder B(hds,true); + B.begin_surface(3,1,6); + add_vertices(B); + add_facets(B); + B.end_surface(); + } + +private: + + //*************************************************** + // add vertices + //*************************************************** + void add_vertices(builder &B) + { + // put original vertices + int index = 0; + typename Polyhedron::Vertex_iterator pVertex; + for(pVertex = m_pMesh->vertices_begin(); + pVertex != m_pMesh->vertices_end(); + pVertex++) + { + pVertex->tag(index); + B.add_vertex(pVertex->point()); + index++; + } + + // as many as #edges + m_pMesh->tag_halfedges(-1); + typename Polyhedron::Halfedge_iterator pHalfedge; + for(pHalfedge = m_pMesh->halfedges_begin(); + pHalfedge != m_pMesh->halfedges_end(); + pHalfedge++) + { + if(pHalfedge->tag() != -1) + continue; + + // simple edge bissection + const Point& p1 = pHalfedge->vertex()->point(); + const Point& p2 = pHalfedge->opposite()->vertex()->point(); + Point point = Point(0.5f*(p1.x()+p2.x()), + 0.5f*(p1.y()+p2.y()), + 0.5f*(p1.z()+p2.z())); + B.add_vertex(point); + + // put vertex indices on both halfedges + pHalfedge->tag(index); + pHalfedge->opposite()->tag(index); + index++; + } + + // and as many as #facets with degree > 3 + m_pMesh->tag_facets(-1); + typename Polyhedron::Facet_iterator pFacet; + for(pFacet = m_pMesh->facets_begin(); + pFacet != m_pMesh->facets_end(); + pFacet++) + { + unsigned int degree = Polyhedron::degree(pFacet); + CGAL_assertion(degree >= 3); + // forget about triangles, they are + // simply 1-to-4 subdivided by edge bisection + if(degree == 3) + continue; + + // barycentric subdivision + Point barycenter; + m_pMesh->compute_facet_center(pFacet,barycenter); + B.add_vertex(barycenter); + pFacet->tag(index); + index++; + } + } + + //*************************************************** + // add facets + //*************************************************** + void add_facets(builder &B) + { + typename Polyhedron::Facet_iterator pFacet; + for(pFacet = m_pMesh->facets_begin(); + pFacet != m_pMesh->facets_end(); + pFacet++) + { + unsigned int degree = Polyhedron::degree(pFacet); + CGAL_assertion(degree >= 3); + + if(degree == 3) + { + typename Polyhedron::Halfedge_handle pHalfedge = pFacet->halfedge(); + int i0 = pHalfedge->tag(); + int i1 = pHalfedge->vertex()->tag(); + int i2 = pHalfedge->next()->tag(); + int i3 = pHalfedge->next()->vertex()->tag(); + int i4 = pHalfedge->next()->next()->tag(); + int i5 = pHalfedge->next()->next()->vertex()->tag(); + CGAL_assertion(i0 >= 0); + CGAL_assertion(i1 >= 0); + CGAL_assertion(i2 >= 0); + CGAL_assertion(i3 >= 0); + CGAL_assertion(i4 >= 0); + CGAL_assertion(i5 >= 0); + + // create 4 triangles + B.begin_facet(); + B.add_vertex_to_facet(i1); + B.add_vertex_to_facet(i2); + B.add_vertex_to_facet(i0); + const Halfedge_handle& h1 = B.end_facet(); + B.begin_facet(); + B.add_vertex_to_facet(i3); + B.add_vertex_to_facet(i4); + B.add_vertex_to_facet(i2); + const Halfedge_handle& h2 = B.end_facet(); + B.begin_facet(); + B.add_vertex_to_facet(i5); + B.add_vertex_to_facet(i0); + B.add_vertex_to_facet(i4); + const Halfedge_handle& h3 = B.end_facet(); + + // center face + B.begin_facet(); + B.add_vertex_to_facet(i0); + B.add_vertex_to_facet(i2); + B.add_vertex_to_facet(i4); + Halfedge_handle h4 = B.end_facet(); + + h1->control_edge(false); + h1->next()->control_edge(false); + h1->next()->next()->control_edge(false); + + h2->control_edge(false); + h2->next()->control_edge(false); + h2->next()->next()->control_edge(false); + + h3->control_edge(false); + h3->next()->control_edge(false); + h3->next()->next()->control_edge(false); + + h4->control_edge(false); + h4->next()->control_edge(false); + h4->next()->next()->control_edge(false); + + if(pHalfedge->control_edge()) + { + h1->control_edge(true); + h3->next()->control_edge(true); + } + if(pHalfedge->next()->control_edge()) + { + h1->next()->control_edge(true); + h2->control_edge(true); + } + if(pHalfedge->next()->next()->control_edge()) + { + h2->next()->control_edge(true); + h3->control_edge(true); + } + } + else + { + // i1: index of barycenter vertex + int i1 = pFacet->tag(); + CGAL_assertion(i1 >= 0); + + // for each halfedge + typename Polyhedron::Halfedge_around_facet_circulator h; + h = pFacet->facet_begin(); + do + { + // i2,3,4: indices of three consecutive + // vertices on halfedges + int i2 = h->tag(); + int i3 = h->vertex()->tag(); + int i4 = h->next()->tag(); + CGAL_assertion(i2 >= 0); + CGAL_assertion(i3 >= 0); + CGAL_assertion(i4 >= 0); + + // create a quad + B.begin_facet(); + B.add_vertex_to_facet(i3); + B.add_vertex_to_facet(i4); + B.add_vertex_to_facet(i1); + B.add_vertex_to_facet(i2); + const Halfedge_handle& pNewHalfedge = B.end_facet(); + + pNewHalfedge->control_edge(false); + pNewHalfedge->next()->control_edge(false); + pNewHalfedge->next()->next()->control_edge(false); + pNewHalfedge->next()->next()->next()->control_edge(false); + + if(h->control_edge()) + pNewHalfedge->control_edge(true); + if(h->next()->control_edge()) + pNewHalfedge->next()->control_edge(true); + } + while(++h != pFacet->facet_begin()); + } + } + } + + //*************************************************** + // correcting factor + //*************************************************** + static float correcting_factor(unsigned int ne, + unsigned int nq) + { + if(ne == 2 && nq == 1) + return -0.20505f; + if(ne == 3 && nq == 1) + return 0.80597f; + if(ne == 3 && nq == 2) + return 0.61539f; + if(ne == 4 && nq == 1) + return 0.34792f; + if(ne == 4 && nq == 2) + return 0.21380f; + if(ne == 4 && nq == 3) + return 0.10550f; + return 0.0f; + } +public: + //*************************************************** + // smooth vertex positions + //*************************************************** + static void smooth(Polyhedron *pMesh, + bool smooth_boundary = true) + { + CGAL_assertion(pMesh != NULL); + + // alloc position vectors + unsigned int nb_vertices = pMesh->size_of_vertices(); + FT *pPos = new FT[3*nb_vertices]; + CGAL_assertion(pPos != NULL); + + // compute new positions + unsigned int index = 0; + typename Polyhedron::Vertex_iterator pVertex; + for(pVertex = pMesh->vertices_begin(); + pVertex != pMesh->vertices_end(); + pVertex++) + { + // border vertices will not move + if(Polyhedron::is_border(pVertex)) + { + // do not smooth it + const Point& curr = pVertex->point(); + if(!smooth_boundary) + { + pPos[3*index] = curr.x(); + pPos[3*index+1] = curr.y(); + pPos[3*index+2] = curr.z(); + } + // smooth using [1/4 1/2 1/4] cubic B-spline averaging mask + else + { + const typename Polyhedron::Halfedge_handle& pHalfedge = + pMesh->get_border_halfedge(pVertex); + CGAL_assertion(pHalfedge != NULL); + const Point& next = pHalfedge->vertex()->point(); + const Point& prev = pHalfedge->prev()->prev()->vertex()->point(); + pPos[3*index] = 0.25f*prev.x() + 0.5f*curr.x() + 0.25f*next.x(); + pPos[3*index+1] = 0.25f*prev.y() + 0.5f*curr.y() + 0.25f*next.y(); + pPos[3*index+2] = 0.25f*prev.z() + 0.5f*curr.z() + 0.25f*next.z(); + } + } // end is border + else + { + + unsigned int nb_quads = 0; + unsigned int nb_edges = 0; + + // rotate around vertex to count #edges and #quads + Halfedge_around_vertex_circulator + pHalfEdge = pVertex->vertex_begin(); + Halfedge_around_vertex_circulator end = pHalfEdge; + CGAL_For_all(pHalfEdge,end) + { + const Facet_handle& pFacet = pHalfEdge->facet(); + CGAL_assertion(pFacet != NULL); + unsigned int degree = Polyhedron::degree(pFacet); + CGAL_assertion(degree == 4 || degree == 3); + if(degree == 4) + nb_quads++; + nb_edges++; + } + + // compute coefficients + FT ne = (FT)nb_edges; + FT nq = (FT)nb_quads; + FT alpha = 1.0f / (1.0f + ne/2.0f + nq/4.0f); + FT beta = alpha / 2.0f; // edges + FT gamma = alpha / 4.0f; // corners of incident quads + FT eta = correcting_factor(nb_edges,nb_quads); + + // new position + pPos[3*index] = alpha * pVertex->point().x(); + pPos[3*index+1] = alpha * pVertex->point().y(); + pPos[3*index+2] = alpha * pVertex->point().z(); + + // rotate around vertex to compute new position + pHalfEdge = pVertex->vertex_begin(); + end = pHalfEdge; + CGAL_For_all(pHalfEdge,end) + { + const Facet_handle& pFacet = pHalfEdge->facet(); + CGAL_assertion(pFacet != NULL); + unsigned int degree = Polyhedron::degree(pFacet); + CGAL_assertion(degree == 4 || degree == 3); + + // add edge-vertex contribution + const Point& point = pHalfEdge->prev()->vertex()->point(); + pPos[3*index] += beta * point.x(); + pPos[3*index+1] += beta * point.y(); + pPos[3*index+2] += beta * point.z(); + + // add corner vertex contribution + if(degree == 4) + { + const Point& corner = pHalfEdge->next()->next()->vertex()->point(); + pPos[3*index] += gamma * corner.x(); + pPos[3*index+1] += gamma * corner.y(); + pPos[3*index+2] += gamma * corner.z(); + } + } + + // apply correction + pPos[3*index] = pPos[3*index] + + eta*(pPos[3*index]-pVertex->point().x()); + pPos[3*index+1] = pPos[3*index+1] + + eta*(pPos[3*index+1]-pVertex->point().y()); + pPos[3*index+2] = pPos[3*index+2] + + eta*(pPos[3*index+2]-pVertex->point().z()); + + } // end !is border + index++; + } + + // set new positions + index = 0; + for(pVertex = pMesh->vertices_begin(); + pVertex != pMesh->vertices_end(); + pVertex++) + { + Point& point = pVertex->point(); + point = Point(pPos[3*index], + pPos[3*index+1], + pPos[3*index+2]); + index++; + } + + // cleanup + delete [] pPos; + } +}; +\end{verbatim}} + { \scriptsize \begin{verbatim} template @@ -961,42 +1353,6 @@ public: }; \end{verbatim}} -Subdivision using a modified incremental builder - -{ \scriptsize -\begin{verbatim} -template -class CModifierQuadTriangle : public CGAL::Modifier_base -{ -private: - Polyhedron *m_pMesh; - typedef typename CGAL::Enriched_builder builder; - -public: - - // life cycle - CModifierQuadTriangle(Polyhedron *pMesh) - { - m_pMesh = pMesh; - } - ~CModifierQuadTriangle() {} - - // subdivision - void operator()( HDS& hds) - { - builder B(hds,true); - B.begin_surface(3,1,6); - add_vertices(B); - add_facets(B); - B.end_surface(); - } -... -}; -\end{verbatim}} - - - - % SurfLab \subsection{Subdivision using a rule template}