mirror of https://github.com/CGAL/cgal
demo updated
This commit is contained in:
parent
0e5d766ca3
commit
ddd88bdfd3
|
|
@ -2056,6 +2056,7 @@ Surface_mesh_parameterization/test/Surface_mesh_parameterization/data/cube.off -
|
|||
Surface_mesh_parameterization/test/Surface_mesh_parameterization/data/high_genus.off -text svneol=unset#application/octet-stream
|
||||
Surface_mesh_parameterization/test/Surface_mesh_parameterization/data/knot2.off -text svneol=unset#application/octet-stream
|
||||
Surface_mesh_parameterization/test/Surface_mesh_parameterization/data/oni.off -text svneol=unset#application/octet-stream
|
||||
Surface_mesh_simplification/demo/Surface_mesh_simplification/edge_collapse_demo.cpp -text
|
||||
Surface_mesh_simplification/doc_tex/Surface_mesh_simplification.tex -text
|
||||
Surface_mesh_simplification/doc_tex/Surface_mesh_simplification/PkgDescription.tex -text
|
||||
Surface_mesh_simplification/doc_tex/Surface_mesh_simplification/Surface_mesh_simplification.tex -text
|
||||
|
|
@ -2142,12 +2143,12 @@ Surface_mesh_simplification/test/Surface_mesh_simplification/data/cube_MP.audit
|
|||
Surface_mesh_simplification/test/Surface_mesh_simplification/data/cube_open.off -text
|
||||
Surface_mesh_simplification/test/Surface_mesh_simplification/data/cube_open_LT.audit -text
|
||||
Surface_mesh_simplification/test/Surface_mesh_simplification/data/cube_open_MP.audit -text
|
||||
Surface_mesh_simplification/test/Surface_mesh_simplification/data/eight.off -text
|
||||
Surface_mesh_simplification/test/Surface_mesh_simplification/data/eight_LT.audit -text
|
||||
Surface_mesh_simplification/test/Surface_mesh_simplification/data/eight_MP.audit -text
|
||||
Surface_mesh_simplification/test/Surface_mesh_simplification/data/genus1.off -text
|
||||
Surface_mesh_simplification/test/Surface_mesh_simplification/data/genus1_LT.audit -text
|
||||
Surface_mesh_simplification/test/Surface_mesh_simplification/data/genus1_MP.audit -text
|
||||
Surface_mesh_simplification/test/Surface_mesh_simplification/data/genus2.off -text
|
||||
Surface_mesh_simplification/test/Surface_mesh_simplification/data/genus2_LT.audit -text
|
||||
Surface_mesh_simplification/test/Surface_mesh_simplification/data/genus2_MP.audit -text
|
||||
Surface_mesh_simplification/test/Surface_mesh_simplification/data/head_open_with_holes.off -text
|
||||
Surface_mesh_simplification/test/Surface_mesh_simplification/data/head_open_with_holes_LT.audit -text
|
||||
Surface_mesh_simplification/test/Surface_mesh_simplification/data/head_open_with_holes_MP.audit -text
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
demo/Surface_simplification/README
|
||||
----------------------------------
|
||||
|
||||
simplification_demo.C
|
||||
edge_collapse_demo.cpp
|
||||
|
||||
|
||||
Fernando Cacciola
|
||||
|
|
|
|||
|
|
@ -1,162 +0,0 @@
|
|||
<?xml version = '1.0'?>
|
||||
<kdevelop>
|
||||
<general>
|
||||
<author>fcacciola</author>
|
||||
<email>fernando.cacciola@gmail.com</email>
|
||||
<version>$VERSION$</version>
|
||||
<projectmanagement>KDevCustomProject</projectmanagement>
|
||||
<primarylanguage>C++</primarylanguage>
|
||||
<ignoreparts/>
|
||||
<projectdirectory>.</projectdirectory>
|
||||
<absoluteprojectpath>false</absoluteprojectpath>
|
||||
<description/>
|
||||
</general>
|
||||
<kdevcustomproject>
|
||||
<run>
|
||||
<mainprogram>simplification_demo</mainprogram>
|
||||
<directoryradio>build</directoryradio>
|
||||
<customdirectory>/</customdirectory>
|
||||
<programargs>./data/Sample0.off 1000</programargs>
|
||||
<terminal>false</terminal>
|
||||
<autocompile>true</autocompile>
|
||||
<envvars/>
|
||||
</run>
|
||||
<build>
|
||||
<buildtool>make</buildtool>
|
||||
<builddir/>
|
||||
</build>
|
||||
<make>
|
||||
<abortonerror>false</abortonerror>
|
||||
<numberofjobs>1</numberofjobs>
|
||||
<prio>0</prio>
|
||||
<dontact>false</dontact>
|
||||
<makebin/>
|
||||
<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>
|
||||
<default/>
|
||||
</environments>
|
||||
</make>
|
||||
</kdevcustomproject>
|
||||
<kdevdebugger>
|
||||
<general>
|
||||
<dbgshell/>
|
||||
<programargs/>
|
||||
<gdbpath/>
|
||||
<configGdbScript/>
|
||||
<runShellScript/>
|
||||
<runGdbScript/>
|
||||
<breakonloadinglibs>true</breakonloadinglibs>
|
||||
<separatetty>false</separatetty>
|
||||
<floatingtoolbar>false</floatingtoolbar>
|
||||
</general>
|
||||
<display>
|
||||
<staticmembers>false</staticmembers>
|
||||
<demanglenames>true</demanglenames>
|
||||
<outputradix>10</outputradix>
|
||||
</display>
|
||||
</kdevdebugger>
|
||||
<kdevdoctreeview>
|
||||
<ignoretocs>
|
||||
<toc>ada</toc>
|
||||
<toc>ada_bugs_gcc</toc>
|
||||
<toc>bash</toc>
|
||||
<toc>bash_bugs</toc>
|
||||
<toc>clanlib</toc>
|
||||
<toc>fortran_bugs_gcc</toc>
|
||||
<toc>gnome1</toc>
|
||||
<toc>gnustep</toc>
|
||||
<toc>gtk</toc>
|
||||
<toc>gtk_bugs</toc>
|
||||
<toc>haskell</toc>
|
||||
<toc>haskell_bugs_ghc</toc>
|
||||
<toc>java_bugs_gcc</toc>
|
||||
<toc>java_bugs_sun</toc>
|
||||
<toc>kde2book</toc>
|
||||
<toc>opengl</toc>
|
||||
<toc>pascal_bugs_fp</toc>
|
||||
<toc>php</toc>
|
||||
<toc>php_bugs</toc>
|
||||
<toc>perl</toc>
|
||||
<toc>perl_bugs</toc>
|
||||
<toc>python</toc>
|
||||
<toc>python_bugs</toc>
|
||||
<toc>qt-kdev3</toc>
|
||||
<toc>ruby</toc>
|
||||
<toc>ruby_bugs</toc>
|
||||
<toc>sdl</toc>
|
||||
<toc>sw</toc>
|
||||
<toc>w3c-dom-level2-html</toc>
|
||||
<toc>w3c-svg</toc>
|
||||
<toc>w3c-uaag10</toc>
|
||||
<toc>wxwidgets_bugs</toc>
|
||||
</ignoretocs>
|
||||
<ignoreqt_xml>
|
||||
<toc>Guide to the Qt Translation Tools</toc>
|
||||
<toc>Qt Assistant Manual</toc>
|
||||
<toc>Qt Designer Manual</toc>
|
||||
<toc>Qt Reference Documentation</toc>
|
||||
<toc>qmake User Guide</toc>
|
||||
</ignoreqt_xml>
|
||||
<ignoredoxygen>
|
||||
<toc>KDE Libraries (Doxygen)</toc>
|
||||
</ignoredoxygen>
|
||||
</kdevdoctreeview>
|
||||
<kdevfilecreate>
|
||||
<filetypes/>
|
||||
<useglobaltypes>
|
||||
<type ext="ui" />
|
||||
<type ext="cpp" />
|
||||
<type ext="h" />
|
||||
</useglobaltypes>
|
||||
</kdevfilecreate>
|
||||
<kdevcppsupport>
|
||||
<references/>
|
||||
<codecompletion>
|
||||
<includeGlobalFunctions>true</includeGlobalFunctions>
|
||||
<includeTypes>true</includeTypes>
|
||||
<includeEnums>true</includeEnums>
|
||||
<includeTypedefs>false</includeTypedefs>
|
||||
<automaticCodeCompletion>true</automaticCodeCompletion>
|
||||
<automaticArgumentsHint>true</automaticArgumentsHint>
|
||||
<automaticHeaderCompletion>true</automaticHeaderCompletion>
|
||||
<codeCompletionDelay>250</codeCompletionDelay>
|
||||
<argumentsHintDelay>400</argumentsHintDelay>
|
||||
<headerCompletionDelay>250</headerCompletionDelay>
|
||||
</codecompletion>
|
||||
<creategettersetter>
|
||||
<prefixGet/>
|
||||
<prefixSet>set</prefixSet>
|
||||
<prefixVariable>m_,_</prefixVariable>
|
||||
<parameterName>theValue</parameterName>
|
||||
<inlineGet>true</inlineGet>
|
||||
<inlineSet>true</inlineSet>
|
||||
</creategettersetter>
|
||||
</kdevcppsupport>
|
||||
<kdevfileview>
|
||||
<groups>
|
||||
<hidenonprojectfiles>false</hidenonprojectfiles>
|
||||
<hidenonlocation>false</hidenonlocation>
|
||||
</groups>
|
||||
<tree>
|
||||
<hidepatterns>*.o,*.lo,CVS</hidepatterns>
|
||||
<hidenonprojectfiles>false</hidenonprojectfiles>
|
||||
</tree>
|
||||
</kdevfileview>
|
||||
<cppsupportpart>
|
||||
<filetemplates>
|
||||
<interfacesuffix>.h</interfacesuffix>
|
||||
<implementationsuffix>.cpp</implementationsuffix>
|
||||
</filetemplates>
|
||||
</cppsupportpart>
|
||||
<kdevvisualadvance>
|
||||
<emulator>VisualBoyAdvance</emulator>
|
||||
<binary/>
|
||||
<addOptions/>
|
||||
<terminal>false</terminal>
|
||||
<fullscreen>false</fullscreen>
|
||||
<graphicFilter>-f0</graphicFilter>
|
||||
<scaling>-1</scaling>
|
||||
</kdevvisualadvance>
|
||||
</kdevelop>
|
||||
|
|
@ -0,0 +1,463 @@
|
|||
// 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: svn+ssh://fcacciola@scm.gforge.inria.fr/svn/cgal/trunk/Surface_mesh_simplification/test/Surface_mesh_simplification/LT_edge_collapse_test.cpp $
|
||||
// $Id: LT_edge_collapse_test.cpp 32177 2006-07-03 11:55:13Z fcacciola $
|
||||
//
|
||||
//
|
||||
// Author(s) : Fernando Cacciola <fernando.cacciola@gmail.com>
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <CGAL/Real_timer.h>
|
||||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Constrained_triangulation_2.h>
|
||||
|
||||
#include <CGAL/Surface_mesh_simplification/HalfedgeGraph_Polyhedron_3.h>
|
||||
#include <CGAL/Surface_mesh_simplification/edge_collapse.h>
|
||||
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/LindstromTurk.h>
|
||||
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Midpoint_and_length.h>
|
||||
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_stop_predicate.h>
|
||||
|
||||
#include <CGAL/IO/Polyhedron_iostream.h>
|
||||
#include <CGAL/Polyhedron_items_with_id_3.h>
|
||||
|
||||
using namespace std ;
|
||||
using namespace boost ;
|
||||
using namespace CGAL ;
|
||||
|
||||
typedef Simple_cartesian<double> Kernel;
|
||||
typedef Kernel::Vector_3 Vector;
|
||||
typedef Kernel::Point_3 Point;
|
||||
|
||||
typedef Polyhedron_3<Kernel,Polyhedron_items_with_id_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;
|
||||
typedef Polyhedron::size_type size_type ;
|
||||
|
||||
struct Visitor
|
||||
{
|
||||
Visitor ( size_t aRequested ) : mRequested(aRequested), mCollected(0) {}
|
||||
|
||||
void OnStarted( Polyhedron& ) {}
|
||||
|
||||
void OnFinished ( Polyhedron& )
|
||||
{
|
||||
cerr << "\n" << flush ;
|
||||
}
|
||||
|
||||
void OnStopConditionReached( Polyhedron& ) {}
|
||||
|
||||
void OnCollected( Halfedge_handle const& aEdge, bool aIsFixed, Polyhedron& )
|
||||
{
|
||||
++ mCollected ;
|
||||
cerr << "\rEdges collected: " << mCollected << flush ;
|
||||
}
|
||||
|
||||
void OnSelected( Halfedge_handle const& aEdge, Polyhedron&, optional<double> const& aCost, size_t aInitial, size_t aCurrent )
|
||||
{
|
||||
if ( aCurrent == aInitial )
|
||||
cerr << "\n" << flush ;
|
||||
|
||||
if ( mRequested < aInitial )
|
||||
{
|
||||
double n = aInitial - aCurrent ;
|
||||
double d = aInitial - mRequested ;
|
||||
cerr << "\r" << aCurrent << " " << ((int)(100.0*(n/d))) << "%" << flush ;
|
||||
}
|
||||
}
|
||||
|
||||
void OnCollapsing(Halfedge_handle const& aEdge, Polyhedron&, optional<Point> const& aPlacement )
|
||||
{
|
||||
}
|
||||
|
||||
void OnNonCollapsable(Halfedge_handle const& aEdge, Polyhedron& )
|
||||
{
|
||||
}
|
||||
|
||||
size_t mRequested ;
|
||||
size_t mCollected ;
|
||||
} ;
|
||||
|
||||
// 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;
|
||||
|
||||
throw std::logic_error("");
|
||||
}
|
||||
|
||||
using namespace CGAL::Surface_mesh_simplification ;
|
||||
|
||||
char const* matched_alpha ( bool matched )
|
||||
{
|
||||
return matched ? "matched" : "UNMATCHED" ;
|
||||
}
|
||||
|
||||
enum Method { LT, MP } ;
|
||||
enum Cache { None, Cost, CostPlacement } ;
|
||||
|
||||
char const* method_to_string( Method aMethod )
|
||||
{
|
||||
switch(aMethod)
|
||||
{
|
||||
case LT: return "LindstromTurk" ; break ;
|
||||
case MP: return "Midpoint" ; break ;
|
||||
}
|
||||
|
||||
return "<unknown>" ;
|
||||
}
|
||||
|
||||
char const* cache_to_string( Cache aCache )
|
||||
{
|
||||
switch(aCache)
|
||||
{
|
||||
case None : return "None" ; break ;
|
||||
case Cost : return "Cost" ; break ;
|
||||
case CostPlacement : return "CostPlacement" ; break ;
|
||||
}
|
||||
|
||||
return "<unknown>" ;
|
||||
}
|
||||
|
||||
typedef Cost_cache <Polyhedron> P_cost_cache ;
|
||||
typedef Cost_and_placement_cache<Polyhedron> P_cost_and_placement_cache ;
|
||||
|
||||
typedef Cached_cost <Polyhedron> P_cached_cost ;
|
||||
typedef Edge_length_cost <Polyhedron> P_MP_cost ;
|
||||
typedef LindstromTurk_cost<Polyhedron> P_LT_cost ;
|
||||
|
||||
typedef Cached_placement<Polyhedron> P_cached_placement ;
|
||||
typedef Midpoint_placement<Polyhedron> P_MP_placement ;
|
||||
typedef LindstromTurk_placement<Polyhedron> P_LT_placement ;
|
||||
|
||||
typedef Set_no_cache<Polyhedron> P_set_no_cache ;
|
||||
|
||||
typedef Set_cost_cache<Polyhedron,P_MP_cost> P_set_cost_cache_MP ;
|
||||
typedef LindstromTurk_set_cost_cache<Polyhedron> P_set_cost_cache_LT ;
|
||||
|
||||
typedef Set_cost_and_placement_cache<Polyhedron,P_MP_cost,P_MP_placement> P_set_cost_and_placement_cache_MP ;
|
||||
typedef LindstromTurk_set_cost_and_placement_cache<Polyhedron> P_set_cost_and_placement_cache_LT ;
|
||||
|
||||
|
||||
void Simplify ( int aStopA, int aStopR, bool aJustPrintSurfaceData, string aName, Method aMethod, Cache aCache )
|
||||
{
|
||||
string off_name = aName ;
|
||||
string result_name = aName+string(".out.off");
|
||||
|
||||
ifstream off_is(off_name.c_str());
|
||||
if ( off_is )
|
||||
{
|
||||
Polyhedron lP;
|
||||
|
||||
scan_OFF(off_is,lP,true);
|
||||
|
||||
if ( lP.is_valid() )
|
||||
{
|
||||
if ( lP.is_pure_triangle() )
|
||||
{
|
||||
if ( !aJustPrintSurfaceData )
|
||||
{
|
||||
size_t lRequestedEdgeCount ;
|
||||
if ( aStopA != -1 )
|
||||
lRequestedEdgeCount = aStopA ;
|
||||
else lRequestedEdgeCount = lP.size_of_halfedges() * aStopR / 200 ;
|
||||
|
||||
cout << "Testing simplification of surface " << off_name
|
||||
<< " using " << method_to_string(aMethod) << " method"
|
||||
<< " with " << cache_to_string(aCache) << " cache." << endl ;
|
||||
|
||||
cout << lP.size_of_facets() << " triangles." << endl
|
||||
<< (lP.size_of_halfedges()/2) << " edges." << endl
|
||||
<< lP.size_of_vertices() << " vertices." << endl
|
||||
<< (lP.is_closed() ? "Closed." : "Open." ) << endl
|
||||
<< "Requested edge count: " << lRequestedEdgeCount << endl ;
|
||||
|
||||
cout << setprecision(19) ;
|
||||
|
||||
set_halfedgeds_items_id(lP);
|
||||
|
||||
P_cached_cost get_cached_cost ;
|
||||
P_MP_cost get_MP_cost;
|
||||
P_LT_cost get_LT_cost;
|
||||
|
||||
P_cached_placement get_cached_placement ;
|
||||
P_MP_placement get_MP_placement;
|
||||
P_LT_placement get_LT_placement;
|
||||
|
||||
P_set_no_cache set_no_cache ;
|
||||
|
||||
P_set_cost_cache_MP set_cost_cache_MP(get_MP_cost) ;
|
||||
P_set_cost_cache_LT set_cost_cache_LT ;
|
||||
|
||||
P_set_cost_and_placement_cache_MP set_cost_and_placement_cache_MP(get_MP_cost,get_MP_placement) ;
|
||||
P_set_cost_and_placement_cache_LT set_cost_and_placement_cache_LT ;
|
||||
|
||||
Count_stop_predicate<Polyhedron> stop(lRequestedEdgeCount);
|
||||
|
||||
Visitor lVisitor(lRequestedEdgeCount) ;
|
||||
|
||||
int r = -1 ;
|
||||
|
||||
Real_timer t ; t.start();
|
||||
switch( aMethod )
|
||||
{
|
||||
case MP:
|
||||
|
||||
switch ( aCache )
|
||||
{
|
||||
case None :
|
||||
|
||||
r = edge_collapse(lP
|
||||
,stop
|
||||
,set_cache(set_no_cache)
|
||||
.get_cost(get_MP_cost)
|
||||
.get_placement(get_MP_placement)
|
||||
.visitor(&lVisitor)
|
||||
);
|
||||
break ;
|
||||
|
||||
case Cost :
|
||||
|
||||
r = edge_collapse(lP
|
||||
,stop
|
||||
,set_cache(set_cost_cache_MP)
|
||||
.get_cost(get_cached_cost)
|
||||
.get_placement(get_MP_placement)
|
||||
.visitor(&lVisitor)
|
||||
);
|
||||
break ;
|
||||
|
||||
case CostPlacement :
|
||||
|
||||
r = edge_collapse(lP
|
||||
,stop
|
||||
,set_cache(set_cost_and_placement_cache_MP)
|
||||
.get_cost(get_cached_cost)
|
||||
.get_placement(get_cached_placement)
|
||||
.visitor(&lVisitor)
|
||||
);
|
||||
break ;
|
||||
|
||||
}
|
||||
|
||||
break ;
|
||||
|
||||
case LT:
|
||||
|
||||
switch ( aCache )
|
||||
{
|
||||
case None :
|
||||
|
||||
r = edge_collapse(lP
|
||||
,stop
|
||||
,set_cache(set_no_cache)
|
||||
.get_cost(get_LT_cost)
|
||||
.get_placement(get_LT_placement)
|
||||
.visitor(&lVisitor)
|
||||
);
|
||||
break ;
|
||||
|
||||
case Cost :
|
||||
|
||||
r = edge_collapse(lP
|
||||
,stop
|
||||
,set_cache(set_cost_cache_LT)
|
||||
.get_cost(get_cached_cost)
|
||||
.get_placement(get_LT_placement)
|
||||
.visitor(&lVisitor)
|
||||
);
|
||||
break ;
|
||||
|
||||
case CostPlacement :
|
||||
|
||||
r = edge_collapse(lP
|
||||
,stop
|
||||
,set_cache(set_cost_and_placement_cache_LT)
|
||||
.get_cost(get_cached_cost)
|
||||
.get_placement(get_cached_placement)
|
||||
.visitor(&lVisitor)
|
||||
);
|
||||
break ;
|
||||
|
||||
}
|
||||
|
||||
break ;
|
||||
}
|
||||
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" ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << off_name << ": " << lP.size_of_facets() << " triangles, "
|
||||
<< (lP.size_of_halfedges()/2) << " edges, "
|
||||
<< lP.size_of_vertices() << " vertices, "
|
||||
<< (lP.is_closed() ? "Closed." : "Open." ) << endl ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Surfaces is not triangulated (has faces with more than 3 sides): " << aName << endl ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Invalid surface: " << aName << endl ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Unable to open test file " << aName << endl ;
|
||||
}
|
||||
}
|
||||
|
||||
bool sPrintUsage = false ;
|
||||
|
||||
void add_case( string aCase, vector<string>& rCases )
|
||||
{
|
||||
bool lAdded = false ;
|
||||
|
||||
string::size_type pos = aCase.find_last_of(".") ;
|
||||
if ( pos != string::npos )
|
||||
{
|
||||
string ext = aCase.substr(pos);
|
||||
if ( ext == ".off" )
|
||||
{
|
||||
rCases.push_back(aCase);
|
||||
lAdded = true ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !lAdded )
|
||||
{
|
||||
sPrintUsage = true ;
|
||||
cerr << "Invalid input file. Only .off files are supported: " << aCase << endl ;
|
||||
}
|
||||
}
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
set_error_handler (error_handler);
|
||||
set_warning_handler(error_handler);
|
||||
|
||||
bool lJustPrintSurfaceData = false ;
|
||||
int lStopA = -1 ;
|
||||
int lStopR = 20 ;
|
||||
Method lMethod = LT ;
|
||||
Cache lCache = CostPlacement ;
|
||||
string lFolder ="";
|
||||
vector<string> lCases ;
|
||||
|
||||
for ( int i = 1 ; i < argc ; ++i )
|
||||
{
|
||||
string opt(argv[i]);
|
||||
if ( opt[0] == '-' )
|
||||
{
|
||||
switch(opt[1])
|
||||
{
|
||||
case 'd' : lFolder = opt.substr(2); break ;
|
||||
case 'a' : lStopA = lexical_cast<int>(opt.substr(2)); break;
|
||||
case 'r' : lStopR = lexical_cast<int>(opt.substr(2)); break;
|
||||
case 'n' : lJustPrintSurfaceData = true ; break ;
|
||||
case 'm' : lMethod = (Method)lexical_cast<int>(opt.substr(2)); break ;
|
||||
case 'c' : lCache = (Cache)lexical_cast<int>(opt.substr(2)); break ;
|
||||
|
||||
default:
|
||||
cerr << "Invalid option: " << opt << endl ;
|
||||
sPrintUsage = true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( int i = 1 ; i < argc ; ++i )
|
||||
{
|
||||
string opt(argv[i]);
|
||||
if ( opt[0] == '@' )
|
||||
{
|
||||
string rspname = opt.substr(1) ;
|
||||
ifstream rsp(rspname.c_str());
|
||||
if ( rsp )
|
||||
{
|
||||
string line ;
|
||||
while ( getline(rsp,line) )
|
||||
add_case(lFolder+line,lCases);
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Cannot open response file: " << rspname << endl ;
|
||||
sPrintUsage = true ;
|
||||
}
|
||||
}
|
||||
else if ( opt[0] != '-' )
|
||||
{
|
||||
add_case(lFolder+opt,lCases);
|
||||
}
|
||||
}
|
||||
|
||||
if ( lCases.size() == 0 )
|
||||
sPrintUsage = true ;
|
||||
|
||||
if ( sPrintUsage )
|
||||
{
|
||||
cout << "edge_collapse_demo <options> file0 file1 ... fileN @response_file" << endl
|
||||
<< " options: " << endl
|
||||
<< " -m method method: 0=LindstromTurk[default] 1=Midpoint" << endl
|
||||
<< " -c data_cache_level level: 0=None 1=Only cost cached 2=Both cost and placement cached[default]" << endl
|
||||
<< " -d folder Specifies the folder where the files are located. " << endl
|
||||
<< " -a absolute_max_edge_count Sets the final number of edges as absolute number." << endl
|
||||
<< " -r relative_max_edge_count Sets the final number of edges as a percentage." << endl
|
||||
<< " -n Do not simplify but simply report data of surfaces." << endl ;
|
||||
|
||||
return 1 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( vector<string>::const_iterator it = lCases.begin(); it != lCases.end() ; ++ it )
|
||||
Simplify( lStopA, lStopR, lJustPrintSurfaceData, *it, lMethod, lCache) ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
}
|
||||
|
||||
// EOF //
|
||||
|
|
@ -14,10 +14,10 @@ include $(CGAL_MAKEFILE)
|
|||
#---------------------------------------------------------------------#
|
||||
|
||||
CXXFLAGS = -I../../include/\
|
||||
-I../../../BGL/include\
|
||||
$(TESTSUITE_CXXFLAGS) \
|
||||
$(EXTRA_FLAGS) \
|
||||
$(CGAL_CXXFLAGS) \
|
||||
$(DEBUG_OPT)
|
||||
$(CGAL_CXXFLAGS)
|
||||
|
||||
#---------------------------------------------------------------------#
|
||||
# linker flags
|
||||
|
|
@ -29,20 +29,18 @@ LIBPATH = \
|
|||
|
||||
LDFLAGS = \
|
||||
$(TESTSUITE_LDFLAGS) \
|
||||
$(CGAL_LDFLAGS)
|
||||
$(CGAL_LDFLAGS)
|
||||
|
||||
#---------------------------------------------------------------------#
|
||||
# target entries
|
||||
#---------------------------------------------------------------------#
|
||||
|
||||
all: \
|
||||
simplification_demo
|
||||
all: edge_collapse_demo
|
||||
|
||||
simplification_demo$(EXE_EXT): simplification_demo$(OBJ_EXT)
|
||||
$(CGAL_CXX) $(LIBPATH) $(EXE_OPT)simplification_demo simplification_demo$(OBJ_EXT) $(LDFLAGS)
|
||||
edge_collapse_demo$(EXE_EXT): edge_collapse_demo$(OBJ_EXT)
|
||||
$(CGAL_CXX) $(LIBPATH) $(EXE_OPT)edge_collapse_demo edge_collapse_demo$(OBJ_EXT) $(LDFLAGS)
|
||||
|
||||
clean: \
|
||||
simplification_demo.clean
|
||||
clean: edge_collapse_demo.clean
|
||||
|
||||
#---------------------------------------------------------------------#
|
||||
# suffix rules
|
||||
|
|
|
|||
|
|
@ -1,319 +0,0 @@
|
|||
// 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
|
||||
|
||||
//Borland, Microsoft and Intel compiler are excluded
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER)
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
int main() {
|
||||
std::cout << "Geomview doesn't work on Windows, so no demo." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
#else // not windows
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
//#define VISUALIZE
|
||||
|
||||
#include <CGAL/Cartesian.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/Polyhedron_BGL.h>
|
||||
#include <CGAL/Polyhedron_extended_BGL.h>
|
||||
#include <CGAL/Polyhedron_BGL_properties.h>
|
||||
#include <CGAL/IO/Polyhedron_geomview_ostream.h>
|
||||
#include <CGAL/IO/Polyhedron_iostream.h>
|
||||
|
||||
//#define CGAL_SURFACE_SIMPLIFICATION_ENABLE_TRACE 4
|
||||
|
||||
void Surface_simplification_external_trace( std::string s )
|
||||
{
|
||||
std::cout << s << std::endl ;
|
||||
}
|
||||
|
||||
#include <CGAL/Surface_mesh_simplification_vertex_pair_collapse.h>
|
||||
|
||||
#include <CGAL/Surface_mesh_simplification/Policies/Construct_minimal_collapse_data.h>
|
||||
#include <CGAL/Surface_mesh_simplification/Policies/Edge_length_cost.h>
|
||||
#include <CGAL/Surface_mesh_simplification/Policies/Midpoint_vertex_placement.h>
|
||||
#include <CGAL/Surface_mesh_simplification/Policies/LindstromTurk.h>
|
||||
#include <CGAL/Surface_mesh_simplification/Policies/Count_stop_pred.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
template <class Refs, class Traits>
|
||||
struct My_vertex : public CGAL::HalfedgeDS_vertex_base<Refs,CGAL::Tag_true,typename Traits::Point_3>
|
||||
{
|
||||
typedef CGAL::HalfedgeDS_vertex_base<Refs,CGAL::Tag_true,typename Traits::Point_3> Base ;
|
||||
|
||||
My_vertex() {}
|
||||
My_vertex( typename Traits::Point_3 p ) : Base(p) {}
|
||||
|
||||
int ID;
|
||||
} ;
|
||||
|
||||
template <class Refs, class Traits>
|
||||
struct My_halfedge : public CGAL::HalfedgeDS_halfedge_base<Refs>
|
||||
{
|
||||
My_halfedge() {}
|
||||
|
||||
int ID;
|
||||
};
|
||||
|
||||
template <class Refs, class Traits>
|
||||
struct My_face : public CGAL::HalfedgeDS_face_base<Refs,CGAL::Tag_true,typename Traits::Plane_3>
|
||||
{
|
||||
typedef CGAL::HalfedgeDS_face_base<Refs,CGAL::Tag_true,typename Traits::Plane_3> Base ;
|
||||
|
||||
My_face() {}
|
||||
My_face( typename Traits::Plane_3 plane ) : Base(plane) {}
|
||||
|
||||
int ID;
|
||||
};
|
||||
|
||||
struct My_items : public CGAL::Polyhedron_items_3
|
||||
{
|
||||
template < class Refs, class Traits>
|
||||
struct Vertex_wrapper {
|
||||
typedef My_vertex<Refs,Traits> Vertex;
|
||||
};
|
||||
template < class Refs, class Traits>
|
||||
struct Halfedge_wrapper {
|
||||
typedef My_halfedge<Refs,Traits> Halfedge;
|
||||
};
|
||||
template < class Refs, class Traits>
|
||||
struct Face_wrapper {
|
||||
typedef My_face<Refs,Traits> Face;
|
||||
};
|
||||
};
|
||||
|
||||
typedef CGAL::Cartesian<double> Kernel;
|
||||
typedef Kernel::Vector_3 Vector;
|
||||
typedef Kernel::Point_3 Point;
|
||||
typedef CGAL::Polyhedron_3<Kernel,My_items> Polyhedron;
|
||||
|
||||
typedef Polyhedron::Vertex Vertex;
|
||||
typedef Polyhedron::Vertex_iterator Vertex_iterator;
|
||||
typedef Polyhedron::Halfedge_handle Halfedge_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;
|
||||
|
||||
void create_center_vertex( Polyhedron& P, Facet_iterator f) {
|
||||
Vector vec( 0.0, 0.0, 0.0);
|
||||
std::size_t order = 0;
|
||||
HF_circulator h = f->facet_begin();
|
||||
do {
|
||||
vec = vec + ( h->vertex()->point() - CGAL::ORIGIN);
|
||||
++ order;
|
||||
} while ( ++h != f->facet_begin());
|
||||
CGAL_assertion( order >= 3); // guaranteed by definition of polyhedron
|
||||
Point center = CGAL::ORIGIN + (vec / order);
|
||||
Halfedge_handle new_center = P.create_center_vertex( f->halfedge());
|
||||
new_center->vertex()->point() = center;
|
||||
}
|
||||
|
||||
struct Smooth_old_vertex {
|
||||
Point operator()( const Vertex& v) const {
|
||||
CGAL_precondition((CGAL::circulator_size( v.vertex_begin()) & 1) == 0);
|
||||
std::size_t degree = CGAL::circulator_size( v.vertex_begin()) / 2;
|
||||
double alpha = ( 4.0 - 2.0 * std::cos( 2.0 * CGAL_PI / degree)) / 9.0;
|
||||
Vector vec = (v.point() - CGAL::ORIGIN) * ( 1.0 - alpha);
|
||||
HV_circulator h = v.vertex_begin();
|
||||
do {
|
||||
vec = vec + ( h->opposite()->vertex()->point() - CGAL::ORIGIN)
|
||||
* alpha / degree;
|
||||
++ h;
|
||||
CGAL_assertion( h != v.vertex_begin()); // even degree guaranteed
|
||||
++ h;
|
||||
} while ( h != v.vertex_begin());
|
||||
return (CGAL::ORIGIN + vec);
|
||||
}
|
||||
};
|
||||
|
||||
void flip_edge( Polyhedron& P, Halfedge_handle e) {
|
||||
Halfedge_handle h = e->next();
|
||||
P.join_facet( e);
|
||||
P.split_facet( h, h->next()->next());
|
||||
}
|
||||
|
||||
void subdiv( Polyhedron& P) {
|
||||
if ( P.size_of_facets() == 0)
|
||||
return;
|
||||
// We use that new vertices/halfedges/facets are appended at the end.
|
||||
std::size_t nv = P.size_of_vertices();
|
||||
Vertex_iterator last_v = P.vertices_end();
|
||||
-- last_v; // the last of the old vertices
|
||||
Edge_iterator last_e = P.edges_end();
|
||||
-- last_e; // the last of the old edges
|
||||
Facet_iterator last_f = P.facets_end();
|
||||
-- last_f; // the last of the old facets
|
||||
|
||||
Facet_iterator f = P.facets_begin(); // create new center vertices
|
||||
do {
|
||||
create_center_vertex( P, f);
|
||||
} while ( f++ != last_f);
|
||||
|
||||
std::vector<Point> pts; // smooth the old vertices
|
||||
pts.reserve( nv); // get intermediate space for the new points
|
||||
++ last_v; // make it the past-the-end position again
|
||||
std::transform( P.vertices_begin(), last_v, std::back_inserter( pts),
|
||||
Smooth_old_vertex());
|
||||
std::copy( pts.begin(), pts.end(), P.points_begin());
|
||||
|
||||
Edge_iterator e = P.edges_begin(); // flip the old edges
|
||||
++ last_e; // make it the past-the-end position again
|
||||
while ( e != last_e) {
|
||||
Halfedge_handle h = e;
|
||||
++e; // careful, incr. before flip since flip destroys current edge
|
||||
flip_edge( P, h);
|
||||
};
|
||||
CGAL_postcondition( P.is_valid());
|
||||
}
|
||||
|
||||
// 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 )
|
||||
{
|
||||
std::cerr << "CGAL error: " << what << " violation!" << std::endl
|
||||
<< "Expr: " << expr << std::endl
|
||||
<< "File: " << file << std::endl
|
||||
<< "Line: " << line << std::endl;
|
||||
if ( msg != 0)
|
||||
std::cerr << "Explanation:" << msg << std::endl;
|
||||
}
|
||||
|
||||
using namespace CGAL::Triangulated_surface_mesh::Simplification ;
|
||||
|
||||
int Simplify_midpoint ( Polyhedron& aP, int aMax )
|
||||
{
|
||||
typedef Minimal_collapse_data<Polyhedron> CollapseData ;
|
||||
|
||||
Construct_minimal_collapse_data<Polyhedron> Construct_collapse_data ;
|
||||
Edge_length_cost <CollapseData> Get_cost ;
|
||||
Midpoint_vertex_placement<CollapseData> Get_vertex_point ;
|
||||
Count_stop_condition <CollapseData> Should_stop(aMax);
|
||||
|
||||
return vertex_pair_collapse(aP,Construct_collapse_data,(void*)0,Get_cost,Get_vertex_point,Should_stop);
|
||||
}
|
||||
|
||||
int Simplify_LT ( Polyhedron& aP, int aMax )
|
||||
{
|
||||
typedef LindstromTurk_collapse_data<Polyhedron> CollapseData ;
|
||||
|
||||
Construct_LindstromTurk_collapse_data<Polyhedron> Construct_collapse_data ;
|
||||
LindstromTurk_cost <Polyhedron> Get_cost ;
|
||||
LindstromTurk_vertex_placement <Polyhedron> Get_vertex_point ;
|
||||
Count_stop_condition <CollapseData> Should_stop(aMax);
|
||||
|
||||
LindstromTurk_params lParams(1,1,1);
|
||||
|
||||
return vertex_pair_collapse(aP,Construct_collapse_data,&lParams,Get_cost,Get_vertex_point,Should_stop);
|
||||
}
|
||||
|
||||
void Simplify ( Polyhedron& aP, int aMax )
|
||||
{
|
||||
std::cout << "Simplifying surface with " << (aP.size_of_halfedges()/2) << " edges..." << std::endl ;
|
||||
|
||||
#ifdef VISUALIZE
|
||||
CGAL::Geomview_stream gv;
|
||||
gv.set_bg_color(CGAL::BLACK);
|
||||
gv.set_face_color(CGAL::WHITE);
|
||||
gv.set_edge_color(CGAL::BLUE);
|
||||
gv.set_vertex_color(CGAL::RED);
|
||||
#endif
|
||||
|
||||
std::cout << std::setprecision(19) ;
|
||||
|
||||
int lVertexID = 0 ;
|
||||
for ( Polyhedron::Vertex_iterator vi = aP.vertices_begin(); vi != aP.vertices_end() ; ++ vi )
|
||||
vi->ID = lVertexID ++ ;
|
||||
|
||||
int lHalfedgeID = 0 ;
|
||||
for ( Polyhedron::Halfedge_iterator hi = aP.halfedges_begin(); hi != aP.halfedges_end() ; ++ hi )
|
||||
hi->ID = lHalfedgeID++ ;
|
||||
|
||||
int lFacetID = 0 ;
|
||||
for ( Polyhedron::Facet_iterator fi = aP.facets_begin(); fi != aP.facets_end() ; ++ fi )
|
||||
fi->ID = lFacetID ++ ;
|
||||
|
||||
|
||||
int r = Simplify_LT(aP,aMax);
|
||||
|
||||
std::cout << "Finished...\n"
|
||||
<< r << " edges removed.\n"
|
||||
<< aP.size_of_vertices() << " vertices.\n"
|
||||
<< (aP.size_of_halfedges()/2) << " edges.\n"
|
||||
<< aP.size_of_facets() << " triangles.\n"
|
||||
<< ( aP.is_valid() ? " valid" : " INVALID!!" )
|
||||
<< std::endl ;
|
||||
|
||||
#ifdef VISUALIZE
|
||||
gv << aP ;
|
||||
std::cout << "Press any key to finish..." << std::endl ;
|
||||
char k ;
|
||||
std::cin >> k ;
|
||||
#endif
|
||||
}
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
CGAL::set_error_handler (error_handler);
|
||||
CGAL::set_warning_handler(error_handler);
|
||||
|
||||
Polyhedron lP;
|
||||
|
||||
char const* infile = argc > 1 ? argv[1] : "./data/tetra2.off" ; //"./data/Sample0.off" ;
|
||||
std::ifstream in(infile);
|
||||
if ( in )
|
||||
{
|
||||
in >> lP ;
|
||||
|
||||
int lMax = argc > 2 ? std::atoi(argv[2]) : 1 ; // 1000
|
||||
|
||||
Simplify(lP,lMax);
|
||||
|
||||
char const* of = argc > 3 ? argv[3] : 0 ;
|
||||
std::string outfile = !of ? std::string(infile) + std::string(".out.off") : of ;
|
||||
|
||||
std::ofstream out(outfile.c_str());
|
||||
if ( out )
|
||||
{
|
||||
out << lP ;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Unable to open out file: " << outfile << std::endl ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Input file not found: " << infile << std::endl ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // not windows
|
||||
// EOF //
|
||||
Loading…
Reference in New Issue