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 MeshDomain::Index Index;
|
||||
typedef typename MeshDomain::Corner_index Corner_index;
|
||||
typedef typename MeshDomain::Subdomain_index Subdomain_index;
|
||||
typedef typename MeshDomain::Surface_patch_index Surface_patch_index;
|
||||
|
||||
|
|
@ -231,8 +232,8 @@ public:
|
|||
else if (dim == 0)
|
||||
{
|
||||
#ifdef CGAL_MESH_3_EXPERIMENTAL_USE_PATCHES_IDS
|
||||
const Patches_ids& ids =
|
||||
(m_domain.corners_incidences_map().find(p)->second);
|
||||
const Corner_index cid = m_domain.corner_index(index);
|
||||
const Patches_ids& ids = m_domain.corners_incidences_map().find(cid)->second;
|
||||
|
||||
if (m_domain_is_a_box && ids.size() == 3)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -623,6 +623,28 @@ of the base class.
|
|||
|
||||
/// @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
|
||||
/// `CGAL::Emptyset_iterator()`.
|
||||
template <typename InputIterator, typename IndicesOutputIterator>
|
||||
|
|
@ -808,7 +830,6 @@ of the base class.
|
|||
Curve_index insert_edge(InputIterator first, InputIterator end);
|
||||
/// @endcond
|
||||
private:
|
||||
void register_corner(const Point_3& p, const Curve_index& index);
|
||||
void compute_corners_incidences();
|
||||
|
||||
/// Returns Index associated to p (p must be the coordinates of a corner
|
||||
|
|
@ -843,17 +864,14 @@ private:
|
|||
public:
|
||||
/// @cond DEVELOPERS
|
||||
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:
|
||||
Corners_incidence_map corners_incidence_map_;
|
||||
mutable Curves_AABB_tree curves_aabb_tree_;
|
||||
mutable bool curves_aabb_tree_is_built;
|
||||
|
||||
public:
|
||||
const Corners_incidence_map& corners_incidences_map() const
|
||||
{ return corners_incidence_map_; }
|
||||
const Corners_incidences& corners_incidences_map() const
|
||||
{ return corners_incidences_; }
|
||||
|
||||
const Curves_AABB_tree& curves_aabb_tree() const {
|
||||
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 <typename InputIterator, typename IndicesOutputIterator>
|
||||
|
|
@ -1080,21 +1159,12 @@ add_features_and_incidences(InputIterator first, InputIterator end,
|
|||
polyline = get(polyline_pmap, *first);
|
||||
const typename boost::property_traits<IncidentPatchesIndicesPMap>::reference
|
||||
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());
|
||||
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());
|
||||
|
||||
Curve_index curve_id = insert_edge(polyline.begin(), polyline.end());
|
||||
edges_incidences_[curve_id].insert(patches_ids.begin(), patches_ids.end());
|
||||
*indices_out++ = curve_id;
|
||||
}
|
||||
|
||||
compute_corners_incidences();
|
||||
return indices_out;
|
||||
}
|
||||
|
|
@ -1172,7 +1242,8 @@ get_incidences(Curve_index 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;
|
||||
|
||||
|
|
@ -1187,6 +1258,9 @@ get_corner_incidences(Corner_index id,
|
|||
IndicesOutputIterator indices_out) const
|
||||
{
|
||||
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;
|
||||
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,
|
||||
IndicesOutputIterator indices_out) const
|
||||
{
|
||||
typename Corners_tmp_incidences::const_iterator it =
|
||||
corners_tmp_incidences_.find(id);
|
||||
typename Corners_tmp_incidences::const_iterator it = corners_tmp_incidences_.find(id);
|
||||
if(it == corners_tmp_incidences_.end())
|
||||
return indices_out;
|
||||
|
||||
const std::set<Curve_index>& incidences = it->second;
|
||||
return std::copy(incidences.begin(), incidences.end(), indices_out);
|
||||
}
|
||||
|
|
@ -1323,7 +1399,6 @@ compute_corners_incidences()
|
|||
}
|
||||
|
||||
Surface_patch_index_set& incidences = corners_incidences_[id];
|
||||
// That should be an empty set.
|
||||
|
||||
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
|
||||
{
|
||||
typename Edges_incidences::const_iterator it = edges_incidences_.find(id);
|
||||
CGAL_assertion(it != edges_incidences_.end());
|
||||
|
||||
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 <typename InputIterator>
|
||||
typename Mesh_domain_with_polyline_features_3<MD_>::Curve_index
|
||||
|
|
|
|||
|
|
@ -53,18 +53,34 @@ class Domain_with_polyline_tester
|
|||
|
||||
typedef Mesh_domain::Corner_index Ci;
|
||||
typedef Mesh_domain::Curve_index Csi;
|
||||
typedef Mesh_domain::Surface_patch_index Spi;
|
||||
typedef Mesh_domain::Index Index;
|
||||
|
||||
typedef std::vector<std::pair<Ci, Point> > Corners_vector;
|
||||
typedef std::pair<Point, Index> P_and_i;
|
||||
typedef CGAL::cpp11::tuple<Csi,P_and_i,P_and_i> Curve_tuple;
|
||||
typedef std::vector<Curve_tuple> Curves_vector;
|
||||
typedef std::vector<Curve_tuple> Curves_vector;
|
||||
|
||||
public:
|
||||
Domain_with_polyline_tester()
|
||||
: 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()
|
||||
{
|
||||
Polylines polylines (1);
|
||||
|
|
@ -90,7 +106,35 @@ public:
|
|||
|
||||
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
|
||||
{
|
||||
Corners_vector corners;
|
||||
|
|
@ -192,6 +236,11 @@ private:
|
|||
|
||||
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;
|
||||
Domain_with_polyline_tester domain_tester;
|
||||
domain_tester.build_curve();
|
||||
|
|
|
|||
Loading…
Reference in New Issue