diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index f2af0247ef..27d53f1a03 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -859,6 +859,16 @@ set_target_properties(geometry_kernel_${kernel} PROPERTIES COMPILE_FLAGS "-DIFC_ target_link_libraries(geometry_kernel_${kernel} ${${KERNEL_UPPER}_LIBRARIES}) list(APPEND kernel_libraries geometry_kernel_${kernel}) +if (${kernel} STREQUAL "cgal") +add_library(geometry_kernel_${kernel}_simple ${IFCGEOM_FILES}) +set_target_properties(geometry_kernel_${kernel}_simple PROPERTIES COMPILE_FLAGS "-DIFC_GEOM_EXPORTS -DIFOPSH_SIMPLE_KERNEL") +# needed? +# if (NOT WASM_BUILD) +# endif() +target_link_libraries(geometry_kernel_${kernel}_simple ${${KERNEL_UPPER}_LIBRARIES}) +list(APPEND kernel_libraries geometry_kernel_${kernel}_simple) +endif() + endforeach() foreach(schema ${SCHEMA_VERSIONS}) @@ -921,6 +931,12 @@ TARGET_LINK_LIBRARIES(Serializers ${SERIALIZER_SCHEMA_LIBRARIES} ${OPENCOLLADA_L endif() +if (MSVC) +# @todo still needs to be understood better, but the cgal and cgal-simple kernel cause multiply defined boost lambda placeholders _1 ... _3 +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /FORCE:MULTIPLE") +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /FORCE:MULTIPLE") +endif() + if (BUILD_CONVERT) if (WITH_CGAL) diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index 68cce14690..0a0029f1e3 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -277,7 +277,7 @@ int main(int argc, char** argv) { po::options_description geom_options("Geometry options"); geom_options.add_options() ("kernel", po::value(&geometry_kernel)->default_value(default_kernel), - "Geometry kernel to use (opencascade or cgal).") + "Geometry kernel to use (opencascade, cgal, cgal-simple).") ("threads,j", po::value(&num_threads)->default_value(1), "Number of parallel processing threads for geometry interpretation.") ("plan", diff --git a/src/ifcconvert/validate_wall_connectivity.cpp b/src/ifcconvert/validate_wall_connectivity.cpp index ba4aa35ba4..c72e035c43 100644 --- a/src/ifcconvert/validate_wall_connectivity.cpp +++ b/src/ifcconvert/validate_wall_connectivity.cpp @@ -98,7 +98,7 @@ void fix_wallconnectivity(IfcParse::IfcFile& f, bool no_progress, bool quiet, bo auto dza = a.bbox().zmax() - a.bbox().zmin(); auto dzb = b.bbox().zmax() - b.bbox().zmin(); - auto bb = CGAL::Polygon_mesh_processing::bbox_3(x_poly); + auto bb = CGAL::Polygon_mesh_processing::bbox(x_poly); if (bb.zmax() - bb.zmin() < std::min(dza, dzb) / 3.) { return; } diff --git a/src/ifcgeom/AbstractKernel.cpp b/src/ifcgeom/AbstractKernel.cpp index b00e4544c1..4047fa09ec 100644 --- a/src/ifcgeom/AbstractKernel.cpp +++ b/src/ifcgeom/AbstractKernel.cpp @@ -10,6 +10,10 @@ #ifdef IFOPSH_WITH_CGAL #include "../ifcgeom/kernels/cgal/CgalKernel.h" +#undef CGAL_KERNEL_H +#undef CGALCONVERSIONRESULT_H +#define IFOPSH_SIMPLE_KERNEL +#include "../ifcgeom/kernels/cgal/CgalKernel.h" #endif using namespace ifcopenshell::geometry; @@ -46,6 +50,10 @@ ifcopenshell::geometry::kernels::AbstractKernel* ifcopenshell::geometry::kernels if (geometry_library_lower == "cgal") { return new CgalKernel(conv_settings); } + + if (geometry_library_lower == "cgal-simple") { + return new SimpleCgalKernel(conv_settings); + } #endif throw IfcParse::IfcException("No geometry kernel registered for " + geometry_library); diff --git a/src/ifcgeom/kernels/cgal/CgalConversionResult.h b/src/ifcgeom/kernels/cgal/CgalConversionResult.h index aa6dfca8e3..5e9acbf4c4 100644 --- a/src/ifcgeom/kernels/cgal/CgalConversionResult.h +++ b/src/ifcgeom/kernels/cgal/CgalConversionResult.h @@ -24,8 +24,9 @@ #undef Handle +#define CGAL_NO_DEPRECATED_CODE + #include -#include #include #include #include @@ -33,10 +34,35 @@ #include #include #include -#include +#ifdef IFOPSH_SIMPLE_KERNEL + +#include + +#define Kernel_ SimpleKernel_ +#define CgalShape SimpleCgalShape +#define cgal_placement_t cgal_simple_placement_t +#define cgal_point_t cgal_simple_point_t +#define cgal_direction_t cgal_simple_direction_t +#define cgal_vector_t cgal_simple_vector_t +#define cgal_plane_t cgal_simple_plane_t +#define cgal_curve_t cgal_simple_curve_t +#define cgal_wire_t cgal_simple_wire_t +#define cgal_face_t cgal_simple_face_t +#define cgal_shape_t cgal_simple_shape_t +#define cgal_vertex_descriptor_t cgal_simple_vertex_descriptor_t +#define cgal_face_descriptor_t cgal_simple_face_descriptor_t + +typedef CGAL::Simple_cartesian Kernel_; + +#else + +#include +#include typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel_; +#endif + typedef Kernel_::Aff_transformation_3 cgal_placement_t; typedef Kernel_::Point_3 cgal_point_t; typedef Kernel_::Vector_3 cgal_direction_t; @@ -45,10 +71,12 @@ typedef Kernel_::Plane_3 cgal_plane_t; typedef std::vector cgal_curve_t; typedef std::vector cgal_wire_t; -struct cgal_face_t { - cgal_wire_t outer; - std::vector inner; -}; +namespace { + struct cgal_face_t { + cgal_wire_t outer; + std::vector inner; + }; +} typedef CGAL::Polyhedron_3 cgal_shape_t; typedef boost::graph_traits>::vertex_descriptor cgal_vertex_descriptor_t; @@ -60,9 +88,8 @@ namespace ifcopenshell { namespace geometry { class CgalShape : public IfcGeom::ConversionResultShape { public: - CgalShape(const cgal_shape_t& shape) - : shape_(shape) - {} + CgalShape(const cgal_shape_t& shape) + : shape_(shape) {} const cgal_shape_t& shape() const { return shape_; } operator const cgal_shape_t& () { return shape_; } diff --git a/src/ifcgeom/kernels/cgal/CgalKernel.cpp b/src/ifcgeom/kernels/cgal/CgalKernel.cpp index 0412e78a69..8d1f34f7af 100644 --- a/src/ifcgeom/kernels/cgal/CgalKernel.cpp +++ b/src/ifcgeom/kernels/cgal/CgalKernel.cpp @@ -47,6 +47,17 @@ void CgalKernel::remove_duplicate_points_from_loop(cgal_wire_t& polygon) { } } +namespace { + struct PolyhedronBuilder : public CGAL::Modifier_base::HalfedgeDS> { + private: + std::list *face_list; + public: + boost::optional from_soup; + PolyhedronBuilder(std::list *face_list); + void operator()(CGAL::Polyhedron_3::HalfedgeDS &hds); + }; +} + CGAL::Polyhedron_3 ifcopenshell::geometry::utils::create_polyhedron(std::list &face_list, bool stitch_borders) { // Naive creation @@ -91,6 +102,7 @@ CGAL::Polyhedron_3 ifcopenshell::geometry::utils::create_polyhedron(std return polyhedron; } +#ifndef IFOPSH_SIMPLE_KERNEL CGAL::Polyhedron_3 ifcopenshell::geometry::utils::create_polyhedron(const CGAL::Nef_polyhedron_3& nef_polyhedron) { if (nef_polyhedron.is_simple()) { try { @@ -137,6 +149,7 @@ CGAL::Nef_polyhedron_3 ifcopenshell::geometry::utils::create_nef_polyhe return CGAL::Nef_polyhedron_3(); } } +#endif bool CgalKernel::convert(const taxonomy::shell* l, cgal_shape_t& shape) { auto faces = l->children_as(); @@ -789,6 +802,9 @@ namespace { bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const IfcUtil::IfcBaseEntity * entity, const std::vector>& openings, const IfcGeom::ConversionResults & entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4 & entity_trsf, IfcGeom::ConversionResults & cut_shapes) { +#ifdef IFOPSH_SIMPLE_KERNEL + return false; +#else CGAL::Nef_nary_union_3> second_operand_collector; size_t second_operand_collector_size = 0; @@ -860,6 +876,7 @@ bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const IfcUtil } return true; +#endif } @@ -1161,6 +1178,8 @@ CGAL::Polyhedron_3 ifcopenshell::geometry::utils::create_cube(const Ker return create_polyhedron(face_list); } +#ifndef IFOPSH_SIMPLE_KERNEL + bool CgalKernel::thin_solid(const CGAL::Nef_polyhedron_3& a, CGAL::Nef_polyhedron_3& result) { // @todo this should be possible as a minkowski sum of facet & cube. rather than a set of boolean ops. @@ -1249,6 +1268,8 @@ bool CgalKernel::preprocess_boolean_operand(const IfcUtil::IfcBaseClass* log_ref #include +#endif + bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std::list>& loops, double& z0, double& z1) { // @todo can also be for other boolean operations, just depth/matrix operands are different if (br->operation != taxonomy::boolean_result::SUBTRACTION) { @@ -1616,6 +1637,9 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ConversionResu } +#ifdef IFOPSH_SIMPLE_KERNEL + return false; +#else bool first = true; CGAL::Nef_polyhedron_3 a; @@ -1816,6 +1840,8 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ConversionResu br->surface_style ? br->surface_style : first_item_style )); return true; + +#endif } PolyhedronBuilder::PolyhedronBuilder(std::list* face_list) { diff --git a/src/ifcgeom/kernels/cgal/CgalKernel.h b/src/ifcgeom/kernels/cgal/CgalKernel.h index e2257a1ea3..ac7916b99d 100644 --- a/src/ifcgeom/kernels/cgal/CgalKernel.h +++ b/src/ifcgeom/kernels/cgal/CgalKernel.h @@ -35,7 +35,11 @@ if ( it != cache.T.end() ) { e = it->second; return true; } #endif */ -#include +#ifdef IFOPSH_SIMPLE_KERNEL +#define CgalKernel SimpleCgalKernel +#define create_cube create_cube_simple +#define create_polyhedron create_polyhedron_simple +#endif #include "../../../ifcparse/macros.h" @@ -44,14 +48,9 @@ if ( it != cache.T.end() ) { e = it->second; return true; } #include "../../../ifcgeom/IfcGeomElement.h" #include "../../../ifcgeom/kernels/cgal/CgalConversionResult.h" -struct PolyhedronBuilder : public CGAL::Modifier_base::HalfedgeDS> { -private: - std::list *face_list; -public: - boost::optional from_soup; - PolyhedronBuilder(std::list *face_list); - void operator()(CGAL::Polyhedron_3::HalfedgeDS &hds); -}; +#include + +#include namespace ifcopenshell { namespace geometry { @@ -59,9 +58,12 @@ namespace ifcopenshell { IFC_GEOM_API CGAL::Polyhedron_3 create_cube(double d); IFC_GEOM_API CGAL::Polyhedron_3 create_cube(const Kernel_::Point_3& lower, const Kernel_::Point_3& upper); IFC_GEOM_API CGAL::Polyhedron_3 create_polyhedron(std::list &face_list, bool stitch_borders = false); + +#ifndef IFOPSH_SIMPLE_KERNEL IFC_GEOM_API CGAL::Polyhedron_3 create_polyhedron(const CGAL::Nef_polyhedron_3 &nef_polyhedron); IFC_GEOM_API CGAL::Nef_polyhedron_3 create_nef_polyhedron(std::list &face_list); IFC_GEOM_API CGAL::Nef_polyhedron_3 create_nef_polyhedron(CGAL::Polyhedron_3 &polyhedron); +#endif } namespace kernels { @@ -69,15 +71,17 @@ namespace ifcopenshell { class IFC_GEOM_API CgalKernel : public AbstractKernel { private: size_t circle_segments_; - // CGAL::Nef_polyhedron_3 precision_cube_; +#ifndef IFOPSH_SIMPLE_KERNEL bool preprocess_boolean_operand(const IfcUtil::IfcBaseClass* log_reference, const cgal_shape_t& shape_const, CGAL::Nef_polyhedron_3& result, bool dilate); + bool thin_solid(const CGAL::Nef_polyhedron_3& a, CGAL::Nef_polyhedron_3& result); CGAL::Nef_polyhedron_3 create_precision_cube_() const { auto cc = utils::create_cube(conv_settings_.getValue(ConversionSettings::GV_PRECISION)); return CGAL::Nef_polyhedron_3(cc); } +#endif public: CgalKernel(const ConversionSettings& settings) @@ -105,7 +109,9 @@ namespace ifcopenshell { virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector>& openings, const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes); +#ifndef IFOPSH_SIMPLE_KERNEL CGAL::Nef_polyhedron_3 precision_cube() const { return create_precision_cube_(); } +#endif }; }