dllimport/export #6926

This commit is contained in:
Thomas Krijnen
2025-09-26 14:24:49 +02:00
parent 21137b9268
commit ce91d296b6
44 changed files with 957 additions and 860 deletions
+4 -3
View File
@@ -45,6 +45,7 @@
#include "../ifcgeom/IfcGeomFilter.h"
#include "../ifcgeom/Iterator.h"
#include "../ifcgeom/IfcGeomRenderStyles.h"
#include "../ifcgeom/hybrid_kernel.h"
#include "../ifcparse/utils.h"
@@ -1018,7 +1019,7 @@ int main(int argc, char** argv) {
if (is_tesselated && (center_model || center_model_geometry)) {
std::vector<double> offset(3);
IfcGeom::Iterator tmp_context_iterator(geometry_kernel, geometry_settings, ifc_file, filter_funcs, num_threads);
IfcGeom::Iterator tmp_context_iterator(ifcopenshell::geometry::kernels::construct(ifc_file, geometry_kernel, geometry_settings), geometry_settings, ifc_file, filter_funcs, num_threads);
time_t start, end;
time(&start);
@@ -1064,7 +1065,7 @@ int main(int argc, char** argv) {
std::unique_ptr<IfcGeom::Iterator> context_iterator;
if (!elems_from_adaptor) {
context_iterator.reset(new IfcGeom::Iterator(geometry_kernel, geometry_settings, ifc_file, filter_funcs, num_threads));
context_iterator.reset(new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(ifc_file, geometry_kernel, geometry_settings), geometry_settings, ifc_file, filter_funcs, num_threads));
}
#if defined(WITH_HDF5) && defined(IFOPSH_WITH_OPENCASCADE)
@@ -1639,7 +1640,7 @@ void fix_quantities(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool std
settings.get<ifcopenshell::geometry::settings::ConvertBackUnits>().value = true;
settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
IfcGeom::Iterator context_iterator(settings, &f, {}, 1);
IfcGeom::Iterator context_iterator(ifcopenshell::geometry::kernels::construct(&f, "opencascade", settings), settings, &f, {}, 1);
if (!context_iterator.initialize()) {
return;
+1 -182
View File
@@ -1,23 +1,9 @@
#include "AbstractKernel.h"
#include "../ifcgeom/IfcGeomElement.h"
#include "../ifcgeom/ConversionSettings.h"
#include "../ifcgeom/abstract_mapping.h"
#include "../ifcgeom/function_item_evaluator.h"
#ifdef IFOPSH_WITH_OPENCASCADE
#include "../ifcgeom/kernels/opencascade/OpenCascadeKernel.h"
#undef Handle
#endif
#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"
#undef CgalKernel
#endif
#include "AbstractKernel.h"
using namespace ifcopenshell::geometry;
@@ -73,173 +59,6 @@ const Settings& ifcopenshell::geometry::kernels::AbstractKernel::settings() cons
return settings_;
}
bool is_valid_for_kernel(const ifcopenshell::geometry::kernels::AbstractKernel* k, const IfcGeom::ConversionResult& shp) {
#ifdef IFOPSH_WITH_OPENCASCADE
if (k->geometry_library() == "opencascade") {
return dynamic_cast<ifcopenshell::geometry::OpenCascadeShape*>(shp.Shape().get()) != nullptr;
}
#endif
#ifdef IFOPSH_WITH_CGAL
if (k->geometry_library() == "cgal-simple") {
return dynamic_cast<ifcopenshell::geometry::SimpleCgalShape*>(shp.Shape().get()) != nullptr;
}
if (k->geometry_library() == "cgal") {
return dynamic_cast<ifcopenshell::geometry::CgalShape*>(shp.Shape().get()) != nullptr;
}
#endif
return false;
}
class HybridKernel : public ifcopenshell::geometry::kernels::AbstractKernel {
std::vector<std::unique_ptr<AbstractKernel>> kernels_;
ifcopenshell::geometry::abstract_mapping* mapping_;
public:
HybridKernel(const std::string& name, IfcParse::IfcFile* file, Settings& settings, std::vector<std::unique_ptr<AbstractKernel>>&& kernels)
: AbstractKernel(name, settings)
, kernels_(std::move(kernels))
, mapping_(ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings))
{}
virtual bool convert(const taxonomy::ptr item, IfcGeom::ConversionResults& rs) {
auto ops = mapping_->find_openings(item->instance->as<IfcUtil::IfcBaseEntity>());
bool has_openings = ops && ops->size();
for (auto& k : kernels_) {
#ifdef IFOPSH_WITH_CGAL
if (has_openings && dynamic_cast<ifcopenshell::geometry::kernels::SimpleCgalKernel*>(k.get())) {
// @todo this would fail later on in the find_openings() call, because we have a
// SimpleCgalShape which cannot be used on a kernel that supports booleans.
// @todo 1 implement the translation between various conversion result shapes
// @todo 2 fold the boolean result openings into the taxonomy item. This should be possible
// now that we have shared_ptr<item> and caching in place. So the inability
// to instance wouldn't matter as much.
continue;
}
#endif
bool success = false;
try {
success = k->convert(item, rs);
} catch(...) {}
if (success) {
return true;
}
}
return false;
}
virtual bool apply_layerset(IfcGeom::ConversionResults& items, const ifcopenshell::geometry::layerset_information& layers) {
for (auto& k : kernels_) {
bool success = false;
try {
success = k->apply_layerset(items, layers);
} catch (...) {}
if (success) {
return true;
}
}
return false;
}
virtual bool apply_folded_layerset(IfcGeom::ConversionResults& items, const ifcopenshell::geometry::layerset_information& layers, const std::map<IfcUtil::IfcBaseEntity*, ifcopenshell::geometry::layerset_information>& folds) {
for (auto& k : kernels_) {
bool success = false;
try {
success = k->apply_folded_layerset(items, layers, folds);
} catch (...) {}
if (success) {
return true;
}
}
return false;
}
virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes)
{
for (auto& k : kernels_) {
bool is_valid = true;
for (auto& s : entity_shapes) {
if (!is_valid_for_kernel(k.get(), s)) {
is_valid = false;
break;
}
}
if (!is_valid) {
continue;
}
bool success = false;
try {
success = k->convert_openings(entity, openings, entity_shapes, entity_trsf, cut_shapes);
} catch (...) {}
if (success) {
return true;
}
}
return false;
}
};
ifcopenshell::geometry::kernels::AbstractKernel* ifcopenshell::geometry::kernels::construct(IfcParse::IfcFile* file, const std::string& geometry_library, Settings& conv_settings) {
std::string geometry_library_lower = boost::to_lower_copy(geometry_library);
#ifdef IFOPSH_WITH_OPENCASCADE
if (geometry_library_lower == "opencascade") {
return new IfcGeom::OpenCascadeKernel(conv_settings);
}
#endif
#ifdef IFOPSH_WITH_CGAL
if (geometry_library_lower == "cgal") {
return new CgalKernel(conv_settings);
}
if (geometry_library_lower == "cgal-simple") {
return new SimpleCgalKernel(conv_settings);
}
#endif
if (geometry_library_lower.rfind("hybrid-", 0) == 0) {
geometry_library_lower = geometry_library_lower.substr(strlen("hybrid"));
std::vector<std::unique_ptr<AbstractKernel>> kernels;
while (!geometry_library_lower.empty()) {
if (geometry_library_lower.find("-", 0) == 0) {
geometry_library_lower = geometry_library_lower.substr(strlen("-"));
} else {
throw IfcParse::IfcException("Invalid hybrid kernel " + geometry_library);
}
auto n = kernels.size();
#ifdef IFOPSH_WITH_OPENCASCADE
if (geometry_library_lower.find("opencascade", 0) == 0) {
kernels.emplace_back(new IfcGeom::OpenCascadeKernel(conv_settings));
geometry_library_lower = geometry_library_lower.substr(strlen("opencascade"));
}
#endif
#ifdef IFOPSH_WITH_CGAL
if (geometry_library_lower.find("cgal-simple", 0) == 0) {
kernels.emplace_back(new SimpleCgalKernel(conv_settings));
geometry_library_lower = geometry_library_lower.substr(strlen("cgal-simple"));
}
if (geometry_library_lower.find("cgal", 0) == 0) {
kernels.emplace_back(new CgalKernel(conv_settings));
geometry_library_lower = geometry_library_lower.substr(strlen("cgal"));
}
#endif
if (kernels.size() != n + 1) {
throw IfcParse::IfcException("Invalid hybrid kernel " + geometry_library);
}
}
for (auto it = kernels.begin(); it != kernels.end(); ++it) {
(**it).propagate_exceptions = it == kernels.begin();
(**it).partial_success_is_success = it == kernels.end() - 1;
}
if (!kernels.empty()) {
return new HybridKernel(geometry_library, file, conv_settings, std::move(kernels));
}
}
throw IfcParse::IfcException("No geometry kernel registered for " + geometry_library);
}
bool ifcopenshell::geometry::kernels::AbstractKernel::convert_impl(const taxonomy::collection::ptr collection, IfcGeom::ConversionResults& r) {
auto s = r.size();
for (auto& c : collection->children) {
+24 -3
View File
@@ -1,3 +1,22 @@
/********************************************************************************
* *
* This file is part of IfcOpenShell. *
* *
* IfcOpenShell is free software: you can redistribute it and/or modify *
* it under the terms of the Lesser GNU General Public License as published by *
* the Free Software Foundation, either version 3.0 of the License, or *
* (at your option) any later version. *
* *
* IfcOpenShell 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 *
* Lesser GNU General Public License for more details. *
* *
* You should have received a copy of the Lesser GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
********************************************************************************/
#ifndef ABSTRACT_KERNEL_H
#define ABSTRACT_KERNEL_H
@@ -7,6 +26,7 @@
#include "../ifcgeom/IfcGeomRepresentation.h"
#include "../ifcgeom/taxonomy.h"
#include "../ifcgeom/ConversionSettings.h"
#include "../ifcgeom/abstract_mapping.h"
static const double ALMOST_ZERO = 1.e-9;
@@ -55,6 +75,8 @@ namespace ifcopenshell {
return geometry_library_;
}
virtual bool supports_boolean_operations() const = 0;
virtual bool convert_impl(const taxonomy::matrix4::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
virtual bool convert_impl(const taxonomy::point3::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
virtual bool convert_impl(const taxonomy::direction3::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
@@ -98,10 +120,9 @@ namespace ifcopenshell {
virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes) = 0;
virtual bool unify_shapes(const IfcGeom::ConversionResults&, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
virtual AbstractKernel* clone() const = 0;
};
AbstractKernel* construct(IfcParse::IfcFile* file, const std::string& geometry_library, Settings& conv_settings);
}
}
}
+3
View File
@@ -26,3 +26,6 @@ std::string IfcGeom::NumberNativeDouble::to_string() const {
ss << std::setprecision(std::numeric_limits<double>::digits10 + 1) << value_;
return ss.str();
}
template struct IFC_GEOM_API IfcGeom::OpaqueCoordinate<3>;
template struct IFC_GEOM_API IfcGeom::OpaqueCoordinate<4>;
+12
View File
@@ -290,10 +290,13 @@ namespace IfcGeom {
virtual ConversionResultShape* add(ConversionResultShape*) = 0;
virtual ConversionResultShape* subtract(ConversionResultShape*) = 0;
virtual ConversionResultShape* intersect(ConversionResultShape*) = 0;
virtual ConversionResultShape* concat(ConversionResultShape*) = 0;
virtual void map(OpaqueCoordinate<4>& from, OpaqueCoordinate<4>& to) = 0;
virtual void map(const std::vector<OpaqueCoordinate<4>>& from, const std::vector<OpaqueCoordinate<4>>& to) = 0;
virtual ConversionResultShape* moved(ifcopenshell::geometry::taxonomy::matrix4::ptr) const = 0;
virtual bool surface_area_along_direction(double tol, const ifcopenshell::geometry::taxonomy::matrix4::ptr&, double& along_x, double& along_y, double& along_z) const = 0;
virtual ~ConversionResultShape() {}
@@ -327,6 +330,15 @@ namespace IfcGeom {
ifcopenshell::geometry::taxonomy::style::ptr StylePtr() const { return style_; }
void setStyle(ifcopenshell::geometry::taxonomy::style::ptr newStyle) { style_ = newStyle; }
int ItemId() const { return id; }
ConversionResultShape* apply_transform(double unit_scale = 1.) const {
if (unit_scale != 1.) {
auto m = ifcopenshell::geometry::taxonomy::matrix4::ptr(placement_->clone_());
m->pre_multiply_scale(unit_scale);
return shape_->moved(m);
} else {
return shape_->moved(placement_);
}
}
};
typedef std::vector<ConversionResult> ConversionResults;
+12 -15
View File
@@ -22,9 +22,9 @@
namespace po = boost::program_options;
namespace std {
istream& operator>>(istream& in, set<int>& ints);
istream& operator>>(istream& in, set<string>& ints);
istream& operator>>(istream& in, vector<double>& vs);
IFC_GEOM_API istream& operator>>(istream& in, set<int>& ints);
IFC_GEOM_API istream& operator>>(istream& in, set<string>& ints);
IFC_GEOM_API istream& operator>>(istream& in, vector<double>& vs);
}
#endif
@@ -249,7 +249,7 @@ namespace ifcopenshell {
CURVES_SURFACES_AND_SOLIDS
};
std::istream& operator>>(std::istream& in, OutputDimensionalityTypes& ioo);
IFC_GEOM_API std::istream& operator>>(std::istream& in, OutputDimensionalityTypes& ioo);
struct OutputDimensionality : public SettingBase<OutputDimensionality, OutputDimensionalityTypes> {
static constexpr const char* const name = "dimensionality";
@@ -266,7 +266,7 @@ namespace ifcopenshell {
SERIALIZED
};
std::istream& operator>>(std::istream& in, IteratorOutputOptions& ioo);
IFC_GEOM_API std::istream& operator>>(std::istream& in, IteratorOutputOptions& ioo);
struct IteratorOutput : public SettingBase<IteratorOutput, IteratorOutputOptions> {
static constexpr const char* const name = "iterator-output";
@@ -395,7 +395,7 @@ namespace ifcopenshell {
MAXSTEPSIZE,
MINSTEPS };
std::istream& operator>>(std::istream& in, FunctionStepMethod& ioo);
IFC_GEOM_API std::istream& operator>>(std::istream& in, FunctionStepMethod& ioo);
struct FunctionStepType : public SettingBase<FunctionStepType, FunctionStepMethod> {
static constexpr const char* const name = "function-step-type";
@@ -425,7 +425,7 @@ namespace ifcopenshell {
POLYHEDRON_WITH_HOLES
};
std::istream& operator>>(std::istream& in, TriangulationMethod& ioo);
IFC_GEOM_API std::istream& operator>>(std::istream& in, TriangulationMethod& ioo);
struct TriangulationType : public SettingBase<TriangulationType, TriangulationMethod> {
static constexpr const char* const name = "triangulation-type";
@@ -536,7 +536,7 @@ namespace ifcopenshell {
}
template <typename settings_t>
class IFC_GEOM_API SettingsContainer {
class SettingsContainer {
public:
typedef boost::variant<bool, int, double, std::string, std::set<int>, std::set<std::string>, std::vector<double>, IteratorOutputOptions, FunctionStepMethod, OutputDimensionalityTypes, TriangulationMethod> value_variant_t;
private:
@@ -645,7 +645,7 @@ namespace ifcopenshell {
}
};
class IFC_GEOM_API Settings : public SettingsContainer<
class Settings : public SettingsContainer<
std::tuple<MesherLinearDeflection, MesherAngularDeflection, ReorientShells, LengthUnit, PlaneUnit, Precision, OutputDimensionality, LayersetFirst, DisableBooleanResult, NoWireIntersectionCheck, NoWireIntersectionTolerance, PrecisionFactor, DebugBooleanOperations, BooleanAttempt2d, SurfaceColour, WeldVertices, UseWorldCoords, UnifyShapes, UseMaterialNames, ConvertBackUnits, ContextIds, ContextTypes, ContextIdentifiers, IteratorOutput, DisableOpeningSubtractions, ApplyDefaultMaterials, DontEmitNormals, GenerateUvs, ApplyLayerSets, UseElementHierarchy, ValidateQuantities, EdgeArrows, BuildingLocalPlacement, SiteLocalPlacement, ForceSpaceTransparency, CircleSegments, CgalSmoothAngleDegrees, KeepBoundingBoxes, ComputeCurvature, FunctionStepType, FunctionStepParam, NoParallelMapping, PermissiveShapeReuse, ModelOffset, ModelRotation, TriangulationType, CgalEmitOriginalEdges, OcctNoCleanTriangulation, CacheShapes, DeferProcessingFirstElement, MaxOffset, MaxOffsetDeviation, ApplyOffset>
>
{};
@@ -654,16 +654,13 @@ namespace ifcopenshell {
// @todo find a place
namespace IfcGeom {
class IFC_GEOM_API geometry_exception : public std::exception {
class IFC_GEOM_API geometry_exception : public std::runtime_error {
protected:
std::string message;
public:
geometry_exception(const std::string& m)
: message(m) {}
virtual ~geometry_exception() throw () {}
virtual const char* what() const throw() {
return message.c_str();
}
: std::runtime_error(m)
{}
};
class IFC_GEOM_API too_many_faces_exception : public geometry_exception {
+2 -104
View File
@@ -4,20 +4,16 @@
using namespace ifcopenshell::geometry;
ifcopenshell::geometry::Converter::Converter(const std::string& geometry_library, IfcParse::IfcFile* file, ifcopenshell::geometry::Settings& s)
: geometry_library_(boost::to_lower_copy(geometry_library))
ifcopenshell::geometry::Converter::Converter(std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel>&& geometry_library, IfcParse::IfcFile* file, ifcopenshell::geometry::Settings& s)
: kernel_(std::move(geometry_library))
{
mapping_ = impl::mapping_implementations().construct(file, s);
kernel_ = kernels::construct(file, geometry_library, mapping_->settings());
// Mapping reads unit information and applies to settings
settings_ = mapping_->settings();
}
ifcopenshell::geometry::Converter::~Converter()
{
if (kernel_ != nullptr) {
delete kernel_;
}
if (mapping_ != nullptr) {
delete mapping_;
}
@@ -414,101 +410,3 @@ IfcGeom::ConversionResults ifcopenshell::geometry::Converter::convert(IfcUtil::I
}
return results;
}
//#include "../../ifcparse/Ifc2x3.h"
//#include "../../ifcparse/Ifc4.h"
//
//// @todo remove
//#include "../../ifcgeom/schema_agnostic/opencascade/OpenCascadeConversionResult.h"
//
//#include <TopExp.hxx>
//#include <TopTools_ListOfShape.hxx>
//#include <TopTools_IndexedMapOfShape.hxx>
//#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
//
//IfcGeom::Kernel::Kernel(const std::string& geometry_library, IfcParse::IfcFile* file) {
// if (file != 0) {
// if (file->schema() == 0) {
// throw IfcParse::IfcException("No schema associated with file");
// }
//
// const std::string& schema_name = file->schema()->name();
// implementation_ = impl::kernel_implementations().construct(schema_name, geometry_library, file);
// }
//}
//
//int IfcGeom::Kernel::count(const ConversionResultShape* s_, int t_, bool unique) {
// // @todo make kernel agnostic
// const TopoDS_Shape& s = ((OpenCascadeShape*) s_)->shape();
// TopAbs_ShapeEnum t = (TopAbs_ShapeEnum) t_;
//
// if (unique) {
// TopTools_IndexedMapOfShape map;
// TopExp::MapShapes(s, t, map);
// return map.Extent();
// } else {
// int i = 0;
// TopExp_Explorer exp(s, t);
// for (; exp.More(); exp.Next()) {
// ++i;
// }
// return i;
// }
//}
//
//
//int IfcGeom::Kernel::surface_genus(const ConversionResultShape* s_) {
// // @todo make kernel agnostic
// const TopoDS_Shape& s = ((OpenCascadeShape*) s_)->shape();
// OpenCascadeShape Ss(s);
//
// int nv = count(&Ss, (int) TopAbs_VERTEX, true);
// int ne = count(&Ss, (int) TopAbs_EDGE, true);
// int nf = count(&Ss, (int) TopAbs_FACE, true);
//
// const int euler = nv - ne + nf;
// const int genus = (2 - euler) / 2;
//
// return genus;
//}
//
//
//IfcUtil::IfcBaseEntity* IfcGeom::Kernel::get_decomposing_entity(IfcUtil::IfcBaseEntity* inst, bool include_openings) {
// if (inst->as<Ifc2x3::IfcProduct>()) {
// return get_decomposing_entity_impl(inst->as<Ifc2x3::IfcProduct>(), include_openings);
// } else if (inst->as<Ifc4::IfcProduct>()) {
// return get_decomposing_entity_impl(inst->as<Ifc4::IfcProduct>(), include_openings);
// } else if (inst->declaration().name() == "IfcProject") {
// return nullptr;
// } else {
// throw IfcParse::IfcException("Unexpected entity " + inst->declaration().name());
// }
//}
//
//
//bool IfcGeom::Kernel::is_manifold(const ConversionResultShape* s_) {
// // @todo make kernel agnostic
// const TopoDS_Shape& a = ((OpenCascadeShape*) s_)->shape();
//
// if (a.ShapeType() == TopAbs_COMPOUND || a.ShapeType() == TopAbs_SOLID) {
// TopoDS_Iterator it(a);
// for (; it.More(); it.Next()) {
// OpenCascadeShape s(it.Value());
// if (!is_manifold(&s)) {
// return false;
// }
// }
// return true;
// } else {
// TopTools_IndexedDataMapOfShapeListOfShape map;
// TopExp::MapShapesAndAncestors(a, TopAbs_EDGE, TopAbs_FACE, map);
//
// for (int i = 1; i <= map.Extent(); ++i) {
// if (map.FindFromIndex(i).Extent() != 2) {
// return false;
// }
// }
//
// return true;
// }
//}
+4 -5
View File
@@ -13,20 +13,19 @@
namespace ifcopenshell { namespace geometry {
class Converter {
class IFC_GEOM_API Converter {
public:
typedef boost::shared_ptr<IfcGeom::Representation::BRep> brep_ptr;
private:
std::string geometry_library_;
ifcopenshell::geometry::abstract_mapping* mapping_;
ifcopenshell::geometry::kernels::AbstractKernel* kernel_;
std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel> kernel_;
ifcopenshell::geometry::Settings settings_;
std::map<ifcopenshell::geometry::taxonomy::ptr, brep_ptr, ifcopenshell::geometry::taxonomy::less_functor> cache_;
public:
ifcopenshell::geometry::kernels::AbstractKernel* kernel() { return kernel_; }
ifcopenshell::geometry::kernels::AbstractKernel* kernel() { return &*kernel_; }
Converter(const std::string& geometry_library, IfcParse::IfcFile* file, ifcopenshell::geometry::Settings& settings);
Converter(std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel>&& geometry_library, IfcParse::IfcFile* file, ifcopenshell::geometry::Settings& settings);
~Converter();
+1 -1
View File
@@ -143,7 +143,7 @@ namespace IfcGeom {
{}
bool calculate_projected_surface_area(double& along_x, double& along_y, double& along_z) const {
return geometry().calculate_projected_surface_area(*this->transformation().data(), along_x, along_y, along_z);
return geometry().calculate_projected_surface_area(this->transformation().data(), along_x, along_y, along_z);
}
private:
BRepElement(const BRepElement& other);
+40 -280
View File
@@ -19,128 +19,6 @@
#include "IfcGeomRepresentation.h"
#ifdef IFOPSH_WITH_OPENCASCADE
#include "../ifcparse/IfcLogger.h"
#include "../ifcgeom/kernels/opencascade/OpenCascadeConversionResult.h"
#include "../ifcgeom/kernels/opencascade/base_utils.h"
#include <BRep_Tool.hxx>
#include <BRepTools.hxx>
#include <BRep_Builder.hxx>
#include <Geom_Plane.hxx>
#include <TopoDS_Compound.hxx>
#include <BRepGProp.hxx>
#include <GProp_GProps.hxx>
#include <TopoDS.hxx>
#include <BRepBuilderAPI_Transform.hxx>
#include <BRepBuilderAPI_GTransform.hxx>
TopoDS_Shape apply_transformation(const TopoDS_Shape& s, const gp_Trsf& t) {
if (t.Form() == gp_Identity) {
return s;
} else {
/// @todo set to 1. and exactly 1. or use epsilon?
if (t.ScaleFactor() != 1.) {
return BRepBuilderAPI_Transform(s, t, true);
} else {
return s.Moved(t);
}
}
}
TopoDS_Shape apply_transformation(const TopoDS_Shape& s, const gp_GTrsf& t) {
if (t.Form() == gp_Other) {
return BRepBuilderAPI_GTransform(s, t, true);
} else {
return apply_transformation(s, t.Trsf());
}
}
namespace {
void accumulate(const gp_Ax3& ax, const gp_Dir& normal, double area, double& along_x, double& along_y, double& along_z) {
along_x += area * fabs(ax.XDirection().Dot(normal));
along_y += area * fabs(ax.YDirection().Dot(normal));
along_z += area * fabs(ax.Direction().Dot(normal));
}
void surface_area_along_direction(double tol, const TopoDS_Shape& s, const gp_Ax3& ax, double& along_x, double& along_y, double& along_z) {
along_x = along_y = along_z = 0.;
bool meshed = false;
TopExp_Explorer exp(s, TopAbs_FACE);
for (; exp.More(); exp.Next()) {
const TopoDS_Face& face = TopoDS::Face(exp.Current());
Handle(Geom_Surface) surf = BRep_Tool::Surface(face);
Handle(Geom_Plane) plane = Handle(Geom_Plane)::DownCast(surf);
if (surf->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
GProp_GProps prop_area;
BRepGProp::SurfaceProperties(face, prop_area);
const double area = prop_area.Mass();
accumulate(ax, plane->Position().Direction(), area, along_x, along_y, along_z);
} else {
if (!meshed) {
try {
BRepMesh_IncrementalMesh(s, tol);
} catch (...) {
Logger::Message(Logger::LOG_ERROR, "Failed to triangulate shape");
return;
}
meshed = true;
}
TopLoc_Location loc;
Handle(Poly_Triangulation) tri = BRep_Tool::Triangulation(face, loc);
if (!tri.IsNull()) {
std::vector<gp_XYZ> coords;
coords.reserve(tri->NbNodes());
for (int i = 1; i <= tri->NbNodes(); ++i) {
coords.push_back(tri->Node(i).Transformed(loc).XYZ());
}
const Poly_Array1OfTriangle& triangles = tri->Triangles();
for (int i = 1; i <= triangles.Length(); ++i) {
int n1, n2, n3;
if (face.Orientation() == TopAbs_REVERSED) {
triangles(i).Get(n3, n2, n1);
} else {
triangles(i).Get(n1, n2, n3);
}
const gp_XYZ& pt1 = coords[n1 - 1];
const gp_XYZ& pt2 = coords[n2 - 1];
const gp_XYZ& pt3 = coords[n3 - 1];
const gp_Vec v1 = pt2 - pt1;
const gp_Vec v2 = pt3 - pt2;
const gp_Vec v3 = pt1 - pt3;
const gp_Vec normal_vector = v1 ^ v2;
if (normal_vector.Magnitude() > 1.e-7) {
gp_Dir normal = gp_Dir();
double edge_lengths[3] = { v1.Magnitude(), v2.Magnitude(), v3.Magnitude() };
std::sort(&edge_lengths[0], &edge_lengths[2]);
const double& a = edge_lengths[0];
const double& b = edge_lengths[1];
const double& c = edge_lengths[2];
const double area = 0.25 * sqrt((a + (b + c))*(c - (a - b))*(c + (a - b))*(a + (b - c)));
accumulate(ax, normal, area, along_x, along_y, along_z);
}
}
}
}
}
}
}
#endif
IfcGeom::Representation::Serialization::Serialization(const BRep& brep)
: Representation(brep.settings(), brep.entity(), brep.id())
{
@@ -169,191 +47,73 @@ IfcGeom::Representation::Serialization::Serialization(const BRep& brep)
surface_style_ids_.push_back(sid);
}
if (brep.begin() != brep.end()) {
#ifdef IFOPSH_WITH_OPENCASCADE
if (std::dynamic_pointer_cast<ifcopenshell::geometry::OpenCascadeShape>(brep.begin()->Shape())) {
ConversionResultShape* shape = brep.as_compound();
ifcopenshell::geometry::taxonomy::matrix4 identity;
shape->Serialize(identity, brep_data_);
delete shape;
} else
#endif
{
for (auto it = brep.begin(); it != brep.end(); ++it) {
std::string part;
it->Shape()->Serialize(*it->Placement(), part);
if (brep_data_.size()) {
brep_data_ = brep_data_ + "\n---\n" + part;
} else {
brep_data_ = part;
}
}
}
}
}
namespace {
bool is_non_uniform(const Eigen::Matrix4d& M, double eps = 1e-6)
{
Eigen::Matrix3d L = M.block<3, 3>(0, 0);
double sx = L.col(0).norm();
double sy = L.col(1).norm();
double sz = L.col(2).norm();
return !(
std::abs(sx - sy) < eps &&
std::abs(sx - sz) < eps &&
std::abs(sy - sz) < eps
);
}
ifcopenshell::geometry::taxonomy::matrix4 identity;
auto* comp = brep.as_compound();
comp->Serialize(identity, brep_data_);
delete comp;
}
IfcGeom::ConversionResultShape* IfcGeom::Representation::BRep::as_compound(bool force_meters) const {
#ifdef IFOPSH_WITH_OPENCASCADE
TopoDS_Compound compound;
BRep_Builder builder;
builder.MakeCompound(compound);
ConversionResultShape* accum = nullptr;
for (auto it = begin(); it != end(); ++it) {
const TopoDS_Shape& s = *std::static_pointer_cast<ifcopenshell::geometry::OpenCascadeShape>(it->Shape());
gp_GTrsf trsf;
if (it->Placement()->components_) {
const auto& m = it->Placement()->ccomponents();
// This is either a bug or very finicky, but this appears to be the only
// way to get the transformation metadata to line up.
//
// - If gp_GTrsf.form is other, applying the transformation will result in
// a conversion to b-spline surfaces for about everything, which impacts
// performance and breaks detection of view volume in the svg serializer,
// which would be the case when setting the SetVectorialPart() block
// unconditionally.
// (calling SetForm() afterwards to detect CompoundTrsf over Other would
// set Scale to zero (bug?))
if (is_non_uniform(m)) {
trsf.SetVectorialPart(gp_Mat(
m(0, 0), m(0, 1), m(0, 2),
m(1, 0), m(1, 1), m(1, 2),
m(2, 0), m(2, 1), m(2, 2)
));
trsf.SetTranslationPart(gp_XYZ(m(0, 3), m(1, 3), m(2, 3)));
} else {
gp_Trsf tr;
tr.SetValues(
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
m(1, 0), m(1, 1), m(1, 2), m(1, 3),
m(2, 0), m(2, 1), m(2, 2), m(2, 3)
);
trsf = tr;
}
}
double unit_scale = 1.0;
if (!force_meters && settings().get<ifcopenshell::geometry::settings::ConvertBackUnits>().get()) {
gp_Trsf scale;
scale.SetScaleFactor(1.0 / settings().get<ifcopenshell::geometry::settings::LengthUnit>().get());
trsf.PreMultiply(scale);
unit_scale = 1.0 / settings().get<ifcopenshell::geometry::settings::LengthUnit>().get();
}
auto s = it->apply_transform(unit_scale);
if (accum) {
auto n = accum->concat(s);
delete s;
delete accum;
accum = n;
} else {
accum = s;
}
const TopoDS_Shape moved_shape = apply_transformation(s, trsf);
builder.Add(compound, moved_shape);
}
return new ifcopenshell::geometry::OpenCascadeShape(std::move(compound));
#else
throw std::runtime_error("Not available without Open Cascade");
#endif
return accum;
}
bool IfcGeom::Representation::BRep::calculate_surface_area(double& area) const {
#ifdef IFOPSH_WITH_OPENCASCADE
try {
std::unique_ptr<ConversionResultShape> s(as_compound());
if (!s) {
area = 0.;
for (IfcGeom::ConversionResults::const_iterator it = begin(); it != end(); ++it) {
GProp_GProps prop;
BRepGProp::SurfaceProperties(*std::static_pointer_cast<ifcopenshell::geometry::OpenCascadeShape>(it->Shape()), prop);
area += prop.Mass();
}
return true;
} catch (...) {
Logger::Error("Error during calculation of surface area");
return false;
}
#else
throw std::runtime_error("Not available without Open Cascade");
#endif
area = s->area()->to_double();
return true;
}
bool IfcGeom::Representation::BRep::calculate_volume(double& volume) const {
#ifdef IFOPSH_WITH_OPENCASCADE
try {
std::unique_ptr<ConversionResultShape> s(as_compound());
if (!s) {
volume = 0.;
for (IfcGeom::ConversionResults::const_iterator it = begin(); it != end(); ++it) {
if (util::is_manifold(*std::static_pointer_cast<ifcopenshell::geometry::OpenCascadeShape>(it->Shape()))) {
GProp_GProps prop;
BRepGProp::VolumeProperties(*std::static_pointer_cast<ifcopenshell::geometry::OpenCascadeShape>(it->Shape()), prop);
volume += prop.Mass();
} else {
return false;
}
}
return true;
} catch (...) {
Logger::Error("Error during calculation of volume");
return false;
}
#else
throw std::runtime_error("Not available without Open Cascade");
#endif
volume = s->area()->to_double();
return true;
}
bool IfcGeom::Representation::BRep::calculate_projected_surface_area(const ifcopenshell::geometry::taxonomy::matrix4& place, double & along_x, double & along_y, double & along_z) const {
#ifdef IFOPSH_WITH_OPENCASCADE
try {
gp_GTrsf trsf;
bool IfcGeom::Representation::BRep::calculate_projected_surface_area(const ifcopenshell::geometry::taxonomy::matrix4::ptr& place, double& along_x, double& along_y, double& along_z) const {
along_x = along_y = along_z = 0.;
if (place.components_) {
gp_Trsf tr;
const auto& m = place.ccomponents();
tr.SetValues(
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
m(1, 0), m(1, 1), m(1, 2), m(1, 3),
m(2, 0), m(2, 1), m(2, 2), m(2, 3)
);
trsf = tr;
for (IfcGeom::ConversionResults::const_iterator it = begin(); it != end(); ++it) {
double x, y, z;
it->Shape()->surface_area_along_direction(settings().get<ifcopenshell::geometry::settings::MesherLinearDeflection>().get(), place, x, y, z);
if (it->Shape()->is_manifold()) {
x /= 2.;
y /= 2.;
z /= 2.;
}
gp_Mat mat = trsf.Trsf().HVectorialPart();
gp_Ax3 ax(trsf.TranslationPart(), mat.Column(3), mat.Column(1));
along_x = along_y = along_z = 0.;
for (IfcGeom::ConversionResults::const_iterator it = begin(); it != end(); ++it) {
double x, y, z;
surface_area_along_direction(settings().get<ifcopenshell::geometry::settings::MesherLinearDeflection>().get(), *std::static_pointer_cast<ifcopenshell::geometry::OpenCascadeShape>(it->Shape()), ax, x, y, z);
if (util::is_manifold(*std::static_pointer_cast<ifcopenshell::geometry::OpenCascadeShape>(it->Shape()))) {
x /= 2.;
y /= 2.;
z /= 2.;
}
along_x += x;
along_y += y;
along_z += z;
}
return true;
} catch (...) {
Logger::Error("Error during calculation of projected surface area");
return false;
along_x += x;
along_y += y;
along_z += z;
}
#else
throw std::runtime_error("Not available without Open Cascade");
#endif
return true;
}
IfcGeom::Representation::Triangulation::Triangulation(const BRep& shape_model)
+1 -1
View File
@@ -72,7 +72,7 @@ namespace IfcGeom {
bool calculate_volume(double&) const;
bool calculate_surface_area(double&) const;
bool calculate_projected_surface_area(const ifcopenshell::geometry::taxonomy::matrix4& ax, double& along_x, double& along_y, double& along_z) const;
bool calculate_projected_surface_area(const ifcopenshell::geometry::taxonomy::matrix4::ptr& ax, double& along_x, double& along_y, double& along_z) const;
int size() const { return (int) shapes_.size(); }
const IfcGeom::ConversionResultShape* item(int i) const;
+1 -1
View File
@@ -194,7 +194,7 @@ void IfcGeom::Iterator::process_concurrently() {
kernel_pool.reserve(conc_threads);
for (unsigned i = 0; i < conc_threads; ++i) {
kernel_pool.push_back(new ifcopenshell::geometry::Converter(geometry_library_, ifc_file, settings_));
kernel_pool.push_back(new ifcopenshell::geometry::Converter(std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel>(converter_->kernel()->clone()), ifc_file, settings_));
}
std::vector<std::future<geometry_conversion_result*>> threadpool;
+13 -30
View File
@@ -86,7 +86,7 @@
namespace IfcGeom {
struct geometry_conversion_result {
struct IFC_GEOM_API geometry_conversion_result {
int index;
// For NoParallelMapping==true
@@ -102,7 +102,7 @@ namespace IfcGeom {
};
class Iterator {
class IFC_GEOM_API Iterator {
private:
GeometrySerializer* cache_ = nullptr;
@@ -212,50 +212,33 @@ namespace IfcGeom {
ifcopenshell::geometry::taxonomy::direction3::ptr remove_offset_();
public:
Iterator(const std::string& geometry_library, const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file, const std::vector<IfcGeom::filter_t>& filters, int num_threads)
Iterator(std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel>&& geometry_library, const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file, const std::vector<IfcGeom::filter_t>& filters, int num_threads)
: settings_(settings)
, ifc_file(file)
, filters_(filters)
, num_threads_(num_threads)
, geometry_library_(geometry_library)
, converter_(new ifcopenshell::geometry::Converter(geometry_library_, ifc_file, settings_))
, geometry_library_(geometry_library->geometry_library())
// @todo verify whether settings are correctly passed on
, converter_(new ifcopenshell::geometry::Converter(std::move(geometry_library), ifc_file, settings_))
{
}
Iterator(const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file, const std::vector<IfcGeom::filter_t>& filters, int num_threads)
: settings_(settings)
, ifc_file(file)
, filters_(filters)
, num_threads_(num_threads)
, geometry_library_("opencascade")
, converter_(new ifcopenshell::geometry::Converter(geometry_library_, ifc_file, settings_))
{
}
Iterator(const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file)
Iterator(std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel>&& geometry_library, const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file)
: settings_(settings)
, ifc_file(file)
, num_threads_(1)
, geometry_library_("opencascade")
, converter_(new ifcopenshell::geometry::Converter(geometry_library_, ifc_file, settings_))
, geometry_library_(geometry_library->geometry_library())
, converter_(new ifcopenshell::geometry::Converter(std::move(geometry_library), ifc_file, settings_))
{
}
Iterator(const std::string& geometry_library, const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file)
: settings_(settings)
, ifc_file(file)
, num_threads_(1)
, geometry_library_(geometry_library)
, converter_(new ifcopenshell::geometry::Converter(geometry_library_, ifc_file, settings_))
{
}
Iterator(const std::string& geometry_library, const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file, int num_threads)
Iterator(std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel>&& geometry_library, const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file, int num_threads)
: settings_(settings)
, ifc_file(file)
, num_threads_(num_threads)
, geometry_library_(geometry_library)
, converter_(new ifcopenshell::geometry::Converter(geometry_library_, ifc_file, settings_))
, geometry_library_(geometry_library->geometry_library())
, converter_(new ifcopenshell::geometry::Converter(std::move(geometry_library), ifc_file, settings_))
{
}
+3 -3
View File
@@ -1,12 +1,12 @@
#include "../../ifcparse/IfcBaseClass.h"
#include "../../ifcgeom/ifc_geom_api.h"
#include "ifc_geomserialization_api.h"
#include <TopoDS_Shape.hxx>
#include <string>
namespace IfcGeom {
IFC_GEOM_API IfcUtil::IfcBaseClass* tesselate(const std::string& schema_name, const TopoDS_Shape& shape, double deflection);
IFC_GEOM_API IfcUtil::IfcBaseClass* serialise(const std::string& schema_name, const TopoDS_Shape& shape, bool advanced);
IFC_GEOMSERIALIZATION_API IfcUtil::IfcBaseClass* tesselate(const std::string& schema_name, const TopoDS_Shape& shape, double deflection);
IFC_GEOMSERIALIZATION_API IfcUtil::IfcBaseClass* serialise(const std::string& schema_name, const TopoDS_Shape& shape, bool advanced);
}
@@ -0,0 +1,37 @@
/********************************************************************************
* *
* This file is part of IfcOpenShell. *
* *
* IfcOpenShell is free software: you can redistribute it and/or modify *
* it under the terms of the Lesser GNU General Public License as published by *
* the Free Software Foundation, either version 3.0 of the License, or *
* (at your option) any later version. *
* *
* IfcOpenShell 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 *
* Lesser GNU General Public License for more details. *
* *
* You should have received a copy of the Lesser GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
********************************************************************************/
#ifndef IFC_GEOMSERIALIZATION_API_H
#define IFC_GEOMSERIALIZATION_API_H
#ifdef IFC_SHARED_BUILD
#ifdef _WIN32
#ifdef IFC_GEOMSERIALIZATION_EXPORTS
#define IFC_GEOMSERIALIZATION_API __declspec(dllexport)
#else
#define IFC_GEOMSERIALIZATION_API __declspec(dllimport)
#endif
#else // simply assume *nix + GCC-like compiler
#define IFC_GEOMSERIALIZATION_API __attribute__((visibility("default")))
#endif
#else
#define IFC_GEOMSERIALIZATION_API
#endif
#endif
+23 -4
View File
@@ -1,3 +1,22 @@
/********************************************************************************
* *
* This file is part of IfcOpenShell. *
* *
* IfcOpenShell is free software: you can redistribute it and/or modify *
* it under the terms of the Lesser GNU General Public License as published by *
* the Free Software Foundation, either version 3.0 of the License, or *
* (at your option) any later version. *
* *
* IfcOpenShell 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 *
* Lesser GNU General Public License for more details. *
* *
* You should have received a copy of the Lesser GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
********************************************************************************/
#ifndef ABSTRACT_MAPPING_H
#define ABSTRACT_MAPPING_H
@@ -16,7 +35,7 @@ namespace ifcopenshell {
namespace geometry {
struct geometry_conversion_task {
struct IFC_GEOM_API geometry_conversion_task {
int index;
IfcUtil::IfcBaseEntity* representation;
aggregate_of_instance::ptr products;
@@ -24,7 +43,7 @@ namespace geometry {
typedef boost::function<bool(IfcUtil::IfcBaseEntity*)> filter_t;
class abstract_mapping {
class IFC_GEOM_API abstract_mapping {
protected:
Settings settings_;
@@ -58,14 +77,14 @@ namespace geometry {
namespace impl {
typedef boost::function2<abstract_mapping*, IfcParse::IfcFile*, Settings&> mapping_fn;
class MappingFactoryImplementation : public std::map<std::string, mapping_fn> {
class IFC_GEOM_API MappingFactoryImplementation : public std::map<std::string, mapping_fn> {
public:
MappingFactoryImplementation();
void bind(const std::string& schema_name, mapping_fn);
abstract_mapping* construct(IfcParse::IfcFile*, Settings&);
};
MappingFactoryImplementation& mapping_implementations();
IFC_GEOM_API MappingFactoryImplementation& mapping_implementations();
}
}
+3 -3
View File
@@ -9,7 +9,7 @@ namespace ifcopenshell { namespace geometry {
/// @brief Computes a point on a helmert curve at s.
/// Returns (x,y,theta) at L/2. The results are in a vector so they can be returned to python
std::vector<double> helmert_curve_point(double A0, double A1, double A2, double s);
IFC_GEOM_API std::vector<double> helmert_curve_point(double A0, double A1, double A2, double s);
/// @brief Converts a loop to a function item.
/// This is intended to be used from python side. Polylines are mapped to a loop, but when
@@ -22,7 +22,7 @@ static taxonomy::function_item::ptr convert_loop_to_function_item(taxonomy::loop
}
/// @brief Abstract class for evaluating a function_item. This class is specialized for each of the function_item types.
struct fn_evaluator {
struct IFC_GEOM_API fn_evaluator {
fn_evaluator(const ifcopenshell::geometry::Settings& settings) : settings_(settings) {
}
fn_evaluator(const fn_evaluator& other) = default;
@@ -39,7 +39,7 @@ struct fn_evaluator {
};
/// @brief utility class to evaluate function_item objects.
class function_item_evaluator {
class IFC_GEOM_API function_item_evaluator {
public:
function_item_evaluator(const ifcopenshell::geometry::Settings& settings, taxonomy::function_item::const_ptr fn);
function_item_evaluator(const function_item_evaluator& other);
View File
+239
View File
@@ -0,0 +1,239 @@
/********************************************************************************
* *
* This file is part of IfcOpenShell. *
* *
* IfcOpenShell is free software: you can redistribute it and/or modify *
* it under the terms of the Lesser GNU General Public License as published by *
* the Free Software Foundation, either version 3.0 of the License, or *
* (at your option) any later version. *
* *
* IfcOpenShell 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 *
* Lesser GNU General Public License for more details. *
* *
* You should have received a copy of the Lesser GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
********************************************************************************/
#ifndef HYBRID_KERNEL_H
#define HYBRID_KERNEL_H
#include "AbstractKernel.h"
#ifdef IFOPSH_WITH_OPENCASCADE
#include "../ifcgeom/kernels/opencascade/OpenCascadeKernel.h"
#undef Handle
#endif
#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"
#undef CgalKernel
#endif
namespace {
inline bool is_valid_for_kernel(const ifcopenshell::geometry::kernels::AbstractKernel* k, const IfcGeom::ConversionResult& shp) {
#ifdef IFOPSH_WITH_OPENCASCADE
if (k->geometry_library() == "opencascade") {
return dynamic_cast<ifcopenshell::geometry::OpenCascadeShape*>(shp.Shape().get()) != nullptr;
}
#endif
#ifdef IFOPSH_WITH_CGAL
if (k->geometry_library() == "cgal-simple") {
return dynamic_cast<ifcopenshell::geometry::SimpleCgalShape*>(shp.Shape().get()) != nullptr;
}
if (k->geometry_library() == "cgal") {
return dynamic_cast<ifcopenshell::geometry::CgalShape*>(shp.Shape().get()) != nullptr;
}
#endif
return false;
}
}
namespace ifcopenshell {
namespace geometry {
namespace kernels {
class HybridKernel : public ifcopenshell::geometry::kernels::AbstractKernel {
std::vector<std::unique_ptr<AbstractKernel>> kernels_;
ifcopenshell::geometry::abstract_mapping* mapping_;
IfcParse::IfcFile* file_;
public:
HybridKernel(const std::string& name, IfcParse::IfcFile* file, Settings& settings, std::vector<std::unique_ptr<AbstractKernel>>&& kernels)
: AbstractKernel(name, settings)
, kernels_(std::move(kernels))
, mapping_(ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings))
, file_(file)
{
}
virtual bool supports_boolean_operations() const
{
for (auto& k : kernels_) {
if (k->supports_boolean_operations()) {
return true;
}
}
return false;
}
virtual bool convert(const taxonomy::ptr item, IfcGeom::ConversionResults& rs)
{
auto ops = mapping_->find_openings(item->instance->as<IfcUtil::IfcBaseEntity>());
bool has_openings = ops && ops->size();
for (auto& k : kernels_) {
#ifdef IFOPSH_WITH_CGAL
if (has_openings && !k->supports_boolean_operations()) {
// @todo this would fail later on in the find_openings() call, because we have a
// SimpleCgalShape which cannot be used on a kernel that supports booleans.
// @todo 1 implement the translation between various conversion result shapes
// @todo 2 fold the boolean result openings into the taxonomy item. This should be possible
// now that we have shared_ptr<item> and caching in place. So the inability
// to instance wouldn't matter as much.
continue;
}
#endif
bool success = false;
try {
success = k->convert(item, rs);
} catch (...) {}
if (success) {
return true;
}
}
return false;
}
virtual bool apply_layerset(IfcGeom::ConversionResults& items, const ifcopenshell::geometry::layerset_information& layers)
{
for (auto& k : kernels_) {
bool success = false;
try {
success = k->apply_layerset(items, layers);
} catch (...) {}
if (success) {
return true;
}
}
return false;
}
virtual bool apply_folded_layerset(IfcGeom::ConversionResults& items, const ifcopenshell::geometry::layerset_information& layers, const std::map<IfcUtil::IfcBaseEntity*, ifcopenshell::geometry::layerset_information>& folds)
{
for (auto& k : kernels_) {
bool success = false;
try {
success = k->apply_folded_layerset(items, layers, folds);
} catch (...) {}
if (success) {
return true;
}
}
return false;
}
virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes)
{
for (auto& k : kernels_) {
bool is_valid = true;
for (auto& s : entity_shapes) {
if (!is_valid_for_kernel(k.get(), s)) {
is_valid = false;
break;
}
}
if (!is_valid) {
continue;
}
bool success = false;
try {
success = k->convert_openings(entity, openings, entity_shapes, entity_trsf, cut_shapes);
} catch (...) {}
if (success) {
return true;
}
}
return false;
}
virtual AbstractKernel* clone() const
{
std::vector<std::unique_ptr<AbstractKernel>> ks;
for (auto& k : kernels_) {
ks.emplace_back(k->clone());
}
// @todo ugly
return new HybridKernel(geometry_library(), file_, const_cast<Settings&>(settings()), std::move(ks));
}
};
inline std::unique_ptr<AbstractKernel> construct(IfcParse::IfcFile* file, const std::string& geometry_library, Settings& conv_settings) {
std::string geometry_library_lower = boost::to_lower_copy(geometry_library);
#ifdef IFOPSH_WITH_OPENCASCADE
if (geometry_library_lower == "opencascade") {
return std::make_unique<IfcGeom::OpenCascadeKernel>(conv_settings);
}
#endif
#ifdef IFOPSH_WITH_CGAL
if (geometry_library_lower == "cgal") {
return std::make_unique<CgalKernel>(conv_settings);
}
if (geometry_library_lower == "cgal-simple") {
return std::make_unique<SimpleCgalKernel>(conv_settings);
}
#endif
if (geometry_library_lower.rfind("hybrid-", 0) == 0) {
geometry_library_lower = geometry_library_lower.substr(strlen("hybrid"));
std::vector<std::unique_ptr<AbstractKernel>> kernels;
while (!geometry_library_lower.empty()) {
if (geometry_library_lower.find("-", 0) == 0) {
geometry_library_lower = geometry_library_lower.substr(strlen("-"));
} else {
throw IfcParse::IfcException("Invalid hybrid kernel " + geometry_library);
}
auto n = kernels.size();
#ifdef IFOPSH_WITH_OPENCASCADE
if (geometry_library_lower.find("opencascade", 0) == 0) {
kernels.emplace_back(new IfcGeom::OpenCascadeKernel(conv_settings));
geometry_library_lower = geometry_library_lower.substr(strlen("opencascade"));
}
#endif
#ifdef IFOPSH_WITH_CGAL
if (geometry_library_lower.find("cgal-simple", 0) == 0) {
kernels.emplace_back(new SimpleCgalKernel(conv_settings));
geometry_library_lower = geometry_library_lower.substr(strlen("cgal-simple"));
}
if (geometry_library_lower.find("cgal", 0) == 0) {
kernels.emplace_back(new CgalKernel(conv_settings));
geometry_library_lower = geometry_library_lower.substr(strlen("cgal"));
}
#endif
if (kernels.size() != n + 1) {
throw IfcParse::IfcException("Invalid hybrid kernel " + geometry_library);
}
}
for (auto it = kernels.begin(); it != kernels.end(); ++it) {
(**it).propagate_exceptions = it == kernels.begin();
(**it).partial_success_is_success = it == kernels.end() - 1;
}
if (!kernels.empty()) {
return std::make_unique<HybridKernel>(geometry_library, file, conv_settings, std::move(kernels));
}
}
throw IfcParse::IfcException("No geometry kernel registered for " + geometry_library);
}
}
}
}
#endif
+4 -2
View File
@@ -4,11 +4,13 @@
#include "taxonomy.h"
#include "ConversionSettings.h"
#include "ifc_geom_api.h"
namespace ifcopenshell {
namespace geometry {
struct cross_section {
struct IFC_GEOM_API cross_section {
double dist_along;
taxonomy::geom_item::ptr section_geometry;
Eigen::Vector3d offset;
@@ -19,7 +21,7 @@ namespace ifcopenshell {
}
};
taxonomy::loft::ptr make_loft(const Settings& settings_, const IfcUtil::IfcBaseClass* inst, const taxonomy::function_item::ptr& directrix, std::vector<cross_section>& cross_sections);
IFC_GEOM_API taxonomy::loft::ptr make_loft(const Settings& settings_, const IfcUtil::IfcBaseClass* inst, const taxonomy::function_item::ptr& directrix, std::vector<cross_section>& cross_sections);
}
}
@@ -3,6 +3,8 @@
#include <CGAL/Polygon_mesh_processing/repair.h>
#include <CGAL/Polygon_mesh_processing/self_intersections.h>
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
#include <CGAL/Polygon_mesh_processing/polygon_mesh_to_polygon_soup.h>
#include "../../../ifcparse/IfcLogger.h"
#include "../../../ifcgeom/IfcGeomRepresentation.h"
@@ -19,6 +21,10 @@ using ifcopenshell::geometry::NumberEpeck;
#define NumberType NumberEpeck
#endif
#ifdef IFOPSH_SIMPLE_KERNEL
#define CgalShape SimpleCgalShape
#endif
typedef CGAL::Polyhedron_3<Kernel_> Polyhedron;
typedef Polyhedron::Facet_const_handle Facet_const_handle;
typedef Polyhedron::Halfedge_around_facet_const_circulator Halfedge_around_facet_circulator;
@@ -701,6 +707,43 @@ ConversionResultShape* ifcopenshell::geometry::CgalShape::intersect(ConversionRe
#endif
}
namespace {
template <typename Polyhedron>
void concatenate_polyhedra(Polyhedron& p1, const Polyhedron& p2) {
std::vector<cgal_point_t> points1, points2;
std::vector<std::vector<std::size_t>> faces1, faces2;
// Extract soups
CGAL::Polygon_mesh_processing::polygon_mesh_to_polygon_soup(p1, points1, faces1);
CGAL::Polygon_mesh_processing::polygon_mesh_to_polygon_soup(p2, points2, faces2);
// Offset indices in faces2 by current number of points in points1
std::size_t offset = points1.size();
for (auto& f : faces2) {
for (auto& idx : f) {
idx += offset;
}
}
// Merge soups
points1.insert(points1.end(), points2.begin(), points2.end());
faces1.insert(faces1.end(), faces2.begin(), faces2.end());
// Build merged polyhedron
Polyhedron merged;
CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(points1, faces1, merged);
p1 = std::move(merged);
}
}
ConversionResultShape* ifcopenshell::geometry::CgalShape::concat(ConversionResultShape* other)
{
auto shp = poly();
concatenate_polyhedra(shp, ((CgalShape*)other)->poly());
return new CgalShape(shp);
}
std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> ifcopenshell::geometry::CgalShape::bounding_box() const
{
throw std::runtime_error("Not implemented");
@@ -736,6 +779,11 @@ void ifcopenshell::geometry::CgalShape::map(const std::vector<OpaqueCoordinate<4
throw std::runtime_error("Not implemented");
}
bool ifcopenshell::geometry::CgalShape::surface_area_along_direction(double tol, const ifcopenshell::geometry::taxonomy::matrix4::ptr& place, double& along_x, double& along_y, double& along_z) const {
// @todo
return false;
}
#ifndef IFOPSH_SIMPLE_KERNEL
void ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id) const {
@@ -20,6 +20,8 @@
#ifndef CGALCONVERSIONRESULT_H
#define CGALCONVERSIONRESULT_H
#include "../../../ifcgeom/kernels/ifc_geomlibrary_api.h"
#include "../../../ifcgeom/IfcGeomElement.h"
#undef Handle
@@ -100,7 +102,7 @@ namespace ifcopenshell { namespace geometry {
using IfcGeom::negate_;
#ifndef IFOPSH_SIMPLE_KERNEL
class IFC_GEOM_API NumberEpeck : public OpaqueNumber {
class IFC_GEOMLIBRARY_API NumberEpeck : public OpaqueNumber {
private:
CGAL::Epeck::FT value_;
@@ -175,7 +177,7 @@ namespace ifcopenshell { namespace geometry {
};
#endif
class CgalShape : public IfcGeom::ConversionResultShape {
class IFC_GEOMLIBRARY_API CgalShape : public IfcGeom::ConversionResultShape {
private:
bool convex_tag_ = false;
mutable boost::optional<cgal_shape_t> shape_;
@@ -250,17 +252,20 @@ namespace ifcopenshell { namespace geometry {
virtual ConversionResultShape* add(ConversionResultShape*);
virtual ConversionResultShape* subtract(ConversionResultShape*);
virtual ConversionResultShape* intersect(ConversionResultShape*);
virtual ConversionResultShape* concat(ConversionResultShape*);
virtual void map(OpaqueCoordinate<4>& from, OpaqueCoordinate<4>& to);
virtual void map(const std::vector<OpaqueCoordinate<4>>& from, const std::vector<OpaqueCoordinate<4>>& to);
virtual ConversionResultShape* moved(ifcopenshell::geometry::taxonomy::matrix4::ptr) const;
virtual bool surface_area_along_direction(double tol, const ifcopenshell::geometry::taxonomy::matrix4::ptr&, double& along_x, double& along_y, double& along_z) const;
bool convex_tag() const { return convex_tag_; }
bool& convex_tag() { return convex_tag_; }
};
#ifndef IFOPSH_SIMPLE_KERNEL
class CgalShapeHalfSpaceDecomposition : public IfcGeom::ConversionResultShape {
class IFC_GEOMLIBRARY_API CgalShapeHalfSpaceDecomposition : public IfcGeom::ConversionResultShape {
private:
std::unique_ptr<halfspace_tree<Kernel_>> shape_;
std::list<CGAL::Plane_3<Kernel_>> planes_;
@@ -315,12 +320,23 @@ namespace ifcopenshell { namespace geometry {
virtual ConversionResultShape* add(ConversionResultShape*);
virtual ConversionResultShape* subtract(ConversionResultShape*);
virtual ConversionResultShape* intersect(ConversionResultShape*);
virtual ConversionResultShape* concat(ConversionResultShape*) {
return nullptr;
}
virtual void map(OpaqueCoordinate<4>& from, OpaqueCoordinate<4>& to);
virtual void map(const std::vector<OpaqueCoordinate<4>>& from, const std::vector<OpaqueCoordinate<4>>& to);
virtual ConversionResultShape* moved(ifcopenshell::geometry::taxonomy::matrix4::ptr) const;
virtual bool surface_area_along_direction(double tol, const ifcopenshell::geometry::taxonomy::matrix4::ptr&, double& along_x, double& along_y, double& along_z) const {
return false;
}
};
#endif
}}
#ifdef IFOPSH_SIMPLE_KERNEL
#undef CgalShape
#endif
#endif
+4
View File
@@ -24,6 +24,10 @@
#include "../../../ifcparse/IfcLogger.h"
#include "../../../ifcgeom/kernels/cgal/CgalConversionResult.h"
#ifdef IFOPSH_SIMPLE_KERNEL
#define CgalShape SimpleCgalShape
#endif
#include <CGAL/minkowski_sum_3.h>
#include <CGAL/exceptions.h>
+20 -7
View File
@@ -47,6 +47,7 @@ if ( it != cache.T.end() ) { e = it->second; return true; }
#include "../../../ifcgeom/IfcGeomElement.h"
#include "../../../ifcgeom/kernels/cgal/CgalConversionResult.h"
#include "../../../ifcgeom/kernels/ifc_geomlibrary_api.h"
#include <CGAL/Polygon_2.h>
@@ -55,20 +56,20 @@ if ( it != cache.T.end() ) { e = it->second; return true; }
namespace ifcopenshell {
namespace geometry {
namespace utils {
IFC_GEOM_API CGAL::Polyhedron_3<Kernel_> create_cube(double d);
IFC_GEOM_API CGAL::Polyhedron_3<Kernel_> create_cube(const Kernel_::Point_3& lower, const Kernel_::Point_3& upper);
IFC_GEOM_API CGAL::Polyhedron_3<Kernel_> create_polyhedron(std::list<cgal_face_t> &face_list, bool stitch_borders = false);
IFC_GEOMLIBRARY_API CGAL::Polyhedron_3<Kernel_> create_cube(double d);
IFC_GEOMLIBRARY_API CGAL::Polyhedron_3<Kernel_> create_cube(const Kernel_::Point_3& lower, const Kernel_::Point_3& upper);
IFC_GEOMLIBRARY_API CGAL::Polyhedron_3<Kernel_> create_polyhedron(std::list<cgal_face_t> &face_list, bool stitch_borders = false);
#ifndef IFOPSH_SIMPLE_KERNEL
IFC_GEOM_API CGAL::Polyhedron_3<Kernel_> create_polyhedron(const CGAL::Nef_polyhedron_3<Kernel_> &nef_polyhedron);
IFC_GEOM_API CGAL::Nef_polyhedron_3<Kernel_> create_nef_polyhedron(std::list<cgal_face_t> &face_list);
IFC_GEOM_API CGAL::Nef_polyhedron_3<Kernel_> create_nef_polyhedron(CGAL::Polyhedron_3<Kernel_> &polyhedron);
IFC_GEOMLIBRARY_API CGAL::Polyhedron_3<Kernel_> create_polyhedron(const CGAL::Nef_polyhedron_3<Kernel_> &nef_polyhedron);
IFC_GEOMLIBRARY_API CGAL::Nef_polyhedron_3<Kernel_> create_nef_polyhedron(std::list<cgal_face_t> &face_list);
IFC_GEOMLIBRARY_API CGAL::Nef_polyhedron_3<Kernel_> create_nef_polyhedron(CGAL::Polyhedron_3<Kernel_> &polyhedron);
#endif
}
namespace kernels {
class IFC_GEOM_API CgalKernel : public AbstractKernel {
class IFC_GEOMLIBRARY_API CgalKernel : public AbstractKernel {
private:
#ifndef IFOPSH_SIMPLE_KERNEL
enum boolean_operand_preprocess {
@@ -94,6 +95,18 @@ namespace ifcopenshell {
: AbstractKernel("cgal", settings)
{}
virtual AbstractKernel* clone() const {
return new CgalKernel(settings());
}
virtual bool supports_boolean_operations() const {
#ifndef IFOPSH_SIMPLE_KERNEL
return true;
#else
return false;
#endif
}
bool convert(const taxonomy::extrusion::ptr, cgal_shape_t&);
bool convert(const taxonomy::face::ptr, std::list<cgal_face_t>&);
bool convert(const taxonomy::loop::ptr, cgal_wire_t&);
+37
View File
@@ -0,0 +1,37 @@
/********************************************************************************
* *
* This file is part of IfcOpenShell. *
* *
* IfcOpenShell is free software: you can redistribute it and/or modify *
* it under the terms of the Lesser GNU General Public License as published by *
* the Free Software Foundation, either version 3.0 of the License, or *
* (at your option) any later version. *
* *
* IfcOpenShell 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 *
* Lesser GNU General Public License for more details. *
* *
* You should have received a copy of the Lesser GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
********************************************************************************/
#ifndef IFC_GEOMLIBRARY_API_H
#define IFC_GEOMLIBRARY_API_H
#ifdef IFC_SHARED_BUILD
#ifdef _WIN32
#ifdef IFC_GEOMLIBRARY_EXPORTS
#define IFC_GEOMLIBRARY_API __declspec(dllexport)
#else
#define IFC_GEOMLIBRARY_API __declspec(dllimport)
#endif
#else // simply assume *nix + GCC-like compiler
#define IFC_GEOMLIBRARY_API __attribute__((visibility("default")))
#endif
#else
#define IFC_GEOMLIBRARY_API
#endif
#endif
@@ -25,6 +25,7 @@
#include "../../../ifcgeom/IfcGeomElement.h"
#include "../../../ifcgeom/Iterator.h"
#include "OpenCascadeConversionResult.h"
#include "OpenCascadeKernel.h"
#include "base_utils.h"
#include <NCollection_UBTree.hxx>
@@ -1503,7 +1504,7 @@ namespace IfcGeom {
settings_.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = true;
settings_.get<ifcopenshell::geometry::settings::ReorientShells>().value = true;
IfcGeom::Iterator it(settings_, &f, {}, 1);
IfcGeom::Iterator it(std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel>(new OpenCascadeKernel(settings_)), settings_, &f, {}, 1);
add_file(it);
}
@@ -7,6 +7,8 @@
#include <Geom_SphericalSurface.hxx>
#include <Geom_Plane.hxx>
#include <BRepTools_WireExplorer.hxx>
#include <TopoDS_Compound.hxx>
#include <BRep_Builder.hxx>
#include "OpenCascadeConversionResult.h"
@@ -546,6 +548,26 @@ ConversionResultShape* ifcopenshell::geometry::OpenCascadeShape::intersect(Conve
return boolean_op(BOPAlgo_COMMON, shape_, ((ifcopenshell::geometry::OpenCascadeShape*)other)->shape_);
}
ConversionResultShape* ifcopenshell::geometry::OpenCascadeShape::concat(ConversionResultShape* other)
{
TopoDS_Compound compound;
BRep_Builder builder;
auto& left = shape_;
auto& right = ((ifcopenshell::geometry::OpenCascadeShape*)other)->shape_;
if (left.ShapeType() == TopAbs_COMPOUND) {
compound = TopoDS::Compound(left);
} else {
builder.MakeCompound(compound);
builder.Add(compound, left);
}
builder.Add(compound, right);
return new OpenCascadeShape(std::move(compound));
}
std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> ifcopenshell::geometry::OpenCascadeShape::bounding_box() const
{
throw std::runtime_error("Not implemented");
@@ -556,6 +578,113 @@ ConversionResultShape* ifcopenshell::geometry::OpenCascadeShape::moved(ifcopensh
return new OpenCascadeShape(IfcGeom::util::apply_transformation(shape_, *t));
}
namespace {
void accumulate(const gp_Ax3& ax, const gp_Dir& normal, double area, double& along_x, double& along_y, double& along_z) {
along_x += area * fabs(ax.XDirection().Dot(normal));
along_y += area * fabs(ax.YDirection().Dot(normal));
along_z += area * fabs(ax.Direction().Dot(normal));
}
void surface_area_along_direction_(double tol, const TopoDS_Shape& s, const gp_Ax3& ax, double& along_x, double& along_y, double& along_z) {
along_x = along_y = along_z = 0.;
bool meshed = false;
TopExp_Explorer exp(s, TopAbs_FACE);
for (; exp.More(); exp.Next()) {
const TopoDS_Face& face = TopoDS::Face(exp.Current());
Handle(Geom_Surface) surf = BRep_Tool::Surface(face);
Handle(Geom_Plane) plane = Handle(Geom_Plane)::DownCast(surf);
if (surf->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
GProp_GProps prop_area;
BRepGProp::SurfaceProperties(face, prop_area);
const double area = prop_area.Mass();
accumulate(ax, plane->Position().Direction(), area, along_x, along_y, along_z);
} else {
if (!meshed) {
try {
BRepMesh_IncrementalMesh(s, tol);
} catch (...) {
Logger::Message(Logger::LOG_ERROR, "Failed to triangulate shape");
return;
}
meshed = true;
}
TopLoc_Location loc;
Handle(Poly_Triangulation) tri = BRep_Tool::Triangulation(face, loc);
if (!tri.IsNull()) {
std::vector<gp_XYZ> coords;
coords.reserve(tri->NbNodes());
for (int i = 1; i <= tri->NbNodes(); ++i) {
coords.push_back(tri->Node(i).Transformed(loc).XYZ());
}
const Poly_Array1OfTriangle& triangles = tri->Triangles();
for (int i = 1; i <= triangles.Length(); ++i) {
int n1, n2, n3;
if (face.Orientation() == TopAbs_REVERSED) {
triangles(i).Get(n3, n2, n1);
} else {
triangles(i).Get(n1, n2, n3);
}
const gp_XYZ& pt1 = coords[n1 - 1];
const gp_XYZ& pt2 = coords[n2 - 1];
const gp_XYZ& pt3 = coords[n3 - 1];
const gp_Vec v1 = pt2 - pt1;
const gp_Vec v2 = pt3 - pt2;
const gp_Vec v3 = pt1 - pt3;
const gp_Vec normal_vector = v1 ^ v2;
if (normal_vector.Magnitude() > 1.e-7) {
gp_Dir normal = gp_Dir();
double edge_lengths[3] = { v1.Magnitude(), v2.Magnitude(), v3.Magnitude() };
std::sort(&edge_lengths[0], &edge_lengths[2]);
const double& a = edge_lengths[0];
const double& b = edge_lengths[1];
const double& c = edge_lengths[2];
const double area = 0.25 * sqrt((a + (b + c)) * (c - (a - b)) * (c + (a - b)) * (a + (b - c)));
accumulate(ax, normal, area, along_x, along_y, along_z);
}
}
}
}
}
}
}
bool ifcopenshell::geometry::OpenCascadeShape::surface_area_along_direction(double tol, const ifcopenshell::geometry::taxonomy::matrix4::ptr& place, double& along_x, double& along_y, double& along_z) const
{
gp_GTrsf trsf;
if (place->components_) {
gp_Trsf tr;
const auto& m = place->ccomponents();
tr.SetValues(
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
m(1, 0), m(1, 1), m(1, 2), m(1, 3),
m(2, 0), m(2, 1), m(2, 2), m(2, 3)
);
trsf = tr;
}
gp_Mat mat = trsf.Trsf().HVectorialPart();
gp_Ax3 ax(trsf.TranslationPart(), mat.Column(3), mat.Column(1));
surface_area_along_direction_(tol, shape_, ax, along_x, along_y, along_z);
return true;
}
void ifcopenshell::geometry::OpenCascadeShape::map(OpaqueCoordinate<4>&, OpaqueCoordinate<4>&) {
throw std::runtime_error("Not implemented");
}
@@ -35,6 +35,7 @@
#include <GCPnts_QuasiUniformDeflection.hxx>
#include "../../../ifcgeom/ConversionResult.h"
#include "../../../ifcgeom/kernels/ifc_geomlibrary_api.h"
namespace ifcopenshell {
namespace geometry {
@@ -42,7 +43,7 @@ namespace ifcopenshell {
using IfcGeom::OpaqueCoordinate;
using IfcGeom::OpaqueNumber;
class OpenCascadeShape : public IfcGeom::ConversionResultShape {
class IFC_GEOMLIBRARY_API OpenCascadeShape : public IfcGeom::ConversionResultShape {
public:
OpenCascadeShape(const TopoDS_Shape& shape)
: shape_(shape) {}
@@ -97,10 +98,13 @@ namespace ifcopenshell {
virtual ConversionResultShape* add(ConversionResultShape*);
virtual ConversionResultShape* subtract(ConversionResultShape*);
virtual ConversionResultShape* intersect(ConversionResultShape*);
virtual ConversionResultShape* concat(ConversionResultShape*);
virtual void map(OpaqueCoordinate<4>& from, OpaqueCoordinate<4>& to);
virtual void map(const std::vector<OpaqueCoordinate<4>>& from, const std::vector<OpaqueCoordinate<4>>& to);
virtual ConversionResultShape* moved(ifcopenshell::geometry::taxonomy::matrix4::ptr) const;
virtual bool surface_area_along_direction(double tol, const ifcopenshell::geometry::taxonomy::matrix4::ptr&, double& along_x, double& along_y, double& along_z) const;
private:
TopoDS_Shape shape_;
};
@@ -51,14 +51,14 @@
#include "../../../ifcgeom/kernels/opencascade/OpenCascadeConversionResult.h"
#include "../../../ifcgeom/ifc_geom_api.h"
#include "../../../ifcgeom/kernels/ifc_geomlibrary_api.h"
#include "../../../ifcgeom/taxonomy.h"
#include "../../../ifcgeom/ConversionSettings.h"
namespace IfcGeom {
class IFC_GEOM_API OpenCascadeKernel : public ifcopenshell::geometry::kernels::AbstractKernel {
class IFC_GEOMLIBRARY_API OpenCascadeKernel : public ifcopenshell::geometry::kernels::AbstractKernel {
private:
/*
@@ -103,6 +103,12 @@ public:
, precision_(settings.get<ifcopenshell::geometry::settings::Precision>().get())
{}
virtual AbstractKernel* clone() const {
return new OpenCascadeKernel(settings());
}
virtual bool supports_boolean_operations() const { return true; }
bool convert(const ifcopenshell::geometry::taxonomy::extrusion::ptr, TopoDS_Shape&);
bool convert(const ifcopenshell::geometry::taxonomy::face::ptr, TopoDS_Shape&, bool reversed_surface = false);
bool convert(const ifcopenshell::geometry::taxonomy::loop::ptr, TopoDS_Wire&);
+60 -8
View File
@@ -4,6 +4,8 @@
#include "OpenCascadeConversionResult.h"
#include "boolean_utils.h"
#include <Standard_Version.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
@@ -48,6 +50,8 @@
#include <TopTools_IndexedMapOfShape.hxx>
#include <ShapeUpgrade_UnifySameDomain.hxx>
// For axis placements detect equality early in order for the
// relatively computionaly expensive gp_Trsf calculation to be skipped
bool IfcGeom::util::axis_equal(const gp_Ax3 & a, const gp_Ax3 & b, double tolerance) {
@@ -297,18 +301,52 @@ TopoDS_Shape IfcGeom::util::apply_transformation(const TopoDS_Shape& s, const gp
}
}
namespace {
bool is_non_uniform(const Eigen::Matrix4d& M, double eps = 1e-6)
{
Eigen::Matrix3d L = M.block<3, 3>(0, 0);
double sx = L.col(0).norm();
double sy = L.col(1).norm();
double sz = L.col(2).norm();
return !(
std::abs(sx - sy) < eps &&
std::abs(sx - sz) < eps &&
std::abs(sy - sz) < eps
);
}
}
TopoDS_Shape IfcGeom::util::apply_transformation(const TopoDS_Shape& s, const ifcopenshell::geometry::taxonomy::matrix4& t) {
// @todo this probably discards non-uniform scale?
gp_GTrsf trsf;
if (t.components_) {
gp_Trsf tr;
const auto& m = t.ccomponents();
tr.SetValues(
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
m(1, 0), m(1, 1), m(1, 2), m(1, 3),
m(2, 0), m(2, 1), m(2, 2), m(2, 3)
);
trsf = tr;
// This is either a bug or very finicky, but this appears to be the only
// way to get the transformation metadata to line up.
//
// - If gp_GTrsf.form is other, applying the transformation will result in
// a conversion to b-spline surfaces for about everything, which impacts
// performance and breaks detection of view volume in the svg serializer,
// which would be the case when setting the SetVectorialPart() block
// unconditionally.
// (calling SetForm() afterwards to detect CompoundTrsf over Other would
// set Scale to zero (bug?))
if (is_non_uniform(m)) {
trsf.SetVectorialPart(gp_Mat(
m(0, 0), m(0, 1), m(0, 2),
m(1, 0), m(1, 1), m(1, 2),
m(2, 0), m(2, 1), m(2, 2)
));
trsf.SetTranslationPart(gp_XYZ(m(0, 3), m(1, 3), m(2, 3)));
} else {
gp_Trsf tr;
tr.SetValues(
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
m(1, 0), m(1, 1), m(1, 2), m(1, 3),
m(2, 0), m(2, 1), m(2, 2), m(2, 3)
);
trsf = tr;
}
}
return apply_transformation(s, trsf);
}
@@ -864,3 +902,17 @@ bool IfcGeom::util::validate_shape(const TopoDS_Shape& s) {
return false;
}
TopoDS_Shape IfcGeom::util::unify(const TopoDS_Shape& s, double tolerance) {
tolerance = (std::min)(min_edge_length(s) / 2., tolerance);
ShapeUpgrade_UnifySameDomain usd(s);
#if OCC_VERSION_HEX >= 0x70200
usd.SetSafeInputMode(true);
#endif
#if OCC_VERSION_HEX >= 0x70100
usd.SetLinearTolerance(tolerance);
usd.SetAngularTolerance(1.e-3);
#endif
usd.Build();
return usd.Shape();
}
+40 -37
View File
@@ -2,6 +2,7 @@
#define BASE_UTILS_H
#include "../../../ifcgeom/ConversionResult.h"
#include "../ifc_geomlibrary_api.h"
#include <gp_Pln.hxx>
#include <gp_Pnt.hxx>
@@ -25,58 +26,60 @@
namespace IfcGeom {
namespace util {
int count(const TopoDS_Shape&, TopAbs_ShapeEnum, bool unique = false);
int surface_genus(const TopoDS_Shape&);
IFC_GEOMLIBRARY_API int count(const TopoDS_Shape&, TopAbs_ShapeEnum, bool unique = false);
IFC_GEOMLIBRARY_API int surface_genus(const TopoDS_Shape&);
bool is_manifold(const TopoDS_Shape& a);
IFC_GEOMLIBRARY_API bool is_manifold(const TopoDS_Shape& a);
// For axis placements detect equality early in order for the
// relatively computionaly expensive gp_Trsf calculation to be skipped
bool axis_equal(const gp_Ax3& a, const gp_Ax3& b, double tolerance);
IFC_GEOMLIBRARY_API bool axis_equal(const gp_Ax3& a, const gp_Ax3& b, double tolerance);
bool axis_equal(const gp_Ax2d& a, const gp_Ax2d& b, double tolerance);
IFC_GEOMLIBRARY_API bool axis_equal(const gp_Ax2d& a, const gp_Ax2d& b, double tolerance);
bool is_identity(const gp_Trsf2d& t, double tolerance);
bool is_identity(const gp_GTrsf2d& t, double tolerance);
bool is_identity(const gp_Trsf& t, double tolerance);
bool is_identity(const gp_GTrsf& t, double tolerance);
IFC_GEOMLIBRARY_API bool is_identity(const gp_Trsf2d& t, double tolerance);
IFC_GEOMLIBRARY_API bool is_identity(const gp_GTrsf2d& t, double tolerance);
IFC_GEOMLIBRARY_API bool is_identity(const gp_Trsf& t, double tolerance);
IFC_GEOMLIBRARY_API bool is_identity(const gp_GTrsf& t, double tolerance);
gp_Trsf combine_offset_and_rotation(const gp_Vec &offset, const gp_Quaternion& rotation);
IFC_GEOMLIBRARY_API gp_Trsf combine_offset_and_rotation(const gp_Vec &offset, const gp_Quaternion& rotation);
bool is_nested_compound_of_solid(const TopoDS_Shape& s, int depth = 0);
IFC_GEOMLIBRARY_API bool is_nested_compound_of_solid(const TopoDS_Shape& s, int depth = 0);
// Creates a solid from a compound of faces. When there are multiple connected components,
// a compound of solids is returned.
bool create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& solid, double tol);
bool shape_to_face_list(const TopoDS_Shape& s, TopTools_ListOfShape& li);
bool create_solid_from_faces(const TopTools_ListOfShape& face_list, TopoDS_Shape& solid, double tol, bool force_sewing = false);
bool is_compound(const TopoDS_Shape& shape);
bool is_convex(const TopoDS_Wire& wire, double tol);
TopoDS_Shape halfspace_from_plane(const gp_Pln& pln, const gp_Pnt& cent);
gp_Pln plane_from_face(const TopoDS_Face& face);
gp_Pnt point_above_plane(const gp_Pln& pln, bool agree = true);
IFC_GEOMLIBRARY_API bool create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& solid, double tol);
IFC_GEOMLIBRARY_API bool shape_to_face_list(const TopoDS_Shape& s, TopTools_ListOfShape& li);
IFC_GEOMLIBRARY_API bool create_solid_from_faces(const TopTools_ListOfShape& face_list, TopoDS_Shape& solid, double tol, bool force_sewing = false);
IFC_GEOMLIBRARY_API bool is_compound(const TopoDS_Shape& shape);
IFC_GEOMLIBRARY_API bool is_convex(const TopoDS_Wire& wire, double tol);
IFC_GEOMLIBRARY_API TopoDS_Shape halfspace_from_plane(const gp_Pln& pln, const gp_Pnt& cent);
IFC_GEOMLIBRARY_API gp_Pln plane_from_face(const TopoDS_Face& face);
IFC_GEOMLIBRARY_API gp_Pnt point_above_plane(const gp_Pln& pln, bool agree = true);
bool fit_halfspace(const TopoDS_Shape& a, const TopoDS_Shape& b, TopoDS_Shape& box, double& height, double tol);
const Handle_Geom_Curve intersect(const Handle_Geom_Surface&, const Handle_Geom_Surface&);
const Handle_Geom_Curve intersect(const Handle_Geom_Surface&, const TopoDS_Face&);
const Handle_Geom_Curve intersect(const TopoDS_Face&, const Handle_Geom_Surface&);
bool intersect(const Handle_Geom_Curve&, const Handle_Geom_Surface&, gp_Pnt&);
bool intersect(const Handle_Geom_Curve&, const TopoDS_Face&, gp_Pnt&);
bool intersect(const Handle_Geom_Curve&, const TopoDS_Shape&, std::vector<gp_Pnt>&);
bool intersect(const Handle_Geom_Surface&, const TopoDS_Shape&, std::vector< std::pair<Handle_Geom_Surface, Handle_Geom_Curve> >&);
bool closest(const gp_Pnt&, const std::vector<gp_Pnt>&, gp_Pnt&);
bool project(const Handle_Geom_Curve&, const gp_Pnt&, gp_Pnt& p, double& u, double& d);
bool project(const Handle_Geom_Surface&, const TopoDS_Shape&, double& u1, double& v1, double& u2, double& v2, double widen = 0.1);
IFC_GEOMLIBRARY_API bool fit_halfspace(const TopoDS_Shape& a, const TopoDS_Shape& b, TopoDS_Shape& box, double& height, double tol);
IFC_GEOMLIBRARY_API const Handle_Geom_Curve intersect(const Handle_Geom_Surface&, const Handle_Geom_Surface&);
IFC_GEOMLIBRARY_API const Handle_Geom_Curve intersect(const Handle_Geom_Surface&, const TopoDS_Face&);
IFC_GEOMLIBRARY_API const Handle_Geom_Curve intersect(const TopoDS_Face&, const Handle_Geom_Surface&);
IFC_GEOMLIBRARY_API bool intersect(const Handle_Geom_Curve&, const Handle_Geom_Surface&, gp_Pnt&);
IFC_GEOMLIBRARY_API bool intersect(const Handle_Geom_Curve&, const TopoDS_Face&, gp_Pnt&);
IFC_GEOMLIBRARY_API bool intersect(const Handle_Geom_Curve&, const TopoDS_Shape&, std::vector<gp_Pnt>&);
IFC_GEOMLIBRARY_API bool intersect(const Handle_Geom_Surface&, const TopoDS_Shape&, std::vector< std::pair<Handle_Geom_Surface, Handle_Geom_Curve> >&);
IFC_GEOMLIBRARY_API bool closest(const gp_Pnt&, const std::vector<gp_Pnt>&, gp_Pnt&);
IFC_GEOMLIBRARY_API bool project(const Handle_Geom_Curve&, const gp_Pnt&, gp_Pnt& p, double& u, double& d);
IFC_GEOMLIBRARY_API bool project(const Handle_Geom_Surface&, const TopoDS_Shape&, double& u1, double& v1, double& u2, double& v2, double widen = 0.1);
double shape_volume(const TopoDS_Shape& s);
double face_area(const TopoDS_Face& f);
IFC_GEOMLIBRARY_API double shape_volume(const TopoDS_Shape& s);
IFC_GEOMLIBRARY_API double face_area(const TopoDS_Face& f);
TopoDS_Shape apply_transformation(const TopoDS_Shape&, const ifcopenshell::geometry::taxonomy::matrix4& t);
TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_Trsf&);
TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_GTrsf&);
IFC_GEOMLIBRARY_API TopoDS_Shape apply_transformation(const TopoDS_Shape&, const ifcopenshell::geometry::taxonomy::matrix4& t);
IFC_GEOMLIBRARY_API TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_Trsf&);
IFC_GEOMLIBRARY_API TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_GTrsf&);
bool flatten_shape_list(const IfcGeom::ConversionResults& shapes, TopoDS_Shape& result, bool fuse, bool create_shell, double tol);
bool validate_shape(const TopoDS_Shape&);
IFC_GEOMLIBRARY_API bool flatten_shape_list(const IfcGeom::ConversionResults& shapes, TopoDS_Shape& result, bool fuse, bool create_shell, double tol);
IFC_GEOMLIBRARY_API bool validate_shape(const TopoDS_Shape&);
IFC_GEOMLIBRARY_API TopoDS_Shape unify(const TopoDS_Shape& s, double tolerance);
}
}
@@ -13,7 +13,6 @@
#include <Extrema_ExtPC.hxx>
#include <Geom_Plane.hxx>
#include <Geom_BSplineCurve.hxx>
#include <ShapeUpgrade_UnifySameDomain.hxx>
#include <GeomAPI_ExtremaCurveCurve.hxx>
#include <ShapeAnalysis_Surface.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
@@ -575,20 +574,6 @@ int IfcGeom::util::eliminate_touching_operands(double prec, const TopoDS_Shape &
return N;
}
TopoDS_Shape IfcGeom::util::unify(const TopoDS_Shape & s, double tolerance) {
tolerance = (std::min)(min_edge_length(s) / 2., tolerance);
ShapeUpgrade_UnifySameDomain usd(s);
#if OCC_VERSION_HEX >= 0x70200
usd.SetSafeInputMode(true);
#endif
#if OCC_VERSION_HEX >= 0x70100
usd.SetLinearTolerance(tolerance);
usd.SetAngularTolerance(1.e-3);
#endif
usd.Build();
return usd.Shape();
}
bool IfcGeom::util::boolean_subtraction_2d_using_builder(const TopoDS_Shape & a_input, const TopTools_ListOfShape & b_input, TopoDS_Shape & result, double eps) {
IfcGeom::impl::tree<int> edge_tree;
@@ -30,6 +30,8 @@
#include <TopTools_IndexedMapOfShape.hxx>
#include <BOPAlgo_Operation.hxx>
#include "../ifc_geomlibrary_api.h"
namespace IfcGeom {
namespace util {
@@ -83,8 +85,6 @@ namespace IfcGeom {
int eliminate_narrow_operands(double prec, const TopTools_ListOfShape& bs, TopTools_ListOfShape & c);
TopoDS_Shape unify(const TopoDS_Shape& s, double tolerance);
bool boolean_subtraction_2d_using_builder(const TopoDS_Shape& a_input, const TopTools_ListOfShape& b_input, TopoDS_Shape& result, double eps);
struct boolean_settings {
@@ -3,27 +3,29 @@
#include <gp_Vec.hxx>
#include <array>
struct ray {
#include "../ifc_geomlibrary_api.h"
struct IFC_GEOMLIBRARY_API ray {
float origin[3];
float dir[3];
float dir_inv[3];
};
struct box {
struct IFC_GEOMLIBRARY_API box {
float corners[2][3];
};
bool is_intersect_ray_box(const struct ray *ray, const struct box *box);
IFC_GEOMLIBRARY_API bool is_intersect_ray_box(const struct ray *ray, const struct box *box);
bool intersectRayTriangle( const gp_Vec& orig, const gp_Vec& dir,
IFC_GEOMLIBRARY_API bool intersectRayTriangle( const gp_Vec& orig, const gp_Vec& dir,
const gp_Vec& vert0, const gp_Vec& vert1, const gp_Vec& vert2,
Standard_Real& at, Standard_Real& au, Standard_Real& av,
bool cull, float enlarge=0.0f);
void edgeEdgeDist(gp_Vec& x, gp_Vec& y, // closest points
IFC_GEOMLIBRARY_API void edgeEdgeDist(gp_Vec& x, gp_Vec& y, // closest points
const gp_Vec& p, const gp_Vec& a, // seg 1 origin, vector
const gp_Vec& q, const gp_Vec& b); // seg 2 origin, vector
float distanceTriangleTriangleSquared(gp_Vec& cp, gp_Vec& cq, const std::array<gp_Vec, 3> p, const std::array<gp_Vec, 3> q);
IFC_GEOMLIBRARY_API float distanceTriangleTriangleSquared(gp_Vec& cp, gp_Vec& cq, const std::array<gp_Vec, 3> p, const std::array<gp_Vec, 3> q);
bool trianglesIntersect(const gp_Vec& a1, const gp_Vec& b1, const gp_Vec& c1, const gp_Vec& a2, const gp_Vec& b2, const gp_Vec& c2/*, Segment* intersection*/, gp_Vec& int1, gp_Vec& int2, bool ignoreCoplanar);
IFC_GEOMLIBRARY_API bool trianglesIntersect(const gp_Vec& a1, const gp_Vec& b1, const gp_Vec& c1, const gp_Vec& a2, const gp_Vec& b2, const gp_Vec& c2/*, Segment* intersection*/, gp_Vec& int1, gp_Vec& int2, bool ignoreCoplanar);
+16 -14
View File
@@ -1,6 +1,8 @@
#ifndef WIRE_UTILS_H
#define WIRE_UTILS_H
#include "../ifc_geomlibrary_api.h"
#include <gp_Pln.hxx>
#include <Geom_Curve.hxx>
@@ -17,9 +19,9 @@
namespace IfcGeom {
namespace util {
bool approximate_plane_through_wire(const TopoDS_Wire& wire, gp_Pln& plane, double eps);
IFC_GEOMLIBRARY_API bool approximate_plane_through_wire(const TopoDS_Wire& wire, gp_Pln& plane, double eps);
bool flatten_wire(TopoDS_Wire& wire, double eps);
IFC_GEOMLIBRARY_API bool flatten_wire(TopoDS_Wire& wire, double eps);
enum triangulate_wire_result {
TRIANGULATE_WIRE_FAIL,
@@ -35,25 +37,25 @@ namespace IfcGeom {
};
/// Triangulate the set of wires. The firstmost wire is assumed to be the outer wire.
triangulate_wire_result triangulate_wire(const std::vector<TopoDS_Wire>& wires, TopTools_ListOfShape& faces);
IFC_GEOMLIBRARY_API triangulate_wire_result triangulate_wire(const std::vector<TopoDS_Wire>& wires, TopTools_ListOfShape& faces);
bool wire_intersections(const TopoDS_Wire& wire, TopTools_ListOfShape& wires, const wire_tolerance_settings& settings);
IFC_GEOMLIBRARY_API bool wire_intersections(const TopoDS_Wire& wire, TopTools_ListOfShape& wires, const wire_tolerance_settings& settings);
void select_largest(const TopTools_ListOfShape& shapes, TopoDS_Shape& largest);
IFC_GEOMLIBRARY_API void select_largest(const TopTools_ListOfShape& shapes, TopoDS_Shape& largest);
bool convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face, const IfcGeom::util::wire_tolerance_settings& settings);
IFC_GEOMLIBRARY_API bool convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face, const IfcGeom::util::wire_tolerance_settings& settings);
bool convert_wire_to_faces(const TopoDS_Wire& wire, TopoDS_Compound& face, const IfcGeom::util::wire_tolerance_settings& settings);
IFC_GEOMLIBRARY_API bool convert_wire_to_faces(const TopoDS_Wire& wire, TopoDS_Compound& face, const IfcGeom::util::wire_tolerance_settings& settings);
void assert_closed_wire(TopoDS_Wire& wire, double tol);
IFC_GEOMLIBRARY_API void assert_closed_wire(TopoDS_Wire& wire, double tol);
bool fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& shape, double tol);
void remove_duplicate_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol);
void remove_collinear_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol);
bool wire_to_sequence_of_point(const TopoDS_Wire&, TColgp_SequenceOfPnt&);
void sequence_of_point_to_wire(const TColgp_SequenceOfPnt&, TopoDS_Wire&, bool closed);
IFC_GEOMLIBRARY_API bool fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& shape, double tol);
IFC_GEOMLIBRARY_API void remove_duplicate_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol);
IFC_GEOMLIBRARY_API void remove_collinear_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol);
IFC_GEOMLIBRARY_API bool wire_to_sequence_of_point(const TopoDS_Wire&, TColgp_SequenceOfPnt&);
IFC_GEOMLIBRARY_API void sequence_of_point_to_wire(const TColgp_SequenceOfPnt&, TopoDS_Wire&, bool closed);
bool convert_curve_to_wire(const Handle(Geom_Curve)& curve, TopoDS_Wire& wire);
IFC_GEOMLIBRARY_API bool convert_curve_to_wire(const Handle(Geom_Curve)& curve, TopoDS_Wire& wire);
}
}
+64 -56
View File
@@ -87,7 +87,7 @@ typedef item* ptr; \
typedef item const* ptr;
#endif
class topology_error : public std::runtime_error {
class IFC_GEOM_API topology_error : public std::runtime_error {
public:
topology_error() : std::runtime_error("Generic topology error") {}
topology_error(const char* const s) : std::runtime_error(s) {}
@@ -138,9 +138,9 @@ typedef item const* ptr;
STYLE
};
const std::string& kind_to_string(kinds k);
IFC_GEOM_API const std::string& kind_to_string(kinds k);
struct item {
struct IFC_GEOM_API item {
private:
uint32_t identity_;
static std::atomic_uint32_t counter_;
@@ -195,7 +195,7 @@ typedef item const* ptr;
}
template <typename T>
struct eigen_base {
struct IFC_GEOM_API eigen_base {
T* components_;
eigen_base() {
@@ -264,7 +264,7 @@ typedef item const* ptr;
}
};
struct matrix4 : public item, public eigen_base<Eigen::Matrix4d> {
struct IFC_GEOM_API matrix4 : public item, public eigen_base<Eigen::Matrix4d> {
private:
void init(const Eigen::Vector3d& o, const Eigen::Vector3d& z, const Eigen::Vector3d& x) {
auto Z = z.normalized();
@@ -319,10 +319,18 @@ typedef item const* ptr;
return boost::hash<decltype(v)>{}(v);
}
void pre_multiply_scale(double s) {
components().block<3, 4>(0, 0) *= s;
}
void post_multiply_scale(double s) {
components().block<4, 3>(0, 0) *= s;
}
Eigen::Vector3d translation_part() const { return ccomponents().col(3).head<3>(); }
};
struct colour : public item, public eigen_base<Eigen::Vector3d> {
struct IFC_GEOM_API colour : public item, public eigen_base<Eigen::Vector3d> {
DECLARE_PTR(colour)
void print(std::ostream& o, int indent = 0) const;
@@ -343,7 +351,7 @@ typedef item const* ptr;
const double& b() const { return ccomponents()[2]; }
};
struct style : public item {
struct IFC_GEOM_API style : public item {
DECLARE_PTR(style)
std::string name;
@@ -385,7 +393,7 @@ typedef item const* ptr;
}
};
struct geom_item : public item {
struct IFC_GEOM_API geom_item : public item {
DECLARE_PTR(geom_item)
style::ptr surface_style;
@@ -396,12 +404,12 @@ typedef item const* ptr;
geom_item(matrix4::ptr m) : surface_style(nullptr), matrix(m) {}
};
struct implicit_item : public geom_item {
struct IFC_GEOM_API implicit_item : public geom_item {
DECLARE_PTR(implicit_item)
using geom_item::geom_item;
};
struct function_item : public implicit_item {
struct IFC_GEOM_API function_item : public implicit_item {
DECLARE_PTR(function_item)
function_item(const IfcUtil::IfcBaseInterface* instance = nullptr) : implicit_item(instance) {}
@@ -422,7 +430,7 @@ typedef item const* ptr;
};
};
struct functor_item : public function_item {
struct IFC_GEOM_API functor_item : public function_item {
DECLARE_PTR(functor_item)
functor_item(double length, std::function<Eigen::Matrix4d(double u)> fn, const IfcUtil::IfcBaseInterface* instance = nullptr) : function_item(instance),
@@ -448,7 +456,7 @@ typedef item const* ptr;
std::function<Eigen::Matrix4d(double u)> fn_;
};
struct piecewise_function : public function_item {
struct IFC_GEOM_API piecewise_function : public function_item {
DECLARE_PTR(piecewise_function)
using spans_t = std::vector<function_item::const_ptr>;
@@ -480,7 +488,7 @@ typedef item const* ptr;
spans_t spans_;
};
struct gradient_function : public function_item {
struct IFC_GEOM_API gradient_function : public function_item {
DECLARE_PTR(gradient_function)
gradient_function(piecewise_function::const_ptr horizontal, piecewise_function::const_ptr vertical, const IfcUtil::IfcBaseInterface* instance = nullptr);
gradient_function(gradient_function&&) = default;
@@ -506,7 +514,7 @@ typedef item const* ptr;
piecewise_function::const_ptr horizontal_, vertical_;
};
struct cant_function : public function_item {
struct IFC_GEOM_API cant_function : public function_item {
DECLARE_PTR(cant_function)
cant_function(gradient_function::const_ptr gradient, piecewise_function::const_ptr cant, const IfcUtil::IfcBaseInterface* instance = nullptr);
cant_function(cant_function&&) = default;
@@ -533,7 +541,7 @@ typedef item const* ptr;
piecewise_function::const_ptr cant_;
};
struct offset_function : public function_item {
struct IFC_GEOM_API offset_function : public function_item {
DECLARE_PTR(offset_function)
offset_function(function_item::const_ptr basis, piecewise_function::const_ptr offset, const IfcUtil::IfcBaseInterface* instance = nullptr);
offset_function(offset_function&&) = default;
@@ -585,7 +593,7 @@ typedef item const* ptr;
}
#endif
bool less(item::const_ptr, item::const_ptr);
IFC_GEOM_API bool less(item::const_ptr, item::const_ptr);
struct less_functor {
bool operator()(item::const_ptr a, item::const_ptr b) const {
@@ -613,13 +621,13 @@ typedef item const* ptr;
// @todo make 4d for easier multiplication
template <size_t N>
struct cartesian_base : public item, public eigen_base<Eigen::Vector3d> {
struct IFC_GEOM_API cartesian_base : public item, public eigen_base<Eigen::Vector3d> {
cartesian_base() : eigen_base() {}
cartesian_base(const Eigen::Vector3d& c) : eigen_base(c) {}
cartesian_base(double x, double y, double z = 0.) : eigen_base(Eigen::Vector3d(x, y, z)) {}
};
struct point3 : public cartesian_base<3> {
struct IFC_GEOM_API point3 : public cartesian_base<3> {
DECLARE_PTR(point3)
virtual point3* clone_() const { return new point3(*this); }
@@ -637,7 +645,7 @@ typedef item const* ptr;
point3(double x, double y, double z = 0.) : cartesian_base(x, y, z) {}
};
struct direction3 : public cartesian_base<3> {
struct IFC_GEOM_API direction3 : public cartesian_base<3> {
DECLARE_PTR(direction3)
virtual direction3* clone_() const { return new direction3(*this); }
@@ -655,14 +663,14 @@ typedef item const* ptr;
direction3(double x, double y, double z = 0.) : cartesian_base(x, y, z) {}
};
struct curve : public geom_item {
struct IFC_GEOM_API curve : public geom_item {
void print_impl(std::ostream& o, const std::string& classname, int indent = 0) const {
o << std::string(indent, ' ') << classname << std::endl;
this->matrix->print(o, indent + 4);
}
};
struct line : public curve {
struct IFC_GEOM_API line : public curve {
DECLARE_PTR(line)
virtual line* clone_() const { return new line(*this); }
@@ -676,7 +684,7 @@ typedef item const* ptr;
void print(std::ostream& o, int indent = 0) const;
};
struct circle : public curve {
struct IFC_GEOM_API circle : public curve {
DECLARE_PTR(circle)
double radius;
@@ -720,7 +728,7 @@ typedef item const* ptr;
}
};
struct ellipse : public curve {
struct IFC_GEOM_API ellipse : public curve {
DECLARE_PTR(ellipse)
double radius;
@@ -737,7 +745,7 @@ typedef item const* ptr;
void print(std::ostream& o, int indent = 0) const;
};
struct bspline_curve : public curve {
struct IFC_GEOM_API bspline_curve : public curve {
DECLARE_PTR(bspline_curve)
virtual bspline_curve* clone_() const { return new bspline_curve(*this); }
@@ -770,7 +778,7 @@ typedef item const* ptr;
int degree;
};
struct offset_curve : public curve {
struct IFC_GEOM_API offset_curve : public curve {
DECLARE_PTR(offset_curve)
direction3::ptr reference;
@@ -786,7 +794,7 @@ typedef item const* ptr;
}
};
struct trimmed_curve : public geom_item {
struct IFC_GEOM_API trimmed_curve : public geom_item {
DECLARE_PTR(trimmed_curve)
// @todo The copy constructor of point3 within the variant fails on the avx instruction
@@ -810,7 +818,7 @@ typedef item const* ptr;
void print(std::ostream& o, int indent = 0) const;
};
struct edge : public trimmed_curve {
struct IFC_GEOM_API edge : public trimmed_curve {
DECLARE_PTR(edge)
edge() : trimmed_curve() {}
@@ -827,7 +835,7 @@ typedef item const* ptr;
};
template <typename T = item>
struct collection_base : public geom_item {
struct IFC_GEOM_API collection_base : public geom_item {
std::vector<typename T::ptr> children;
collection_base() {}
@@ -893,7 +901,7 @@ typedef item const* ptr;
}
};
struct collection : public collection_base<geom_item> {
struct IFC_GEOM_API collection : public collection_base<geom_item> {
DECLARE_PTR(collection)
virtual collection* clone_() const { return new collection(*this); }
@@ -906,7 +914,7 @@ typedef item const* ptr;
};
struct loop : public collection_base<edge> {
struct IFC_GEOM_API loop : public collection_base<edge> {
DECLARE_PTR(loop)
boost::optional<bool> external, closed;
@@ -969,7 +977,7 @@ typedef item const* ptr;
}
};
struct face : public collection_base<loop> {
struct IFC_GEOM_API face : public collection_base<loop> {
DECLARE_PTR(face)
item::ptr basis;
@@ -990,7 +998,7 @@ typedef item const* ptr;
}
};
struct shell : public collection_base<face> {
struct IFC_GEOM_API shell : public collection_base<face> {
DECLARE_PTR(shell)
boost::optional<bool> closed;
@@ -1028,7 +1036,7 @@ typedef item const* ptr;
}
};
struct solid : public collection_base<shell> {
struct IFC_GEOM_API solid : public collection_base<shell> {
DECLARE_PTR(solid)
virtual solid* clone_() const { return new solid(*this); }
@@ -1040,7 +1048,7 @@ typedef item const* ptr;
}
};
struct loft : public collection_base<geom_item> {
struct IFC_GEOM_API loft : public collection_base<geom_item> {
DECLARE_PTR(loft)
item::ptr axis;
@@ -1059,9 +1067,9 @@ typedef item const* ptr;
}
};
struct surface : public geom_item {};
struct IFC_GEOM_API surface : public geom_item {};
struct plane : public surface {
struct IFC_GEOM_API plane : public surface {
DECLARE_PTR(plane)
virtual plane* clone_() const { return new plane(*this); }
@@ -1073,7 +1081,7 @@ typedef item const* ptr;
}
};
struct cylinder : public surface {
struct IFC_GEOM_API cylinder : public surface {
DECLARE_PTR(cylinder)
double radius;
@@ -1087,7 +1095,7 @@ typedef item const* ptr;
}
};
struct sphere : public surface {
struct IFC_GEOM_API sphere : public surface {
DECLARE_PTR(sphere)
double radius;
@@ -1101,7 +1109,7 @@ typedef item const* ptr;
}
};
struct torus : public surface {
struct IFC_GEOM_API torus : public surface {
DECLARE_PTR(torus)
double radius1;
@@ -1116,7 +1124,7 @@ typedef item const* ptr;
}
};
struct bspline_surface : public surface {
struct IFC_GEOM_API bspline_surface : public surface {
DECLARE_PTR(bspline_surface)
virtual bspline_surface* clone_() const { return new bspline_surface(*this); }
@@ -1159,7 +1167,7 @@ typedef item const* ptr;
std::array<int, 2> degree;
};
struct sweep : public geom_item {
struct IFC_GEOM_API sweep : public geom_item {
DECLARE_PTR(sweep)
item::ptr basis;
@@ -1168,7 +1176,7 @@ typedef item const* ptr;
sweep(matrix4::ptr m, item::ptr b) : geom_item(m), basis(b) {}
};
struct extrusion : public sweep {
struct IFC_GEOM_API extrusion : public sweep {
DECLARE_PTR(extrusion)
direction3::ptr direction;
@@ -1187,7 +1195,7 @@ typedef item const* ptr;
}
};
struct revolve : public sweep {
struct IFC_GEOM_API revolve : public sweep {
DECLARE_PTR(revolve)
point3::ptr axis_origin;
@@ -1205,7 +1213,7 @@ typedef item const* ptr;
}
};
struct sweep_along_curve : public sweep {
struct IFC_GEOM_API sweep_along_curve : public sweep {
DECLARE_PTR(sweep_along_curve)
item::ptr surface;
@@ -1226,7 +1234,7 @@ typedef item const* ptr;
}
};
struct node : public item {
struct IFC_GEOM_API node : public item {
DECLARE_PTR(node)
// std::map<std::string, geom_item> representations;
@@ -1242,7 +1250,7 @@ typedef item const* ptr;
}
};
struct boolean_result : public collection_base<geom_item> {
struct IFC_GEOM_API boolean_result : public collection_base<geom_item> {
DECLARE_PTR(boolean_result)
enum operation_t {
@@ -1300,7 +1308,7 @@ typedef item const* ptr;
static const size_t max = std::tuple_size<impl::UpgradesTuple>::value;
};
boost::optional<face::ptr> loop_to_face_upgrade_impl(ptr item);
IFC_GEOM_API boost::optional<face::ptr> loop_to_face_upgrade_impl(ptr item);
template <typename T>
class loop_to_face_upgrade {
private:
@@ -1326,7 +1334,7 @@ typedef item const* ptr;
}
};
boost::optional<edge::ptr> curve_to_edge_upgrade_impl(ptr item);
IFC_GEOM_API boost::optional<edge::ptr> curve_to_edge_upgrade_impl(ptr item);
template <typename T>
class curve_to_edge_upgrade {
private:
@@ -1352,7 +1360,7 @@ typedef item const* ptr;
}
};
boost::optional<loop::ptr> curve_to_loop_upgrade_impl(ptr item);
IFC_GEOM_API boost::optional<loop::ptr> curve_to_loop_upgrade_impl(ptr item);
template <typename T>
class curve_to_loop_upgrade {
private:
@@ -1378,7 +1386,7 @@ typedef item const* ptr;
}
};
boost::optional<loop::ptr> edge_to_loop_upgrade_impl(ptr item);
IFC_GEOM_API boost::optional<loop::ptr> edge_to_loop_upgrade_impl(ptr item);
template <typename T>
class edge_to_loop_upgrade {
private:
@@ -1404,7 +1412,7 @@ typedef item const* ptr;
}
};
boost::optional<face::ptr> curve_to_face_upgrade_impl(ptr item);
IFC_GEOM_API boost::optional<face::ptr> curve_to_face_upgrade_impl(ptr item);
template <typename T>
class curve_to_face_upgrade {
private:
@@ -1430,7 +1438,7 @@ typedef item const* ptr;
}
};
boost::optional<function_item::ptr> loop_to_function_item_upgrade_impl(ptr item);
IFC_GEOM_API boost::optional<function_item::ptr> loop_to_function_item_upgrade_impl(ptr item);
template <typename T>
class loop_to_function_item_upgrade {
private:
@@ -1672,7 +1680,7 @@ typedef item const* ptr;
}
}
taxonomy::collection::ptr flatten(const taxonomy::collection::ptr& deep);
IFC_GEOM_API taxonomy::collection::ptr flatten(const taxonomy::collection::ptr& deep);
template <typename Fn>
bool apply_predicate_to_collection(const taxonomy::ptr& i, Fn fn) {
@@ -1724,10 +1732,10 @@ typedef item const* ptr;
return collection;
}
taxonomy::solid::ptr create_box(double dx, double dy, double dz);
taxonomy::solid::ptr create_box(double x, double y, double z, double dx, double dy, double dz);
IFC_GEOM_API taxonomy::solid::ptr create_box(double dx, double dy, double dz);
IFC_GEOM_API taxonomy::solid::ptr create_box(double x, double y, double z, double dx, double dy, double dz);
struct layerset_information {
struct IFC_GEOM_API layerset_information {
std::vector<double> thicknesses;
std::vector<ifcopenshell::geometry::taxonomy::ptr> layers;
std::vector<ifcopenshell::geometry::taxonomy::style> styles;
+3 -3
View File
@@ -32,9 +32,9 @@
#include <string>
namespace IfcUtil {
std::u32string::value_type convert_codepage(int codepage, int index);
std::string convert_utf8(const std::u32string& string);
std::u32string convert_utf8(const std::string& string);
IFC_PARSE_API std::u32string::value_type convert_codepage(int codepage, int index);
IFC_PARSE_API std::string convert_utf8(const std::u32string& string);
IFC_PARSE_API std::u32string convert_utf8(const std::string& string);
} // namespace IfcUtil
namespace IfcParse {
+40 -40
View File
@@ -501,52 +501,52 @@ void rocks_db_attribute_storage::set(void* storage, const IfcParse::declaration*
std::to_string(index), v);
}
template void rocks_db_attribute_storage::set<Blank>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const Blank& value);
template void rocks_db_attribute_storage::set<int>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const int& value);
template void rocks_db_attribute_storage::set<bool>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const bool& value);
template void rocks_db_attribute_storage::set<boost::logic::tribool>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const boost::logic::tribool& value);
template void rocks_db_attribute_storage::set<double>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const double& value);
template void rocks_db_attribute_storage::set<std::string>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const std::string& value);
template void rocks_db_attribute_storage::set<boost::dynamic_bitset<>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const boost::dynamic_bitset<>& value);
template void rocks_db_attribute_storage::set<EnumerationReference>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const EnumerationReference& value);
template void rocks_db_attribute_storage::set<IfcUtil::IfcBaseClass*>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, IfcUtil::IfcBaseClass* const& value);
template void rocks_db_attribute_storage::set<std::vector<int>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const std::vector<int>& value);
template void rocks_db_attribute_storage::set<std::vector<double>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const std::vector<double>& value);
template void rocks_db_attribute_storage::set<std::vector<std::string>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const std::vector<std::string>& value);
template void rocks_db_attribute_storage::set<std::vector<boost::dynamic_bitset<>>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const std::vector<boost::dynamic_bitset<>>& value);
template void rocks_db_attribute_storage::set<aggregate_of_instance::ptr>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const aggregate_of_instance::ptr& value);
template void rocks_db_attribute_storage::set<std::vector<std::vector<int>>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const std::vector<std::vector<int>>& value);
template void rocks_db_attribute_storage::set<std::vector<std::vector<double>>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const std::vector<std::vector<double>>& value);
template void rocks_db_attribute_storage::set<aggregate_of_aggregate_of_instance::ptr>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const aggregate_of_aggregate_of_instance::ptr& value);
template IFC_PARSE_API void rocks_db_attribute_storage::set<Blank>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const Blank& value);
template IFC_PARSE_API void rocks_db_attribute_storage::set<int>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const int& value);
template IFC_PARSE_API void rocks_db_attribute_storage::set<bool>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const bool& value);
template IFC_PARSE_API void rocks_db_attribute_storage::set<boost::logic::tribool>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const boost::logic::tribool& value);
template IFC_PARSE_API void rocks_db_attribute_storage::set<double>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const double& value);
template IFC_PARSE_API void rocks_db_attribute_storage::set<std::string>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const std::string& value);
template IFC_PARSE_API void rocks_db_attribute_storage::set<boost::dynamic_bitset<>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const boost::dynamic_bitset<>& value);
template IFC_PARSE_API void rocks_db_attribute_storage::set<EnumerationReference>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const EnumerationReference& value);
template IFC_PARSE_API void rocks_db_attribute_storage::set<IfcUtil::IfcBaseClass*>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, IfcUtil::IfcBaseClass* const& value);
template IFC_PARSE_API void rocks_db_attribute_storage::set<std::vector<int>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const std::vector<int>& value);
template IFC_PARSE_API void rocks_db_attribute_storage::set<std::vector<double>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const std::vector<double>& value);
template IFC_PARSE_API void rocks_db_attribute_storage::set<std::vector<std::string>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const std::vector<std::string>& value);
template IFC_PARSE_API void rocks_db_attribute_storage::set<std::vector<boost::dynamic_bitset<>>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const std::vector<boost::dynamic_bitset<>>& value);
template IFC_PARSE_API void rocks_db_attribute_storage::set<aggregate_of_instance::ptr>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const aggregate_of_instance::ptr& value);
template IFC_PARSE_API void rocks_db_attribute_storage::set<std::vector<std::vector<int>>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const std::vector<std::vector<int>>& value);
template IFC_PARSE_API void rocks_db_attribute_storage::set<std::vector<std::vector<double>>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const std::vector<std::vector<double>>& value);
template IFC_PARSE_API void rocks_db_attribute_storage::set<aggregate_of_aggregate_of_instance::ptr>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const aggregate_of_aggregate_of_instance::ptr& value);
// @todo why do these need to be included, but are not in BaseEntity::set()?
template void rocks_db_attribute_storage::set<Derived>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const Derived& value);
template void rocks_db_attribute_storage::set<empty_aggregate_t>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const empty_aggregate_t& value);
template void rocks_db_attribute_storage::set<empty_aggregate_of_aggregate_t>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const empty_aggregate_of_aggregate_t& value);
template IFC_PARSE_API void rocks_db_attribute_storage::set<Derived>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const Derived& value);
template IFC_PARSE_API void rocks_db_attribute_storage::set<empty_aggregate_t>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const empty_aggregate_t& value);
template IFC_PARSE_API void rocks_db_attribute_storage::set<empty_aggregate_of_aggregate_t>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index, const empty_aggregate_of_aggregate_t& value);
template bool rocks_db_attribute_storage::has<Blank>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template bool rocks_db_attribute_storage::has<int>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template bool rocks_db_attribute_storage::has<bool>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template bool rocks_db_attribute_storage::has<boost::logic::tribool>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template bool rocks_db_attribute_storage::has<double>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template bool rocks_db_attribute_storage::has<std::string>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template bool rocks_db_attribute_storage::has<boost::dynamic_bitset<>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template bool rocks_db_attribute_storage::has<EnumerationReference>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template bool rocks_db_attribute_storage::has<IfcUtil::IfcBaseClass*>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template bool rocks_db_attribute_storage::has<std::vector<int>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template bool rocks_db_attribute_storage::has<std::vector<double>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template bool rocks_db_attribute_storage::has<std::vector<std::string>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template bool rocks_db_attribute_storage::has<std::vector<boost::dynamic_bitset<>>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template bool rocks_db_attribute_storage::has<aggregate_of_instance::ptr>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template bool rocks_db_attribute_storage::has<std::vector<std::vector<int>>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template bool rocks_db_attribute_storage::has<std::vector<std::vector<double>>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template bool rocks_db_attribute_storage::has<aggregate_of_aggregate_of_instance::ptr>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template IFC_PARSE_API bool rocks_db_attribute_storage::has<Blank>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template IFC_PARSE_API bool rocks_db_attribute_storage::has<int>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template IFC_PARSE_API bool rocks_db_attribute_storage::has<bool>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template IFC_PARSE_API bool rocks_db_attribute_storage::has<boost::logic::tribool>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template IFC_PARSE_API bool rocks_db_attribute_storage::has<double>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template IFC_PARSE_API bool rocks_db_attribute_storage::has<std::string>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template IFC_PARSE_API bool rocks_db_attribute_storage::has<boost::dynamic_bitset<>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template IFC_PARSE_API bool rocks_db_attribute_storage::has<EnumerationReference>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template IFC_PARSE_API bool rocks_db_attribute_storage::has<IfcUtil::IfcBaseClass*>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template IFC_PARSE_API bool rocks_db_attribute_storage::has<std::vector<int>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template IFC_PARSE_API bool rocks_db_attribute_storage::has<std::vector<double>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template IFC_PARSE_API bool rocks_db_attribute_storage::has<std::vector<std::string>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template IFC_PARSE_API bool rocks_db_attribute_storage::has<std::vector<boost::dynamic_bitset<>>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template IFC_PARSE_API bool rocks_db_attribute_storage::has<aggregate_of_instance::ptr>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template IFC_PARSE_API bool rocks_db_attribute_storage::has<std::vector<std::vector<int>>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template IFC_PARSE_API bool rocks_db_attribute_storage::has<std::vector<std::vector<double>>>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template IFC_PARSE_API bool rocks_db_attribute_storage::has<aggregate_of_aggregate_of_instance::ptr>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
// @todo why do these need to be included, but are not in BaseEntity::set()?
template bool rocks_db_attribute_storage::has<Derived>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template bool rocks_db_attribute_storage::has<empty_aggregate_t>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template bool rocks_db_attribute_storage::has<empty_aggregate_of_aggregate_t>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template IFC_PARSE_API bool rocks_db_attribute_storage::has<Derived>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template IFC_PARSE_API bool rocks_db_attribute_storage::has<empty_aggregate_t>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
template IFC_PARSE_API bool rocks_db_attribute_storage::has<empty_aggregate_of_aggregate_t>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
#endif
+11 -11
View File
@@ -41,7 +41,7 @@
#include <boost/logic/tribool.hpp>
#include <boost/dynamic_bitset.hpp>
class EnumerationReference {
class IFC_PARSE_API EnumerationReference {
private:
const IfcParse::enumeration_type* enumeration_;
size_t index_;
@@ -64,10 +64,10 @@ public:
return enumeration_;
}
};
class Blank {};
class Derived {};
class empty_aggregate_t {};
class empty_aggregate_of_aggregate_t {};
class IFC_PARSE_API Blank {};
class IFC_PARSE_API Derived {};
class IFC_PARSE_API empty_aggregate_t {};
class IFC_PARSE_API empty_aggregate_of_aggregate_t {};
template<typename... Args>
struct parameter_pack {
@@ -154,14 +154,14 @@ struct TypeEncoder_t<parameter_pack<Types...>> {
using TypeEncoder = TypeEncoder_t<type_variant_parameter_pack>;
struct MutableAttributeValue {
struct IFC_PARSE_API MutableAttributeValue {
int name_;
uint8_t index_;
};
namespace IfcParse {
namespace impl {
class rocks_db_file_storage;
class IFC_PARSE_API rocks_db_file_storage;
}
}
@@ -283,7 +283,7 @@ namespace impl {
#endif
// short lived
struct AttributeValue {
struct IFC_PARSE_API AttributeValue {
uint8_t index_;
uint8_t storage_model_ = 0;
const IfcParse::declaration* entity_or_type_ = 0;
@@ -391,15 +391,15 @@ struct AttributeValue {
};
struct rocks_db_attribute_storage {
struct IFC_PARSE_API rocks_db_attribute_storage {
public:
#ifdef IFOPSH_WITH_ROCKSDB
// @todo void* is obviously very ugly here
template<typename T>
void set(void* storage, const IfcParse::declaration*, std::size_t identity, std::size_t index, const T& value);
IFC_PARSE_API void set(void* storage, const IfcParse::declaration*, std::size_t identity, std::size_t index, const T& value);
template<typename T>
bool has(void* storage, const IfcParse::declaration* decl, std::size_t identity, std::size_t index) const;
IFC_PARSE_API bool has(void* storage, const IfcParse::declaration* decl, std::size_t identity, std::size_t index) const;
template<typename Visitor>
auto apply_visitor(void* storage, const IfcParse::declaration* decl, std::size_t identity, std::size_t index, Visitor&& visitor) const {
+2 -3
View File
@@ -84,10 +84,9 @@ enum filetype {
FT_AUTODETECT
};
filetype guess_file_type(const std::string& fn);
IFC_PARSE_API filetype guess_file_type(const std::string& fn);
class InstanceStreamer {
class IFC_PARSE_API InstanceStreamer {
private:
IfcSpfStream* stream_;
IfcSpfLexer* lexer_;
+3 -8
View File
@@ -188,7 +188,7 @@ namespace IfcParse {
};
namespace impl {
struct in_memory_file_storage {
struct IFC_PARSE_API in_memory_file_storage {
IfcParse::IfcSpfLexer* tokens;
// IfcParse::IfcSpfStream* stream;
@@ -248,11 +248,6 @@ namespace IfcParse {
}
};
static bool guid_map_;
static bool guid_map() { return guid_map_; }
static void guid_map(bool b) { guid_map_ = b; }
entity_instance_by_name_t byid_;
type_instance_by_name_t tbyid_;
entities_by_type_t bytype_excl_;
@@ -303,7 +298,7 @@ namespace IfcParse {
IfcUtil::IfcBaseClass* create(const IfcParse::declaration* decl);
};
class rocks_db_file_storage {
class IFC_PARSE_API rocks_db_file_storage {
public:
rocksdb::DB* db;
rocksdb::WriteOptions wopts;
@@ -441,7 +436,7 @@ namespace IfcParse {
*/
// @todo merge iterators (template?)
class rocksdb_types_iterator {
class IFC_PARSE_API rocksdb_types_iterator {
private:
rocksdb::Iterator* state_;
const rocks_db_file_storage* storage_;
+6 -4
View File
@@ -71,6 +71,7 @@
}
%newobject IfcGeom::Representation::BRep::item;
%newobject IfcGeom::Representation::BRep::as_compound;
%newobject IfcGeom::ConversionResultShape::halfspaces;
%newobject IfcGeom::ConversionResultShape::box;
@@ -78,6 +79,7 @@
%newobject IfcGeom::ConversionResultShape::add;
%newobject IfcGeom::ConversionResultShape::subtract;
%newobject IfcGeom::ConversionResultShape::intersect;
%newobject IfcGeom::ConversionResultShape::concat;
%newobject IfcGeom::ConversionResultShape::moved;
%newobject IfcGeom::ConversionResultShape::area;
@@ -635,7 +637,7 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
IfcGeom::Iterator* construct_iterator_with_include_exclude(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, std::vector<std::string> elems, bool include, int num_threads) {
std::set<std::string> elems_set(elems.begin(), elems.end());
IfcGeom::entity_filter ef{ include, false, elems_set };
return new IfcGeom::Iterator(geometry_library, settings, file, {ef}, num_threads);
return new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(file, geometry_library, settings), settings, file, {ef}, num_threads);
}
IfcGeom::Iterator* construct_iterator_with_include_exclude_globalid(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, std::vector<std::string> elems, bool include, int num_threads) {
@@ -644,13 +646,13 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
af.attribute_name = "GlobalId";
af.populate(elems_set);
af.include = include;
return new IfcGeom::Iterator(geometry_library, settings, file, {af}, num_threads);
return new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(file, geometry_library, settings), settings, file, {af}, num_threads);
}
IfcGeom::Iterator* construct_iterator_with_include_exclude_id(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, std::vector<int> elems, bool include, int num_threads) {
std::set<int> elems_set(elems.begin(), elems.end());
IfcGeom::instance_id_filter af(include, false, elems_set);
return new IfcGeom::Iterator(geometry_library, settings, file, {af}, num_threads);
return new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(file, geometry_library, settings), settings, file, {af}, num_threads);
}
%}
@@ -876,7 +878,7 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
static boost::variant<IfcGeom::Element*, IfcGeom::Representation::Representation*, IfcGeom::Transformation*> helper_fn_create_shape(const std::string& geometry_library, ifcopenshell::geometry::Settings& st, IfcUtil::IfcBaseClass* instance, IfcUtil::IfcBaseClass* representation = 0) {
IfcParse::IfcFile* file = instance->file_;
ifcopenshell::geometry::Converter kernel(geometry_library, file, st);
ifcopenshell::geometry::Converter kernel(ifcopenshell::geometry::kernels::construct(file, geometry_library, st), file, st);
if (typename Schema::IfcProduct* product = instance->as<typename Schema::IfcProduct>()) {
if (representation) {
+1
View File
@@ -294,6 +294,7 @@ constexpr bool is_std_vector_vector_v = is_std_vector_vector<T>::value;
#endif
#include "../ifcgeom/Iterator.h"
#include "../ifcgeom/ConversionResult.h"
#include "../ifcgeom/hybrid_kernel.h"
#include "../serializers/SvgSerializer.h"
#include "../serializers/WavefrontObjSerializer.h"
+1 -1
View File
@@ -22,7 +22,7 @@
#ifdef IFC_SHARED_BUILD
#ifdef _WIN32
#ifdef Serializers_EXPORTS
#ifdef SERIALIZERS_EXPORTS
#define SERIALIZERS_API __declspec(dllexport)
#else
#define SERIALIZERS_API __declspec(dllimport)