mirror of https://github.com/CGAL/cgal
Update
This commit is contained in:
parent
5907ec9a18
commit
a17c5b1eb2
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2017 GeometryFactory (France). All rights reserved.
|
// Copyright (c) 2019 GeometryFactory (France). All rights reserved.
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org).
|
// This file is part of CGAL (www.cgal.org).
|
||||||
// You can redistribute it and/or modify it under the terms of the GNU
|
// You can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0+
|
// SPDX-License-Identifier: GPL-3.0+
|
||||||
//
|
//
|
||||||
// Author(s) : Andreas Fabri
|
// Author(s) : Maxime Gimeno
|
||||||
//
|
//
|
||||||
#ifndef CGAL_SURFACE_MESH_SIMPLIFICATION_POLICIES_EDGE_COLLAPSE_BOUNDED_DISTANCE_PLACEMENT_H
|
#ifndef CGAL_SURFACE_MESH_SIMPLIFICATION_POLICIES_EDGE_COLLAPSE_BOUNDED_DISTANCE_PLACEMENT_H
|
||||||
#define CGAL_SURFACE_MESH_SIMPLIFICATION_POLICIES_EDGE_COLLAPSE_BOUNDED_DISTANCE_PLACEMENT_H
|
#define CGAL_SURFACE_MESH_SIMPLIFICATION_POLICIES_EDGE_COLLAPSE_BOUNDED_DISTANCE_PLACEMENT_H
|
||||||
|
|
@ -29,7 +29,7 @@ namespace CGAL {
|
||||||
namespace Surface_mesh_simplification
|
namespace Surface_mesh_simplification
|
||||||
{
|
{
|
||||||
|
|
||||||
template<class Placement>
|
template<class Placement, class Tree>
|
||||||
class Bounded_distance_placement
|
class Bounded_distance_placement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -38,9 +38,10 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Bounded_distance_placement(const double sq_dist,
|
Bounded_distance_placement(const double dist,
|
||||||
|
const Tree& tree,
|
||||||
const Placement& placement = Placement() )
|
const Placement& placement = Placement() )
|
||||||
: mPlacement(placement), threshold_sq_dist(sq_dist)
|
: mPlacement(placement), tree(tree), threshold_dist(dist)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,25 +54,13 @@ public:
|
||||||
typedef typename CGAL::Kernel_traits< Point >::Kernel Kernel;
|
typedef typename CGAL::Kernel_traits< Point >::Kernel Kernel;
|
||||||
if(op){
|
if(op){
|
||||||
const Point* p = boost::get<Point>(&op);
|
const Point* p = boost::get<Point>(&op);
|
||||||
const typename Profile::Triangle_vector& triangles = aProfile.triangles();
|
|
||||||
typename Profile::Triangle_vector::const_iterator it = triangles.begin();
|
|
||||||
typename Profile::VertexPointMap ppmap = aProfile.vertex_point_map();
|
|
||||||
|
|
||||||
bool does_intersect = false;
|
|
||||||
CGAL::Sphere_3<Kernel> s(*p, threshold_sq_dist);
|
if(tree.do_intersect(CGAL::Sphere_3<Kernel>(*p, threshold_dist*threshold_dist))){
|
||||||
while(it!= triangles.end()){
|
return op;
|
||||||
typename Kernel::Triangle_3 t(get(ppmap, it->v0), get(ppmap, it->v1), get(ppmap, it->v2));
|
|
||||||
if(CGAL::do_intersect(t, s)){
|
|
||||||
does_intersect = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
++it;
|
|
||||||
}
|
|
||||||
if(!does_intersect)
|
|
||||||
{
|
|
||||||
return boost::none;
|
return boost::none;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,7 +68,8 @@ public:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Placement mPlacement ;
|
Placement mPlacement ;
|
||||||
double threshold_sq_dist;
|
const Tree& tree;
|
||||||
|
double threshold_dist;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,72 +15,79 @@
|
||||||
#include <CGAL/AABB_traits.h>
|
#include <CGAL/AABB_traits.h>
|
||||||
#include <CGAL/AABB_face_graph_triangle_primitive.h>
|
#include <CGAL/AABB_face_graph_triangle_primitive.h>
|
||||||
|
|
||||||
|
//bbox
|
||||||
|
#include <CGAL/Polygon_mesh_processing/bbox.h>
|
||||||
|
|
||||||
|
|
||||||
//Timer
|
//Timer
|
||||||
#include <CGAL/Timer.h>
|
//#include <CGAL/Timer.h>
|
||||||
//filter{
|
|
||||||
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Bounded_distance_placement.h>
|
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Bounded_distance_placement.h>
|
||||||
//} end filter
|
|
||||||
|
|
||||||
namespace SMS = CGAL::Surface_mesh_simplification ;
|
namespace SMS = CGAL::Surface_mesh_simplification ;
|
||||||
typedef CGAL::Simple_cartesian<double> Kernel;
|
typedef CGAL::Simple_cartesian<double> Kernel;
|
||||||
typedef CGAL::Surface_mesh<Kernel::Point_3> Surface;
|
typedef CGAL::Surface_mesh<Kernel::Point_3> Surface;
|
||||||
|
|
||||||
|
|
||||||
|
typedef CGAL::AABB_face_graph_triangle_primitive<Surface> Primitive;
|
||||||
|
typedef CGAL::AABB_traits<Kernel, Primitive> Traits;
|
||||||
|
typedef CGAL::AABB_tree<Traits> Tree;
|
||||||
|
|
||||||
|
|
||||||
int main( int argc, char** argv )
|
int main( int argc, char** argv )
|
||||||
{
|
{
|
||||||
Surface surface_mesh;
|
Surface ref_mesh;
|
||||||
std::ifstream is(argc > 1 ? argv[1] : "input.off");
|
std::ifstream is(argc > 1 ? argv[1] : "data/helmet.off");
|
||||||
is >> surface_mesh;
|
is >> ref_mesh;
|
||||||
// This is a stop predicate (defines when the algorithm terminates).
|
|
||||||
// In this example, the simplification stops when the number of undirected edges
|
|
||||||
// left in the surface mesh drops below the specified number (1000)
|
|
||||||
SMS::Count_stop_predicate<Surface> stop(num_halfedges(surface_mesh)/10);
|
|
||||||
|
|
||||||
typedef SMS::Bounded_distance_placement<SMS::LindstromTurk_placement<Surface> > Filtered_placement;
|
SMS::Count_stop_predicate<Surface> stop(num_halfedges(ref_mesh)/10);
|
||||||
|
|
||||||
|
typedef SMS::Bounded_distance_placement<SMS::LindstromTurk_placement<Surface>, Tree> Filtered_placement;
|
||||||
typedef SMS::LindstromTurk_placement<Surface> Placement;
|
typedef SMS::LindstromTurk_placement<Surface> Placement;
|
||||||
double placement1_time, placement2_time;
|
//double placement1_time, placement2_time, tree_time;
|
||||||
|
|
||||||
std::cout<<"input has "<<num_vertices(surface_mesh)<<" vertices."<<std::endl;
|
//std::cout<<"input has "<<num_vertices(ref_mesh)<<" vertices."<<std::endl;
|
||||||
double input_sq_dist=0.000000001;
|
CGAL::Iso_cuboid_3<Kernel> bbox(CGAL::Polygon_mesh_processing::bbox(ref_mesh));
|
||||||
std::cout<<"threshold squared distance = "<<input_sq_dist<<std::endl;
|
|
||||||
CGAL::Timer timer;
|
|
||||||
// This the actual call to the simplification algorithm.
|
|
||||||
// The surface mesh and stop conditions are mandatory arguments.
|
|
||||||
// The index maps are needed because the vertices and edges
|
|
||||||
// of this surface mesh lack an "id()" field.
|
|
||||||
Surface copy_mesh = surface_mesh;
|
|
||||||
Placement placement1;
|
|
||||||
Filtered_placement placement2(input_sq_dist, placement1);
|
|
||||||
timer.start();
|
|
||||||
|
|
||||||
SMS::edge_collapse( surface_mesh,
|
|
||||||
|
Kernel::Point_3 cmin = (bbox.min)();
|
||||||
|
Kernel::Point_3 cmax = (bbox.max)();
|
||||||
|
double diag = std::sqrt(CGAL::squared_distance(cmin,cmax));
|
||||||
|
|
||||||
|
Surface small_mesh = ref_mesh;
|
||||||
|
Surface big_mesh = ref_mesh;
|
||||||
|
Tree tree( faces(ref_mesh).first, faces(ref_mesh).second, ref_mesh);
|
||||||
|
|
||||||
|
Placement placement_ref;
|
||||||
|
Filtered_placement placement_small(0.00005*diag, tree, placement_ref);
|
||||||
|
Filtered_placement placement_big(50*diag, tree, placement_ref);
|
||||||
|
|
||||||
|
SMS::edge_collapse( small_mesh,
|
||||||
stop,
|
stop,
|
||||||
CGAL::parameters::get_cost (SMS::LindstromTurk_cost<Surface>())
|
CGAL::parameters::get_cost (SMS::LindstromTurk_cost<Surface>())
|
||||||
.get_placement(placement2)
|
.get_placement(placement_small)
|
||||||
);
|
);
|
||||||
timer.stop();
|
|
||||||
placement2_time=timer.time();
|
SMS::edge_collapse( big_mesh,
|
||||||
timer.reset();
|
|
||||||
timer.start();
|
|
||||||
SMS::edge_collapse( copy_mesh,
|
|
||||||
stop,
|
stop,
|
||||||
CGAL::parameters::get_cost (SMS::LindstromTurk_cost<Surface>())
|
CGAL::parameters::get_cost (SMS::LindstromTurk_cost<Surface>())
|
||||||
.get_placement(placement1)
|
.get_placement(placement_big)
|
||||||
);
|
);
|
||||||
timer.stop();
|
|
||||||
placement1_time=timer.time();
|
SMS::edge_collapse( ref_mesh,
|
||||||
surface_mesh.collect_garbage();
|
stop,
|
||||||
copy_mesh.collect_garbage();
|
CGAL::parameters::get_cost (SMS::LindstromTurk_cost<Surface>())
|
||||||
std::cout<<"Filtered placement time = "<<placement2_time<<"s."<<std::endl;
|
.get_placement(placement_ref)
|
||||||
std::cout<<" Not filtered placement took "<<placement1_time<<"s."<<std::endl;
|
);
|
||||||
std::cout<<"There are "<<num_vertices(surface_mesh)<<" vertices left when filtered and "<<num_vertices(copy_mesh)<<" when not filtered."<<std::endl;
|
|
||||||
std::ofstream os( "out_filtered.off" );
|
ref_mesh.collect_garbage();
|
||||||
os.precision(17);
|
small_mesh.collect_garbage();
|
||||||
os << surface_mesh;
|
big_mesh.collect_garbage();
|
||||||
os.close();
|
//std::cout<<"Filtered placement time = "<<placement2_time<<"s."<<std::endl;
|
||||||
os.open("out_clear.off");
|
//std::cout<<" Not filtered placement took "<<placement1_time<<"s."<<std::endl;
|
||||||
os << copy_mesh;
|
//std::cout<<"There are "<<num_vertices(surface_mesh)<<" vertices left when filtered and "<<num_vertices(copy_mesh)<<" when not filtered."<<std::endl;
|
||||||
os.close();
|
assert(num_vertices(big_mesh) == num_vertices(ref_mesh));
|
||||||
|
assert(num_vertices(small_mesh) != num_vertices(ref_mesh));
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue