// Copyright (c) 2005 Rijksuniversiteit Groningen (Netherlands) // All rights reserved. // // This file is part of CGAL (www.cgal.org); you may redistribute it under // the terms of the Q Public License version 1.0. // See the file LICENSE.QPL distributed with CGAL. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // // // Author(s) : Nico Kruithof #ifndef CGAL_MARCHING_TETRAHEDRA_H #define CGAL_MARCHING_TETRAHEDRA_H #include #include #include #include CGAL_BEGIN_NAMESPACE // If TriangulationDataStructure_3 only gets a Cell_handle range // it is not possible to derive the Vertex_handle type. template class Marching_tetrahedra_builder : public Modifier_base { public: typedef Triangulation_3 Triangulation; typedef HalfedgeDS_3 HDS; typedef MarchingTetrahedraTraits_3 Traits; typedef MarchingTetrahedraObserver_3 Observer; private: typedef typename Triangulation::Finite_cells_iterator T_cell_iterator; typedef typename Triangulation::Vertex_handle T_vertex_handle; typedef typename HDS::Face_handle HDS_face_handle; typedef typename HDS::Vertex_handle HDS_vertex_handle; typedef std::map T_vertex_map; typedef typename T_vertex_map::iterator T_vertex_map_it; // First vertex lies inside the surface, the second vertex outside typedef std::pair T_edge; typedef std::map T_edge_map; typedef typename T_edge_map::iterator T_edge_map_it; typedef Polyhedron_incremental_builder_3 Polyh_incr_builder; public: Marching_tetrahedra_builder( const Triangulation &triang, const Traits &traits, Observer &observer) : triang(triang), traits(traits), observer(observer), nVertices(0) { } void operator()( HDS& hds) { // sortedV is an array of vertex indices. // The first nIn vertices lie inside the surface, the last 4-nIn outside. int sortedV[4], cellV[4], nIn; T_edge edge; Polyh_incr_builder B( hds, true); B.begin_surface(0,0,0); for (T_cell_iterator cit = triang.finite_cells_begin(); cit != triang.finite_cells_end(); cit++) { // Compute signs on vertices and sort them: nIn = 0; for (int i=0; i<4; i++) { if (is_inside(cit,i)) { sortedV[nIn] = i; nIn++; } else { sortedV[3-i+nIn] = i; } } // Process edges whose vertices lie on different sides of the surface int edgeN=0; for (int i=0; ivertex(i)); if (it == triang_vertex_signs.end()) { bool side = (traits.sign(ch,i) == POSITIVE); triang_vertex_signs[ch->vertex(i)] = side; CGAL_assertion(triang_vertex_signs[ch->vertex(i)] == side); return side; } else { return it->second; } } int process_edge(Polyh_incr_builder &B, T_cell_iterator ch, int i, int j) { CGAL_assertion(is_inside(ch, i)); CGAL_assertion(!is_inside(ch, j)); T_edge edge = T_edge(ch->vertex(i),ch->vertex(j)); T_edge_map_it edge_it = polyh_vert.find(edge); if (edge_it == polyh_vert.end()) { HDS_vertex_handle vh = B.add_vertex(traits.intersection(ch, i, j)); polyh_vert[edge] = nVertices; nVertices ++; observer.after_vertex_insertion(ch, i, j, vh); return nVertices-1; } else { return edge_it->second; } } // Orientation is right void process_cell( Polyh_incr_builder &B, int *vs, bool change_orientation, T_cell_iterator ch) { CGAL_assertion((vs[0]!=vs[1]) && (vs[0]!=vs[2]) && (vs[1]!=vs[2])); HDS_face_handle f = B.begin_facet(); if (change_orientation) { B.add_vertex_to_facet( vs[0] ); B.add_vertex_to_facet( vs[2] ); B.add_vertex_to_facet( vs[1] ); } else { B.add_vertex_to_facet( vs[0] ); B.add_vertex_to_facet( vs[1] ); B.add_vertex_to_facet( vs[2] ); } B.end_facet(); observer.after_facet_insertion(ch, f); } private: const Triangulation &triang; const Traits &traits; Observer &observer; T_edge_map polyh_vert; T_vertex_map triang_vertex_signs; int nVertices; }; template void marching_tetrahedra_3( const Triangulation_3 &triangulation, Polyhedron_3 &polyhedron, const MarchingTetrahedraTraits_3 &traits) { typedef typename Polyhedron_3::HalfedgeDS HDS; typedef Marching_tetrahedra_observer_default_3 Observer; typedef Marching_tetrahedra_builder< Triangulation_3, HDS, MarchingTetrahedraTraits_3, Observer> Builder; Observer observer; Builder builder(triangulation, traits, observer); polyhedron.delegate(builder); } template void marching_tetrahedra_3( const Triangulation_3 &triangulation, Polyhedron_3 &polyhedron, const MarchingTetrahedraTraits_3 &traits, MarchingTetrahedraObserver_3 &observer) { typedef typename Polyhedron_3::HalfedgeDS HDS; typedef Marching_tetrahedra_builder< Triangulation_3,HDS, MarchingTetrahedraTraits_3, MarchingTetrahedraObserver_3> Builder; Builder builder(triangulation, traits, observer); polyhedron.delegate(builder); } CGAL_END_NAMESPACE #endif // CGAL_MARCHING_TETRAHEDRA_H