1 // Copyright (c) 2012-2016 GeometryFactory Sarl (France). 2 // All rights reserved. 3 // 4 // This file is part of CGAL (www.cgal.org). 5 // 6 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Mesh_3/include/CGAL/Mesh_3/experimental/Facet_topological_criterion_with_adjacency.h $ 7 // $Id: Facet_topological_criterion_with_adjacency.h 58b10a3 2020-03-26T18:58:50+01:00 Sébastien Loriot 8 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial 9 // 10 // Author(s) : Laurent Rineau 11 12 #ifndef CGAL_MESH_3_FACET_TOPOLOGICAL_CRITERION_WITH_ADJACENCY_H 13 #define CGAL_MESH_3_FACET_TOPOLOGICAL_CRITERION_WITH_ADJACENCY_H 14 15 #include <CGAL/license/Mesh_3.h> 16 17 #include <CGAL/Mesh_3/mesh_standard_criteria.h> 18 #include <CGAL/number_utils.h> 19 #include <CGAL/array.h> 20 21 namespace CGAL { 22 23 namespace Mesh_3 { 24 25 template <typename Tr, typename MeshDomain, typename Visitor_> 26 class Facet_topological_criterion_with_adjacency : 27 public Mesh_3::Abstract_criterion<Tr, Visitor_> 28 { 29 private: 30 typedef typename Tr::Facet Facet; 31 32 typedef Mesh_3::Abstract_criterion<Tr,Visitor_> Base; 33 typedef typename Base::Quality Quality; 34 typedef typename Base::Is_bad Is_bad; 35 36 typedef Facet_topological_criterion_with_adjacency<Tr,MeshDomain, Visitor_> Self; 37 38 typedef typename Tr::Geom_traits::FT FT; 39 40 const MeshDomain* domain; 41 42 public: 43 /// Constructor Facet_topological_criterion_with_adjacency(const MeshDomain * domain)44 Facet_topological_criterion_with_adjacency(const MeshDomain* domain) 45 : domain(domain) 46 {} 47 48 /// Destructor ~Facet_topological_criterion_with_adjacency()49 virtual ~Facet_topological_criterion_with_adjacency() {} 50 51 protected: do_accept(Visitor_ & v)52 virtual void do_accept(Visitor_& v) const 53 { 54 v.visit(*this); 55 } 56 do_clone()57 virtual Self* do_clone() const 58 { 59 // Call copy ctor on this 60 return new Self(*this); 61 } 62 do_is_bad(const Tr &,const Facet & f)63 virtual Is_bad do_is_bad (const Tr& /*tr*/, const Facet& f) const 64 { 65 typedef typename Tr::Vertex_handle Vertex_handle; 66 typedef typename Tr::Cell_handle Cell_handle; 67 68 const Cell_handle& ch = f.first; 69 const int& i = f.second; 70 71 typedef typename MeshDomain::Surface_patch_index Patch_index; 72 73 const Patch_index patch_index = ch->surface_patch_index(i); 74 75 typedef std::vector<Patch_index> Index_set; 76 77 int nb_vertices_on_curves = 0; 78 79 for(int k = 0; k < 3; ++k) { 80 const Vertex_handle v = ch->vertex((i+k+1)&3); 81 switch(v->in_dimension()) { 82 case 0: 83 { 84 ++nb_vertices_on_curves; // corners are on curves 85 const typename MeshDomain::Corner_index corner_id = 86 domain->corner_index(v->index()); 87 88 Index_set set; 89 domain->get_corner_incidences(corner_id, std::back_inserter(set)); 90 if(std::find(set.begin(), set.end(), patch_index) == set.end()) { 91 #ifdef CGAL_MESH_3_DEBUG_FACET_CRITERIA 92 std::cerr << "Bad facet " 93 "(Facet_topological_criterion_with_adjacency: corner #" 94 << corner_id << ", point " << v->point() 95 << ", is not incident to patch #" << patch_index << ")" 96 << std::endl; 97 #endif 98 return Is_bad(Quality(1)); // bad! 99 } 100 } 101 break; 102 case 1: 103 { 104 ++nb_vertices_on_curves; 105 const typename MeshDomain::Curve_index curve_id = 106 domain->curve_index(v->index()); 107 Index_set set; 108 domain->get_incidences(curve_id, std::back_inserter(set)); 109 if(std::find(set.begin(), set.end(), patch_index) == set.end()) { 110 #ifdef CGAL_MESH_3_DEBUG_FACET_CRITERIA 111 std::cerr << "Bad facet " 112 "(Facet_topological_criterion_with_adjacency: curve #" 113 << curve_id << ", at point " << v->point() 114 << ", is not incident to patch #" << patch_index << ")" 115 << std::endl; 116 #endif 117 return Is_bad(Quality(1)); // bad! 118 } 119 } 120 break; 121 case 2: 122 if(domain->surface_patch_index(v->index()) != patch_index) { 123 #ifdef CGAL_MESH_3_DEBUG_FACET_CRITERIA 124 std::cerr << "Bad facet (Facet_topological_criterion_with_adjacency: " 125 "vertex at point " 126 << v->point() << " is not on patch #" << patch_index << ")" 127 << std::endl; 128 #endif 129 return Is_bad(Quality(1)); // bad! 130 } 131 break; 132 default: 133 return Is_bad(Quality(1)); 134 break; 135 } 136 } 137 if(nb_vertices_on_curves == 3) { 138 #ifdef CGAL_MESH_3_DEBUG_FACET_CRITERIA 139 std::cerr << "Bad facet (Facet_topological_criterion_with_adjacency: " 140 "three points on a curve)\n"; 141 #endif 142 return Is_bad(Quality(1)); // bad! 143 // All vertices are on curves. That means that the facet could be on 144 // several different patches. Let's disallow that. 145 } 146 return Is_bad(); 147 } 148 }; // end class Facet_topological_criterion_with_adjacency 149 150 } // end namespace Mesh_3 151 152 } // end namespace CGAL 153 154 #endif // CGAL_MESH_3_FACET_TOPOLOGICAL_CRITERION_WITH_ADJACENCY_H 155