From 7eaa3c8adcbce1fc4fcfaba0a6775319bb40d59b Mon Sep 17 00:00:00 2001 From: Fernando Cacciola Date: Mon, 3 Jul 2006 17:19:46 +0000 Subject: [PATCH] Bug in link-condition fixed --- .../Detail/Lindstrom_Turk_core_impl.h | 13 + .../Policies/Edge_length_cost.h | 10 +- .../Policies/Midpoint_vertex_placement.h | 8 +- .../Policies/Minimal_collapse_data.h | 2 + .../Vertex_pair_collapse_impl.h | 134 ++-- .../LT_edge_collapse_test.cpp | 599 +----------------- .../LT_edge_collapse_test.kdevelop | 24 +- .../test/Surface_mesh_simplification/makefile | 5 + 8 files changed, 98 insertions(+), 697 deletions(-) diff --git a/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Detail/Lindstrom_Turk_core_impl.h b/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Detail/Lindstrom_Turk_core_impl.h index 08e972cc920..3b23effbdec 100644 --- a/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Detail/Lindstrom_Turk_core_impl.h +++ b/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Detail/Lindstrom_Turk_core_impl.h @@ -20,6 +20,19 @@ CGAL_BEGIN_NAMESPACE +struct G +{ + ~G() + { + std::cout << "PFixed=" << PFixed << " QFixed=" << QFixed << " Boundary=" << Boundary << std::endl ; + } + + int PFixed ; + int QFixed ; + int Boundary ; +} ; +G g ; + // // Implementation of the strategy from: // diff --git a/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Edge_length_cost.h b/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Edge_length_cost.h index 607704b2bf1..d1824f91629 100644 --- a/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Edge_length_cost.h +++ b/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Edge_length_cost.h @@ -44,10 +44,10 @@ public: typedef Collapse_data_ Collapse_data ; - typedef typename Collapse_data::TSM TSM ; - typedef typename Collapse_data::vertex_descrirptor vertex_descriptor ; - typedef typename Collapse_data::Point_3 Point_3 ; - typedef typename Collapse_data::FT FT ; + typedef typename Collapse_data::TSM TSM ; + typedef typename Collapse_data::vertex_descriptor vertex_descriptor ; + typedef typename Collapse_data::Point_3 Point_3 ; + typedef typename Collapse_data::FT FT ; public: @@ -65,7 +65,7 @@ public: else return result_type(); } - Point_3 const& get_point ( vertex_descriptor const& v, TSM& aSurface ) + Point_3 const& get_point ( vertex_descriptor const& v, TSM& aSurface ) const { vertex_point_t vertex_point ; return get(vertex_point,aSurface,v) ; diff --git a/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Midpoint_vertex_placement.h b/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Midpoint_vertex_placement.h index 33574ddf262..3b5fdee2ffc 100644 --- a/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Midpoint_vertex_placement.h +++ b/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Midpoint_vertex_placement.h @@ -44,9 +44,9 @@ public: typedef Collapse_data_ Collapse_data ; - typedef typename Collapse_data::TSM TSM ; - typedef typename Collapse_data::vertex_descrirptor vertex_descriptor ; - typedef typename Collapse_data::Point_3 Point_3 ; + typedef typename Collapse_data::TSM TSM ; + typedef typename Collapse_data::vertex_descriptor vertex_descriptor ; + typedef typename Collapse_data::Point_3 Point_3 ; typedef optional result_type ; @@ -69,7 +69,7 @@ public: else return result_type(); } - Point_3 const& get_point ( vertex_descriptor const& v, TSM& aSurface ) + Point_3 const& get_point ( vertex_descriptor const& v, TSM& aSurface ) const { vertex_point_t vertex_point ; return get(vertex_point,aSurface,v) ; diff --git a/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Minimal_collapse_data.h b/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Minimal_collapse_data.h index b5c06e51d13..d2058e7386a 100644 --- a/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Minimal_collapse_data.h +++ b/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Minimal_collapse_data.h @@ -39,6 +39,8 @@ public: typedef typename Surface_geometric_traits::Point_3 Point_3 ; typedef typename Surface_geometric_traits::FT FT ; + struct Params{} ; + public : Minimal_collapse_data() diff --git a/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Vertex_pair_collapse_impl.h b/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Vertex_pair_collapse_impl.h index 377753ebb3e..c69be85db0e 100644 --- a/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Vertex_pair_collapse_impl.h +++ b/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Vertex_pair_collapse_impl.h @@ -236,78 +236,43 @@ void VertexPairCollapse::Loop() template bool VertexPairCollapse::Is_collapsable( vertex_descriptor const& p, vertex_descriptor const& q, edge_descriptor const& p_q ) { - bool rR = true ; - + out_edge_iterator eb1, ee1 ; + out_edge_iterator eb2, ee2 ; + edge_descriptor q_p = opposite_edge(p_q,mSurface); - edge_descriptor p_t = next_edge_ccw(p_q,mSurface); - edge_descriptor p_b = next_edge_cw (p_q,mSurface); - edge_descriptor q_t = next_edge_cw (q_p,mSurface); - edge_descriptor q_b = next_edge_ccw(q_p,mSurface); - - CGAL_TSMS_TRACE(5, "Testing link condition:" - << "\np_q: V" << source(p_q,mSurface)->id() << "->V" << target(p_q,mSurface)->id() - << "\nq_p: V" << source(q_p,mSurface)->id() << "->V" << target(q_p,mSurface)->id() - << "\np_t: V" << source(p_t,mSurface)->id() << "->V" << target(p_t,mSurface)->id() - << "\np_b: V" << source(p_b,mSurface)->id() << "->V" << target(p_b,mSurface)->id() - << "\nq_t: V" << source(q_t,mSurface)->id() << "->V" << target(q_t,mSurface)->id() - << "\nq_n: V" << source(q_b,mSurface)->id() << "->V" << target(q_b,mSurface)->id() - ); - + vertex_descriptor t = target(next_edge_cw (q_p,mSurface),mSurface); + vertex_descriptor b = target(next_edge_ccw(q_p,mSurface),mSurface); - // degree(p) and degree(q) >= 3 - if ( target(p_t,mSurface) != q - && target(p_b,mSurface) != q - && target(q_t,mSurface) != p - && target(q_b,mSurface) != p - ) + for ( tie(eb1,ee1) = out_edges(p,mSurface) ; eb1 != ee1 ; ++ eb1 ) { - // link('p') .intersection. link('q') == link('p_q') (that is, exactly {'t','b'}) - if ( target(p_t,mSurface) == target(q_t,mSurface) - && target(p_b,mSurface) == target(q_b,mSurface) - ) + edge_descriptor p_x = *eb1 ; + + if ( p_x != p_q ) { - edge_descriptor p_tn = p_t ; - edge_descriptor p_bn = p_b ; - edge_descriptor q_tn = q_t ; - edge_descriptor q_bn = q_b ; + vertex_descriptor x = target(p_x,mSurface); - do + for ( tie(eb2,ee2) = out_edges(x,mSurface) ; eb2 != ee2 ; ++ eb2 ) { - p_tn = next_edge_ccw(p_tn,mSurface); - p_bn = next_edge_cw (p_bn,mSurface); - q_tn = next_edge_cw (q_tn,mSurface); - q_bn = next_edge_ccw(q_bn,mSurface); + edge_descriptor x_y = *eb2 ; - CGAL_TSMS_TRACE(5, "\n p_tn: V" << source(p_tn,mSurface)->id() << "->V" << target(p_tn,mSurface)->id() - << "\n q_tn: V" << source(q_tn,mSurface)->id() << "->V" << target(q_tn,mSurface)->id() - << "\n p_bn: V" << source(p_bn,mSurface)->id() << "->V" << target(p_bn,mSurface)->id() - << "\n q_bn: V" << source(q_bn,mSurface)->id() << "->V" << target(q_bn,mSurface)->id() - ); - - if ( target(p_tn,mSurface) == target(q_tn,mSurface) - || target(p_bn,mSurface) == target(q_bn,mSurface) - ) + if ( target(x_y,mSurface) == q ) { - rR = false ; - break ; - } - } - while ( p_tn != p_bn && q_tn != q_bn ) ; - } - else - { - CGAL_TSMS_TRACE(5, "t and b vertices not shared by p and q"); - rR = false ; + if ( x != t && x != b ) + { + CGAL_TSMS_TRACE(0, "Link condition for E" << p_q->id() << " V" << p->id() << "->V" << q->id() << " failed." + << "\n Non-face triangle found: V" << p->id() << "->V" << x->id() << "->V" << q->id() + << "\n (top face: V" << p->id() << "->V" << t->id() << "->V" << q->id() << ")" + << "\n (bottom face: V" << p->id() << "->V" << b->id() << "->V" << q->id() << ")" + ); + return false ; + } + } + } } - } - else - { - CGAL_TSMS_TRACE(5, "degree(p) or degree(q) < 3"); - rR = false ; - } + } - return rR ; + return true ; } template @@ -338,11 +303,17 @@ void VertexPairCollapse::Collapse( vertex_pair_ptr aPair ) edge_descriptor lEdgeQB = next_edge_ccw(lEdgeQP,mSurface); - CGAL_TSMS_TRACE(3,"EdgePQ E" << lEdgePQ->ID << " Opposite EdgePQ E" << lEdgePQ->opposite()->ID - << " V" << lEdgePQ->opposite()->vertex()->ID << "->V" << lEdgePQ->vertex()->ID + CGAL_TSMS_TRACE(3,"EdgePQ E" << lEdgePQ->ID + << "(V" << lEdgePQ->vertex()->ID << "->V" << lEdgePQ->opposite()->vertex()->ID + << ") EdgeQP E" << lEdgePQ->opposite()->ID ) ; - CGAL_TSMS_TRACE(3,"EdgePT E" << lEdgePT->ID << " Opposite EdgePT E" << lEdgePT->opposite()->ID - << " V" << lEdgePT->opposite()->vertex()->ID << "->V" << lEdgePT->vertex()->ID + CGAL_TSMS_TRACE(3,"EdgePT E" << lEdgePT->ID + << "(V" << lEdgePT->vertex()->ID << "->V" << lEdgePT->opposite()->vertex()->ID + << ") EdgeTP E" << lEdgePT->opposite()->ID + ) ; + CGAL_TSMS_TRACE(3,"EdgeQB E" << lEdgeQB->ID + << "(V" << lEdgeQB->vertex()->ID << "->V" << lEdgeQB->opposite()->vertex()->ID + << ") EdgeBQ E" << lEdgeQB->opposite()->ID ) ; // The collapse will also remove QB so it must be pop off the PQ as well @@ -424,7 +395,9 @@ void VertexPairCollapse::Update_neighbors( vertex_pair_ptr aCollaps if ( lPair->p() == aCollapsingPair->p() ) { - CGAL_TSMS_TRACE(4,"Replacing lPair->p() with Q" ) ; + CGAL_TSMS_TRACE(4,"Replacing lPair->p() with V" << aCollapsingPair->q()->id() << "(Q)" ) ; + + CGAL_assertion( aCollapsingPair->q() != lPair->q() ) ; lPair->data().set(aCollapsingPair->q() ,lPair ->q() @@ -436,7 +409,9 @@ void VertexPairCollapse::Update_neighbors( vertex_pair_ptr aCollaps } else if ( lPair->q() == aCollapsingPair->p() ) { - CGAL_TSMS_TRACE(4,"Replacing lPair->q() with Q" ) ; + CGAL_TSMS_TRACE(4,"Replacing lPair->q() with V" << aCollapsingPair->q()->id() << " (Q)" ) ; + + CGAL_assertion( aCollapsingPair->q() != lPair->p() ) ; lPair->data().set(lPair ->p() ,aCollapsingPair->q() @@ -455,13 +430,10 @@ void VertexPairCollapse::Update_neighbors( vertex_pair_ptr aCollaps // Only those pairs still in the PQ are update. // The mark is used because in the way we loop here the same pair is found many times. - if ( lPair->is_in_PQ() ) + if ( lPair->is_in_PQ() && lToUpdate.find(lPair) == lToUpdate.end() ) { - if ( lToUpdate.find(lPair) == lToUpdate.end() ) - { - CGAL_TSMS_TRACE(4,"Pair registered for updating.") ; - lToUpdate.insert(lPair) ; - } + CGAL_TSMS_TRACE(4,"Pair registered for updating.") ; + lToUpdate.insert(lPair) ; } } } @@ -473,21 +445,25 @@ void VertexPairCollapse::Update_neighbors( vertex_pair_ptr aCollaps for ( typename vertex_pair_set::iterator it = lToUpdate.begin(), eit = lToUpdate.end() ; it != eit ; ++ it ) { vertex_pair_ptr lPair = *it ; - CGAL_TSMS_TRACE(3,"Updating cost of " << *lPair) ; + + //bool lIsPFixed = lPair->p() == aCollapsingPair->q() ? true : lPair->is_p_fixed() ; + //bool lIsQFixed = lPair->q() == aCollapsingPair->q() ? true : lPair->is_q_fixed() ; + bool lIsPFixed = lPair->is_p_fixed() ; + bool lIsQFixed = lPair->is_q_fixed() ; - // The cost of a pair can be recalculated by invalidating its cache and updating the PQ. - // The PQ update will reposition the pair in the heap querying its cost(), - // but since the cost was invalidated, it will be computed again Set_collapse_data(lPair->data() ,lPair->p() ,lPair->q() - ,lPair->is_p_fixed() - ,lPair->is_q_fixed() + ,lIsPFixed + ,lIsQFixed ,lPair->edge() ,lPair->surface() ,mParamsToSetCollapseData ) ; lPair->cost() = Get_cost(lPair->data()); + + CGAL_TSMS_TRACE(3,"Updated cost of " << *lPair) ; + update_in_PQ(lPair); } diff --git a/Surface_mesh_simplification/test/Surface_mesh_simplification/LT_edge_collapse_test.cpp b/Surface_mesh_simplification/test/Surface_mesh_simplification/LT_edge_collapse_test.cpp index 22d2459990b..7ef37b89a5e 100644 --- a/Surface_mesh_simplification/test/Surface_mesh_simplification/LT_edge_collapse_test.cpp +++ b/Surface_mesh_simplification/test/Surface_mesh_simplification/LT_edge_collapse_test.cpp @@ -1,597 +1,2 @@ -// // Copyright (c) 2002 Max Planck Institut fuer Informatik (Germany). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you may redistribute it under -// the terms of the Q Public License version 1.0. -// See the file LICENSE.QPL distributed with CGAL. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// -// -// Author(s) : Fernando Cacciola - - -#include -#include -#include -#include -#include - -//#define CGAL_CHECK_EXPENSIVE - -#include -#include -#include -#include -#include -#include -#include -#include - -//#define CGAL_SURFACE_SIMPLIFICATION_ENABLE_LT_TRACE 4 -//#define CGAL_SURFACE_SIMPLIFICATION_ENABLE_TRACE 1 - -#define STATS -//#define AUDIT - -void Surface_simplification_external_trace( std::string s ) -{ - static std::ofstream lout("tsms_log.txt"); - lout << s << std::flush << std::endl ; - std::printf("%s\n",s.c_str()); -} - -int exit_code = 0 ; - -#include -#include -#include -#include -#include - -using namespace std ; -using namespace boost ; -using namespace CGAL ; - -typedef Simple_cartesian Kernel; -typedef Kernel::Vector_3 Vector; -typedef Kernel::Point_3 Point; - -template -struct My_vertex : public HalfedgeDS_vertex_base -{ - typedef HalfedgeDS_vertex_base Base ; - - My_vertex() : ID(-1), IsFixed(false) {} - My_vertex( Point p ) : Base(p), ID(-1), IsFixed(false) {} - - int id() const { return ID ; } - - int ID; - bool IsFixed ; -} ; - -template -struct My_halfedge : public HalfedgeDS_halfedge_base -{ - My_halfedge() - : - ID(-1) - {} - - int id() const { return ID ; } - - int ID; - - void* cached_pointer ; -}; - -template -struct My_face : public HalfedgeDS_face_base -{ - typedef HalfedgeDS_face_base Base ; - - My_face() : ID(-1) {} - My_face( typename Traits::Plane_3 plane ) : Base(plane) {} - - int id() const { return ID ; } - - int ID; -}; - -struct My_items : public Polyhedron_items_3 -{ - template < class Refs, class Traits> - struct Vertex_wrapper { - typedef My_vertex Vertex; - }; - template < class Refs, class Traits> - struct Halfedge_wrapper { - typedef My_halfedge Halfedge; - }; - template < class Refs, class Traits> - struct Face_wrapper { - typedef My_face Face; - }; -}; - -typedef Polyhedron_3 Polyhedron; - -typedef Polyhedron::Vertex Vertex; -typedef Polyhedron::Vertex_iterator Vertex_iterator; -typedef Polyhedron::Vertex_handle Vertex_handle; -typedef Polyhedron::Vertex_const_handle Vertex_const_handle; -typedef Polyhedron::Halfedge_handle Halfedge_handle; -typedef Polyhedron::Halfedge_const_handle Halfedge_const_handle; -typedef Polyhedron::Edge_iterator Edge_iterator; -typedef Polyhedron::Facet_iterator Facet_iterator; -typedef Polyhedron::Halfedge_around_vertex_const_circulator HV_circulator; -typedef Polyhedron::Halfedge_around_facet_circulator HF_circulator; - -CGAL_BEGIN_NAMESPACE - -template<> -struct External_polyhedron_get_is_vertex_fixed -{ - bool operator() ( Polyhedron const&, Vertex_const_handle v ) const { return v->IsFixed; } -} ; - -template<> -struct External_polyhedron_access_edge_cached_pointer -{ - void*& operator() ( Polyhedron&, Halfedge_handle he ) const { return he->cached_pointer; } -} ; - -CGAL_END_NAMESPACE - - -#ifdef AUDIT - -double sCostMatchThreshold = 1e-2 ; -double sVertexMatchThreshold = 1e-2 ; - -struct Audit_data -{ - Audit_data( Point p, Point q ) : P(p), Q(q) {} - - Point P, Q ; - optional Cost ; - optional NewVertexPoint ; -} ; -typedef shared_ptr Audit_data_ptr ; -typedef vector Audit_data_vector ; - -Audit_data_vector sAuditData ; - -Audit_data_ptr lookup_audit ( Point p, Point q ) -{ - for ( Audit_data_vector::iterator it = sAuditData.begin() ; it != sAuditData.end() ; ++ it ) - { - Audit_data_ptr data = *it ; - if ( data->P == p && data->Q == q ) - return data ; - } - return Audit_data_ptr() ; -} - -Audit_data_ptr get_or_create_audit ( Point p, Point q ) -{ - Audit_data_ptr data = lookup_audit(p,q); - if ( !data ) - { - data = Audit_data_ptr(new Audit_data(p,q)); - sAuditData.push_back(data); - } - return data ; -} - -struct Audit_report -{ - Audit_report( int eid ) - : - HalfedgeID(eid) - , CostMatched(false) - , OrderMatched(false) - , NewVertexMatched(false) - {} - - - int HalfedgeID ; - Audit_data_ptr AuditData ; - optional Cost ; - optional NewVertexPoint ; - bool CostMatched ; - bool OrderMatched ; - bool NewVertexMatched ; -} ; - -typedef shared_ptr Audit_report_ptr ; - -typedef map Audit_report_map ; - -Audit_report_map sAuditReport ; - -typedef char_separator Separator ; -typedef tokenizer Tokenizer ; - -Point ParsePoint( vector tokens, int aIdx ) -{ - double x = atof(tokens[aIdx+0].c_str()); - double y = atof(tokens[aIdx+1].c_str()); - double z = atof(tokens[aIdx+2].c_str()); - - return Point(x,y,z); -} - -void ParseAuditLine( string s ) -{ - Tokenizer tk(s,Separator(",")); - vector tokens(tk.begin(),tk.end()); - if ( tokens.size() >= 7 ) - { - Point p = ParsePoint(tokens,0); - Point q = ParsePoint(tokens,3); - - Audit_data_ptr lData = get_or_create_audit(p,q); - - double cost = atof(tokens[6].c_str()) ; - - if ( cost != std::numeric_limits::max() ) - lData->Cost = cost ; - - if ( tokens.size() == 10 ) - lData->NewVertexPoint = ParsePoint(tokens,7); - } - else - cerr << "WARNING: Invalid audit line: [" << s << "]" << endl ; -} - - -void ParseAudit ( string name ) -{ - ifstream is(name.c_str()); - if ( is ) - { - while ( is ) - { - string line ; - getline(is,line); - if ( line.length() > 0 ) - ParseAuditLine(line); - } - } - else cerr << "Warning: Audit file " << name << " doesn't exist." << endl ; -} - -string to_string( optional const& c ) -{ - if ( c ) - return str( format("%1%") % (*c) ) ; - else return "NONE" ; -} - -string to_string( optional const& p ) -{ - if ( p ) - return str( format("(%1%,%2%,%3%)") % p->x() % p->y() % p->z() ) ; - else return "NONE" ; -} - -void register_collected_edge( Vertex_handle const& p - , Vertex_handle const& q - , Halfedge_handle const& e - , optional const& cost - , optional const& newv - ) -{ - Audit_report_ptr lReport( new Audit_report(e->ID) ) ; - - lReport->Cost = cost ; - lReport->NewVertexPoint = newv ; - - Audit_data_ptr lData ; //= lookup_audit(p->point(),q->point()); - if ( lData ) - { - lReport->AuditData = lData ; - - if ( !!lData->Cost && !!cost ) - { - double d = fabs(*lData->Cost - *cost) ; - if ( d < sCostMatchThreshold ) - lReport->CostMatched = true ; - } - else if (!lData->Cost && !cost ) - lReport->CostMatched = true ; - - if ( !!lData->NewVertexPoint && !!newv ) - { - double d = std::sqrt(squared_distance(*lData->NewVertexPoint,*newv)); - - if ( d < sVertexMatchThreshold ) - lReport->NewVertexMatched = true ; - } - else if ( !lData->NewVertexPoint && !newv ) - lReport->NewVertexMatched = true ; - } - - sAuditReport.insert( make_pair(e->ID,lReport) ) ; -} -#endif - -#ifdef STATS -int sInitial ; -int sCollected ; -int sProcessed ; -int sCollapsed ; -int sNonCollapsable ; -int sCostUncomputable ; -int sFixed ; -int sRemoved ; -#endif - - -struct Visitor -{ - void OnStarted( Polyhedron& aSurface ) - { -#ifdef STATS - sInitial = aSurface.size_of_halfedges() / 2 ; -#endif - } - - void OnFinished ( Polyhedron& aSurface ) - { -#ifdef STATS - printf("\n"); -#endif - } - - void OnThetrahedronReached ( Polyhedron& aSurface ) {} - void OnStopConditionReached( Polyhedron& aSurface ) {} - - void OnCollected( Polyhedron& aSurface - , Vertex_handle const& aP - , Vertex_handle const& aQ - , bool aIsPFixed - , bool aIsQFixed - , Halfedge_handle const& aEdge - , optional aCost - , optional aNewVertexPoint - ) - { -#ifdef AUDIT - register_collected_edge(aP,aQ,aEdge,aCost,aNewVertexPoint); -#endif -#ifdef STATS - ++sCollected ; - printf("\rEdges collected %d",sCollected); -#endif - } - - void OnProcessed( Polyhedron& aSurface - , Vertex_handle const& aP - , Vertex_handle const& aQ - , bool aIsPFixed - , bool aIsQFixed - , Halfedge_handle const& aEdge - , optional aCost - , optional aNewVertexPoint - , bool aIsCollapsable - ) - { -#ifdef STATS - if ( sProcessed == 0 ) - printf("\n"); - ++ sProcessed ; - if ( aIsPFixed && aIsQFixed ) - ++ sFixed ; - else if ( !aIsCollapsable ) - { - if ( !aCost ) - ++ sCostUncomputable ; - else ++ sNonCollapsable ; - } - else - ++ sCollapsed; -#endif - - } - - void OnCollapsed( Polyhedron& aSurface - , Vertex_handle const& aP - , Halfedge_handle const& aPQ - , Halfedge_handle const& aPT - , Halfedge_handle const& aQB - ) - { -#ifdef STATS - sRemoved += 3 ; - printf("\r%d%%",((int)(100.0*((double)sRemoved/(double)sInitial)))); -#endif - } - -} ; - -// This is here only to allow a breakpoint to be placed so I can trace back the problem. -void error_handler ( char const* what, char const* expr, char const* file, int line, char const* msg ) -{ - cerr << "CGAL error: " << what << " violation!" << endl - << "Expr: " << expr << endl - << "File: " << file << endl - << "Line: " << line << endl; - if ( msg != 0) - cerr << "Explanation:" << msg << endl; -} - -using namespace CGAL::Triangulated_surface_mesh::Simplification ; - -char const* matched_alpha ( bool matched ) -{ - return matched ? "matched" : "UNMATCHED" ; -} - -bool Test ( int aStop, string name ) -{ - bool rSucceeded = false ; - - string off_name = name+string(".off"); - string audit_name = name+string(".audit"); - string result_name = name+string(".out.off"); - - cout << "Testing simplification of surface " << off_name << endl ; - - ifstream off_is(off_name.c_str()); - if ( off_is ) - { - Polyhedron lP; - - scan_OFF(off_is,lP,true); - - cout << (lP.size_of_halfedges()/2) << " edges..." << endl ; - - cout << setprecision(19) ; - - int lVertexID = 0 ; - for ( Polyhedron::Vertex_iterator vi = lP.vertices_begin(); vi != lP.vertices_end() ; ++ vi ) - vi->ID = lVertexID ++ ; - - int lHalfedgeID = 0 ; - for ( Polyhedron::Halfedge_iterator hi = lP.halfedges_begin(); hi != lP.halfedges_end() ; ++ hi ) - hi->ID = lHalfedgeID++ ; - - int lFacetID = 0 ; - for ( Polyhedron::Facet_iterator fi = lP.facets_begin(); fi != lP.facets_end() ; ++ fi ) - fi->ID = lFacetID ++ ; - -#ifdef AUDIT - sAuditData .clear(); - sAuditReport.clear(); - ParseAudit(audit_name); - cout << "Audit data loaded." << endl ; -#endif - - typedef LindstromTurk_collapse_data Collapse_data ; - - Set_LindstromTurk_collapse_data Set_collapse_data ; - LindstromTurk_cost Get_cost ; - LindstromTurk_vertex_placement Get_vertex_point ; - Count_stop_condition Should_stop(aStop); - - Collapse_data::Params lParams; - - Visitor lVisitor ; - - Real_timer t ; t.start(); - int r = vertex_pair_collapse(lP,Set_collapse_data,&lParams,Get_cost,Get_vertex_point,Should_stop,&lVisitor); - t.stop(); - - ofstream off_out(result_name.c_str(),ios::trunc); - off_out << lP ; - - cout << "\nFinished...\n" - << "Ellapsed time: " << t.time() << " seconds.\n" - << r << " edges removed.\n" - << endl - << lP.size_of_vertices() << " final vertices.\n" - << (lP.size_of_halfedges()/2) << " final edges.\n" - << lP.size_of_facets() << " final triangles.\n" - << ( lP.is_valid() ? " valid\n" : " INVALID!!\n" ) ; - -#ifdef STATS - cout << "\n------------STATS--------------\n" - << sProcessed << " edges processed.\n" - << sCollapsed << " edges collapsed.\n" - << sNonCollapsable << " non-collapsable edges.\n" - << sCostUncomputable << " non-computable edges.\n" - << sFixed << " fixed edges.\n" - << sRemoved << " edges removed.\n" - << (sRemoved/3) << " vertices removed." ; -#endif - -#ifdef AUDIT - unsigned lMatches = 0 ; - - cout << "Audit report:\n" ; - for ( Audit_report_map::const_iterator ri = sAuditReport.begin() ; ri != sAuditReport.end() ; ++ ri ) - { - Audit_report_ptr lReport = ri->second ; - - if ( lReport->AuditData ) - { - if ( lReport->NewVertexMatched ) - ++ lMatches ; - - cout << "Collapsed Halfedge " << lReport->HalfedgeID << endl - << " Cost: Actual=" << to_string(lReport->Cost) << ", Expected=" << to_string(lReport->AuditData->Cost) - << ". " << matched_alpha(lReport->CostMatched) << endl - << " New vertex point: Actual=" << to_string(lReport->NewVertexPoint) << ", Expected=" - << to_string(lReport->AuditData->NewVertexPoint) - << ". " << matched_alpha(lReport->NewVertexMatched) - << endl ; - } - else - { - cout << "No audit data for Halfedge " << lReport->HalfedgeID << endl ; - ++ lMatches ; - } - } - - rSucceeded = ( lMatches == sAuditReport.size() ) ; -#else - rSucceeded = true ; -#endif - - } - else - { - cerr << "Unable to open test file " << name << endl ; - } - - return rSucceeded ; -} - -int main( int argc, char** argv ) -{ - set_error_handler (error_handler); - set_warning_handler(error_handler); - - if ( argc > 3 ) - { - vector cases ; - - int lStop = atoi(argv[1]); - - string lFolder(argv[2]); - - for ( int i = 3 ; i < argc ; ++i ) - cases.push_back( string(argv[i]) ) ; - - unsigned lOK = 0 ; - for ( vector::const_iterator it = cases.begin(); it != cases.end() ; ++ it ) - { - if ( Test( lStop, lFolder + *it) ) - ++ lOK ; - } - - cout << endl - << lOK << " cases succedded." << endl - << (cases.size() - lOK ) << " cases failed." << endl ; - - return lOK == cases.size() ? 0 : 1 ; - } - else - { - cout << "USAGE: LT_edge_collapse_test final_edge_count folder file0 file1 file2 ..." << endl ; - - return 1 ; - } -} - -// EOF // +#define TEST_LT +#include "edge_collapse_test.cpp" diff --git a/Surface_mesh_simplification/test/Surface_mesh_simplification/LT_edge_collapse_test.kdevelop b/Surface_mesh_simplification/test/Surface_mesh_simplification/LT_edge_collapse_test.kdevelop index d2d7ddf1e23..3412c4b5dc4 100644 --- a/Surface_mesh_simplification/test/Surface_mesh_simplification/LT_edge_collapse_test.kdevelop +++ b/Surface_mesh_simplification/test/Surface_mesh_simplification/LT_edge_collapse_test.kdevelop @@ -9,7 +9,7 @@ . false - + @@ -26,8 +26,8 @@ 1 0 false - - + + CGAL_MAKEFILE=/home/fcacciola/Programming/CGAL/make/makefile_i686_Linux-2.6_g++-4.0.2 DEBUGGING=yes default @@ -38,17 +38,17 @@ make - + - + 1000 data/ horse.5000 - - - - + + + + true false false @@ -128,7 +128,7 @@ 250 - + set m_,_ theValue @@ -154,8 +154,8 @@ VisualBoyAdvance - - + + false false -f0 diff --git a/Surface_mesh_simplification/test/Surface_mesh_simplification/makefile b/Surface_mesh_simplification/test/Surface_mesh_simplification/makefile index d457cdc90d3..9c326aead91 100644 --- a/Surface_mesh_simplification/test/Surface_mesh_simplification/makefile +++ b/Surface_mesh_simplification/test/Surface_mesh_simplification/makefile @@ -35,12 +35,17 @@ LDFLAGS = \ #---------------------------------------------------------------------# all: \ + Midpoint_edge_collapse_test \ LT_edge_collapse_test +Midpoint_edge_collapse_test$(EXE_EXT): Midpoint_edge_collapse_test$(OBJ_EXT) + $(CGAL_CXX) $(LIBPATH) $(EXE_OPT)Midpoint_edge_collapse_test Midpoint_edge_collapse_test$(OBJ_EXT) $(LDFLAGS) + LT_edge_collapse_test$(EXE_EXT): LT_edge_collapse_test$(OBJ_EXT) $(CGAL_CXX) $(LIBPATH) $(EXE_OPT)LT_edge_collapse_test LT_edge_collapse_test$(OBJ_EXT) $(LDFLAGS) clean: \ + Midpoint_edge_collapse_test.clean \ LT_edge_collapse_test.clean #---------------------------------------------------------------------#