Subject: CGAL users discussion list
List archive
- From: "Qianqian Fang" <>
- To:
- Subject: Re: [cgal-discuss] fix border edges for mesh simplification
- Date: Tue, 1 Apr 2008 13:37:09 -0400
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=beta; h=message-id:date:from:to:subject:in-reply-to:mime-version:content-type:references; b=sf4R2inzk0Uli+KdpdpGrHoPipNVVY+SQfS9V/RCD413WFzBZxMdU6bstaHQk3xhzBhHHUz4N+cI18POdrkFaHT32jrdICnI+vU20lRGPw6aYzqzx1M4v/3CxUGikdMjlr+XT1VakH9rUk6X6bPp8oInwoaE9+y8fODoabau/uw=
thank you Fernando
Now the code compiles normally. Unfortunately, the simplified surface mesh is similar to the
old one:some of the border edges were collapsed.
My test dataset (testoff.off) and my modified code (including your class) are attached.
There are 348 border nodes and edges in the mesh. The command line to run the test is
./edge_collapse_enriched_polyhedron testoff.off 0.05
the output info is :
Edges collected: 164574
822622
Edges collected: 164574
Edges proccessed: 52708
Edges collapsed: 51576
Edges not collapsed due to topological constrians: 591
Edge not collapsed due to cost computation constrians: 0
Edge not collapsed due to placement computation constrians: 540
Finished...
156348 edges removed.
8226 final edges.
There are 540 edges were not collapsed due to placement constrains, seems the
wrapper class is functioning. This number is greater than 348, I guess it is the
total edges connect to border nodes? (a little smaller than I expected though)
do you think there could be an indexing problem while removing the edges from
the surface?
I don't want to spend too much of your time on this, but if you have some quick
thoughts or ideas where to look at, that would be great help.
thank you again
Qianqian
On Tue, Apr 1, 2008 at 11:33 AM, Fernando Cacciola <> wrote:
Hi Qianqian,
OK...
> Fernando Cacciola wrote:
>> Hi Qianqian,
>>
>>> typedef typename Profile::const_in_edge_iterator
>>> const_in_edge_iterator ;
>>
> Replacing the above line to
> typedef typename Profile::ConstGraphTraits::const_in_edge_iterator
> const_in_edge_iterator ;
>
> the error message became:
>
> edge_collapse_enriched_polyhedron.cpp:142: error: no type named
> 'const_in_edge_iterator' in 'struct boost::graph_traits<const
> CGAL::Polyhedron_3<CGAL::Simple_cartesian<double>,
> CGAL::Polyhedron_items_with_id_3, CGAL::HalfedgeDS_default,
> std::allocator<int> > >'
>
> seems something still not quite right.
>
I couldn't compile the warpper myself because the development version of the
package was broken and I had been postponing fixing it until I finish something
else.
But now I just fixed it, so I was able to try the wrapper myself...
There were some additional errors, but the attached version works AFAICT.
Best
Fernando Cacciola
GeometryFactory
--
You are currently subscribed to cgal-discuss.
To unsubscribe or access the archives, go to
https://lists-sop.inria.fr/wws/info/cgal-discuss
#include <iostream> #include <fstream> #include <CGAL/Simple_cartesian.h> #include <CGAL/Polyhedron_3.h> #include <CGAL/IO/Polyhedron_iostream.h> // Adaptor for Polyhedron_3 #include <CGAL/Surface_mesh_simplification/HalfedgeGraph_Polyhedron_3.h> // Simplification function #include <CGAL/Surface_mesh_simplification/edge_collapse.h> // Extended polyhedron items which include an id() field #include <CGAL/Polyhedron_items_with_id_3.h> // Stop-condition policy #include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_ratio_stop_predicate.h> // Non-default cost and placement policies #include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Midpoint_and_length.h> typedef CGAL::Simple_cartesian<double> Kernel; typedef Kernel::Point_3 Point ; // // Setup an enriched polyhedron type which stores an id() field in the items // typedef CGAL::Polyhedron_3<Kernel,CGAL::Polyhedron_items_with_id_3> Surface; typedef Surface::Halfedge_handle Halfedge_handle ; namespace SMS = CGAL::Surface_mesh_simplification ; typedef SMS::Edge_profile<Surface> Profile ; // The following is a Visitor that keeps track of the simplification process. // In this example the progress is printed real-time and a few statistics are // recorded (and printed in the end). // struct Visitor { Visitor() : collected(0) , processed(0) , collapsed(0) , non_collapsable(0) , cost_uncomputable(0) , placement_uncomputable(0) {} // Called on algorithm entry void OnStarted( Surface& ) {} // Called on algorithm exit void OnFinished ( Surface& ) { std::cerr << "\n" << std::flush ; } // Called when the stop condition returned true void OnStopConditionReached( Profile const& ) {} // Called during the collecting phase for each edge collected. void OnCollected( Profile const&, boost::optional<double> const& ) { ++ collected ; std::cerr << "\rEdges collected: " << collected << std::flush ; } // Called during the processing phase for each edge selected. // If cost is absent the edge won't be collapsed. void OnSelected(Profile const& ,boost::optional<double> cost ,std::size_t initial ,std::size_t current ) { ++ processed ; if ( !cost ) ++ cost_uncomputable ; if ( current == initial ) std::cerr << "\n" << std::flush ; std::cerr << "\r" << current << std::flush ; } // Called during the processing phase for each edge being collapsed. // If placement is absent the edge is left uncollapsed. void OnCollapsing(Profile const& ,boost::optional<Point> placement ) { if ( placement ) ++ collapsed; else ++ placement_uncomputable ; } // Called for each edge which failed the so called link-condition, // that is, which cannot be collapsed because doing so would // turn the surface into a non-manifold. void OnNonCollapsable( Profile const& ) { ++ non_collapsable; } std::size_t collected , processed , collapsed , non_collapsable , cost_uncomputable , placement_uncomputable ; } ; template<class GetPlacement_> struct Placement_with_fixed_border_vertices : GetPlacement_ { typedef GetPlacement_ GetPlacement ; typedef typename GetPlacement::Profile Profile ; typedef typename GetPlacement::result_type result_type ; typedef typename Profile::ECM ECM ; typedef typename Profile::const_vertex_descriptor const_vertex_descriptor ; typedef typename Profile::const_edge_descriptor const_edge_descriptor ; typedef typename Profile::ConstGraphTraits::in_edge_iterator const_in_edge_iterator ; result_type operator()( Profile const& aProfile ) const { if ( is_border_vertex(aProfile.v0(), aProfile.surface()) || is_border_vertex(aProfile.v1(), aProfile.surface()) ) return boost::none ; else return this->GetPlacement::operator()(aProfile); } bool is_border_vertex( const_vertex_descriptor v, ECM& aSurface ) const { bool rR = false ; const_in_edge_iterator eb, ee ; for ( boost::tie(eb,ee) = boost::in_edges(v,aSurface) ; eb != ee ; ++ eb ) { const_edge_descriptor lEdge = *eb ; if ( lEdge->is_border() || lEdge->opposite()->is_border() ) { rR = true ; break ; } } return rR ; } } ; typedef Placement_with_fixed_border_vertices< SMS::Midpoint_placement<Surface> > My_placement ; int main( int argc, char** argv ) { Surface surface; float maxface=0.1; std::ifstream is(argv[1]) ; is >> surface ; if(argc>2) maxface=atof(argv[2]); printf("max face ratio=%f\n",maxface); // The items in this polyhedron have an "id()" field // which the default index maps used in the algorithm // need to get the index of a vertex/edge. // However, the Polyhedron_3 class doesn't assign any value to // this id(), so we must do it here: int index = 0 ; for( Surface::Halfedge_iterator eb = surface.halfedges_begin() , ee = surface.halfedges_end() ; eb != ee ; ++ eb ) eb->id() = index++; index = 0 ; for( Surface::Vertex_iterator vb = surface.vertices_begin() , ve = surface.vertices_end() ; vb != ve ; ++ vb ) vb->id() = index++; // In this example, the simplification stops when the number of undirected edges // drops below 10% of the initial count SMS::Count_ratio_stop_predicate<Surface> stop(maxface); Visitor vis ; // The index maps are not explicitelty passed as in the previous // example because the surface items have a proper id() field. // On the other hand, we pass here explicit cost and placement // function which differ from the default policies, ommited in // the previous example. int r = SMS::edge_collapse (surface ,stop ,CGAL::get_cost (SMS::Edge_length_cost <Surface>()) .get_placement( My_placement() ) .visitor(&vis) ); std::cout << "\nEdges collected: " << vis.collected << "\nEdges proccessed: " << vis.processed << "\nEdges collapsed: " << vis.collapsed << std::endl << "\nEdges not collapsed due to topological constrians: " << vis.non_collapsable << "\nEdge not collapsed due to cost computation constrians: " << vis.cost_uncomputable << "\nEdge not collapsed due to placement computation constrians: " << vis.placement_uncomputable << std::endl ; std::cout << "\nFinished...\n" << r << " edges removed.\n" << (surface.size_of_halfedges()/2) << " final edges.\n" ; std::ofstream os( argc > 3 ? argv[3] : "out.off" ) ; os << surface ; return 0 ; } // EOF //
Attachment:
testoff.off.gz
Description: GNU Zip compressed data
- Re: [cgal-discuss] fix border edges for mesh simplification, Fernando Cacciola, 04/01/2008
- Re: [cgal-discuss] fix border edges for mesh simplification, Qianqian Fang, 04/01/2008
- Re: [cgal-discuss] fix border edges for mesh simplification, Fernando Cacciola, 04/03/2008
- Re: [cgal-discuss] fix border edges for mesh simplification, Qianqian Fang, 04/06/2008
- Re: [cgal-discuss] fix border edges for mesh simplification, Fernando Cacciola, 04/03/2008
- Re: [cgal-discuss] fix border edges for mesh simplification, Qianqian Fang, 04/01/2008
Archive powered by MHonArc 2.6.16.