mirror of https://github.com/CGAL/cgal
improve concept
This commit is contained in:
parent
730bbba98b
commit
37fb95b5cd
|
|
@ -16,6 +16,7 @@ class PMPSizingField{
|
|||
public:
|
||||
|
||||
/// @name Types
|
||||
/// These types are used for the documentation of the functions of the concept and not needed implementation wise.
|
||||
/// @{
|
||||
|
||||
/// Vertex descriptor type
|
||||
|
|
@ -38,27 +39,29 @@ typedef unspecified_type FT;
|
|||
/// @name Functions
|
||||
/// @{
|
||||
|
||||
/// a function that returns the sizing value at `v`.
|
||||
FT at(const vertex_descriptor v) const;
|
||||
/// returns the sizing value at `v` (used during tangential relaxation).
|
||||
FT at(const vertex_descriptor v, const PolygonMesh& pmesh) const;
|
||||
|
||||
/// a function controlling edge split and edge collapse,
|
||||
/// returning the ratio of the current edge length and the local target edge length between
|
||||
/// the points of `va` and `vb` in case the current edge is too long, and `std::nullopt` otherwise.
|
||||
/// returns the ratio of the current edge squared length and the local target edge squared length between
|
||||
/// the points of `va` and `vb` in case the current edge is too long, and `std::nullopt` otherwise
|
||||
/// (used for triggering edge splits and preventing some edge collapses).
|
||||
std::optional<FT> is_too_long(const vertex_descriptor va,
|
||||
const vertex_descriptor vb) const;
|
||||
const vertex_descriptor vb,
|
||||
const PolygonMesh& pmesh) const;
|
||||
|
||||
/// a function controlling edge collapse by returning the ratio of the squared length of `h` and the
|
||||
/// local target edge length if it is too short, and `std::nullopt` otherwise.
|
||||
/// returns the ratio of the squared length of `h` and the
|
||||
/// local target edge squared length if it is too short, and `std::nullopt` otherwise
|
||||
/// (used for triggering edge collapses).
|
||||
std::optional<FT> is_too_short(const halfedge_descriptor h,
|
||||
const PolygonMesh& pmesh) const;
|
||||
|
||||
/// a function returning the location of the split point of the edge of `h`.
|
||||
/// returns the position of the new vertex created when splitting the edge of `h`.
|
||||
Point_3 split_placement(const halfedge_descriptor h,
|
||||
const PolygonMesh& pmesh) const;
|
||||
|
||||
/// a function that updates the sizing field value at the vertex `v`.
|
||||
void update(const vertex_descriptor v,
|
||||
const PolygonMesh& pmesh);
|
||||
/// function called after the addition of the split vertex `v` in `pmesh`.
|
||||
void register_split_vertex(const vertex_descriptor v,
|
||||
const PolygonMesh& pmesh);
|
||||
|
||||
/// @}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,14 +19,12 @@ struct My_sizing_field
|
|||
{
|
||||
double min_size, max_size;
|
||||
double ymin, ymax;
|
||||
const Mesh& mesh;
|
||||
|
||||
My_sizing_field(double min_size, double max_size, double ymin, double ymax, const Mesh& mesh)
|
||||
My_sizing_field(double min_size, double max_size, double ymin, double ymax)
|
||||
: min_size(min_size)
|
||||
, max_size(max_size)
|
||||
, ymin(ymin)
|
||||
, ymax(ymax)
|
||||
, mesh(mesh)
|
||||
{}
|
||||
|
||||
double at(K::Point_3 p) const
|
||||
|
|
@ -34,10 +32,11 @@ struct My_sizing_field
|
|||
double y=p.y();
|
||||
return CGAL::square( (y-ymin)/(ymax-ymin) * (min_size - max_size) + max_size );
|
||||
}
|
||||
double at(const Mesh::Vertex_index v) const { return at(mesh.point(v)); }
|
||||
double at(const Mesh::Vertex_index v, const Mesh& mesh) const { return at(mesh.point(v)); }
|
||||
|
||||
std::optional<double> is_too_long(const Mesh::Vertex_index va,
|
||||
const Mesh::Vertex_index vb) const
|
||||
const Mesh::Vertex_index vb,
|
||||
const Mesh& mesh) const
|
||||
{
|
||||
// TODO: no mesh as parameters?
|
||||
K::Point_3 mp = CGAL::midpoint(mesh.point(va), mesh.point(vb));
|
||||
|
|
@ -49,7 +48,7 @@ struct My_sizing_field
|
|||
}
|
||||
|
||||
std::optional<double> is_too_short(const Mesh::Halfedge_index h,
|
||||
const Mesh&) const
|
||||
const Mesh& mesh) const
|
||||
{
|
||||
K::Point_3 mp = CGAL::midpoint(mesh.point(source(h, mesh)), mesh.point(target(h, mesh)));
|
||||
double sql_at = at(mp);
|
||||
|
|
@ -60,12 +59,12 @@ struct My_sizing_field
|
|||
}
|
||||
|
||||
K::Point_3 split_placement(const Mesh::Halfedge_index h,
|
||||
const Mesh&) const
|
||||
const Mesh& mesh) const
|
||||
{
|
||||
return CGAL::midpoint(mesh.point(source(h, mesh)), mesh.point(target(h, mesh)));
|
||||
}
|
||||
|
||||
void update(const Mesh::Vertex_index, const Mesh&) {}
|
||||
void register_split_vertex(const Mesh::Vertex_index, const Mesh&) {}
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -83,7 +82,7 @@ int main(int argc, char* argv[])
|
|||
<< " (" << num_faces(mesh) << " faces)..." << std::endl;
|
||||
|
||||
CGAL::Bbox_3 bb = PMP::bbox(mesh);
|
||||
My_sizing_field sizing_field(0.1, 30, bb.ymin(), bb.ymax(), mesh);
|
||||
My_sizing_field sizing_field(0.1, 30, bb.ymin(), bb.ymax());
|
||||
unsigned int nb_iter = 5;
|
||||
|
||||
PMP::isotropic_remeshing(
|
||||
|
|
|
|||
|
|
@ -213,13 +213,13 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
FT at(const vertex_descriptor v) const
|
||||
FT at(const vertex_descriptor v, const PolygonMesh& /* pmesh */) const
|
||||
{
|
||||
CGAL_assertion(get(m_vertex_sizing_map, v));
|
||||
return get(m_vertex_sizing_map, v);
|
||||
}
|
||||
|
||||
std::optional<FT> is_too_long(const vertex_descriptor va, const vertex_descriptor vb) const
|
||||
std::optional<FT> is_too_long(const vertex_descriptor va, const vertex_descriptor vb, const PolygonMesh& /* pmesh */) const
|
||||
{
|
||||
const FT sqlen = sqlength(va, vb);
|
||||
FT sqtarg_len = CGAL::square(4./3. * (CGAL::min)(get(m_vertex_sizing_map, va),
|
||||
|
|
@ -251,7 +251,7 @@ public:
|
|||
get(m_vpmap, source(h, pmesh)));
|
||||
}
|
||||
|
||||
void update(const vertex_descriptor v, const PolygonMesh& pmesh)
|
||||
void register_split_vertex(const vertex_descriptor v, const PolygonMesh& pmesh)
|
||||
{
|
||||
// calculating it as the average of two vertices on other ends
|
||||
// of halfedges as updating is done during an edge split
|
||||
|
|
|
|||
|
|
@ -102,12 +102,12 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
FT at(const vertex_descriptor /* v */) const
|
||||
FT at(const vertex_descriptor /* v */, const PolygonMesh& /* pmesh */) const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
std::optional<FT> is_too_long(const vertex_descriptor va, const vertex_descriptor vb) const
|
||||
std::optional<FT> is_too_long(const vertex_descriptor va, const vertex_descriptor vb, const PolygonMesh& /* pmesh */) const
|
||||
{
|
||||
const FT sqlen = sqlength(va, vb);
|
||||
if (sqlen > m_sq_long)
|
||||
|
|
@ -133,7 +133,7 @@ public:
|
|||
get(m_vpmap, source(h, pmesh)));
|
||||
}
|
||||
|
||||
void update(const vertex_descriptor /* v */, const PolygonMesh& /* pmesh */)
|
||||
void register_split_vertex(const vertex_descriptor /* v */, const PolygonMesh& /* pmesh */)
|
||||
{}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ namespace internal {
|
|||
get(ecmap, e) ||
|
||||
get(fpm, face(h,pmesh))!=get(fpm, face(opposite(h,pmesh),pmesh)) )
|
||||
{
|
||||
if (sizing.is_too_long(source(h, pmesh), target(h, pmesh)))
|
||||
if (sizing.is_too_long(source(h, pmesh), target(h, pmesh), pmesh))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -400,7 +400,7 @@ namespace internal {
|
|||
for(edge_descriptor e : edge_range)
|
||||
{
|
||||
const halfedge_descriptor he = halfedge(e, mesh_);
|
||||
std::optional<double> sqlen = sizing.is_too_long(source(he, mesh_), target(he, mesh_));
|
||||
std::optional<double> sqlen = sizing.is_too_long(source(he, mesh_), target(he, mesh_), mesh_);
|
||||
if(sqlen != std::nullopt)
|
||||
long_edges.emplace(he, sqlen.value());
|
||||
}
|
||||
|
|
@ -433,16 +433,16 @@ namespace internal {
|
|||
std::cout << " refinement point : " << refinement_point << std::endl;
|
||||
#endif
|
||||
//update sizing field with the new point
|
||||
sizing.update(vnew, mesh_);
|
||||
sizing.register_split_vertex(vnew, mesh_);
|
||||
|
||||
//check sub-edges
|
||||
//if it was more than twice the "long" threshold, insert them
|
||||
std::optional<double> sqlen_new = sizing.is_too_long(source(hnew, mesh_), target(hnew, mesh_));
|
||||
std::optional<double> sqlen_new = sizing.is_too_long(source(hnew, mesh_), target(hnew, mesh_), mesh_);
|
||||
if(sqlen_new != std::nullopt)
|
||||
long_edges.emplace(hnew, sqlen_new.value());
|
||||
|
||||
const halfedge_descriptor hnext = next(hnew, mesh_);
|
||||
sqlen_new = sizing.is_too_long(source(hnext, mesh_), target(hnext, mesh_));
|
||||
sqlen_new = sizing.is_too_long(source(hnext, mesh_), target(hnext, mesh_), mesh_);
|
||||
if (sqlen_new != std::nullopt)
|
||||
long_edges.emplace(hnext, sqlen_new.value());
|
||||
|
||||
|
|
@ -500,7 +500,7 @@ namespace internal {
|
|||
if (!is_split_allowed(e))
|
||||
continue;
|
||||
const halfedge_descriptor he = halfedge(e, mesh_);
|
||||
std::optional<double> sqlen = sizing.is_too_long(source(he, mesh_), target(he, mesh_));
|
||||
std::optional<double> sqlen = sizing.is_too_long(source(he, mesh_), target(he, mesh_), mesh_);
|
||||
if(sqlen != std::nullopt)
|
||||
long_edges.emplace(halfedge(e, mesh_), sqlen.value());
|
||||
}
|
||||
|
|
@ -550,16 +550,16 @@ namespace internal {
|
|||
halfedge_added(hnew_opp, status(opposite(he, mesh_)));
|
||||
|
||||
//update sizing field with the new point
|
||||
sizing.update(vnew, mesh_);
|
||||
sizing.register_split_vertex(vnew, mesh_);
|
||||
|
||||
//check sub-edges
|
||||
//if it was more than twice the "long" threshold, insert them
|
||||
std::optional<double> sqlen_new = sizing.is_too_long(source(hnew, mesh_), target(hnew, mesh_));
|
||||
std::optional<double> sqlen_new = sizing.is_too_long(source(hnew, mesh_), target(hnew, mesh_), mesh_);
|
||||
if(sqlen_new != std::nullopt)
|
||||
long_edges.emplace(hnew, sqlen_new.value());
|
||||
|
||||
const halfedge_descriptor hnext = next(hnew, mesh_);
|
||||
sqlen_new = sizing.is_too_long(source(hnext, mesh_), target(hnext, mesh_));
|
||||
sqlen_new = sizing.is_too_long(source(hnext, mesh_), target(hnext, mesh_), mesh_);
|
||||
if (sqlen_new != std::nullopt)
|
||||
long_edges.emplace(hnext, sqlen_new.value());
|
||||
|
||||
|
|
@ -580,7 +580,7 @@ namespace internal {
|
|||
|
||||
if (snew == PATCH)
|
||||
{
|
||||
std::optional<double> sql = sizing.is_too_long(source(hnew2, mesh_), target(hnew2, mesh_));
|
||||
std::optional<double> sql = sizing.is_too_long(source(hnew2, mesh_), target(hnew2, mesh_), mesh_);
|
||||
if(sql != std::nullopt)
|
||||
long_edges.emplace(hnew2, sql.value());
|
||||
}
|
||||
|
|
@ -603,7 +603,7 @@ namespace internal {
|
|||
|
||||
if (snew == PATCH)
|
||||
{
|
||||
std::optional<double> sql = sizing.is_too_long(source(hnew2, mesh_), target(hnew2, mesh_));
|
||||
std::optional<double> sql = sizing.is_too_long(source(hnew2, mesh_), target(hnew2, mesh_), mesh_);
|
||||
if (sql != std::nullopt)
|
||||
long_edges.emplace(hnew2, sql.value());
|
||||
}
|
||||
|
|
@ -747,7 +747,7 @@ namespace internal {
|
|||
for(halfedge_descriptor ha : halfedges_around_target(va, mesh_))
|
||||
{
|
||||
vertex_descriptor va_i = source(ha, mesh_);
|
||||
std::optional<double> sqha = sizing.is_too_long(vb, va_i);
|
||||
std::optional<double> sqha = sizing.is_too_long(vb, va_i, mesh_);
|
||||
if (sqha != std::nullopt)
|
||||
{
|
||||
collapse_ok = false;
|
||||
|
|
|
|||
|
|
@ -60,13 +60,14 @@ public:
|
|||
typedef typename K::FT FT;
|
||||
|
||||
public:
|
||||
virtual FT at(const vertex_descriptor v) const = 0;
|
||||
virtual FT at(const vertex_descriptor v, const PolygonMesh&) const = 0;
|
||||
virtual std::optional<FT> is_too_long(const vertex_descriptor va,
|
||||
const vertex_descriptor vb) const = 0;
|
||||
const vertex_descriptor vb,
|
||||
const PolygonMesh&) const = 0;
|
||||
virtual std::optional<FT> is_too_short(const halfedge_descriptor h,
|
||||
const PolygonMesh& pmesh) const = 0;
|
||||
virtual Point_3 split_placement(const halfedge_descriptor h, const PolygonMesh& pmesh) const = 0;
|
||||
virtual void update(const vertex_descriptor v, const PolygonMesh& pmesh) = 0;
|
||||
virtual void register_split_vertex(const vertex_descriptor v, const PolygonMesh& pmesh) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -288,9 +288,9 @@ void tangential_relaxation(const VertexRange& vertices,
|
|||
|
||||
const double tri_area = gt_area(get(vpm, v), get(vpm, v1), get(vpm, v2));
|
||||
const double face_weight = tri_area
|
||||
/ (1. / 3. * (sizing.at(v)
|
||||
+ sizing.at(v1)
|
||||
+ sizing.at(v2)));
|
||||
/ (1. / 3. * (sizing.at(v, tm)
|
||||
+ sizing.at(v1, tm)
|
||||
+ sizing.at(v2, tm)));
|
||||
weight += face_weight;
|
||||
|
||||
const Point_3 centroid = gt_centroid(get(vpm, v), get(vpm, v1), get(vpm, v2));
|
||||
|
|
|
|||
Loading…
Reference in New Issue