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).
|
||||
// You can redistribute it and/or modify it under the terms of the GNU
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
// $Id$
|
||||
// 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
|
||||
#define CGAL_SURFACE_MESH_SIMPLIFICATION_POLICIES_EDGE_COLLAPSE_BOUNDED_DISTANCE_PLACEMENT_H
|
||||
|
|
@ -29,7 +29,7 @@ namespace CGAL {
|
|||
namespace Surface_mesh_simplification
|
||||
{
|
||||
|
||||
template<class Placement>
|
||||
template<class Placement, class Tree>
|
||||
class Bounded_distance_placement
|
||||
{
|
||||
public:
|
||||
|
|
@ -38,9 +38,10 @@ public:
|
|||
|
||||
public:
|
||||
|
||||
Bounded_distance_placement(const double sq_dist,
|
||||
Bounded_distance_placement(const double dist,
|
||||
const Tree& tree,
|
||||
const Placement& placement = Placement() )
|
||||
: mPlacement(placement), threshold_sq_dist(sq_dist)
|
||||
: mPlacement(placement), tree(tree), threshold_dist(dist)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -53,24 +54,12 @@ public:
|
|||
typedef typename CGAL::Kernel_traits< Point >::Kernel Kernel;
|
||||
if(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);
|
||||
while(it!= triangles.end()){
|
||||
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;
|
||||
|
||||
if(tree.do_intersect(CGAL::Sphere_3<Kernel>(*p, threshold_dist*threshold_dist))){
|
||||
return op;
|
||||
}
|
||||
return boost::none;
|
||||
}
|
||||
return op;
|
||||
}
|
||||
|
|
@ -79,7 +68,8 @@ public:
|
|||
private:
|
||||
|
||||
Placement mPlacement ;
|
||||
double threshold_sq_dist;
|
||||
const Tree& tree;
|
||||
double threshold_dist;
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,72 +15,79 @@
|
|||
#include <CGAL/AABB_traits.h>
|
||||
#include <CGAL/AABB_face_graph_triangle_primitive.h>
|
||||
|
||||
//bbox
|
||||
#include <CGAL/Polygon_mesh_processing/bbox.h>
|
||||
|
||||
|
||||
//Timer
|
||||
#include <CGAL/Timer.h>
|
||||
//filter{
|
||||
//#include <CGAL/Timer.h>
|
||||
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Bounded_distance_placement.h>
|
||||
//} end filter
|
||||
|
||||
namespace SMS = CGAL::Surface_mesh_simplification ;
|
||||
typedef CGAL::Simple_cartesian<double> Kernel;
|
||||
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 )
|
||||
{
|
||||
Surface surface_mesh;
|
||||
std::ifstream is(argc > 1 ? argv[1] : "input.off");
|
||||
is >> surface_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);
|
||||
Surface ref_mesh;
|
||||
std::ifstream is(argc > 1 ? argv[1] : "data/helmet.off");
|
||||
is >> ref_mesh;
|
||||
|
||||
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;
|
||||
double placement1_time, placement2_time;
|
||||
//double placement1_time, placement2_time, tree_time;
|
||||
|
||||
std::cout<<"input has "<<num_vertices(surface_mesh)<<" vertices."<<std::endl;
|
||||
double input_sq_dist=0.000000001;
|
||||
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();
|
||||
//std::cout<<"input has "<<num_vertices(ref_mesh)<<" vertices."<<std::endl;
|
||||
CGAL::Iso_cuboid_3<Kernel> bbox(CGAL::Polygon_mesh_processing::bbox(ref_mesh));
|
||||
|
||||
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,
|
||||
CGAL::parameters::get_cost (SMS::LindstromTurk_cost<Surface>())
|
||||
.get_placement(placement2)
|
||||
.get_placement(placement_small)
|
||||
);
|
||||
timer.stop();
|
||||
placement2_time=timer.time();
|
||||
timer.reset();
|
||||
timer.start();
|
||||
SMS::edge_collapse( copy_mesh,
|
||||
|
||||
SMS::edge_collapse( big_mesh,
|
||||
stop,
|
||||
CGAL::parameters::get_cost (SMS::LindstromTurk_cost<Surface>())
|
||||
.get_placement(placement1)
|
||||
.get_placement(placement_big)
|
||||
);
|
||||
timer.stop();
|
||||
placement1_time=timer.time();
|
||||
surface_mesh.collect_garbage();
|
||||
copy_mesh.collect_garbage();
|
||||
std::cout<<"Filtered placement time = "<<placement2_time<<"s."<<std::endl;
|
||||
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" );
|
||||
os.precision(17);
|
||||
os << surface_mesh;
|
||||
os.close();
|
||||
os.open("out_clear.off");
|
||||
os << copy_mesh;
|
||||
os.close();
|
||||
|
||||
SMS::edge_collapse( ref_mesh,
|
||||
stop,
|
||||
CGAL::parameters::get_cost (SMS::LindstromTurk_cost<Surface>())
|
||||
.get_placement(placement_ref)
|
||||
);
|
||||
|
||||
ref_mesh.collect_garbage();
|
||||
small_mesh.collect_garbage();
|
||||
big_mesh.collect_garbage();
|
||||
//std::cout<<"Filtered placement time = "<<placement2_time<<"s."<<std::endl;
|
||||
//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;
|
||||
assert(num_vertices(big_mesh) == num_vertices(ref_mesh));
|
||||
assert(num_vertices(small_mesh) != num_vertices(ref_mesh));
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue