mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 06:39:13 +00:00
dllimport/export #6926
This commit is contained in:
@@ -45,6 +45,7 @@
|
|||||||
#include "../ifcgeom/IfcGeomFilter.h"
|
#include "../ifcgeom/IfcGeomFilter.h"
|
||||||
#include "../ifcgeom/Iterator.h"
|
#include "../ifcgeom/Iterator.h"
|
||||||
#include "../ifcgeom/IfcGeomRenderStyles.h"
|
#include "../ifcgeom/IfcGeomRenderStyles.h"
|
||||||
|
#include "../ifcgeom/hybrid_kernel.h"
|
||||||
|
|
||||||
#include "../ifcparse/utils.h"
|
#include "../ifcparse/utils.h"
|
||||||
|
|
||||||
@@ -1018,7 +1019,7 @@ int main(int argc, char** argv) {
|
|||||||
if (is_tesselated && (center_model || center_model_geometry)) {
|
if (is_tesselated && (center_model || center_model_geometry)) {
|
||||||
std::vector<double> offset(3);
|
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_t start, end;
|
||||||
time(&start);
|
time(&start);
|
||||||
@@ -1064,7 +1065,7 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
std::unique_ptr<IfcGeom::Iterator> context_iterator;
|
std::unique_ptr<IfcGeom::Iterator> context_iterator;
|
||||||
if (!elems_from_adaptor) {
|
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)
|
#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::ConvertBackUnits>().value = true;
|
||||||
settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
|
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()) {
|
if (!context_iterator.initialize()) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,23 +1,9 @@
|
|||||||
#include "AbstractKernel.h"
|
|
||||||
|
|
||||||
#include "../ifcgeom/IfcGeomElement.h"
|
#include "../ifcgeom/IfcGeomElement.h"
|
||||||
#include "../ifcgeom/ConversionSettings.h"
|
#include "../ifcgeom/ConversionSettings.h"
|
||||||
#include "../ifcgeom/abstract_mapping.h"
|
#include "../ifcgeom/abstract_mapping.h"
|
||||||
#include "../ifcgeom/function_item_evaluator.h"
|
#include "../ifcgeom/function_item_evaluator.h"
|
||||||
|
|
||||||
#ifdef IFOPSH_WITH_OPENCASCADE
|
#include "AbstractKernel.h"
|
||||||
#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
|
|
||||||
|
|
||||||
using namespace ifcopenshell::geometry;
|
using namespace ifcopenshell::geometry;
|
||||||
|
|
||||||
@@ -73,173 +59,6 @@ const Settings& ifcopenshell::geometry::kernels::AbstractKernel::settings() cons
|
|||||||
return settings_;
|
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) {
|
bool ifcopenshell::geometry::kernels::AbstractKernel::convert_impl(const taxonomy::collection::ptr collection, IfcGeom::ConversionResults& r) {
|
||||||
auto s = r.size();
|
auto s = r.size();
|
||||||
for (auto& c : collection->children) {
|
for (auto& c : collection->children) {
|
||||||
|
|||||||
@@ -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
|
#ifndef ABSTRACT_KERNEL_H
|
||||||
#define ABSTRACT_KERNEL_H
|
#define ABSTRACT_KERNEL_H
|
||||||
|
|
||||||
@@ -7,6 +26,7 @@
|
|||||||
#include "../ifcgeom/IfcGeomRepresentation.h"
|
#include "../ifcgeom/IfcGeomRepresentation.h"
|
||||||
#include "../ifcgeom/taxonomy.h"
|
#include "../ifcgeom/taxonomy.h"
|
||||||
#include "../ifcgeom/ConversionSettings.h"
|
#include "../ifcgeom/ConversionSettings.h"
|
||||||
|
#include "../ifcgeom/abstract_mapping.h"
|
||||||
|
|
||||||
static const double ALMOST_ZERO = 1.e-9;
|
static const double ALMOST_ZERO = 1.e-9;
|
||||||
|
|
||||||
@@ -55,6 +75,8 @@ namespace ifcopenshell {
|
|||||||
return geometry_library_;
|
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::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::point3::ptr, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||||
virtual bool convert_impl(const taxonomy::direction3::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,
|
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;
|
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 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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,3 +26,6 @@ std::string IfcGeom::NumberNativeDouble::to_string() const {
|
|||||||
ss << std::setprecision(std::numeric_limits<double>::digits10 + 1) << value_;
|
ss << std::setprecision(std::numeric_limits<double>::digits10 + 1) << value_;
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template struct IFC_GEOM_API IfcGeom::OpaqueCoordinate<3>;
|
||||||
|
template struct IFC_GEOM_API IfcGeom::OpaqueCoordinate<4>;
|
||||||
@@ -290,10 +290,13 @@ namespace IfcGeom {
|
|||||||
virtual ConversionResultShape* add(ConversionResultShape*) = 0;
|
virtual ConversionResultShape* add(ConversionResultShape*) = 0;
|
||||||
virtual ConversionResultShape* subtract(ConversionResultShape*) = 0;
|
virtual ConversionResultShape* subtract(ConversionResultShape*) = 0;
|
||||||
virtual ConversionResultShape* intersect(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(OpaqueCoordinate<4>& from, OpaqueCoordinate<4>& to) = 0;
|
||||||
virtual void map(const std::vector<OpaqueCoordinate<4>>& from, const std::vector<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 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() {}
|
virtual ~ConversionResultShape() {}
|
||||||
|
|
||||||
@@ -327,6 +330,15 @@ namespace IfcGeom {
|
|||||||
ifcopenshell::geometry::taxonomy::style::ptr StylePtr() const { return style_; }
|
ifcopenshell::geometry::taxonomy::style::ptr StylePtr() const { return style_; }
|
||||||
void setStyle(ifcopenshell::geometry::taxonomy::style::ptr newStyle) { style_ = newStyle; }
|
void setStyle(ifcopenshell::geometry::taxonomy::style::ptr newStyle) { style_ = newStyle; }
|
||||||
int ItemId() const { return id; }
|
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;
|
typedef std::vector<ConversionResult> ConversionResults;
|
||||||
|
|||||||
@@ -22,9 +22,9 @@
|
|||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
istream& operator>>(istream& in, set<int>& ints);
|
IFC_GEOM_API istream& operator>>(istream& in, set<int>& ints);
|
||||||
istream& operator>>(istream& in, set<string>& ints);
|
IFC_GEOM_API istream& operator>>(istream& in, set<string>& ints);
|
||||||
istream& operator>>(istream& in, vector<double>& vs);
|
IFC_GEOM_API istream& operator>>(istream& in, vector<double>& vs);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -249,7 +249,7 @@ namespace ifcopenshell {
|
|||||||
CURVES_SURFACES_AND_SOLIDS
|
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> {
|
struct OutputDimensionality : public SettingBase<OutputDimensionality, OutputDimensionalityTypes> {
|
||||||
static constexpr const char* const name = "dimensionality";
|
static constexpr const char* const name = "dimensionality";
|
||||||
@@ -266,7 +266,7 @@ namespace ifcopenshell {
|
|||||||
SERIALIZED
|
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> {
|
struct IteratorOutput : public SettingBase<IteratorOutput, IteratorOutputOptions> {
|
||||||
static constexpr const char* const name = "iterator-output";
|
static constexpr const char* const name = "iterator-output";
|
||||||
@@ -395,7 +395,7 @@ namespace ifcopenshell {
|
|||||||
MAXSTEPSIZE,
|
MAXSTEPSIZE,
|
||||||
MINSTEPS };
|
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> {
|
struct FunctionStepType : public SettingBase<FunctionStepType, FunctionStepMethod> {
|
||||||
static constexpr const char* const name = "function-step-type";
|
static constexpr const char* const name = "function-step-type";
|
||||||
@@ -425,7 +425,7 @@ namespace ifcopenshell {
|
|||||||
POLYHEDRON_WITH_HOLES
|
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> {
|
struct TriangulationType : public SettingBase<TriangulationType, TriangulationMethod> {
|
||||||
static constexpr const char* const name = "triangulation-type";
|
static constexpr const char* const name = "triangulation-type";
|
||||||
@@ -536,7 +536,7 @@ namespace ifcopenshell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename settings_t>
|
template <typename settings_t>
|
||||||
class IFC_GEOM_API SettingsContainer {
|
class SettingsContainer {
|
||||||
public:
|
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;
|
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:
|
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>
|
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
|
// @todo find a place
|
||||||
namespace IfcGeom {
|
namespace IfcGeom {
|
||||||
class IFC_GEOM_API geometry_exception : public std::exception {
|
class IFC_GEOM_API geometry_exception : public std::runtime_error {
|
||||||
protected:
|
protected:
|
||||||
std::string message;
|
std::string message;
|
||||||
public:
|
public:
|
||||||
geometry_exception(const std::string& m)
|
geometry_exception(const std::string& m)
|
||||||
: message(m) {}
|
: std::runtime_error(m)
|
||||||
virtual ~geometry_exception() throw () {}
|
{}
|
||||||
virtual const char* what() const throw() {
|
|
||||||
return message.c_str();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class IFC_GEOM_API too_many_faces_exception : public geometry_exception {
|
class IFC_GEOM_API too_many_faces_exception : public geometry_exception {
|
||||||
|
|||||||
+2
-104
@@ -4,20 +4,16 @@
|
|||||||
|
|
||||||
using namespace ifcopenshell::geometry;
|
using namespace ifcopenshell::geometry;
|
||||||
|
|
||||||
ifcopenshell::geometry::Converter::Converter(const std::string& geometry_library, IfcParse::IfcFile* file, ifcopenshell::geometry::Settings& s)
|
ifcopenshell::geometry::Converter::Converter(std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel>&& geometry_library, IfcParse::IfcFile* file, ifcopenshell::geometry::Settings& s)
|
||||||
: geometry_library_(boost::to_lower_copy(geometry_library))
|
: kernel_(std::move(geometry_library))
|
||||||
{
|
{
|
||||||
mapping_ = impl::mapping_implementations().construct(file, s);
|
mapping_ = impl::mapping_implementations().construct(file, s);
|
||||||
kernel_ = kernels::construct(file, geometry_library, mapping_->settings());
|
|
||||||
// Mapping reads unit information and applies to settings
|
// Mapping reads unit information and applies to settings
|
||||||
settings_ = mapping_->settings();
|
settings_ = mapping_->settings();
|
||||||
}
|
}
|
||||||
|
|
||||||
ifcopenshell::geometry::Converter::~Converter()
|
ifcopenshell::geometry::Converter::~Converter()
|
||||||
{
|
{
|
||||||
if (kernel_ != nullptr) {
|
|
||||||
delete kernel_;
|
|
||||||
}
|
|
||||||
if (mapping_ != nullptr) {
|
if (mapping_ != nullptr) {
|
||||||
delete mapping_;
|
delete mapping_;
|
||||||
}
|
}
|
||||||
@@ -414,101 +410,3 @@ IfcGeom::ConversionResults ifcopenshell::geometry::Converter::convert(IfcUtil::I
|
|||||||
}
|
}
|
||||||
return results;
|
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;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|||||||
@@ -13,20 +13,19 @@
|
|||||||
|
|
||||||
namespace ifcopenshell { namespace geometry {
|
namespace ifcopenshell { namespace geometry {
|
||||||
|
|
||||||
class Converter {
|
class IFC_GEOM_API Converter {
|
||||||
public:
|
public:
|
||||||
typedef boost::shared_ptr<IfcGeom::Representation::BRep> brep_ptr;
|
typedef boost::shared_ptr<IfcGeom::Representation::BRep> brep_ptr;
|
||||||
private:
|
private:
|
||||||
std::string geometry_library_;
|
|
||||||
ifcopenshell::geometry::abstract_mapping* mapping_;
|
ifcopenshell::geometry::abstract_mapping* mapping_;
|
||||||
ifcopenshell::geometry::kernels::AbstractKernel* kernel_;
|
std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel> kernel_;
|
||||||
ifcopenshell::geometry::Settings settings_;
|
ifcopenshell::geometry::Settings settings_;
|
||||||
std::map<ifcopenshell::geometry::taxonomy::ptr, brep_ptr, ifcopenshell::geometry::taxonomy::less_functor> cache_;
|
std::map<ifcopenshell::geometry::taxonomy::ptr, brep_ptr, ifcopenshell::geometry::taxonomy::less_functor> cache_;
|
||||||
|
|
||||||
public:
|
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();
|
~Converter();
|
||||||
|
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ namespace IfcGeom {
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
bool calculate_projected_surface_area(double& along_x, double& along_y, double& along_z) const {
|
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:
|
private:
|
||||||
BRepElement(const BRepElement& other);
|
BRepElement(const BRepElement& other);
|
||||||
|
|||||||
@@ -19,128 +19,6 @@
|
|||||||
|
|
||||||
#include "IfcGeomRepresentation.h"
|
#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)
|
IfcGeom::Representation::Serialization::Serialization(const BRep& brep)
|
||||||
: Representation(brep.settings(), brep.entity(), brep.id())
|
: Representation(brep.settings(), brep.entity(), brep.id())
|
||||||
{
|
{
|
||||||
@@ -169,191 +47,73 @@ IfcGeom::Representation::Serialization::Serialization(const BRep& brep)
|
|||||||
surface_style_ids_.push_back(sid);
|
surface_style_ids_.push_back(sid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (brep.begin() != brep.end()) {
|
ifcopenshell::geometry::taxonomy::matrix4 identity;
|
||||||
#ifdef IFOPSH_WITH_OPENCASCADE
|
auto* comp = brep.as_compound();
|
||||||
if (std::dynamic_pointer_cast<ifcopenshell::geometry::OpenCascadeShape>(brep.begin()->Shape())) {
|
comp->Serialize(identity, brep_data_);
|
||||||
ConversionResultShape* shape = brep.as_compound();
|
delete comp;
|
||||||
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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IfcGeom::ConversionResultShape* IfcGeom::Representation::BRep::as_compound(bool force_meters) const {
|
IfcGeom::ConversionResultShape* IfcGeom::Representation::BRep::as_compound(bool force_meters) const {
|
||||||
#ifdef IFOPSH_WITH_OPENCASCADE
|
ConversionResultShape* accum = nullptr;
|
||||||
TopoDS_Compound compound;
|
|
||||||
BRep_Builder builder;
|
|
||||||
builder.MakeCompound(compound);
|
|
||||||
|
|
||||||
for (auto it = begin(); it != end(); ++it) {
|
for (auto it = begin(); it != end(); ++it) {
|
||||||
const TopoDS_Shape& s = *std::static_pointer_cast<ifcopenshell::geometry::OpenCascadeShape>(it->Shape());
|
double unit_scale = 1.0;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!force_meters && settings().get<ifcopenshell::geometry::settings::ConvertBackUnits>().get()) {
|
if (!force_meters && settings().get<ifcopenshell::geometry::settings::ConvertBackUnits>().get()) {
|
||||||
gp_Trsf scale;
|
unit_scale = 1.0 / settings().get<ifcopenshell::geometry::settings::LengthUnit>().get();
|
||||||
scale.SetScaleFactor(1.0 / settings().get<ifcopenshell::geometry::settings::LengthUnit>().get());
|
}
|
||||||
trsf.PreMultiply(scale);
|
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));
|
return accum;
|
||||||
#else
|
|
||||||
throw std::runtime_error("Not available without Open Cascade");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool IfcGeom::Representation::BRep::calculate_surface_area(double& area) const {
|
bool IfcGeom::Representation::BRep::calculate_surface_area(double& area) const {
|
||||||
#ifdef IFOPSH_WITH_OPENCASCADE
|
std::unique_ptr<ConversionResultShape> s(as_compound());
|
||||||
try {
|
if (!s) {
|
||||||
area = 0.;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
#else
|
area = s->area()->to_double();
|
||||||
throw std::runtime_error("Not available without Open Cascade");
|
return true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IfcGeom::Representation::BRep::calculate_volume(double& volume) const {
|
bool IfcGeom::Representation::BRep::calculate_volume(double& volume) const {
|
||||||
#ifdef IFOPSH_WITH_OPENCASCADE
|
std::unique_ptr<ConversionResultShape> s(as_compound());
|
||||||
try {
|
if (!s) {
|
||||||
volume = 0.;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
#else
|
volume = s->area()->to_double();
|
||||||
throw std::runtime_error("Not available without Open Cascade");
|
return true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IfcGeom::Representation::BRep::calculate_projected_surface_area(const ifcopenshell::geometry::taxonomy::matrix4& place, double & along_x, double & along_y, double & along_z) const {
|
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 {
|
||||||
#ifdef IFOPSH_WITH_OPENCASCADE
|
along_x = along_y = along_z = 0.;
|
||||||
try {
|
|
||||||
gp_GTrsf trsf;
|
|
||||||
|
|
||||||
if (place.components_) {
|
for (IfcGeom::ConversionResults::const_iterator it = begin(); it != end(); ++it) {
|
||||||
gp_Trsf tr;
|
double x, y, z;
|
||||||
const auto& m = place.ccomponents();
|
it->Shape()->surface_area_along_direction(settings().get<ifcopenshell::geometry::settings::MesherLinearDeflection>().get(), place, x, y, z);
|
||||||
tr.SetValues(
|
|
||||||
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
|
if (it->Shape()->is_manifold()) {
|
||||||
m(1, 0), m(1, 1), m(1, 2), m(1, 3),
|
x /= 2.;
|
||||||
m(2, 0), m(2, 1), m(2, 2), m(2, 3)
|
y /= 2.;
|
||||||
);
|
z /= 2.;
|
||||||
trsf = tr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gp_Mat mat = trsf.Trsf().HVectorialPart();
|
along_x += x;
|
||||||
gp_Ax3 ax(trsf.TranslationPart(), mat.Column(3), mat.Column(1));
|
along_y += y;
|
||||||
|
along_z += z;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
throw std::runtime_error("Not available without Open Cascade");
|
return true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IfcGeom::Representation::Triangulation::Triangulation(const BRep& shape_model)
|
IfcGeom::Representation::Triangulation::Triangulation(const BRep& shape_model)
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ namespace IfcGeom {
|
|||||||
|
|
||||||
bool calculate_volume(double&) const;
|
bool calculate_volume(double&) const;
|
||||||
bool calculate_surface_area(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(); }
|
int size() const { return (int) shapes_.size(); }
|
||||||
const IfcGeom::ConversionResultShape* item(int i) const;
|
const IfcGeom::ConversionResultShape* item(int i) const;
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ void IfcGeom::Iterator::process_concurrently() {
|
|||||||
|
|
||||||
kernel_pool.reserve(conc_threads);
|
kernel_pool.reserve(conc_threads);
|
||||||
for (unsigned i = 0; i < conc_threads; ++i) {
|
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;
|
std::vector<std::future<geometry_conversion_result*>> threadpool;
|
||||||
|
|||||||
+13
-30
@@ -86,7 +86,7 @@
|
|||||||
|
|
||||||
namespace IfcGeom {
|
namespace IfcGeom {
|
||||||
|
|
||||||
struct geometry_conversion_result {
|
struct IFC_GEOM_API geometry_conversion_result {
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
// For NoParallelMapping==true
|
// For NoParallelMapping==true
|
||||||
@@ -102,7 +102,7 @@ namespace IfcGeom {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Iterator {
|
class IFC_GEOM_API Iterator {
|
||||||
private:
|
private:
|
||||||
GeometrySerializer* cache_ = nullptr;
|
GeometrySerializer* cache_ = nullptr;
|
||||||
|
|
||||||
@@ -212,50 +212,33 @@ namespace IfcGeom {
|
|||||||
|
|
||||||
ifcopenshell::geometry::taxonomy::direction3::ptr remove_offset_();
|
ifcopenshell::geometry::taxonomy::direction3::ptr remove_offset_();
|
||||||
public:
|
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)
|
: settings_(settings)
|
||||||
, ifc_file(file)
|
, ifc_file(file)
|
||||||
, filters_(filters)
|
, filters_(filters)
|
||||||
, num_threads_(num_threads)
|
, num_threads_(num_threads)
|
||||||
, geometry_library_(geometry_library)
|
, geometry_library_(geometry_library->geometry_library())
|
||||||
, converter_(new ifcopenshell::geometry::Converter(geometry_library_, ifc_file, settings_))
|
// @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)
|
Iterator(std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel>&& geometry_library, const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file)
|
||||||
: 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)
|
|
||||||
: settings_(settings)
|
: settings_(settings)
|
||||||
, ifc_file(file)
|
, ifc_file(file)
|
||||||
, num_threads_(1)
|
, num_threads_(1)
|
||||||
, geometry_library_("opencascade")
|
, geometry_library_(geometry_library->geometry_library())
|
||||||
, converter_(new ifcopenshell::geometry::Converter(geometry_library_, ifc_file, settings_))
|
, 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)
|
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_(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)
|
|
||||||
: settings_(settings)
|
: settings_(settings)
|
||||||
, ifc_file(file)
|
, ifc_file(file)
|
||||||
, num_threads_(num_threads)
|
, num_threads_(num_threads)
|
||||||
, geometry_library_(geometry_library)
|
, geometry_library_(geometry_library->geometry_library())
|
||||||
, converter_(new ifcopenshell::geometry::Converter(geometry_library_, ifc_file, settings_))
|
, converter_(new ifcopenshell::geometry::Converter(std::move(geometry_library), ifc_file, settings_))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
#include "../../ifcparse/IfcBaseClass.h"
|
#include "../../ifcparse/IfcBaseClass.h"
|
||||||
|
|
||||||
#include "../../ifcgeom/ifc_geom_api.h"
|
#include "ifc_geomserialization_api.h"
|
||||||
|
|
||||||
#include <TopoDS_Shape.hxx>
|
#include <TopoDS_Shape.hxx>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace IfcGeom {
|
namespace IfcGeom {
|
||||||
IFC_GEOM_API IfcUtil::IfcBaseClass* tesselate(const std::string& schema_name, const TopoDS_Shape& shape, double deflection);
|
IFC_GEOMSERIALIZATION_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* 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
|
||||||
@@ -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
|
#ifndef ABSTRACT_MAPPING_H
|
||||||
#define ABSTRACT_MAPPING_H
|
#define ABSTRACT_MAPPING_H
|
||||||
|
|
||||||
@@ -16,7 +35,7 @@ namespace ifcopenshell {
|
|||||||
|
|
||||||
namespace geometry {
|
namespace geometry {
|
||||||
|
|
||||||
struct geometry_conversion_task {
|
struct IFC_GEOM_API geometry_conversion_task {
|
||||||
int index;
|
int index;
|
||||||
IfcUtil::IfcBaseEntity* representation;
|
IfcUtil::IfcBaseEntity* representation;
|
||||||
aggregate_of_instance::ptr products;
|
aggregate_of_instance::ptr products;
|
||||||
@@ -24,7 +43,7 @@ namespace geometry {
|
|||||||
|
|
||||||
typedef boost::function<bool(IfcUtil::IfcBaseEntity*)> filter_t;
|
typedef boost::function<bool(IfcUtil::IfcBaseEntity*)> filter_t;
|
||||||
|
|
||||||
class abstract_mapping {
|
class IFC_GEOM_API abstract_mapping {
|
||||||
protected:
|
protected:
|
||||||
Settings settings_;
|
Settings settings_;
|
||||||
|
|
||||||
@@ -58,14 +77,14 @@ namespace geometry {
|
|||||||
namespace impl {
|
namespace impl {
|
||||||
typedef boost::function2<abstract_mapping*, IfcParse::IfcFile*, Settings&> mapping_fn;
|
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:
|
public:
|
||||||
MappingFactoryImplementation();
|
MappingFactoryImplementation();
|
||||||
void bind(const std::string& schema_name, mapping_fn);
|
void bind(const std::string& schema_name, mapping_fn);
|
||||||
abstract_mapping* construct(IfcParse::IfcFile*, Settings&);
|
abstract_mapping* construct(IfcParse::IfcFile*, Settings&);
|
||||||
};
|
};
|
||||||
|
|
||||||
MappingFactoryImplementation& mapping_implementations();
|
IFC_GEOM_API MappingFactoryImplementation& mapping_implementations();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ namespace ifcopenshell { namespace geometry {
|
|||||||
|
|
||||||
/// @brief Computes a point on a helmert curve at s.
|
/// @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
|
/// 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.
|
/// @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
|
/// 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.
|
/// @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 ifcopenshell::geometry::Settings& settings) : settings_(settings) {
|
||||||
}
|
}
|
||||||
fn_evaluator(const fn_evaluator& other) = default;
|
fn_evaluator(const fn_evaluator& other) = default;
|
||||||
@@ -39,7 +39,7 @@ struct fn_evaluator {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// @brief utility class to evaluate function_item objects.
|
/// @brief utility class to evaluate function_item objects.
|
||||||
class function_item_evaluator {
|
class IFC_GEOM_API function_item_evaluator {
|
||||||
public:
|
public:
|
||||||
function_item_evaluator(const ifcopenshell::geometry::Settings& settings, taxonomy::function_item::const_ptr fn);
|
function_item_evaluator(const ifcopenshell::geometry::Settings& settings, taxonomy::function_item::const_ptr fn);
|
||||||
function_item_evaluator(const function_item_evaluator& other);
|
function_item_evaluator(const function_item_evaluator& other);
|
||||||
|
|||||||
@@ -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,11 +4,13 @@
|
|||||||
#include "taxonomy.h"
|
#include "taxonomy.h"
|
||||||
#include "ConversionSettings.h"
|
#include "ConversionSettings.h"
|
||||||
|
|
||||||
|
#include "ifc_geom_api.h"
|
||||||
|
|
||||||
namespace ifcopenshell {
|
namespace ifcopenshell {
|
||||||
|
|
||||||
namespace geometry {
|
namespace geometry {
|
||||||
|
|
||||||
struct cross_section {
|
struct IFC_GEOM_API cross_section {
|
||||||
double dist_along;
|
double dist_along;
|
||||||
taxonomy::geom_item::ptr section_geometry;
|
taxonomy::geom_item::ptr section_geometry;
|
||||||
Eigen::Vector3d offset;
|
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/repair.h>
|
||||||
#include <CGAL/Polygon_mesh_processing/self_intersections.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 "../../../ifcparse/IfcLogger.h"
|
||||||
#include "../../../ifcgeom/IfcGeomRepresentation.h"
|
#include "../../../ifcgeom/IfcGeomRepresentation.h"
|
||||||
@@ -19,6 +21,10 @@ using ifcopenshell::geometry::NumberEpeck;
|
|||||||
#define NumberType NumberEpeck
|
#define NumberType NumberEpeck
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef IFOPSH_SIMPLE_KERNEL
|
||||||
|
#define CgalShape SimpleCgalShape
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef CGAL::Polyhedron_3<Kernel_> Polyhedron;
|
typedef CGAL::Polyhedron_3<Kernel_> Polyhedron;
|
||||||
typedef Polyhedron::Facet_const_handle Facet_const_handle;
|
typedef Polyhedron::Facet_const_handle Facet_const_handle;
|
||||||
typedef Polyhedron::Halfedge_around_facet_const_circulator Halfedge_around_facet_circulator;
|
typedef Polyhedron::Halfedge_around_facet_const_circulator Halfedge_around_facet_circulator;
|
||||||
@@ -701,6 +707,43 @@ ConversionResultShape* ifcopenshell::geometry::CgalShape::intersect(ConversionRe
|
|||||||
#endif
|
#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
|
std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> ifcopenshell::geometry::CgalShape::bounding_box() const
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Not implemented");
|
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");
|
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
|
#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 {
|
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
|
#ifndef CGALCONVERSIONRESULT_H
|
||||||
#define CGALCONVERSIONRESULT_H
|
#define CGALCONVERSIONRESULT_H
|
||||||
|
|
||||||
|
#include "../../../ifcgeom/kernels/ifc_geomlibrary_api.h"
|
||||||
|
|
||||||
#include "../../../ifcgeom/IfcGeomElement.h"
|
#include "../../../ifcgeom/IfcGeomElement.h"
|
||||||
|
|
||||||
#undef Handle
|
#undef Handle
|
||||||
@@ -100,7 +102,7 @@ namespace ifcopenshell { namespace geometry {
|
|||||||
using IfcGeom::negate_;
|
using IfcGeom::negate_;
|
||||||
|
|
||||||
#ifndef IFOPSH_SIMPLE_KERNEL
|
#ifndef IFOPSH_SIMPLE_KERNEL
|
||||||
class IFC_GEOM_API NumberEpeck : public OpaqueNumber {
|
class IFC_GEOMLIBRARY_API NumberEpeck : public OpaqueNumber {
|
||||||
private:
|
private:
|
||||||
CGAL::Epeck::FT value_;
|
CGAL::Epeck::FT value_;
|
||||||
|
|
||||||
@@ -175,7 +177,7 @@ namespace ifcopenshell { namespace geometry {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class CgalShape : public IfcGeom::ConversionResultShape {
|
class IFC_GEOMLIBRARY_API CgalShape : public IfcGeom::ConversionResultShape {
|
||||||
private:
|
private:
|
||||||
bool convex_tag_ = false;
|
bool convex_tag_ = false;
|
||||||
mutable boost::optional<cgal_shape_t> shape_;
|
mutable boost::optional<cgal_shape_t> shape_;
|
||||||
@@ -250,17 +252,20 @@ namespace ifcopenshell { namespace geometry {
|
|||||||
virtual ConversionResultShape* add(ConversionResultShape*);
|
virtual ConversionResultShape* add(ConversionResultShape*);
|
||||||
virtual ConversionResultShape* subtract(ConversionResultShape*);
|
virtual ConversionResultShape* subtract(ConversionResultShape*);
|
||||||
virtual ConversionResultShape* intersect(ConversionResultShape*);
|
virtual ConversionResultShape* intersect(ConversionResultShape*);
|
||||||
|
virtual ConversionResultShape* concat(ConversionResultShape*);
|
||||||
|
|
||||||
virtual void map(OpaqueCoordinate<4>& from, OpaqueCoordinate<4>& to);
|
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 void map(const std::vector<OpaqueCoordinate<4>>& from, const std::vector<OpaqueCoordinate<4>>& to);
|
||||||
virtual ConversionResultShape* moved(ifcopenshell::geometry::taxonomy::matrix4::ptr) const;
|
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() const { return convex_tag_; }
|
||||||
bool& convex_tag() { return convex_tag_; }
|
bool& convex_tag() { return convex_tag_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef IFOPSH_SIMPLE_KERNEL
|
#ifndef IFOPSH_SIMPLE_KERNEL
|
||||||
class CgalShapeHalfSpaceDecomposition : public IfcGeom::ConversionResultShape {
|
class IFC_GEOMLIBRARY_API CgalShapeHalfSpaceDecomposition : public IfcGeom::ConversionResultShape {
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<halfspace_tree<Kernel_>> shape_;
|
std::unique_ptr<halfspace_tree<Kernel_>> shape_;
|
||||||
std::list<CGAL::Plane_3<Kernel_>> planes_;
|
std::list<CGAL::Plane_3<Kernel_>> planes_;
|
||||||
@@ -315,12 +320,23 @@ namespace ifcopenshell { namespace geometry {
|
|||||||
virtual ConversionResultShape* add(ConversionResultShape*);
|
virtual ConversionResultShape* add(ConversionResultShape*);
|
||||||
virtual ConversionResultShape* subtract(ConversionResultShape*);
|
virtual ConversionResultShape* subtract(ConversionResultShape*);
|
||||||
virtual ConversionResultShape* intersect(ConversionResultShape*);
|
virtual ConversionResultShape* intersect(ConversionResultShape*);
|
||||||
|
virtual ConversionResultShape* concat(ConversionResultShape*) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void map(OpaqueCoordinate<4>& from, OpaqueCoordinate<4>& to);
|
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 void map(const std::vector<OpaqueCoordinate<4>>& from, const std::vector<OpaqueCoordinate<4>>& to);
|
||||||
virtual ConversionResultShape* moved(ifcopenshell::geometry::taxonomy::matrix4::ptr) const;
|
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
|
#endif
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
#ifdef IFOPSH_SIMPLE_KERNEL
|
||||||
|
#undef CgalShape
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -24,6 +24,10 @@
|
|||||||
#include "../../../ifcparse/IfcLogger.h"
|
#include "../../../ifcparse/IfcLogger.h"
|
||||||
#include "../../../ifcgeom/kernels/cgal/CgalConversionResult.h"
|
#include "../../../ifcgeom/kernels/cgal/CgalConversionResult.h"
|
||||||
|
|
||||||
|
#ifdef IFOPSH_SIMPLE_KERNEL
|
||||||
|
#define CgalShape SimpleCgalShape
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <CGAL/minkowski_sum_3.h>
|
#include <CGAL/minkowski_sum_3.h>
|
||||||
#include <CGAL/exceptions.h>
|
#include <CGAL/exceptions.h>
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ if ( it != cache.T.end() ) { e = it->second; return true; }
|
|||||||
|
|
||||||
#include "../../../ifcgeom/IfcGeomElement.h"
|
#include "../../../ifcgeom/IfcGeomElement.h"
|
||||||
#include "../../../ifcgeom/kernels/cgal/CgalConversionResult.h"
|
#include "../../../ifcgeom/kernels/cgal/CgalConversionResult.h"
|
||||||
|
#include "../../../ifcgeom/kernels/ifc_geomlibrary_api.h"
|
||||||
|
|
||||||
#include <CGAL/Polygon_2.h>
|
#include <CGAL/Polygon_2.h>
|
||||||
|
|
||||||
@@ -55,20 +56,20 @@ if ( it != cache.T.end() ) { e = it->second; return true; }
|
|||||||
namespace ifcopenshell {
|
namespace ifcopenshell {
|
||||||
namespace geometry {
|
namespace geometry {
|
||||||
namespace utils {
|
namespace utils {
|
||||||
IFC_GEOM_API CGAL::Polyhedron_3<Kernel_> create_cube(double d);
|
IFC_GEOMLIBRARY_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_GEOMLIBRARY_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_polyhedron(std::list<cgal_face_t> &face_list, bool stitch_borders = false);
|
||||||
|
|
||||||
#ifndef IFOPSH_SIMPLE_KERNEL
|
#ifndef IFOPSH_SIMPLE_KERNEL
|
||||||
IFC_GEOM_API CGAL::Polyhedron_3<Kernel_> create_polyhedron(const CGAL::Nef_polyhedron_3<Kernel_> &nef_polyhedron);
|
IFC_GEOMLIBRARY_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_GEOMLIBRARY_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::Nef_polyhedron_3<Kernel_> create_nef_polyhedron(CGAL::Polyhedron_3<Kernel_> &polyhedron);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace kernels {
|
namespace kernels {
|
||||||
|
|
||||||
class IFC_GEOM_API CgalKernel : public AbstractKernel {
|
class IFC_GEOMLIBRARY_API CgalKernel : public AbstractKernel {
|
||||||
private:
|
private:
|
||||||
#ifndef IFOPSH_SIMPLE_KERNEL
|
#ifndef IFOPSH_SIMPLE_KERNEL
|
||||||
enum boolean_operand_preprocess {
|
enum boolean_operand_preprocess {
|
||||||
@@ -94,6 +95,18 @@ namespace ifcopenshell {
|
|||||||
: AbstractKernel("cgal", settings)
|
: 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::extrusion::ptr, cgal_shape_t&);
|
||||||
bool convert(const taxonomy::face::ptr, std::list<cgal_face_t>&);
|
bool convert(const taxonomy::face::ptr, std::list<cgal_face_t>&);
|
||||||
bool convert(const taxonomy::loop::ptr, cgal_wire_t&);
|
bool convert(const taxonomy::loop::ptr, cgal_wire_t&);
|
||||||
|
|||||||
@@ -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/IfcGeomElement.h"
|
||||||
#include "../../../ifcgeom/Iterator.h"
|
#include "../../../ifcgeom/Iterator.h"
|
||||||
#include "OpenCascadeConversionResult.h"
|
#include "OpenCascadeConversionResult.h"
|
||||||
|
#include "OpenCascadeKernel.h"
|
||||||
#include "base_utils.h"
|
#include "base_utils.h"
|
||||||
|
|
||||||
#include <NCollection_UBTree.hxx>
|
#include <NCollection_UBTree.hxx>
|
||||||
@@ -1503,7 +1504,7 @@ namespace IfcGeom {
|
|||||||
settings_.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = true;
|
settings_.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = true;
|
||||||
settings_.get<ifcopenshell::geometry::settings::ReorientShells>().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);
|
add_file(it);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
#include <Geom_SphericalSurface.hxx>
|
#include <Geom_SphericalSurface.hxx>
|
||||||
#include <Geom_Plane.hxx>
|
#include <Geom_Plane.hxx>
|
||||||
#include <BRepTools_WireExplorer.hxx>
|
#include <BRepTools_WireExplorer.hxx>
|
||||||
|
#include <TopoDS_Compound.hxx>
|
||||||
|
#include <BRep_Builder.hxx>
|
||||||
|
|
||||||
#include "OpenCascadeConversionResult.h"
|
#include "OpenCascadeConversionResult.h"
|
||||||
|
|
||||||
@@ -546,6 +548,26 @@ ConversionResultShape* ifcopenshell::geometry::OpenCascadeShape::intersect(Conve
|
|||||||
return boolean_op(BOPAlgo_COMMON, shape_, ((ifcopenshell::geometry::OpenCascadeShape*)other)->shape_);
|
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
|
std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> ifcopenshell::geometry::OpenCascadeShape::bounding_box() const
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Not implemented");
|
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));
|
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>&) {
|
void ifcopenshell::geometry::OpenCascadeShape::map(OpaqueCoordinate<4>&, OpaqueCoordinate<4>&) {
|
||||||
throw std::runtime_error("Not implemented");
|
throw std::runtime_error("Not implemented");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include <GCPnts_QuasiUniformDeflection.hxx>
|
#include <GCPnts_QuasiUniformDeflection.hxx>
|
||||||
|
|
||||||
#include "../../../ifcgeom/ConversionResult.h"
|
#include "../../../ifcgeom/ConversionResult.h"
|
||||||
|
#include "../../../ifcgeom/kernels/ifc_geomlibrary_api.h"
|
||||||
|
|
||||||
namespace ifcopenshell {
|
namespace ifcopenshell {
|
||||||
namespace geometry {
|
namespace geometry {
|
||||||
@@ -42,7 +43,7 @@ namespace ifcopenshell {
|
|||||||
using IfcGeom::OpaqueCoordinate;
|
using IfcGeom::OpaqueCoordinate;
|
||||||
using IfcGeom::OpaqueNumber;
|
using IfcGeom::OpaqueNumber;
|
||||||
|
|
||||||
class OpenCascadeShape : public IfcGeom::ConversionResultShape {
|
class IFC_GEOMLIBRARY_API OpenCascadeShape : public IfcGeom::ConversionResultShape {
|
||||||
public:
|
public:
|
||||||
OpenCascadeShape(const TopoDS_Shape& shape)
|
OpenCascadeShape(const TopoDS_Shape& shape)
|
||||||
: shape_(shape) {}
|
: shape_(shape) {}
|
||||||
@@ -97,10 +98,13 @@ namespace ifcopenshell {
|
|||||||
virtual ConversionResultShape* add(ConversionResultShape*);
|
virtual ConversionResultShape* add(ConversionResultShape*);
|
||||||
virtual ConversionResultShape* subtract(ConversionResultShape*);
|
virtual ConversionResultShape* subtract(ConversionResultShape*);
|
||||||
virtual ConversionResultShape* intersect(ConversionResultShape*);
|
virtual ConversionResultShape* intersect(ConversionResultShape*);
|
||||||
|
virtual ConversionResultShape* concat(ConversionResultShape*);
|
||||||
|
|
||||||
virtual void map(OpaqueCoordinate<4>& from, OpaqueCoordinate<4>& to);
|
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 void map(const std::vector<OpaqueCoordinate<4>>& from, const std::vector<OpaqueCoordinate<4>>& to);
|
||||||
virtual ConversionResultShape* moved(ifcopenshell::geometry::taxonomy::matrix4::ptr) const;
|
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:
|
private:
|
||||||
TopoDS_Shape shape_;
|
TopoDS_Shape shape_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -51,14 +51,14 @@
|
|||||||
|
|
||||||
#include "../../../ifcgeom/kernels/opencascade/OpenCascadeConversionResult.h"
|
#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/taxonomy.h"
|
||||||
#include "../../../ifcgeom/ConversionSettings.h"
|
#include "../../../ifcgeom/ConversionSettings.h"
|
||||||
|
|
||||||
namespace IfcGeom {
|
namespace IfcGeom {
|
||||||
|
|
||||||
class IFC_GEOM_API OpenCascadeKernel : public ifcopenshell::geometry::kernels::AbstractKernel {
|
class IFC_GEOMLIBRARY_API OpenCascadeKernel : public ifcopenshell::geometry::kernels::AbstractKernel {
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -103,6 +103,12 @@ public:
|
|||||||
, precision_(settings.get<ifcopenshell::geometry::settings::Precision>().get())
|
, 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::extrusion::ptr, TopoDS_Shape&);
|
||||||
bool convert(const ifcopenshell::geometry::taxonomy::face::ptr, TopoDS_Shape&, bool reversed_surface = false);
|
bool convert(const ifcopenshell::geometry::taxonomy::face::ptr, TopoDS_Shape&, bool reversed_surface = false);
|
||||||
bool convert(const ifcopenshell::geometry::taxonomy::loop::ptr, TopoDS_Wire&);
|
bool convert(const ifcopenshell::geometry::taxonomy::loop::ptr, TopoDS_Wire&);
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
#include "OpenCascadeConversionResult.h"
|
#include "OpenCascadeConversionResult.h"
|
||||||
#include "boolean_utils.h"
|
#include "boolean_utils.h"
|
||||||
|
|
||||||
|
#include <Standard_Version.hxx>
|
||||||
|
|
||||||
#include <TopExp.hxx>
|
#include <TopExp.hxx>
|
||||||
#include <TopExp_Explorer.hxx>
|
#include <TopExp_Explorer.hxx>
|
||||||
#include <TopoDS.hxx>
|
#include <TopoDS.hxx>
|
||||||
@@ -48,6 +50,8 @@
|
|||||||
|
|
||||||
#include <TopTools_IndexedMapOfShape.hxx>
|
#include <TopTools_IndexedMapOfShape.hxx>
|
||||||
|
|
||||||
|
#include <ShapeUpgrade_UnifySameDomain.hxx>
|
||||||
|
|
||||||
// For axis placements detect equality early in order for the
|
// For axis placements detect equality early in order for the
|
||||||
// relatively computionaly expensive gp_Trsf calculation to be skipped
|
// relatively computionaly expensive gp_Trsf calculation to be skipped
|
||||||
bool IfcGeom::util::axis_equal(const gp_Ax3 & a, const gp_Ax3 & b, double tolerance) {
|
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) {
|
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;
|
gp_GTrsf trsf;
|
||||||
if (t.components_) {
|
if (t.components_) {
|
||||||
gp_Trsf tr;
|
|
||||||
const auto& m = t.ccomponents();
|
const auto& m = t.ccomponents();
|
||||||
tr.SetValues(
|
// This is either a bug or very finicky, but this appears to be the only
|
||||||
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
|
// way to get the transformation metadata to line up.
|
||||||
m(1, 0), m(1, 1), m(1, 2), m(1, 3),
|
//
|
||||||
m(2, 0), m(2, 1), m(2, 2), m(2, 3)
|
// - If gp_GTrsf.form is other, applying the transformation will result in
|
||||||
);
|
// a conversion to b-spline surfaces for about everything, which impacts
|
||||||
trsf = tr;
|
// 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);
|
return apply_transformation(s, trsf);
|
||||||
}
|
}
|
||||||
@@ -864,3 +902,17 @@ bool IfcGeom::util::validate_shape(const TopoDS_Shape& s) {
|
|||||||
|
|
||||||
return false;
|
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();
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define BASE_UTILS_H
|
#define BASE_UTILS_H
|
||||||
|
|
||||||
#include "../../../ifcgeom/ConversionResult.h"
|
#include "../../../ifcgeom/ConversionResult.h"
|
||||||
|
#include "../ifc_geomlibrary_api.h"
|
||||||
|
|
||||||
#include <gp_Pln.hxx>
|
#include <gp_Pln.hxx>
|
||||||
#include <gp_Pnt.hxx>
|
#include <gp_Pnt.hxx>
|
||||||
@@ -25,58 +26,60 @@
|
|||||||
namespace IfcGeom {
|
namespace IfcGeom {
|
||||||
namespace util {
|
namespace util {
|
||||||
|
|
||||||
int count(const TopoDS_Shape&, TopAbs_ShapeEnum, bool unique = false);
|
IFC_GEOMLIBRARY_API int count(const TopoDS_Shape&, TopAbs_ShapeEnum, bool unique = false);
|
||||||
int surface_genus(const TopoDS_Shape&);
|
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
|
// For axis placements detect equality early in order for the
|
||||||
// relatively computionaly expensive gp_Trsf calculation to be skipped
|
// 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);
|
IFC_GEOMLIBRARY_API bool is_identity(const gp_Trsf2d& t, double tolerance);
|
||||||
bool is_identity(const gp_GTrsf2d& t, double tolerance);
|
IFC_GEOMLIBRARY_API bool is_identity(const gp_GTrsf2d& t, double tolerance);
|
||||||
bool is_identity(const gp_Trsf& t, double tolerance);
|
IFC_GEOMLIBRARY_API 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_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,
|
// Creates a solid from a compound of faces. When there are multiple connected components,
|
||||||
// a compound of solids is returned.
|
// a compound of solids is returned.
|
||||||
bool create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& solid, double tol);
|
IFC_GEOMLIBRARY_API 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);
|
IFC_GEOMLIBRARY_API 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);
|
IFC_GEOMLIBRARY_API 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);
|
IFC_GEOMLIBRARY_API bool is_compound(const TopoDS_Shape& shape);
|
||||||
bool is_convex(const TopoDS_Wire& wire, double tol);
|
IFC_GEOMLIBRARY_API bool is_convex(const TopoDS_Wire& wire, double tol);
|
||||||
TopoDS_Shape halfspace_from_plane(const gp_Pln& pln, const gp_Pnt& cent);
|
IFC_GEOMLIBRARY_API TopoDS_Shape halfspace_from_plane(const gp_Pln& pln, const gp_Pnt& cent);
|
||||||
gp_Pln plane_from_face(const TopoDS_Face& face);
|
IFC_GEOMLIBRARY_API gp_Pln plane_from_face(const TopoDS_Face& face);
|
||||||
gp_Pnt point_above_plane(const gp_Pln& pln, bool agree = true);
|
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);
|
IFC_GEOMLIBRARY_API 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&);
|
IFC_GEOMLIBRARY_API 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&);
|
IFC_GEOMLIBRARY_API const Handle_Geom_Curve intersect(const Handle_Geom_Surface&, const TopoDS_Face&);
|
||||||
const Handle_Geom_Curve intersect(const TopoDS_Face&, const Handle_Geom_Surface&);
|
IFC_GEOMLIBRARY_API const Handle_Geom_Curve intersect(const TopoDS_Face&, const Handle_Geom_Surface&);
|
||||||
bool intersect(const Handle_Geom_Curve&, const Handle_Geom_Surface&, gp_Pnt&);
|
IFC_GEOMLIBRARY_API bool intersect(const Handle_Geom_Curve&, const Handle_Geom_Surface&, gp_Pnt&);
|
||||||
bool intersect(const Handle_Geom_Curve&, const TopoDS_Face&, gp_Pnt&);
|
IFC_GEOMLIBRARY_API bool intersect(const Handle_Geom_Curve&, const TopoDS_Face&, gp_Pnt&);
|
||||||
bool intersect(const Handle_Geom_Curve&, const TopoDS_Shape&, std::vector<gp_Pnt>&);
|
IFC_GEOMLIBRARY_API 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> >&);
|
IFC_GEOMLIBRARY_API 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&);
|
IFC_GEOMLIBRARY_API 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);
|
IFC_GEOMLIBRARY_API 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 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);
|
IFC_GEOMLIBRARY_API double shape_volume(const TopoDS_Shape& s);
|
||||||
double face_area(const TopoDS_Face& f);
|
IFC_GEOMLIBRARY_API double face_area(const TopoDS_Face& f);
|
||||||
|
|
||||||
TopoDS_Shape apply_transformation(const TopoDS_Shape&, const ifcopenshell::geometry::taxonomy::matrix4& t);
|
IFC_GEOMLIBRARY_API TopoDS_Shape apply_transformation(const TopoDS_Shape&, const ifcopenshell::geometry::taxonomy::matrix4& t);
|
||||||
TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_Trsf&);
|
IFC_GEOMLIBRARY_API 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 gp_GTrsf&);
|
||||||
|
|
||||||
bool flatten_shape_list(const IfcGeom::ConversionResults& shapes, TopoDS_Shape& result, bool fuse, bool create_shell, double tol);
|
IFC_GEOMLIBRARY_API 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 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 <Extrema_ExtPC.hxx>
|
||||||
#include <Geom_Plane.hxx>
|
#include <Geom_Plane.hxx>
|
||||||
#include <Geom_BSplineCurve.hxx>
|
#include <Geom_BSplineCurve.hxx>
|
||||||
#include <ShapeUpgrade_UnifySameDomain.hxx>
|
|
||||||
#include <GeomAPI_ExtremaCurveCurve.hxx>
|
#include <GeomAPI_ExtremaCurveCurve.hxx>
|
||||||
#include <ShapeAnalysis_Surface.hxx>
|
#include <ShapeAnalysis_Surface.hxx>
|
||||||
#include <BRepBuilderAPI_MakeFace.hxx>
|
#include <BRepBuilderAPI_MakeFace.hxx>
|
||||||
@@ -575,20 +574,6 @@ int IfcGeom::util::eliminate_touching_operands(double prec, const TopoDS_Shape &
|
|||||||
return N;
|
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) {
|
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;
|
IfcGeom::impl::tree<int> edge_tree;
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
#include <TopTools_IndexedMapOfShape.hxx>
|
#include <TopTools_IndexedMapOfShape.hxx>
|
||||||
#include <BOPAlgo_Operation.hxx>
|
#include <BOPAlgo_Operation.hxx>
|
||||||
|
|
||||||
|
#include "../ifc_geomlibrary_api.h"
|
||||||
|
|
||||||
namespace IfcGeom {
|
namespace IfcGeom {
|
||||||
namespace util {
|
namespace util {
|
||||||
|
|
||||||
@@ -83,8 +85,6 @@ namespace IfcGeom {
|
|||||||
|
|
||||||
int eliminate_narrow_operands(double prec, const TopTools_ListOfShape& bs, TopTools_ListOfShape & c);
|
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);
|
bool boolean_subtraction_2d_using_builder(const TopoDS_Shape& a_input, const TopTools_ListOfShape& b_input, TopoDS_Shape& result, double eps);
|
||||||
|
|
||||||
struct boolean_settings {
|
struct boolean_settings {
|
||||||
|
|||||||
@@ -3,27 +3,29 @@
|
|||||||
#include <gp_Vec.hxx>
|
#include <gp_Vec.hxx>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
struct ray {
|
#include "../ifc_geomlibrary_api.h"
|
||||||
|
|
||||||
|
struct IFC_GEOMLIBRARY_API ray {
|
||||||
float origin[3];
|
float origin[3];
|
||||||
float dir[3];
|
float dir[3];
|
||||||
float dir_inv[3];
|
float dir_inv[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct box {
|
struct IFC_GEOMLIBRARY_API box {
|
||||||
float corners[2][3];
|
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,
|
const gp_Vec& vert0, const gp_Vec& vert1, const gp_Vec& vert2,
|
||||||
Standard_Real& at, Standard_Real& au, Standard_Real& av,
|
Standard_Real& at, Standard_Real& au, Standard_Real& av,
|
||||||
bool cull, float enlarge=0.0f);
|
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& p, const gp_Vec& a, // seg 1 origin, vector
|
||||||
const gp_Vec& q, const gp_Vec& b); // seg 2 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);
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#ifndef WIRE_UTILS_H
|
#ifndef WIRE_UTILS_H
|
||||||
#define WIRE_UTILS_H
|
#define WIRE_UTILS_H
|
||||||
|
|
||||||
|
#include "../ifc_geomlibrary_api.h"
|
||||||
|
|
||||||
#include <gp_Pln.hxx>
|
#include <gp_Pln.hxx>
|
||||||
|
|
||||||
#include <Geom_Curve.hxx>
|
#include <Geom_Curve.hxx>
|
||||||
@@ -17,9 +19,9 @@
|
|||||||
|
|
||||||
namespace IfcGeom {
|
namespace IfcGeom {
|
||||||
namespace util {
|
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 {
|
enum triangulate_wire_result {
|
||||||
TRIANGULATE_WIRE_FAIL,
|
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 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);
|
IFC_GEOMLIBRARY_API 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);
|
IFC_GEOMLIBRARY_API 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);
|
IFC_GEOMLIBRARY_API void remove_collinear_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol);
|
||||||
bool wire_to_sequence_of_point(const TopoDS_Wire&, TColgp_SequenceOfPnt&);
|
IFC_GEOMLIBRARY_API 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 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
@@ -87,7 +87,7 @@ typedef item* ptr; \
|
|||||||
typedef item const* ptr;
|
typedef item const* ptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class topology_error : public std::runtime_error {
|
class IFC_GEOM_API topology_error : public std::runtime_error {
|
||||||
public:
|
public:
|
||||||
topology_error() : std::runtime_error("Generic topology error") {}
|
topology_error() : std::runtime_error("Generic topology error") {}
|
||||||
topology_error(const char* const s) : std::runtime_error(s) {}
|
topology_error(const char* const s) : std::runtime_error(s) {}
|
||||||
@@ -138,9 +138,9 @@ typedef item const* ptr;
|
|||||||
STYLE
|
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:
|
private:
|
||||||
uint32_t identity_;
|
uint32_t identity_;
|
||||||
static std::atomic_uint32_t counter_;
|
static std::atomic_uint32_t counter_;
|
||||||
@@ -195,7 +195,7 @@ typedef item const* ptr;
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct eigen_base {
|
struct IFC_GEOM_API eigen_base {
|
||||||
T* components_;
|
T* components_;
|
||||||
|
|
||||||
eigen_base() {
|
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:
|
private:
|
||||||
void init(const Eigen::Vector3d& o, const Eigen::Vector3d& z, const Eigen::Vector3d& x) {
|
void init(const Eigen::Vector3d& o, const Eigen::Vector3d& z, const Eigen::Vector3d& x) {
|
||||||
auto Z = z.normalized();
|
auto Z = z.normalized();
|
||||||
@@ -319,10 +319,18 @@ typedef item const* ptr;
|
|||||||
return boost::hash<decltype(v)>{}(v);
|
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>(); }
|
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)
|
DECLARE_PTR(colour)
|
||||||
|
|
||||||
void print(std::ostream& o, int indent = 0) const;
|
void print(std::ostream& o, int indent = 0) const;
|
||||||
@@ -343,7 +351,7 @@ typedef item const* ptr;
|
|||||||
const double& b() const { return ccomponents()[2]; }
|
const double& b() const { return ccomponents()[2]; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct style : public item {
|
struct IFC_GEOM_API style : public item {
|
||||||
DECLARE_PTR(style)
|
DECLARE_PTR(style)
|
||||||
|
|
||||||
std::string name;
|
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)
|
DECLARE_PTR(geom_item)
|
||||||
|
|
||||||
style::ptr surface_style;
|
style::ptr surface_style;
|
||||||
@@ -396,12 +404,12 @@ typedef item const* ptr;
|
|||||||
geom_item(matrix4::ptr m) : surface_style(nullptr), matrix(m) {}
|
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)
|
DECLARE_PTR(implicit_item)
|
||||||
using geom_item::geom_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)
|
DECLARE_PTR(function_item)
|
||||||
|
|
||||||
function_item(const IfcUtil::IfcBaseInterface* instance = nullptr) : implicit_item(instance) {}
|
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)
|
DECLARE_PTR(functor_item)
|
||||||
|
|
||||||
functor_item(double length, std::function<Eigen::Matrix4d(double u)> fn, const IfcUtil::IfcBaseInterface* instance = nullptr) : function_item(instance),
|
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_;
|
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)
|
DECLARE_PTR(piecewise_function)
|
||||||
|
|
||||||
using spans_t = std::vector<function_item::const_ptr>;
|
using spans_t = std::vector<function_item::const_ptr>;
|
||||||
@@ -480,7 +488,7 @@ typedef item const* ptr;
|
|||||||
spans_t spans_;
|
spans_t spans_;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gradient_function : public function_item {
|
struct IFC_GEOM_API gradient_function : public function_item {
|
||||||
DECLARE_PTR(gradient_function)
|
DECLARE_PTR(gradient_function)
|
||||||
gradient_function(piecewise_function::const_ptr horizontal, piecewise_function::const_ptr vertical, const IfcUtil::IfcBaseInterface* instance = nullptr);
|
gradient_function(piecewise_function::const_ptr horizontal, piecewise_function::const_ptr vertical, const IfcUtil::IfcBaseInterface* instance = nullptr);
|
||||||
gradient_function(gradient_function&&) = default;
|
gradient_function(gradient_function&&) = default;
|
||||||
@@ -506,7 +514,7 @@ typedef item const* ptr;
|
|||||||
piecewise_function::const_ptr horizontal_, vertical_;
|
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)
|
DECLARE_PTR(cant_function)
|
||||||
cant_function(gradient_function::const_ptr gradient, piecewise_function::const_ptr cant, const IfcUtil::IfcBaseInterface* instance = nullptr);
|
cant_function(gradient_function::const_ptr gradient, piecewise_function::const_ptr cant, const IfcUtil::IfcBaseInterface* instance = nullptr);
|
||||||
cant_function(cant_function&&) = default;
|
cant_function(cant_function&&) = default;
|
||||||
@@ -533,7 +541,7 @@ typedef item const* ptr;
|
|||||||
piecewise_function::const_ptr cant_;
|
piecewise_function::const_ptr cant_;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct offset_function : public function_item {
|
struct IFC_GEOM_API offset_function : public function_item {
|
||||||
DECLARE_PTR(offset_function)
|
DECLARE_PTR(offset_function)
|
||||||
offset_function(function_item::const_ptr basis, piecewise_function::const_ptr offset, const IfcUtil::IfcBaseInterface* instance = nullptr);
|
offset_function(function_item::const_ptr basis, piecewise_function::const_ptr offset, const IfcUtil::IfcBaseInterface* instance = nullptr);
|
||||||
offset_function(offset_function&&) = default;
|
offset_function(offset_function&&) = default;
|
||||||
@@ -585,7 +593,7 @@ typedef item const* ptr;
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool less(item::const_ptr, item::const_ptr);
|
IFC_GEOM_API bool less(item::const_ptr, item::const_ptr);
|
||||||
|
|
||||||
struct less_functor {
|
struct less_functor {
|
||||||
bool operator()(item::const_ptr a, item::const_ptr b) const {
|
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
|
// @todo make 4d for easier multiplication
|
||||||
template <size_t N>
|
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() : eigen_base() {}
|
||||||
cartesian_base(const Eigen::Vector3d& c) : eigen_base(c) {}
|
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)) {}
|
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)
|
DECLARE_PTR(point3)
|
||||||
|
|
||||||
virtual point3* clone_() const { return new point3(*this); }
|
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) {}
|
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)
|
DECLARE_PTR(direction3)
|
||||||
|
|
||||||
virtual direction3* clone_() const { return new direction3(*this); }
|
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) {}
|
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 {
|
void print_impl(std::ostream& o, const std::string& classname, int indent = 0) const {
|
||||||
o << std::string(indent, ' ') << classname << std::endl;
|
o << std::string(indent, ' ') << classname << std::endl;
|
||||||
this->matrix->print(o, indent + 4);
|
this->matrix->print(o, indent + 4);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct line : public curve {
|
struct IFC_GEOM_API line : public curve {
|
||||||
DECLARE_PTR(line)
|
DECLARE_PTR(line)
|
||||||
|
|
||||||
virtual line* clone_() const { return new line(*this); }
|
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;
|
void print(std::ostream& o, int indent = 0) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct circle : public curve {
|
struct IFC_GEOM_API circle : public curve {
|
||||||
DECLARE_PTR(circle)
|
DECLARE_PTR(circle)
|
||||||
|
|
||||||
double radius;
|
double radius;
|
||||||
@@ -720,7 +728,7 @@ typedef item const* ptr;
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ellipse : public curve {
|
struct IFC_GEOM_API ellipse : public curve {
|
||||||
DECLARE_PTR(ellipse)
|
DECLARE_PTR(ellipse)
|
||||||
|
|
||||||
double radius;
|
double radius;
|
||||||
@@ -737,7 +745,7 @@ typedef item const* ptr;
|
|||||||
void print(std::ostream& o, int indent = 0) const;
|
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)
|
DECLARE_PTR(bspline_curve)
|
||||||
|
|
||||||
virtual bspline_curve* clone_() const { return new bspline_curve(*this); }
|
virtual bspline_curve* clone_() const { return new bspline_curve(*this); }
|
||||||
@@ -770,7 +778,7 @@ typedef item const* ptr;
|
|||||||
int degree;
|
int degree;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct offset_curve : public curve {
|
struct IFC_GEOM_API offset_curve : public curve {
|
||||||
DECLARE_PTR(offset_curve)
|
DECLARE_PTR(offset_curve)
|
||||||
|
|
||||||
direction3::ptr reference;
|
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)
|
DECLARE_PTR(trimmed_curve)
|
||||||
|
|
||||||
// @todo The copy constructor of point3 within the variant fails on the avx instruction
|
// @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;
|
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)
|
DECLARE_PTR(edge)
|
||||||
|
|
||||||
edge() : trimmed_curve() {}
|
edge() : trimmed_curve() {}
|
||||||
@@ -827,7 +835,7 @@ typedef item const* ptr;
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T = item>
|
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;
|
std::vector<typename T::ptr> children;
|
||||||
|
|
||||||
collection_base() {}
|
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)
|
DECLARE_PTR(collection)
|
||||||
|
|
||||||
virtual collection* clone_() const { return new collection(*this); }
|
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)
|
DECLARE_PTR(loop)
|
||||||
|
|
||||||
boost::optional<bool> external, closed;
|
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)
|
DECLARE_PTR(face)
|
||||||
|
|
||||||
item::ptr basis;
|
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)
|
DECLARE_PTR(shell)
|
||||||
|
|
||||||
boost::optional<bool> closed;
|
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)
|
DECLARE_PTR(solid)
|
||||||
|
|
||||||
virtual solid* clone_() const { return new solid(*this); }
|
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)
|
DECLARE_PTR(loft)
|
||||||
|
|
||||||
item::ptr axis;
|
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)
|
DECLARE_PTR(plane)
|
||||||
|
|
||||||
virtual plane* clone_() const { return new plane(*this); }
|
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)
|
DECLARE_PTR(cylinder)
|
||||||
|
|
||||||
double radius;
|
double radius;
|
||||||
@@ -1087,7 +1095,7 @@ typedef item const* ptr;
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sphere : public surface {
|
struct IFC_GEOM_API sphere : public surface {
|
||||||
DECLARE_PTR(sphere)
|
DECLARE_PTR(sphere)
|
||||||
|
|
||||||
double radius;
|
double radius;
|
||||||
@@ -1101,7 +1109,7 @@ typedef item const* ptr;
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct torus : public surface {
|
struct IFC_GEOM_API torus : public surface {
|
||||||
DECLARE_PTR(torus)
|
DECLARE_PTR(torus)
|
||||||
|
|
||||||
double radius1;
|
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)
|
DECLARE_PTR(bspline_surface)
|
||||||
|
|
||||||
virtual bspline_surface* clone_() const { return new bspline_surface(*this); }
|
virtual bspline_surface* clone_() const { return new bspline_surface(*this); }
|
||||||
@@ -1159,7 +1167,7 @@ typedef item const* ptr;
|
|||||||
std::array<int, 2> degree;
|
std::array<int, 2> degree;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sweep : public geom_item {
|
struct IFC_GEOM_API sweep : public geom_item {
|
||||||
DECLARE_PTR(sweep)
|
DECLARE_PTR(sweep)
|
||||||
|
|
||||||
item::ptr basis;
|
item::ptr basis;
|
||||||
@@ -1168,7 +1176,7 @@ typedef item const* ptr;
|
|||||||
sweep(matrix4::ptr m, item::ptr b) : geom_item(m), basis(b) {}
|
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)
|
DECLARE_PTR(extrusion)
|
||||||
|
|
||||||
direction3::ptr direction;
|
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)
|
DECLARE_PTR(revolve)
|
||||||
|
|
||||||
point3::ptr axis_origin;
|
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)
|
DECLARE_PTR(sweep_along_curve)
|
||||||
|
|
||||||
item::ptr surface;
|
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)
|
DECLARE_PTR(node)
|
||||||
|
|
||||||
// std::map<std::string, geom_item> representations;
|
// 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)
|
DECLARE_PTR(boolean_result)
|
||||||
|
|
||||||
enum operation_t {
|
enum operation_t {
|
||||||
@@ -1300,7 +1308,7 @@ typedef item const* ptr;
|
|||||||
static const size_t max = std::tuple_size<impl::UpgradesTuple>::value;
|
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>
|
template <typename T>
|
||||||
class loop_to_face_upgrade {
|
class loop_to_face_upgrade {
|
||||||
private:
|
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>
|
template <typename T>
|
||||||
class curve_to_edge_upgrade {
|
class curve_to_edge_upgrade {
|
||||||
private:
|
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>
|
template <typename T>
|
||||||
class curve_to_loop_upgrade {
|
class curve_to_loop_upgrade {
|
||||||
private:
|
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>
|
template <typename T>
|
||||||
class edge_to_loop_upgrade {
|
class edge_to_loop_upgrade {
|
||||||
private:
|
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>
|
template <typename T>
|
||||||
class curve_to_face_upgrade {
|
class curve_to_face_upgrade {
|
||||||
private:
|
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>
|
template <typename T>
|
||||||
class loop_to_function_item_upgrade {
|
class loop_to_function_item_upgrade {
|
||||||
private:
|
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>
|
template <typename Fn>
|
||||||
bool apply_predicate_to_collection(const taxonomy::ptr& i, Fn fn) {
|
bool apply_predicate_to_collection(const taxonomy::ptr& i, Fn fn) {
|
||||||
@@ -1724,10 +1732,10 @@ typedef item const* ptr;
|
|||||||
return collection;
|
return collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
taxonomy::solid::ptr create_box(double dx, double dy, double dz);
|
IFC_GEOM_API 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 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<double> thicknesses;
|
||||||
std::vector<ifcopenshell::geometry::taxonomy::ptr> layers;
|
std::vector<ifcopenshell::geometry::taxonomy::ptr> layers;
|
||||||
std::vector<ifcopenshell::geometry::taxonomy::style> styles;
|
std::vector<ifcopenshell::geometry::taxonomy::style> styles;
|
||||||
|
|||||||
@@ -32,9 +32,9 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace IfcUtil {
|
namespace IfcUtil {
|
||||||
std::u32string::value_type convert_codepage(int codepage, int index);
|
IFC_PARSE_API std::u32string::value_type convert_codepage(int codepage, int index);
|
||||||
std::string convert_utf8(const std::u32string& string);
|
IFC_PARSE_API std::string convert_utf8(const std::u32string& string);
|
||||||
std::u32string convert_utf8(const std::string& string);
|
IFC_PARSE_API std::u32string convert_utf8(const std::string& string);
|
||||||
} // namespace IfcUtil
|
} // namespace IfcUtil
|
||||||
|
|
||||||
namespace IfcParse {
|
namespace IfcParse {
|
||||||
|
|||||||
@@ -501,52 +501,52 @@ void rocks_db_attribute_storage::set(void* storage, const IfcParse::declaration*
|
|||||||
std::to_string(index), v);
|
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 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 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<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 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 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<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 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 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<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 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 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<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 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 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<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 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 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<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 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 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<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 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 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<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<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()?
|
// @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 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 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_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<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 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 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<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 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 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<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 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 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<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 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 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<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 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 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<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 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 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<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 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 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<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 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 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<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<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()?
|
// @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 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 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_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<empty_aggregate_of_aggregate_t>(void* storage, const IfcParse::declaration* decl, std::size_t identity, size_t index) const;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
#include <boost/logic/tribool.hpp>
|
#include <boost/logic/tribool.hpp>
|
||||||
#include <boost/dynamic_bitset.hpp>
|
#include <boost/dynamic_bitset.hpp>
|
||||||
|
|
||||||
class EnumerationReference {
|
class IFC_PARSE_API EnumerationReference {
|
||||||
private:
|
private:
|
||||||
const IfcParse::enumeration_type* enumeration_;
|
const IfcParse::enumeration_type* enumeration_;
|
||||||
size_t index_;
|
size_t index_;
|
||||||
@@ -64,10 +64,10 @@ public:
|
|||||||
return enumeration_;
|
return enumeration_;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
class Blank {};
|
class IFC_PARSE_API Blank {};
|
||||||
class Derived {};
|
class IFC_PARSE_API Derived {};
|
||||||
class empty_aggregate_t {};
|
class IFC_PARSE_API empty_aggregate_t {};
|
||||||
class empty_aggregate_of_aggregate_t {};
|
class IFC_PARSE_API empty_aggregate_of_aggregate_t {};
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
struct parameter_pack {
|
struct parameter_pack {
|
||||||
@@ -154,14 +154,14 @@ struct TypeEncoder_t<parameter_pack<Types...>> {
|
|||||||
|
|
||||||
using TypeEncoder = TypeEncoder_t<type_variant_parameter_pack>;
|
using TypeEncoder = TypeEncoder_t<type_variant_parameter_pack>;
|
||||||
|
|
||||||
struct MutableAttributeValue {
|
struct IFC_PARSE_API MutableAttributeValue {
|
||||||
int name_;
|
int name_;
|
||||||
uint8_t index_;
|
uint8_t index_;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace IfcParse {
|
namespace IfcParse {
|
||||||
namespace impl {
|
namespace impl {
|
||||||
class rocks_db_file_storage;
|
class IFC_PARSE_API rocks_db_file_storage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,7 +283,7 @@ namespace impl {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// short lived
|
// short lived
|
||||||
struct AttributeValue {
|
struct IFC_PARSE_API AttributeValue {
|
||||||
uint8_t index_;
|
uint8_t index_;
|
||||||
uint8_t storage_model_ = 0;
|
uint8_t storage_model_ = 0;
|
||||||
const IfcParse::declaration* entity_or_type_ = 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:
|
public:
|
||||||
#ifdef IFOPSH_WITH_ROCKSDB
|
#ifdef IFOPSH_WITH_ROCKSDB
|
||||||
// @todo void* is obviously very ugly here
|
// @todo void* is obviously very ugly here
|
||||||
template<typename T>
|
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>
|
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>
|
template<typename Visitor>
|
||||||
auto apply_visitor(void* storage, const IfcParse::declaration* decl, std::size_t identity, std::size_t index, Visitor&& visitor) const {
|
auto apply_visitor(void* storage, const IfcParse::declaration* decl, std::size_t identity, std::size_t index, Visitor&& visitor) const {
|
||||||
|
|||||||
@@ -84,10 +84,9 @@ enum filetype {
|
|||||||
FT_AUTODETECT
|
FT_AUTODETECT
|
||||||
};
|
};
|
||||||
|
|
||||||
filetype guess_file_type(const std::string& fn);
|
IFC_PARSE_API filetype guess_file_type(const std::string& fn);
|
||||||
|
|
||||||
|
class IFC_PARSE_API InstanceStreamer {
|
||||||
class InstanceStreamer {
|
|
||||||
private:
|
private:
|
||||||
IfcSpfStream* stream_;
|
IfcSpfStream* stream_;
|
||||||
IfcSpfLexer* lexer_;
|
IfcSpfLexer* lexer_;
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ namespace IfcParse {
|
|||||||
};
|
};
|
||||||
|
|
||||||
namespace impl {
|
namespace impl {
|
||||||
struct in_memory_file_storage {
|
struct IFC_PARSE_API in_memory_file_storage {
|
||||||
IfcParse::IfcSpfLexer* tokens;
|
IfcParse::IfcSpfLexer* tokens;
|
||||||
// IfcParse::IfcSpfStream* stream;
|
// 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_;
|
entity_instance_by_name_t byid_;
|
||||||
type_instance_by_name_t tbyid_;
|
type_instance_by_name_t tbyid_;
|
||||||
entities_by_type_t bytype_excl_;
|
entities_by_type_t bytype_excl_;
|
||||||
@@ -303,7 +298,7 @@ namespace IfcParse {
|
|||||||
IfcUtil::IfcBaseClass* create(const IfcParse::declaration* decl);
|
IfcUtil::IfcBaseClass* create(const IfcParse::declaration* decl);
|
||||||
};
|
};
|
||||||
|
|
||||||
class rocks_db_file_storage {
|
class IFC_PARSE_API rocks_db_file_storage {
|
||||||
public:
|
public:
|
||||||
rocksdb::DB* db;
|
rocksdb::DB* db;
|
||||||
rocksdb::WriteOptions wopts;
|
rocksdb::WriteOptions wopts;
|
||||||
@@ -441,7 +436,7 @@ namespace IfcParse {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// @todo merge iterators (template?)
|
// @todo merge iterators (template?)
|
||||||
class rocksdb_types_iterator {
|
class IFC_PARSE_API rocksdb_types_iterator {
|
||||||
private:
|
private:
|
||||||
rocksdb::Iterator* state_;
|
rocksdb::Iterator* state_;
|
||||||
const rocks_db_file_storage* storage_;
|
const rocks_db_file_storage* storage_;
|
||||||
|
|||||||
@@ -71,6 +71,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
%newobject IfcGeom::Representation::BRep::item;
|
%newobject IfcGeom::Representation::BRep::item;
|
||||||
|
%newobject IfcGeom::Representation::BRep::as_compound;
|
||||||
|
|
||||||
%newobject IfcGeom::ConversionResultShape::halfspaces;
|
%newobject IfcGeom::ConversionResultShape::halfspaces;
|
||||||
%newobject IfcGeom::ConversionResultShape::box;
|
%newobject IfcGeom::ConversionResultShape::box;
|
||||||
@@ -78,6 +79,7 @@
|
|||||||
%newobject IfcGeom::ConversionResultShape::add;
|
%newobject IfcGeom::ConversionResultShape::add;
|
||||||
%newobject IfcGeom::ConversionResultShape::subtract;
|
%newobject IfcGeom::ConversionResultShape::subtract;
|
||||||
%newobject IfcGeom::ConversionResultShape::intersect;
|
%newobject IfcGeom::ConversionResultShape::intersect;
|
||||||
|
%newobject IfcGeom::ConversionResultShape::concat;
|
||||||
%newobject IfcGeom::ConversionResultShape::moved;
|
%newobject IfcGeom::ConversionResultShape::moved;
|
||||||
|
|
||||||
%newobject IfcGeom::ConversionResultShape::area;
|
%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) {
|
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());
|
std::set<std::string> elems_set(elems.begin(), elems.end());
|
||||||
IfcGeom::entity_filter ef{ include, false, elems_set };
|
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) {
|
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.attribute_name = "GlobalId";
|
||||||
af.populate(elems_set);
|
af.populate(elems_set);
|
||||||
af.include = include;
|
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) {
|
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());
|
std::set<int> elems_set(elems.begin(), elems.end());
|
||||||
IfcGeom::instance_id_filter af(include, false, elems_set);
|
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) {
|
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_;
|
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 (typename Schema::IfcProduct* product = instance->as<typename Schema::IfcProduct>()) {
|
||||||
if (representation) {
|
if (representation) {
|
||||||
|
|||||||
@@ -294,6 +294,7 @@ constexpr bool is_std_vector_vector_v = is_std_vector_vector<T>::value;
|
|||||||
#endif
|
#endif
|
||||||
#include "../ifcgeom/Iterator.h"
|
#include "../ifcgeom/Iterator.h"
|
||||||
#include "../ifcgeom/ConversionResult.h"
|
#include "../ifcgeom/ConversionResult.h"
|
||||||
|
#include "../ifcgeom/hybrid_kernel.h"
|
||||||
|
|
||||||
#include "../serializers/SvgSerializer.h"
|
#include "../serializers/SvgSerializer.h"
|
||||||
#include "../serializers/WavefrontObjSerializer.h"
|
#include "../serializers/WavefrontObjSerializer.h"
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#ifdef IFC_SHARED_BUILD
|
#ifdef IFC_SHARED_BUILD
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#ifdef Serializers_EXPORTS
|
#ifdef SERIALIZERS_EXPORTS
|
||||||
#define SERIALIZERS_API __declspec(dllexport)
|
#define SERIALIZERS_API __declspec(dllexport)
|
||||||
#else
|
#else
|
||||||
#define SERIALIZERS_API __declspec(dllimport)
|
#define SERIALIZERS_API __declspec(dllimport)
|
||||||
|
|||||||
Reference in New Issue
Block a user