This is an automated email from the git hooks/post-receive script. giggls-guest pushed a commit to branch master in repository sfcgal.
commit 08f9bc0f4dd342ed5a9924d00d5f8d7d934f7747 Author: Sven Geggus <[email protected]> Date: Fri Sep 18 17:46:43 2015 +0200 Imported Upstream version 1.2.0 --- .gitignore | 12 +- .travis.yml | 19 +++ CMakeLists.txt | 9 +- NEWS | 16 ++- src/Exception.h | 2 +- src/algorithm/connection.cpp | 2 +- src/algorithm/covers.h | 2 +- src/algorithm/difference.h | 2 +- src/algorithm/intersection.h | 2 +- src/algorithm/intersects.h | 2 +- src/algorithm/isValid.cpp | 12 ++ src/algorithm/straightSkeleton.cpp | 135 +++++++++++++++------ src/algorithm/straightSkeleton.h | 16 ++- src/algorithm/translate.cpp | 12 ++ src/algorithm/translate.h | 7 +- src/algorithm/union.cpp | 4 +- src/algorithm/union.h | 2 +- src/capi/sfcgal_c.cpp | 1 + src/capi/sfcgal_c.h | 10 +- src/detail/GeometrySet.cpp | 4 +- src/detail/TestGeometry.h | 2 + src/detail/graph/Edge.h | 2 +- src/detail/graph/GeometryGraph.h | 2 +- test/CMakeLists.txt | 8 -- test/bench/BenchStraightSkeleton.cpp | 95 +++++++++++++++ ...tSkeletonTest.cpp => ApproximateMedialAxis.cpp} | 60 +++++---- .../unit/SFCGAL/algorithm/StraightSkeletonTest.cpp | 54 +++++++-- test/unit/SFCGAL/capi/sfcgal_cTest.cpp | 28 +++++ travis/linux/before_install.sh | 16 +++ viewer/src/SFCGAL/viewer/plugins/DataPlugin.cpp | 2 +- 30 files changed, 422 insertions(+), 118 deletions(-) diff --git a/.gitignore b/.gitignore index 88fe904..eef6c1b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,11 @@ +CMakeCache.txt +CMakeFiles +Makefile +cmake_install.cmake +install_manifest.txt +CTestTestfile.cmake +Testing + .settings .cproject .project @@ -19,6 +27,4 @@ polygon_triangulation2.obj gmon.out -include/SFCGAL/version.h -include/SFCGAL/config.h - +include/SFCGAL diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..32a0cd5 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,19 @@ +language: cpp + +# os: +# - linux +# - osx + +compiler: + - gcc + - clang + +before_install: + - ./travis/${TRAVIS_OS_NAME}/before_install.sh + +before_script: + - cmake -DSFCGAL_BUILD_TESTS=ON + +script: + - make + - make test diff --git a/CMakeLists.txt b/CMakeLists.txt index 4089385..42bf129 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ option( SFCGAL_BUILD_VIEWER "build viewer and OpenSceneGraph support (outputs in set( CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules;${CMAKE_MODULE_PATH}" ) set( SFCGAL_VERSION_MAJOR 1 ) -set( SFCGAL_VERSION_MINOR 1 ) +set( SFCGAL_VERSION_MINOR 2 ) set( SFCGAL_VERSION_PATCH 0 ) set( SFCGAL_VERSION "${SFCGAL_VERSION_MAJOR}.${SFCGAL_VERSION_MINOR}.${SFCGAL_VERSION_PATCH}" ) @@ -72,7 +72,10 @@ if ( SFCGAL_BUILD_TESTS OR SFCGAL_BUILD_EXAMPLES OR SFCGAL_BUILD_OSG OR SFCGAL_B set( SFCGAL_Boost_COMPONENTS program_options chrono filesystem timer ${SFCGAL_Boost_COMPONENTS} ) endif() find_package( Boost COMPONENTS ${SFCGAL_Boost_COMPONENTS} REQUIRED ) - +if((${Boost_MAJOR_VERSION} EQUAL 1) AND (${Boost_MINOR_VERSION} EQUAL 58)) + message( STATUS "Defining BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT" ) + add_definitions( "-DBOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT" ) +endif() #-- GMP (facultative) ------------------------------------- find_package( GMP ) @@ -106,7 +109,7 @@ if( ${CGAL_USE_AUTOLINK} ) add_definitions( "-DCGAL_NO_AUTOLINK" ) endif() -find_package( CGAL 4.1 COMPONENTS Core REQUIRED ) +find_package( CGAL 4.3 COMPONENTS Core REQUIRED ) message( STATUS "CGAL ${CGAL_VERSION} found" ) include_directories( ${CMAKE_BINARY_DIR}/include ) diff --git a/NEWS b/NEWS index 72d5f17..e38de1c 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,15 @@ -1.0.5: +1.2.0 (2015-09-18): + * Improve the computation speed of straight skeletons by using an inexact construction kernel + * Add a new function approximateMedialAxis + * Fix an invalidity case (polygon degenerated to a point) #108 + * Fix compilation issues with boost 1.58 + * Add Travis support +1.1.0 (2015-01-14): + * New spatial operation Union(geom, geom) and Difference(geom, geom). + * Exposed Volume(geom) in C api and added output with a decimal + representation sfcgal_geometry_as_text_decim (thanks @matze09) + * Minor bug fixes +1.0.5 (2014-08-19): * Fix validity check message when converting to 2D * Fix a polygon orientation test (postgis bug #2818) * Fix a bug in plane3D @@ -9,6 +20,7 @@ * Avoid osg dependency when viewer is not built * Fix postgresql include directory * Add detection of lib64 directories -1.0.4: +1.0.4 (2013-11-29): Fix compilation with CGAL 4.3 +For older news, see https://github.com/Oslandia/SFCGAL/releases diff --git a/src/Exception.h b/src/Exception.h index cf3178a..b575c4d 100644 --- a/src/Exception.h +++ b/src/Exception.h @@ -48,7 +48,7 @@ public: */ virtual const char* what() const throw(); /** - * returns diagnostic informations (file, line, etc.) + * returns diagnostic information (file, line, etc.) */ std::string diagnostic() const throw(); protected: diff --git a/src/algorithm/connection.cpp b/src/algorithm/connection.cpp index 559e5de..0d3906f 100644 --- a/src/algorithm/connection.cpp +++ b/src/algorithm/connection.cpp @@ -51,7 +51,7 @@ void SurfaceGraph::addRing( const LineString& ring, FaceIndex faceIndex ) if ( foundEdgeWithBadOrientation != _edgeMap.end() ) { _isValid = Validity::invalid( - ( boost::format( "inconsistant orientation of PolyhedralSurface detected at edge %d (%d-%d) of polygon %d" ) % s % edge.first % edge.second % faceIndex ).str() + ( boost::format( "inconsistent orientation of PolyhedralSurface detected at edge %d (%d-%d) of polygon %d" ) % s % edge.first % edge.second % faceIndex ).str() ); } diff --git a/src/algorithm/covers.h b/src/algorithm/covers.h index 71038da..5b5ca39 100644 --- a/src/algorithm/covers.h +++ b/src/algorithm/covers.h @@ -31,7 +31,7 @@ class Solid; class Point; namespace detail { template <int Dim> class GeometrySet; -template <int Dim> class PrimitiveHandle; +template <int Dim> struct PrimitiveHandle; } namespace algorithm { diff --git a/src/algorithm/difference.h b/src/algorithm/difference.h index af0b6b9..9e98461 100644 --- a/src/algorithm/difference.h +++ b/src/algorithm/difference.h @@ -29,7 +29,7 @@ namespace SFCGAL { class Geometry; namespace detail { template <int Dim> class GeometrySet; -template <int Dim> class PrimitiveHandle; +template <int Dim> struct PrimitiveHandle; } namespace algorithm { diff --git a/src/algorithm/intersection.h b/src/algorithm/intersection.h index 5a632fd..0b4dc0c 100644 --- a/src/algorithm/intersection.h +++ b/src/algorithm/intersection.h @@ -29,7 +29,7 @@ namespace SFCGAL { class Geometry; namespace detail { template <int Dim> class GeometrySet; -template <int Dim> class PrimitiveHandle; +template <int Dim> struct PrimitiveHandle; } namespace algorithm { diff --git a/src/algorithm/intersects.h b/src/algorithm/intersects.h index 834f60b..ce9ccdd 100644 --- a/src/algorithm/intersects.h +++ b/src/algorithm/intersects.h @@ -30,7 +30,7 @@ class PolyhedralSurface; class TriangulatedSurface; namespace detail { template <int Dim> class GeometrySet; -template <int Dim> class PrimitiveHandle; +template <int Dim> struct PrimitiveHandle; } namespace algorithm { diff --git a/src/algorithm/isValid.cpp b/src/algorithm/isValid.cpp index f75d732..5c04130 100644 --- a/src/algorithm/isValid.cpp +++ b/src/algorithm/isValid.cpp @@ -141,6 +141,18 @@ const Validity isValid( const Polygon& p, const double& toleranceAbs ) } } + // When polygon degenerates to a single point, it is not trapped by the rest of the code, + // so we check that here + for ( size_t r=0; r != numRings; ++r ) { + const LineString & ring = p.ringN( r ); + const Point & start = ring.startPoint(); + size_t i = 0; + for( ; i < ring.numPoints() && start == ring.pointN(i); i++ ) ; // noop + if ( i == ring.numPoints() ){ + return Validity::invalid( ( boost::format( "ring %d degenerated to a point" ) % r ).str() ); + } + } + // Orientation in 2D if ( !p.is3D() ) { // Opposit orientation for interior and exterior rings diff --git a/src/algorithm/straightSkeleton.cpp b/src/algorithm/straightSkeleton.cpp index f5dda93..a44188a 100644 --- a/src/algorithm/straightSkeleton.cpp +++ b/src/algorithm/straightSkeleton.cpp @@ -20,6 +20,7 @@ #include <SFCGAL/algorithm/straightSkeleton.h> +#include <SFCGAL/Envelope.h> #include <SFCGAL/LineString.h> #include <SFCGAL/Polygon.h> #include <SFCGAL/Triangle.h> @@ -31,8 +32,10 @@ #include <SFCGAL/algorithm/orientation.h> #include <SFCGAL/algorithm/isValid.h> #include <SFCGAL/algorithm/intersection.h> +#include <SFCGAL/algorithm/translate.h> #include <CGAL/create_straight_skeleton_from_polygon_with_holes_2.h> +#include <CGAL/Straight_skeleton_converter_2.h> namespace SFCGAL { namespace algorithm { @@ -43,10 +46,13 @@ typedef CGAL::Polygon_with_holes_2<Kernel> Polygon_with_holes_2 ; typedef CGAL::Straight_skeleton_2<Kernel> Straight_skeleton_2 ; + template<class K> void straightSkeletonToMultiLineString( const CGAL::Straight_skeleton_2<K>& ss, - MultiLineString& result + MultiLineString& result, + bool innerOnly, + Kernel::Vector_2& translate ) { typedef CGAL::Straight_skeleton_2<K> Ss ; @@ -64,50 +70,113 @@ void straightSkeletonToMultiLineString( continue ; } + // Skip non-inner edges if requested + if ( innerOnly && ! it->is_inner_bisector() ) { + continue ; + } + // avoid duplicates if ( it->opposite() < it ) { continue ; } - result.addGeometry( new LineString( + std::auto_ptr<LineString> ls ( new LineString( Point( it->opposite()->vertex()->point() ), - Point( it->vertex()->point() ) - ) ); + Point( it->vertex()->point() ) ) + ); + algorithm::translate( *ls, translate ); + result.addGeometry( ls.release() ); } } +boost::shared_ptr< Straight_skeleton_2 > +straightSkeleton(const Polygon_with_holes_2& poly) +{ + boost::shared_ptr< CGAL::Straight_skeleton_2<CGAL::Epick> > sk = + CGAL::create_interior_straight_skeleton_2( + poly.outer_boundary().vertices_begin(), + poly.outer_boundary().vertices_end (), + poly.holes_begin (), + poly.holes_end (), + CGAL::Epick() + ); + return CGAL::convert_straight_skeleton_2< Straight_skeleton_2 > ( *sk ) ; +} + +// Throw an exception if any two polygon rings touch, +// since CGAL segfaults in that case. +// @todo find upstream reference to find out exact case +// See https://github.com/Oslandia/SFCGAL/issues/75 +void +checkNoTouchingHoles( const Polygon& g ) +{ + const size_t numRings = g.numRings(); + + for ( size_t ri=0; ri < numRings-1; ++ri ) { + for ( size_t rj=ri+1; rj < numRings; ++rj ) { + std::auto_ptr<Geometry> inter = g.is3D() + ? intersection3D( g.ringN( ri ), g.ringN( rj ) ) + : intersection( g.ringN( ri ), g.ringN( rj ) ); + + // @note this check would accept rings touching at + // more than a single point, which may be + // still dangerous. @todo find out ! + if ( ! inter->isEmpty() && inter->is< Point >() ) { + BOOST_THROW_EXCEPTION( NotImplementedException( + "straight skeleton of Polygon with touching interior rings is not implemented" + ) ); + } + } + } +} + +Polygon_with_holes_2 +preparePolygon( const Polygon& poly, Kernel::Vector_2& trans ) +{ + checkNoTouchingHoles( poly ); + Envelope env = poly.envelope(); + trans = Kernel::Vector_2(-env.xMin(), -env.yMin()); + + // @todo: avoid cloning ! + std::auto_ptr<Polygon> cloned ( poly.clone() ); + algorithm::translate( *cloned, trans ); + Polygon_with_holes_2 ret = cloned->toPolygon_with_holes_2(); + trans = -trans; + + return ret; +} /// /// /// -std::auto_ptr< MultiLineString > straightSkeleton( const Geometry& g, bool autoOrientation, NoValidityCheck ) +std::auto_ptr< MultiLineString > straightSkeleton( const Geometry& g, bool autoOrientation, NoValidityCheck, bool innerOnly ) { switch ( g.geometryTypeId() ) { case TYPE_TRIANGLE: - return straightSkeleton( g.as< Triangle >().toPolygon(), autoOrientation ) ; + return straightSkeleton( g.as< Triangle >().toPolygon(), autoOrientation, innerOnly ) ; case TYPE_POLYGON: - return straightSkeleton( g.as< Polygon >(), autoOrientation ) ; + return straightSkeleton( g.as< Polygon >(), autoOrientation, innerOnly ) ; case TYPE_MULTIPOLYGON: - return straightSkeleton( g.as< MultiPolygon >(), autoOrientation ) ; + return straightSkeleton( g.as< MultiPolygon >(), autoOrientation, innerOnly ) ; default: return std::auto_ptr< MultiLineString >( new MultiLineString ); } } -std::auto_ptr< MultiLineString > straightSkeleton( const Geometry& g, bool autoOrientation ) +std::auto_ptr< MultiLineString > straightSkeleton( const Geometry& g, bool autoOrientation, bool innerOnly ) { SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D( g ); - return straightSkeleton( g, autoOrientation, NoValidityCheck() ); + return straightSkeleton( g, autoOrientation, NoValidityCheck(), innerOnly ); } /// /// /// -std::auto_ptr< MultiLineString > straightSkeleton( const Polygon& g, bool /*autoOrientation*/ ) +std::auto_ptr< MultiLineString > straightSkeleton( const Polygon& g, bool /*autoOrientation*/, bool innerOnly ) { std::auto_ptr< MultiLineString > result( new MultiLineString ); @@ -115,32 +184,16 @@ std::auto_ptr< MultiLineString > straightSkeleton( const Polygon& g, bool /*auto return result ; } - // test if holes touch, since CGAL segfaults if it does - const size_t numRings = g.numRings(); - - for ( size_t ri=1; ri < numRings; ++ri ) { - for ( size_t rj=ri+1; rj < numRings; ++rj ) { - std::auto_ptr<Geometry> inter = g.is3D() - ? intersection3D( g.ringN( ri ), g.ringN( rj ) ) - : intersection( g.ringN( ri ), g.ringN( rj ) ); - - if ( ! inter->isEmpty() && inter->is< Point >() ) { - BOOST_THROW_EXCEPTION( NotImplementedException( - "straight skeleton of Polygon with touching interior rings is not implemented" - ) ); - } - } - } - - - Polygon_with_holes_2 polygon = g.toPolygon_with_holes_2() ; - boost::shared_ptr< Straight_skeleton_2 > skeleton = CGAL::create_interior_straight_skeleton_2( polygon ) ; + Kernel::Vector_2 trans; + Polygon_with_holes_2 polygon = preparePolygon( g, trans ); + boost::shared_ptr< Straight_skeleton_2 > skeleton = + straightSkeleton( polygon ); if ( !skeleton.get() ) { BOOST_THROW_EXCEPTION( Exception( "CGAL failed to create straightSkeleton" ) ) ; } - straightSkeletonToMultiLineString( *skeleton, *result ) ; + straightSkeletonToMultiLineString( *skeleton, *result, innerOnly, trans ) ; return result ; } @@ -148,24 +201,34 @@ std::auto_ptr< MultiLineString > straightSkeleton( const Polygon& g, bool /*auto /// /// /// -std::auto_ptr< MultiLineString > straightSkeleton( const MultiPolygon& g, bool /*autoOrientation*/ ) +std::auto_ptr< MultiLineString > straightSkeleton( const MultiPolygon& g, bool /*autoOrientation*/, bool innerOnly ) { std::auto_ptr< MultiLineString > result( new MultiLineString ); for ( size_t i = 0; i < g.numGeometries(); i++ ) { - Polygon_with_holes_2 polygon = g.polygonN( i ).toPolygon_with_holes_2() ; - boost::shared_ptr< Straight_skeleton_2 > skeleton = CGAL::create_interior_straight_skeleton_2( polygon ) ; + Kernel::Vector_2 trans; + Polygon_with_holes_2 polygon = preparePolygon( g.polygonN( i ), trans ); + boost::shared_ptr< Straight_skeleton_2 > skeleton = straightSkeleton( polygon ) ; if ( !skeleton.get() ) { BOOST_THROW_EXCEPTION( Exception( "CGAL failed to create straightSkeleton" ) ) ; } - straightSkeletonToMultiLineString( *skeleton, *result ) ; + straightSkeletonToMultiLineString( *skeleton, *result, innerOnly, trans ) ; } return result ; } +std::auto_ptr< MultiLineString > approximateMedialAxis( const Geometry& g ) +{ + SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D( g ); + + std::auto_ptr< MultiLineString > mx = + straightSkeleton( g, false, NoValidityCheck(), true ); + + return mx; +} }//namespace algorithm }//namespace SFCGAL diff --git a/src/algorithm/straightSkeleton.h b/src/algorithm/straightSkeleton.h index 52c26e2..8ac3b76 100644 --- a/src/algorithm/straightSkeleton.h +++ b/src/algorithm/straightSkeleton.h @@ -37,6 +37,14 @@ namespace algorithm { struct NoValidityCheck; /** + * @brief build an approximate medial axis for a Polygon + * @param g input geometry + * @ingroup public_api + * @pre g is a valid geometry + */ +SFCGAL_API std::auto_ptr< MultiLineString > approximateMedialAxis( const Geometry& g ); + +/** * @brief build a 2D straight skeleton for a Polygon * @todo add supports for TriangulatedSurface and PolyhedralSurface * @todo output M as distance to border? @@ -45,7 +53,7 @@ struct NoValidityCheck; * @ingroup public_api * @pre g is a valid geometry */ -SFCGAL_API std::auto_ptr< MultiLineString > straightSkeleton( const Geometry& g, bool autoOrientation = true ) ; +SFCGAL_API std::auto_ptr< MultiLineString > straightSkeleton( const Geometry& g, bool autoOrientation = true, bool innerOnly = false ) ; /** * @brief build a 2D straight skeleton for a Polygon @@ -55,18 +63,18 @@ SFCGAL_API std::auto_ptr< MultiLineString > straightSkeleton( const Geometry& g, * @pre g is a valid geometry * @warning No actual validity check is done */ -SFCGAL_API std::auto_ptr< MultiLineString > straightSkeleton( const Geometry& g, bool autoOrientation, NoValidityCheck ) ; +SFCGAL_API std::auto_ptr< MultiLineString > straightSkeleton( const Geometry& g, bool autoOrientation, NoValidityCheck, bool innerOnly = false ) ; /** * @brief build a 2D straight skeleton for a Polygon * @ingroup detail */ -SFCGAL_API std::auto_ptr< MultiLineString > straightSkeleton( const Polygon& g, bool autoOrientation = true ) ; +SFCGAL_API std::auto_ptr< MultiLineString > straightSkeleton( const Polygon& g, bool autoOrientation = true, bool innerOnly = false ) ; /** * @brief build a 2D straight skeleton for a Polygon * @ingroup detail */ -SFCGAL_API std::auto_ptr< MultiLineString > straightSkeleton( const MultiPolygon& g, bool autoOrientation = true ) ; +SFCGAL_API std::auto_ptr< MultiLineString > straightSkeleton( const MultiPolygon& g, bool autoOrientation = true, bool innerOnly = false ) ; }//namespace algorithm }//namespace SFCGAL diff --git a/src/algorithm/translate.cpp b/src/algorithm/translate.cpp index 1387fbf..bb99354 100644 --- a/src/algorithm/translate.cpp +++ b/src/algorithm/translate.cpp @@ -34,6 +34,7 @@ #include <SFCGAL/MultiSolid.h> #include <SFCGAL/detail/transform/AffineTransform3.h> +#include <SFCGAL/detail/transform/AffineTransform2.h> namespace SFCGAL { @@ -53,6 +54,17 @@ void translate( Geometry& g, const Kernel::Vector_3& v ) /// /// /// +void translate( Geometry& g, const Kernel::Vector_2& v ) +{ + transform::AffineTransform2 visitor( + CGAL::Aff_transformation_2< Kernel >( CGAL::TRANSLATION, v ) + ); + g.accept( visitor ) ; +} + +/// +/// +/// void translate( Geometry& g, Kernel::FT dx, Kernel::FT dy, Kernel::FT dz ) { translate( g, Kernel::Vector_3( dx,dy,dz ) ); diff --git a/src/algorithm/translate.h b/src/algorithm/translate.h index 6ee458f..9d1d939 100644 --- a/src/algorithm/translate.h +++ b/src/algorithm/translate.h @@ -35,13 +35,16 @@ namespace algorithm { /** * @brief translate a geometry from a given vector * @todo unittest - * @todo rename to translate3D and add translate for 2D */ SFCGAL_API void translate( Geometry& g, const Kernel::Vector_3& v ) ; /** * @brief translate a geometry from a given vector * @todo unittest - * @todo rename to translate3D and add translate for 2D + */ +SFCGAL_API void translate( Geometry& g, const Kernel::Vector_2& v ) ; +/** + * @brief translate a geometry from a given vector + * @todo unittest */ SFCGAL_API void translate( Geometry& g, Kernel::FT dx, Kernel::FT dy, Kernel::FT dz ) ; diff --git a/src/algorithm/union.cpp b/src/algorithm/union.cpp index 1f135b1..3932cbe 100644 --- a/src/algorithm/union.cpp +++ b/src/algorithm/union.cpp @@ -935,7 +935,7 @@ void collectPrimitives( const typename HandledBox<Dim>::Vector& boxes, detail::G std::auto_ptr<Geometry> union_( const Geometry& ga, const Geometry& gb, NoValidityCheck ) { - typename HandledBox<2>::Vector boxes; + HandledBox<2>::Vector boxes; compute_bboxes( detail::GeometrySet<2>( ga ), std::back_inserter( boxes ) ); const unsigned numBoxA = boxes.size(); compute_bboxes( detail::GeometrySet<2>( gb ), std::back_inserter( boxes ) ); @@ -960,7 +960,7 @@ std::auto_ptr<Geometry> union_( const Geometry& ga, const Geometry& gb ) std::auto_ptr<Geometry> union3D( const Geometry& ga, const Geometry& gb, NoValidityCheck ) { - typename HandledBox<3>::Vector boxes; + HandledBox<3>::Vector boxes; compute_bboxes( detail::GeometrySet<3>( ga ), std::back_inserter( boxes ) ); const unsigned numBoxA = boxes.size(); compute_bboxes( detail::GeometrySet<3>( gb ), std::back_inserter( boxes ) ); diff --git a/src/algorithm/union.h b/src/algorithm/union.h index 5443a0d..9bfb419 100644 --- a/src/algorithm/union.h +++ b/src/algorithm/union.h @@ -29,7 +29,7 @@ namespace SFCGAL { class Geometry; namespace detail { template <int Dim> class GeometrySet; -template <int Dim> class PrimitiveHandle; +template <int Dim> struct PrimitiveHandle; } namespace algorithm { diff --git a/src/capi/sfcgal_c.cpp b/src/capi/sfcgal_c.cpp index 1ff5d53..e8b32b6 100644 --- a/src/capi/sfcgal_c.cpp +++ b/src/capi/sfcgal_c.cpp @@ -731,6 +731,7 @@ SFCGAL_GEOMETRY_FUNCTION_BINARY_CONSTRUCTION( union_3d, SFCGAL::algorithm::union SFCGAL_GEOMETRY_FUNCTION_UNARY_CONSTRUCTION( convexhull, SFCGAL::algorithm::convexHull ) SFCGAL_GEOMETRY_FUNCTION_UNARY_CONSTRUCTION( convexhull_3d, SFCGAL::algorithm::convexHull3D ) SFCGAL_GEOMETRY_FUNCTION_UNARY_CONSTRUCTION( straight_skeleton, SFCGAL::algorithm::straightSkeleton ) +SFCGAL_GEOMETRY_FUNCTION_UNARY_CONSTRUCTION( approximate_medial_axis, SFCGAL::algorithm::approximateMedialAxis ) SFCGAL_GEOMETRY_FUNCTION_UNARY_CONSTRUCTION( tesselate, SFCGAL::algorithm::tesselate ) #define SFCGAL_GEOMETRY_FUNCTION_UNARY_MEASURE( name, sfcgal_function ) \ diff --git a/src/capi/sfcgal_c.h b/src/capi/sfcgal_c.h index 10b8195..617e593 100644 --- a/src/capi/sfcgal_c.h +++ b/src/capi/sfcgal_c.h @@ -132,7 +132,7 @@ SFCGAL_API void sfcgal_geometry_as_text( const sfcgal_geome /** * Returns a WKT representation of the given geometry using floating point coordinate values. * Floating point precision can be set via the numDecimals parameter. - * Setting numDecimals to -1 yields the same result as sfcgal_geometry_as_text. + * Setting numDecimals to -1 yields the same result as sfcgal_geometry_as_text. * @post buffer is returned allocated and must be freed by the caller * @ingroup capi */ @@ -782,6 +782,14 @@ SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_offset_polygon( const sfc */ SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_straight_skeleton( const sfcgal_geometry_t* geom ); +/** + * Returns the approximate medial axis for the given Polygon + * Approximate medial axis is based on straight skeleton + * @pre isValid(geom) == true + * @ingroup capi + */ +SFCGAL_API sfcgal_geometry_t* sfcgal_geometry_approximate_medial_axis( const sfcgal_geometry_t* geom ); + /*--------------------------------------------------------------------------------------* * * Error handling diff --git a/src/detail/GeometrySet.cpp b/src/detail/GeometrySet.cpp index 5947bfc..8d744e4 100644 --- a/src/detail/GeometrySet.cpp +++ b/src/detail/GeometrySet.cpp @@ -557,10 +557,10 @@ void recompose_points( const typename GeometrySet<Dim>::PointCollection& points, // compare less than struct ComparePoints { - bool operator()( const CGAL::Point_2<Kernel>& lhs, const CGAL::Point_2<Kernel>& rhs ) { + bool operator()( const CGAL::Point_2<Kernel>& lhs, const CGAL::Point_2<Kernel>& rhs ) const { return lhs.x() < rhs.x() || lhs.y() < rhs.y(); } - bool operator()( const CGAL::Point_3<Kernel>& lhs, const CGAL::Point_3<Kernel>& rhs ) { + bool operator()( const CGAL::Point_3<Kernel>& lhs, const CGAL::Point_3<Kernel>& rhs ) const { return lhs.x() < rhs.x() || lhs.y() < rhs.y() || lhs.z() < rhs.z(); } }; diff --git a/src/detail/TestGeometry.h b/src/detail/TestGeometry.h index 6f12c76..a523371 100644 --- a/src/detail/TestGeometry.h +++ b/src/detail/TestGeometry.h @@ -62,6 +62,7 @@ const std::vector< TestGeometry > createTestGeometries() {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,-0.5 0.5,-0.1 0.5,0.1 -0.5,-0.5 -0.5),(0.1 -0.5,0.1 0.5,0.5 0.5,0.5 -0.5,0.1 -0.5))", true, "one contact point between 2 interior rings"}, {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-.7 0,.7 0,0 -.7,-.7 0),(-.5 0,-.5 .5,0 .5,-.5 0),(.5 0,.1 .5,.5 .5,.5 0))", true, "3 touching interior ring define a connected interior"}, // invalid + {"POLYGON((1 2,1 2,1 2,1 2))", false, "degenerated to a point"}, {"POLYGON((-1.0 -1.0,-1.0 1.0,-1.0 -1.0))", false, "only 3 points"}, {"POLYGON((-1.0 -1.0,-1.0 1.0,1.0 1.0,-1.0 -1.0,-1.0 1.0))", false, "not closed"}, {"POLYGON((-1.0 -1.0,1.0 -1.0,1.0 -1.0,-1.0 -1.0,-1.0 -1.0))", false, "zero surface"}, @@ -88,6 +89,7 @@ const std::vector< TestGeometry > createTestGeometries() {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0),(1.0 -0.5 -0.5,1.0 -0.5 0.5,1.0 -0.1 0.5,1.0 -0.1 -0.5,1.0 -0.5 -0.5),(1.0 0.1 -0.5,1.0 0.1 0.5,1.0 0.5 0.5,1.0 0.5 -0.5,1.0 0.1 -0.5))", true, "two interior rings"}, {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0),(1.0 -0.5 -0.5,1.0 -0.5 0.5,1.0 -0.1 0.5,1.0 0.1 -0.5,1.0 -0.5 -0.5),(1.0 0.1 -0.5,1.0 0.1 0.5,1.0 0.5 0.5,1.0 0.5 -0.5,1.0 0.1 -0.5))", true, "one contact point between 2 interior rings"}, // invalid + {"POLYGON((1 2 0,1 2 0,1 2 0,1 2 0))", false, "degenerated to a point"}, {"POLYGON((1.0 -1.0 -1.0,1.0 -1.0 1.0,1.0 -1.0 -1.0))", false, "only 3 points"}, {"POLYGON((1.0 -1.0 -1.0,1.0 -1.0 1.0,1.0 1.0 1.0,1.0 -1.0 -1.0,1.0 -1.0 1.0))", false, "not closed"}, {"POLYGON((1.0 -1.0 -1.0,1.0 1.0 -1.0,1.0 1.0 -1.0,1.0 -1.0 -1.0,1.0 -1.0 -1.0))", false, "zero surface"}, diff --git a/src/detail/graph/Edge.h b/src/detail/graph/Edge.h index e751ba5..b69b84d 100644 --- a/src/detail/graph/Edge.h +++ b/src/detail/graph/Edge.h @@ -28,7 +28,7 @@ namespace graph { /** * @brief [private]An edge in a GeometryGraph with minimal requirements (some algorithms could need - * more informations) + * more information) */ struct SFCGAL_API Edge { Edge( const int& face_ = -1 ); diff --git a/src/detail/graph/GeometryGraph.h b/src/detail/graph/GeometryGraph.h index 7b54883..2584271 100644 --- a/src/detail/graph/GeometryGraph.h +++ b/src/detail/graph/GeometryGraph.h @@ -52,7 +52,7 @@ inline EdgeDirection reverse( const EdgeDirection& direction ) * * @brief [private]Represents the vertices and edges for a list of geometries. * - * A boost::adjancency_list is wrapped in order to be able to annex some informations + * A boost::adjancency_list is wrapped in order to be able to annex some information * and to provide basic functionalities. * * @warning duplicate matching is performed in GeometryGraphBuilder (allows to modify position once it's done) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 67469fc..64f8014 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -18,11 +18,3 @@ if( SFCGAL_BUILD_BENCH ) add_subdirectory( bench ) endif() -if(CMAKE_SYSTEM_NAME MATCHES "Linux") - add_test( style-test ${CMAKE_SOURCE_DIR}/script/test-style-SFCGAL.sh ) -endif() - - - - - diff --git a/test/bench/BenchStraightSkeleton.cpp b/test/bench/BenchStraightSkeleton.cpp new file mode 100644 index 0000000..35f2a0d --- /dev/null +++ b/test/bench/BenchStraightSkeleton.cpp @@ -0,0 +1,95 @@ +/** + * SFCGAL + * + * Copyright (C) 2015 Sandro Santilli <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ +#include <SFCGAL/Point.h> +#include <SFCGAL/LineString.h> +#include <SFCGAL/Polygon.h> +#include <SFCGAL/Triangle.h> +#include <SFCGAL/PolyhedralSurface.h> +#include <SFCGAL/TriangulatedSurface.h> +#include <SFCGAL/Solid.h> +#include <SFCGAL/GeometryCollection.h> +#include <SFCGAL/MultiPoint.h> +#include <SFCGAL/MultiLineString.h> +#include <SFCGAL/MultiPolygon.h> +#include <SFCGAL/MultiSolid.h> +#include <SFCGAL/io/wkt.h> +#include <SFCGAL/algorithm/straightSkeleton.h> + +#include "../test_config.h" +#include "Bench.h" + +#include <boost/test/unit_test.hpp> + + +using namespace boost::unit_test ; +using namespace SFCGAL ; + +BOOST_AUTO_TEST_SUITE( SFCGAL_BenchStraightSkeleton ) + + +// See https://github.com/Oslandia/SFCGAL/issues/80 +BOOST_AUTO_TEST_CASE( testPolygon80 ) +{ + std::auto_ptr< Geometry > g( io::readWkt( +"POLYGON((1684000 5402672.31399816,1683946.034501 5402654.436405,1683891.240865 5402626.55208,1683828.852807 5402603.566759,1683763.966259 5402588.179891,1683710.005454 5402593.368835,1683643.321311 5402617.6139,1683558.455081 5402667.62372,1683479.657793 5402723.692308,1683393.274328 5402782.790279,1683344.780518 5402828.261023,1683302.347403 5402879.780536,1683275.07015 5402920.702207,1683275.07015 5402961.61388,1683285.674306 5403005.564933,1683312.951559 5403060.123828,1683325.081196 [...] + ) ); + + bench().start( "StraightSkeleton of polygon - issue #80" ) ; + + int iterations = 1; + for ( int i = 0; i < iterations; i++ ) { + std::auto_ptr< Geometry > sum( algorithm::straightSkeleton( *g ) ); + } + + bench().stop(); +} + +// See https://github.com/Oslandia/SFCGAL/issues/80 +BOOST_AUTO_TEST_CASE( testMultiPolygon80 ) +{ + std::auto_ptr< Geometry > g( io::readWkt( +"MULTIPOLYGON(((1684000 5402672.31399816,1683946.034501 5402654.436405,1683891.240865 5402626.55208,1683828.852807 5402603.566759,1683763.966259 5402588.179891,1683710.005454 5402593.368835,1683643.321311 5402617.6139,1683558.455081 5402667.62372,1683479.657793 5402723.692308,1683393.274328 5402782.790279,1683344.780518 5402828.261023,1683302.347403 5402879.780536,1683275.07015 5402920.702207,1683275.07015 5402961.61388,1683285.674306 5403005.564933,1683312.951559 5403060.123828,1683325. [...] + ) ); + + bench().start( "StraightSkeleton of multipolygon - issue #80" ) ; + + int iterations = 1; + for ( int i = 0; i < iterations; i++ ) { + std::auto_ptr< Geometry > sum( algorithm::straightSkeleton( *g ) ); + } + + bench().stop(); +} + + + +BOOST_AUTO_TEST_SUITE_END() + + + + + + +//BOOST_AUTO_TEST_CASE( testTemp ){ +// std::auto_ptr< Geometry > gA( io::readWkt("MULTIPOLYGON(((11.795461 32.713032,11.381695 35.857648,15.188336 38.091981,28.428825 38.257487,30.994170 33.788822,30.580405 29.816675,26.773764 22.617159,11.050683 18.562259,-0.534745 21.044851,-3.513855 26.837565,3.520155 26.506553,4.099426 24.685985,4.678698 22.782665,6.582018 21.541369,8.899104 21.458616,16.098620 21.706875,18.332952 25.016998,17.919187 27.499589,16.429632 27.830601,14.360805 26.175540,13.036756 24.520479,10.885177 23.527 [...] +// std::auto_ptr< Geometry > gB( io::readWkt( "POLYGON((-1 0,0 -1,1 0,0 1,-1 0))" ) ); +// +// std::auto_ptr< Geometry > sum( algorithm::minkowskiSum( *gA, gB->as< Polygon >() ) ); +// std::cout << sum->asText(6) << std::endl ; +//} diff --git a/test/unit/SFCGAL/algorithm/StraightSkeletonTest.cpp b/test/unit/SFCGAL/algorithm/ApproximateMedialAxis.cpp similarity index 55% copy from test/unit/SFCGAL/algorithm/StraightSkeletonTest.cpp copy to test/unit/SFCGAL/algorithm/ApproximateMedialAxis.cpp index 7d76ef8..ed7ae4f 100644 --- a/test/unit/SFCGAL/algorithm/StraightSkeletonTest.cpp +++ b/test/unit/SFCGAL/algorithm/ApproximateMedialAxis.cpp @@ -40,24 +40,17 @@ using namespace boost::unit_test ; using namespace SFCGAL ; -BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_StraightSkeletonTest ) +BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_ApproximateMedialAxisTest ) BOOST_AUTO_TEST_CASE( testTriangle ) { std::auto_ptr< Geometry > g( io::readWkt( "TRIANGLE((0 0,1 0,1 1,0 0))" ) ); - std::string expectedWKT( "MULTILINESTRING((0.0 0.0,0.7 0.3),(1.0 0.0,0.7 0.3),(1.0 1.0,0.7 0.3))" ); + std::string expectedWKT( "MULTILINESTRING EMPTY"); { - std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ) ; - BOOST_CHECK_EQUAL( result->numGeometries(), 3U ); - BOOST_CHECK_EQUAL( result->asText( 1 ), expectedWKT ); - } - // check orientation insensitive - { - g->as< Triangle >().reverse() ; - std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ) ; - BOOST_CHECK_EQUAL( result->numGeometries(), 3U ); + std::auto_ptr< MultiLineString > result( algorithm::approximateMedialAxis( *g ) ) ; + BOOST_CHECK_EQUAL( result->numGeometries(), 0U ); BOOST_CHECK_EQUAL( result->asText( 1 ), expectedWKT ); } } @@ -65,29 +58,25 @@ BOOST_AUTO_TEST_CASE( testTriangle ) BOOST_AUTO_TEST_CASE( testPolygon ) { - std::auto_ptr< Geometry > g( io::readWkt( "POLYGON((0 0,10 0,10 10,0 10,0 0))" ) ); + std::auto_ptr< Geometry > g( io::readWkt( "POLYGON((0 0,20 0,20 10,0 10,0 0))" ) ); - std::string expectedWKT( "MULTILINESTRING((0 0,5 5),(10 0,5 5),(10 10,5 5),(0 10,5 5))" ); + std::string expectedWKT( "MULTILINESTRING((5 5,15 5))" ); { - std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ) ; - BOOST_CHECK_EQUAL( result->numGeometries(), 4U ); - BOOST_CHECK_EQUAL( result->asText( 0 ), expectedWKT ); - } - // check orientation insensitive - { - g->as< Polygon >().exteriorRing().reverse() ; - std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ) ; - BOOST_CHECK_EQUAL( result->numGeometries(), 4U ); + std::auto_ptr< MultiLineString > result( algorithm::approximateMedialAxis( *g ) ) ; + BOOST_CHECK_EQUAL( result->numGeometries(), 1U ); BOOST_CHECK_EQUAL( result->asText( 0 ), expectedWKT ); } } BOOST_AUTO_TEST_CASE( testPolygonWithHole ) { - std::auto_ptr< Geometry > g( io::readWkt( "POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,-0.5 0.5,0.5 0.5,1.0 -0.5,-0.5 -0.5))" ) ); - - // just for valgrind - std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ) ; + std::auto_ptr< Geometry > g( io::readWkt( "POLYGON((0 0,10 0,10 10,0 10,0 0),(4 4,4 6,6 6,6 4,4 4))" ) ); + std::string expectedWKT( "MULTILINESTRING((2 2,8 2),(2 2,2 8),(8 2,8 8),(2 8,8 8))" ); + { + std::auto_ptr< MultiLineString > result( algorithm::approximateMedialAxis( *g ) ) ; + BOOST_CHECK_EQUAL( result->numGeometries(), 4U ); + BOOST_CHECK_EQUAL( result->asText( 0 ), expectedWKT ); + } } BOOST_AUTO_TEST_CASE( testPolygonWithTouchingHoles ) @@ -95,15 +84,15 @@ BOOST_AUTO_TEST_CASE( testPolygonWithTouchingHoles ) std::auto_ptr< Geometry > g( io::readWkt( "POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,-0.5 0.5,-0.1 0.5,0.1 -0.5,-0.5 -0.5),(0.1 -0.5,0.1 0.5,0.5 0.5,0.5 -0.5,0.1 -0.5))" ) ); // just for valgrind - BOOST_CHECK_THROW( std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ), NotImplementedException ) ; + BOOST_CHECK_THROW( std::auto_ptr< MultiLineString > result( algorithm::approximateMedialAxis( *g ) ), NotImplementedException ) ; } BOOST_AUTO_TEST_CASE( testMultiPolygon ) { std::auto_ptr< Geometry > g( io::readWkt( "MULTIPOLYGON(((3.000000 0.000000,2.875000 0.484123,2.750000 0.661438,2.625000 0.780625,2.500000 0.866025,2.375000 0.927025,2.250000 0.968246,2.125000 0.992157,2.000000 1.000000,1.875000 1.484123,1.750000 1.661438,1.625000 1.780625,1.500000 1.866025,1.375000 1.927025,1.250000 1.968246,1.125000 1.992157,1.000000 2.000000,0.750000 2.661438,0.500000 2.866025,0.250000 2.968246,0.000000 3.000000,-0.250000 2.968246,-0.500000 2.866025,-0.750000 2.66 [...] - std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ) ; - BOOST_CHECK_EQUAL( result->numGeometries(), 220U ); + std::auto_ptr< MultiLineString > result( algorithm::approximateMedialAxis( *g ) ) ; + BOOST_CHECK_EQUAL( result->numGeometries(), 108U ); } @@ -113,9 +102,16 @@ BOOST_AUTO_TEST_CASE( testInvalidTypes ) wkt.push_back( "POINT(1 2)" ); wkt.push_back( "LINESTRING(0 0,1 1)" ); - std::auto_ptr< Geometry > g( io::readWkt( "MULTIPOLYGON(((3.000000 0.000000,2.875000 0.484123,2.750000 0.661438,2.625000 0.780625,2.500000 0.866025,2.375000 0.927025,2.250000 0.968246,2.125000 0.992157,2.000000 1.000000,1.875000 1.484123,1.750000 1.661438,1.625000 1.780625,1.500000 1.866025,1.375000 1.927025,1.250000 1.968246,1.125000 1.992157,1.000000 2.000000,0.750000 2.661438,0.500000 2.866025,0.250000 2.968246,0.000000 3.000000,-0.250000 2.968246,-0.500000 2.866025,-0.750000 2.66 [...] - std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ) ; - BOOST_CHECK_EQUAL( result->numGeometries(), 220U ); + for ( std::vector< std::string >::const_iterator it=wkt.begin(), + itE=wkt.end(); + it != itE; ++it ) + { + std::auto_ptr< Geometry > g( io::readWkt( *it ) ); + std::auto_ptr< MultiLineString > result( + algorithm::approximateMedialAxis( *g ) + ); + BOOST_CHECK_EQUAL( result->numGeometries(), 0U ); + } } diff --git a/test/unit/SFCGAL/algorithm/StraightSkeletonTest.cpp b/test/unit/SFCGAL/algorithm/StraightSkeletonTest.cpp index 7d76ef8..abb7798 100644 --- a/test/unit/SFCGAL/algorithm/StraightSkeletonTest.cpp +++ b/test/unit/SFCGAL/algorithm/StraightSkeletonTest.cpp @@ -45,9 +45,9 @@ BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_StraightSkeletonTest ) BOOST_AUTO_TEST_CASE( testTriangle ) { - std::auto_ptr< Geometry > g( io::readWkt( "TRIANGLE((0 0,1 0,1 1,0 0))" ) ); + std::auto_ptr< Geometry > g( io::readWkt( "TRIANGLE((1 1,2 1,2 2,1 1))" ) ); - std::string expectedWKT( "MULTILINESTRING((0.0 0.0,0.7 0.3),(1.0 0.0,0.7 0.3),(1.0 1.0,0.7 0.3))" ); + std::string expectedWKT( "MULTILINESTRING((1.0 1.0,1.7 1.3),(2.0 1.0,1.7 1.3),(2.0 2.0,1.7 1.3))" ); { std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ) ; BOOST_CHECK_EQUAL( result->numGeometries(), 3U ); @@ -65,9 +65,9 @@ BOOST_AUTO_TEST_CASE( testTriangle ) BOOST_AUTO_TEST_CASE( testPolygon ) { - std::auto_ptr< Geometry > g( io::readWkt( "POLYGON((0 0,10 0,10 10,0 10,0 0))" ) ); + std::auto_ptr< Geometry > g( io::readWkt( "POLYGON((1 1,11 1,11 11,1 11,1 1))" ) ); - std::string expectedWKT( "MULTILINESTRING((0 0,5 5),(10 0,5 5),(10 10,5 5),(0 10,5 5))" ); + std::string expectedWKT( "MULTILINESTRING((1 1,6 6),(11 1,6 6),(11 11,6 6),(1 11,6 6))" ); { std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ) ; BOOST_CHECK_EQUAL( result->numGeometries(), 4U ); @@ -81,21 +81,29 @@ BOOST_AUTO_TEST_CASE( testPolygon ) BOOST_CHECK_EQUAL( result->asText( 0 ), expectedWKT ); } } + BOOST_AUTO_TEST_CASE( testPolygonWithHole ) { - std::auto_ptr< Geometry > g( io::readWkt( "POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,-0.5 0.5,0.5 0.5,1.0 -0.5,-0.5 -0.5))" ) ); - - // just for valgrind - std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ) ; + std::auto_ptr< Geometry > g( io::readWkt( "POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,-0.5 0.5,0.5 0.5,-0.5 -0.5))" ) ); + std::string expectedWKT( "MULTILINESTRING((-1.00 -1.00,-0.75 -0.75),(1.00 -1.00,0.41 -0.41),(1.00 1.00,0.75 0.75),(-1.00 1.00,-0.75 0.75),(-0.50 -0.50,-0.65 -0.85),(-0.50 0.50,-0.75 0.75),(0.50 0.50,0.85 0.65),(-0.65 -0.85,0.41 -0.41),(-0.65 -0.85,-0.75 -0.75),(0.85 0.65,0.75 0.75),(0.85 0.65,0.41 -0.41),(-0.75 -0.75,-0.75 0.75),(0.75 0.75,-0.75 0.75))" ); + { + std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ) ; + //BOOST_CHECK_EQUAL( result->numGeometries(), 4U ); + BOOST_CHECK_EQUAL( result->asText( 2 ), expectedWKT ); + } +} +BOOST_AUTO_TEST_CASE( testPolygonWithHoleTouchingShell ) +{ + std::auto_ptr< Geometry > g( io::readWkt( "POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,-0.5 0.5,0.5 0.5,1.0 -0.5,-0.5 -0.5))" ) ); + BOOST_CHECK_THROW( algorithm::straightSkeleton( *g ), NotImplementedException ); } BOOST_AUTO_TEST_CASE( testPolygonWithTouchingHoles ) { std::auto_ptr< Geometry > g( io::readWkt( "POLYGON((-1.0 -1.0,1.0 -1.0,1.0 1.0,-1.0 1.0,-1.0 -1.0),(-0.5 -0.5,-0.5 0.5,-0.1 0.5,0.1 -0.5,-0.5 -0.5),(0.1 -0.5,0.1 0.5,0.5 0.5,0.5 -0.5,0.1 -0.5))" ) ); - // just for valgrind - BOOST_CHECK_THROW( std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ), NotImplementedException ) ; + BOOST_CHECK_THROW( algorithm::straightSkeleton( *g ), NotImplementedException ); } @@ -113,11 +121,31 @@ BOOST_AUTO_TEST_CASE( testInvalidTypes ) wkt.push_back( "POINT(1 2)" ); wkt.push_back( "LINESTRING(0 0,1 1)" ); - std::auto_ptr< Geometry > g( io::readWkt( "MULTIPOLYGON(((3.000000 0.000000,2.875000 0.484123,2.750000 0.661438,2.625000 0.780625,2.500000 0.866025,2.375000 0.927025,2.250000 0.968246,2.125000 0.992157,2.000000 1.000000,1.875000 1.484123,1.750000 1.661438,1.625000 1.780625,1.500000 1.866025,1.375000 1.927025,1.250000 1.968246,1.125000 1.992157,1.000000 2.000000,0.750000 2.661438,0.500000 2.866025,0.250000 2.968246,0.000000 3.000000,-0.250000 2.968246,-0.500000 2.866025,-0.750000 2.66 [...] - std::auto_ptr< MultiLineString > result( algorithm::straightSkeleton( *g ) ) ; - BOOST_CHECK_EQUAL( result->numGeometries(), 220U ); + for ( std::vector< std::string >::const_iterator it=wkt.begin(), + itE=wkt.end(); + it != itE; ++it ) + { + std::auto_ptr< Geometry > g( io::readWkt( *it ) ); + std::auto_ptr< MultiLineString > result( + algorithm::straightSkeleton( *g ) + ); + BOOST_CHECK_EQUAL( result->numGeometries(), 0U ); + } } +// See https://github.com/Oslandia/SFCGAL/issues/75 +BOOST_AUTO_TEST_CASE( testPostgisIssue3107 ) +{ + std::auto_ptr< Geometry > g( io::readWkt( "POLYGON((1347259.25 7184745.94,1347273.17 7184758.16,1347280.39 7184749.95,1347278.04 7184747.88,1347281.66 7184743.76,1347284.01 7184745.83,1347293.5 7184735.05,1347279.61 7184722.85,1347269.29 7184734.6,1347270.35 7184735.51,1347267.31 7184738.96,1347266.22 7184738.01,1347259.25 7184745.94),(1347267.31 7184738.96,1347269.31 7184736.7,1347272.57 7184739.55,1347270.56 7184741.83,1347267.31 7184738.96))" ) ); + BOOST_CHECK_THROW( algorithm::straightSkeleton( *g ), NotImplementedException ); +} + +// See https://github.com/Oslandia/SFCGAL/issues/91 +BOOST_AUTO_TEST_CASE( testMultiPolygonWithTouchingHoles ) +{ + std::auto_ptr< Geometry > g( io::readWkt( "MULTIPOLYGON(((1347259.25 7184745.94,1347273.17 7184758.16,1347280.39 7184749.95,1347278.04 7184747.88,1347281.66 7184743.76,1347284.01 7184745.83,1347293.5 7184735.05,1347279.61 7184722.85,1347269.29 7184734.6,1347270.35 7184735.51,1347267.31 7184738.96,1347266.22 7184738.01,1347259.25 7184745.94),(1347267.31 7184738.96,1347269.31 7184736.7,1347272.57 7184739.55,1347270.56 7184741.83,1347267.31 7184738.96)))" ) ); + BOOST_CHECK_THROW( algorithm::straightSkeleton( *g ), NotImplementedException ); +} BOOST_AUTO_TEST_SUITE_END() diff --git a/test/unit/SFCGAL/capi/sfcgal_cTest.cpp b/test/unit/SFCGAL/capi/sfcgal_cTest.cpp index 26b642a..356ac49 100644 --- a/test/unit/SFCGAL/capi/sfcgal_cTest.cpp +++ b/test/unit/SFCGAL/capi/sfcgal_cTest.cpp @@ -74,6 +74,34 @@ BOOST_AUTO_TEST_CASE( testErrorOnBadGeometryType ) BOOST_CHECK( hasError == true ); } +BOOST_AUTO_TEST_CASE( testStraightSkeletonPolygon ) +{ + sfcgal_set_error_handlers( printf, on_error ); + + std::auto_ptr<Geometry> g( io::readWkt( +"POLYGON((0 0, 20 0, 20 10, 0 10, 0 0))" + ) ); + + hasError = false; + sfcgal_geometry_t* sk = sfcgal_geometry_straight_skeleton( g.get() ); + BOOST_CHECK( hasError == false ); + BOOST_CHECK_EQUAL( 5, sfcgal_geometry_collection_num_geometries( sk ) ); +} + +BOOST_AUTO_TEST_CASE( testStraightSkeletonMultiPolygon ) +{ + sfcgal_set_error_handlers( printf, on_error ); + + std::auto_ptr<Geometry> g( io::readWkt( +"MULTIPOLYGON(((0 0, 20 0, 20 10, 0 10, 0 0)),((100 0,200 0,150 100,100 0)))" + ) ); + + hasError = false; + sfcgal_geometry_t* sk = sfcgal_geometry_straight_skeleton( g.get() ); + BOOST_CHECK( hasError == false ); + BOOST_CHECK_EQUAL( 8, sfcgal_geometry_collection_num_geometries( sk ) ); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/travis/linux/before_install.sh b/travis/linux/before_install.sh new file mode 100755 index 0000000..00d52b7 --- /dev/null +++ b/travis/linux/before_install.sh @@ -0,0 +1,16 @@ +export DEBIAN_FRONTEND=noninteractive +sudo add-apt-repository ppa:apokluda/boost1.53 --yes +sudo apt-get update -qq +sudo apt-get install --force-yes \ + cmake libboost-chrono1.53-dev libboost-program-options1.53-dev libboost-filesystem1.53-dev libboost-timer1.53-dev \ + libboost-test1.53-dev libboost-date-time1.53-dev libboost-thread1.53-dev \ + libboost-system1.53-dev libboost-serialization1.53-dev \ + libmpfr-dev libgmp-dev +#CGAL +wget https://gforge.inria.fr/frs/download.php/file/32994/CGAL-4.3.tar.gz +tar xzf CGAL-4.3.tar.gz +cd CGAL-4.3 && cmake . && make && sudo make install && cd .. + + +cmake --version +clang --version diff --git a/viewer/src/SFCGAL/viewer/plugins/DataPlugin.cpp b/viewer/src/SFCGAL/viewer/plugins/DataPlugin.cpp index b9122ef..71b125c 100644 --- a/viewer/src/SFCGAL/viewer/plugins/DataPlugin.cpp +++ b/viewer/src/SFCGAL/viewer/plugins/DataPlugin.cpp @@ -91,7 +91,7 @@ void DataPlugin::load() { QMenu* pluginMenu = viewerWindow()->menuBar()->addMenu( "Data" ) ; - QAction* actionDisplayInformations = pluginMenu->addAction( QString( "&display informations" ) ); + QAction* actionDisplayInformations = pluginMenu->addAction( QString( "&display information" ) ); connect( actionDisplayInformations, SIGNAL( triggered() ), this, SLOT( displayInformations() ) ); } -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/sfcgal.git _______________________________________________ Pkg-grass-devel mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel

