Skip to content

Commit

Permalink
Merge branch 'master' into 'visibility2D'
Browse files Browse the repository at this point in the history
# Conflicts:
#   NEWS
  • Loading branch information
lbartoletti committed Oct 10, 2023
2 parents 59842f2 + 34f5a2e commit bba3284
Show file tree
Hide file tree
Showing 15 changed files with 554 additions and 144 deletions.
13 changes: 9 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,25 @@ endif ()
#-----------------------------------------------------------

#-- find CGAL ---------------------------------------------
if( CGAL_USE_GMPXX )
add_definitions( "-DCGAL_USE_GMPXX" )
endif()
option( CGAL_USE_AUTOLINK "disable CGAL autolink" OFF )

if( ${CGAL_USE_AUTOLINK} )
add_definitions( "-DCGAL_NO_AUTOLINK" )
endif()

find_package( CGAL 5.3 COMPONENTS Core REQUIRED )
find_package( CGAL 5.6 COMPONENTS Core REQUIRED )
message( STATUS "CGAL ${CGAL_VERSION} found" )

# For CGAL >= 5
add_definitions( "-DCGAL_USE_GMPXX=1" )

include_directories( ${CMAKE_BINARY_DIR}/include )

#-- BOOST --------------------------------------------------
if( NOT CGAL_USE_GMPXX )
add_definitions( "-DCGAL_DO_NOT_USE_BOOST_MP" )
endif()

option( Boost_USE_AUTO_LINK "boost use autolink" OFF )
if( NOT ${Boost_USE_AUTO_LINK} )
add_definitions( "-DBOOST_ALL_NO_LIB" )
Expand Down
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
1.5.0 (2023-xx-xx):
* Add polygon partition (Raphaël Delhome, Loïc Bartoletti)
* WKT: Fix triangle code (Loïc Bartoletti)
* Straight Skeleton: Add a version with extrusion (Loïc Bartoletti)
* Add visibility algorithms (Loïc Bartoletti)
1.4.1 (2022-01-27):
* Add alpha-shapes algorithm (Loïc Bartoletti, Hugo Mercier)
Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ set_target_properties( SFCGAL PROPERTIES VERSION ${SFCGAL_VERSION}

target_link_libraries( SFCGAL CGAL::CGAL CGAL::CGAL_Core)

if( "${CGAL_VERSION}" VERSION_GREATER_EQUAL "5.0.0")
if( CGAL_USE_GMPXX )
target_link_libraries( SFCGAL gmpxx )
endif()

Expand Down
18 changes: 18 additions & 0 deletions src/PolyhedralSurface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,24 @@ PolyhedralSurface::PolyhedralSurface(const MarkedPolyhedron &poly) : Surface()
}
}

///
///
///
PolyhedralSurface::PolyhedralSurface(const Mesh &sm) : Surface()
{

using vertex_descriptor = Mesh::Vertex_index;
for (auto face : sm.faces()) {
auto *new_face = new LineString();
for (vertex_descriptor vd : vertices_around_face(sm.halfedge(face), sm)) {
new_face->addPoint(Point(sm.point(vd)));
}

new_face->addPoint(new_face->startPoint().clone());
_polygons.push_back(new Polygon(new_face));
}
}

///
///
///
Expand Down
8 changes: 8 additions & 0 deletions src/PolyhedralSurface.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@
#include <boost/serialization/base_object.hpp>
#include <vector>

#include <SFCGAL/Kernel.h>
#include <SFCGAL/Point.h>
#include <SFCGAL/Polygon.h>
#include <SFCGAL/TriangulatedSurface.h>
#include <SFCGAL/triangulate/triangulatePolygon.h>

#include <CGAL/Polyhedron_3.h>
#include <CGAL/Surface_mesh.h>

using Mesh = CGAL::Surface_mesh<SFCGAL::Kernel::Point_3>;

namespace SFCGAL {

Expand All @@ -42,6 +46,10 @@ class SFCGAL_API PolyhedralSurface : public Surface {
* Constructor from a CGAL::Polyhedron_3
*/
PolyhedralSurface(const detail::MarkedPolyhedron &poly);
/**
* Constructor from a CGAL::Surface_mesh
*/
PolyhedralSurface(const Mesh &sm);
/**
* Copy constructor
*/
Expand Down
28 changes: 21 additions & 7 deletions src/algorithm/extrude.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ extrude(const Point &g, const Kernel::Vector_3 &v) -> LineString *;
auto
extrude(const LineString &g, const Kernel::Vector_3 &v) -> PolyhedralSurface *;
auto
extrude(const Polygon &g, const Kernel::Vector_3 &v) -> Solid *;
extrude(const Polygon &g, const Kernel::Vector_3 &v, bool addTop = true)
-> Solid *;
auto
extrude(const Triangle &g, const Kernel::Vector_3 &v) -> Solid *;

Expand Down Expand Up @@ -120,7 +121,7 @@ extrude(const LineString &g, const Kernel::Vector_3 &v) -> PolyhedralSurface *
///
///
auto
extrude(const Polygon &g, const Kernel::Vector_3 &v) -> Solid *
extrude(const Polygon &g, const Kernel::Vector_3 &v, bool addTop) -> Solid *
{
if (g.isEmpty()) {
return new Solid();
Expand All @@ -142,11 +143,12 @@ extrude(const Polygon &g, const Kernel::Vector_3 &v) -> Solid *
polyhedralSurface.addPolygon(bottom);

// "top"
Polygon top(bottom);
top.reverse();
translate(top, v);
polyhedralSurface.addPolygon(top);

if (addTop) {
Polygon top(bottom);
top.reverse();
translate(top, v);
polyhedralSurface.addPolygon(top);
}
// exterior ring and interior rings extruded
for (size_t i = 0; i < bottom.numRings(); i++) {
std::unique_ptr<PolyhedralSurface> boundaryExtruded(
Expand Down Expand Up @@ -391,5 +393,17 @@ extrude(const Geometry &g, const double &dx, const double &dy, const double &dz)
return extrude(g, Kernel::FT(dx), Kernel::FT(dy), Kernel::FT(dz));
}

SFCGAL_API auto
extrude(const Polygon &g, const double &height) -> std::unique_ptr<Geometry>
{

if (!std::isfinite(height)) {
BOOST_THROW_EXCEPTION(NonFiniteValueException(
"trying to extrude with non finite value in direction"));
}

return std::unique_ptr<Geometry>(
extrude(g, Kernel::Vector_3(0.0, 0.0, height), false));
}
} // namespace algorithm
} // namespace SFCGAL
2 changes: 2 additions & 0 deletions src/algorithm/extrude.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ SFCGAL_API std::unique_ptr<Geometry>
SFCGAL_API std::unique_ptr<Geometry>
extrude(const Geometry &g, const Kernel::Vector_3 &v);

SFCGAL_API std::unique_ptr<Geometry>
extrude(const Polygon &g, const double &height);
} // namespace algorithm
} // namespace SFCGAL

Expand Down
49 changes: 49 additions & 0 deletions src/algorithm/straightSkeleton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,34 @@
#include <SFCGAL/MultiLineString.h>
#include <SFCGAL/MultiPolygon.h>
#include <SFCGAL/Polygon.h>
#include <SFCGAL/PolyhedralSurface.h>
#include <SFCGAL/Solid.h>
#include <SFCGAL/Triangle.h>

#include <SFCGAL/Exception.h>

#include <SFCGAL/algorithm/intersection.h>
#include <SFCGAL/algorithm/isValid.h>
#include <SFCGAL/algorithm/orientation.h>
#include <SFCGAL/algorithm/tesselate.h>
#include <SFCGAL/algorithm/translate.h>

#include <CGAL/Straight_skeleton_converter_2.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/create_straight_skeleton_from_polygon_with_holes_2.h>
#include <CGAL/extrude_skeleton.h>

#include <memory>

namespace SFCGAL {
namespace algorithm {

using Point_2 = Kernel::Point_2;
using Point_3 = Kernel::Point_3;
using Polygon_2 = CGAL::Polygon_2<Kernel>;
using Polygon_with_holes_2 = CGAL::Polygon_with_holes_2<Kernel>;
using Straight_skeleton_2 = CGAL::Straight_skeleton_2<Kernel>;
using Mesh = CGAL::Surface_mesh<Point_3>;

namespace { // anonymous

Expand Down Expand Up @@ -379,5 +386,47 @@ approximateMedialAxis(const Geometry &g) -> std::unique_ptr<MultiLineString>
return mx;
}

auto
extrudeStraightSkeleton(const Polygon &g, double height)
-> std::unique_ptr<PolyhedralSurface>
{

Mesh sm;
CGAL::extrude_skeleton(g.toPolygon_with_holes_2(), sm,
CGAL::parameters::maximum_height(height));
std::unique_ptr<PolyhedralSurface> polys(new PolyhedralSurface(sm));

return polys;
}

auto
extrudeStraightSkeleton(const Geometry &g, double height)
-> std::unique_ptr<PolyhedralSurface>
{
SFCGAL_ASSERT_GEOMETRY_VALIDITY_2D(g);

if (g.geometryTypeId() != TYPE_POLYGON) {
BOOST_THROW_EXCEPTION(Exception("Geometry must be a Polygon"));
}
std::unique_ptr<PolyhedralSurface> result(
extrudeStraightSkeleton(g.as<Polygon>(), height));
propagateValidityFlag(*result, true);
return result;
}

auto
extrudeStraightSkeleton(const Geometry &g, double building_height,
double roof_height)
-> std::unique_ptr<PolyhedralSurface>
{
std::unique_ptr<PolyhedralSurface> roof{
extrudeStraightSkeleton(g, roof_height)};
translate(*roof, 0.0, 0.0, building_height);
std::unique_ptr<Geometry> building(extrude(g.as<Polygon>(), building_height));
std::unique_ptr<PolyhedralSurface> result{
new PolyhedralSurface(building->as<Solid>().exteriorShell())};
result->addPolygons(*roof);
return result;
};
} // namespace algorithm
} // namespace SFCGAL
22 changes: 21 additions & 1 deletion src/algorithm/straightSkeleton.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
#ifndef _SFCGAL_ALGORITHM_STRAIGHTSKELETON_H_
#define _SFCGAL_ALGORITHM_STRAIGHTSKELETON_H_

#include <SFCGAL/PolyhedralSurface.h>
#include <SFCGAL/algorithm/extrude.h>
#include <SFCGAL/algorithm/union.h>
#include <SFCGAL/config.h>

#include <memory>

namespace SFCGAL {
Expand Down Expand Up @@ -84,6 +86,24 @@ SFCGAL_API std::unique_ptr<MultiLineString>
bool innerOnly = false, bool outputDistanceInM = false,
const double &toleranceAbs = 1e-8);

/**
* @brief build a 3D straight skeleton extruded for a Polygon
* @ingroup detail
* @throws NotImplementedException If g is a Polygon with point touching rings.
*/
SFCGAL_API auto
extrudedStraightSkeleton(const Polygon &g, double height)
-> std::unique_ptr<PolyhedralSurface>;

SFCGAL_API auto
extrudeStraightSkeleton(const Geometry &g, double height)
-> std::unique_ptr<PolyhedralSurface>;

SFCGAL_API auto
extrudeStraightSkeleton(const Geometry &g, double building_height,
double roof_height)
-> std::unique_ptr<PolyhedralSurface>;

} // namespace algorithm
} // namespace SFCGAL

Expand Down
13 changes: 13 additions & 0 deletions src/algorithm/translate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,18 @@ translate(Geometry &g, const Kernel::FT dx, const Kernel::FT dy,
translate(g, Kernel::Vector_3(dx, dy, dz));
}

///
///
///
void
translate(Geometry &g, const double &dx, const double &dy, const double &dz)
{
if (!std::isfinite(dx) || !std::isfinite(dy) || !std::isfinite(dz)) {
BOOST_THROW_EXCEPTION(NonFiniteValueException(
"trying to translate with non finite value in direction"));
}

return translate(g, Kernel::FT(dx), Kernel::FT(dy), Kernel::FT(dz));
}
} // namespace algorithm
} // namespace SFCGAL
7 changes: 7 additions & 0 deletions src/algorithm/translate.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ SFCGAL_API void
translate(Geometry &g, const Kernel::FT dx, const Kernel::FT dy,
const Kernel::FT dz);

/**
* @brief translate a geometry from double-coordinates
* @todo unittest
*/
SFCGAL_API void
translate(Geometry &g, const double &dx, const double &dy, const double &dz);

} // namespace algorithm
} // namespace SFCGAL

Expand Down
43 changes: 43 additions & 0 deletions src/capi/sfcgal_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1171,6 +1171,49 @@ sfcgal_geometry_has_validity_flag(const sfcgal_geometry_t *geom) -> int
return g1->hasValidityFlag() ? 1 : 0;
}

extern "C" auto
sfcgal_geometry_extrude_straight_skeleton(const sfcgal_geometry_t *geom,
double height) -> sfcgal_geometry_t *
{
const auto *g1 = reinterpret_cast<const SFCGAL::Geometry *>(geom);
std::unique_ptr<SFCGAL::PolyhedralSurface> polys;

try {
polys = SFCGAL::algorithm::extrudeStraightSkeleton(*g1, height);
} catch (std::exception &e) {
SFCGAL_WARNING("During straight_extrude_skeleton_distance(A):");
SFCGAL_WARNING(" with A: %s",
((const SFCGAL::Geometry *)(geom))->asText().c_str());
SFCGAL_ERROR("%s", e.what());
return nullptr;
}

return polys.release();
}

extern "C" auto
sfcgal_geometry_extrude_polygon_straight_skeleton(const sfcgal_geometry_t *geom,
double building_height,
double roof_height)
-> sfcgal_geometry_t *
{
const auto *g1 = reinterpret_cast<const SFCGAL::Geometry *>(geom);
std::unique_ptr<SFCGAL::Geometry> polys;

try {
polys = SFCGAL::algorithm::extrudeStraightSkeleton(*g1, building_height,
roof_height);
} catch (std::exception &e) {
SFCGAL_WARNING("During straight_extrude_skeleton_distance(A):");
SFCGAL_WARNING(" with A: %s",
((const SFCGAL::Geometry *)(geom))->asText().c_str());
SFCGAL_ERROR("%s", e.what());
return nullptr;
}

return polys.release();
}

extern "C" auto
sfcgal_geometry_straight_skeleton_distance_in_m(const sfcgal_geometry_t *geom)
-> sfcgal_geometry_t *
Expand Down
15 changes: 15 additions & 0 deletions src/capi/sfcgal_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,21 @@ sfcgal_geometry_straight_skeleton(const sfcgal_geometry_t *geom);
SFCGAL_API sfcgal_geometry_t *
sfcgal_geometry_straight_skeleton_distance_in_m(const sfcgal_geometry_t *geom);

/**
* Returns the extrude straight skeleton of the given Polygon
* @pre geom must be a Polygon
* @pre isValid(geom) == true
* @post isValid(return) == true
* @ingroup capi
*/
SFCGAL_API sfcgal_geometry_t *
sfcgal_geometry_extrude_straight_skeleton(const sfcgal_geometry_t *geom,
double height);
SFCGAL_API sfcgal_geometry_t *
sfcgal_geometry_extrude_polygon_straight_skeleton(const sfcgal_geometry_t *geom,
double building_height,
double roof_height);

/**
* Returns the approximate medial axis for the given Polygon
* Approximate medial axis is based on straight skeleton
Expand Down
1 change: 0 additions & 1 deletion test/unit/SFCGAL/KernelTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#include <boost/test/unit_test.hpp>

#include <SFCGAL/Kernel.h>
#include <CGAL/mpq_class.h>
#include <SFCGAL/Coordinate.h>
#include <SFCGAL/LineString.h>

Expand Down
Loading

0 comments on commit bba3284

Please sign in to comment.