mirror of https://github.com/CGAL/cgal
Merge pull request #3073 from MaelRL/Mesh_3-Add_add_corner-GF
Mesh_3: Add `add_corner()` and similar corner-adding functions
This commit is contained in:
commit
46bf950f2d
|
|
@ -74,6 +74,7 @@ public:
|
||||||
typedef typename CGAL::Default::Get<AABBTreeTemplate, AABB_tree>::type Tree;
|
typedef typename CGAL::Default::Get<AABBTreeTemplate, AABB_tree>::type Tree;
|
||||||
|
|
||||||
typedef typename MeshDomain::Index Index;
|
typedef typename MeshDomain::Index Index;
|
||||||
|
typedef typename MeshDomain::Corner_index Corner_index;
|
||||||
typedef typename MeshDomain::Subdomain_index Subdomain_index;
|
typedef typename MeshDomain::Subdomain_index Subdomain_index;
|
||||||
typedef typename MeshDomain::Surface_patch_index Surface_patch_index;
|
typedef typename MeshDomain::Surface_patch_index Surface_patch_index;
|
||||||
|
|
||||||
|
|
@ -231,8 +232,8 @@ public:
|
||||||
else if (dim == 0)
|
else if (dim == 0)
|
||||||
{
|
{
|
||||||
#ifdef CGAL_MESH_3_EXPERIMENTAL_USE_PATCHES_IDS
|
#ifdef CGAL_MESH_3_EXPERIMENTAL_USE_PATCHES_IDS
|
||||||
const Patches_ids& ids =
|
const Corner_index cid = m_domain.corner_index(index);
|
||||||
(m_domain.corners_incidences_map().find(p)->second);
|
const Patches_ids& ids = m_domain.corners_incidences_map().find(cid)->second;
|
||||||
|
|
||||||
if (m_domain_is_a_box && ids.size() == 3)
|
if (m_domain_is_a_box && ids.size() == 3)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -623,6 +623,28 @@ of the base class.
|
||||||
|
|
||||||
/// @cond DEVELOPERS
|
/// @cond DEVELOPERS
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
/// Add a 0-dimensional feature in the domain.
|
||||||
|
Corner_index add_corner(const Point_3& p);
|
||||||
|
|
||||||
|
/// Overloads where the last parameter \c out is not `CGAL::Emptyset_iterator()`.
|
||||||
|
template <typename InputIterator, typename IndicesOutputIterator>
|
||||||
|
IndicesOutputIterator
|
||||||
|
add_corners(InputIterator first, InputIterator end,
|
||||||
|
IndicesOutputIterator out /*= CGAL::Emptyset_iterator()*/);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Add 0-dimensional features in the domain. The value type of `InputIterator` must
|
||||||
|
be `Point_3`.
|
||||||
|
*/
|
||||||
|
template <typename InputIterator>
|
||||||
|
void
|
||||||
|
add_corners(InputIterator first, InputIterator end)
|
||||||
|
{ add_corners(first, end, CGAL::Emptyset_iterator()); }
|
||||||
|
|
||||||
|
Corner_index register_corner(const Point_3& p, const Curve_index& index);
|
||||||
|
Corner_index add_corner_with_context(const Point_3& p, const Surface_patch_index& index);
|
||||||
|
|
||||||
/// Overloads where the last parameter \c out is not
|
/// Overloads where the last parameter \c out is not
|
||||||
/// `CGAL::Emptyset_iterator()`.
|
/// `CGAL::Emptyset_iterator()`.
|
||||||
template <typename InputIterator, typename IndicesOutputIterator>
|
template <typename InputIterator, typename IndicesOutputIterator>
|
||||||
|
|
@ -808,7 +830,6 @@ of the base class.
|
||||||
Curve_index insert_edge(InputIterator first, InputIterator end);
|
Curve_index insert_edge(InputIterator first, InputIterator end);
|
||||||
/// @endcond
|
/// @endcond
|
||||||
private:
|
private:
|
||||||
void register_corner(const Point_3& p, const Curve_index& index);
|
|
||||||
void compute_corners_incidences();
|
void compute_corners_incidences();
|
||||||
|
|
||||||
/// Returns Index associated to p (p must be the coordinates of a corner
|
/// Returns Index associated to p (p must be the coordinates of a corner
|
||||||
|
|
@ -843,17 +864,14 @@ private:
|
||||||
public:
|
public:
|
||||||
/// @cond DEVELOPERS
|
/// @cond DEVELOPERS
|
||||||
typedef CGAL::AABB_tree<AABB_curves_traits> Curves_AABB_tree;
|
typedef CGAL::AABB_tree<AABB_curves_traits> Curves_AABB_tree;
|
||||||
typedef std::set<Surface_patch_index> Set_of_patch_ids;
|
|
||||||
typedef std::map<Point_3, Set_of_patch_ids> Corners_incidence_map;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Corners_incidence_map corners_incidence_map_;
|
|
||||||
mutable Curves_AABB_tree curves_aabb_tree_;
|
mutable Curves_AABB_tree curves_aabb_tree_;
|
||||||
mutable bool curves_aabb_tree_is_built;
|
mutable bool curves_aabb_tree_is_built;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const Corners_incidence_map& corners_incidences_map() const
|
const Corners_incidences& corners_incidences_map() const
|
||||||
{ return corners_incidence_map_; }
|
{ return corners_incidences_; }
|
||||||
|
|
||||||
const Curves_AABB_tree& curves_aabb_tree() const {
|
const Curves_AABB_tree& curves_aabb_tree() const {
|
||||||
if(!curves_aabb_tree_is_built) build_curves_aabb_tree();
|
if(!curves_aabb_tree_is_built) build_curves_aabb_tree();
|
||||||
|
|
@ -1013,6 +1031,67 @@ construct_point_on_curve(const Point_3& starting_point,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @cond DEVELOPERS
|
||||||
|
template <class MD_>
|
||||||
|
typename Mesh_domain_with_polyline_features_3<MD_>::Corner_index
|
||||||
|
Mesh_domain_with_polyline_features_3<MD_>::
|
||||||
|
add_corner(const Point_3& p)
|
||||||
|
{
|
||||||
|
typename Corners::iterator cit = corners_.lower_bound(p);
|
||||||
|
|
||||||
|
// If the corner already exists, return its assigned Corner_index...
|
||||||
|
if(cit != corners_.end() && !(corners_.key_comp()(p, cit->first)))
|
||||||
|
return cit->second;
|
||||||
|
|
||||||
|
// ... otherwise, insert it!
|
||||||
|
const Corner_index index = current_corner_index_++;
|
||||||
|
corners_.insert(cit, std::make_pair(p, index));
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class MD_>
|
||||||
|
template <typename InputIterator, typename IndicesOutputIterator>
|
||||||
|
IndicesOutputIterator
|
||||||
|
Mesh_domain_with_polyline_features_3<MD_>::
|
||||||
|
add_corners(InputIterator first, InputIterator end,
|
||||||
|
IndicesOutputIterator indices_out)
|
||||||
|
{
|
||||||
|
while ( first != end )
|
||||||
|
*indices_out++ = add_corner(*first++);
|
||||||
|
|
||||||
|
return indices_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class MD_>
|
||||||
|
typename Mesh_domain_with_polyline_features_3<MD_>::Corner_index
|
||||||
|
Mesh_domain_with_polyline_features_3<MD_>::
|
||||||
|
register_corner(const Point_3& p, const Curve_index& curve_index)
|
||||||
|
{
|
||||||
|
// 'add_corner' will itself seek if 'p' is already a corner, and, in that case,
|
||||||
|
// return the Corner_index that has been assigned to this position.
|
||||||
|
Corner_index index = add_corner(p);
|
||||||
|
corners_tmp_incidences_[index].insert(curve_index);
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class MD_>
|
||||||
|
typename Mesh_domain_with_polyline_features_3<MD_>::Corner_index
|
||||||
|
Mesh_domain_with_polyline_features_3<MD_>::
|
||||||
|
add_corner_with_context(const Point_3& p, const Surface_patch_index& surface_patch_index)
|
||||||
|
{
|
||||||
|
Corner_index index = add_corner(p);
|
||||||
|
|
||||||
|
Surface_patch_index_set& incidences = corners_incidences_[index];
|
||||||
|
incidences.insert(surface_patch_index);
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
/// @endcond
|
||||||
|
|
||||||
|
|
||||||
template <class MD_>
|
template <class MD_>
|
||||||
template <typename InputIterator, typename IndicesOutputIterator>
|
template <typename InputIterator, typename IndicesOutputIterator>
|
||||||
|
|
@ -1080,21 +1159,12 @@ add_features_and_incidences(InputIterator first, InputIterator end,
|
||||||
polyline = get(polyline_pmap, *first);
|
polyline = get(polyline_pmap, *first);
|
||||||
const typename boost::property_traits<IncidentPatchesIndicesPMap>::reference
|
const typename boost::property_traits<IncidentPatchesIndicesPMap>::reference
|
||||||
patches_ids = get(inc_patches_ind_pmap, *first);
|
patches_ids = get(inc_patches_ind_pmap, *first);
|
||||||
const typename Gt::Point_3& p1 = *polyline.begin();
|
|
||||||
const typename Gt::Point_3& p2 = *boost::prior(polyline.end());
|
Curve_index curve_id = insert_edge(polyline.begin(), polyline.end());
|
||||||
Set_of_patch_ids& ids_p1 = corners_incidence_map_[p1];
|
|
||||||
std::copy(patches_ids.begin(),
|
|
||||||
patches_ids.end(),
|
|
||||||
std::inserter(ids_p1, ids_p1.begin()));
|
|
||||||
Set_of_patch_ids& ids_p2 = corners_incidence_map_[p2];
|
|
||||||
std::copy(patches_ids.begin(),
|
|
||||||
patches_ids.end(),
|
|
||||||
std::inserter(ids_p2, ids_p2.begin()));
|
|
||||||
Curve_index curve_id =
|
|
||||||
insert_edge(polyline.begin(), polyline.end());
|
|
||||||
edges_incidences_[curve_id].insert(patches_ids.begin(), patches_ids.end());
|
edges_incidences_[curve_id].insert(patches_ids.begin(), patches_ids.end());
|
||||||
*indices_out++ = curve_id;
|
*indices_out++ = curve_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
compute_corners_incidences();
|
compute_corners_incidences();
|
||||||
return indices_out;
|
return indices_out;
|
||||||
}
|
}
|
||||||
|
|
@ -1172,7 +1242,8 @@ get_incidences(Curve_index id,
|
||||||
{
|
{
|
||||||
typename Edges_incidences::const_iterator it = edges_incidences_.find(id);
|
typename Edges_incidences::const_iterator it = edges_incidences_.find(id);
|
||||||
|
|
||||||
if(it == edges_incidences_.end()) return indices_out;
|
if(it == edges_incidences_.end())
|
||||||
|
return indices_out;
|
||||||
|
|
||||||
const Surface_patch_index_set& incidences = it->second;
|
const Surface_patch_index_set& incidences = it->second;
|
||||||
|
|
||||||
|
|
@ -1187,6 +1258,9 @@ get_corner_incidences(Corner_index id,
|
||||||
IndicesOutputIterator indices_out) const
|
IndicesOutputIterator indices_out) const
|
||||||
{
|
{
|
||||||
typename Corners_incidences::const_iterator it = corners_incidences_.find(id);
|
typename Corners_incidences::const_iterator it = corners_incidences_.find(id);
|
||||||
|
if(it == corners_incidences_.end())
|
||||||
|
return indices_out;
|
||||||
|
|
||||||
const Surface_patch_index_set& incidences = it->second;
|
const Surface_patch_index_set& incidences = it->second;
|
||||||
return std::copy(incidences.begin(), incidences.end(), indices_out);
|
return std::copy(incidences.begin(), incidences.end(), indices_out);
|
||||||
}
|
}
|
||||||
|
|
@ -1198,8 +1272,10 @@ Mesh_domain_with_polyline_features_3<MD_>::
|
||||||
get_corner_incident_curves(Corner_index id,
|
get_corner_incident_curves(Corner_index id,
|
||||||
IndicesOutputIterator indices_out) const
|
IndicesOutputIterator indices_out) const
|
||||||
{
|
{
|
||||||
typename Corners_tmp_incidences::const_iterator it =
|
typename Corners_tmp_incidences::const_iterator it = corners_tmp_incidences_.find(id);
|
||||||
corners_tmp_incidences_.find(id);
|
if(it == corners_tmp_incidences_.end())
|
||||||
|
return indices_out;
|
||||||
|
|
||||||
const std::set<Curve_index>& incidences = it->second;
|
const std::set<Curve_index>& incidences = it->second;
|
||||||
return std::copy(incidences.begin(), incidences.end(), indices_out);
|
return std::copy(incidences.begin(), incidences.end(), indices_out);
|
||||||
}
|
}
|
||||||
|
|
@ -1323,7 +1399,6 @@ compute_corners_incidences()
|
||||||
}
|
}
|
||||||
|
|
||||||
Surface_patch_index_set& incidences = corners_incidences_[id];
|
Surface_patch_index_set& incidences = corners_incidences_[id];
|
||||||
// That should be an empty set.
|
|
||||||
|
|
||||||
BOOST_FOREACH(Curve_index curve_index, corner_tmp_incidences)
|
BOOST_FOREACH(Curve_index curve_index, corner_tmp_incidences)
|
||||||
{
|
{
|
||||||
|
|
@ -1347,34 +1422,11 @@ Mesh_domain_with_polyline_features_3<MD_>::
|
||||||
get_incidences(Curve_index id) const
|
get_incidences(Curve_index id) const
|
||||||
{
|
{
|
||||||
typename Edges_incidences::const_iterator it = edges_incidences_.find(id);
|
typename Edges_incidences::const_iterator it = edges_incidences_.find(id);
|
||||||
|
CGAL_assertion(it != edges_incidences_.end());
|
||||||
|
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
/// @endcond
|
|
||||||
|
|
||||||
template <class MD_>
|
|
||||||
void
|
|
||||||
Mesh_domain_with_polyline_features_3<MD_>::
|
|
||||||
register_corner(const Point_3& p, const Curve_index& curve_index)
|
|
||||||
{
|
|
||||||
|
|
||||||
typename Corners::iterator cit = corners_.lower_bound(p);
|
|
||||||
|
|
||||||
// If the corner already exists, returns...
|
|
||||||
if(cit != corners_.end() && !(corners_.key_comp()(p, cit->first))) {
|
|
||||||
corners_tmp_incidences_[cit->second].insert(curve_index);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ...else insert it!
|
|
||||||
|
|
||||||
const Corner_index index = current_corner_index_;
|
|
||||||
++current_corner_index_;
|
|
||||||
|
|
||||||
corners_.insert(cit, std::make_pair(p, index));
|
|
||||||
corners_tmp_incidences_[index].insert(curve_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @cond DEVELOPERS
|
|
||||||
template <class MD_>
|
template <class MD_>
|
||||||
template <typename InputIterator>
|
template <typename InputIterator>
|
||||||
typename Mesh_domain_with_polyline_features_3<MD_>::Curve_index
|
typename Mesh_domain_with_polyline_features_3<MD_>::Curve_index
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ class Domain_with_polyline_tester
|
||||||
|
|
||||||
typedef Mesh_domain::Corner_index Ci;
|
typedef Mesh_domain::Corner_index Ci;
|
||||||
typedef Mesh_domain::Curve_index Csi;
|
typedef Mesh_domain::Curve_index Csi;
|
||||||
|
typedef Mesh_domain::Surface_patch_index Spi;
|
||||||
typedef Mesh_domain::Index Index;
|
typedef Mesh_domain::Index Index;
|
||||||
|
|
||||||
typedef std::vector<std::pair<Ci, Point> > Corners_vector;
|
typedef std::vector<std::pair<Ci, Point> > Corners_vector;
|
||||||
|
|
@ -65,6 +66,21 @@ public:
|
||||||
: p1_(1,0,0), p2_(1,1,0), p3_(1,2,0.1), p4_(0.9, 0.9, 1)
|
: p1_(1,0,0), p2_(1,1,0), p3_(1,2,0.1), p4_(0.9, 0.9, 1)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
void build_corners()
|
||||||
|
{
|
||||||
|
domain_.add_corner(p1_);
|
||||||
|
|
||||||
|
std::vector<Point> corners;
|
||||||
|
corners.push_back(p2_);
|
||||||
|
domain_.add_corners(corners.begin(), corners.end());
|
||||||
|
|
||||||
|
Csi dummy_curve_index = 12;
|
||||||
|
domain_.register_corner(p3_, dummy_curve_index);
|
||||||
|
|
||||||
|
Spi dummy_surface_patch_index = 21;
|
||||||
|
domain_.add_corner_with_context(p4_, dummy_surface_patch_index);
|
||||||
|
}
|
||||||
|
|
||||||
void build_curve()
|
void build_curve()
|
||||||
{
|
{
|
||||||
Polylines polylines (1);
|
Polylines polylines (1);
|
||||||
|
|
@ -91,6 +107,34 @@ public:
|
||||||
domain_.add_features(polylines.begin(),polylines.end());
|
domain_.add_features(polylines.begin(),polylines.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_corners() const
|
||||||
|
{
|
||||||
|
Corners_vector corners;
|
||||||
|
domain_.get_corners(std::back_inserter(corners));
|
||||||
|
assert(corners.size() == 4);
|
||||||
|
|
||||||
|
Corners_vector::const_iterator cit = corners.begin(), end = corners.end();
|
||||||
|
for(; cit!=end; ++cit)
|
||||||
|
{
|
||||||
|
if(cit->second == p3_)
|
||||||
|
{
|
||||||
|
std::vector<Csi> incident_curves;
|
||||||
|
domain_.get_corner_incident_curves(cit->first, std::back_inserter(incident_curves));
|
||||||
|
assert(incident_curves.size() == 1 && incident_curves.front() == 12);
|
||||||
|
}
|
||||||
|
else if(cit->second == p4_)
|
||||||
|
{
|
||||||
|
std::vector<Spi> incident_surface_patchs;
|
||||||
|
domain_.get_corner_incidences(cit->first, std::back_inserter(incident_surface_patchs));
|
||||||
|
assert(incident_surface_patchs.size() == 1 && incident_surface_patchs.front() == 21);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(cit->second == p1_ || cit->second == p2_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void test_curve_corners() const
|
void test_curve_corners() const
|
||||||
{
|
{
|
||||||
Corners_vector corners;
|
Corners_vector corners;
|
||||||
|
|
@ -192,6 +236,11 @@ private:
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
std::cout << "Test corners" << std::endl;
|
||||||
|
Domain_with_polyline_tester domain_corner_tester;
|
||||||
|
domain_corner_tester.build_corners();
|
||||||
|
domain_corner_tester.test_corners();
|
||||||
|
|
||||||
std::cout << "Test curve segments" << std::endl;
|
std::cout << "Test curve segments" << std::endl;
|
||||||
Domain_with_polyline_tester domain_tester;
|
Domain_with_polyline_tester domain_tester;
|
||||||
domain_tester.build_curve();
|
domain_tester.build_curve();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue