// Copyright (c) 2014 CNRS and LIRIS' Establishments (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org); you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 3 of the License, // or (at your option) any later version. // // 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) : Guillaume Damiand // #ifndef CGAL_GENERALIZED_MAP_CONSTRUCTORS_H #define CGAL_GENERALIZED_MAP_CONSTRUCTORS_H 1 #include namespace CGAL { /** @file Generalized_map_constructors.h * Basic creation operations for a generalized map. * Create edge, triangle, quadrilateral, tetrahedron, hexahedron. */ /** Create an edge. * @param amap the used generalized map. * @return a dart of the new edge. */ template < class Map > typename Map::Dart_handle make_edge(Map& amap) { typename Map::Dart_handle d1 = amap.create_dart(); typename Map::Dart_handle d2 = amap.create_dart(); amap.basic_link_alpha(d1, d2, 0); return d1; } /** Create a combinatorial polygon of length alg * (a cycle of alg edges alpha1 links together). * @param amap the used generalized map. * @return a new dart. */ template < class Map > typename Map::Dart_handle make_combinatorial_polygon(Map& amap, unsigned int alg) { CGAL_assertion(alg>0); typename Map::Dart_handle start = make_edge(amap); typename Map::Dart_handle prev = amap.template alpha<0>(start); for ( unsigned int nb=1; nb(prev, cur); prev=amap.template alpha<0>(cur); } amap.template basic_link_alpha<1>(prev, start); return start; } /** Test if a face is a combinatorial polygon of length alg * (a cycle of alg darts beta1 links together). * @param amap the used generalized map. * @param adart an intial dart * @return true iff the face containing adart is a polygon of length alg. */ template < class Map > bool is_face_combinatorial_polygon(const Map& amap, typename Map::Dart_const_handle adart, unsigned int alg) { CGAL_assertion(alg>0); unsigned int nb = 0; typename Map::Dart_const_handle cur = adart; do { ++nb; if ( amap.is_free(cur, 0) || amap.is_free(amap.alpha(cur, 0), 1) ) return false; // Open face cur = amap.alpha(cur,0,1); } while( cur!=adart ); return (nb==alg); } /** Create a combinatorial tetrahedron from 4 triangles. * @param amap the used generalized map. * @param d1 a dart onto a first triangle. * @param d2 a dart onto a second triangle. * @param d3 a dart onto a third triangle. * @param d4 a dart onto a fourth triangle. * @return a new dart. */ template < class Map > typename Map::Dart_handle make_combinatorial_tetrahedron(Map& amap, typename Map::Dart_handle d1, typename Map::Dart_handle d2, typename Map::Dart_handle d3, typename Map::Dart_handle d4) { amap.template topo_sew<2>(d1, d2); amap.template topo_sew<2>(d3, amap.alpha(d2, 1)); amap.template topo_sew<2>(amap.alpha(d1, 1), amap.alpha(d3, 1)); amap.template topo_sew<2>(d4, amap.alpha(d2, 0, 1)); amap.template topo_sew<2>(amap.alpha(d4, 0, 1), amap.alpha(d3, 0, 1)); amap.template topo_sew<2>(amap.alpha(d4, 1), amap.alpha(d1, 0, 1)); return d1; } /** Test if a volume is a combinatorial tetrahedron. * @param amap the used generalized map. * @param adart an intial dart * @return true iff the volume containing adart is a combinatorial tetrahedron. */ template < class Map > bool is_volume_combinatorial_tetrahedron(const Map& amap, typename Map::Dart_const_handle d1) { typename Map::Dart_const_handle d2 = amap.alpha(d1, 2); typename Map::Dart_const_handle d3 = amap.alpha(d2, 1, 2); typename Map::Dart_const_handle d4 = amap.alpha(d2, 0, 1, 2); if ( !is_face_combinatorial_polygon(amap, d1, 3) || !is_face_combinatorial_polygon(amap, d2, 3) || !is_face_combinatorial_polygon(amap, d3, 3) || !is_face_combinatorial_polygon(amap, d4, 3) ) return false; // TODO do better with marks (?). if ( belong_to_same_cell(amap, d1, d2) || belong_to_same_cell(amap, d1, d3) || belong_to_same_cell(amap, d1, d4) || belong_to_same_cell(amap, d2, d3) || belong_to_same_cell(amap, d2, d4) || belong_to_same_cell(amap, d3, d4) ) return false; if ( amap.alpha(d1,1,2)!=amap.alpha(d3,1) || amap.alpha(d4,0,1,2)!=amap.alpha(d3,0,1) || amap.alpha(d4,1,2)!=amap.alpha(d1,0,1) ) return false; return true; } /** Create a new combinatorial tetrahedron. * @param amap the used generalized map. * @return a new dart. */ template < class Map > typename Map::Dart_handle make_combinatorial_tetrahedron(Map& amap) { typename Map::Dart_handle d1 = make_combinatorial_polygon(amap,3); typename Map::Dart_handle d2 = make_combinatorial_polygon(amap,3); typename Map::Dart_handle d3 = make_combinatorial_polygon(amap,3); typename Map::Dart_handle d4 = make_combinatorial_polygon(amap,3); return make_combinatorial_tetrahedron(amap, d1, d2, d3, d4); } /** Create a combinatorial hexahedron from 6 quadrilaterals. * @param amap the used generalized map. * @param d1 a dart onto a first quadrilateral. * @param d2 a dart onto a second quadrilateral. * @param d3 a dart onto a third quadrilateral. * @param d4 a dart onto a fourth quadrilateral. * @param d5 a dart onto a fifth quadrilateral. * @param d6 a dart onto a sixth quadrilateral. * @return a dart of the new cuboidal_cell. */ template < class Map > typename Map::Dart_handle make_combinatorial_hexahedron(Map& amap, typename Map::Dart_handle d1, typename Map::Dart_handle d2, typename Map::Dart_handle d3, typename Map::Dart_handle d4, typename Map::Dart_handle d5, typename Map::Dart_handle d6) { amap.template topo_sew<2>(d1, amap.alpha(d4,1,0,1,0)); amap.template topo_sew<2>(amap.alpha(d1,0,1), amap.alpha(d6,1)); amap.template topo_sew<2>(amap.alpha(d1,1,0,1), d2); amap.template topo_sew<2>(amap.alpha(d1,1), d5); amap.template topo_sew<2>(d3, amap.alpha(d2,1,0,1)); amap.template topo_sew<2>(amap.alpha(d3,0,1,0), amap.alpha(d6,0,1)); amap.template topo_sew<2>(amap.alpha(d3,1,0,1,0), d4); amap.template topo_sew<2>(amap.alpha(d3,1), amap.alpha(d5,0,1,0,1)); amap.template topo_sew<2>(d6, amap.alpha(d4,1,0)); amap.template topo_sew<2>(amap.alpha(d6,1,0,1), amap.alpha(d2,0,1)); amap.template topo_sew<2>(amap.alpha(d5,1,0), amap.alpha(d4,0,1)); amap.template topo_sew<2>(amap.alpha(d5,0,1), amap.alpha(d2,1)); return d1; } /** Test if a volume is a combinatorial hexahedron. * @param amap the used generalized map. * @param adart an intial dart * @return true iff the volume containing adart is a combinatorial hexahedron. */ template < class Map > bool is_volume_combinatorial_hexahedron(const Map& amap, typename Map::Dart_const_handle d1) { typename Map::Dart_const_handle d2 = amap.alpha(d1,1,0,1,2); typename Map::Dart_const_handle d3 = amap.alpha(d2,1,0,1,2); typename Map::Dart_const_handle d4 = amap.alpha(d3,1,0,1,0,2); typename Map::Dart_const_handle d5 = amap.alpha(d1,1,2); typename Map::Dart_const_handle d6 = amap.alpha(d4,1,0,2); if (!is_face_combinatorial_polygon(amap, d1, 4) || !is_face_combinatorial_polygon(amap, d2, 4) || !is_face_combinatorial_polygon(amap, d3, 4) || !is_face_combinatorial_polygon(amap, d4, 4) || !is_face_combinatorial_polygon(amap, d5, 4) || !is_face_combinatorial_polygon(amap, d6, 4) ) return false; // TODO do better with marks. if ( belong_to_same_cell(amap, d1, d2) || belong_to_same_cell(amap, d1, d3) || belong_to_same_cell(amap, d1, d4) || belong_to_same_cell(amap, d1, d5) || belong_to_same_cell(amap, d1, d6) || belong_to_same_cell(amap, d2, d3) || belong_to_same_cell(amap, d2, d4) || belong_to_same_cell(amap, d2, d5) || belong_to_same_cell(amap, d2, d6) || belong_to_same_cell(amap, d3, d4) || belong_to_same_cell(amap, d3, d5) || belong_to_same_cell(amap, d3, d6) || belong_to_same_cell(amap, d4, d5) || belong_to_same_cell(amap, d4, d6) || belong_to_same_cell(amap, d5, d6) ) return false; if ( amap.alpha(d1,2) !=amap.alpha(d4,0,1,0,1) || amap.alpha(d1,0,1,2) !=amap.alpha(d6,1) || amap.alpha(d3,0,1,2) !=amap.alpha(d6,0,1,0) || amap.alpha(d3,1,2) !=amap.alpha(d5,0,1,0,1) || amap.alpha(d6,1,0,1,2)!=amap.alpha(d2,0,1) || amap.alpha(d5,1,2) !=amap.alpha(d4,0,1,0) || amap.alpha(d5,0,1,2) !=amap.alpha(d2,1) ) return false; return true; } /** Create a new combinatorial hexahedron. * @param amap the used generalized map. * @return a new dart. */ template < class Map > typename Map::Dart_handle make_combinatorial_hexahedron(Map& amap) { typename Map::Dart_handle d1 = make_combinatorial_polygon(amap,4); typename Map::Dart_handle d2 = make_combinatorial_polygon(amap,4); typename Map::Dart_handle d3 = make_combinatorial_polygon(amap,4); typename Map::Dart_handle d4 = make_combinatorial_polygon(amap,4); typename Map::Dart_handle d5 = make_combinatorial_polygon(amap,4); typename Map::Dart_handle d6 = make_combinatorial_polygon(amap,4); return make_combinatorial_hexahedron(amap, d1, d2, d3, d4, d5, d6); } } // namespace CGAL #endif // CGAL_GENERALIZED_MAP_CONSTRUCTORS_H // // EOF //