mirror of https://github.com/CGAL/cgal
Various fixes
This commit is contained in:
parent
89bfa685e3
commit
51bcbc0625
|
|
@ -1 +1 @@
|
|||
|
||||
* Add a test driver that uses font outlines as test shapes.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
20 June 2006 Fernando Cacciola
|
||||
- Bug fixes
|
||||
- Vertex-evetns replaced by Speudo-split events .
|
||||
31 March 2006 Fernando Cacciola
|
||||
- Start
|
||||
|
||||
|
|
|
|||
|
|
@ -218,14 +218,34 @@ boost::optional< MatrixC33<R> > inverse_matrix ( MatrixC33<R> const& m )
|
|||
{
|
||||
typedef typename R::RT RT ;
|
||||
|
||||
typedef boost::optional< MatrixC33<R> > result_type ;
|
||||
typedef MatrixC33<R> Matrix ;
|
||||
|
||||
typedef boost::optional<Matrix> result_type ;
|
||||
|
||||
result_type rInverse ;
|
||||
|
||||
RT det = m.determinant();
|
||||
|
||||
if ( ! CGAL_NTS is_zero(det) )
|
||||
rInverse = result_type( adjoint_matrix(m) / det ) ;
|
||||
{
|
||||
RT c00 = (m.r1().y()*m.r2().z() - m.r1().z()*m.r2().y()) / det;
|
||||
RT c01 = (m.r2().y()*m.r0().z() - m.r0().y()*m.r2().z()) / det;
|
||||
RT c02 = (m.r0().y()*m.r1().z() - m.r1().y()*m.r0().z()) / det;
|
||||
|
||||
RT c10 = (m.r1().z()*m.r2().x() - m.r1().x()*m.r2().z()) / det;
|
||||
RT c11 = (m.r0().x()*m.r2().z() - m.r2().x()*m.r0().z()) / det;
|
||||
RT c12 = (m.r1().x()*m.r0().z() - m.r0().x()*m.r1().z()) / det;
|
||||
|
||||
RT c20 = (m.r1().x()*m.r2().y() - m.r2().x()*m.r1().y()) / det;
|
||||
RT c21 = (m.r2().x()*m.r0().y() - m.r0().x()*m.r2().y()) / det;
|
||||
RT c22 = (m.r0().x()*m.r1().y() - m.r0().y()*m.r1().x()) / det;
|
||||
|
||||
rInverse = result_type( Matrix(c00,c01,c02
|
||||
,c10,c11,c12
|
||||
,c20,c21,c22
|
||||
)
|
||||
) ;
|
||||
}
|
||||
|
||||
return rInverse ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Surface_mesh_simplification/TSMS_common.h>
|
||||
#include <CGAL/Surface_mesh_simplification/Policies/LindstromTurk_collapse_data.h>
|
||||
#include <CGAL/Cartesian/MatrixC33.h>
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
|
|
|
|||
|
|
@ -54,10 +54,8 @@ LindstromTurkImpl<CD>::LindstromTurkImpl( Params const& aParams
|
|||
|
||||
if ( !aIsPFixed || !aIsQFixed )
|
||||
{
|
||||
|
||||
CGAL_TSMS_LT_TRACE(2,"Computing LT data for E" << mP_Q->ID << " (V" << mP->ID << "->V" << mQ->ID << ")" );
|
||||
|
||||
|
||||
// Volume preservation and optimization constrians are based on the normals to the triangles in the star of the collapsing egde
|
||||
// Triangle shape optimization constrians are based on the link of the collapsing edge (the cycle of vertices around the edge)
|
||||
Triangles lTriangles;
|
||||
|
|
@ -68,7 +66,7 @@ LindstromTurkImpl<CD>::LindstromTurkImpl( Params const& aParams
|
|||
|
||||
Extract_triangles_and_link(lTriangles,lLink);
|
||||
|
||||
#ifdef CGAL_SURFACE_SIMPLIFICATION_ENABLE_TRACE
|
||||
#ifdef CGAL_SURFACE_SIMPLIFICATION_ENABLE_LT_TRACE
|
||||
std::ostringstream ss ;
|
||||
for( typename Link::const_iterator it = lLink.begin(), eit = lLink.end() ; it != eit ; ++it )
|
||||
ss << "v" << (*it)->ID << " " ;
|
||||
|
|
@ -161,6 +159,8 @@ LindstromTurkImpl<CD>::LindstromTurkImpl( Params const& aParams
|
|||
|
||||
FT lSquaredLength = squared_distance(lP,lQ);
|
||||
|
||||
CGAL_TSMS_LT_TRACE(1,"Squared edge length: " << lSquaredLength ) ;
|
||||
|
||||
FT lBdryCost = 0;
|
||||
if ( lBdry )
|
||||
lBdryCost = Compute_boundary_cost(*lOptionalV,*lBdry);
|
||||
|
|
@ -169,18 +169,24 @@ LindstromTurkImpl<CD>::LindstromTurkImpl( Params const& aParams
|
|||
|
||||
FT lShapeCost = Compute_shape_cost(*lOptionalP,lLink);
|
||||
|
||||
FT lTotalCost = mParams.BoundaryWeight * lBdryCost
|
||||
+ mParams.VolumeWeight * lVolumeCost * lSquaredLength
|
||||
FT lTotalCost = mParams.VolumeWeight * lVolumeCost
|
||||
+ mParams.BoundaryWeight * lBdryCost * lSquaredLength
|
||||
+ mParams.ShapeWeight * lShapeCost * lSquaredLength * lSquaredLength ;
|
||||
|
||||
lOptionalCost = Optional_FT(lTotalCost);
|
||||
|
||||
CGAL_TSMS_LT_TRACE(1,"New vertex point: " << xyz_to_string(lV) << " cost: " << lTotalCost );
|
||||
CGAL_TSMS_LT_TRACE(1,"New vertex point: " << xyz_to_string(*lOptionalP) << "\nTotal cost: " << lTotalCost );
|
||||
|
||||
CGAL_TSMS_LT_TRACE(2,"\nSquared edge length: " << lSquaredLength
|
||||
<< "\nBoundary cost: " << lBdryCost
|
||||
<< "\nVolume cost: " << lVolumeCost
|
||||
<< "\nShape cost: " << lShapeCost
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
CGAL_TSMS_LT_TRACE(1,"The edge is fixed edge.");
|
||||
CGAL_TSMS_LT_TRACE(1,"The edge is a fixed edge.");
|
||||
|
||||
|
||||
mResult = result_type( new Collapse_data(mP,mQ,aIsPFixed,aIsQFixed,mP_Q,mSurface,lOptionalCost,lOptionalP) );
|
||||
|
|
@ -317,8 +323,8 @@ void LindstromTurkImpl<CD>::Extract_triangles_and_link( Triangles& rTriangles, L
|
|||
|
||||
if ( v2 != mQ )
|
||||
{
|
||||
CGAL_expensive_precondition(std::find(rLink.begin(),rLink.end(),v2) == rLink.end() );
|
||||
rLink.push_back(v2) ;
|
||||
if ( std::find(rLink.begin(),rLink.end(),v2) == rLink.end() )
|
||||
rLink.push_back(v2) ;
|
||||
}
|
||||
|
||||
Extract_triangle(v0,v1,v2,e02,rTriangles);
|
||||
|
|
@ -360,6 +366,8 @@ void LindstromTurkImpl<CD>::Extract_triangles_and_link( Triangles& rTriangles, L
|
|||
template<class CD>
|
||||
void LindstromTurkImpl<CD>::Add_boundary_preservation_constrians( Boundary const& aBdry )
|
||||
{
|
||||
CGAL_TSMS_LT_TRACE(2,"Adding boundary preservation constrians. ");
|
||||
|
||||
Vector e1 = aBdry.op + aBdry.pq + aBdry.qr ;
|
||||
Vector e3 = aBdry.opN + aBdry.pqN + aBdry.qrN ;
|
||||
|
||||
|
|
@ -373,15 +381,20 @@ void LindstromTurkImpl<CD>::Add_boundary_preservation_constrians( Boundary const
|
|||
template<class CD>
|
||||
void LindstromTurkImpl<CD>::Add_volume_preservation_constrians( Triangles const& aTriangles )
|
||||
{
|
||||
CGAL_TSMS_LT_TRACE(2,"Adding volume preservation constrians. " << aTriangles.size() << " triangles.");
|
||||
|
||||
Vector lSumV = NULL_VECTOR ;
|
||||
FT lSumL(0) ;
|
||||
FT lSumL(0) ;
|
||||
|
||||
for( typename Triangles::const_iterator it = aTriangles.begin(), eit = aTriangles.end() ; it != eit ; ++it )
|
||||
{
|
||||
CGAL_TSMS_LT_TRACE(2,"V:" << xyz_to_string(it->NormalV) << ", L:" << it->NormalL);
|
||||
|
||||
lSumV = lSumV + it->NormalV ;
|
||||
lSumL = lSumL + it->NormalL ;
|
||||
}
|
||||
|
||||
|
||||
mConstrians.Add_if_alpha_compatible(lSumV,lSumL);
|
||||
|
||||
}
|
||||
|
|
@ -389,6 +402,8 @@ void LindstromTurkImpl<CD>::Add_volume_preservation_constrians( Triangles const&
|
|||
template<class CD>
|
||||
void LindstromTurkImpl<CD>::Add_boundary_and_volume_optimization_constrians( OptionalBoundary const& aBdry, Triangles const& aTriangles )
|
||||
{
|
||||
CGAL_TSMS_LT_TRACE(2,"Adding boundary and volume optimization constrians. ");
|
||||
|
||||
Matrix H = NULL_MATRIX ;
|
||||
Vector c = NULL_VECTOR ;
|
||||
|
||||
|
|
@ -401,7 +416,7 @@ void LindstromTurkImpl<CD>::Add_boundary_and_volume_optimization_constrians( Opt
|
|||
|
||||
H += direct_product(lTri.NormalV,lTri.NormalV) ;
|
||||
|
||||
c = c + ( lTri.NormalL * lTri.NormalV ) ;
|
||||
c = c - ( lTri.NormalL * lTri.NormalV ) ;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -433,6 +448,8 @@ void LindstromTurkImpl<CD>::Add_boundary_and_volume_optimization_constrians( Opt
|
|||
template<class CD>
|
||||
void LindstromTurkImpl<CD>::Add_shape_optimization_constrians( Link const& aLink )
|
||||
{
|
||||
CGAL_TSMS_LT_TRACE(2,"Add shape optimization constrians. ");
|
||||
|
||||
FT s(aLink.size());
|
||||
|
||||
Matrix H (s,0,0
|
||||
|
|
@ -487,6 +504,7 @@ LindstromTurkImpl<CD>::Compute_shape_cost( Point const& p, Link const& aLink )
|
|||
return rCost ;
|
||||
}
|
||||
|
||||
/*
|
||||
template<class CD>
|
||||
void LindstromTurkImpl<CD>::Constrians::Add_if_alpha_compatible( Vector const& Ai, FT const& bi )
|
||||
{
|
||||
|
|
@ -538,6 +556,67 @@ void LindstromTurkImpl<CD>::Constrians::Add_if_alpha_compatible( Vector const& A
|
|||
++ n ;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
template<class CD>
|
||||
void LindstromTurkImpl<CD>::Constrians::Add_if_alpha_compatible( Vector const& Ai, FT const& bi )
|
||||
{
|
||||
double slai = to_double(Ai*Ai) ;
|
||||
if ( slai > 0.0 )
|
||||
{
|
||||
double l = CGAL_NTS sqrt(slai) ;
|
||||
|
||||
Vector Ain = Ai / l ;
|
||||
FT bin = bi / l ;
|
||||
|
||||
bool lAddIt = true ;
|
||||
|
||||
if ( n == 1 )
|
||||
{
|
||||
FT d01 = A.r0() * Ai ;
|
||||
|
||||
double sla0 = to_double(A.r0() * A.r0()) ;
|
||||
double sd01 = to_double(d01 * d01) ;
|
||||
|
||||
if ( sd01 > ( sla0 * slai * squared_cos_alpha() ) )
|
||||
lAddIt = false ;
|
||||
}
|
||||
else if ( n == 2 )
|
||||
{
|
||||
Vector N = cross_product(A.r0(),A.r1());
|
||||
|
||||
FT dc012 = N * Ai ;
|
||||
|
||||
double slc01 = to_double(N * N) ;
|
||||
double sdc012 = to_double(dc012 * dc012);
|
||||
|
||||
if ( sdc012 <= slc01 * slai * squared_sin_alpha() )
|
||||
lAddIt = false ;
|
||||
}
|
||||
|
||||
if ( lAddIt )
|
||||
{
|
||||
switch ( n )
|
||||
{
|
||||
case 0 :
|
||||
A.r0() = Ain ;
|
||||
b = Vector(bin,b.y(),b.z());
|
||||
break ;
|
||||
case 1 :
|
||||
A.r1() = Ain ;
|
||||
b = Vector(b.x(),bin,b.z());
|
||||
break ;
|
||||
case 2 :
|
||||
A.r2() = Ain ;
|
||||
b = Vector(b.x(),b.y(),bin);
|
||||
break ;
|
||||
}
|
||||
++ n ;
|
||||
}
|
||||
}
|
||||
|
||||
CGAL_TSMS_LT_TRACE(1,"Constrains.A:" << matrix_to_string(A) << "\nConstrains.b:" << xyz_to_string(b) ) ;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include <CGAL/Cartesian/MatrixC33.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
|
|
@ -102,6 +104,12 @@ inline std::string xyz_to_string( XYZ const& xyz )
|
|||
return boost::str( boost::format("(%1%,%2%,%3%)") % xyz.x() % xyz.y() % xyz.z() ) ;
|
||||
}
|
||||
|
||||
template<class Matrix>
|
||||
inline std::string matrix_to_string( Matrix const& m )
|
||||
{
|
||||
return boost::str( boost::format("[%1%|%2%|%3%]") % xyz_to_string(m.r0()) % xyz_to_string(m.r1()) % xyz_to_string(m.r2()) ) ;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline std::string optional_to_string( boost::optional<T> const& o )
|
||||
{
|
||||
|
|
@ -144,31 +152,14 @@ CGAL_END_NAMESPACE
|
|||
|
||||
|
||||
|
||||
#if defined(CGAL_SURFACE_SIMPLIFICATION_ENABLE_AUDIT)
|
||||
#define CGAL_TSMS_ENABLE_AUDIT
|
||||
#endif
|
||||
|
||||
#ifdef CGAL_TSMS_ENABLE_AUDIT
|
||||
|
||||
# include<string>
|
||||
# include<iostream>
|
||||
# include<sstream>
|
||||
# define CGAL_TSMS_AUDIT_IMPL(m) \
|
||||
{ \
|
||||
std::ostringstream ss ; ss << m ; std::string s = ss.str(); \
|
||||
Surface_simplification_external_audit(s); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CGAL_SURFACE_SIMPLIFICATION_ENABLE_AUDIT
|
||||
# define CGAL_TSMS_AUDIT(m) CGAL_TSMS_AUDIT_IMPL(m)
|
||||
# define CGAL_TSMS_AUDIT(p,q,e,c,v) CGAL_TSMS_audit(p,q,e,c,v)
|
||||
#else
|
||||
# define CGAL_TSMS_AUDIT(m)
|
||||
# define CGAL_TSMS_AUDIT(p,q,e,c,v)
|
||||
#endif
|
||||
|
||||
|
||||
#undef CGAL_TSMS_ENABLE_TRACE
|
||||
#undef CGAL_TSMS_ENABLE_AUDIT
|
||||
|
||||
#endif // CGAL_SURFACE_MESH_SIMPLIFICATION_TSMS_COMMON_H //
|
||||
// EOF //
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ void VertexPairCollapse<M,D,C,V,S>::Collect()
|
|||
set_pair(edge,lPair);
|
||||
insert_in_PQ(lPair);
|
||||
CGAL_TSMS_TRACE(3, (lPair->cost(),*lPair) << " accepted." );
|
||||
CGAL_TSMS_AUDIT("C-" << xyz_to_string(sp) << "->" << xyz_to_string(tp) << "-" << optional_to_string(lPair->cost()) );
|
||||
CGAL_TSMS_AUDIT(s,t,edge,lPair->cost(),Get_new_vertex_point(*lPair->data()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -229,7 +229,6 @@ void VertexPairCollapse<M,D,C,V,S>::Collapse( vertex_pair_ptr const& aPair )
|
|||
if ( lNewVertexPoint )
|
||||
{
|
||||
CGAL_TSMS_TRACE(2,"New vertex point: " << xyz_to_string(*lNewVertexPoint) ) ;
|
||||
CGAL_TSMS_AUDIT("V-" << xyz_to_string(get_point(lP)) << "->" << xyz_to_string(get_point(lQ)) << "-" << xyz_to_string(*lNewVertexPoint) );
|
||||
|
||||
// The actual collapse of edge PQ merges the top and bottom facets with its left and right adjacents resp, then
|
||||
// joins P and Q.
|
||||
|
|
@ -338,7 +337,6 @@ void VertexPairCollapse<M,D,C,V,S>::Collapse( vertex_pair_ptr const& aPair )
|
|||
else
|
||||
{
|
||||
CGAL_TSMS_TRACE(0,"Unable to calculate new vertex point. Pair " << aPair << " discarded without being removed" ) ;
|
||||
CGAL_TSMS_AUDIT("V-" << xyz_to_string(get_point(lP)) << "->" << xyz_to_string(get_point(lQ)) << "-NONE" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2002 Max Planck Institut fuer Informatik (Germany).
|
||||
// // 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
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <boost/tokenizer.hpp>
|
||||
|
||||
#define CGAL_CHECK_EXPENSIVE
|
||||
|
||||
|
|
@ -33,19 +34,15 @@
|
|||
#include <CGAL/IO/Polyhedron_geomview_ostream.h>
|
||||
#include <CGAL/IO/Polyhedron_iostream.h>
|
||||
|
||||
//#define CGAL_SURFACE_SIMPLIFICATION_ENABLE_TRACE 4
|
||||
//#define CGAL_SURFACE_SIMPLIFICATION_ENABLE_LT_TRACE 4
|
||||
//#define CGAL_SURFACE_SIMPLIFICATION_ENABLE_TRACE 3
|
||||
#define CGAL_SURFACE_SIMPLIFICATION_ENABLE_AUDIT
|
||||
|
||||
//#define CREATE_TESTCASE
|
||||
|
||||
void Surface_simplification_external_trace( std::string s )
|
||||
{
|
||||
std::cout << s << std::endl ;
|
||||
}
|
||||
|
||||
void Surface_simplification_external_audit( std::string s )
|
||||
{
|
||||
std::cout << s << std::endl ;
|
||||
static std::ofstream lout("tsms_log.txt");
|
||||
lout << s << std::flush << std::endl ;
|
||||
std::printf("%s\n",s.c_str());
|
||||
}
|
||||
|
||||
int exit_code = 0 ;
|
||||
|
|
@ -58,39 +55,56 @@ int exit_code = 0 ;
|
|||
#include <CGAL/Surface_mesh_simplification/Policies/LindstromTurk.h>
|
||||
#include <CGAL/Surface_mesh_simplification/Policies/Count_stop_pred.h>
|
||||
|
||||
using namespace std ;
|
||||
using namespace boost ;
|
||||
using namespace CGAL ;
|
||||
|
||||
//typedef Simple_homogeneous<int> Kernel;
|
||||
typedef Simple_cartesian<double> Kernel;
|
||||
typedef Kernel::Vector_3 Vector;
|
||||
typedef Kernel::Point_3 Point;
|
||||
|
||||
template <class Refs, class Traits>
|
||||
struct My_vertex : public CGAL::HalfedgeDS_vertex_base<Refs,CGAL::Tag_true,typename Traits::Point_3>
|
||||
struct My_vertex : public HalfedgeDS_vertex_base<Refs,Tag_true,Point>
|
||||
{
|
||||
typedef CGAL::HalfedgeDS_vertex_base<Refs,CGAL::Tag_true,typename Traits::Point_3> Base ;
|
||||
typedef HalfedgeDS_vertex_base<Refs,Tag_true,Point> Base ;
|
||||
|
||||
My_vertex() : ID(-1), IsFixed(false) {}
|
||||
My_vertex( typename Traits::Point_3 p ) : Base(p), ID(-1), IsFixed(false) {}
|
||||
|
||||
int ID;
|
||||
My_vertex( Point p ) : Base(p), ID(-1), IsFixed(false) {}
|
||||
|
||||
int id() const { return ID ; }
|
||||
|
||||
int ID;
|
||||
bool IsFixed ;
|
||||
} ;
|
||||
|
||||
template <class Refs, class Traits>
|
||||
struct My_halfedge : public CGAL::HalfedgeDS_halfedge_base<Refs>
|
||||
struct My_halfedge : public HalfedgeDS_halfedge_base<Refs>
|
||||
{
|
||||
My_halfedge() : ID(-1) {}
|
||||
My_halfedge()
|
||||
:
|
||||
ID(-1)
|
||||
{}
|
||||
|
||||
int id() const { return ID ; }
|
||||
|
||||
int ID;
|
||||
};
|
||||
|
||||
template <class Refs, class Traits>
|
||||
struct My_face : public CGAL::HalfedgeDS_face_base<Refs,CGAL::Tag_true,typename Traits::Plane_3>
|
||||
struct My_face : public HalfedgeDS_face_base<Refs,Tag_true,typename Traits::Plane_3>
|
||||
{
|
||||
typedef CGAL::HalfedgeDS_face_base<Refs,CGAL::Tag_true,typename Traits::Plane_3> Base ;
|
||||
typedef HalfedgeDS_face_base<Refs,Tag_true,typename Traits::Plane_3> 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 CGAL::Polyhedron_items_3
|
||||
struct My_items : public Polyhedron_items_3
|
||||
{
|
||||
template < class Refs, class Traits>
|
||||
struct Vertex_wrapper {
|
||||
|
|
@ -106,16 +120,14 @@ struct My_items : public CGAL::Polyhedron_items_3
|
|||
};
|
||||
};
|
||||
|
||||
//typedef CGAL::Simple_homogeneous<int> Kernel;
|
||||
typedef CGAL::Simple_cartesian<double> Kernel;
|
||||
typedef Kernel::Vector_3 Vector;
|
||||
typedef Kernel::Point_3 Point;
|
||||
typedef CGAL::Polyhedron_3<Kernel,My_items> Polyhedron;
|
||||
typedef Polyhedron_3<Kernel,My_items> 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;
|
||||
|
|
@ -129,9 +141,177 @@ struct External_polyhedron_get_is_vertex_fixed<Polyhedron>
|
|||
bool operator() ( Polyhedron const&, Vertex_const_handle v ) const { return v->IsFixed; }
|
||||
} ;
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
CGAL_END_NAMESPACE
|
||||
|
||||
using namespace std ;
|
||||
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<double> Cost ;
|
||||
optional<Point> NewVertexPoint ;
|
||||
} ;
|
||||
typedef shared_ptr<Audit_data> Audit_data_ptr ;
|
||||
typedef vector<Audit_data_ptr> 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<double> Cost ;
|
||||
optional<Point> NewVertexPoint ;
|
||||
bool CostMatched ;
|
||||
bool OrderMatched ;
|
||||
bool NewVertexMatched ;
|
||||
} ;
|
||||
|
||||
typedef shared_ptr<Audit_report> Audit_report_ptr ;
|
||||
|
||||
typedef map<int,Audit_report_ptr> Audit_report_map ;
|
||||
|
||||
Audit_report_map sAuditReport ;
|
||||
|
||||
typedef char_separator<char> Separator ;
|
||||
typedef tokenizer<Separator> Tokenizer ;
|
||||
|
||||
Point ParsePoint( vector<string> 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<string> 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<double>::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<double> const& c )
|
||||
{
|
||||
if ( c )
|
||||
return str( format("%1%") % (*c) ) ;
|
||||
else return "NONE" ;
|
||||
}
|
||||
|
||||
string to_string( optional<Point> const& p )
|
||||
{
|
||||
if ( p )
|
||||
return str( format("(%1%,%2%,%3%)") % p->x() % p->y() % p->z() ) ;
|
||||
else return "NONE" ;
|
||||
}
|
||||
|
||||
void CGAL_TSMS_audit( Vertex_handle const& p
|
||||
, Vertex_handle const& q
|
||||
, Halfedge_handle const& e
|
||||
, optional<double> const& cost
|
||||
, optional<Point> 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) ) ;
|
||||
}
|
||||
|
||||
// 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 )
|
||||
|
|
@ -146,16 +326,27 @@ void error_handler ( char const* what, char const* expr, char const* file, int l
|
|||
|
||||
using namespace CGAL::Triangulated_surface_mesh::Simplification ;
|
||||
|
||||
void Test ( char const* testcase )
|
||||
char const* matched_alpha ( bool matched )
|
||||
{
|
||||
ifstream in(testcase);
|
||||
if ( in )
|
||||
return matched ? "matched" : "UNMATCHED" ;
|
||||
}
|
||||
|
||||
bool Test ( string name )
|
||||
{
|
||||
bool rSucceeded = false ;
|
||||
|
||||
string off_name = name+string(".off");
|
||||
string audit_name = name+string(".audit");
|
||||
string result_name = name+string(".out.off");
|
||||
|
||||
ifstream off_is(off_name.c_str());
|
||||
if ( off_is )
|
||||
{
|
||||
Polyhedron lP;
|
||||
|
||||
in >> lP ;
|
||||
off_is >> lP ;
|
||||
|
||||
cout << "Testing Lindstrom Turk simplification of suracewith " << (lP.size_of_halfedges()/2) << " edges..." << endl ;
|
||||
cout << "Testing Lindstrom Turk simplification of surace with " << (lP.size_of_halfedges()/2) << " edges..." << endl ;
|
||||
|
||||
cout << setprecision(19) ;
|
||||
|
||||
|
|
@ -170,8 +361,12 @@ void Test ( char const* testcase )
|
|||
int lFacetID = 0 ;
|
||||
for ( Polyhedron::Facet_iterator fi = lP.facets_begin(); fi != lP.facets_end() ; ++ fi )
|
||||
fi->ID = lFacetID ++ ;
|
||||
|
||||
|
||||
|
||||
sAuditData.clear();
|
||||
//ParseAudit(audit_name);
|
||||
|
||||
cout << "Audit data loaded." << endl ;
|
||||
|
||||
typedef LindstromTurk_collapse_data<Polyhedron> Collapse_data ;
|
||||
|
||||
Construct_LindstromTurk_collapse_data<Collapse_data> Construct_collapse_data ;
|
||||
|
|
@ -181,56 +376,81 @@ void Test ( char const* testcase )
|
|||
|
||||
Collapse_data::Params lParams;
|
||||
|
||||
sAuditReport.clear();
|
||||
int r = vertex_pair_collapse(lP,Construct_collapse_data,&lParams,Get_cost,Get_vertex_point,Should_stop);
|
||||
|
||||
|
||||
ofstream off_out(result_name.c_str(),ios::trunc);
|
||||
off_out << lP ;
|
||||
|
||||
cout << "Finished...\n"
|
||||
<< r << " edges removed.\n"
|
||||
<< lP.size_of_vertices() << " vertices.\n"
|
||||
<< (lP.size_of_halfedges()/2) << " edges.\n"
|
||||
<< lP.size_of_facets() << " triangles.\n"
|
||||
<< ( lP.is_valid() ? " valid" : " INVALID!!" )
|
||||
<< endl ;
|
||||
<< ( lP.is_valid() ? " valid\n" : " INVALID!!\n" ) ;
|
||||
|
||||
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
|
||||
{
|
||||
cerr << "Unable to open test file " << testcase << endl ;
|
||||
exit_code = 1 ;
|
||||
cerr << "Unable to open test file " << name << endl ;
|
||||
}
|
||||
}
|
||||
|
||||
void CreateTestCase()
|
||||
{
|
||||
Polyhedron lP;
|
||||
|
||||
Point p( 0 , 0 , 0);
|
||||
Point q( 0 ,100, 0);
|
||||
Point r( 100, 0 , 0);
|
||||
Point s( 0 , 0 , 100);
|
||||
|
||||
Halfedge_handle h = lP.make_tetrahedron( p, q, r, s);
|
||||
|
||||
Halfedge_handle g = lP.create_center_vertex(h);
|
||||
|
||||
g->vertex()->point() = Point(25,25,0);
|
||||
|
||||
ofstream out("data/sample0.off");
|
||||
if ( out )
|
||||
out << lP ;
|
||||
return rSucceeded ;
|
||||
}
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
CGAL::set_error_handler (error_handler);
|
||||
CGAL::set_warning_handler(error_handler);
|
||||
set_error_handler (error_handler);
|
||||
set_warning_handler(error_handler);
|
||||
|
||||
#ifdef CREATE_TESTCASE
|
||||
CreateTestCase();
|
||||
#else
|
||||
vector<string> cases ;
|
||||
|
||||
for ( int i = 1 ; i < argc ; ++i )
|
||||
Test(argv[i]);
|
||||
#endif
|
||||
|
||||
return exit_code;
|
||||
cases.push_back( string(argv[i]) ) ;
|
||||
|
||||
if ( cases.size() == 0 )
|
||||
cases.push_back( string("data/sample5") ) ;
|
||||
|
||||
unsigned lOK = 0 ;
|
||||
for ( vector<string>::const_iterator it = cases.begin(); it != cases.end() ; ++ it )
|
||||
{
|
||||
if ( Test(*it) )
|
||||
++ lOK ;
|
||||
}
|
||||
|
||||
cout << endl
|
||||
<< lOK << " cases succedded." << endl
|
||||
<< (cases.size() - lOK ) << " cases failed." << endl ;
|
||||
|
||||
return lOK == cases.size() ? 0 : 1 ;
|
||||
}
|
||||
|
||||
// EOF //
|
||||
|
|
|
|||
|
|
@ -9,14 +9,14 @@
|
|||
<ignoreparts/>
|
||||
<projectdirectory>.</projectdirectory>
|
||||
<absoluteprojectpath>false</absoluteprojectpath>
|
||||
<description/>
|
||||
<description></description>
|
||||
</general>
|
||||
<kdevcustomproject>
|
||||
<run>
|
||||
<mainprogram>LT_edge_collapse_test</mainprogram>
|
||||
<directoryradio>executable</directoryradio>
|
||||
<customdirectory>/</customdirectory>
|
||||
<programargs>data/sample0.off</programargs>
|
||||
<programargs>data/sample5</programargs>
|
||||
<terminal>false</terminal>
|
||||
<autocompile>true</autocompile>
|
||||
<envvars/>
|
||||
|
|
@ -26,8 +26,8 @@
|
|||
<numberofjobs>1</numberofjobs>
|
||||
<prio>0</prio>
|
||||
<dontact>false</dontact>
|
||||
<makebin/>
|
||||
<defaulttarget/>
|
||||
<makebin></makebin>
|
||||
<defaulttarget></defaulttarget>
|
||||
<makeoptions>CGAL_MAKEFILE=/home/fcacciola/Programming/CGAL/make/makefile_i686_Linux-2.6_g++-4.0.2 DEBUGGING=yes</makeoptions>
|
||||
<selectedenvironment>default</selectedenvironment>
|
||||
<environments>
|
||||
|
|
@ -36,17 +36,17 @@
|
|||
</make>
|
||||
<build>
|
||||
<buildtool>make</buildtool>
|
||||
<builddir/>
|
||||
<builddir></builddir>
|
||||
</build>
|
||||
</kdevcustomproject>
|
||||
<kdevdebugger>
|
||||
<general>
|
||||
<dbgshell/>
|
||||
<programargs/>
|
||||
<gdbpath/>
|
||||
<configGdbScript/>
|
||||
<runShellScript/>
|
||||
<runGdbScript/>
|
||||
<dbgshell></dbgshell>
|
||||
<programargs></programargs>
|
||||
<gdbpath></gdbpath>
|
||||
<configGdbScript></configGdbScript>
|
||||
<runShellScript></runShellScript>
|
||||
<runGdbScript></runGdbScript>
|
||||
<breakonloadinglibs>true</breakonloadinglibs>
|
||||
<separatetty>false</separatetty>
|
||||
<floatingtoolbar>false</floatingtoolbar>
|
||||
|
|
@ -126,7 +126,7 @@
|
|||
<headerCompletionDelay>250</headerCompletionDelay>
|
||||
</codecompletion>
|
||||
<creategettersetter>
|
||||
<prefixGet/>
|
||||
<prefixGet></prefixGet>
|
||||
<prefixSet>set</prefixSet>
|
||||
<prefixVariable>m_,_</prefixVariable>
|
||||
<parameterName>theValue</parameterName>
|
||||
|
|
@ -152,8 +152,8 @@
|
|||
</cppsupportpart>
|
||||
<kdevvisualadvance>
|
||||
<emulator>VisualBoyAdvance</emulator>
|
||||
<binary/>
|
||||
<addOptions/>
|
||||
<binary></binary>
|
||||
<addOptions></addOptions>
|
||||
<terminal>false</terminal>
|
||||
<fullscreen>false</fullscreen>
|
||||
<graphicFilter>-f0</graphicFilter>
|
||||
|
|
|
|||
Loading…
Reference in New Issue