cgal/Generalized_map/include/CGAL/Generalized_map_constructors.h

292 lines
11 KiB
C++

// 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 <guillaume.damiand@liris.cnrs.fr>
//
#ifndef CGAL_GENERALIZED_MAP_CONSTRUCTORS_H
#define CGAL_GENERALIZED_MAP_CONSTRUCTORS_H 1
#include <CGAL/Combinatorial_map_basic_operations.h>
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<alg; ++nb )
{
typename Map::Dart_handle cur = make_edge(amap);
amap.template basic_link_alpha<1>(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<Map,2,1>(amap, d1, d2) ||
belong_to_same_cell<Map,2,1>(amap, d1, d3) ||
belong_to_same_cell<Map,2,1>(amap, d1, d4) ||
belong_to_same_cell<Map,2,1>(amap, d2, d3) ||
belong_to_same_cell<Map,2,1>(amap, d2, d4) ||
belong_to_same_cell<Map,2,1>(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<Map,2,1>(amap, d1, d2) ||
belong_to_same_cell<Map,2,1>(amap, d1, d3) ||
belong_to_same_cell<Map,2,1>(amap, d1, d4) ||
belong_to_same_cell<Map,2,1>(amap, d1, d5) ||
belong_to_same_cell<Map,2,1>(amap, d1, d6) ||
belong_to_same_cell<Map,2,1>(amap, d2, d3) ||
belong_to_same_cell<Map,2,1>(amap, d2, d4) ||
belong_to_same_cell<Map,2,1>(amap, d2, d5) ||
belong_to_same_cell<Map,2,1>(amap, d2, d6) ||
belong_to_same_cell<Map,2,1>(amap, d3, d4) ||
belong_to_same_cell<Map,2,1>(amap, d3, d5) ||
belong_to_same_cell<Map,2,1>(amap, d3, d6) ||
belong_to_same_cell<Map,2,1>(amap, d4, d5) ||
belong_to_same_cell<Map,2,1>(amap, d4, d6) ||
belong_to_same_cell<Map,2,1>(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 //