mirror of https://github.com/CGAL/cgal
add a hidden parameter to allow non-manifold vertices or edges
this is to be used only is advanced code that deals with invalid T3
This commit is contained in:
parent
74d376cf09
commit
d7759abbb7
|
|
@ -41,7 +41,8 @@ namespace SMDS_3 {
|
|||
bool build_triangulation_from_file(std::istream& is,
|
||||
Tr& tr,
|
||||
bool verbose = false,
|
||||
bool replace_domain_0 = false);
|
||||
bool replace_domain_0 = false,
|
||||
bool allow_non_manifold = false);
|
||||
|
||||
} // namespace SMDS_3
|
||||
} // namespace CGAL
|
||||
|
|
|
|||
|
|
@ -129,7 +129,8 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(
|
|||
item->setName(fileinfo.baseName());
|
||||
item->set_valid(false);
|
||||
|
||||
if(CGAL::SMDS_3::build_triangulation_from_file(in, item->c3t3().triangulation(), true))
|
||||
if(CGAL::SMDS_3::build_triangulation_from_file(in, item->c3t3().triangulation(),
|
||||
/*verbose = */true, /*replace_subdomain_0 = */false, /*allow_non_manifold = */true))
|
||||
{
|
||||
item->c3t3().rescan_after_load_of_triangulation(); //fix counters for facets and cells
|
||||
for( C3t3::Cell_handle cit : item->c3t3().triangulation().finite_cell_handles())
|
||||
|
|
|
|||
|
|
@ -68,7 +68,8 @@ template<class Tr>
|
|||
bool add_facet_to_incident_cells_map(const typename Tr::Cell_handle c, int i,
|
||||
boost::unordered_map<std::array<typename Tr::Vertex_handle, 3>,
|
||||
std::vector<std::pair<typename Tr::Cell_handle, int> > >& incident_cells_map,
|
||||
const bool verbose)
|
||||
const bool verbose,
|
||||
const bool allow_non_manifold)
|
||||
{
|
||||
typedef typename Tr::Vertex_handle Vertex_handle;
|
||||
typedef typename Tr::Cell_handle Cell_handle;
|
||||
|
|
@ -76,8 +77,10 @@ bool add_facet_to_incident_cells_map(const typename Tr::Cell_handle c, int i,
|
|||
typedef std::pair<Cell_handle, int> Incident_cell;
|
||||
typedef boost::unordered_map<Facet_vvv, std::vector<Incident_cell> > Incident_cells_map;
|
||||
|
||||
bool success = true;
|
||||
|
||||
// the opposite vertex of f in c is i
|
||||
Facet_vvv f = make_ordered_vertex_array(c->vertex((i + 1) % 4),
|
||||
Facet_vvv f = CGAL::SMDS_3::make_ordered_vertex_array(c->vertex((i + 1) % 4),
|
||||
c->vertex((i + 2) % 4),
|
||||
c->vertex((i + 3) % 4));
|
||||
CGAL_precondition(f[0] != f[1] && f[1] != f[2]);
|
||||
|
|
@ -94,11 +97,12 @@ bool add_facet_to_incident_cells_map(const typename Tr::Cell_handle c, int i,
|
|||
{
|
||||
if(verbose)
|
||||
std::cout << "Error in add_facet_to_incident_cells_map" << std::endl;
|
||||
return false;
|
||||
if(!allow_non_manifold)
|
||||
success = false;
|
||||
}
|
||||
is_insert_successful.first->second.push_back(e);
|
||||
}
|
||||
return true;
|
||||
return success;
|
||||
}
|
||||
|
||||
template<class Tr, typename CellRange, typename SubdomainsRange, typename FacetPatchMap>
|
||||
|
|
@ -110,12 +114,14 @@ bool build_finite_cells(Tr& tr,
|
|||
std::vector<std::pair<typename Tr::Cell_handle, int> > >& incident_cells_map,
|
||||
const FacetPatchMap& border_facets,
|
||||
const bool verbose,
|
||||
bool replace_domain_0 = false)
|
||||
const bool replace_domain_0)
|
||||
{
|
||||
typedef typename Tr::Vertex_handle Vertex_handle;
|
||||
typedef typename Tr::Cell_handle Cell_handle;
|
||||
typedef typename Tr::Cell::Surface_patch_index Surface_patch_index;
|
||||
|
||||
bool success = true;
|
||||
|
||||
CGAL_assertion_code(
|
||||
typename Tr::Geom_traits::Construct_point_3 cp =
|
||||
tr.geom_traits().construct_point_3_object();
|
||||
|
|
@ -168,8 +174,9 @@ bool build_finite_cells(Tr& tr,
|
|||
// build the map used for adjacency later
|
||||
for(int j=0; j<4; ++j)
|
||||
{
|
||||
if(!add_facet_to_incident_cells_map<Tr>(c, j, incident_cells_map, verbose))
|
||||
return false;
|
||||
if(!CGAL::SMDS_3::add_facet_to_incident_cells_map<Tr>(c, j, incident_cells_map, verbose, false))
|
||||
//do not allow non-manifold in the finite cells case
|
||||
success = false;
|
||||
if(border_facets.size() != 0)
|
||||
{
|
||||
std::array<int,3> facet;
|
||||
|
|
@ -208,7 +215,7 @@ bool build_finite_cells(Tr& tr,
|
|||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return success;
|
||||
}
|
||||
|
||||
template<class Tr>
|
||||
|
|
@ -216,14 +223,15 @@ bool add_infinite_facets_to_incident_cells_map(typename Tr::Cell_handle c,
|
|||
int inf_vert_pos,
|
||||
boost::unordered_map<std::array<typename Tr::Vertex_handle, 3>,
|
||||
std::vector<std::pair<typename Tr::Cell_handle, int> > >& incident_cells_map,
|
||||
const bool verbose)
|
||||
const bool verbose,
|
||||
const bool allow_non_manifold)
|
||||
{
|
||||
int l = (inf_vert_pos + 1) % 4;
|
||||
bool b1 = add_facet_to_incident_cells_map<Tr>(c, l, incident_cells_map, verbose);
|
||||
bool b1 = CGAL::SMDS_3::add_facet_to_incident_cells_map<Tr>(c, l, incident_cells_map, verbose, allow_non_manifold);
|
||||
l = (inf_vert_pos + 2) % 4;
|
||||
bool b2 = add_facet_to_incident_cells_map<Tr>(c, l, incident_cells_map, verbose);
|
||||
bool b2 = CGAL::SMDS_3::add_facet_to_incident_cells_map<Tr>(c, l, incident_cells_map, verbose, allow_non_manifold);
|
||||
l = (inf_vert_pos + 3) % 4;
|
||||
bool b3 = add_facet_to_incident_cells_map<Tr>(c, l, incident_cells_map, verbose);
|
||||
bool b3 = CGAL::SMDS_3::add_facet_to_incident_cells_map<Tr>(c, l, incident_cells_map, verbose, allow_non_manifold);
|
||||
return b1 && b2 && b3;
|
||||
}
|
||||
|
||||
|
|
@ -231,7 +239,8 @@ template<class Tr>
|
|||
bool build_infinite_cells(Tr& tr,
|
||||
boost::unordered_map<std::array<typename Tr::Vertex_handle, 3>,
|
||||
std::vector<std::pair<typename Tr::Cell_handle, int> > >& incident_cells_map,
|
||||
const bool verbose)
|
||||
const bool verbose,
|
||||
const bool allow_non_manifold)
|
||||
{
|
||||
typedef typename Tr::Vertex_handle Vertex_handle;
|
||||
typedef typename Tr::Cell_handle Cell_handle;
|
||||
|
|
@ -239,6 +248,8 @@ bool build_infinite_cells(Tr& tr,
|
|||
typedef std::pair<Cell_handle, int> Incident_cell;
|
||||
typedef boost::unordered_map<Facet_vvv, std::vector<Incident_cell> > Incident_cells_map;
|
||||
|
||||
bool success = true;
|
||||
|
||||
std::vector<Cell_handle> infinite_cells;
|
||||
|
||||
// check the incident cells map for facets who only have one incident cell
|
||||
|
|
@ -289,7 +300,7 @@ bool build_infinite_cells(Tr& tr,
|
|||
{
|
||||
for (int i = 1; i < 4; ++i)
|
||||
{
|
||||
std::array<Vertex_handle, 3> vs = make_ordered_vertex_array(c->vertex((i + 1) % 4),
|
||||
std::array<Vertex_handle, 3> vs = CGAL::SMDS_3::make_ordered_vertex_array(c->vertex((i + 1) % 4),
|
||||
c->vertex((i + 2) % 4),
|
||||
c->vertex((i + 3) % 4));
|
||||
if (facets.find(vs) == facets.end())
|
||||
|
|
@ -299,42 +310,78 @@ bool build_infinite_cells(Tr& tr,
|
|||
}
|
||||
}
|
||||
for (auto fp : facets)
|
||||
CGAL_assertion(fp.second == 2);
|
||||
{
|
||||
if (fp.second != 2)
|
||||
{
|
||||
std::cout << "Warning : non manifold edge" << std::endl;
|
||||
std::cout << "fp.second = " << fp.second << std::endl;
|
||||
std::cout << fp.first[0]->point() << " "
|
||||
<< fp.first[1]->point() << " "
|
||||
<< fp.first[2]->point() << std::endl;
|
||||
success = false;
|
||||
}
|
||||
// CGAL_assertion(fp.second == 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
// add the facets to the incident cells map
|
||||
for (const Cell_handle& c : infinite_cells)
|
||||
if(!add_infinite_facets_to_incident_cells_map<Tr>(c, 0, incident_cells_map, verbose))
|
||||
return false;
|
||||
if(!CGAL::SMDS_3::add_infinite_facets_to_incident_cells_map<Tr>(c,
|
||||
0,
|
||||
incident_cells_map,
|
||||
verbose,
|
||||
allow_non_manifold))
|
||||
success = false;
|
||||
|
||||
return true;
|
||||
return success;
|
||||
}
|
||||
|
||||
template<typename Tr>
|
||||
bool has_infinite_vertex(const std::array<typename Tr::Vertex_handle, 3>& v,
|
||||
const Tr& tr)
|
||||
{
|
||||
for (auto vh : v)
|
||||
{
|
||||
if (tr.infinite_vertex() == vh)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class Tr>
|
||||
bool assign_neighbors(Tr& tr,
|
||||
const boost::unordered_map<std::array<typename Tr::Vertex_handle, 3>,
|
||||
std::vector<std::pair<typename Tr::Cell_handle, int> > >& incident_cells_map)
|
||||
std::vector<std::pair<typename Tr::Cell_handle, int> > >& incident_cells_map,
|
||||
const bool allow_non_manifold)
|
||||
{
|
||||
typedef typename Tr::Cell_handle Cell_handle;
|
||||
typedef std::pair<Cell_handle, int> Incident_cell;
|
||||
typedef boost::unordered_map<std::array<typename Tr::Vertex_handle, 3>,
|
||||
std::vector<Incident_cell> > Incident_cells_map;
|
||||
|
||||
bool success = true;
|
||||
|
||||
typename Incident_cells_map::const_iterator icit = incident_cells_map.begin();
|
||||
for(; icit!=incident_cells_map.end(); ++icit)
|
||||
{
|
||||
const std::vector<Incident_cell>& adjacent_cells = icit->second;
|
||||
if(adjacent_cells.size() != 2)
|
||||
return false;
|
||||
if (adjacent_cells.size() == 2)
|
||||
{
|
||||
Cell_handle c0 = adjacent_cells[0].first;
|
||||
int i0 = adjacent_cells[0].second;
|
||||
Cell_handle c1 = adjacent_cells[1].first;
|
||||
int i1 = adjacent_cells[1].second;
|
||||
|
||||
Cell_handle c0 = adjacent_cells[0].first;
|
||||
int i0 = adjacent_cells[0].second;
|
||||
Cell_handle c1 = adjacent_cells[1].first;
|
||||
int i1 = adjacent_cells[1].second;
|
||||
|
||||
tr.tds().set_adjacency(c0, i0, c1, i1);
|
||||
tr.tds().set_adjacency(c0, i0, c1, i1);
|
||||
}
|
||||
else if(allow_non_manifold)// if (adjacent_cells.size() == 4)
|
||||
{
|
||||
const auto& v = icit->first;
|
||||
CGAL_assertion(has_infinite_vertex(v, tr));
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return success;
|
||||
}
|
||||
|
||||
template<class Tr,
|
||||
|
|
@ -347,8 +394,9 @@ bool build_triangulation_impl(Tr& tr,
|
|||
const std::vector<typename Tr::Cell::Subdomain_index>& subdomains,
|
||||
const FacetPatchMap& border_facets,
|
||||
std::vector<typename Tr::Vertex_handle>& vertex_handle_vector,
|
||||
const bool verbose = false,
|
||||
bool replace_domain_0 = false)
|
||||
const bool verbose,// = false,
|
||||
const bool replace_domain_0,// = false,
|
||||
const bool allow_non_manifold) // = false
|
||||
{
|
||||
typedef typename Tr::Vertex_handle Vertex_handle;
|
||||
typedef typename Tr::Cell_handle Cell_handle;
|
||||
|
|
@ -358,6 +406,8 @@ bool build_triangulation_impl(Tr& tr,
|
|||
typedef std::pair<Cell_handle, int> Incident_cell;
|
||||
typedef boost::unordered_map<Facet_vvv, std::vector<Incident_cell> > Incident_cells_map;
|
||||
|
||||
bool success = true;
|
||||
|
||||
Incident_cells_map incident_cells_map;
|
||||
vertex_handle_vector.resize(points.size() + 1); // id to vertex_handle
|
||||
//index 0 is for infinite vertex
|
||||
|
|
@ -379,14 +429,23 @@ bool build_triangulation_impl(Tr& tr,
|
|||
}
|
||||
if (!finite_cells.empty())
|
||||
{
|
||||
if(!build_finite_cells<Tr>(tr, finite_cells, subdomains, vertex_handle_vector, incident_cells_map,
|
||||
border_facets, verbose, replace_domain_0))
|
||||
return false;
|
||||
if(!build_infinite_cells<Tr>(tr, incident_cells_map, verbose))
|
||||
return false;
|
||||
if (!CGAL::SMDS_3::build_finite_cells<Tr>(tr, finite_cells, subdomains, vertex_handle_vector, incident_cells_map,
|
||||
border_facets, verbose, replace_domain_0))
|
||||
{
|
||||
if(verbose) std::cout << "build_finite_cells went wrong" << std::endl;
|
||||
success = false;
|
||||
}
|
||||
if (!CGAL::SMDS_3::build_infinite_cells<Tr>(tr, incident_cells_map, verbose, allow_non_manifold))
|
||||
{
|
||||
if(verbose) std::cout << "build_infinite_cells went wrong" << std::endl;
|
||||
success = false;
|
||||
}
|
||||
tr.tds().set_dimension(3);
|
||||
if (!assign_neighbors<Tr>(tr, incident_cells_map))
|
||||
return false;
|
||||
if (!CGAL::SMDS_3::assign_neighbors<Tr>(tr, incident_cells_map, allow_non_manifold))
|
||||
{
|
||||
if(verbose) std::cout << "assign_neighbors went wrong" << std::endl;
|
||||
success = false;
|
||||
}
|
||||
if (verbose)
|
||||
{
|
||||
std::cout << "built triangulation : " << std::endl;
|
||||
|
|
@ -396,7 +455,7 @@ bool build_triangulation_impl(Tr& tr,
|
|||
if(verbose)
|
||||
std::cout << tr.number_of_vertices() << " vertices" << std::endl;
|
||||
|
||||
return true;// tr.tds().is_valid();
|
||||
return success;// tr.tds().is_valid();
|
||||
//TDS not valid when cells do not cover the convex hull of vertices
|
||||
}
|
||||
|
||||
|
|
@ -410,13 +469,15 @@ bool build_triangulation_one_subdomain(Tr& tr,
|
|||
const typename Tr::Cell::Subdomain_index& subdomain,
|
||||
const FacetPatchMap& border_facets,
|
||||
std::vector<typename Tr::Vertex_handle>& vertex_handle_vector,
|
||||
const bool verbose = false,
|
||||
bool replace_domain_0 = false)
|
||||
const bool verbose,// = false,
|
||||
const bool replace_domain_0,// = false
|
||||
const bool allow_non_manifold)// = false
|
||||
{
|
||||
std::vector<typename Tr::Cell::Subdomain_index> subdomains(finite_cells.size(), subdomain);
|
||||
return build_triangulation_impl(tr, points, finite_cells, subdomains,
|
||||
border_facets, vertex_handle_vector,
|
||||
verbose, replace_domain_0);
|
||||
verbose, replace_domain_0,
|
||||
allow_non_manifold);
|
||||
}
|
||||
|
||||
template<class Tr,
|
||||
|
|
@ -428,14 +489,16 @@ bool build_triangulation_one_subdomain(Tr& tr,
|
|||
const CellRange& finite_cells,
|
||||
const typename Tr::Cell::Subdomain_index& subdomain,
|
||||
const FacetPatchMap& border_facets,
|
||||
const bool verbose = false,
|
||||
bool replace_domain_0 = false)
|
||||
const bool verbose,// = false,
|
||||
const bool replace_domain_0,// = false
|
||||
const bool allow_non_manifold)//= false
|
||||
{
|
||||
std::vector<typename Tr::Cell::Subdomain_index> subdomains(finite_cells.size(), subdomain);
|
||||
std::vector<typename Tr::Vertex_handle> vertex_handle_vector;
|
||||
return build_triangulation_impl(tr, points, finite_cells, subdomains,
|
||||
border_facets, vertex_handle_vector,
|
||||
verbose, replace_domain_0);
|
||||
verbose, replace_domain_0,
|
||||
allow_non_manifold);
|
||||
}
|
||||
|
||||
template<class Tr,
|
||||
|
|
@ -448,22 +511,25 @@ bool build_triangulation_with_subdomains_range(Tr& tr,
|
|||
const CellRange& finite_cells,
|
||||
const SubdomainsRange& subdomains,
|
||||
const FacetPatchMap& border_facets,
|
||||
const bool verbose = false,
|
||||
bool replace_domain_0 = false)
|
||||
const bool verbose,// = false
|
||||
const bool replace_domain_0,// = false,
|
||||
const bool allow_non_manifold)
|
||||
{
|
||||
std::vector<typename Tr::Vertex_handle> vertex_handle_vector;
|
||||
std::vector<typename Tr::Cell::Subdomain_index> subdomains_vector(
|
||||
subdomains.begin(), subdomains.end());
|
||||
return build_triangulation_impl(tr, points, finite_cells, subdomains_vector, border_facets,
|
||||
vertex_handle_vector,
|
||||
verbose, replace_domain_0);
|
||||
verbose, replace_domain_0,
|
||||
allow_non_manifold);
|
||||
}
|
||||
|
||||
template<class Tr>
|
||||
bool build_triangulation_from_file(std::istream& is,
|
||||
Tr& tr,
|
||||
const bool verbose,
|
||||
bool replace_domain_0)
|
||||
const bool replace_domain_0,
|
||||
const bool allow_non_manifold)
|
||||
{
|
||||
using Point_3 = typename Tr::Point;
|
||||
using Subdomain_index = typename Tr::Cell::Subdomain_index;
|
||||
|
|
@ -575,7 +641,8 @@ bool build_triangulation_from_file(std::istream& is,
|
|||
return build_triangulation_with_subdomains_range(tr,
|
||||
points, finite_cells, subdomains, border_facets,
|
||||
verbose,
|
||||
replace_domain_0 && !dont_replace_domain_0);
|
||||
replace_domain_0 && !dont_replace_domain_0,
|
||||
allow_non_manifold);
|
||||
}
|
||||
|
||||
} // namespace SMDS_3
|
||||
|
|
|
|||
|
|
@ -92,7 +92,8 @@ namespace CGAL {
|
|||
}
|
||||
|
||||
typename Tr::Cell::Subdomain_index default_si(1);
|
||||
CGAL::SMDS_3::build_triangulation_one_subdomain(tr, points, finite_cells, default_si, border_facets);
|
||||
CGAL::SMDS_3::build_triangulation_one_subdomain(tr, points, finite_cells, default_si, border_facets,
|
||||
/*verbose = */false, /*replace_domain_0 = */false, /*allow_non_manifold =*/false);
|
||||
|
||||
CGAL_assertion(CGAL::SMDS_3::internal::is_convex(tr));
|
||||
|
||||
|
|
@ -144,6 +145,15 @@ namespace CGAL {
|
|||
* set to have `1` as `Subdomain_index`}
|
||||
* \cgalParamExtra{to avoid copies of large data sets, this parameter can be passed using `std::cref`}
|
||||
* \cgalParamNEnd
|
||||
*\cond SKIP_IN_MANUAL
|
||||
* \cgalParamNBegin{allow_non_manifold}
|
||||
* \cgalParamDescription{allows the construction of a triangulation with non-manifold edges
|
||||
* and non manifold vertices. The triangulation is invalid if this situation is met,
|
||||
* so it should be used only in advanced cases, and the triangulation will be hardly usable.}
|
||||
* \cgalParamType{bool}
|
||||
* \cgalParamDefault{false}
|
||||
* \cgalParamNEnd
|
||||
*\encond
|
||||
* \cgalNamedParamsEnd
|
||||
*
|
||||
* @returns the 3D triangulation built from parameters
|
||||
|
|
@ -188,8 +198,12 @@ namespace CGAL {
|
|||
const Subdomains_ref_type& subdomains = choose_parameter(
|
||||
get_parameter_reference(np, internal_np::subdomain_indices),
|
||||
1);
|
||||
const bool non_manifold = choose_parameter(
|
||||
get_parameter(np, internal_np::allow_non_manifold),
|
||||
false);
|
||||
|
||||
CGAL::SMDS_3::build_triangulation_with_subdomains_range(tr, points, tets, subdomains, facets);
|
||||
CGAL::SMDS_3::build_triangulation_with_subdomains_range(tr, points, tets, subdomains, facets,
|
||||
/*verbose = */false, /*replace_domain_0 = */false, non_manifold);
|
||||
|
||||
CGAL_assertion(CGAL::SMDS_3::internal::is_convex(tr));
|
||||
|
||||
|
|
|
|||
|
|
@ -216,6 +216,7 @@ CGAL_add_named_parameter(all_vertices_t, all_vertices, all_vertices)
|
|||
CGAL_add_named_parameter(all_cells_t, all_cells, all_cells)
|
||||
CGAL_add_named_parameter(rebind_labels_t, rebind_labels, rebind_labels)
|
||||
CGAL_add_named_parameter(show_patches_t, show_patches, show_patches)
|
||||
CGAL_add_named_parameter(allow_non_manifold_t, allow_non_manifold, allow_non_manifold)
|
||||
|
||||
// output parameters
|
||||
CGAL_add_named_parameter(face_proxy_map_t, face_proxy_map, face_proxy_map)
|
||||
|
|
|
|||
|
|
@ -111,7 +111,9 @@ public:
|
|||
std::map<Facet, typename C3t3::Surface_patch_index> border_facets;
|
||||
if (CGAL::SMDS_3::build_triangulation_impl(
|
||||
triangulation, points, finite_cells, subdomains, border_facets,
|
||||
new_vertices /*, verbose*/))
|
||||
new_vertices, /*verbose*/ false,
|
||||
/*replace_domain_0*/ false,
|
||||
/*allow_non_manifold*/false))
|
||||
{
|
||||
CGAL_assertion(triangulation.tds().is_valid());
|
||||
CGAL_assertion(triangulation.infinite_vertex() == new_vertices[0]);
|
||||
|
|
|
|||
Loading…
Reference in New Issue