Work towards v1.0 data model with encapsulated weak_ptr as basis for instances

This commit is contained in:
Thomas Krijnen
2026-01-04 10:40:02 +01:00
parent f09ca658f1
commit 7098beb819
210 changed files with 28269 additions and 26471 deletions
+2 -2
View File
@@ -20,8 +20,8 @@ bool ifcopenshell::geometry::kernels::AbstractKernel::convert(const taxonomy::pt
auto it = cache_.find(item);
if (it != cache_.end()) {
results = it->second;
Logger::Notice("Cache hit #" + std::to_string(item->instance->as<IfcUtil::IfcBaseEntity>()->id()) +
" -> #" + std::to_string(it->first->instance->as<IfcUtil::IfcBaseEntity>()->id()));
Logger::Notice("Cache hit #" + std::to_string(item->instance.id()) +
" -> #" + std::to_string(it->first->instance.id()));
return true;
}
}
+2 -2
View File
@@ -121,8 +121,8 @@ namespace ifcopenshell {
*/
virtual bool apply_layerset(IfcGeom::ConversionResults&, const ifcopenshell::geometry::layerset_information&) { throw not_implemented_error(); }
virtual bool apply_folded_layerset(IfcGeom::ConversionResults&, const ifcopenshell::geometry::layerset_information&, const std::map<IfcUtil::IfcBaseEntity*, ifcopenshell::geometry::layerset_information>&) { throw not_implemented_error(); }
virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
virtual bool apply_folded_layerset(IfcGeom::ConversionResults&, const ifcopenshell::geometry::layerset_information&, const std::map<express::Base, ifcopenshell::geometry::layerset_information>&) { throw not_implemented_error(); }
virtual bool convert_openings(const express::Base& entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes) = 0;
virtual bool unify_shapes(const IfcGeom::ConversionResults&, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
+9 -9
View File
@@ -5,16 +5,15 @@
#include <limits>
#include <string>
#include <iostream>
#include <string>
#include <map>
#include <tuple>
#include <type_traits>
#include <optional>
#include <variant>
#include <boost/program_options.hpp>
#include <boost/optional.hpp>
#include <boost/variant.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/optional/optional_io.hpp>
#include "ifc_geom_api.h"
@@ -48,7 +47,8 @@ namespace ifcopenshell {
// of vector settings we need to strip away the optional and detect argument presence
// with !vector::empty()
// tfk: we no longer do this because negative values can not be passed like this as boost confuses them with options
// std::conditional_t<std::is_same_v<T, std::vector<double>>, T, boost::optional<T>> value;
// std::conditional_t<std::is_same_v<T, std::vector<double>>, T, std::optional<T>> value;
// tfk: note that we use boost::optional to avoid a lack of deserialization support with std::optional and boost program options
boost::optional<T> value;
SettingBase() {}
@@ -80,7 +80,7 @@ namespace ifcopenshell {
return value;
} else {
if (value) {
return value.get();
return value.value();
}
if constexpr (HasDefault<Derived>()) {
return Derived::defaultvalue;
@@ -539,7 +539,7 @@ namespace ifcopenshell {
template <typename settings_t>
class SettingsContainer {
public:
typedef boost::variant<bool, int, double, std::string, std::set<int>, std::set<std::string>, std::vector<double>, IteratorOutputOptions, FunctionStepMethod, OutputDimensionalityTypes, TriangulationMethod> value_variant_t;
typedef std::variant<bool, int, double, std::string, std::set<int>, std::set<std::string>, std::vector<double>, IteratorOutputOptions, FunctionStepMethod, OutputDimensionalityTypes, TriangulationMethod> value_variant_t;
private:
settings_t settings;
@@ -579,15 +579,15 @@ namespace ifcopenshell {
void set_option_(const std::string& name, const value_variant_t& val) {
if (std::tuple_element_t<Index, settings_t>::name == name) {
if constexpr (std::is_enum_v<typename std::tuple_element_t<Index, settings_t>::base_type>) {
if (auto* val_ptr = boost::get<int>(&val)) {
if (auto* val_ptr = std::get_if<int>(&val)) {
auto val_as_enum = (typename std::tuple_element_t<Index, settings_t>::base_type) *val_ptr;
std::get<Index>(settings).value = val_as_enum;
return;
}
}
try {
std::get<Index>(settings).value = boost::get<typename std::tuple_element_t<Index, settings_t>::base_type>(val);
} catch (const boost::bad_get&) {
std::get<Index>(settings).value = std::get<typename std::tuple_element_t<Index, settings_t>::base_type>(val);
} catch (const std::bad_variant_access&) {
std::string ty = impl::readable_name<typename std::tuple_element_t<Index, settings_t>::base_type>::name;
throw std::runtime_error("Expected a value of type <" + ty + "> for setting '" + name + "'");
}
+33 -30
View File
@@ -37,12 +37,14 @@ namespace {
}
}
IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_representation_and_product(taxonomy::ptr representation_node, const IfcUtil::IfcBaseEntity* product, const taxonomy::matrix4::ptr& place_) {
IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_representation_and_product(taxonomy::ptr representation_node, const express::Base product_, const taxonomy::matrix4::ptr& place_) {
auto product = product_.as<express::Entity>();
std::stringstream representation_id_builder;
auto place = place_;
representation_id_builder << representation_node->instance->as<IfcUtil::IfcBaseEntity>()->id();
representation_id_builder << representation_node->instance.id();
IfcGeom::Representation::BRep* shape;
IfcGeom::ConversionResults shapes;
@@ -50,11 +52,11 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
if (!kernel_->convert(representation_node, shapes)) {
return 0;
}
if (settings_.get<ifcopenshell::geometry::settings::ApplyLayerSets>().get()) {
ifcopenshell::geometry::layerset_information layerinfo;
std::vector<ifcopenshell::geometry::endpoint_connection> neighbours;
std::map<IfcUtil::IfcBaseEntity*, ifcopenshell::geometry::layerset_information> neigbour_layers;
std::map<express::Base, ifcopenshell::geometry::layerset_information> neigbour_layers;
int layerset_id, lid;
if (mapping_->get_layerset_information(product, layerinfo, layerset_id)) {
@@ -146,10 +148,10 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
}
if (material_style_applied) {
representation_id_builder << "-material-" << single_material->id();
representation_id_builder << "-material-" << single_material.id();
}
if (settings_.get<ifcopenshell::geometry::settings::ForceSpaceTransparency>().has() && product->declaration().is("IfcSpace")) {
if (settings_.get<ifcopenshell::geometry::settings::ForceSpaceTransparency>().has() && product.declaration().is("IfcSpace")) {
for (auto& s : shapes) {
if (s.hasStyle()) {
// @todo the uglyness
@@ -160,27 +162,27 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
int parent_id = -1;
try {
IfcUtil::IfcBaseEntity* parent_object = mapping_->get_decomposing_entity(product);
express::Base parent_object = mapping_->get_decomposing_entity(product);
if (parent_object) {
parent_id = parent_object->id();
parent_id = parent_object.id();
}
} catch (const std::exception& e) {
Logger::Error(e);
}
const std::string name = product->get_value<std::string>("Name", "");
const std::string guid = product->get_value<std::string>("GlobalId", "");
const std::string name = product.get_value<std::string>("Name", "");
const std::string guid = product.get_value<std::string>("GlobalId", "");
const std::string product_type = product->declaration().name();
const std::string product_type = product.declaration().name();
// Does the IfcElement have any IfcOpenings?
// Note that openings for IfcOpeningElements are not processed
auto openings = mapping_->find_openings(product);
if (!settings_.get<ifcopenshell::geometry::settings::DisableOpeningSubtractions>().get() && openings && openings->size()) {
if (!settings_.get<ifcopenshell::geometry::settings::DisableOpeningSubtractions>().get() && !openings.empty()) {
representation_id_builder << "-openings";
for (auto it = openings->begin(); it != openings->end(); ++it) {
representation_id_builder << "-" << (*it)->id();
for (auto& op : openings) {
representation_id_builder << "-" << op.id();
}
IfcGeom::ConversionResults opened_shapes;
@@ -188,9 +190,9 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
try {
std::vector<std::pair<taxonomy::ptr, taxonomy::matrix4>> opening_items;
std::transform(openings->begin(), openings->end(), std::back_inserter(opening_items), [this](IfcUtil::IfcBaseClass* opening) {
std::transform(openings.begin(), openings.end(), std::back_inserter(opening_items), [this](express::Base opening) {
auto prod_item = mapping()->map(opening);
auto repr = mapping()->representation_of(opening->as<IfcUtil::IfcBaseEntity>());
auto repr = mapping()->representation_of(opening);
if (repr) {
return std::make_pair(mapping()->map(repr), *taxonomy::cast<taxonomy::geom_item>(prod_item)->matrix);
} else {
@@ -251,21 +253,21 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
std::string context_string = "";
// IfcShapeRepresentation.
const IfcUtil::IfcBaseEntity *representation = representation_node->instance->as<IfcUtil::IfcBaseEntity>();
auto representation_identifier = representation->get("RepresentationIdentifier");
auto representation = representation_node->instance.as<express::Entity>();
auto representation_identifier = representation.get("RepresentationIdentifier");
if (!representation_identifier.isNull()) {
context_string = (std::string) representation_identifier;
}
else {
IfcUtil::IfcBaseClass *context = (IfcUtil::IfcBaseClass*)representation->get("ContextOfItems");
auto context_type = context->as<IfcUtil::IfcBaseEntity>()->get("ContextType");
auto context = (express::Base)representation.get("ContextOfItems");
auto context_type = context.as<express::Entity>().get("ContextType");
if (!context_type.isNull()) {
context_string = (std::string)context_type;
}
}
auto elem = new IfcGeom::BRepElement(
product->id(),
product.id(),
parent_id,
name,
product_type,
@@ -351,25 +353,26 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
return elem;
}
IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_processed_representation(const IfcUtil::IfcBaseEntity* product, const taxonomy::matrix4::ptr& place, IfcGeom::BRepElement* brep) {
IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_processed_representation(const express::Base product_, const taxonomy::matrix4::ptr& place, IfcGeom::BRepElement* brep) {
auto product = product_.as<express::Entity>();
int parent_id = -1;
try {
IfcUtil::IfcBaseEntity* parent_object = mapping_->get_decomposing_entity(product);
express::Base parent_object = mapping_->get_decomposing_entity(product);
if (parent_object) {
parent_id = parent_object->id();
parent_id = parent_object.id();
}
} catch (const std::exception& e) {
Logger::Error(e);
}
const std::string guid = product->get_value<std::string>("GlobalId");
const std::string name = product->get_value<std::string>("Name", "");
const std::string product_type = product->declaration().name();
const std::string guid = product.get_value<std::string>("GlobalId");
const std::string name = product.get_value<std::string>("Name", "");
const std::string product_type = product.declaration().name();
const std::string context_string = brep->context();
return new IfcGeom::BRepElement(
product->id(),
product.id(),
parent_id,
name,
product_type,
@@ -381,7 +384,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_process
);
}
IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_representation_and_product(const IfcUtil::IfcBaseEntity* representation, const IfcUtil::IfcBaseEntity* product) {
IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_representation_and_product(const express::Base representation, const express::Base product) {
auto interpreted_representation = mapping_->map(representation);
if (!interpreted_representation) {
interpreted_representation = taxonomy::make<taxonomy::collection>();
@@ -394,7 +397,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
);
}
IfcGeom::ConversionResults ifcopenshell::geometry::Converter::convert(IfcUtil::IfcBaseClass * item)
IfcGeom::ConversionResults ifcopenshell::geometry::Converter::convert(express::Base item)
{
std::clock_t map_start = std::clock();
auto geom_item = mapping_->map(item);
+7 -7
View File
@@ -33,8 +33,8 @@ namespace ifcopenshell { namespace geometry {
/*
virtual NativeElement<double, double>* convert(
const IteratorSettings& settings, IfcUtil::IfcBaseClass* representation,
IfcUtil::IfcBaseClass* product)
const IteratorSettings& settings, express::Base representation,
express::Base product)
{
return implementation_->convert(settings, representation, product);
}
@@ -43,13 +43,13 @@ namespace ifcopenshell { namespace geometry {
double total_map_time = 0.;
double total_geom_time = 0.;
IfcGeom::ConversionResults convert(IfcUtil::IfcBaseClass* item);
IfcGeom::ConversionResults convert(express::Base item);
IfcGeom::BRepElement* create_brep_for_representation_and_product(const IfcUtil::IfcBaseEntity* representation, const IfcUtil::IfcBaseEntity* product);
// IfcGeom::BRepElement* create_brep_for_processed_representation(const IfcUtil::IfcBaseEntity* representation, const IfcUtil::IfcBaseEntity* product, IfcGeom::BRepElement* brep);
IfcGeom::BRepElement* create_brep_for_representation_and_product(const express::Base representation, const express::Base product);
// IfcGeom::BRepElement* create_brep_for_processed_representation(const express::Base representation, const express::Base product, IfcGeom::BRepElement* brep);
IfcGeom::BRepElement* create_brep_for_representation_and_product(ifcopenshell::geometry::taxonomy::ptr, const IfcUtil::IfcBaseEntity* product, const ifcopenshell::geometry::taxonomy::matrix4::ptr& place);
IfcGeom::BRepElement* create_brep_for_processed_representation(const IfcUtil::IfcBaseEntity* product, const ifcopenshell::geometry::taxonomy::matrix4::ptr& place, IfcGeom::BRepElement*);
IfcGeom::BRepElement* create_brep_for_representation_and_product(ifcopenshell::geometry::taxonomy::ptr, const express::Base product, const ifcopenshell::geometry::taxonomy::matrix4::ptr& place);
IfcGeom::BRepElement* create_brep_for_processed_representation(const express::Base product, const ifcopenshell::geometry::taxonomy::matrix4::ptr& place, IfcGeom::BRepElement*);
const ifcopenshell::geometry::Settings& settings() { return settings_; }
};
+2 -2
View File
@@ -107,7 +107,7 @@ class stream_or_filename {
private:
std::shared_ptr<std::ofstream> ofs_;
std::shared_ptr<std::ostringstream> oss_;
boost::optional<std::string> filename_;
std::optional<std::string> filename_;
public:
std::ostream& stream;
@@ -126,7 +126,7 @@ public:
return oss_->str();
}
boost::optional<std::string> filename() const {
std::optional<std::string> filename() const {
return filename_;
}
+8 -7
View File
@@ -26,6 +26,7 @@
#include "../ifcparse/Argument.h"
#include "../ifcparse/IfcGlobalId.h"
#include "../ifcparse/IfcLogger.h"
#include "../ifcparse/InstanceData.h"
#include "../ifcgeom/IfcGeomRepresentation.h"
#include "../ifcgeom/ifc_geom_api.h"
@@ -60,7 +61,7 @@ namespace IfcGeom {
std::string _context;
std::string _unique_id;
Transformation _transformation;
const IfcUtil::IfcBaseEntity* product_;
const express::Entity product_;
std::vector<const IfcGeom::Element*> _parents;
public:
@@ -71,9 +72,9 @@ namespace IfcGeom {
// Use the id to compare, or the elevation is the elements are IfcBuildingStoreys and the elevation is set
friend bool operator < (const Element& element1, const Element& element2) {
if (element1.type() == "IfcBuildingStorey" && element2.type() == "IfcBuildingStorey") {
size_t attr_index = element1.product()->declaration().as_entity()->attribute_index("Elevation");
auto elev_attr1 = element1.product()->get_attribute_value(attr_index);
auto elev_attr2 = element2.product()->get_attribute_value(attr_index);
size_t attr_index = element1.product().declaration().as_entity()->attribute_index("Elevation");
auto elev_attr1 = element1.product().get_attribute_value(attr_index);
auto elev_attr2 = element2.product().get_attribute_value(attr_index);
if (!elev_attr1.isNull() && !elev_attr2.isNull()) {
double elev1 = elev_attr1;
@@ -95,12 +96,12 @@ namespace IfcGeom {
const std::string& context() const { return _context; }
const std::string& unique_id() const { return _unique_id; }
const Transformation& transformation() const { return _transformation; }
const IfcUtil::IfcBaseEntity* product() const { return product_; }
const express::Entity& product() const { return product_; }
const std::vector<const IfcGeom::Element*>& parents() const { return _parents; }
void SetParents(std::vector<const IfcGeom::Element*>& newparents) { _parents = newparents; }
Element(const ifcopenshell::geometry::Settings& settings, int id, int parent_id, const std::string& name, const std::string& type,
const std::string& guid, const std::string& context, const ifcopenshell::geometry::taxonomy::matrix4::ptr& trsf, const IfcUtil::IfcBaseEntity* product)
const std::string& guid, const std::string& context, const ifcopenshell::geometry::taxonomy::matrix4::ptr& trsf, const express::Entity& product)
: _id(id), _parent_id(parent_id), _name(name), _type(type), _guid(guid), _context(context), _transformation(settings, trsf)
, product_(product)
{
@@ -137,7 +138,7 @@ namespace IfcGeom {
const IfcGeom::Representation::BRep& geometry() const { return *_geometry; }
BRepElement(int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid,
const std::string& context, const ifcopenshell::geometry::taxonomy::matrix4::ptr& trsf, const boost::shared_ptr<IfcGeom::Representation::BRep>& geometry,
const IfcUtil::IfcBaseEntity* product)
const express::Entity& product)
: Element(geometry->settings(), id, parent_id, name, type, guid, context, trsf, product)
, _geometry(geometry)
{}
+19 -23
View File
@@ -41,10 +41,6 @@
#include <functional>
namespace IfcGeom {
/// The filter function (free or member function) or function object (use boost::ref() to reference to it)
/// should return true if the geometry for the product is wanted to be included in the output.
/// http://www.boost.org/doc/libs/1_62_0/doc/html/function/tutorial.html
typedef boost::function<bool(IfcUtil::IfcBaseEntity*)> filter_t;
struct filter
{
@@ -60,7 +56,7 @@ namespace IfcGeom {
/// Optional description for the filtering criteria of this filter.
std::string description;
bool match(IfcUtil::IfcBaseEntity* prod, const filter_t& pred) const {
bool match(const express::Base& prod, const ifcopenshell::geometry::filter_t& pred) const {
bool is_match = pred(prod);
if (!is_match && traverse) {
is_match = traverse_match(prod, pred);
@@ -68,16 +64,16 @@ namespace IfcGeom {
return is_match == include;
}
bool traverse_match(IfcUtil::IfcBaseEntity* prod, const filter_t& pred) const
bool traverse_match(const express::Base& prod, const ifcopenshell::geometry::filter_t& pred) const
{
IfcUtil::IfcBaseEntity* parent, *current = prod;
express::Base parent, current = prod;
// @todo examine if this can indeed be static. For now usage is only
// in IfcConvert so invocation is bound to a single file with a single
// schema.
// @todo pass settings
ifcopenshell::geometry::Settings s;
static auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(prod->file_, s);
while ((parent = mapping->get_decomposing_entity(current, traverse_openings)) != nullptr) {
static auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(prod.data()->file(), s);
while ((parent = mapping->get_decomposing_entity(current, traverse_openings))) {
if (pred(parent)) {
return true;
}
@@ -136,9 +132,9 @@ namespace IfcGeom {
attribute_filter(const std::string& attribute_name)
: attribute_name(attribute_name) {}
std::string value(IfcUtil::IfcBaseEntity* prod) const {
std::string value(const express::Base& prod) const {
try {
return (std::string) prod->get(attribute_name);
return (std::string) prod.as<express::Entity>().get(attribute_name);
} catch (...) {
// Either
// (a) not an attribute name for this entity instance
@@ -150,11 +146,11 @@ namespace IfcGeom {
}
}
bool match(IfcUtil::IfcBaseEntity* prod) const {
bool match(express::Base prod) const {
return wildcard_filter::match(value(prod));
}
bool operator()(IfcUtil::IfcBaseEntity* prod) const {
bool operator()(express::Base prod) const {
return filter::match(prod, std::bind(&attribute_filter::match, this, std::placeholders::_1));
}
@@ -175,21 +171,21 @@ namespace IfcGeom {
};
struct layer_filter : public wildcard_filter {
typedef std::map<std::string, IfcUtil::IfcBaseEntity*> layer_map_t;
typedef std::map<std::string, express::Base> layer_map_t;
layer_filter() {}
layer_filter(bool include, bool traverse, const std::set<std::string>& patterns)
: wildcard_filter(include, traverse, patterns) {}
bool match(IfcUtil::IfcBaseEntity* prod) const {
bool match(express::Base prod) const {
// @todo
ifcopenshell::geometry::Settings s;
static auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(prod->file_, s);
static auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(prod.data()->file(), s);
layer_map_t layers = mapping->get_layers(prod);
return std::find_if(layers.begin(), layers.end(), wildcards_match(values)) != layers.end();
}
bool operator()(IfcUtil::IfcBaseEntity* prod) const {
bool operator()(express::Base prod) const {
return filter::match(prod, std::bind(&layer_filter::match, this, std::placeholders::_1));
}
@@ -222,17 +218,17 @@ namespace IfcGeom {
: filter(include, traverse)
, entity_names(entity_names) {}
bool match(IfcUtil::IfcBaseEntity* prod) const {
bool match(express::Base prod) const {
// The set is iterated over to able to filter on subtypes.
for (auto& name : entity_names) {
if (prod->declaration().is(name)) {
if (prod.declaration().is(name)) {
return true;
}
}
return false;
}
bool operator()(IfcUtil::IfcBaseEntity* prod) const {
bool operator()(express::Base prod) const {
return filter::match(prod, std::bind(&entity_filter::match, this, std::placeholders::_1));
}
@@ -254,11 +250,11 @@ namespace IfcGeom {
: filter(include, traverse)
, instance_ids_(instance_ids) {}
bool match(IfcUtil::IfcBaseEntity* prod) const {
return instance_ids_.find(prod->id()) != instance_ids_.end();
bool match(express::Base prod) const {
return instance_ids_.find(prod.id()) != instance_ids_.end();
}
bool operator()(IfcUtil::IfcBaseEntity* prod) const {
bool operator()(express::Base prod) const {
return filter::match(prod, std::bind(&instance_id_filter::match, this, std::placeholders::_1));
}
+1 -1
View File
@@ -31,7 +31,7 @@ IfcGeom::Representation::Serialization::Serialization(const BRep& brep)
surface_styles_.push_back(clr(1));
surface_styles_.push_back(clr(2));
sid = it->Style().instance ? it->Style().instance->as<IfcUtil::IfcBaseEntity>()->id() : -1;
sid = it->Style().instance ? it->Style().instance.id() : -1;
} else {
surface_styles_.push_back(-1.);
surface_styles_.push_back(-1.);
+42 -42
View File
@@ -46,9 +46,9 @@ bool IfcGeom::Iterator::initialize() {
if (!res.item) {
continue;
}
std::transform(task.products->begin(), task.products->end(), std::back_inserter(res.products), [this, &res](IfcUtil::IfcBaseClass* prod) {
std::transform(task.products.begin(), task.products.end(), std::back_inserter(res.products), [this, &res](const express::Base& prod) {
auto prod_item = converter_->mapping()->map(prod);
return std::make_pair(prod->as<IfcUtil::IfcBaseEntity>(), ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::geom_item>(prod_item)->matrix);
return std::make_pair(prod, ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::geom_item>(prod_item)->matrix);
});
}
tasks_.push_back(res);
@@ -57,7 +57,7 @@ bool IfcGeom::Iterator::initialize() {
if (settings_.get<ifcopenshell::geometry::settings::NoParallelMapping>().get() && settings_.get<ifcopenshell::geometry::settings::PermissiveShapeReuse>().get()) {
std::unordered_map<
ifcopenshell::geometry::taxonomy::item::ptr,
std::vector<std::pair<IfcUtil::IfcBaseEntity*, ifcopenshell::geometry::taxonomy::matrix4::ptr>>> folded;
std::vector<std::pair<express::Base, ifcopenshell::geometry::taxonomy::matrix4::ptr>>> folded;
for (auto& r : tasks_) {
auto i = r.item;
@@ -104,7 +104,7 @@ bool IfcGeom::Iterator::initialize() {
size_t num_products = 0;
for (auto& r : tasks_) {
num_products += !settings_.get<ifcopenshell::geometry::settings::NoParallelMapping>().get() ? r.products_2->size() : r.products.size();
num_products += !settings_.get<ifcopenshell::geometry::settings::NoParallelMapping>().get() ? r.products_2.size() : r.products.size();
}
time_points[2] = high_resolution_clock::now();
@@ -116,7 +116,7 @@ bool IfcGeom::Iterator::initialize() {
std::vector<taxonomy::ptr> items;
std::map<taxonomy::ptr, taxonomy::matrix4> placements;
std::transform(products.begin(), products.end(), std::back_inserter(items), [this, &placements](IfcUtil::IfcBaseClass* p) {
std::transform(products.begin(), products.end(), std::back_inserter(items), [this, &placements](express::Base p) {
auto item = converter_->mapping()->map(p);
// Product placements do not affect item reuse and should temporarily be swapped to identity
if (item) {
@@ -132,7 +132,7 @@ bool IfcGeom::Iterator::initialize() {
geometry_conversion_result r;
r.item = *it;
std::transform(it, jt, std::back_inserter(r.products), [&r, &placements](taxonomy::ptr product_node) {
return std::make_pair((IfcUtil::IfcBaseEntity*) product_node->instance, placements[product_node]);
return std::make_pair((express::Base) product_node->instance, placements[product_node]);
});
tasks_.push_back(r);
it = jt;
@@ -143,7 +143,7 @@ bool IfcGeom::Iterator::initialize() {
if (tasks_.size() == 0) {
Logger::Warning("No representations encountered, aborting");
initialization_outcome_.reset(false);
initialization_outcome_.emplace(false);
} else if (!settings_.get<ifcopenshell::geometry::settings::DeferProcessingFirstElement>().get()) {
task_iterator_ = tasks_.begin();
@@ -161,7 +161,7 @@ bool IfcGeom::Iterator::initialize() {
initialization_outcome_ = create();
}
} else {
initialization_outcome_.reset(true);
initialization_outcome_.emplace(true);
}
return *initialization_outcome_;
@@ -263,7 +263,7 @@ void IfcGeom::Iterator::process_concurrently() {
finished_ = true;
Logger::SetProduct(boost::none);
Logger::SetProduct(std::nullopt);
if (!terminating_) {
Logger::Status("\rDone creating geometry (" + boost::lexical_cast<std::string>(all_processed_elements_.size()) +
@@ -306,9 +306,9 @@ void IfcGeom::Iterator::compute_bounds(bool with_geometry)
std::vector<ifcopenshell::geometry::geometry_conversion_task> reps;
converter_->mapping()->get_representations(reps, filters_);
std::vector<IfcUtil::IfcBaseClass*> products;
std::vector<express::Base> products;
for (auto& r : reps) {
std::copy(r.products->begin(), r.products->end(), std::back_inserter(products));
std::copy(r.products.begin(), r.products.end(), std::back_inserter(products));
}
for (auto& product : products) {
@@ -323,7 +323,7 @@ void IfcGeom::Iterator::compute_bounds(bool with_geometry)
}
}
const IfcUtil::IfcBaseClass* IfcGeom::Iterator::create_shape_model_for_next_entity() {
express::Base IfcGeom::Iterator::create_shape_model_for_next_entity() {
geometry_conversion_result* task = nullptr;
for (; task_iterator_ < tasks_.end();) {
task = &*task_iterator_++;
@@ -336,9 +336,9 @@ const IfcUtil::IfcBaseClass* IfcGeom::Iterator::create_shape_model_for_next_enti
}
if (task) {
process_finished_rep(task);
return task->item->instance->as<IfcUtil::IfcBaseClass>();
return task->item->instance;
} else {
return nullptr;
return express::Base{};
}
}
@@ -349,31 +349,31 @@ void IfcGeom::Iterator::create_element_(ifcopenshell::geometry::Converter* kerne
if (!rep->item) {
return;
}
std::transform(rep->products_2->begin(), rep->products_2->end(), std::back_inserter(rep->products), [this, &rep, kernel](IfcUtil::IfcBaseClass* prod) {
std::transform(rep->products_2.begin(), rep->products_2.end(), std::back_inserter(rep->products), [this, &rep, kernel](const express::Base& prod) {
auto prod_item = kernel->mapping()->map(prod);
return std::make_pair(prod->as<IfcUtil::IfcBaseEntity>(), ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::geom_item>(prod_item)->matrix);
return std::make_pair(prod, ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::geom_item>(prod_item)->matrix);
});
} else {
}
auto product_node = rep->products.front();
const IfcUtil::IfcBaseEntity* product = product_node.first;
const express::Base product = product_node.first;
const auto& place = product_node.second;
Logger::SetProduct(product);
IfcGeom::BRepElement* brep = static_cast<IfcGeom::BRepElement*>(decorate_with_cache_(GeometrySerializer::READ_BREP, (std::string)product->get("GlobalId"), std::to_string(rep->item->instance->as<IfcUtil::IfcBaseEntity>()->id()), [kernel, settings, product, place, rep]() {
IfcGeom::BRepElement* brep = static_cast<IfcGeom::BRepElement*>(decorate_with_cache_(GeometrySerializer::READ_BREP, (std::string)product.as<express::Entity>().get("GlobalId"), std::to_string(rep->item->instance.id()), [kernel, settings, product, place, rep]() {
return kernel->create_brep_for_representation_and_product(rep->item, product, place);
}));
if (!brep) {
Logger::SetProduct(boost::none);
Logger::SetProduct(std::nullopt);
return;
}
auto elem = process_based_on_settings(settings, brep);
if (!elem) {
Logger::SetProduct(boost::none);
Logger::SetProduct(std::nullopt);
return;
}
@@ -382,10 +382,10 @@ void IfcGeom::Iterator::create_element_(ifcopenshell::geometry::Converter* kerne
for (auto it = rep->products.begin() + 1; it != rep->products.end(); ++it) {
const auto& p = *it;
const IfcUtil::IfcBaseEntity* product2 = p.first;
const express::Base product2 = p.first;
const auto& place2 = p.second;
IfcGeom::BRepElement* brep2 = static_cast<IfcGeom::BRepElement*>(decorate_with_cache_(GeometrySerializer::READ_BREP, (std::string)product2->get("GlobalId"), std::to_string(rep->item->instance->as<IfcUtil::IfcBaseEntity>()->id()), [kernel, settings, product2, place2, brep]() {
IfcGeom::BRepElement* brep2 = static_cast<IfcGeom::BRepElement*>(decorate_with_cache_(GeometrySerializer::READ_BREP, (std::string)product2.as<express::Entity>().get("GlobalId"), std::to_string(rep->item->instance.id()), [kernel, settings, product2, place2, brep]() {
return kernel->create_brep_for_processed_representation(product2, place2, brep);
}));
if (brep2) {
@@ -397,7 +397,7 @@ void IfcGeom::Iterator::create_element_(ifcopenshell::geometry::Converter* kerne
}
}
Logger::SetProduct(boost::none);
Logger::SetProduct(std::nullopt);
}
IfcGeom::Element* IfcGeom::Iterator::process_based_on_settings(ifcopenshell::geometry::Settings settings, IfcGeom::BRepElement* elem, IfcGeom::TriangulationElement* previous)
@@ -490,7 +490,7 @@ void IfcGeom::Iterator::validate_iterator_state() const {
/// Moves to the next shape representation, create its geometry, and returns the associated product.
/// Use get() to retrieve the created geometry.
const IfcUtil::IfcBaseClass* IfcGeom::Iterator::next() {
express::Base IfcGeom::Iterator::next() {
using std::chrono::high_resolution_clock;
validate_iterator_state();
@@ -501,11 +501,11 @@ const IfcUtil::IfcBaseClass* IfcGeom::Iterator::next() {
if (num_threads_ != 1) {
if (!wait_for_element()) {
Logger::SetProduct(boost::none);
Logger::SetProduct(std::nullopt);
time_points[3] = high_resolution_clock::now();
log_timepoints();
task_result_ptr_exhausted = true;
return nullptr;
return express::Base{};
}
task_result_iterator_++;
@@ -517,11 +517,11 @@ const IfcUtil::IfcBaseClass* IfcGeom::Iterator::next() {
// shape representation
if (task_result_iterator_ == --all_processed_elements_.end()) {
if (!create()) {
Logger::SetProduct(boost::none);
Logger::SetProduct(std::nullopt);
time_points[3] = high_resolution_clock::now();
log_timepoints();
task_result_ptr_exhausted = true;
return nullptr;
return express::Base{};
}
}
@@ -565,8 +565,8 @@ IfcGeom::Element* IfcGeom::Iterator::get()
while (parent_object != NULL && hasParent && parent_object->parent_id() != -1) {
// Find the next parent
auto pid = parent_object->parent_id();
auto ifc_product = ifc_file->instance_by_id(pid)->as<IfcUtil::IfcBaseEntity>();
if (ifc_product->declaration().name() == "IfcProject") {
auto ifc_product = ifc_file->instance_by_id(pid);
if (ifc_product.declaration().name() == "IfcProject") {
hasParent = false;
} else {
try {
@@ -595,20 +595,20 @@ const IfcGeom::Element* IfcGeom::Iterator::get_object(int id) {
ifcopenshell::geometry::taxonomy::matrix4::ptr m4;
int parent_id = -1;
std::string instance_type, product_name, product_guid;
IfcUtil::IfcBaseEntity* ifc_product = 0;
express::Base ifc_product;
try {
ifc_product = ifc_file->instance_by_id(id)->as<IfcUtil::IfcBaseEntity>();
instance_type = ifc_product->declaration().name();
ifc_product = ifc_file->instance_by_id(id);
instance_type = ifc_product.declaration().name();
if (ifc_product->declaration().is("IfcRoot")) {
product_guid = (std::string)ifc_product->get("GlobalId");
product_name = ifc_product->get_value<std::string>("Name", "");
if (ifc_product.declaration().is("IfcRoot")) {
product_guid = ifc_product.as<express::Entity>().get_value<std::string>("GlobalId");
product_name = ifc_product.as<express::Entity>().get_value<std::string>("Name", "");
}
auto parent_object = converter_->mapping()->get_decomposing_entity(ifc_product);
if (parent_object) {
parent_id = parent_object->id();
parent_id = parent_object.id();
}
// fails in case of IfcProject
@@ -634,12 +634,12 @@ const IfcGeom::Element* IfcGeom::Iterator::get_object(int id) {
Logger::Error("Unknown error returning product");
}
Element* ifc_object = new Element(settings_, id, parent_id, product_name, instance_type, product_guid, "", m4, ifc_product);
Element* ifc_object = new Element(settings_, id, parent_id, product_name, instance_type, product_guid, "", m4, ifc_product.as<express::Entity>());
return ifc_object;
}
const IfcUtil::IfcBaseClass* IfcGeom::Iterator::create() {
const IfcUtil::IfcBaseClass* product = nullptr;
express::Base IfcGeom::Iterator::create() {
express::Base product;
try {
product = create_shape_model_for_next_entity();
} catch (const std::exception& e) {
@@ -676,7 +676,7 @@ ifcopenshell::geometry::taxonomy::direction3::ptr IfcGeom::Iterator::remove_offs
throw std::runtime_error("remove_offset() can only be called with defer-processing-first-element and no-parallel-mapping settings");
}
auto collect_offset = [&](const item::ptr& itm, const std::vector<std::pair<IfcUtil::IfcBaseEntity*, matrix4::ptr>>& pr) -> std::pair<double, Eigen::Vector3d> {
auto collect_offset = [&](const item::ptr& itm, const std::vector<std::pair<express::Base, matrix4::ptr>>& pr) -> std::pair<double, Eigen::Vector3d> {
std::function<std::pair<double, Eigen::Vector3d>(const item::ptr&, Eigen::Matrix4d)> traverse;
traverse = [&](const item::ptr& node, Eigen::Matrix4d m4) -> std::pair<double, Eigen::Vector3d> {
if (auto shl = std::dynamic_pointer_cast<shell>(node)) {
@@ -756,7 +756,7 @@ ifcopenshell::geometry::taxonomy::direction3::ptr IfcGeom::Iterator::remove_offs
Eigen::Matrix4d translation_matrix = Eigen::Matrix4d::Identity();
translation_matrix.block<3, 1>(0, 3) = vec;
auto remove_offset = [&](const item::ptr& itm, const std::vector<std::pair<IfcUtil::IfcBaseEntity*, matrix4::ptr>>& pr) -> bool {
auto remove_offset = [&](const item::ptr& itm, const std::vector<std::pair<express::Base, matrix4::ptr>>& pr) -> bool {
std::function<bool(const item::ptr&, Eigen::Matrix4d)> traverse;
traverse = [&](const item::ptr& node, Eigen::Matrix4d m4) -> bool {
if (auto shl = std::dynamic_pointer_cast<shell>(node)) {
+22 -18
View File
@@ -91,14 +91,18 @@ namespace IfcGeom {
// For NoParallelMapping==true
ifcopenshell::geometry::taxonomy::ptr item;
std::vector<std::pair<IfcUtil::IfcBaseEntity*, ifcopenshell::geometry::taxonomy::matrix4::ptr>> products;
std::vector<std::pair<express::Base, ifcopenshell::geometry::taxonomy::matrix4::ptr>> products;
// For NoParallelMapping==false
IfcUtil::IfcBaseEntity* representation;
aggregate_of_instance::ptr products_2;
express::Base representation;
std::vector<express::Base> products_2;
std::vector<IfcGeom::BRepElement*> breps;
std::vector<IfcGeom::Element*> elements;
bool is_parallel() const {
return !!representation;
}
};
@@ -127,7 +131,7 @@ namespace IfcGeom {
ifcopenshell::geometry::Settings settings_;
IfcParse::IfcFile* ifc_file;
std::vector<filter_t> filters_;
std::vector<ifcopenshell::geometry::filter_t> filters_;
int num_threads_;
std::string geometry_library_;
@@ -193,7 +197,7 @@ namespace IfcGeom {
return element;
}
const IfcUtil::IfcBaseClass* create_shape_model_for_next_entity();
express::Base create_shape_model_for_next_entity();
void create_element_(
ifcopenshell::geometry::Converter* kernel,
@@ -213,7 +217,7 @@ namespace IfcGeom {
ifcopenshell::geometry::taxonomy::direction3::ptr remove_offset_();
public:
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)
Iterator(std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel>&& geometry_library, const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file, const std::vector<ifcopenshell::geometry::filter_t>& filters, int num_threads)
: settings_(settings)
, ifc_file(file)
, filters_(filters)
@@ -255,16 +259,16 @@ namespace IfcGeom {
return items;
}
aggregate_of_aggregate_of_instance::ptr get_task_products() const {
aggregate_of_aggregate_of_instance::ptr products = aggregate_of_aggregate_of_instance::ptr(new aggregate_of_aggregate_of_instance);
std::vector<std::vector<express::Base>> get_task_products() const {
std::vector<std::vector<express::Base>> products;
for (const auto& task : tasks_) {
if (task.products_2) {
products->push(task.products_2);
if (task.is_parallel()) {
products.push_back(task.products_2);
} else {
for (auto& product : task.products) {
aggregate_of_instance::ptr p(new aggregate_of_instance);
p->push(product.first);
products->push(p);
std::vector<express::Base> p;
p.push_back(product.first);
products.push_back(p);
}
}
}
@@ -276,7 +280,7 @@ namespace IfcGeom {
// Check if error occurred during iterator initialization or iteration over elements.
bool had_error_processing_elements() const { return had_error_processing_elements_; }
boost::optional<bool> initialization_outcome_;
std::optional<bool> initialization_outcome_;
/**
* @return Returns true if the iterator is initialized with any elements, false otherwise.
@@ -309,15 +313,15 @@ namespace IfcGeom {
IfcParse::IfcFile* file() const { return ifc_file; }
const std::vector<IfcGeom::filter_t>& filters() const { return filters_; }
std::vector<IfcGeom::filter_t>& filters() { return filters_; }
const std::vector<ifcopenshell::geometry::filter_t>& filters() const { return filters_; }
std::vector<ifcopenshell::geometry::filter_t>& filters() { return filters_; }
const ifcopenshell::geometry::taxonomy::point3& bounds_min() const { return bounds_min_; }
const ifcopenshell::geometry::taxonomy::point3& bounds_max() const { return bounds_max_; }
/// Moves to the next shape representation, create its geometry, and returns the associated product.
/// Use get() to retrieve the created geometry.
const IfcUtil::IfcBaseClass* next();
express::Base next();
/// Gets the representation of the current geometrical entity.
Element* get();
@@ -330,7 +334,7 @@ namespace IfcGeom {
const Element* get_object(int id);
const IfcUtil::IfcBaseClass* create();
express::Base create();
};
}
+12 -5
View File
@@ -6,15 +6,17 @@
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/algorithm/string/case_conv.hpp>
#include "../../ifcparse/IfcFile.h"
#define EXTERNAL_DEFS_1(r, data, elem) \
IfcUtil::IfcBaseClass* BOOST_PP_CAT(tesselate_Ifc, elem)(const TopoDS_Shape& shape, double deflection);
express::Base BOOST_PP_CAT(tesselate_Ifc, elem)(IfcParse::IfcFile&, const TopoDS_Shape& shape, double deflection);
#define EXTERNAL_DEFS_2(r, data, elem) \
IfcUtil::IfcBaseClass* BOOST_PP_CAT(serialise_Ifc, elem)(const TopoDS_Shape& shape, bool advanced);
express::Base BOOST_PP_CAT(serialise_Ifc, elem)(IfcParse::IfcFile&, const TopoDS_Shape& shape, bool advanced);
#define CONDITIONAL_CALL(r, data, elem) \
if (schema_name_lower == BOOST_PP_STRINGIZE(BOOST_PP_CAT(elem,))) { \
return BOOST_PP_CAT(METHOD_NAME, elem)(shape, arg_2); \
return BOOST_PP_CAT(METHOD_NAME, elem)(f, shape, arg_2); \
}
BOOST_PP_SEQ_FOR_EACH(EXTERNAL_DEFS_1, , SCHEMA_SEQ);
@@ -22,8 +24,11 @@ BOOST_PP_SEQ_FOR_EACH(EXTERNAL_DEFS_2, , SCHEMA_SEQ);
#define METHOD_NAME tesselate_Ifc
IfcUtil::IfcBaseClass* IfcGeom::tesselate(const std::string& schema_name, const TopoDS_Shape& shape, double arg_2) {
express::Base IfcGeom::tesselate(IfcParse::IfcFile& f, const TopoDS_Shape& shape, double arg_2) {
auto schema_name = f.schema()->name();
// @todo an ugly hack to guarantee schemas are initialised.
// @todo is this still needed? parsing a file should have initialized the schemas already.
try {
IfcParse::schema_by_name("IFC2X3");
} catch (IfcParse::IfcException&) {}
@@ -38,7 +43,9 @@ IfcUtil::IfcBaseClass* IfcGeom::tesselate(const std::string& schema_name, const
#undef METHOD_NAME
#define METHOD_NAME serialise_Ifc
IfcUtil::IfcBaseClass* IfcGeom::serialise(const std::string& schema_name, const TopoDS_Shape& shape, bool arg_2) {
express::Base IfcGeom::serialise(IfcParse::IfcFile& f, const TopoDS_Shape& shape, bool arg_2) {
auto schema_name = f.schema()->name();
// @todo an ugly hack to guarantee schemas are initialised.
try {
IfcParse::schema_by_name("IFC2X3");
+4 -4
View File
@@ -1,4 +1,4 @@
#include "../../ifcparse/IfcBaseClass.h"
#include "../../ifcparse/express.h"
#include "ifc_geomserialization_api.h"
@@ -7,6 +7,6 @@
#include <string>
namespace IfcGeom {
IFC_GEOMSERIALIZATION_API IfcUtil::IfcBaseClass* tesselate(const std::string& schema_name, const TopoDS_Shape& shape, double deflection);
IFC_GEOMSERIALIZATION_API IfcUtil::IfcBaseClass* serialise(const std::string& schema_name, const TopoDS_Shape& shape, bool advanced);
}
IFC_GEOMSERIALIZATION_API express::Base tesselate(IfcParse::IfcFile& f, const TopoDS_Shape& shape, double deflection);
IFC_GEOMSERIALIZATION_API express::Base serialise(IfcParse::IfcFile& f, const TopoDS_Shape& shape, bool advanced);
} // namespace IfcGeom
+334 -249
View File
@@ -24,6 +24,7 @@
#include "../../../ifcparse/macros.h"
#include "../../../ifcparse/IfcParse.h"
#include "../../../ifcparse/IfcFile.h"
#define INCLUDE_PARENT_PARENT_DIR(x) STRINGIFY(../../../ifcparse/x.h)
#include INCLUDE_PARENT_PARENT_DIR(IfcSchema)
@@ -33,27 +34,25 @@
#include <numeric>
#include <numeric>
template <typename T, typename U>
int convert_to_ifc(const T& t, U*& u, bool /*advanced*/) {
std::vector<double> coords(3);
coords[0] = t.X(); coords[1] = t.Y(); coords[2] = t.Z();
u = new U(coords);
int convert_to_ifc(IfcParse::IfcFile& f, const T& t, U& u, bool /*advanced*/) {
u = f.create<U>();
u.set_attribute_value(0, std::vector<double>{t.X(), t.Y(), t.Z()});
return 1;
}
template <>
int convert_to_ifc(const TopoDS_Vertex& v, IfcSchema::IfcCartesianPoint*& p, bool advanced) {
int convert_to_ifc(IfcParse::IfcFile& f, const TopoDS_Vertex& v, IfcSchema::IfcCartesianPoint& p, bool advanced) {
gp_Pnt pnt = BRep_Tool::Pnt(v);
return convert_to_ifc(pnt, p, advanced);
return convert_to_ifc(f, pnt, p, advanced);
}
template <>
int convert_to_ifc(const TopoDS_Vertex& v, IfcSchema::IfcVertex*& vertex, bool advanced) {
IfcSchema::IfcCartesianPoint* p;
if (convert_to_ifc(v, p, advanced)) {
vertex = new IfcSchema::IfcVertexPoint(p);
int convert_to_ifc(IfcParse::IfcFile& f, const TopoDS_Vertex& v, IfcSchema::IfcVertexPoint& vertex, bool advanced) {
IfcSchema::IfcCartesianPoint p;
if (convert_to_ifc(f, v, p, advanced)) {
vertex = f.create<IfcSchema::IfcVertexPoint>();
vertex.setVertexGeometry(p);
return 1;
} else {
return 0;
@@ -61,14 +60,17 @@ int convert_to_ifc(const TopoDS_Vertex& v, IfcSchema::IfcVertex*& vertex, bool a
}
template <>
int convert_to_ifc(const gp_Ax2& a, IfcSchema::IfcAxis2Placement3D*& ax, bool advanced) {
IfcSchema::IfcCartesianPoint* p;
IfcSchema::IfcDirection *x, *z;
if (!(convert_to_ifc(a.Location(), p, advanced) && convert_to_ifc(a.Direction(), z, advanced) && convert_to_ifc(a.XDirection(), x, advanced))) {
ax = 0;
int convert_to_ifc(IfcParse::IfcFile& f, const gp_Ax2& a, IfcSchema::IfcAxis2Placement3D& ax, bool advanced) {
IfcSchema::IfcCartesianPoint p;
IfcSchema::IfcDirection x, z;
if (!(convert_to_ifc(f, a.Location(), p, advanced) && convert_to_ifc(f, a.Direction(), z, advanced) && convert_to_ifc(f, a.XDirection(), x, advanced))) {
ax = IfcSchema::IfcAxis2Placement3D{};
return 0;
}
ax = new IfcSchema::IfcAxis2Placement3D(p, z, x);
ax = f.create<IfcSchema::IfcAxis2Placement3D>();
ax.setLocation(p);
ax.setAxis(z);
ax.setRefDirection(x);
return 1;
}
@@ -110,44 +112,55 @@ namespace {
#endif
template <>
int convert_to_ifc(const Handle_Geom_Curve& c, IfcSchema::IfcCurve*& curve, bool advanced) {
int convert_to_ifc(IfcParse::IfcFile& f, const Handle_Geom_Curve& c, IfcSchema::IfcCurve& curve, bool advanced) {
if (c->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
Handle_Geom_TrimmedCurve trim = Handle_Geom_TrimmedCurve::DownCast(c);
const Handle_Geom_Curve basis = trim->BasisCurve();
return convert_to_ifc(basis, curve, advanced);
return convert_to_ifc(f, basis, curve, advanced);
} else if (c->DynamicType() == STANDARD_TYPE(Geom_Line)) {
IfcSchema::IfcDirection* d;
IfcSchema::IfcCartesianPoint* p;
IfcSchema::IfcDirection d;
IfcSchema::IfcCartesianPoint p;
Handle_Geom_Line line = Handle_Geom_Line::DownCast(c);
if (!convert_to_ifc(line->Position().Location(), p, advanced)) {
if (!convert_to_ifc(f, line->Position().Location(), p, advanced)) {
return 0;
}
if (!convert_to_ifc(line->Position().Direction(), d, advanced)) {
if (!convert_to_ifc(f, line->Position().Direction(), d, advanced)) {
return 0;
}
IfcSchema::IfcVector* v = new IfcSchema::IfcVector(d, 1.);
curve = new IfcSchema::IfcLine(p, v);
IfcSchema::IfcVector v = f.create<IfcSchema::IfcVector>();
v.setOrientation(d);
v.setMagnitude(1.);
IfcSchema::IfcLine l = f.create<IfcSchema::IfcLine>();
l.setPnt(p);
l.setDir(v);
curve = l;
return 1;
} else if (c->DynamicType() == STANDARD_TYPE(Geom_Circle)) {
IfcSchema::IfcAxis2Placement3D* ax;
IfcSchema::IfcAxis2Placement3D ax;
Handle_Geom_Circle circle = Handle_Geom_Circle::DownCast(c);
convert_to_ifc(circle->Position(), ax, advanced);
curve = new IfcSchema::IfcCircle(ax, circle->Radius());
convert_to_ifc(f, circle->Position(), ax, advanced);
auto circ = f.create<IfcSchema::IfcCircle>();
circ.setPosition(ax);
circ.setRadius(circle->Radius());
curve = circ;
return 1;
} else if (c->DynamicType() == STANDARD_TYPE(Geom_Ellipse)) {
IfcSchema::IfcAxis2Placement3D* ax;
IfcSchema::IfcAxis2Placement3D ax;
Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(c);
convert_to_ifc(ellipse->Position(), ax, advanced);
curve = new IfcSchema::IfcEllipse(ax, ellipse->MajorRadius(), ellipse->MinorRadius());
auto el = f.create<IfcSchema::IfcEllipse>();
el.setPosition(ax);
el.setSemiAxis1(ellipse->MajorRadius());
el.setSemiAxis2(ellipse->MinorRadius());
curve = el;
return 1;
}
@@ -161,15 +174,15 @@ int convert_to_ifc(const Handle_Geom_Curve& c, IfcSchema::IfcCurve*& curve, bool
IfcSchema::IfcKnotType::Value knot_spec = IfcSchema::IfcKnotType::IfcKnotType_QUASI_UNIFORM_KNOTS;
IfcSchema::IfcCartesianPoint::list::ptr points(new IfcSchema::IfcCartesianPoint::list);
std::vector<IfcSchema::IfcCartesianPoint> points;
TColgp_Array1OfPnt poles(1, bezier->NbPoles());
bezier->Poles(poles);
for (int i = 1; i <= bezier->NbPoles(); ++i) {
IfcSchema::IfcCartesianPoint* p;
if (!convert_to_ifc(poles.Value(i), p, advanced)) {
IfcSchema::IfcCartesianPoint p;
if (!convert_to_ifc(f, poles.Value(i), p, advanced)) {
return 0;
}
points->push(p);
points.push_back(p);
if (i == 1 || i == bezier->NbPoles()) {
mults.push_back(bezier->Degree() + 1);
@@ -184,32 +197,31 @@ int convert_to_ifc(const Handle_Geom_Curve& c, IfcSchema::IfcCurve*& curve, bool
bezier->Weights(bspline_weights);
opencascade_array_to_vector(bspline_weights, weights);
curve = new IfcSchema::IfcRationalBSplineCurveWithKnots(
bezier->Degree(),
points,
IfcSchema::IfcBSplineCurveForm::IfcBSplineCurveForm_UNSPECIFIED,
bezier->IsClosed() != 0,
false,
mults,
knots,
knot_spec,
weights
);
auto bspl = f.create<IfcSchema::IfcRationalBSplineCurveWithKnots>();
bspl.setDegree(bezier->Degree());
bspl.setControlPointsList(points);
bspl.setCurveForm(IfcSchema::IfcBSplineCurveForm::IfcBSplineCurveForm_UNSPECIFIED);
bspl.setClosedCurve(bezier->IsClosed() != 0);
bspl.setSelfIntersect(false);
bspl.setKnotMultiplicities(mults);
bspl.setKnots(knots);
bspl.setKnotSpec(knot_spec);
bspl.setWeightsData(weights);
return 1;
}
else if (c->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve)) {
Handle_Geom_BSplineCurve bspline = Handle_Geom_BSplineCurve::DownCast(c);
IfcSchema::IfcCartesianPoint::list::ptr points(new IfcSchema::IfcCartesianPoint::list);
std::vector<IfcSchema::IfcCartesianPoint> points;
TColgp_Array1OfPnt poles(1, bspline->NbPoles());
bspline->Poles(poles);
for (int i = 1; i <= bspline->NbPoles(); ++i) {
IfcSchema::IfcCartesianPoint* p;
if (!convert_to_ifc(poles.Value(i), p, advanced)) {
IfcSchema::IfcCartesianPoint p;
if (!convert_to_ifc(f, poles.Value(i), p, advanced)) {
return 0;
}
points->push(p);
points.push_back(p);
}
IfcSchema::IfcKnotType::Value knot_spec = opencascade_knotspec_to_ifc(bspline->KnotDistribution());
@@ -237,39 +249,33 @@ int convert_to_ifc(const Handle_Geom_Curve& c, IfcSchema::IfcCurve*& curve, bool
}
}
if (bspline->IsPeriodic() && points->size()) {
points->push(*points->begin());
if (bspline->IsPeriodic() && points.size()) {
points.push_back(points.front());
weights.push_back(weights[0]);
auto sum = std::accumulate(mults.begin(), mults.end(), 0);
auto d = sum - (bspline->Degree() + (int)points->size() + 1);
auto d = sum - (bspline->Degree() + (int) points.size() + 1);
(*mults.begin()) -= d / 2;
(*mults.rbegin()) -= d / 2;
}
IfcSchema::IfcBSplineCurveWithKnots bspl;
if (rational) {
curve = new IfcSchema::IfcRationalBSplineCurveWithKnots(
bspline->Degree(),
points,
IfcSchema::IfcBSplineCurveForm::IfcBSplineCurveForm_UNSPECIFIED,
bspline->IsClosed() != 0,
false,
mults,
knots,
knot_spec,
weights
);
} else {
curve = new IfcSchema::IfcBSplineCurveWithKnots(
bspline->Degree(),
points,
IfcSchema::IfcBSplineCurveForm::IfcBSplineCurveForm_UNSPECIFIED,
bspline->IsClosed() != 0,
false,
mults,
knots,
knot_spec
);
}
auto rbspl = f.create<IfcSchema::IfcRationalBSplineCurveWithKnots>();
rbspl.setWeightsData(weights);
bspl = rbspl;
} else {
bspl = f.create<IfcSchema::IfcBSplineCurveWithKnots>();
}
bspl.setDegree(bspline->Degree());
bspl.setControlPointsList(points);
bspl.setCurveForm(IfcSchema::IfcBSplineCurveForm::IfcBSplineCurveForm_UNSPECIFIED);
bspl.setClosedCurve(bspline->IsClosed() != 0);
bspl.setSelfIntersect(false);
bspl.setKnotMultiplicities(mults);
bspl.setKnots(knots);
bspl.setKnotSpec(knot_spec);
return 1;
}
@@ -278,46 +284,50 @@ int convert_to_ifc(const Handle_Geom_Curve& c, IfcSchema::IfcCurve*& curve, bool
}
template <>
int convert_to_ifc(const Handle_Geom_Surface& s, IfcSchema::IfcSurface*& surface, bool advanced) {
int convert_to_ifc(IfcParse::IfcFile& f, const Handle_Geom_Surface& s, IfcSchema::IfcSurface& surface, bool advanced) {
if (s->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
Handle_Geom_Plane plane = Handle_Geom_Plane::DownCast(s);
IfcSchema::IfcAxis2Placement3D* place;
IfcSchema::IfcAxis2Placement3D place;
/// @todo: Note that the Ax3 is converted to an Ax2 here
if (!convert_to_ifc(plane->Position().Ax2(), place, advanced)) {
if (!convert_to_ifc(f, plane->Position().Ax2(), place, advanced)) {
return 0;
}
surface = new IfcSchema::IfcPlane(place);
auto pln = f.create<IfcSchema::IfcPlane>();
pln.setPosition(place);
surface = pln;
return 1;
}
#ifdef SCHEMA_HAS_IfcRationalBSplineSurfaceWithKnots
else if (s->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
Handle_Geom_CylindricalSurface cyl = Handle_Geom_CylindricalSurface::DownCast(s);
IfcSchema::IfcAxis2Placement3D* place;
IfcSchema::IfcAxis2Placement3D place;
/// @todo: Note that the Ax3 is converted to an Ax2 here
if (!convert_to_ifc(cyl->Position().Ax2(), place, advanced)) {
if (!convert_to_ifc(f, cyl->Position().Ax2(), place, advanced)) {
return 0;
}
surface = new IfcSchema::IfcCylindricalSurface(place, cyl->Radius());
auto surf = f.create<IfcSchema::IfcCylindricalSurface>();
surf.setPosition(place);
surf.setRadius(cyl->Radius());
surface = surf;
return 1;
} else if (s->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface)) {
typedef aggregate_of_aggregate_of<IfcSchema::IfcCartesianPoint> points_t;
std::vector<std::vector<IfcSchema::IfcCartesianPoint>> points;
Handle_Geom_BSplineSurface bspline = Handle_Geom_BSplineSurface::DownCast(s);
points_t::ptr points(new points_t);
TColgp_Array2OfPnt poles(1, bspline->NbUPoles(), 1, bspline->NbVPoles());
bspline->Poles(poles);
for (int i = 1; i <= bspline->NbUPoles(); ++i) {
std::vector<IfcSchema::IfcCartesianPoint*> ps;
auto& ps = points.emplace_back();
ps.reserve(bspline->NbVPoles());
for (int j = 1; j <= bspline->NbVPoles(); ++j) {
IfcSchema::IfcCartesianPoint* p;
if (!convert_to_ifc(poles.Value(i, j), p, advanced)) {
IfcSchema::IfcCartesianPoint p;
if (!convert_to_ifc(f, poles.Value(i, j), p, advanced)) {
return 0;
}
ps.push_back(p);
}
points->push(ps);
}
IfcSchema::IfcKnotType::Value knot_spec_u = opencascade_knotspec_to_ifc(bspline->UKnotDistribution());
@@ -361,38 +371,30 @@ int convert_to_ifc(const Handle_Geom_Surface& s, IfcSchema::IfcSurface*& surface
}
}
IfcSchema::IfcBSplineSurfaceWithKnots bspl;
if (rational) {
surface = new IfcSchema::IfcRationalBSplineSurfaceWithKnots(
bspline->UDegree(),
bspline->VDegree(),
points,
IfcSchema::IfcBSplineSurfaceForm::IfcBSplineSurfaceForm_UNSPECIFIED,
bspline->IsUClosed() != 0,
bspline->IsVClosed() != 0,
false,
umults,
vmults,
uknots,
vknots,
knot_spec_u,
weights
);
auto rbspl = f.create<IfcSchema::IfcRationalBSplineSurfaceWithKnots>();
rbspl.setWeightsData(weights);
bspl = rbspl;
} else {
surface = new IfcSchema::IfcBSplineSurfaceWithKnots(
bspline->UDegree(),
bspline->VDegree(),
points,
IfcSchema::IfcBSplineSurfaceForm::IfcBSplineSurfaceForm_UNSPECIFIED,
bspline->IsUClosed() != 0,
bspline->IsVClosed() != 0,
false,
umults,
vmults,
uknots,
vknots,
knot_spec_u
);
}
bspl = f.create<IfcSchema::IfcBSplineSurfaceWithKnots>();
}
bspl.setUDegree(bspline->UDegree());
bspl.setVDegree(bspline->VDegree());
bspl.setControlPointsList(points);
bspl.setSurfaceForm(IfcSchema::IfcBSplineSurfaceForm::IfcBSplineSurfaceForm_UNSPECIFIED);
bspl.setUClosed(bspline->IsUClosed() != 0);
bspl.setVClosed(bspline->IsVClosed() != 0);
bspl.setSelfIntersect(false);
bspl.setUMultiplicities(umults);
bspl.setVMultiplicities(vmults);
bspl.setUKnots(uknots);
bspl.setVKnots(vknots);
bspl.setKnotSpec(knot_spec_u);
surface = bspl;
return 1;
}
@@ -401,27 +403,37 @@ int convert_to_ifc(const Handle_Geom_Surface& s, IfcSchema::IfcSurface*& surface
}
template <>
int convert_to_ifc(const TopoDS_Edge& e, IfcSchema::IfcCurve*& c, bool advanced) {
int convert_to_ifc(IfcParse::IfcFile& f, const TopoDS_Edge& e, IfcSchema::IfcCurve& c, bool advanced) {
double a, b;
IfcSchema::IfcCurve* base;
IfcSchema::IfcCurve base;
Handle_Geom_Curve crv = BRep_Tool::Curve(e, a, b);
if (!convert_to_ifc(crv, base, advanced)) {
if (!convert_to_ifc(f, crv, base, advanced)) {
return 0;
}
IfcSchema::IfcTrimmingSelect::list::ptr trim1(new IfcSchema::IfcTrimmingSelect::list);
IfcSchema::IfcTrimmingSelect::list::ptr trim2(new IfcSchema::IfcTrimmingSelect::list);
trim1->push(new IfcSchema::IfcParameterValue(a));
trim2->push(new IfcSchema::IfcParameterValue(b));
auto ta = f.create<IfcSchema::IfcParameterValue>();
ta.set_attribute_value(0, a);
auto tb = f.create<IfcSchema::IfcParameterValue>();
tb.set_attribute_value(0, b);
c = new IfcSchema::IfcTrimmedCurve(base, trim1, trim2, true, IfcSchema::IfcTrimmingPreference::IfcTrimmingPreference_PARAMETER);
std::vector<IfcSchema::IfcTrimmingSelect> trim1{ta};
std::vector<IfcSchema::IfcTrimmingSelect> trim2{tb};
auto tc = f.create<IfcSchema::IfcTrimmedCurve>();
tc.setBasisCurve(base);
tc.setTrim1(trim1);
tc.setTrim2(trim2);
tc.setSenseAgreement(true);
tc.setMasterRepresentation(IfcSchema::IfcTrimmingPreference::IfcTrimmingPreference_PARAMETER);
c = tc;
return 1;
}
template <>
int convert_to_ifc(const TopoDS_Edge& e, IfcSchema::IfcEdge*& edge, bool advanced) {
int convert_to_ifc(IfcParse::IfcFile& f, const TopoDS_Edge& e, IfcSchema::IfcEdge& edge, bool advanced) {
double a, b;
TopExp_Explorer exp(e, TopAbs_VERTEX);
@@ -431,8 +443,8 @@ int convert_to_ifc(const TopoDS_Edge& e, IfcSchema::IfcEdge*& edge, bool advance
if (!exp.More()) return 0;
TopoDS_Vertex v2 = TopoDS::Vertex(exp.Current());
IfcSchema::IfcVertex *vertex1, *vertex2;
if (!(convert_to_ifc(v1, vertex1, advanced) && convert_to_ifc(v2, vertex2, advanced))) {
IfcSchema::IfcVertexPoint vertex1, vertex2;
if (!(convert_to_ifc(f, v1, vertex1, advanced) && convert_to_ifc(f, v2, vertex2, advanced))) {
return 0;
}
@@ -443,18 +455,36 @@ int convert_to_ifc(const TopoDS_Edge& e, IfcSchema::IfcEdge*& edge, bool advance
}
if (crv->DynamicType() == STANDARD_TYPE(Geom_Line) && !advanced) {
IfcSchema::IfcEdge* edge2 = new IfcSchema::IfcEdge(vertex1, vertex2);
edge = new IfcSchema::IfcOrientedEdge(edge2, true);
IfcSchema::IfcEdge edge2 = f.create<IfcSchema::IfcEdge>();
edge2.setEdgeStart(vertex1);
edge2.setEdgeEnd(vertex2);
auto ori = f.create<IfcSchema::IfcOrientedEdge>();
ori.setEdgeElement(edge2);
ori.setOrientation(true);
edge = ori;
return 1;
} else {
IfcSchema::IfcCurve* curve;
if (!convert_to_ifc(crv, curve, advanced)) {
IfcSchema::IfcCurve curve;
if (!convert_to_ifc(f, crv, curve, advanced)) {
return 0;
}
/// @todo probably not correct
const bool sense = e.Orientation() == TopAbs_FORWARD;
IfcSchema::IfcEdge* edge2 = new IfcSchema::IfcEdgeCurve(vertex1, vertex2, curve, true);
edge = new IfcSchema::IfcOrientedEdge(edge2, sense);
auto ec = f.create<IfcSchema::IfcEdgeCurve>();
ec.setEdgeStart(vertex1);
ec.setEdgeEnd(vertex2);
ec.setEdgeGeometry(curve);
ec.setSameSense(true);
auto ori = f.create<IfcSchema::IfcOrientedEdge>();
ori.setEdgeElement(ec);
ori.setOrientation(sense);
edge = ori;
return 1;
}
}
@@ -475,7 +505,7 @@ namespace {
}
template <>
int convert_to_ifc(const TopoDS_Wire& wire, IfcSchema::IfcLoop*& loop, bool advanced) {
int convert_to_ifc(IfcParse::IfcFile& f, const TopoDS_Wire& wire, IfcSchema::IfcLoop& loop, bool advanced) {
bool polygonal = true;
for (TopExp_Explorer exp(wire, TopAbs_EDGE); exp.More(); exp.Next()) {
double a, b;
@@ -491,25 +521,27 @@ int convert_to_ifc(const TopoDS_Wire& wire, IfcSchema::IfcLoop*& loop, bool adva
if (!polygonal && !advanced) {
return 0;
} else if (polygonal && !advanced) {
IfcSchema::IfcCartesianPoint::list::ptr points(new IfcSchema::IfcCartesianPoint::list);
std::vector<IfcSchema::IfcCartesianPoint> points;
BRepTools_WireExplorer exp(wire);
IfcSchema::IfcCartesianPoint* p;
IfcSchema::IfcCartesianPoint p;
for (; exp.More(); exp.Next()) {
if (convert_to_ifc(exp.CurrentVertex(), p, advanced)) {
points->push(p);
if (convert_to_ifc(f, exp.CurrentVertex(), p, advanced)) {
points.push_back(p);
} else {
return 0;
}
}
loop = new IfcSchema::IfcPolyLoop(points);
auto pl = f.create<IfcSchema::IfcPolyLoop>();
pl.setPolygon(points);
loop = pl;
return 1;
} else {
IfcSchema::IfcOrientedEdge::list::ptr edges(new IfcSchema::IfcOrientedEdge::list);
std::vector<IfcSchema::IfcOrientedEdge> edges;
BRepTools_WireExplorer exp(wire);
for (; exp.More(); exp.Next()) {
IfcSchema::IfcEdge* edge;
// With advanced set to true convert_to_ifc(TopoDS_Edge&) will always create an IfcOrientedEdge
if (!convert_to_ifc(exp.Current(), edge, true)) {
IfcSchema::IfcEdge edge;
// With advanced set to true convert_to_ifc(IfcParse::IfcFile& f, TopoDS_Edge&) will always create an IfcOrientedEdge
if (!convert_to_ifc(f, exp.Current(), edge, true)) {
double a, b;
if (BRep_Tool::Curve(TopoDS::Edge(exp.Current()), a, b).IsNull()) {
continue;
@@ -517,32 +549,37 @@ int convert_to_ifc(const TopoDS_Wire& wire, IfcSchema::IfcLoop*& loop, bool adva
return 0;
}
}
edges->push(edge->as<IfcSchema::IfcOrientedEdge>());
edges.push_back(edge.as<IfcSchema::IfcOrientedEdge>());
}
loop = new IfcSchema::IfcEdgeLoop(edges);
auto el = f.create<IfcSchema::IfcEdgeLoop>();
el.setEdgeList(edges);
loop = el;
return 1;
}
}
template <>
int convert_to_ifc(const TopoDS_Face& f, IfcSchema::IfcFace*& face, bool advanced) {
Handle_Geom_Surface surf = BRep_Tool::Surface(f);
TopExp_Explorer exp(f, TopAbs_WIRE);
IfcSchema::IfcFaceBound::list::ptr bounds(new IfcSchema::IfcFaceBound::list);
int convert_to_ifc(IfcParse::IfcFile& f, const TopoDS_Face& fa, IfcSchema::IfcFace& face, bool advanced) {
Handle_Geom_Surface surf = BRep_Tool::Surface(fa);
TopExp_Explorer exp(fa, TopAbs_WIRE);
std::vector<IfcSchema::IfcFaceBound> bounds;
int index = 0;
auto outer = BRepTools::OuterWire(f);
auto outer = BRepTools::OuterWire(fa);
for (; exp.More(); exp.Next(), ++index) {
IfcSchema::IfcLoop* loop;
if (!convert_to_ifc(TopoDS::Wire(exp.Current()), loop, advanced)) {
IfcSchema::IfcLoop loop;
if (!convert_to_ifc(f, TopoDS::Wire(exp.Current()), loop, advanced)) {
return 0;
}
IfcSchema::IfcFaceBound* bnd;
IfcSchema::IfcFaceBound bnd;
if (outer == exp.Current()) {
bnd = new IfcSchema::IfcFaceOuterBound(loop, true);
bnd = f.create<IfcSchema::IfcFaceOuterBound>();
} else {
bnd = new IfcSchema::IfcFaceBound(loop, true);
bnd = f.create<IfcSchema::IfcFaceBound>();
}
bounds->push(bnd);
bnd.setBound(loop);
bnd.setOrientation(true);
bounds.push_back(bnd);
}
const bool is_planar = surf->DynamicType() == STANDARD_TYPE(Geom_Plane);
@@ -551,15 +588,20 @@ int convert_to_ifc(const TopoDS_Face& f, IfcSchema::IfcFace*& face, bool advance
return 0;
}
if (is_planar && !advanced) {
face = new IfcSchema::IfcFace(bounds);
face = f.create<IfcSchema::IfcFace>();
face.setBounds(bounds);
return 1;
} else {
#ifdef SCHEMA_HAS_IfcAdvancedFace
IfcSchema::IfcSurface* surface;
if (!convert_to_ifc(surf, surface, advanced)) {
IfcSchema::IfcSurface surface;
if (!convert_to_ifc(f, surf, surface, advanced)) {
return 0;
}
face = new IfcSchema::IfcAdvancedFace(bounds, surface, f.Orientation() == TopAbs_FORWARD);
auto adv = f.create<IfcSchema::IfcAdvancedFace>();
adv.setBounds(bounds);
adv.setFaceSurface(surface);
adv.setSameSense(fa.Orientation() == TopAbs_FORWARD);
face = adv;
return 1;
#else
// No IfcAdvancedFace in Ifc2x3
@@ -569,30 +611,33 @@ int convert_to_ifc(const TopoDS_Face& f, IfcSchema::IfcFace*& face, bool advance
}
template <typename U>
int convert_to_ifc(const TopoDS_Shape& s, U*& item, bool advanced) {
IfcSchema::IfcFace::list::ptr faces(new IfcSchema::IfcFace::list);
IfcSchema::IfcFace* f;
int convert_to_ifc(IfcParse::IfcFile& f, const TopoDS_Shape& s, U& item, bool advanced) {
std::vector<IfcSchema::IfcFace> faces;
IfcSchema::IfcFace fa;
for (TopExp_Explorer exp(s, TopAbs_FACE); exp.More(); exp.Next()) {
if (convert_to_ifc(TopoDS::Face(exp.Current()), f, advanced)) {
faces->push(f);
if (convert_to_ifc(f, TopoDS::Face(exp.Current()), fa, advanced)) {
faces.push_back(fa);
} else {
/// Cleanup:
for (IfcSchema::IfcFace::list::it it = faces->begin(); it != faces->end(); ++it) {
aggregate_of_instance::ptr data = IfcParse::traverse(*it)->unique();
for (aggregate_of_instance::it jt = data->begin(); jt != data->end(); ++jt) {
delete *jt;
}
std::set<express::Base> created;
for (auto& face : faces) {
auto resources = f.traverse(face);
created.insert(resources.begin(), resources.end());
}
for (auto& c : created) {
f.removeEntity(c);
}
return 0;
}
}
item = new U(faces);
return faces->size();
item = f.create<U>();
item.setCfsFaces(faces);
return faces.size();
}
IfcUtil::IfcBaseClass* POSTFIX_SCHEMA(serialise)(const TopoDS_Shape& shape, bool advanced) {
express::Base POSTFIX_SCHEMA(serialise)(IfcParse::IfcFile& f, const TopoDS_Shape& shape, bool advanced) {
#ifndef SCHEMA_HAS_IfcAdvancedBrep
advanced = false;
@@ -600,25 +645,25 @@ IfcUtil::IfcBaseClass* POSTFIX_SCHEMA(serialise)(const TopoDS_Shape& shape, bool
for (TopExp_Explorer exp(shape, TopAbs_COMPSOLID); exp.More();) {
/// @todo CompSolids are not supported
return 0;
return express::Base{};
}
IfcSchema::IfcRepresentation* rep = 0;
IfcSchema::IfcRepresentationItem::list::ptr items(new IfcSchema::IfcRepresentationItem::list);
IfcSchema::IfcRepresentation rep;
std::vector<IfcSchema::IfcRepresentationItem> items;
// First check if there is a solid with one or more shells
for (TopExp_Explorer exp(shape, TopAbs_SOLID); exp.More(); exp.Next()) {
IfcSchema::IfcClosedShell* outer = 0;
IfcSchema::IfcClosedShell::list::ptr inner(new IfcSchema::IfcClosedShell::list);
IfcSchema::IfcClosedShell outer;
std::vector<IfcSchema::IfcClosedShell> inner;
for (TopExp_Explorer exp2(exp.Current(), TopAbs_SHELL); exp2.More(); exp2.Next()) {
IfcSchema::IfcClosedShell* shell;
if (!convert_to_ifc(exp2.Current(), shell, advanced)) {
return 0;
IfcSchema::IfcClosedShell shell;
if (!convert_to_ifc(f, exp2.Current(), shell, advanced)) {
return express::Base{};
}
/// @todo Are shells always in this order or does Orientation() needs to be checked?
/// > #4216, no, consider using BRepClass3d::OuterShell()
if (outer) {
inner->push(shell);
inner.push_back(shell);
} else {
outer = shell;
}
@@ -626,89 +671,129 @@ IfcUtil::IfcBaseClass* POSTFIX_SCHEMA(serialise)(const TopoDS_Shape& shape, bool
#ifdef SCHEMA_HAS_IfcAdvancedBrep
if (advanced) {
if (inner->size()) {
items->push(new IfcSchema::IfcAdvancedBrepWithVoids(outer, inner));
if (inner.size()) {
auto inst = f.create<IfcSchema::IfcAdvancedBrepWithVoids>();
inst.setOuter(outer);
inst.setVoids(inner);
items.push_back(inst);
} else {
items->push(new IfcSchema::IfcAdvancedBrep(outer));
auto inst = f.create<IfcSchema::IfcAdvancedBrep>();
inst.setOuter(outer);
items.push_back(inst);
}
} else
#endif
/// @todo this is not necessarily correct as the shell is not necessarily facetted.
if (inner->size()) {
items->push(new IfcSchema::IfcFacetedBrepWithVoids(outer, inner));
if (inner.size()) {
auto inst = f.create<IfcSchema::IfcFacetedBrepWithVoids>();
inst.setOuter(outer);
inst.setVoids(inner);
items.push_back(inst);
} else {
items->push(new IfcSchema::IfcFacetedBrep(outer));
auto inst = f.create<IfcSchema::IfcFacetedBrep>();
inst.setOuter(outer);
items.push_back(inst);
}
}
if (items->size() > 0) {
rep = new IfcSchema::IfcShapeRepresentation(0, std::string("Body"), advanced ? std::string("AdvancedBrep") : std::string("Brep"), items);
if (items.size() > 0) {
auto srep = f.create<IfcSchema::IfcShapeRepresentation>();
srep.setRepresentationIdentifier("Body");
srep.setRepresentationType(advanced ? "AdvancedBrep" : "Brep");
srep.setItems(items);
rep = srep;
} else {
// If not, see if there is a shell
IfcSchema::IfcShell::list::ptr shells(new IfcSchema::IfcShell::list);
std::vector<IfcSchema::IfcShell> shells;
for (TopExp_Explorer exp(shape, TopAbs_SHELL); exp.More(); exp.Next()) {
IfcSchema::IfcOpenShell* shell;
if (!convert_to_ifc(exp.Current(), shell, advanced)) {
return 0;
IfcSchema::IfcOpenShell shell;
if (!convert_to_ifc(f, exp.Current(), shell, advanced)) {
return express::Base{};
}
shells->push(shell);
shells.push_back(shell);
}
if (shells->size() > 0) {
items->push(new IfcSchema::IfcShellBasedSurfaceModel(shells));
rep = new IfcSchema::IfcShapeRepresentation(0, std::string("Body"), advanced ? std::string("AdvancedBrep") : std::string("Brep"), items);
if (shells.size() > 0) {
auto inst = f.create<IfcSchema::IfcShellBasedSurfaceModel>();
inst.setSbsmBoundary(shells);
items.push_back(inst);
auto srep = f.create<IfcSchema::IfcShapeRepresentation>();
srep.setRepresentationIdentifier("Body");
srep.setRepresentationType(advanced ? "AdvancedBrep" : "Brep");
srep.setItems(items);
rep = srep;
} else {
// If not, see if there is are one of more faces. Note that they will be grouped into a shell.
IfcSchema::IfcOpenShell* shell;
int face_count = convert_to_ifc(shape, shell, advanced);
IfcSchema::IfcOpenShell shell;
int face_count = convert_to_ifc(f, shape, shell, advanced);
if (face_count > 0) {
items->push(shell);
rep = new IfcSchema::IfcShapeRepresentation(0, std::string("Body"), advanced ? std::string("AdvancedBrep") : std::string("Brep"), items);
items.push_back(shell);
auto srep = f.create<IfcSchema::IfcShapeRepresentation>();
srep.setRepresentationIdentifier("Body");
srep.setRepresentationType(advanced ? "AdvancedBrep" : "Brep");
srep.setItems(items);
rep = srep;
} else {
// If not, see if there are any edges. Note that wires are skipped as
// they are not commonly top-level geometrical descriptions in IFC.
// Also note that edges are written as trimmed curves rather than edges.
aggregate_of_instance::ptr edges(new aggregate_of_instance);
std::vector<express::Entity> edges;
for (TopExp_Explorer exp(shape, TopAbs_EDGE); exp.More(); exp.Next()) {
IfcSchema::IfcCurve* c;
if (!convert_to_ifc(TopoDS::Edge(exp.Current()), c, advanced)) {
return 0;
IfcSchema::IfcCurve c;
if (!convert_to_ifc(f, TopoDS::Edge(exp.Current()), c, advanced)) {
return express::Base{};
}
edges->push(c);
edges.push_back(c);
}
if (edges->size() == 0) {
return 0;
} else if (edges->size() == 1) {
rep = new IfcSchema::IfcShapeRepresentation(0, std::string("Axis"), std::string("Curve2D"), edges->as<IfcSchema::IfcRepresentationItem>());
if (edges.size() == 0) {
return express::Base{};
} else if (edges.size() == 1) {
auto srep = f.create<IfcSchema::IfcShapeRepresentation>();
srep.setRepresentationIdentifier("Axis");
srep.setRepresentationType("Curve2D");
srep.setItems(cast_vector<IfcSchema::IfcRepresentationItem>(edges));
rep = srep;
} else {
// A geometric set is created as that probably (?) makes more sense in IFC
IfcSchema::IfcGeometricCurveSet* curves = new IfcSchema::IfcGeometricCurveSet(edges->as<IfcSchema::IfcGeometricSetSelect>());
items->push(curves);
rep = new IfcSchema::IfcShapeRepresentation(0, std::string("Axis"), std::string("GeometricCurveSet"), items->as<IfcSchema::IfcRepresentationItem>());
auto curves = f.create<IfcSchema::IfcGeometricCurveSet>();
curves.setElements(cast_vector<IfcSchema::IfcGeometricSetSelect>(edges));
items.push_back(curves);
auto srep = f.create<IfcSchema::IfcShapeRepresentation>();
srep.setRepresentationIdentifier("Axis");
srep.setRepresentationType("GeometricCurveSet");
srep.setItems(items);
rep = srep;
}
}
}
}
IfcSchema::IfcRepresentation::list::ptr reps(new IfcSchema::IfcRepresentation::list);
reps->push(rep);
return new IfcSchema::IfcProductDefinitionShape(boost::none, boost::none, reps);
auto pds = f.create<IfcSchema::IfcProductDefinitionShape>();
pds.setRepresentations({rep});
return pds;
}
IfcUtil::IfcBaseClass* POSTFIX_SCHEMA(tesselate)(const TopoDS_Shape& shape, double deflection) {
express::Base POSTFIX_SCHEMA(tesselate)(IfcParse::IfcFile& f, const TopoDS_Shape& shape, double deflection) {
// @todo use triangulated face set in ifc4+ schema
BRepMesh_IncrementalMesh(shape, deflection);
IfcSchema::IfcFace::list::ptr faces(new IfcSchema::IfcFace::list);
std::vector<IfcSchema::IfcFace> faces;
for (TopExp_Explorer exp(shape, TopAbs_FACE); exp.More(); exp.Next()) {
const TopoDS_Face& face = TopoDS::Face(exp.Current());
@@ -716,45 +801,45 @@ IfcUtil::IfcBaseClass* POSTFIX_SCHEMA(tesselate)(const TopoDS_Shape& shape, doub
Handle(Poly_Triangulation) tri = BRep_Tool::Triangulation(face, loc);
if (!tri.IsNull()) {
std::vector<IfcSchema::IfcCartesianPoint*> vertices;
std::vector<IfcSchema::IfcCartesianPoint> vertices;
for (int i = 1; i <= tri->NbNodes(); ++i) {
gp_Pnt pnt = tri->Node(i).Transformed(loc);
std::vector<double> xyz; xyz.push_back(pnt.X()); xyz.push_back(pnt.Y()); xyz.push_back(pnt.Z());
IfcSchema::IfcCartesianPoint* cpnt = new IfcSchema::IfcCartesianPoint(xyz);
IfcSchema::IfcCartesianPoint cpnt = f.create<IfcSchema::IfcCartesianPoint>();
cpnt.setCoordinates(xyz);
vertices.push_back(cpnt);
}
const Poly_Array1OfTriangle& triangles = tri->Triangles();
for (int i = 1; i <= triangles.Length(); ++i) {
int n1, n2, n3;
triangles(i).Get(n1, n2, n3);
IfcSchema::IfcCartesianPoint::list::ptr points(new IfcSchema::IfcCartesianPoint::list);
points->push(vertices[n1 - 1]);
points->push(vertices[n2 - 1]);
points->push(vertices[n3 - 1]);
IfcSchema::IfcPolyLoop* loop = new IfcSchema::IfcPolyLoop(points);
IfcSchema::IfcFaceOuterBound* bound = new IfcSchema::IfcFaceOuterBound(loop, face.Orientation() != TopAbs_REVERSED);
IfcSchema::IfcFaceBound::list::ptr bounds(new IfcSchema::IfcFaceBound::list);
bounds->push(bound);
IfcSchema::IfcFace* face2 = new IfcSchema::IfcFace(bounds);
faces->push(face2);
std::vector<IfcSchema::IfcCartesianPoint> points {
vertices[n1 - 1], vertices[n2 - 1], vertices[n3 - 1]
};
IfcSchema::IfcPolyLoop loop = f.create<IfcSchema::IfcPolyLoop>();
loop.setPolygon(points);
IfcSchema::IfcFaceOuterBound bound = f.create<IfcSchema::IfcFaceOuterBound>();
bound.setBound(loop);
bound.setOrientation(face.Orientation() != TopAbs_REVERSED);
IfcSchema::IfcFace face2 = f.create<IfcSchema::IfcFace>();
face2.setBounds({bound});
faces.push_back(face2);
}
}
}
IfcSchema::IfcOpenShell* shell = new IfcSchema::IfcOpenShell(faces);
IfcSchema::IfcConnectedFaceSet::list::ptr shells(new IfcSchema::IfcConnectedFaceSet::list);
shells->push(shell);
IfcSchema::IfcFaceBasedSurfaceModel* surface_model = new IfcSchema::IfcFaceBasedSurfaceModel(shells);
auto shell = f.create<IfcSchema::IfcOpenShell>();
shell.setCfsFaces(faces);
IfcSchema::IfcRepresentation::list::ptr reps(new IfcSchema::IfcRepresentation::list);
IfcSchema::IfcRepresentationItem::list::ptr items(new IfcSchema::IfcRepresentationItem::list);
auto surface_model = f.create<IfcSchema::IfcFaceBasedSurfaceModel>();
surface_model.setFbsmFaces({shell});
items->push(surface_model);
auto rep = f.create<IfcSchema::IfcShapeRepresentation>();
rep.setRepresentationIdentifier("Tessellation");
rep.setRepresentationType("SurfaceModel");
rep.setItems({surface_model});
IfcSchema::IfcShapeRepresentation* rep = new IfcSchema::IfcShapeRepresentation(
0, std::string("Facetation"), std::string("SurfaceModel"), items);
reps->push(rep);
IfcSchema::IfcProductDefinitionShape* shapedef = new IfcSchema::IfcProductDefinitionShape(boost::none, boost::none, reps);
auto shapedef = f.create<IfcSchema::IfcProductDefinitionShape>();
shapedef.setRepresentations({rep});
return shapedef;
}
+3 -3
View File
@@ -86,14 +86,14 @@ void IfcGeom::set_default_style_file(const std::string& json_file) {
default_materials.insert(std::make_pair(name, std::make_shared<ifcopenshell::geometry::taxonomy::style>(name)));
pt::ptree material = material_pair.second;
boost::optional<pt::ptree&> diffuse = material.get_child_optional("diffuse");
auto diffuse = material.get_child_optional("diffuse");
default_materials[name]->diffuse = read_colour_component(diffuse);
// @todo Is it necessary to get the surface too?
// boost::optional<pt::ptree&> surface = material.get_child_optional("surface");
// std::optional<pt::ptree&> surface = material.get_child_optional("surface");
// default_materials[name]->surface = read_colour_component(surface);
boost::optional<pt::ptree&> specular = material.get_child_optional("specular");
auto specular = material.get_child_optional("specular");
default_materials[name]->specular = read_colour_component(specular);
if (material.get_child_optional("specular-roughness")) {
+17 -15
View File
@@ -20,8 +20,7 @@
#ifndef ABSTRACT_MAPPING_H
#define ABSTRACT_MAPPING_H
#include "../ifcparse/IfcBaseClass.h"
#include "../ifcparse/aggregate_of_instance.h"
#include "../ifcparse/express.h"
#include "../ifcgeom/taxonomy.h"
#include "../ifcgeom/ConversionSettings.h"
@@ -37,11 +36,14 @@ namespace geometry {
struct IFC_GEOM_API geometry_conversion_task {
int index;
IfcUtil::IfcBaseEntity* representation;
aggregate_of_instance::ptr products;
express::Base representation;
std::vector<express::Base> products;
};
typedef boost::function<bool(IfcUtil::IfcBaseEntity*)> filter_t;
/// The filter function (free or member function) or function object (use boost::ref() to reference to it)
/// should return true if the geometry for the product is wanted to be included in the output.
/// http://www.boost.org/doc/libs/1_62_0/doc/html/function/tutorial.html
typedef boost::function<bool(const express::Base&)> filter_t;
class IFC_GEOM_API abstract_mapping {
protected:
@@ -53,19 +55,19 @@ namespace geometry {
abstract_mapping(Settings& s) : settings_(s) {}
virtual ~abstract_mapping() {}
virtual ifcopenshell::geometry::taxonomy::ptr map(const IfcUtil::IfcBaseInterface*) = 0;
virtual void get_representations(std::vector<geometry_conversion_task>& tasks, std::vector<filter_t>& filters) = 0;
virtual IfcUtil::IfcBaseEntity* get_decomposing_entity(const IfcUtil::IfcBaseEntity* product, bool include_openings = true) = 0;
virtual std::map<std::string, IfcUtil::IfcBaseEntity*> get_layers(IfcUtil::IfcBaseEntity*) = 0;
virtual aggregate_of_instance::ptr find_openings(const IfcUtil::IfcBaseEntity*) = 0;
virtual ifcopenshell::geometry::taxonomy::ptr map(const express::Base&) = 0;
virtual void get_representations(std::vector<geometry_conversion_task>& tasks, std::vector<filter_t>& filters) = 0;
virtual express::Base get_decomposing_entity(const express::Base& product, bool include_openings = true) = 0;
virtual std::map<std::string, express::Base> get_layers(const express::Base&) = 0;
virtual std::vector<express::Base> find_openings(const express::Base&) = 0;
virtual void initialize_settings() = 0;
virtual bool get_layerset_information(const IfcUtil::IfcBaseInterface*, layerset_information&, int&) = 0;
virtual bool get_wall_neighbours(const IfcUtil::IfcBaseInterface*, std::vector<endpoint_connection>&) = 0;
virtual const IfcUtil::IfcBaseEntity* get_product_type(const IfcUtil::IfcBaseEntity*) = 0;
virtual const IfcUtil::IfcBaseEntity* get_single_material_association(const IfcUtil::IfcBaseEntity*) = 0;
virtual bool get_layerset_information(const express::Base&, layerset_information&, int&) = 0;
virtual bool get_wall_neighbours(const express::Base&, std::vector<endpoint_connection>&) = 0;
virtual const express::Base get_product_type(const express::Base&) = 0;
virtual const express::Base get_single_material_association(const express::Base&) = 0;
virtual double get_length_unit() const = 0;
virtual const std::string& get_length_unit_name() const = 0;
virtual IfcUtil::IfcBaseEntity* representation_of(const IfcUtil::IfcBaseEntity* product) = 0;
virtual express::Base representation_of(const express::Base& product) = 0;
const Settings& settings() const { return settings_; }
Settings& settings() { return settings_; }
+1 -1
View File
@@ -76,7 +76,7 @@ class IFC_GEOM_API function_item_evaluator {
taxonomy::item::ptr evaluate(const std::vector<double>& dist) const;
fn_evaluator* fn_evaluator_ = nullptr;
mutable boost::optional<std::vector<double>> eval_points_; // cache evaluation points
mutable std::optional<std::vector<double>> eval_points_; // cache evaluation points
};
}}
+4 -4
View File
@@ -82,8 +82,8 @@ namespace ifcopenshell {
}
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();
auto ops = mapping_->find_openings(item->instance);
bool has_openings = ops.size();
for (auto& k : kernels_) {
#ifdef IFOPSH_WITH_CGAL
if (has_openings && !k->supports_boolean_operations()) {
@@ -119,7 +119,7 @@ namespace ifcopenshell {
}
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)
virtual bool apply_folded_layerset(IfcGeom::ConversionResults& items, const ifcopenshell::geometry::layerset_information& layers, const std::map<express::Base, ifcopenshell::geometry::layerset_information>& folds)
{
for (auto& k : kernels_) {
bool success = false;
@@ -132,7 +132,7 @@ namespace ifcopenshell {
}
return false;
}
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 express::Base& 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_) {
+15 -15
View File
@@ -1,4 +1,4 @@
#include "profile_helper.h"
#include "profile_helper.h"
#include "infra_sweep_helper.h"
#include "function_item_evaluator.h"
@@ -35,7 +35,7 @@ bool has_intersection(const std::set<T, Cmp>& A,
}
taxonomy::loft::ptr ifcopenshell::geometry::make_loft(const Settings& settings_, const IfcUtil::IfcBaseClass* inst, const taxonomy::function_item::ptr& fn, std::vector<cross_section>& cross_sections)
taxonomy::loft::ptr ifcopenshell::geometry::make_loft(const Settings& settings_, const express::Base inst, const taxonomy::function_item::ptr& fn, std::vector<cross_section>& cross_sections)
{
std::sort(cross_sections.begin(), cross_sections.end());
@@ -98,12 +98,12 @@ taxonomy::loft::ptr ifcopenshell::geometry::make_loft(const Settings& settings_,
(profile_index + 1 < longitudes.end()) &&
(relative_dist_along >= 1.e-9 || offset_a.cwiseAbs().maxCoeff() > 0. || rotation_a);
boost::optional<Eigen::Matrix3d> interpolated_rotation;
std::optional<Eigen::Matrix3d> interpolated_rotation;
if (should_interpolate) {
taxonomy::geom_item::ptr profile_b;
Eigen::Vector3d offset_b;
boost::optional<Eigen::Matrix3d> rotation_b;
std::optional<Eigen::Matrix3d> rotation_b;
if ((profile_index + 1 < longitudes.end())) {
profile_b = cross_sections[std::distance(longitudes.begin(), profile_index) + 1].section_geometry;
offset_b = cross_sections[std::distance(longitudes.begin(), profile_index) + 1].offset;
@@ -180,7 +180,7 @@ taxonomy::loft::ptr ifcopenshell::geometry::make_loft(const Settings& settings_,
return nullptr;
}
if (w1->tags.is_initialized() != w2->tags.is_initialized()) {
if (w1->tags.has_value() != w2->tags.has_value()) {
Logger::Warning("Mismatching availability tags on loops", inst);
return nullptr;
}
@@ -211,21 +211,21 @@ taxonomy::loft::ptr ifcopenshell::geometry::make_loft(const Settings& settings_,
std::map<std::string, taxonomy::point3::ptr> tag_to_point_on_w1, tag_to_point_on_w2;
auto loop_to_points = [](const taxonomy::loop::ptr& loop, const boost::optional<std::vector<std::string>>& input_tags) -> std::pair<std::vector<taxonomy::point3::ptr>, std::vector<std::set<std::string>>> {
auto loop_to_points = [](const taxonomy::loop::ptr& loop, const std::optional<std::vector<std::string>>& input_tags) -> std::pair<std::vector<taxonomy::point3::ptr>, std::vector<std::set<std::string>>> {
std::vector<taxonomy::point3::ptr> points;
std::vector<std::set<std::string>> tags;
std::vector<std::string>::const_iterator tag_it;
if (!loop->closed.get_value_or(false)) {
points = {boost::get<taxonomy::point3::ptr>(loop->children[0]->start)};
if (!loop->closed.value_or(false)) {
points = {std::get<taxonomy::point3::ptr>(loop->children[0]->start)};
if (input_tags) {
tags = {{input_tags->front()}};
tag_it = ++input_tags->begin();
}
}
for (auto& e : loop->children) {
const auto& p1 = boost::get<taxonomy::point3::ptr>(e->start);
const auto& p2 = boost::get<taxonomy::point3::ptr>(e->end);
const auto& p1 = std::get<taxonomy::point3::ptr>(e->start);
const auto& p2 = std::get<taxonomy::point3::ptr>(e->end);
if (input_tags && p1->ccomponents() == p2->ccomponents()) {
tags.back().insert(*tag_it);
++tag_it;
@@ -239,7 +239,7 @@ taxonomy::loft::ptr ifcopenshell::geometry::make_loft(const Settings& settings_,
}
}
if (!input_tags) {
if (loop->closed.get_value_or(false)) {
if (loop->closed.value_or(false)) {
// close polygon by referencing first point
points.push_back(points.front());
}
@@ -365,13 +365,13 @@ taxonomy::loft::ptr ifcopenshell::geometry::make_loft(const Settings& settings_,
/*
// This is handled in the loop_to_points() function above
if (!points.empty()) {
if (!w1->closed.get_value_or(true) && !w2->closed.get_value_or(true)) {
if (!w1->closed.value_or(true) && !w2->closed.value_or(true)) {
// open polygon, add last point
auto& p1 = boost::get<taxonomy::point3::ptr>(w1->children.back()->end);
auto& p2 = boost::get<taxonomy::point3::ptr>(w2->children.back()->end);
auto& p1 = std::get<taxonomy::point3::ptr>(w1->children.back()->end);
auto& p2 = std::get<taxonomy::point3::ptr>(w2->children.back()->end);
auto p3 = (lerp(p1->ccomponents(), p2->ccomponents(), relative_dist_along) + interpolated_offset).eval();
points.push_back(taxonomy::make<taxonomy::point3>(p3));
} else if (w1->closed.get_value_or(true) && w2->closed.get_value_or(true)) {
} else if (w1->closed.value_or(true) && w2->closed.value_or(true)) {
// close polygon by referencing first point
// @todo add a closed=true|false to polygon_from_points()?
points.push_back(points.front());
+2 -2
View File
@@ -14,14 +14,14 @@ namespace ifcopenshell {
double dist_along;
taxonomy::geom_item::ptr section_geometry;
Eigen::Vector3d offset;
boost::optional<Eigen::Matrix3d> rotation;
std::optional<Eigen::Matrix3d> rotation;
bool operator <(const cross_section& other) const {
return dist_along < other.dist_along;
}
};
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);
IFC_GEOM_API taxonomy::loft::ptr make_loft(const Settings& settings_, const express::Base inst, const taxonomy::function_item::ptr& directrix, std::vector<cross_section>& cross_sections);
}
}
@@ -223,7 +223,7 @@ void ifcopenshell::geometry::CgalShape::Triangulate(ifcopenshell::geometry::Sett
}
}
boost::optional<double> smooth_treshold;
std::optional<double> smooth_treshold;
{
auto setting_value = settings.get<ifcopenshell::geometry::settings::CgalSmoothAngleDegrees>().get();
if (setting_value > 0.) {
@@ -180,9 +180,9 @@ namespace ifcopenshell { namespace geometry {
class IFC_GEOMLIBRARY_API CgalShape : public IfcGeom::ConversionResultShape {
private:
bool convex_tag_ = false;
mutable boost::optional<cgal_shape_t> shape_;
mutable std::optional<cgal_shape_t> shape_;
#ifndef IFOPSH_SIMPLE_KERNEL
mutable boost::optional<CGAL::Nef_polyhedron_3<Kernel_>> nef_;
mutable std::optional<CGAL::Nef_polyhedron_3<Kernel_>> nef_;
#endif
public:
CgalShape(const cgal_shape_t& shape, bool convex = false);
+32 -32
View File
@@ -47,7 +47,7 @@ namespace {
private:
std::list<cgal_face_t> *face_list;
public:
boost::optional<cgal_shape_t> from_soup;
std::optional<cgal_shape_t> from_soup;
PolyhedronBuilder(std::list<cgal_face_t> *face_list);
void operator()(CGAL::Polyhedron_3<Kernel_>::HalfedgeDS &hds);
};
@@ -232,7 +232,7 @@ bool CgalKernel::convert(const taxonomy::face::ptr face, std::list<cgal_face_t>&
int num_outer_bounds = 0;
for (auto& bound : face->children) {
if (bound->external.get_value_or(false)) num_outer_bounds++;
if (bound->external.value_or(false)) num_outer_bounds++;
}
if (face->children.size() > 1 && num_outer_bounds > 1 && face->children.size() != num_outer_bounds) {
@@ -244,7 +244,7 @@ bool CgalKernel::convert(const taxonomy::face::ptr face, std::list<cgal_face_t>&
for (auto& bound : face->children) {
const bool is_interior = !(bound->external.get_value_or(false) || face->children.size() == 1);
const bool is_interior = !(bound->external.value_or(false) || face->children.size() == 1);
// single face bound is always external... even if not marked as such
cgal_wire_t wire;
@@ -284,11 +284,11 @@ namespace {
if (auto e = taxonomy::dcast<taxonomy::edge>(curve)) {
if (true || e->basis == nullptr) {
if (builder.empty()) {
const auto& p = boost::get<taxonomy::point3::ptr>(e->start);
const auto& p = std::get<taxonomy::point3::ptr>(e->start);
cgal_point_t pnt(p->ccomponents()(0), p->ccomponents()(1), p->ccomponents()(2));
builder.push_back(pnt);
}
const auto& p = boost::get<taxonomy::point3::ptr>(e->end);
const auto& p = std::get<taxonomy::point3::ptr>(e->end);
cgal_point_t pnt(p->ccomponents()(0), p->ccomponents()(1), p->ccomponents()(2));
builder.push_back(pnt);
} else if (e->basis->kind() == taxonomy::CIRCLE) {
@@ -450,17 +450,17 @@ namespace {
void operator()(const taxonomy::trimmed_curve::ptr& e) {
auto e_basis = e->basis;
while (e_basis->kind() == taxonomy::EDGE && e_basis->instance && e_basis->instance->declaration().name() == "IfcTrimmedCurve") {
while (e_basis->kind() == taxonomy::EDGE && e_basis->instance && e_basis->instance.declaration().name() == "IfcTrimmedCurve") {
// @todo we still might have something to wrt orientation on periodic curves
// to make sure we select the correct arc later on.
e_basis = taxonomy::cast<taxonomy::edge>(e_basis)->basis;
}
point_projection_visitor v1{ e->basis }, v2{ e->basis };
boost::apply_visitor(v1, e->start);
boost::apply_visitor(v2, e->end);
std::visit(v1, e->start);
std::visit(v2, e->end);
if (!e->curve_sense.get_value_or(true)) {
if (!e->curve_sense.value_or(true)) {
std::swap(v1.u, v2.u);
}
@@ -469,7 +469,7 @@ namespace {
dispatch_curve_creation<cgal_curve_creation_visitor>::dispatch(e->basis, v);
this->points = v.points;
if (!e->curve_sense.get_value_or(true)) {
if (!e->curve_sense.value_or(true)) {
std::reverse(this->points.begin(), this->points.end());
}
}
@@ -581,7 +581,7 @@ namespace {
CGAL::Polygon_2<Kernel_> loop_to_polygon_2(taxonomy::loop::ptr loop) {
CGAL::Polygon_2<Kernel_> polygon;
for (auto& e : loop->children) {
auto& p = *boost::get<taxonomy::point3::ptr>(e->start);
auto& p = *std::get<taxonomy::point3::ptr>(e->start);
CGAL::Point_2<Kernel_> pnt(p.ccomponents()(0), p.ccomponents()(1));
polygon.push_back(pnt);
}
@@ -685,12 +685,12 @@ bool CgalKernel::convert(const taxonomy::loop::ptr loop, cgal_wire_t& result) {
convert_curve(settings_, e, edge);
} else {
edge = {
*boost::get<taxonomy::point3::ptr>(e->start),
*boost::get<taxonomy::point3::ptr>(e->end)
*std::get<taxonomy::point3::ptr>(e->start),
*std::get<taxonomy::point3::ptr>(e->end)
};
}
if (!e->orientation.get_value_or(true)) {
if (!e->orientation.value_or(true)) {
std::reverse(edge.begin(), edge.end());
}
@@ -809,7 +809,7 @@ bool CgalKernel::convert_impl(const taxonomy::shell::ptr shell, ConversionResult
return false;
}
results.emplace_back(ConversionResult(
shell->instance->as<IfcUtil::IfcBaseEntity>()->id(),
shell->instance.id(),
shell->matrix,
new CgalShape(shape),
shell->surface_style
@@ -834,7 +834,7 @@ bool CgalKernel::convert_impl(const taxonomy::solid::ptr solid, ConversionResult
return false;
}
results.emplace_back(ConversionResult(
solid->instance->as<IfcUtil::IfcBaseEntity>()->id(),
solid->instance.id(),
solid->matrix,
new CgalShape(shape),
solid->surface_style
@@ -857,7 +857,7 @@ namespace {
}
}
bool ifcopenshell::geometry::kernels::CgalKernel::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)
bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const express::Base& 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)
{
#ifdef IFOPSH_SIMPLE_KERNEL
return false;
@@ -865,9 +865,9 @@ bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const IfcUtil
CGAL::Nef_nary_union_3<CGAL::Nef_polyhedron_3<Kernel_>> second_operand_collector;
size_t second_operand_collector_size = 0;
std::list<std::pair<const IfcUtil::IfcBaseClass*, std::list<cgal_shape_t>>> operands;
std::list<std::pair<express::Base, std::list<cgal_shape_t>>> operands;
std::list<const IfcUtil::IfcBaseClass*> second_operand_instances;
std::list<express::Base> second_operand_instances;
std::list<cgal_shape_t> first_operands, second_operands;
std::list<CGAL::Nef_polyhedron_3<Kernel_>> first_operands_nef, second_operands_nef;
@@ -916,13 +916,13 @@ bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const IfcUtil
}
}
CGAL::Nef_polyhedron_3<Kernel_> nef;
if (!preprocess_boolean_operand(op.first->instance->as<IfcUtil::IfcBaseClass>(), {}, {}, {}, entity_shape, nef, PP_NONE)) {
if (!preprocess_boolean_operand(op.first->instance, {}, {}, {}, entity_shape, nef, PP_NONE)) {
continue;
}
// auto tree = build_halfspace_tree_decomposed(nef, all_operand_planes);
second_operand_instances.push_back(op.first->instance->as<IfcUtil::IfcBaseClass>());
second_operand_instances.push_back(op.first->instance);
second_operands.push_back(entity_shape);
second_operands_nef.push_back(nef);
}
@@ -984,7 +984,7 @@ bool CgalKernel::convert_impl(const taxonomy::extrusion::ptr extrusion, Conversi
return false;
}
results.emplace_back(ConversionResult(
extrusion->instance->as<IfcUtil::IfcBaseEntity>()->id(),
extrusion->instance.id(),
extrusion->matrix,
new CgalShape(shape),
extrusion->surface_style
@@ -1321,7 +1321,7 @@ bool CgalKernel::thin_solid(const CGAL::Nef_polyhedron_3<Kernel_>& a, CGAL::Nef_
return true;
}
bool CgalKernel::preprocess_boolean_operand(const IfcUtil::IfcBaseClass* log_reference, const std::list<cgal_shape_t>& first_operands, const std::list<CGAL::Nef_polyhedron_3<Kernel_>>& first_operands_nef, const std::list<Kernel_::Plane_3>& all_operand_planes, const cgal_shape_t& shape_const, CGAL::Nef_polyhedron_3<Kernel_>& result, boolean_operand_preprocess proc) {
bool CgalKernel::preprocess_boolean_operand(const express::Base& log_reference, const std::list<cgal_shape_t>& first_operands, const std::list<CGAL::Nef_polyhedron_3<Kernel_>>& first_operands_nef, const std::list<Kernel_::Plane_3>& all_operand_planes, const cgal_shape_t& shape_const, CGAL::Nef_polyhedron_3<Kernel_>& result, boolean_operand_preprocess proc) {
cgal_shape_t shape = shape_const;
if (!shape.is_valid()) {
@@ -1727,7 +1727,7 @@ namespace {
}
}
bool CgalKernel::process_as_2d_polygon(const std::list<std::list<std::pair<const IfcUtil::IfcBaseClass*, cgal_shape_t>>>& operands, std::list<CGAL::Polygon_2<Kernel_>>& loops, double& z0, double& z1) {
bool CgalKernel::process_as_2d_polygon(const std::list<std::list<std::pair<express::Base, cgal_shape_t>>>& operands, std::list<CGAL::Polygon_2<Kernel_>>& loops, double& z0, double& z1) {
if (operands.front().size() != 1) {
return false;
}
@@ -1887,7 +1887,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion
}
return ConversionResult(
br->instance->as<IfcUtil::IfcBaseEntity>()->id(),
br->instance.id(),
br->matrix,
new CgalShape(shp),
br->surface_style ? br->surface_style : first_item_style
@@ -1912,7 +1912,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion
taxonomy::style::ptr first_item_style = nullptr;
std::list<std::pair<const IfcUtil::IfcBaseClass*, std::list<cgal_shape_t>>> operands;
std::list<std::pair<express::Base, std::list<cgal_shape_t>>> operands;
for (auto& c : br->children) {
// AbstractKernel::convert(c, results);
@@ -1921,9 +1921,9 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion
ConversionResults cr;
operands.emplace_back();
operands.back().first = c->instance->as<IfcUtil::IfcBaseClass>();
operands.back().first = c->instance;
if (c->kind() == taxonomy::SOLID && c->instance->declaration().is("IfcHalfSpaceSolid") && !first) {
if (c->kind() == taxonomy::SOLID && c->instance.declaration().is("IfcHalfSpaceSolid") && !first) {
auto face = taxonomy::cast<taxonomy::solid>(c)->children[0]->children[0];
if (face->basis == nullptr || face->basis->kind() != taxonomy::PLANE) {
@@ -1951,7 +1951,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion
});
double wmin, wmax;
if (face->orientation.get_value_or(false)) {
if (face->orientation.value_or(false)) {
wmin = 0.;
wmax = uvw_max[2] + eps;
} else {
@@ -2043,7 +2043,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion
for (auto& li : operands) {
for (auto& s : li.second) {
results.emplace_back(ConversionResult(
br->instance->data().id(),
br->instance.data().id(),
br->matrix,
new CgalShape(s),
br->surface_style ? br->surface_style : first_item_style
@@ -2065,7 +2065,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion
for (auto& p : operands) {
for (auto& s : p.second) {
results.emplace_back(ConversionResult(
br->instance->data().id(),
br->instance.data().id(),
br->matrix,
new CgalShape(s),
br->surface_style ? br->surface_style : first_item_style
@@ -2131,7 +2131,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion
}
results.emplace_back(ConversionResult(
br->instance->as<IfcUtil::IfcBaseEntity>()->id(),
br->instance.id(),
br->matrix,
new CgalShape(a_poly),
br->surface_style ? br->surface_style : first_item_style
+3 -3
View File
@@ -80,7 +80,7 @@ namespace ifcopenshell {
PP_NONE
};
bool preprocess_boolean_operand(const IfcUtil::IfcBaseClass* log_reference, const std::list<cgal_shape_t>& first_operands, const std::list<CGAL::Nef_polyhedron_3<Kernel_>>& first_operands_nef, const std::list<Kernel_::Plane_3>& all_operand_planes, const cgal_shape_t& shape_const, CGAL::Nef_polyhedron_3<Kernel_>& result, boolean_operand_preprocess proc);
bool preprocess_boolean_operand(const express::Base& log_reference, const std::list<cgal_shape_t>& first_operands, const std::list<CGAL::Nef_polyhedron_3<Kernel_>>& first_operands_nef, const std::list<Kernel_::Plane_3>& all_operand_planes, const cgal_shape_t& shape_const, CGAL::Nef_polyhedron_3<Kernel_>& result, boolean_operand_preprocess proc);
bool thin_solid(const CGAL::Nef_polyhedron_3<Kernel_>& a, CGAL::Nef_polyhedron_3<Kernel_>& result);
@@ -115,14 +115,14 @@ namespace ifcopenshell {
bool process_extrusion(const cgal_face_t& bottom_face, taxonomy::direction3::ptr direction, double height, cgal_shape_t& shape);
bool process_as_2d_polygon(const taxonomy::boolean_result::ptr br, std::list<CGAL::Polygon_2<Kernel_>>& loops, double& z0, double& z1);
bool process_as_2d_polygon(const std::list<std::list<std::pair<const IfcUtil::IfcBaseClass*, cgal_shape_t>>>& operands, std::list<CGAL::Polygon_2<Kernel_>>& loops, double& z0, double& z1);
bool process_as_2d_polygon(const std::list<std::list<std::pair<express::Base, cgal_shape_t>>>& operands, std::list<CGAL::Polygon_2<Kernel_>>& loops, double& z0, double& z1);
virtual bool convert_impl(const taxonomy::shell::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::extrusion::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::boolean_result::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::solid::ptr, IfcGeom::ConversionResults&);
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 express::Base& 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);
#ifndef IFOPSH_SIMPLE_KERNEL
@@ -621,7 +621,7 @@ struct Intersection_visitor {
template <typename Kernel>
struct Segment_collector {
typedef void result_type;
boost::optional<CGAL::Segment_3<Kernel>> segment;
std::optional<CGAL::Segment_3<Kernel>> segment;
void operator()(const CGAL::Point_3<Kernel>&)
{
@@ -648,7 +648,7 @@ public:
template <typename Edge, typename Graph>
bool tree_edge(Edge e, const Graph& g) {
if (boost::get(boost::edge_weight, g, e) == edgetype_) {
if (std::get(boost::edge_weight, g, e) == edgetype_) {
auto srcid = boost::source(e, g);
auto tgtid = boost::target(e, g);
@@ -667,7 +667,7 @@ public:
typename boost::graph_traits<Graph>::out_edge_iterator ei, ei_end;
for (boost::tie(ei, ei_end) = boost::out_edges(tgtid, g); ei != ei_end; ++ei) {
if (boost::get(boost::edge_weight, g, *ei) != edgetype_) {
if (std::get(boost::edge_weight, g, *ei) != edgetype_) {
tgt_has_any_reflex_edge = true;
// std::cout << " reflex: " << boost::source(*ei, g) << " -- " << boost::target(*ei, g) << std::endl;
break;
@@ -712,9 +712,9 @@ public:
if (x) {
// std::cout << " triangle: " << t << std::endl;
// Intersection_visitor v;
// boost::apply_visitor([](auto x) {std::cout << " intersects: " << x << std::endl; })(*x);
// std::visit([](auto x) {std::cout << " intersects: " << x << std::endl; })(*x);
Segment_collector<Kernel> sc;
boost::apply_visitor(sc)(*x);
std::visit(sc)(*x);
if (sc.segment) {
if (!std::any_of(edges_i.begin(), edges_i.end(), [&sc](CGAL::Segment_3<Kernel>& s) {
// When intersecting with the boundary of a facet we likely multiple co-planar facets. Exclude intersection.
@@ -723,7 +723,7 @@ public:
return false;
}
Segment_collector<Kernel> scy;
boost::apply_visitor(scy)(*xy);
std::visit(scy)(*xy);
return (bool)scy.segment;
})) {
return true;
@@ -807,7 +807,7 @@ std::unique_ptr<halfspace_tree<TreeKernel>> build_halfspace_tree(Graph<Kernel>&
bool all_convex = true;
typename boost::graph_traits<Graph<Kernel>>::edge_iterator ei, ei_end;
for (boost::tie(ei, ei_end) = boost::edges(G); ei != ei_end; ++ei) {
if (boost::get(boost::edge_weight, G, *ei) != edge_trait) {
if (std::get(boost::edge_weight, G, *ei) != edge_trait) {
// all_convex = false;
break;
}
@@ -1030,7 +1030,7 @@ public:
auto verts_backup = verts;
auto facets_backup = facets;
boost::optional<CGAL::Polygon_with_holes_2<Kernel>> pwh;
std::optional<CGAL::Polygon_with_holes_2<Kernel>> pwh;
auto nf = std::distance(h->facet_cycles_begin(), h->facet_cycles_end());
for (auto fc = h->facet_cycles_begin(); fc != h->facet_cycles_end(); ++fc) {
// std::cout << "h_plane.point() " << h_plane.point() << std::endl;
@@ -73,7 +73,7 @@ namespace IfcGeom {
struct ray_intersection_result {
double distance;
int style_index;
const IfcUtil::IfcBaseEntity* instance;
express::Entity instance;
std::array<double, 3> position;
std::array<double, 3> normal;
double ray_distance;
@@ -82,8 +82,8 @@ namespace IfcGeom {
struct clash {
int clash_type; // 0 = protrusion, 1 = pierce, 2 = collision, 3 = clearance
const IfcUtil::IfcBaseClass* a;
const IfcUtil::IfcBaseClass* b;
express::Base a;
express::Base b;
double distance;
std::array<double, 3> p1;
std::array<double, 3> p2;
@@ -1442,9 +1442,9 @@ namespace IfcGeom {
// Temporary structures for H5
std::vector<IfcGeom::TriangulationElement*> triangulation_elements_;
std::map<const IfcUtil::IfcBaseClass*, std::string> global_ids_;
std::map<const IfcUtil::IfcBaseClass*, std::string> names_;
std::map<const IfcUtil::IfcBaseClass*, ifcopenshell::geometry::taxonomy::matrix4::ptr> placements_;
std::map<express::Base, std::string> global_ids_;
std::map<express::Base, std::string> names_;
std::map<express::Base, ifcopenshell::geometry::taxonomy::matrix4::ptr> placements_;
std::map<std::string, std::vector<double>> local_verts_;
std::map<std::string, std::vector<int>> local_faces_;
std::map<std::string, std::vector<ifcopenshell::geometry::taxonomy::style::ptr>> local_materials_;
@@ -1481,7 +1481,7 @@ namespace IfcGeom {
};
}
class tree : public impl::tree<const IfcUtil::IfcBaseEntity*> {
class tree : public impl::tree<express::Entity> {
public:
tree() {};
@@ -53,7 +53,7 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(ifcopenshell::geometr
// above can be static?
// A 3x3 matrix to rotate the vertex normals
boost::optional<gp_Mat> rotation_matrix;
std::optional<gp_Mat> rotation_matrix;
if (place.components_) {
const auto& m = *place.components_;
@@ -40,7 +40,7 @@ namespace {
using namespace ifcopenshell::geometry;
bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
bool IfcGeom::OpenCascadeKernel::convert_openings(const express::Base& 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) {
util::boolean_settings bst;
@@ -260,7 +260,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
}
results.emplace_back(ConversionResult(
r->instance->as<IfcUtil::IfcBaseEntity>()->id(),
r->instance.id(),
r->matrix,
new OpenCascadeShape(shape),
r->surface_style
@@ -297,7 +297,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
// std::for_each(rs.begin(), rs.end(), [&openings](IfcSchema::IfcRelVoidsElement* rel) {
// if (rel->RelatedOpeningElement()->ObjectPlacement() && rel->RelatedOpeningElement()->Representation()) {
// auto reps = rel->RelatedOpeningElement()->Representation()->Representations();
// if (!(reps->size() == 1 && (*reps->begin())->RepresentationIdentifier().get_value_or("") == "Reference")) {
// if (!(reps->size() == 1 && (*reps->begin())->RepresentationIdentifier().value_or("") == "Reference")) {
// openings->push(rel);
// }
// }
@@ -428,7 +428,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
//
// int parent_id = -1;
// try {
// IfcUtil::IfcBaseEntity* parent_object = get_decomposing_entity(product);
// express::Entity* parent_object = get_decomposing_entity(product);
// if (parent_object && parent_object->as<IfcSchema::IfcObjectDefinition>()) {
// parent_id = parent_object->data().id();
// }
@@ -436,7 +436,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
// Logger::Error(e);
// }
//
// const std::string name = product->Name().get_value_or("");
// const std::string name = product->Name().value_or("");
// const std::string guid = product->GlobalId();
//
// gp_Trsf trsf;
@@ -677,7 +677,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
// {
// int parent_id = -1;
// try {
// IfcUtil::IfcBaseEntity* parent_object = get_decomposing_entity(product);
// express::Entity* parent_object = get_decomposing_entity(product);
// if (parent_object && parent_object->as<IfcSchema::IfcObjectDefinition>()) {
// parent_id = parent_object->data().id();
// }
@@ -685,7 +685,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
// Logger::Error(e);
// }
//
// const std::string name = product->Name().get_value_or("");
// const std::string name = product->Name().value_or("");
// const std::string guid = product->GlobalId();
//
// gp_Trsf trsf;
@@ -998,7 +998,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
// layer_offset += *thickness++;
//
// bool found_intersection = false, parallel = false;
// boost::optional<gp_Pnt> point_outside_param_range;
// std::optional<gp_Pnt> point_outside_param_range;
//
// const Handle_Geom_Surface& surface = *jt;
//
@@ -1209,7 +1209,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
// placement_rel_to_type_ = type;
// }
//
// void IfcGeom::Kernel::set_conversion_placement_rel_to_instance(const IfcUtil::IfcBaseEntity* instance) {
// void IfcGeom::Kernel::set_conversion_placement_rel_to_instance(const express::Entity* instance) {
// placement_rel_to_instance_ = instance;
// }
//
@@ -1281,7 +1281,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
// if (shading_styles.second->declaration().is(IfcSchema::IfcSurfaceStyleRendering::Class())) {
// IfcSchema::IfcSurfaceStyleRendering* rendering_style = static_cast<IfcSchema::IfcSurfaceStyleRendering*>(shading_styles.second);
// if (rendering_style->DiffuseColour() && process_colour(rendering_style->DiffuseColour(), rgb)) {
// SurfaceStyle::ColorComponent diffuse = surface_style.Diffuse().get_value_or(SurfaceStyle::ColorComponent(1, 1, 1));
// SurfaceStyle::ColorComponent diffuse = surface_style.Diffuse().value_or(SurfaceStyle::ColorComponent(1, 1, 1));
// surface_style.Diffuse().reset(SurfaceStyle::ColorComponent(diffuse.R() * rgb[0], diffuse.G() * rgb[1], diffuse.B() * rgb[2]));
// }
// if (rendering_style->DiffuseTransmissionColour()) {
@@ -130,11 +130,11 @@ public:
virtual bool convert_impl(const ifcopenshell::geometry::taxonomy::loft::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const ifcopenshell::geometry::taxonomy::sweep_along_curve::ptr, IfcGeom::ConversionResults&);
virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<ifcopenshell::geometry::taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
virtual bool convert_openings(const express::Base& entity, const std::vector<std::pair<ifcopenshell::geometry::taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes);
virtual bool unify_shapes(const IfcGeom::ConversionResults& input, IfcGeom::ConversionResults& output);
typedef boost::variant<boost::blank, Handle(Geom_Curve), TopoDS_Wire> curve_creation_visitor_result_type;
typedef std::variant<boost::blank, Handle(Geom_Curve), TopoDS_Wire> curve_creation_visitor_result_type;
curve_creation_visitor_result_type convert_curve(const ifcopenshell::geometry::taxonomy::ptr);
Handle(Geom_Surface) convert_surface(const ifcopenshell::geometry::taxonomy::ptr);
@@ -151,8 +151,8 @@ public:
}
};
IfcUtil::IfcBaseClass* POSTFIX_SCHEMA(tesselate_)(const TopoDS_Shape& shape, double deflection);
IfcUtil::IfcBaseClass* POSTFIX_SCHEMA(serialise_)(const TopoDS_Shape& shape, bool advanced);
express::Base POSTFIX_SCHEMA(tesselate_)(const TopoDS_Shape& shape, double deflection);
express::Base POSTFIX_SCHEMA(serialise_)(const TopoDS_Shape& shape, bool advanced);
}
#endif
@@ -107,7 +107,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, Con
if (settings_.get<settings::DisableBooleanResult>().get()) {
results.emplace_back(IfcGeom::ConversionResult(
br->instance->as<IfcUtil::IfcBaseEntity>()->id(),
br->instance.id(),
br->matrix,
new OpenCascadeShape(a),
br->surface_style ? br->surface_style : first_item_style
@@ -189,7 +189,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, Con
}
results.emplace_back(IfcGeom::ConversionResult(
br->instance->as<IfcUtil::IfcBaseEntity>()->id(),
br->instance.id(),
br->matrix,
new OpenCascadeShape(a),
br->surface_style ? br->surface_style : first_item_style
@@ -78,7 +78,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::extrusion::ptr extrusion, I
}
results.emplace_back(ConversionResult(
extrusion->instance->as<IfcUtil::IfcBaseEntity>()->id(),
extrusion->instance.id(),
extrusion->matrix,
new OpenCascadeShape(shape),
extrusion->surface_style
+10 -10
View File
@@ -151,8 +151,8 @@ namespace {
// It's a bit more convenient to use high level BRepPrimAPI calls that operate on
// topology. On a single edge that will create a Geom_TrimmedCurve for us.
auto crv_or_wire = kernel->convert_curve(i);
if (crv_or_wire.which() == 2) {
const auto& w = boost::get<TopoDS_Wire>(crv_or_wire);
if (crv_or_wire.index() == 2) {
const auto& w = std::get<TopoDS_Wire>(crv_or_wire);
return w;
} else {
throw std::runtime_error("Unexpected curve evaluation");
@@ -162,15 +162,15 @@ namespace {
Handle(Geom_Curve) get_curve(const taxonomy::item::ptr& i) {
// @todo unify with trimmed curve handling
auto crv_or_wire = kernel->convert_curve(i);
if (crv_or_wire.which() == 0) {
if (crv_or_wire.index() == 0) {
throw std::runtime_error("Failed to obtain curve");
} else if (crv_or_wire.which() == 1) {
return boost::get<Handle(Geom_Curve)>(crv_or_wire);
} else if (crv_or_wire.which() == 2) {
} else if (crv_or_wire.index() == 1) {
return std::get<Handle(Geom_Curve)>(crv_or_wire);
} else if (crv_or_wire.index() == 2) {
// @todo
const double precision_ = 1.e-5;
Logger::Warning("Approximating BasisCurve due to possible discontinuities", i->instance);
const auto& w = boost::get<TopoDS_Wire>(crv_or_wire);
const auto& w = std::get<TopoDS_Wire>(crv_or_wire);
#if OCC_VERSION_HEX < 0x70600
BRepAdaptor_CompCurve cc(w, true);
Handle(Adaptor3d_HCurve) hcc = Handle(Adaptor3d_HCurve)(new BRepAdaptor_HCompCurve(cc));
@@ -279,7 +279,7 @@ bool OpenCascadeKernel::convert(const taxonomy::face::ptr face, TopoDS_Shape& re
int num_outer_bounds = 0;
for (auto& bound : face->children) {
if (bound->external.get_value_or(false)) {
if (bound->external.value_or(false)) {
num_outer_bounds++;
}
}
@@ -305,7 +305,7 @@ bool OpenCascadeKernel::convert(const taxonomy::face::ptr face, TopoDS_Shape& re
bool same_sense = true; /* todo bound->Orientation(); */
const bool is_interior =
!bound->external.get_value_or(false) &&
!bound->external.value_or(false) &&
(num_bounds > 1) &&
(num_outer_bounds < num_bounds);
@@ -604,7 +604,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::face::ptr face, IfcGeom::Co
return false;
}
results.emplace_back(ConversionResult(
face->instance->as<IfcUtil::IfcBaseEntity>()->id(),
face->instance.id(),
new OpenCascadeShape(shape),
face->surface_style
));
@@ -43,7 +43,7 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
for (auto& e : l->children) {
for (size_t i = 0; i < 2; ++i) {
// @todo make sure only cartesian points are provided here
auto& p = boost::get<ifcopenshell::geometry::taxonomy::point3::ptr>(i == 0 ? e->start : e->end);
auto& p = std::get<ifcopenshell::geometry::taxonomy::point3::ptr>(i == 0 ? e->start : e->end);
if (point_identities_visited.find(p->identity()) == point_identities_visited.end()) {
point_identities_visited.insert(p->identity());
points.push_back(p);
@@ -198,7 +198,7 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
}
}
if (duplicates_.size() || loops_removed || (non_manifold && shell->closed.get_value_or(false))) {
if (duplicates_.size() || loops_removed || (non_manifold && shell->closed.value_or(false))) {
Logger::Warning(boost::lexical_cast<std::string>(duplicate_faces) + " duplicate faces removed, " + boost::lexical_cast<std::string>(loops_removed) + " degenerate loops eliminated and " + boost::lexical_cast<std::string>(non_manifold) + " non-manifold edges");
}
}
@@ -209,14 +209,14 @@ void IfcGeom::OpenCascadeKernel::faceset_helper::loop_(const ifcopenshell::geome
}
for (auto& edge : ps->children) {
auto A = boost::get<ifcopenshell::geometry::taxonomy::point3::ptr>(edge->start)->identity();
auto B = boost::get<ifcopenshell::geometry::taxonomy::point3::ptr>(edge->end)->identity();
auto A = std::get<ifcopenshell::geometry::taxonomy::point3::ptr>(edge->start)->identity();
auto B = std::get<ifcopenshell::geometry::taxonomy::point3::ptr>(edge->end)->identity();
auto C = vertex_mapping_[A], D = vertex_mapping_[B];
bool fwd = C < D;
if (!fwd) {
std::swap(C, D);
}
if (!edge->orientation.get_value_or(true)) {
if (!edge->orientation.value_or(true)) {
fwd = !fwd;
}
if (C != D) {
+7 -7
View File
@@ -156,21 +156,21 @@ bool OpenCascadeKernel::convert(const taxonomy::loft::ptr loft, TopoDS_Shape& re
// I think make_loft() where should just return a shell instead, because
// this faceted lofting does not depend on any functionality in the geometry library
// and the branching with tags needs to be solved twice otherwise
auto loop_to_points = [](const taxonomy::loop::ptr& loop, const boost::optional<std::vector<std::string>>& input_tags) -> std::pair<std::vector<taxonomy::point3::ptr>, std::vector<std::set<std::string>>> {
auto loop_to_points = [](const taxonomy::loop::ptr& loop, const std::optional<std::vector<std::string>>& input_tags) -> std::pair<std::vector<taxonomy::point3::ptr>, std::vector<std::set<std::string>>> {
std::vector<taxonomy::point3::ptr> points;
std::vector<std::set<std::string>> tags;
std::vector<std::string>::const_iterator tag_it;
if (!loop->closed.get_value_or(false)) {
points = {boost::get<taxonomy::point3::ptr>(loop->children[0]->start)};
if (!loop->closed.value_or(false)) {
points = {std::get<taxonomy::point3::ptr>(loop->children[0]->start)};
if (input_tags) {
tags = {{input_tags->front()}};
tag_it = ++input_tags->begin();
}
}
for (auto& e : loop->children) {
const auto& p1 = boost::get<taxonomy::point3::ptr>(e->start);
const auto& p2 = boost::get<taxonomy::point3::ptr>(e->end);
const auto& p1 = std::get<taxonomy::point3::ptr>(e->start);
const auto& p2 = std::get<taxonomy::point3::ptr>(e->end);
if (input_tags && p1->ccomponents() == p2->ccomponents()) {
tags.back().insert(*tag_it);
++tag_it;
@@ -184,7 +184,7 @@ bool OpenCascadeKernel::convert(const taxonomy::loft::ptr loft, TopoDS_Shape& re
}
}
if (!input_tags) {
if (loop->closed.get_value_or(false)) {
if (loop->closed.value_or(false)) {
// close polygon by referencing first point
points.push_back(points.front());
}
@@ -409,7 +409,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::loft::ptr loft, IfcGeom::Co
return false;
}
results.emplace_back(ConversionResult(
loft->instance->as<IfcUtil::IfcBaseEntity>()->id(),
loft->instance.id(),
loft->matrix,
new OpenCascadeShape(shape),
loft->surface_style
+46 -29
View File
@@ -105,32 +105,32 @@ namespace {
OpenCascadeKernel::curve_creation_visitor_result_type operator()(const taxonomy::edge::ptr& e) {
// @todo for polyloops/-lines we should probably construct edges based on correct oriented TopoDS_Vertex instead.
if (e->start.which() != e->end.which()) {
if (e->start.index() != e->end.index()) {
throw std::runtime_error("Different trim types not supported");
}
const bool reversed = !e->orientation.get_value_or(true);
const bool reversed = !e->orientation.value_or(true);
TopoDS_Edge E;
auto e_basis = e->basis;
if (e_basis) {
while (e_basis->kind() == taxonomy::EDGE && e_basis->instance && e_basis->instance->declaration().name() == "IfcTrimmedCurve") {
while (e_basis->kind() == taxonomy::EDGE && e_basis->instance && e_basis->instance.declaration().name() == "IfcTrimmedCurve") {
// @todo we still might have something to wrt orientation on periodic curves
// to make sure we select the correct arc later on.
e_basis = taxonomy::cast<taxonomy::edge>(e_basis)->basis;
}
auto crv_or_wire = kernel->convert_curve(e_basis);
Handle(Geom_Curve) curve;
if (crv_or_wire.which() == 0) {
if (crv_or_wire.index() == 0) {
// raise exception
return result;
} else if (crv_or_wire.which() == 1) {
curve = boost::get<Handle(Geom_Curve)>(crv_or_wire);
} else if (crv_or_wire.index() == 1) {
curve = std::get<Handle(Geom_Curve)>(crv_or_wire);
} else {
// @todo
const double precision_ = 1.e-5;
Logger::Warning("Approximating BasisCurve due to possible discontinuities", e->instance);
const auto& w = boost::get<TopoDS_Wire>(crv_or_wire);
const auto& w = std::get<TopoDS_Wire>(crv_or_wire);
#if OCC_VERSION_HEX < 0x70600
BRepAdaptor_CompCurve cc(w, true);
Handle(Adaptor3d_HCurve) hcc = Handle(Adaptor3d_HCurve)(new BRepAdaptor_HCompCurve(cc));
@@ -147,25 +147,25 @@ namespace {
auto e_start = e->start;
auto e_end = e->end;
if (!e->curve_sense.get_value_or(true)) {
if (!e->curve_sense.value_or(true)) {
std::swap(e_start, e_end);
}
// @todo, copy over logic from previous IfcTrimmedCurve handling
if (e_start.which() == 0) {
if (e_start.index() == 0) {
E = BRepBuilderAPI_MakeEdge(curve).Edge();
} else if (e_start.which() == 1) {
auto p1 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*boost::get<taxonomy::point3::ptr>(e_start));
auto p2 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*boost::get<taxonomy::point3::ptr>(e_end));
} else if (e_start.index() == 1) {
auto p1 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*std::get<taxonomy::point3::ptr>(e_start));
auto p2 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*std::get<taxonomy::point3::ptr>(e_end));
if (curve->IsClosed() && p1.Distance(p2) <= kernel->settings().get<settings::Precision>().get()) {
E = BRepBuilderAPI_MakeEdge(curve).Edge();
} else {
E = BRepBuilderAPI_MakeEdge(curve, p1, p2).Edge();
}
} else if (e_start.which() == 2) {
auto v1 = boost::get<double>(e_start);
auto v2 = boost::get<double>(e_end);
} else if (e_start.index() == 2) {
auto v1 = std::get<double>(e_start);
auto v2 = std::get<double>(e_end);
if (is_conic && ALMOST_THE_SAME(fmod(v2 - v1, M_PI * 2.), 0.)) {
E = BRepBuilderAPI_MakeEdge(curve).Edge();
@@ -178,15 +178,15 @@ namespace {
// comply with the direction of conical curves. The ordering of the
// vertices then still needs to be reversed in order to have begin and
// end vertex consistent with IFC.
if (!e->curve_sense.get_value_or(true)) {
if (!e->curve_sense.value_or(true)) {
E.Reverse();
}
} else {
if (e->start.which() != 1) {
if (e->start.index() != 1) {
throw std::runtime_error("Non-cartesian trim on edge without curve");
}
auto p1 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*boost::get<taxonomy::point3::ptr>(e->start));
auto p2 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*boost::get<taxonomy::point3::ptr>(e->end));
auto p1 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*std::get<taxonomy::point3::ptr>(e->start));
auto p2 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*std::get<taxonomy::point3::ptr>(e->end));
E = BRepBuilderAPI_MakeEdge(p1, p2).Edge();
}
@@ -235,10 +235,27 @@ OpenCascadeKernel::curve_creation_visitor_result_type OpenCascadeKernel::convert
bool OpenCascadeKernel::convert(const taxonomy::loop::ptr loop, TopoDS_Wire& wire) {
TopTools_ListOfShape converted_segments;
/*
if (loop->tags) {
std::wcout << "Tags:";
for (const auto& t : *loop->tags) {
std::wcout << " \"" << t.c_str() << "\"";
}
std::wcout << std::endl;
}*/
for (auto& segment : loop->children) {
/*{
std::ostringstream oss;
segment->print(oss);
auto s = oss.str();
std::wcout << s.c_str() << std::endl;
}*/
TopoDS_Wire segment_wire;
try {
segment_wire = boost::get<TopoDS_Wire>(convert_curve(segment));
segment_wire = std::get<TopoDS_Wire>(convert_curve(segment));
} catch (...) {
// @todo we should do some better logging here and catch specific exceptions
// but most notably we just want to continue processing when there are
@@ -276,14 +293,14 @@ bool OpenCascadeKernel::convert(const taxonomy::loop::ptr loop, TopoDS_Wire& wir
TopTools_ListIteratorOfListOfShape it(converted_segments);
bool force_close = false;
if (loop->instance && loop->instance->as<IfcUtil::IfcBaseEntity>() && loop->instance->as<IfcUtil::IfcBaseEntity>()->file_) {
auto* inst = loop->instance->as<IfcUtil::IfcBaseEntity>();
auto* file = loop->instance->as<IfcUtil::IfcBaseEntity>()->file_;
auto profile = file->getInverse(inst->id(), file->schema()->declaration_by_name("IfcProfileDef"), -1);
force_close = profile && profile->size() > 0;
if (loop->instance && loop->instance.as<express::Entity>()) {
auto inst = loop->instance.as<express::Entity>();
auto file = loop->instance.as<express::Entity>().data()->file();
auto profile = file->getInverse(inst.id(), file->schema()->declaration_by_name("IfcProfileDef"), -1);
force_close = profile.size() > 0;
}
wire_builder bld(precision_, loop->instance ? loop->instance->as<IfcUtil::IfcBaseEntity>() : nullptr);
wire_builder bld(precision_, loop->instance ? loop->instance.as<express::Entity>() : express::Base{});
shape_pair_enumerate(it, bld, force_close);
wire = bld.wire();
@@ -384,7 +401,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::loop::ptr loop, IfcGeom::Co
}
results.emplace_back(ConversionResult(
loop->instance->as<IfcUtil::IfcBaseEntity>()->id(),
loop->instance.id(),
new OpenCascadeShape(shape),
loop->surface_style
));
@@ -392,10 +409,10 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::loop::ptr loop, IfcGeom::Co
}
bool OpenCascadeKernel::convert_impl(const taxonomy::edge::ptr edge, IfcGeom::ConversionResults& results) {
TopoDS_Wire shape = boost::get<TopoDS_Wire>(convert_curve(edge));
TopoDS_Wire shape = std::get<TopoDS_Wire>(convert_curve(edge));
results.emplace_back(ConversionResult(
edge->instance->as<IfcUtil::IfcBaseEntity>()->id(),
edge->instance.id(),
new OpenCascadeShape(shape),
edge->surface_style
));
+1 -1
View File
@@ -14,7 +14,7 @@ bool OpenCascadeKernel::convert(const taxonomy::matrix4::ptr matrix, gp_GTrsf& t
m(2, 0), m(2, 1), m(2, 2)
);
if (matrix->instance && matrix->instance->declaration().name() == "IfcCartesianTransformationOperator3DnonUniform") {
if (matrix->instance && matrix->instance.declaration().name() == "IfcCartesianTransformationOperator3DnonUniform") {
// std::wcout << "non uniform" << std::endl;
}
+1 -1
View File
@@ -112,7 +112,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::shell::ptr shell, IfcGeom::
return false;
}
results.emplace_back(ConversionResult(
shell->instance->as<IfcUtil::IfcBaseEntity>()->id(),
shell->instance.id(),
shell->matrix,
new OpenCascadeShape(shape),
shell->surface_style
+3 -3
View File
@@ -34,7 +34,7 @@ using namespace IfcGeom::util;
bool OpenCascadeKernel::convert(const taxonomy::solid::ptr solid, TopoDS_Shape& result) {
TopoDS_Shape S;
if (solid->instance->declaration().is("IfcHalfSpaceSolid")) {
if (solid->instance.declaration().is("IfcHalfSpaceSolid")) {
// halfspace
if (solid->children.size() != 1) {
throw std::runtime_error("Unexpected number of children on solid");
@@ -44,7 +44,7 @@ bool OpenCascadeKernel::convert(const taxonomy::solid::ptr solid, TopoDS_Shape&
const auto& m = taxonomy::cast<taxonomy::plane>(face->basis)->matrix->ccomponents();
gp_Pln pln(convert_xyz2<gp_Pnt>(m.col(3)), convert_xyz2<gp_Dir>(m.col(2)));
const gp_Pnt pnt = pln.Location().Translated(face->orientation.get_value_or(false) ? pln.Axis().Direction() : -pln.Axis().Direction());
const gp_Pnt pnt = pln.Location().Translated(face->orientation.value_or(false) ? pln.Axis().Direction() : -pln.Axis().Direction());
TopoDS_Shape halfspace = BRepPrimAPI_MakeHalfSpace(BRepBuilderAPI_MakeFace(pln), pnt).Solid();
if (!face->children.empty()) {
@@ -107,7 +107,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::solid::ptr solid, IfcGeom::
return false;
}
results.emplace_back(ConversionResult(
solid->instance->as<IfcUtil::IfcBaseEntity>()->id(),
solid->instance.id(),
solid->matrix,
new OpenCascadeShape(shape),
solid->surface_style
@@ -113,8 +113,8 @@ bool OpenCascadeKernel::convert(const taxonomy::sweep_along_curve::ptr scs, Topo
applied_temporary_offset = true;
std::set<taxonomy::point3::ptr> unique_points;
for (auto& e : std::dynamic_pointer_cast<taxonomy::loop>(curve)->children) {
auto* a = boost::get<taxonomy::point3::ptr>(&e->start);
auto* b = boost::get<taxonomy::point3::ptr>(&e->end);
auto* a = std::get_if<taxonomy::point3::ptr>(&e->start);
auto* b = std::get_if<taxonomy::point3::ptr>(&e->end);
if (a) {
unique_points.insert(*a);
}
@@ -129,7 +129,7 @@ bool OpenCascadeKernel::convert(const taxonomy::sweep_along_curve::ptr scs, Topo
}
auto w = convert_curve(scs->curve);
if (w.which() != 2) {
if (w.index() != 2) {
Logger::Error("Unsupported directrix");
return false;
}
@@ -158,7 +158,7 @@ bool OpenCascadeKernel::convert(const taxonomy::sweep_along_curve::ptr scs, Topo
}
gp_Trsf directrix;
TopoDS_Wire wire = boost::get<TopoDS_Wire>(w);
TopoDS_Wire wire = std::get<TopoDS_Wire>(w);
const bool is_plane = surface && surface->DynamicType() == STANDARD_TYPE(Geom_Plane);
@@ -346,7 +346,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::sweep_along_curve::ptr scs,
m = scs->matrix;
}
results.emplace_back(ConversionResult(
scs->instance->as<IfcUtil::IfcBaseEntity>()->id(),
scs->instance.id(),
m,
new OpenCascadeShape(shape),
scs->surface_style
@@ -20,7 +20,7 @@
#ifndef WIRE_BUILDER_H
#define WIRE_BUILDER_H
#include "../../../ifcparse/IfcBaseClass.h"
#include "../../../ifcparse/express.h"
#include <Geom_Curve.hxx>
@@ -46,10 +46,10 @@ namespace IfcGeom {
double p_;
bool override_next_;
gp_Pnt next_override_;
const IfcUtil::IfcBaseClass* inst_;
express::Base inst_;
public:
wire_builder(double p, const IfcUtil::IfcBaseClass* inst = 0) : p_(p), override_next_(false), inst_(inst) {}
wire_builder(double p, const express::Base& inst = express::Base()) : p_(p), override_next_(false), inst_(inst) {}
void operator()(const TopoDS_Shape& a);
@@ -23,16 +23,16 @@
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAnnotationFillArea* inst) {
auto loop = taxonomy::cast<taxonomy::loop>(map(inst->OuterBoundary()));
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAnnotationFillArea& inst) {
auto loop = taxonomy::cast<taxonomy::loop>(map(inst.OuterBoundary()));
if (loop) {
auto face = taxonomy::make<taxonomy::face>();
loop->external = true;
face->children = { loop };
if (inst->InnerBoundaries()) {
IfcSchema::IfcCurve::list::ptr inner_boundaries = *inst->InnerBoundaries();
for (auto& v : *inner_boundaries) {
if (inst.InnerBoundaries()) {
std::vector<IfcSchema::IfcCurve> inner_boundaries = *inst.InnerBoundaries();
for (auto& v : inner_boundaries) {
auto inner_loop = taxonomy::cast<taxonomy::loop>(map(v));
if (inner_loop) {
inner_loop->external = false;
@@ -23,10 +23,10 @@
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcArbitraryClosedProfileDef* inst) {
auto loop = taxonomy::cast<taxonomy::loop>(map(inst->OuterCurve()));
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcArbitraryClosedProfileDef& inst) {
auto loop = taxonomy::cast<taxonomy::loop>(map(inst.OuterCurve()));
if (loop) {
if (inst->ProfileType() == IfcSchema::IfcProfileTypeEnum::IfcProfileType_CURVE) {
if (inst.ProfileType() == IfcSchema::IfcProfileTypeEnum::IfcProfileType_CURVE) {
return loop;
}
@@ -34,10 +34,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcArbitraryClosedProfileDef* i
loop->external = true;
face->children = { loop };
if (inst->as<IfcSchema::IfcArbitraryProfileDefWithVoids>()) {
auto with_voids = inst->as<IfcSchema::IfcArbitraryProfileDefWithVoids>();
auto voids = with_voids->InnerCurves();
for (auto& v : *voids) {
if (inst.as<IfcSchema::IfcArbitraryProfileDefWithVoids>()) {
auto with_voids = inst.as<IfcSchema::IfcArbitraryProfileDefWithVoids>();
auto voids = with_voids.InnerCurves();
for (auto& v : voids) {
auto inner_loop = taxonomy::cast<taxonomy::loop>(map(v));
if (inner_loop) {
inner_loop->external = false;
@@ -23,8 +23,8 @@
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcArbitraryOpenProfileDef* inst) {
auto mapped = map(inst->Curve());
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcArbitraryOpenProfileDef& inst) {
auto mapped = map(inst.Curve());
if (mapped->kind() == taxonomy::LOOP) {
auto r = taxonomy::loop::ptr((taxonomy::loop*)mapped->clone_());
r->closed = false;
+4 -4
View File
@@ -22,17 +22,17 @@
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis1Placement* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis1Placement& inst) {
Eigen::Vector3d P(0, 0, 0), axis(0, 0, 1), ref;
try {
taxonomy::point3::ptr v = taxonomy::cast<taxonomy::point3>(map(inst->Location()));
taxonomy::point3::ptr v = taxonomy::cast<taxonomy::point3>(map(inst.Location()));
P = *v->components_;
} catch (const std::exception&) {
Logger::Warning("Placement with invalid Location:", inst);
}
const bool hasAxis = inst->Axis();
const bool hasAxis = inst.Axis();
if (hasAxis) {
taxonomy::direction3::ptr v = taxonomy::cast<taxonomy::direction3>(map(inst->Axis()));
taxonomy::direction3::ptr v = taxonomy::cast<taxonomy::direction3>(map(inst.Axis()));
axis = *v->components_;
}
+4 -4
View File
@@ -23,17 +23,17 @@
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2Placement2D* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2Placement2D& inst) {
Eigen::Vector3d P(0, 0, 0), axis(0, 0, 1), V(1, 0, 0);
try {
taxonomy::point3::ptr v = taxonomy::cast<taxonomy::point3>(map(inst->Location()));
taxonomy::point3::ptr v = taxonomy::cast<taxonomy::point3>(map(inst.Location()));
P = *v->components_;
} catch (const std::exception&) {
Logger::Warning("Placement with invalid Location:", inst);
}
const bool hasRef = !!inst->RefDirection();
const bool hasRef = !!inst.RefDirection();
if (hasRef) {
taxonomy::direction3::ptr v = taxonomy::cast<taxonomy::direction3>(map(inst->RefDirection()));
taxonomy::direction3::ptr v = taxonomy::cast<taxonomy::direction3>(map(inst.RefDirection()));
V = *v->components_;
}
return taxonomy::make<taxonomy::matrix4>(P, axis, V);
+6 -6
View File
@@ -23,28 +23,28 @@
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2Placement3D* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2Placement3D& inst) {
Eigen::Vector3d o(0, 0, 0), axis(0, 0, 1), refDirection, X(1, 0, 0);
try {
taxonomy::point3::ptr v = taxonomy::cast<taxonomy::point3>(map(inst->Location()));
taxonomy::point3::ptr v = taxonomy::cast<taxonomy::point3>(map(inst.Location()));
o = *v->components_;
} catch (const std::exception&) {
Logger::Warning("Placement with invalid Location:", inst);
}
const bool hasAxis = !!inst->Axis();
const bool hasRef = !!inst->RefDirection();
const bool hasAxis = !!inst.Axis();
const bool hasRef = !!inst.RefDirection();
if (hasAxis != hasRef) {
Logger::Warning("Axis and RefDirection should be specified together", inst);
}
if (hasAxis) {
taxonomy::direction3::ptr v = taxonomy::cast<taxonomy::direction3>(map(inst->Axis()));
taxonomy::direction3::ptr v = taxonomy::cast<taxonomy::direction3>(map(inst.Axis()));
axis = *v->components_;
}
if (hasRef) {
taxonomy::direction3::ptr v = taxonomy::cast<taxonomy::direction3>(map(inst->RefDirection()));
taxonomy::direction3::ptr v = taxonomy::cast<taxonomy::direction3>(map(inst.RefDirection()));
refDirection = *v->components_;
} else {
if (acos(axis.dot(X)) > 1.e-5) {
@@ -23,15 +23,15 @@ using namespace ifcopenshell::geometry;
#if defined SCHEMA_HAS_IfcAxis2PlacementLinear
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2PlacementLinear* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2PlacementLinear& inst) {
if (!inst->Location()->as<IfcSchema::IfcPointByDistanceExpression>()) {
if (!inst.Location().as<IfcSchema::IfcPointByDistanceExpression>()) {
Logger::Error(std::runtime_error("Location must be IfcPointByDistanceExpression for IfcAxis2PlacementLinear"));
}
Eigen::Vector3d o, axis(0, 0, 1), refDirection;
taxonomy::matrix4::ptr m = taxonomy::cast<taxonomy::matrix4>(map(inst->Location()));
taxonomy::matrix4::ptr m = taxonomy::cast<taxonomy::matrix4>(map(inst.Location()));
o = m->components().col(3).head<3>();
// From 8.9.3.4 IfcAxis2PlacementLinear there are 4 cases that need to be considered
@@ -40,8 +40,8 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2PlacementLinear* inst)
// 3) Neither Axis or RefDirection are provided
// 4) Both Axis and RefDirection are provided
const bool hasAxis = inst->Axis() != nullptr;
const bool hasRef = inst->RefDirection() != nullptr;
const bool hasAxis = !!inst.Axis();
const bool hasRef = !!inst.RefDirection();
/*
if (hasAxis != hasRef) {
@@ -50,7 +50,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2PlacementLinear* inst)
*/
if (hasAxis && !hasRef) {
taxonomy::direction3::ptr a = taxonomy::cast<taxonomy::direction3>(map(inst->Axis()));
taxonomy::direction3::ptr a = taxonomy::cast<taxonomy::direction3>(map(inst.Axis()));
axis = *a->components_;
refDirection = m->components().col(0).head<3>(); // RefDirection is the curve tangent when omitted
@@ -58,7 +58,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2PlacementLinear* inst)
// axis.cross(refDirection) gives y. y.cross(axis) gives x=refDirection
refDirection = axis.cross(refDirection).cross(axis);
} else if (!hasAxis && hasRef) {
taxonomy::direction3::ptr r = taxonomy::cast<taxonomy::direction3>(map(inst->RefDirection()));
taxonomy::direction3::ptr r = taxonomy::cast<taxonomy::direction3>(map(inst.RefDirection()));
refDirection = *r->components_;
Eigen::Vector3d up(0, 0, 1);
axis = refDirection.cross(up.cross(refDirection));
@@ -67,10 +67,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2PlacementLinear* inst)
Eigen::Vector3d up(0, 0, 1);
axis = refDirection.cross(up.cross(refDirection));
} else {
taxonomy::direction3::ptr a = taxonomy::cast<taxonomy::direction3>(map(inst->Axis()));
taxonomy::direction3::ptr a = taxonomy::cast<taxonomy::direction3>(map(inst.Axis()));
axis = *a->components_;
taxonomy::direction3::ptr r = taxonomy::cast<taxonomy::direction3>(map(inst->RefDirection()));
taxonomy::direction3::ptr r = taxonomy::cast<taxonomy::direction3>(map(inst.RefDirection()));
refDirection = *r->components_;
refDirection = axis.cross(refDirection).cross(axis); // refDirection needs to be orthogonal to axis
}
@@ -25,20 +25,20 @@
using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcBSplineCurveWithKnots
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBSplineCurveWithKnots* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBSplineCurveWithKnots& inst) {
auto bc = taxonomy::make<taxonomy::bspline_curve>();
const IfcSchema::IfcCartesianPoint::list::ptr cps = inst->ControlPointsList();
const std::vector<IfcSchema::IfcCartesianPoint> cps = inst.ControlPointsList();
std::vector<taxonomy::point3::ptr> points;
std::transform(cps->begin(), cps->end(), std::back_inserter(points), [this](IfcSchema::IfcCartesianPoint* cp) { return taxonomy::cast<taxonomy::point3>(map(cp)); });
std::transform(cps.begin(), cps.end(), std::back_inserter(points), [this](const IfcSchema::IfcCartesianPoint& cp) { return taxonomy::cast<taxonomy::point3>(map(cp)); });
bc->control_points = points;
bc->multiplicities = inst->KnotMultiplicities();
bc->knots = inst->Knots();
if (inst->as<IfcSchema::IfcRationalBSplineCurveWithKnots>()) {
bc->weights = inst->as<IfcSchema::IfcRationalBSplineCurveWithKnots>()->WeightsData();
bc->multiplicities = inst.KnotMultiplicities();
bc->knots = inst.Knots();
if (inst.as<IfcSchema::IfcRationalBSplineCurveWithKnots>()) {
bc->weights = inst.as<IfcSchema::IfcRationalBSplineCurveWithKnots>().WeightsData();
}
bc->degree = inst->Degree();
bc->degree = inst.Degree();
return bc;
}
@@ -25,22 +25,22 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcBSplineSurfaceWithKnots
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBSplineSurfaceWithKnots* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBSplineSurfaceWithKnots& inst) {
auto bs = taxonomy::make<taxonomy::bspline_surface>();
auto cps = inst->ControlPointsList();
std::transform(cps->begin(), cps->end(), std::back_inserter(bs->control_points), [this](const std::vector<IfcSchema::IfcCartesianPoint*>& inner) {
auto cps = inst.ControlPointsList();
std::transform(cps.begin(), cps.end(), std::back_inserter(bs->control_points), [this](const std::vector<IfcSchema::IfcCartesianPoint>& inner) {
std::vector<taxonomy::point3::ptr> ps;
std::transform(inner.begin(), inner.end(), std::back_inserter(ps), [this](IfcSchema::IfcCartesianPoint* cp) { return taxonomy::cast<taxonomy::point3>(map(cp)); });
std::transform(inner.begin(), inner.end(), std::back_inserter(ps), [this](const IfcSchema::IfcCartesianPoint& cp) { return taxonomy::cast<taxonomy::point3>(map(cp)); });
return ps;
});
bs->multiplicities = { inst->UMultiplicities(), inst->VMultiplicities() };
bs->knots = { inst->UKnots(), inst->VKnots() };
if (inst->as<IfcSchema::IfcRationalBSplineSurfaceWithKnots>()) {
bs->weights = inst->as<IfcSchema::IfcRationalBSplineSurfaceWithKnots>()->WeightsData();
bs->multiplicities = { inst.UMultiplicities(), inst.VMultiplicities() };
bs->knots = { inst.UKnots(), inst.VKnots() };
if (inst.as<IfcSchema::IfcRationalBSplineSurfaceWithKnots>()) {
bs->weights = inst.as<IfcSchema::IfcRationalBSplineSurfaceWithKnots>().WeightsData();
}
bs->degree = { inst->UDegree(), inst->VDegree() };
bs->degree = { inst.UDegree(), inst.VDegree() };
return bs;
}
+5 -5
View File
@@ -22,13 +22,13 @@
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBlock* inst) {
const double dx = inst->XLength() * length_unit_;
const double dy = inst->YLength() * length_unit_;
const double dz = inst->ZLength() * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBlock& inst) {
const double dx = inst.XLength() * length_unit_;
const double dy = inst.YLength() * length_unit_;
const double dz = inst.ZLength() * length_unit_;
auto solid = create_box(dx, dy, dz);
solid->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
solid->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
return solid;
}
+12 -12
View File
@@ -37,22 +37,22 @@ namespace {
}
}
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBooleanResult* inst) {
IfcSchema::IfcBooleanOperand* operand1 = inst->FirstOperand();
IfcSchema::IfcBooleanOperand* operand2 = inst->SecondOperand();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBooleanResult& inst) {
IfcSchema::IfcBooleanOperand operand1 = inst.FirstOperand();
IfcSchema::IfcBooleanOperand operand2 = inst.SecondOperand();
bool has_halfspace_operand = false;
std::vector<IfcSchema::IfcBooleanOperand*> operands;
std::vector<IfcSchema::IfcBooleanOperand> operands;
operands.push_back(operand2);
auto op = boolean_op_type(inst->Operator());
auto op = boolean_op_type(inst.Operator());
if (op == taxonomy::boolean_result::SUBTRACTION) {
int n_half_space_operands = 0;
bool process_as_list = true;
while (true) {
auto res1 = operand1->as<IfcSchema::IfcBooleanResult>();
if (res1 && res1->SecondOperand()->as<IfcSchema::IfcHalfSpaceSolid>() && ++n_half_space_operands > 8) {
auto res1 = operand1.as<IfcSchema::IfcBooleanResult>();
if (res1 && res1.SecondOperand().as<IfcSchema::IfcHalfSpaceSolid>() && ++n_half_space_operands > 8) {
// There is something peculiar about many half space subtraction operands that OCCT does not like.
// Often these are used to create a semi-curved arch, as is the case in 693. Supplying all these
// operands at once apparently leads to too many edge-edge interference checks.
@@ -62,9 +62,9 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBooleanResult* inst) {
break;
}
if (res1) {
if (boolean_op_type(res1->Operator()) == op) {
operand1 = res1->FirstOperand();
operands.push_back(res1->SecondOperand());
if (boolean_op_type(res1.Operator()) == op) {
operand1 = res1.FirstOperand();
operands.push_back(res1.SecondOperand());
} else {
process_as_list = false;
break;
@@ -75,14 +75,14 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBooleanResult* inst) {
}
if (!process_as_list) {
operand1 = inst->FirstOperand();
operand1 = inst.FirstOperand();
operands = { operand2 };
}
}
operands.insert(operands.begin(), operand1);
auto br = map_to_collection<taxonomy::boolean_result>(this, &operands);
auto br = map_to_collection<taxonomy::boolean_result>(this, operands);
if (br) {
br->operation = op;
}
+5 -5
View File
@@ -22,17 +22,17 @@
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBoundingBox* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBoundingBox& inst) {
if (!settings_.get<settings::KeepBoundingBoxes>().get()) {
failed_on_purpose_.insert(inst);
return nullptr;
}
const double dx = inst->XDim() * length_unit_;
const double dy = inst->YDim() * length_unit_;
const double dz = inst->ZDim() * length_unit_;
const double dx = inst.XDim() * length_unit_;
const double dy = inst.YDim() * length_unit_;
const double dz = inst.ZDim() * length_unit_;
taxonomy::point3::ptr corner = taxonomy::cast<taxonomy::point3>(map(inst->Corner()));
taxonomy::point3::ptr corner = taxonomy::cast<taxonomy::point3>(map(inst.Corner()));
auto solid = create_box(corner->ccomponents().x(), corner->ccomponents().y(), corner->ccomponents().z(), dx, dy, dz);
return solid;
+9 -9
View File
@@ -27,16 +27,16 @@ using namespace ifcopenshell::geometry;
#include <vector>
#include <boost/optional/optional.hpp>
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCShapeProfileDef* inst) {
const double y = inst->Depth() / 2.0f * length_unit_;
const double x = inst->Width() / 2.0f * length_unit_;
const double d1 = inst->WallThickness() * length_unit_;
const double d2 = inst->Girth() * length_unit_;
bool doFillet = !!inst->InternalFilletRadius();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCShapeProfileDef& inst) {
const double y = inst.Depth() / 2.0f * length_unit_;
const double x = inst.Width() / 2.0f * length_unit_;
const double d1 = inst.WallThickness() * length_unit_;
const double d2 = inst.Girth() * length_unit_;
bool doFillet = !!inst.InternalFilletRadius();
double f1 = 0;
double f2 = 0;
if ( doFillet ) {
f1 = *inst->InternalFilletRadius() * length_unit_;
f1 = *inst.InternalFilletRadius() * length_unit_;
f2 = f1 + d1;
}
@@ -50,10 +50,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCShapeProfileDef* inst) {
taxonomy::matrix4::ptr m4;
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
return profile_helper(m4, {
+2 -2
View File
@@ -21,8 +21,8 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCartesianPoint* inst) {
std::vector<double> xyz = inst->Coordinates();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCartesianPoint& inst) {
std::vector<double> xyz = inst.Coordinates();
return taxonomy::make<taxonomy::point3>(
xyz.size() >= 1 ? xyz[0] * length_unit_ : 0.,
xyz.size() >= 2 ? xyz[1] * length_unit_ : 0.,
@@ -21,26 +21,26 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCartesianTransformationOperator2D* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCartesianTransformationOperator2D& inst) {
auto m = taxonomy::make<taxonomy::matrix4>();
Eigen::Vector4d origin, axis1(1.0, 0.0, 0.0, 0.0), axis2(0.0, 1.0, 0.0, 0.0), axis3(0.0, 0.0, 1.0, 0.0);
taxonomy::point3::ptr O = taxonomy::cast<taxonomy::point3>(map(inst->LocalOrigin()));
taxonomy::point3::ptr O = taxonomy::cast<taxonomy::point3>(map(inst.LocalOrigin()));
origin << *O->components_, 1.0;
if (inst->Axis1()) {
taxonomy::direction3::ptr ax1 = taxonomy::cast<taxonomy::direction3>(map(inst->Axis1()));
if (inst.Axis1()) {
taxonomy::direction3::ptr ax1 = taxonomy::cast<taxonomy::direction3>(map(inst.Axis1()));
axis1 << *ax1->components_, 0.0;
if (!inst->Axis2()) {
if (!inst.Axis2()) {
// orthogonal complement
axis2 << -axis1(1), axis1(0), 0., 0.;
}
}
if (inst->Axis2()) {
taxonomy::direction3::ptr ax2 = taxonomy::cast<taxonomy::direction3>(map(inst->Axis2()));
if (inst.Axis2()) {
taxonomy::direction3::ptr ax2 = taxonomy::cast<taxonomy::direction3>(map(inst.Axis2()));
axis2 << *ax2->components_, 0.0;
if (!inst->Axis2()) {
if (!inst.Axis2()) {
// orthogonal complement
axis1 << -axis2(1), axis2(0), 0., 0.;
}
@@ -49,12 +49,12 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCartesianTransformationOpera
double scale1, scale2;
scale1 = 1.0;
if (inst->Scale()) {
scale1 = *inst->Scale();
if (inst.Scale()) {
scale1 = *inst.Scale();
}
if (inst->as<IfcSchema::IfcCartesianTransformationOperator2DnonUniform>()) {
auto nu = inst->as<IfcSchema::IfcCartesianTransformationOperator2DnonUniform>();
scale2 = nu->Scale2() ? *nu->Scale2() : scale1;
if (inst.as<IfcSchema::IfcCartesianTransformationOperator2DnonUniform>()) {
auto nu = inst.as<IfcSchema::IfcCartesianTransformationOperator2DnonUniform>();
scale2 = nu.Scale2() ? *nu.Scale2() : scale1;
} else {
scale2 = scale1;
}
@@ -21,26 +21,26 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCartesianTransformationOperator3D* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCartesianTransformationOperator3D& inst) {
Eigen::Vector4d origin;
Eigen::Vector4d axis1(1., 0., 0., 0.);
Eigen::Vector4d axis2(0., 1., 0., 0.);
Eigen::Vector4d axis3(0., 0., 1., 0.);
taxonomy::point3::ptr O = taxonomy::cast<taxonomy::point3>(map(inst->LocalOrigin()));
taxonomy::point3::ptr O = taxonomy::cast<taxonomy::point3>(map(inst.LocalOrigin()));
origin << *O->components_, 1.0;
if (inst->Axis1()) {
taxonomy::direction3::ptr ax1 = taxonomy::cast<taxonomy::direction3>(map(inst->Axis1()));
if (inst.Axis1()) {
taxonomy::direction3::ptr ax1 = taxonomy::cast<taxonomy::direction3>(map(inst.Axis1()));
axis1 << *ax1->components_, 0.0;
}
if (inst->Axis2()) {
taxonomy::direction3::ptr ax2 = taxonomy::cast<taxonomy::direction3>(map(inst->Axis2()));
if (inst.Axis2()) {
taxonomy::direction3::ptr ax2 = taxonomy::cast<taxonomy::direction3>(map(inst.Axis2()));
axis2 << *ax2->components_, 0.0;
}
if (inst->Axis3()) {
taxonomy::direction3::ptr ax3 = taxonomy::cast<taxonomy::direction3>(map(inst->Axis3()));
if (inst.Axis3()) {
taxonomy::direction3::ptr ax3 = taxonomy::cast<taxonomy::direction3>(map(inst.Axis3()));
axis3 << *ax3->components_, 0.0;
}
@@ -52,13 +52,13 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCartesianTransformationOpera
double scale1, scale2, scale3;
scale1 = 1.;
if (inst->Scale()) {
scale1 = *inst->Scale();
if (inst.Scale()) {
scale1 = *inst.Scale();
}
if (inst->as<IfcSchema::IfcCartesianTransformationOperator3DnonUniform>()) {
auto nu = inst->as<IfcSchema::IfcCartesianTransformationOperator3DnonUniform>();
scale2 = nu->Scale2() ? *nu->Scale2() : scale1;
scale3 = nu->Scale3() ? *nu->Scale3() : scale1;
if (inst.as<IfcSchema::IfcCartesianTransformationOperator3DnonUniform>()) {
auto nu = inst.as<IfcSchema::IfcCartesianTransformationOperator3DnonUniform>();
scale2 = nu.Scale2() ? *nu.Scale2() : scale1;
scale3 = nu.Scale3() ? *nu.Scale3() : scale1;
} else {
scale2 = scale3 = scale1;
}
@@ -21,14 +21,14 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCenterLineProfileDef* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCenterLineProfileDef& inst) {
return nullptr;
/*
const double d = inst->Thickness() * length_unit_ / 2.;
const double d = inst.Thickness() * length_unit_ / 2.;
auto f = taxonomy::make<taxonomy::face>();
auto ofc = taxonomy::make<taxonomy::offset_curve>();
ofc->basis = map(inst->Curve());
ofc->basis = map(inst.Curve());
ofc->offset = d;
// @todo
// f->children.push_back(ofc);
@@ -39,7 +39,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCenterLineProfileDef* inst)
/*
TopoDS_Wire wire;
if (!convert_wire(inst->Curve(), wire)) return false;
if (!convert_wire(inst.Curve(), wire)) return false;
// BRepOffsetAPI_MakeOffset insists on creating circular arc
// segments for joining the curves that constitute the center
+3 -5
View File
@@ -21,16 +21,14 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
#define ALMOST_ZERO 1.e-7;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCircle* inst) {
const double r = inst->Radius() * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCircle& inst) {
const double r = inst.Radius() * length_unit_;
if (r < settings_.get<settings::Precision>().get()) {
Logger::Message(Logger::LOG_ERROR, "Radius not greater than zero for:", inst);
return nullptr;
}
IfcSchema::IfcAxis2Placement* placement = inst->Position();
auto placement = inst.Position();
auto c = taxonomy::make<taxonomy::circle>();
c->radius = r;
c->matrix = taxonomy::cast<taxonomy::matrix4>(map(placement));
+6 -6
View File
@@ -23,11 +23,11 @@ using namespace ifcopenshell::geometry;
#include <boost/math/constants/constants.hpp>
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCircleProfileDef* inst) {
std::vector<double> radii = { inst->Radius() * length_unit_ };
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCircleProfileDef& inst) {
std::vector<double> radii = { inst.Radius() * length_unit_ };
if (inst->as<IfcSchema::IfcCircleHollowProfileDef>()) {
double t = inst->as<IfcSchema::IfcCircleHollowProfileDef>()->WallThickness() * length_unit_;
if (inst.as<IfcSchema::IfcCircleHollowProfileDef>()) {
double t = inst.as<IfcSchema::IfcCircleHollowProfileDef>().WallThickness() * length_unit_;
radii.push_back(radii.front() - t);
}
@@ -42,10 +42,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCircleProfileDef* inst) {
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
c->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
c->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
} else {
// matrix needs to be set on elementary curves
c->matrix = taxonomy::make<taxonomy::matrix4>();
+17 -17
View File
@@ -21,38 +21,38 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve& inst) {
auto loop = taxonomy::make<taxonomy::loop>();
taxonomy::piecewise_function::spans_t spans;
#ifdef SCHEMA_HAS_IfcSegment
// 4x3
IfcSchema::IfcSegment::list::ptr segments = inst->Segments();
std::vector<IfcSchema::IfcSegment> segments = inst.Segments();
#else
IfcSchema::IfcCompositeCurveSegment::list::ptr segments = inst->Segments();
std::vector<IfcSchema::IfcCompositeCurveSegment> segments = inst.Segments();
#endif
for (auto& segment : *segments) {
if (segment->as<IfcSchema::IfcCompositeCurveSegment>() && segment->as<IfcSchema::IfcCompositeCurveSegment>()->ParentCurve()->as<IfcSchema::IfcLine>()) {
for (auto& segment : segments) {
if (segment.as<IfcSchema::IfcCompositeCurveSegment>() && segment.as<IfcSchema::IfcCompositeCurveSegment>().ParentCurve().as<IfcSchema::IfcLine>()) {
Logger::Notice("Infinite IfcLine used as ParentCurve of segment, treating as a segment", segment);
double u0 = 0.0;
double u1 = segment->as<IfcSchema::IfcCompositeCurveSegment>()->ParentCurve()->as<IfcSchema::IfcLine>()->Dir()->Magnitude() * length_unit_;
double u1 = segment.as<IfcSchema::IfcCompositeCurveSegment>().ParentCurve().as<IfcSchema::IfcLine>().Dir().Magnitude() * length_unit_;
if (u1 < settings_.get<settings::Precision>().get()) {
Logger::Warning("Segment length below tolerance", segment);
}
auto e = taxonomy::make<taxonomy::edge>();
e->basis = map(segment->as<IfcSchema::IfcCompositeCurveSegment>()->ParentCurve());
e->basis = map(segment.as<IfcSchema::IfcCompositeCurveSegment>().ParentCurve());
e->start = u0;
e->end = u1;
e->curve_sense.reset(segment->as<IfcSchema::IfcCompositeCurveSegment>()->SameSense());
e->curve_sense.emplace(segment.as<IfcSchema::IfcCompositeCurveSegment>().SameSense());
loop->children.push_back(e);
}
else if (segment->as<IfcSchema::IfcCompositeCurveSegment>()) {
auto crv = map(segment->as<IfcSchema::IfcCompositeCurveSegment>()->ParentCurve());
else if (segment.as<IfcSchema::IfcCompositeCurveSegment>()) {
auto crv = map(segment.as<IfcSchema::IfcCompositeCurveSegment>().ParentCurve());
if (crv) {
if (!segment->as<IfcSchema::IfcCompositeCurveSegment>()->SameSense()) {
if (!segment.as<IfcSchema::IfcCompositeCurveSegment>().SameSense()) {
crv->reverse();
}
if (crv->kind() == taxonomy::EDGE) {
@@ -62,7 +62,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) {
for (auto& s : taxonomy::cast<taxonomy::loop>(crv)->children) {
loop->children.push_back(s);
}
} else if ((crv->kind() == taxonomy::CIRCLE || crv->kind() == taxonomy::ELLIPSE) && segments->size() == 1) {
} else if ((crv->kind() == taxonomy::CIRCLE || crv->kind() == taxonomy::ELLIPSE) && segments.size() == 1) {
// A circle or ellipse segment is a full circle/ellipse, only possible when it is the only segment
std::shared_ptr<taxonomy::edge> e = std::make_shared<taxonomy::edge>();
e->basis = crv;
@@ -76,9 +76,9 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) {
}
}
#ifdef SCHEMA_HAS_IfcCurveSegment
else if (segment->as<IfcSchema::IfcCurveSegment>()) {
else if (segment.as<IfcSchema::IfcCurveSegment>()) {
// @todo check that we don't get a mixture of implicit and explicit definitions
auto crv = map(segment->as<IfcSchema::IfcCurveSegment>());
auto crv = map(segment.as<IfcSchema::IfcCurveSegment>());
if (crv && crv->kind() == taxonomy::LOOP) {
for (auto& s : taxonomy::cast<taxonomy::loop>(crv)->children) {
loop->children.push_back(s);
@@ -95,8 +95,8 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) {
}
if (spans.empty()) {
aggregate_of_instance::ptr profile = inst->file_->getInverse(inst->id(), &IfcSchema::IfcProfileDef::Class(), -1);
const bool force_close = profile && profile->size() > 0;
std::vector<express::Entity> profile = inst.data()->file()->getInverse(inst.id(), &IfcSchema::IfcProfileDef::Class(), -1);
const bool force_close = !profile.empty();
loop->closed = force_close;
loop->instance = inst;
return loop;
@@ -182,7 +182,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve* l, TopoDS_Wi
TopTools_ListIteratorOfListOfShape it(converted_segments);
aggregate_of_instance::ptr profile = inst->data().getInverse(&IfcSchema::IfcProfileDef::Class(), -1);
std::vector<express::Base> profile = inst.data().getInverse(&IfcSchema::IfcProfileDef::Class(), -1);
const bool force_close = profile && profile->size() > 0;
util::wire_builder bld(getValue(GV_PRECISION), l);
@@ -21,8 +21,8 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeProfileDef* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeProfileDef& inst) {
// @todo double check that this is actually supported
IfcSchema::IfcProfileDef::list::ptr profiles = inst->Profiles();
std::vector<IfcSchema::IfcProfileDef> profiles = inst.Profiles();
return map_to_collection<>(this, profiles);
}
+3 -3
View File
@@ -21,11 +21,11 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcConnectedFaceSet* inst) {
auto shell = map_to_collection<taxonomy::shell>(this, inst->CfsFaces());
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcConnectedFaceSet& inst) {
auto shell = map_to_collection<taxonomy::shell>(this, inst.CfsFaces());
if (!shell) {
return nullptr;
}
shell->closed = inst->declaration().is(IfcSchema::IfcClosedShell::Class());
shell->closed = inst.declaration().is(IfcSchema::IfcClosedShell::Class());
return shell;
}
@@ -25,25 +25,25 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcCraneRailAShapeProfileDef
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCraneRailAShapeProfileDef* inst) {
double oh = inst->OverallHeight() * length_unit_;
double bw2 = inst->BaseWidth2() * length_unit_;
double hw = inst->HeadWidth() * length_unit_;
double hd2 = inst->HeadDepth2() * length_unit_;
double hd3 = inst->HeadDepth3() * length_unit_;
double wt = inst->WebThickness() * length_unit_;
double bw4 = inst->BaseWidth4() * length_unit_;
double bd1 = inst->BaseDepth1() * length_unit_;
double bd2 = inst->BaseDepth2() * length_unit_;
double bd3 = inst->BaseDepth3() * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCraneRailAShapeProfileDef& inst) {
double oh = inst.OverallHeight() * length_unit_;
double bw2 = inst.BaseWidth2() * length_unit_;
double hw = inst.HeadWidth() * length_unit_;
double hd2 = inst.HeadDepth2() * length_unit_;
double hd3 = inst.HeadDepth3() * length_unit_;
double wt = inst.WebThickness() * length_unit_;
double bw4 = inst.BaseWidth4() * length_unit_;
double bd1 = inst.BaseDepth1() * length_unit_;
double bd2 = inst.BaseDepth2() * length_unit_;
double bd3 = inst.BaseDepth3() * length_unit_;
taxonomy::matrix4::ptr m4;
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
return profile_helper(m4, {
+2 -2
View File
@@ -21,6 +21,6 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCsgSolid* inst) {
return map(inst->TreeRootExpression());
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCsgSolid& inst) {
return map(inst.TreeRootExpression());
}
+6 -6
View File
@@ -21,15 +21,15 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCurveBoundedPlane* inst) {
taxonomy::plane::ptr pl = taxonomy::cast<taxonomy::plane>(map(inst->BasisSurface()));
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCurveBoundedPlane& inst) {
taxonomy::plane::ptr pl = taxonomy::cast<taxonomy::plane>(map(inst.BasisSurface()));
auto f = taxonomy::make<taxonomy::face>();
f->children.push_back(taxonomy::cast<taxonomy::loop>(map(inst->OuterBoundary())));
f->children.push_back(taxonomy::cast<taxonomy::loop>(map(inst.OuterBoundary())));
IfcSchema::IfcCurve::list::ptr boundaries = inst->InnerBoundaries();
std::vector<IfcSchema::IfcCurve> boundaries = inst.InnerBoundaries();
for (IfcSchema::IfcCurve::list::it it = boundaries->begin(); it != boundaries->end(); ++it) {
f->children.push_back(taxonomy::cast<taxonomy::loop>(map(*it)));
for (auto& b : boundaries) {
f->children.push_back(taxonomy::cast<taxonomy::loop>(map(b)));
}
f->matrix = pl->matrix;
+133 -137
View File
@@ -44,19 +44,19 @@ enum segment_type_t {
// @todo use std::numbers::pi when upgrading to C++ 20
static const double PI = boost::math::constants::pi<double>();
double translate_to_length_measure(const IfcSchema::IfcCurve* crv, double param_value) {
double translate_to_length_measure(const IfcSchema::IfcCurve& crv, double param_value) {
if (std::abs(param_value) < 1.e-7) {
return param_value;
} else if (auto line = crv->as<IfcSchema::IfcLine>()) {
return line->Dir()->Magnitude() * param_value;
} else if (auto clothoid = crv->as<IfcSchema::IfcClothoid>()) {
} else if (auto line = crv.as<IfcSchema::IfcLine>()) {
return line.Dir().Magnitude() * param_value;
} else if (auto clothoid = crv.as<IfcSchema::IfcClothoid>()) {
// param_value = 1.0, corresponds to tangent direction = PI/2
// param_value = (arc length)/fabs(A*PI)
return fabs(clothoid->ClothoidConstant()*sqrt(PI))*param_value;
} else if (auto circ = crv->as<IfcSchema::IfcCircle>()) {
return circ->Radius() * param_value;
return fabs(clothoid.ClothoidConstant()*sqrt(PI))*param_value;
} else if (auto circ = crv.as<IfcSchema::IfcCircle>()) {
return circ.Radius() * param_value;
#ifdef SCHEMA_HAS_IfcPolynomialCurve
} else if (auto poly = crv->as<IfcSchema::IfcPolynomialCurve>()) {
} else if (auto poly = crv.as<IfcSchema::IfcPolynomialCurve>()) {
return param_value;
#endif
} else {
@@ -64,12 +64,12 @@ double translate_to_length_measure(const IfcSchema::IfcCurve* crv, double param_
}
}
double translate_if_param_value(const IfcSchema::IfcCurve* crv, IfcSchema::IfcCurveMeasureSelect* val) {
if (auto param = val->as<IfcSchema::IfcParameterValue>()) {
double translate_if_param_value(const IfcSchema::IfcCurve& crv, const IfcSchema::IfcCurveMeasureSelect& val) {
if (auto param = val.as<IfcSchema::IfcParameterValue>()) {
// We don't care whether length- or positive length measure.
return translate_to_length_measure(crv, *param);
return translate_to_length_measure(crv, param);
} else {
return val->as<IfcUtil::IfcBaseClass>()->get_attribute_value(0);
return val.concrete().get_attribute_value(0);
}
}
@@ -181,12 +181,12 @@ struct cant_curve_segment_function {
class curve_segment_evaluator {
private:
mapping* mapping_ = nullptr;
const IfcSchema::IfcCurveSegment* inst_ = nullptr; // this curve segment instance
IfcSchema::IfcCurveSegment inst_; // this curve segment instance
double length_unit_;
double start_;
double length_; // length along the curve, as provided from the IfcCurveSegment
segment_type_t segment_type_;
const IfcSchema::IfcCurve* parent_curve_ = nullptr;
IfcSchema::IfcCurve parent_curve_;
double projected_length_; // for vertical segments, this is the length of curve projected onto the "Distance Along" axis
@@ -197,51 +197,47 @@ class curve_segment_evaluator {
std::optional<Eigen::Matrix4d> next_segment_placement_; // placement of the next segment
public:
curve_segment_evaluator(mapping* mapping, const IfcSchema::IfcCurveSegment* inst, double length_unit)
curve_segment_evaluator(mapping* mapping, const IfcSchema::IfcCurveSegment& inst, double length_unit)
: mapping_(mapping),
inst_(inst),
length_unit_(length_unit),
parent_curve_(inst->ParentCurve()) {
parent_curve_(inst.ParentCurve()) {
#ifdef SCHEMA_IfcSegment_HAS_UsingCurves
auto composite_curves = inst->UsingCurves();
auto composite_curves = inst.UsingCurves();
#else
aggregate_of<IfcSchema::IfcCompositeCurve>::ptr composite_curves;
throw std::runtime_error("Schema not supported");
#endif
// Find the next segment after inst
const IfcSchema::IfcCurveSegment* next_inst = nullptr;
if (composite_curves) {
if (composite_curves->size() == 1) {
auto segments = (*composite_curves->begin())->as<IfcSchema::IfcCompositeCurve>()->Segments();
bool emit_next = false;
for (auto& s : *segments) {
if (emit_next) {
next_inst = s->as<IfcSchema::IfcCurveSegment>();
break;
}
if (s == inst) {
emit_next = true;
}
IfcSchema::IfcCurveSegment next_inst;
if (composite_curves.size() == 1) {
auto segments = composite_curves.front().as<IfcSchema::IfcCompositeCurve>().Segments();
bool emit_next = false;
for (auto& s : segments) {
if (emit_next) {
next_inst = s.as<IfcSchema::IfcCurveSegment>();
break;
}
if (s == inst) {
emit_next = true;
}
} else {
Logger::Warning("IfcCurveSegment belongs to multiple IfcCompositeCurve instances. Cannot determine the next segment.");
}
} else {
Logger::Warning("IfcCurveSegment belongs to multiple IfcCompositeCurve instances. Cannot determine the next segment.");
}
bool is_horizontal = false;
bool is_vertical = false;
bool is_cant = false;
if (composite_curves) {
for (auto& cc : *composite_curves) {
if (cc->as<IfcSchema::IfcSegmentedReferenceCurve>()) {
is_cant = true;
} else if (cc->as<IfcSchema::IfcGradientCurve>()) {
is_vertical = true;
} else {
is_horizontal = true;
}
for (auto& cc : composite_curves) {
if (cc.as<IfcSchema::IfcSegmentedReferenceCurve>()) {
is_cant = true;
} else if (cc.as<IfcSchema::IfcGradientCurve>()) {
is_vertical = true;
} else {
is_horizontal = true;
}
}
@@ -254,36 +250,36 @@ class curve_segment_evaluator {
segment_type_ = is_horizontal ? ST_HORIZONTAL : is_vertical ? ST_VERTICAL : is_cant ? ST_CANT : ST_HORIZONTAL;
#ifdef SCHEMA_IfcCurveSegment_HAS_SegmentStart
start_ = translate_if_param_value(inst->ParentCurve(), inst->SegmentStart()) * length_unit;
start_ = translate_if_param_value(inst.ParentCurve(), inst.SegmentStart()) * length_unit;
#else
throw std::runtime_error("Schema not supported");
#endif
length_ = translate_if_param_value(inst->ParentCurve(), inst->SegmentLength()) * length_unit;
length_ = translate_if_param_value(inst.ParentCurve(), inst.SegmentLength()) * length_unit;
projected_length_ = length_; // initialize with something reasonable
if (inst) {
#ifdef SCHEMA_IfcCurveSegment_HAS_Placement
curve_segment_placement_ = taxonomy::cast<taxonomy::matrix4>(mapping_->map(inst->Placement()))->ccomponents();
curve_segment_placement_ = taxonomy::cast<taxonomy::matrix4>(mapping_->map(inst.Placement()))->ccomponents();
#endif
}
if (next_inst) {
#ifdef SCHEMA_IfcCurveSegment_HAS_Placement
next_segment_placement_ = taxonomy::cast<taxonomy::matrix4>(mapping_->map(next_inst->Placement()))->ccomponents();
next_segment_placement_ = taxonomy::cast<taxonomy::matrix4>(mapping_->map(next_inst.Placement()))->ccomponents();
#endif
} else {
// there is not a next segment, however IfcGradientCurve and IfcSegmentReferenceCurve have an
// optional EndPoint which services the same purpose as the zero-length last segment.
IfcSchema::IfcPlacement* end_point = nullptr;
if (composite_curves->size() == 1) {
auto& cc = *(composite_curves)->begin();
IfcSchema::IfcPlacement end_point;
if (composite_curves.size() == 1) {
auto& cc = composite_curves.front();
if (segment_type_ == ST_VERTICAL) {
auto gradient_curve = cc->as<IfcSchema::IfcGradientCurve>();
auto gradient_curve = cc.as<IfcSchema::IfcGradientCurve>();
#ifdef SCHEMA_IfcCurveSegment_HAS_Placement
end_point = gradient_curve->EndPoint();
end_point = gradient_curve.EndPoint();
#endif
} else if (segment_type_ == ST_CANT) {
auto segmented_reference_curve = cc->as<IfcSchema::IfcSegmentedReferenceCurve>();
end_point = segmented_reference_curve->EndPoint();
auto segmented_reference_curve = cc.as<IfcSchema::IfcSegmentedReferenceCurve>();
end_point = segmented_reference_curve.EndPoint();
}
} else {
Logger::Warning("IfcCurveSegment belongs to multiple IfcCompositeCurve instances. Cannot determine the end point.");
@@ -297,8 +293,8 @@ class curve_segment_evaluator {
// Take the boost::type value from mpl::for_each and test it against our curve instance
template <typename T>
void operator()(boost::type<T>) {
if (parent_curve_->as<T>()) {
(*this)(parent_curve_->as<T>());
if (parent_curve_.as<T>()) {
(*this)(parent_curve_.as<T>());
}
}
@@ -308,7 +304,7 @@ class curve_segment_evaluator {
taxonomy::ptr get_segment_curve_function() {
if (!parent_curve_fn_ || !parent_curve_start_point_) {
Logger::Error(std::runtime_error(inst_->ParentCurve()->declaration().name() + " not implemented"), inst_);
Logger::Error(std::runtime_error(inst_.ParentCurve().declaration().name() + " not implemented"), inst_);
}
auto length = fabs(this->length());
@@ -521,9 +517,9 @@ class curve_segment_evaluator {
// returns function for super elevation and the slope of the super elevation curve if the super elevation is constant
// over the length of the segment. otherwise, no functions are returned because they are the same as the cant tilt angle
// functions.
std::pair<boost::optional<std::function<double(double)>>, boost::optional<std::function<double(double)>>> get_superelevation_functions() {
boost::optional<std::function<double(double)>> superelevation_fn;
boost::optional<std::function<double(double)>> superelevation_slope_fn;
std::pair<std::optional<std::function<double(double)>>, std::optional<std::function<double(double)>>> get_superelevation_functions() {
std::optional<std::function<double(double)>> superelevation_fn;
std::optional<std::function<double(double)>> superelevation_slope_fn;
if (curve_segment_placement_.has_value() && next_segment_placement_.has_value()) {
double y1 = (*curve_segment_placement_)(1, 3);
@@ -541,12 +537,12 @@ class curve_segment_evaluator {
}
#ifdef SCHEMA_HAS_IfcClothoid
void operator()(const IfcSchema::IfcClothoid* c) {
auto A = c->ClothoidConstant() * length_unit_;
void operator()(const IfcSchema::IfcClothoid& c) {
auto A = c.ClothoidConstant() * length_unit_;
auto L = length(); // already includes length_unit_
if (segment_type_ == ST_CANT) {
boost::optional<std::function<double(double)>> super, slope;
std::optional<std::function<double(double)>> super, slope;
std::tie(super, slope) = get_superelevation_functions();
auto cant = [A, L](double t) -> double { return A ? L * L * A * t / fabs(pow(A, 3)) : 0.0; };
@@ -570,12 +566,12 @@ class curve_segment_evaluator {
#endif
#if defined SCHEMA_HAS_IfcCosineSpiral
void operator()(const IfcSchema::IfcCosineSpiral* c) {
auto constant_term = c->ConstantTerm();
void operator()(const IfcSchema::IfcCosineSpiral& c) {
auto constant_term = c.ConstantTerm();
if (constant_term.has_value()) {
constant_term.value() *= length_unit_;
}
auto cosine_term = c->CosineTerm() * length_unit_;
auto cosine_term = c.CosineTerm() * length_unit_;
auto L = length(); // already converted to internal units by constructor
if (segment_type_ == ST_HORIZONTAL) {
@@ -594,7 +590,7 @@ class curve_segment_evaluator {
double s = 1.0;
set_spiral_function(s, fn_x, fn_y, curvature);
} else if (segment_type_ == ST_CANT) {
boost::optional<std::function<double(double)>> super, slope;
std::optional<std::function<double(double)>> super, slope;
std::tie(super, slope) = get_superelevation_functions();
auto cant = [constant_term, cosine_term, L](double t) -> double {
@@ -632,16 +628,16 @@ class curve_segment_evaluator {
#endif
#if defined SCHEMA_HAS_IfcSineSpiral
void operator()(const IfcSchema::IfcSineSpiral* c) {
auto constant_term = c->ConstantTerm();
void operator()(const IfcSchema::IfcSineSpiral& c) {
auto constant_term = c.ConstantTerm();
if (constant_term.has_value()) {
constant_term.value() *= length_unit_;
}
auto linear_term = c->LinearTerm();
auto linear_term = c.LinearTerm();
if (linear_term.has_value()) {
linear_term.value() *= length_unit_;
}
auto sine_term = c->SineTerm() * length_unit_;
auto sine_term = c.SineTerm() * length_unit_;
auto L = length(); // already converted to internal units by constructor
if (segment_type_ == ST_HORIZONTAL) {
auto theta = [constant_term, linear_term, sine_term, L](double t) -> double {
@@ -661,7 +657,7 @@ class curve_segment_evaluator {
double s = 1.0;
set_spiral_function(s, fn_x, fn_y, curvature);
} else if (segment_type_ == ST_CANT) {
boost::optional<std::function<double(double)>> super, slope;
std::optional<std::function<double(double)>> super, slope;
std::tie(super, slope) = get_superelevation_functions();
auto cant = [constant_term, linear_term, sine_term, L](double t) -> double {
@@ -698,16 +694,16 @@ class curve_segment_evaluator {
}
#endif
void polynomial_spiral(boost::optional<double> A0, boost::optional<double> A1, boost::optional<double> A2, boost::optional<double> A3, boost::optional<double> A4, boost::optional<double> A5, boost::optional<double> A6, boost::optional<double> A7) {
void polynomial_spiral(std::optional<double> A0, std::optional<double> A1, std::optional<double> A2, std::optional<double> A3, std::optional<double> A4, std::optional<double> A5, std::optional<double> A6, std::optional<double> A7) {
auto theta = [A0, A1, A2, A3, A4, A5, A6, A7, start = start_ * length_unit_, lu = length_unit_](double t) -> double {
auto a0 = A0.get_value_or(0.0) != 0.0 ? t / (A0.value() * lu) : 0.0;
auto a1 = A1.get_value_or(0.0) != 0.0 ? A1.value() * lu * std::pow(t, 2) / (2 * fabs(std::pow(A1.value() * lu, 3))) : 0.0;
auto a2 = A2.get_value_or(0.0) != 0.0 ? std::pow(t, 3) / (3 * std::pow(A2.value() * lu, 3)) : 0.0;
auto a3 = A3.get_value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 4) / (4 * fabs(std::pow(A3.value() * lu, 5))) : 0.0;
auto a4 = A4.get_value_or(0.0) != 0.0 ? std::pow(t, 5) / (5 * std::pow(A4.value() * lu, 5)) : 0.0;
auto a5 = A5.get_value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 6) / (6 * fabs(std::pow(A5.value() * lu, 7))) : 0.0;
auto a6 = A6.get_value_or(0.0) != 0.0 ? std::pow(t, 7) / (7 * std::pow(A6.value() * lu, 7)) : 0.0;
auto a7 = A7.get_value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 8) / (8 * fabs(std::pow(A7.value() * lu, 9))) : 0.0;
auto a0 = A0.value_or(0.0) != 0.0 ? t / (A0.value() * lu) : 0.0;
auto a1 = A1.value_or(0.0) != 0.0 ? A1.value() * lu * std::pow(t, 2) / (2 * fabs(std::pow(A1.value() * lu, 3))) : 0.0;
auto a2 = A2.value_or(0.0) != 0.0 ? std::pow(t, 3) / (3 * std::pow(A2.value() * lu, 3)) : 0.0;
auto a3 = A3.value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 4) / (4 * fabs(std::pow(A3.value() * lu, 5))) : 0.0;
auto a4 = A4.value_or(0.0) != 0.0 ? std::pow(t, 5) / (5 * std::pow(A4.value() * lu, 5)) : 0.0;
auto a5 = A5.value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 6) / (6 * fabs(std::pow(A5.value() * lu, 7))) : 0.0;
auto a6 = A6.value_or(0.0) != 0.0 ? std::pow(t, 7) / (7 * std::pow(A6.value() * lu, 7)) : 0.0;
auto a7 = A7.value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 8) / (8 * fabs(std::pow(A7.value() * lu, 9))) : 0.0;
return a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7;
};
@@ -718,14 +714,14 @@ class curve_segment_evaluator {
// this is same as cant function in polynomial_cant_spiral
auto curvature = [A0, A1, A2, A3, A4, A5, A6, A7, start = start_, L = length_, lu = length_unit_, length = length_](double t) -> double {
t += start;
auto a0 = A0.get_value_or(0.0) != 0.0 ? 1 / (A0.value() * lu) : 0.0;
auto a1 = A1.get_value_or(0.0) != 0.0 ? A1.value() * lu * t / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
auto a2 = A2.get_value_or(0.0) != 0.0 ? std::pow(t, 2) / std::pow(A2.value() * lu, 3) : 0.0;
auto a3 = A3.get_value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 3) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
auto a4 = A4.get_value_or(0.0) != 0.0 ? std::pow(t, 4) / std::pow(A4.value() * lu, 5) : 0.0;
auto a5 = A5.get_value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 5) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
auto a6 = A6.get_value_or(0.0) != 0.0 ? std::pow(t, 6) / std::pow(A6.value() * lu, 7) : 0.0;
auto a7 = A7.get_value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 7) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
auto a0 = A0.value_or(0.0) != 0.0 ? 1 / (A0.value() * lu) : 0.0;
auto a1 = A1.value_or(0.0) != 0.0 ? A1.value() * lu * t / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
auto a2 = A2.value_or(0.0) != 0.0 ? std::pow(t, 2) / std::pow(A2.value() * lu, 3) : 0.0;
auto a3 = A3.value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 3) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
auto a4 = A4.value_or(0.0) != 0.0 ? std::pow(t, 4) / std::pow(A4.value() * lu, 5) : 0.0;
auto a5 = A5.value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 5) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
auto a6 = A6.value_or(0.0) != 0.0 ? std::pow(t, 6) / std::pow(A6.value() * lu, 7) : 0.0;
auto a7 = A7.value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 7) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
return L * (a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7);
};
@@ -734,20 +730,20 @@ class curve_segment_evaluator {
set_spiral_function(s, fn_x, fn_y, curvature);
}
void polynomial_cant_spiral(boost::optional<double> A0, boost::optional<double> A1, boost::optional<double> A2, boost::optional<double> A3, boost::optional<double> A4, boost::optional<double> A5, boost::optional<double> A6, boost::optional<double> A7) {
boost::optional<std::function<double(double)>> super, slope;
void polynomial_cant_spiral(std::optional<double> A0, std::optional<double> A1, std::optional<double> A2, std::optional<double> A3, std::optional<double> A4, std::optional<double> A5, std::optional<double> A6, std::optional<double> A7) {
std::optional<std::function<double(double)>> super, slope;
std::tie(super, slope) = get_superelevation_functions();
auto cant = [A0, A1, A2, A3, A4, A5, A6, A7, start = start_, L = length_, lu = length_unit_, length = length_](double t) -> double {
t += start;
auto a0 = A0.get_value_or(0.0) != 0.0 ? 1 / (A0.value() * lu) : 0.0;
auto a1 = A1.get_value_or(0.0) != 0.0 ? A1.value() * lu * t / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
auto a2 = A2.get_value_or(0.0) != 0.0 ? std::pow(t, 2) / std::pow(A2.value() * lu, 3) : 0.0;
auto a3 = A3.get_value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 3) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
auto a4 = A4.get_value_or(0.0) != 0.0 ? std::pow(t, 4) / std::pow(A4.value() * lu, 5) : 0.0;
auto a5 = A5.get_value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 5) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
auto a6 = A6.get_value_or(0.0) != 0.0 ? std::pow(t, 6) / std::pow(A6.value() * lu, 7) : 0.0;
auto a7 = A7.get_value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 7) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
auto a0 = A0.value_or(0.0) != 0.0 ? 1 / (A0.value() * lu) : 0.0;
auto a1 = A1.value_or(0.0) != 0.0 ? A1.value() * lu * t / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
auto a2 = A2.value_or(0.0) != 0.0 ? std::pow(t, 2) / std::pow(A2.value() * lu, 3) : 0.0;
auto a3 = A3.value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 3) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
auto a4 = A4.value_or(0.0) != 0.0 ? std::pow(t, 4) / std::pow(A4.value() * lu, 5) : 0.0;
auto a5 = A5.value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 5) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
auto a6 = A6.value_or(0.0) != 0.0 ? std::pow(t, 6) / std::pow(A6.value() * lu, 7) : 0.0;
auto a7 = A7.value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 7) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
return L * L * (a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7);
};
@@ -758,13 +754,13 @@ class curve_segment_evaluator {
if (!slope.has_value()) {
slope = [A1, A2, A3, A4, A5, A6, A7, start = start_, L = length_, lu = length_unit_, length = length_](double t) -> double {
t += start;
auto a1 = A1.get_value_or(0.0) != 0.0 ? A1.value() * lu / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
auto a2 = A2.get_value_or(0.0) != 0.0 ? 2 * t / std::pow(A2.value() * lu, 3) : 0.0;
auto a3 = A3.get_value_or(0.0) != 0.0 ? 3 * A3.value() * lu * std::pow(t, 2) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
auto a4 = A4.get_value_or(0.0) != 0.0 ? 4 * std::pow(t, 3) / std::pow(A4.value() * lu, 5) : 0.0;
auto a5 = A5.get_value_or(0.0) != 0.0 ? 5 * A5.value() * lu * std::pow(t, 4) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
auto a6 = A6.get_value_or(0.0) != 0.0 ? 6 * std::pow(t, 5) / std::pow(A6.value() * lu, 7) : 0.0;
auto a7 = A7.get_value_or(0.0) != 0.0 ? 7 * A7.value() * lu * std::pow(t, 6) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
auto a1 = A1.value_or(0.0) != 0.0 ? A1.value() * lu / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
auto a2 = A2.value_or(0.0) != 0.0 ? 2 * t / std::pow(A2.value() * lu, 3) : 0.0;
auto a3 = A3.value_or(0.0) != 0.0 ? 3 * A3.value() * lu * std::pow(t, 2) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
auto a4 = A4.value_or(0.0) != 0.0 ? 4 * std::pow(t, 3) / std::pow(A4.value() * lu, 5) : 0.0;
auto a5 = A5.value_or(0.0) != 0.0 ? 5 * A5.value() * lu * std::pow(t, 4) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
auto a6 = A6.value_or(0.0) != 0.0 ? 6 * std::pow(t, 5) / std::pow(A6.value() * lu, 7) : 0.0;
auto a7 = A7.value_or(0.0) != 0.0 ? 7 * A7.value() * lu * std::pow(t, 6) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
return L * L * (a1 + a2 + a3 + a4 + a5 + a6 + a7);
};
}
@@ -773,11 +769,11 @@ class curve_segment_evaluator {
}
#ifdef SCHEMA_HAS_IfcSecondOrderPolynomialSpiral
void operator()(const IfcSchema::IfcSecondOrderPolynomialSpiral* c) {
auto A0 = c->ConstantTerm();
auto A1 = c->LinearTerm();
auto A2 = c->QuadraticTerm();
boost::optional<double> A3, A4, A5, A6, A7;
void operator()(const IfcSchema::IfcSecondOrderPolynomialSpiral& c) {
auto A0 = c.ConstantTerm();
auto A1 = c.LinearTerm();
auto A2 = c.QuadraticTerm();
std::optional<double> A3, A4, A5, A6, A7;
if (segment_type_ == ST_CANT) {
polynomial_cant_spiral(A0, A1, A2, A3, A4, A5, A6, A7);
@@ -788,15 +784,15 @@ class curve_segment_evaluator {
#endif
#ifdef SCHEMA_HAS_IfcThirdOrderPolynomialSpiral
void operator()(const IfcSchema::IfcThirdOrderPolynomialSpiral* c) {
auto A0 = c->ConstantTerm();
auto A1 = c->LinearTerm();
auto A2 = c->QuadraticTerm();
boost::optional<double> A3, A4, A5, A6, A7;
void operator()(const IfcSchema::IfcThirdOrderPolynomialSpiral& c) {
auto A0 = c.ConstantTerm();
auto A1 = c.LinearTerm();
auto A2 = c.QuadraticTerm();
std::optional<double> A3, A4, A5, A6, A7;
#ifdef SCHEMA_IfcThirdOrderPolynomialSpiral_HAS_CubicTerm
A3 = c->CubicTerm();
A3 = c.CubicTerm();
#else
A3 = c->QubicTerm();
A3 = c.QubicTerm();
#endif
if (segment_type_ == ST_CANT) {
@@ -808,15 +804,15 @@ class curve_segment_evaluator {
#endif
#ifdef SCHEMA_HAS_IfcSeventhOrderPolynomialSpiral
void operator()(const IfcSchema::IfcSeventhOrderPolynomialSpiral* c) {
auto A0 = c->ConstantTerm();
auto A1 = c->LinearTerm();
auto A2 = c->QuadraticTerm();
auto A3 = c->CubicTerm();
auto A4 = c->QuarticTerm();
auto A5 = c->QuinticTerm();
auto A6 = c->SexticTerm();
auto A7 = c->SepticTerm();
void operator()(const IfcSchema::IfcSeventhOrderPolynomialSpiral& c) {
auto A0 = c.ConstantTerm();
auto A1 = c.LinearTerm();
auto A2 = c.QuadraticTerm();
auto A3 = c.CubicTerm();
auto A4 = c.QuarticTerm();
auto A5 = c.QuinticTerm();
auto A6 = c.SexticTerm();
auto A7 = c.SepticTerm();
if (segment_type_ == ST_CANT) {
polynomial_cant_spiral(A0, A1, A2, A3, A4, A5, A6, A7);
@@ -826,10 +822,10 @@ class curve_segment_evaluator {
}
#endif
void operator()(const IfcSchema::IfcCircle* c) {
void operator()(const IfcSchema::IfcCircle& c) {
if (segment_type_ == ST_HORIZONTAL || segment_type_ == ST_VERTICAL) {
auto R = c->Radius() * length_unit_;
auto parent_curve_position = taxonomy::cast<taxonomy::matrix4>(mapping_->map(c->Position()))->ccomponents();
auto R = c.Radius() * length_unit_;
auto parent_curve_position = taxonomy::cast<taxonomy::matrix4>(mapping_->map(c.Position()))->ccomponents();
// center point of the parent curve
auto pcCenterX = parent_curve_position(0, 3);
@@ -854,7 +850,7 @@ class curve_segment_evaluator {
} else {
Eigen::Matrix4d curve_segment_placement;
#ifdef SCHEMA_IfcCurveSegment_HAS_Placement
curve_segment_placement = taxonomy::cast<taxonomy::matrix4>(mapping_->map(inst_->Placement()))->ccomponents();
curve_segment_placement = taxonomy::cast<taxonomy::matrix4>(mapping_->map(inst_.Placement()))->ccomponents();
#endif
auto csStartX = curve_segment_placement(0, 3);
auto csStartY = curve_segment_placement(1, 3);
@@ -965,10 +961,10 @@ class curve_segment_evaluator {
}
}
void operator()(const IfcSchema::IfcLine* l) {
void operator()(const IfcSchema::IfcLine& l) {
projected_length_ = length_;
auto c = l->Pnt()->Coordinates();
auto c = l.Pnt().Coordinates();
auto pcX = c[0] * length_unit_;
auto pcY = c[1] * length_unit_;
@@ -980,7 +976,7 @@ class curve_segment_evaluator {
//
// Magnitude is not used because it relates to the parameterization of the line, which isn't currently done for IfcCurveSegment
// @todo - parameterization was recently added so Magnitude needs to be taking into consideration
auto dr = l->Dir()->Orientation()->DirectionRatios();
auto dr = l.Dir().Orientation().DirectionRatios();
// normalize the direction ratios
double m_squared = std::inner_product(dr.begin(), dr.end(), dr.begin(), 0.0);
@@ -1039,11 +1035,11 @@ class curve_segment_evaluator {
}
#ifdef SCHEMA_HAS_IfcPolynomialCurve
void operator()(const IfcSchema::IfcPolynomialCurve* pc) {
void operator()(const IfcSchema::IfcPolynomialCurve& pc) {
// see https://forums.buildingsmart.org/t/ifcpolynomialcurve-clarification/4716 for discussion on IfcPolynomialCurve
auto coeffX = pc->CoefficientsX().get_value_or(std::vector<double>());
auto coeffY = pc->CoefficientsY().get_value_or(std::vector<double>());
auto coeffZ = pc->CoefficientsZ().get_value_or(std::vector<double>());
auto coeffX = pc.CoefficientsX().value_or(std::vector<double>());
auto coeffY = pc.CoefficientsY().value_or(std::vector<double>());
auto coeffZ = pc.CoefficientsZ().value_or(std::vector<double>());
if (!coeffZ.empty()) {
Logger::Warning("Expected IfcPolynomialCurve.CoefficientsZ to be undefined for alignment geometry. Coefficients ignored.", pc);
}
@@ -1187,7 +1183,7 @@ class curve_segment_evaluator {
};
} // namespace
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCurveSegment* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCurveSegment& inst) {
curve_segment_evaluator cse(this, inst, length_unit_);
boost::mpl::for_each<curve_seg_types, boost::type<boost::mpl::_>>(std::ref(cse));
return cse.get_segment_curve_function();
@@ -23,10 +23,10 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcCylindricalSurface
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCylindricalSurface* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCylindricalSurface& inst) {
auto c = taxonomy::make<taxonomy::cylinder>();
c->radius = inst->Radius() * length_unit_;
c->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
c->radius = inst.Radius() * length_unit_;
c->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
return c;
}
+4 -4
View File
@@ -21,8 +21,8 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcDerivedProfileDef* inst) {
auto it = map(inst->ParentProfile());
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcDerivedProfileDef& inst) {
auto it = map(inst.ParentProfile());
if (it == nullptr) {
return nullptr;
}
@@ -32,7 +32,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcDerivedProfileDef* inst) {
taxonomy::matrix4::ptr m;
bool is_mirror = false;
#ifdef SCHEMA_HAS_IfcMirroredProfileDef
if (inst->as<IfcSchema::IfcMirroredProfileDef>()) {
if (inst.as<IfcSchema::IfcMirroredProfileDef>()) {
m = taxonomy::make<taxonomy::matrix4>();
// @todo test
m->components().col(0) *= -1.;
@@ -40,7 +40,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcDerivedProfileDef* inst) {
}
#endif
if (!is_mirror) {
m = taxonomy::cast<taxonomy::matrix4>(map(inst->Operator()));
m = taxonomy::cast<taxonomy::matrix4>(map(inst.Operator()));
if (!m) {
return nullptr;
}
+2 -2
View File
@@ -21,8 +21,8 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcDirection* inst) {
auto coords = inst->DirectionRatios();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcDirection& inst) {
auto coords = inst.DirectionRatios();
return taxonomy::make<taxonomy::direction3>(
coords.size() >= 1 ? coords[0] : 0.,
coords.size() >= 2 ? coords[1] : 0.,
+10 -8
View File
@@ -21,15 +21,17 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEdge* inst) {
if (!inst->EdgeStart()->declaration().is(IfcSchema::IfcVertexPoint::Class()) || !inst->EdgeEnd()->declaration().is(IfcSchema::IfcVertexPoint::Class())) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEdge& inst) {
auto v1 = inst.EdgeStart().as<IfcSchema::IfcVertexPoint>();
auto v2 = inst.EdgeStart().as<IfcSchema::IfcVertexPoint>();
if (!v1 || !v2) {
Logger::Message(Logger::LOG_ERROR, "Only IfcVertexPoints are supported for EdgeStart and -End", inst);
return nullptr;
}
IfcSchema::IfcPoint* pnt1 = ((IfcSchema::IfcVertexPoint*) inst->EdgeStart())->VertexGeometry();
IfcSchema::IfcPoint* pnt2 = ((IfcSchema::IfcVertexPoint*) inst->EdgeEnd())->VertexGeometry();
if (!pnt1->declaration().is(IfcSchema::IfcCartesianPoint::Class()) || !pnt2->declaration().is(IfcSchema::IfcCartesianPoint::Class())) {
auto pnt1 = v1.VertexGeometry();
auto pnt2 = v2.VertexGeometry();
if (!pnt1.declaration().is(IfcSchema::IfcCartesianPoint::Class()) || !pnt2.declaration().is(IfcSchema::IfcCartesianPoint::Class())) {
Logger::Message(Logger::LOG_ERROR, "Only IfcCartesianPoints are supported for VertexGeometry", inst);
return nullptr;
}
@@ -39,15 +41,15 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEdge* inst) {
e->start = taxonomy::cast<taxonomy::point3>(map(pnt1));
e->end = taxonomy::cast<taxonomy::point3>(map(pnt2));
if (inst->as<IfcSchema::IfcEdgeCurve>()) {
auto basis = map(inst->as<IfcSchema::IfcEdgeCurve>()->EdgeGeometry());
if (auto ec = inst.as<IfcSchema::IfcEdgeCurve>()) {
auto basis = map(ec.EdgeGeometry());
auto loop = taxonomy::dcast<taxonomy::loop>(basis);
if (loop && loop->children.size() == 1) {
loop->calculate_linear_edge_curves();
basis = loop->children[0]->basis;
}
e->basis = basis;
e->curve_sense = inst->as<IfcSchema::IfcEdgeCurve>()->SameSense();
e->curve_sense = ec.SameSense();
}
return e;
+2 -2
View File
@@ -21,6 +21,6 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEdgeLoop* inst) {
return map_to_collection<taxonomy::loop>(this, inst->EdgeList());
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEdgeLoop& inst) {
return map_to_collection<taxonomy::loop>(this, inst.EdgeList());
}
+4 -4
View File
@@ -21,9 +21,9 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEllipse* inst) {
double x = inst->SemiAxis1() * length_unit_;
double y = inst->SemiAxis2() * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEllipse& inst) {
double x = inst.SemiAxis1() * length_unit_;
double y = inst.SemiAxis2() * length_unit_;
const double tol = settings_.get<settings::Precision>().get();
if (x < tol || y < tol) {
Logger::Message(Logger::LOG_ERROR, "Radius not greater than zero for:", inst);
@@ -31,7 +31,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEllipse* inst) {
}
auto el = taxonomy::make<taxonomy::ellipse>();
el->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
el->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
// Open Cascade does not allow ellipses of which the minor radius
// is greater than the major radius. Hence, in this case, the
+5 -5
View File
@@ -21,9 +21,9 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEllipseProfileDef* inst) {
double rx = inst->SemiAxis1() * length_unit_;
double ry = inst->SemiAxis2() * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEllipseProfileDef& inst) {
double rx = inst.SemiAxis1() * length_unit_;
double ry = inst.SemiAxis2() * length_unit_;
const double tol = settings_.get<settings::Precision>().get();
if (rx < tol || ry < tol) {
Logger::Message(Logger::LOG_ERROR, "Radius not greater than zero for:", inst);
@@ -35,10 +35,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEllipseProfileDef* inst) {
taxonomy::matrix4::ptr m4;
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
} else {
// matrix needs to be set on elementary curves.
m4 = taxonomy::make<taxonomy::matrix4>();
+7 -7
View File
@@ -24,8 +24,8 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolid* inst) {
const double height = inst->Depth() * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolid& inst) {
const double height = inst.Depth() * length_unit_;
if (height < settings_.get<settings::Precision>().get()) {
Logger::Message(Logger::LOG_ERROR, "Non-positive extrusion height encountered for:", inst);
#ifndef PERMISSIVE_EXTRUSION
@@ -36,10 +36,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolid* inst) {
taxonomy::matrix4::ptr matrix;
bool has_position = true;
#ifdef SCHEMA_IfcSweptAreaSolid_Position_IS_OPTIONAL
has_position = inst->Position() != nullptr;
has_position = !!inst.Position();
#endif
if (has_position) {
matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
#ifdef PERMISSIVE_EXTRUSION
@@ -49,7 +49,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolid* inst) {
}
#endif
auto basis = map(inst->SweptArea());
auto basis = map(inst.SweptArea());
if (auto bases = taxonomy::dcast<taxonomy::collection>(basis)) {
// @todo this requires a unified approach for all sweeps
auto c = taxonomy::make<taxonomy::collection>();
@@ -58,7 +58,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolid* inst) {
taxonomy::make<taxonomy::extrusion>(
matrix,
taxonomy::cast<taxonomy::face>(f),
taxonomy::cast<taxonomy::direction3>(map(inst->ExtrudedDirection())),
taxonomy::cast<taxonomy::direction3>(map(inst.ExtrudedDirection())),
height
)
);
@@ -69,7 +69,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolid* inst) {
return taxonomy::make<taxonomy::extrusion>(
matrix,
taxonomy::cast<taxonomy::face>(basis),
taxonomy::cast<taxonomy::direction3>(map(inst->ExtrudedDirection())),
taxonomy::cast<taxonomy::direction3>(map(inst.ExtrudedDirection())),
height
);
}
@@ -24,22 +24,22 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcExtrudedAreaSolidTapered
#define mapping POSTFIX_SCHEMA(mapping)
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolidTapered* inst) {
const double height = inst->Depth() * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolidTapered& inst) {
const double height = inst.Depth() * length_unit_;
if (height < settings_.get<settings::Precision>().get()) {
Logger::Message(Logger::LOG_ERROR, "Non-positive extrusion height encountered for:", inst);
return nullptr;
}
taxonomy::direction3::ptr dir = taxonomy::cast<taxonomy::direction3>(map(inst->ExtrudedDirection()));
taxonomy::direction3::ptr dir = taxonomy::cast<taxonomy::direction3>(map(inst.ExtrudedDirection()));
Eigen::Affine3d af3d(Eigen::Translation3d(height * dir->ccomponents()));
Eigen::Matrix4d end_profile = af3d.matrix();
auto loft = taxonomy::make<taxonomy::loft>();
loft->axis = nullptr;
loft->children = {
taxonomy::cast<taxonomy::face>(map(inst->SweptArea())),
taxonomy::cast<taxonomy::face>(map(inst->EndSweptArea()))
taxonomy::cast<taxonomy::face>(map(inst.SweptArea())),
taxonomy::cast<taxonomy::face>(map(inst.EndSweptArea()))
};
if (!loft->children.back()->matrix) {
@@ -51,10 +51,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolidTapered* in
taxonomy::matrix4::ptr matrix;
bool has_position = true;
#ifdef SCHEMA_IfcSweptAreaSolid_Position_IS_OPTIONAL
has_position = inst->Position() != nullptr;
has_position = !!inst.Position();
#endif
if (has_position) {
matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
loft->matrix = matrix;
+8 -331
View File
@@ -21,16 +21,16 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFace* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFace& inst) {
auto face = taxonomy::make<taxonomy::face>();
auto bounds = inst->Bounds();
for (auto& bound : *bounds) {
if (auto r = taxonomy::cast<taxonomy::loop>(map(bound->Bound()))) {
if (!bound->Orientation()) {
auto bounds = inst.Bounds();
for (auto& bound : bounds) {
if (auto r = taxonomy::cast<taxonomy::loop>(map(bound.Bound()))) {
if (!bound.Orientation()) {
r->reverse();
}
// @todo check why loop sets external to true initially
r->external = bound->declaration().is(IfcSchema::IfcFaceOuterBound::Class());
r->external = bound.declaration().is(IfcSchema::IfcFaceOuterBound::Class());
/*
// Make a copy in case we need immutability later for e.g. caching
auto s = r->clone();
@@ -42,10 +42,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFace* inst) {
}
}
auto face_surface = inst->as<IfcSchema::IfcFaceSurface>();
auto face_surface = inst.as<IfcSchema::IfcFaceSurface>();
if (face_surface) {
face->basis = map(face_surface->FaceSurface());
face->basis = map(face_surface.FaceSurface());
}
if (face->children.empty()) {
@@ -56,326 +56,3 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFace* inst) {
}
return face;
}
/*
#include <gp_Vec.hxx>
#include <gp_Dir.hxx>
#include <gp_Pln.hxx>
#include <Geom_Line.hxx>
#include <Geom_Plane.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Face.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Iterator.hxx>
#include <ShapeFix_Shape.hxx>
#include <ShapeFix_ShapeTolerance.hxx>
#include <BRep_Tool.hxx>
#include <TopTools_DataMapOfShapeInteger.hxx>
#include <BRepLib_FindSurface.hxx>
#include <ShapeExtend_MsgRegistrator.hxx>
#include <Message_Msg.hxx>
#include "mapping.h"
#include "../ifcgeom_schema_agnostic/face_definition.h"
#include "../ifcgeom_schema_agnostic/wire_utils.h"
#define mapping POSTFIX_SCHEMA(mapping)
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFace* l, TopoDS_Shape& result) {
IfcSchema::IfcFaceBound::list::ptr bounds = inst->Bounds();
util::face_definition fd;
const bool is_face_surface = inst->declaration().is(IfcSchema::IfcFaceSurface::Class());
if (is_face_surface) {
IfcSchema::IfcFaceSurface* fs = (IfcSchema::IfcFaceSurface*) l;
fs->FaceSurface();
// FIXME: Surfaces are interpreted as a TopoDS_Shape
TopoDS_Shape surface_shape;
if (!convert_shape(fs->FaceSurface(), surface_shape)) return false;
// FIXME: Assert this obtains the only face
TopExp_Explorer exp(surface_shape, TopAbs_FACE);
if (!exp.More()) return false;
TopoDS_Face surface = TopoDS::Face(exp.Current());
fd.surface() = BRep_Tool::Surface(surface);
}
const int num_bounds = bounds->size();
int num_outer_bounds = 0;
for (IfcSchema::IfcFaceBound::list::it it = bounds->begin(); it != bounds->end(); ++it) {
IfcSchema::IfcFaceBound* bound = *it;
if (bound->declaration().is(IfcSchema::IfcFaceOuterBound::Class())) num_outer_bounds ++;
}
// The number of outer bounds should be one according to the schema. Also Open Cascade
// expects this, but it is not strictly checked. Regardless, if the number is greater,
// the face will still be processed as long as there are no holes. A compound of faces
// is returned in that case.
if (num_bounds > 1 && num_outer_bounds > 1 && num_bounds != num_outer_bounds) {
Logger::Message(Logger::LOG_ERROR, "Invalid configuration of boundaries for:", l);
return false;
}
if (num_outer_bounds > 1) {
Logger::Message(Logger::LOG_WARNING, "Multiple outer boundaries for:", l);
fd.all_outer() = true;
}
TopTools_DataMapOfShapeInteger wire_senses;
for (int process_interior = 0; process_interior <= 1; ++process_interior) {
for (IfcSchema::IfcFaceBound::list::it it = bounds->begin(); it != bounds->end(); ++it) {
IfcSchema::IfcFaceBound* bound = *it;
IfcSchema::IfcLoop* loop = bound->Bound();
bool same_sense = bound->Orientation();
const bool is_interior =
!bound->declaration().is(IfcSchema::IfcFaceOuterBound::Class()) &&
(num_bounds > 1) &&
(num_outer_bounds < num_bounds);
// The exterior face boundary is processed first
if (is_interior == !process_interior) continue;
TopTools_ListOfShape wires;
TopoDS_Wire wire;
if (faceset_helper_ && loop->as<IfcSchema::IfcPolyLoop>()) {
if (!faceset_helper_->wires(loop->as<IfcSchema::IfcPolyLoop>(), wires)) {
Logger::Message(Logger::LOG_WARNING, "Face boundary loop not included", loop);
continue;
}
} else {
if (convert_wire(loop, wire)) {
wires.Append(wire);
} else {
Logger::Message(Logger::LOG_ERROR, "Failed to process face boundary loop", loop);
return false;
}
}
if (wires.Size() > 1) {
Logger::Message(Logger::LOG_WARNING, "Face loop definition results in " + std::to_string(wires.Size()) + " loops", loop);
if (!is_interior) {
fd.all_outer() = true;
}
}
for (auto& w : wires) {
if (!same_sense) {
w.Reverse();
}
wire_senses.Bind(w.Oriented(TopAbs_FORWARD), same_sense ? TopAbs_FORWARD : TopAbs_REVERSED);
fd.wires().emplace_back(TopoDS::Wire(w));
}
}
}
if (fd.wires().empty()) {
Logger::Warning("Face with no boundaries", l);
return false;
}
if (fd.surface().IsNull()) {
// Use the first wire to find a plane manually for polygonal wires
const TopoDS_Wire& wire = fd.wires().front();
if (util::is_polyhedron(wire)) {
TopExp_Explorer exp(wire, TopAbs_EDGE);
int count = 0;
TopoDS_Edge edges[2];
for (; exp.More(); exp.Next(), count++) {
if (count < 2) {
edges[count] = TopoDS::Edge(exp.Current());
}
}
if (count == 3) {
// Help Open Cascade by finding the plane more efficiently
double _, __;
Handle(Geom_Line) c1 = Handle(Geom_Line)::DownCast(BRep_Tool::Curve(edges[0], _, __));
Handle(Geom_Line) c2 = Handle(Geom_Line)::DownCast(BRep_Tool::Curve(edges[1], _, __));
const gp_Vec ab = c1->Position().Direction();
const gp_Vec ac = c2->Position().Direction();
const gp_Vec cross = ab.Crossed(ac);
if (cross.SquareMagnitude() > ALMOST_ZERO) {
const gp_Dir n = cross;
fd.surface() = new Geom_Plane(c1->Position().Location(), n);
}
} else {
gp_Pln pln;
if (util::approximate_plane_through_wire(wire, pln, getValue(GV_PRECISION))) {
fd.surface() = new Geom_Plane(pln);
}
}
}
}
if (fd.surface().IsNull()) {
// BRepLib_FindSurface is used in case no surface is found or provided
const TopoDS_Wire& wire = fd.wires().front();
BRepLib_FindSurface fs(wire, getValue(GV_PRECISION), true, true);
if (fs.Found()) {
fd.surface() = fs.Surface();
ShapeFix_ShapeTolerance ftol;
ftol.SetTolerance(wire, fs.ToleranceReached(), TopAbs_WIRE);
}
}
TopTools_ListOfShape face_list;
if (fd.surface().IsNull()) {
// The set of wires is triangulated in case no surface can be found
Logger::Message(Logger::LOG_WARNING, "Triangulating face boundaries for face", l);
if (fd.all_outer()) {
for (const auto& w : fd.wires()) {
TopTools_ListOfShape fl;
auto r = util::triangulate_wire({ w }, fl);
if (r == util::TRIANGULATE_WIRE_FAIL) {
continue;
}
face_list.Append(fl);
if (faceset_helper_ && r == util::TRIANGULATE_WIRE_NON_MANIFOLD) {
faceset_helper_->non_manifold() = true;
}
}
} else {
auto r = util::triangulate_wire(fd.wires(), face_list);
if (r != util::TRIANGULATE_WIRE_FAIL) {
if (faceset_helper_ && r == util::TRIANGULATE_WIRE_NON_MANIFOLD) {
faceset_helper_->non_manifold() = true;
}
}
}
} else if (!fd.all_outer()) {
BRepBuilderAPI_MakeFace mf(fd.surface(), fd.outer_wire());
TopoDS_Face f = mf.Face();
if (mf.IsDone()) {
if (std::distance(fd.inner_wires().first, fd.inner_wires().second)) {
mf.Init(f);
for (auto it = fd.inner_wires().first; it != fd.inner_wires().second; ++it) {
mf.Add(*it);
}
face_list.Append(mf.Face());
} else {
face_list.Append(f);
}
}
} else {
for (const auto& w : fd.wires()) {
BRepBuilderAPI_MakeFace mf(fd.surface(), w);
if (mf.IsDone()) {
face_list.Append(mf.Face());
}
}
}
if (!fd.surface().IsNull()) {
// Some fixes for orientation and p-curves. If we have no surface, it
// means the face has been triangulated in which case none of these
// fixes are necessary.
if (fd.surface()->DynamicType() != STANDARD_TYPE(Geom_Plane)) {
// In case of (non-planar) face surface, p-curves need to be computed.
// For planar faces, Open Cascade generates p-curves on the fly.
for (TopTools_ListIteratorOfListOfShape it(face_list); it.More(); it.Next()) {
ShapeFix_Shape sfs(it.Value());
Handle(ShapeExtend_MsgRegistrator) msg;
msg = new ShapeExtend_MsgRegistrator;
sfs.SetMsgRegistrator(msg);
sfs.Perform();
it.Value() = sfs.Shape();
ShapeExtend_DataMapIteratorOfDataMapOfShapeListOfMsg jt(msg->MapShape());
for (; jt.More(); jt.Next()) {
Message_ListIteratorOfListOfMsg kt(jt.Value());
for (; kt.More(); kt.Next()) {
char* c = new char[kt.Value().Value().LengthOfCString() + 1];
kt.Value().Value().ToUTF8CString(c);
Logger::Notice(c, l);
delete[] c;
}
}
}
}
for (TopTools_ListIteratorOfListOfShape it(face_list); it.More(); it.Next()) {
const TopoDS_Face& face = TopoDS::Face(it.Value());
ShapeFix_Face sfs(TopoDS::Face(face));
TopTools_DataMapOfShapeListOfShape wire_map;
sfs.FixOrientation(wire_map);
TopoDS_Iterator jt(face, false);
for (; jt.More(); jt.Next()) {
const TopoDS_Wire& w = TopoDS::Wire(jt.Value());
// tfk: @todo if wire_map contains w, I would assume wire_senses also contains w,
// this is not the case in github issue #405.
if (wire_map.IsBound(w) && wire_senses.IsBound(w)) {
const TopTools_ListOfShape& shapes = wire_map.Find(w);
TopTools_ListIteratorOfListOfShape kt(shapes);
for (; kt.More(); kt.Next()) {
// Apparently the wire got reversed, so register it with opposite orientation in the map
wire_senses.Bind(kt.Value(), wire_senses.Find(w) == TopAbs_FORWARD ? TopAbs_REVERSED : TopAbs_FORWARD);
}
}
}
it.Value() = sfs.Face();
}
for (TopTools_ListIteratorOfListOfShape it(face_list); it.More(); it.Next()) {
TopoDS_Face& face = TopoDS::Face(it.Value());
bool all_reversed = true;
TopoDS_Iterator jt(face, false);
for (; jt.More(); jt.Next()) {
const TopoDS_Wire& w = TopoDS::Wire(jt.Value());
if (!wire_senses.IsBound(w.Oriented(TopAbs_FORWARD)) || (w.Orientation() == wire_senses.Find(w.Oriented(TopAbs_FORWARD)))) {
all_reversed = false;
}
}
if (all_reversed) {
face.Reverse();
}
}
}
if (face_list.Extent() == 0) {
return false;
} else if (face_list.Extent() > 1) {
TopoDS_Compound compound;
BRep_Builder builder;
builder.MakeCompound(compound);
for (TopTools_ListIteratorOfListOfShape it(face_list); it.More(); it.Next()) {
TopoDS_Face& face = TopoDS::Face(it.Value());
builder.Add(compound, face);
}
result = compound;
} else {
result = face_list.First();
}
return true;
}
*/
@@ -21,7 +21,7 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFaceBasedSurfaceModel* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFaceBasedSurfaceModel& inst) {
// @todo check styles?
return map_to_collection(this, inst->FbsmFaces());
return map_to_collection(this, inst.FbsmFaces());
}
@@ -24,10 +24,10 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcFixedReferenceSweptAreaSolid
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFixedReferenceSweptAreaSolid* inst) {
auto dir = map(inst->Directrix());
auto ref = taxonomy::cast<taxonomy::direction3>(map(inst->FixedReference()));
auto profile = taxonomy::cast<taxonomy::face>(map(inst->SweptArea()));
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFixedReferenceSweptAreaSolid& inst) {
auto dir = map(inst.Directrix());
auto ref = taxonomy::cast<taxonomy::direction3>(map(inst.FixedReference()));
auto profile = taxonomy::cast<taxonomy::face>(map(inst.SweptArea()));
auto loft = taxonomy::make<taxonomy::loft>();
// @todo intialize as default
@@ -42,14 +42,14 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFixedReferenceSweptAreaSolid
// IfcDirectrixCurveSweptAreaSolid introduced in 4.3 changed attribute type
// from optional IfcParamValue to optional IfcCurveMeasureSelect.
// Invocation of mapping on pre-4.3 models can never result in a piecewise_function.
if (inst->StartParam() && inst->StartParam()->as<IfcSchema::IfcLengthMeasure>()) {
double s = *inst->StartParam()->as<IfcSchema::IfcLengthMeasure>();
if (inst.StartParam() && inst.StartParam().as<IfcSchema::IfcLengthMeasure>()) {
double s = inst.StartParam().as<IfcSchema::IfcLengthMeasure>();
if (s > start) {
start = s;
}
}
if (inst->EndParam() && inst->EndParam()->as<IfcSchema::IfcLengthMeasure>()) {
double e = *inst->EndParam()->as<IfcSchema::IfcLengthMeasure>();
if (inst.EndParam() && inst.EndParam().as<IfcSchema::IfcLengthMeasure>()) {
double e = inst.EndParam().as<IfcSchema::IfcLengthMeasure>();
if (e < end) {
end = e;
}
@@ -71,7 +71,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFixedReferenceSweptAreaSolid
bool is_directrix_derived = false;
#ifdef SCHEMA_HAS_IfcDirectrixDerivedReferenceSweptAreaSolid
if (inst->as<IfcSchema::IfcDirectrixDerivedReferenceSweptAreaSolid>()) {
if (inst.as<IfcSchema::IfcDirectrixDerivedReferenceSweptAreaSolid>()) {
is_directrix_derived = true;
}
#endif
@@ -116,8 +116,8 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFixedReferenceSweptAreaSolid
}
} else {
taxonomy::matrix4::ptr matrix;
if (inst->Position() != nullptr) {
matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
if (inst.Position()) {
matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
// TODO: Implement handling for non-alignment curves using sweep_along_curve
auto sweep = taxonomy::make<taxonomy::sweep_along_curve>(
+2 -2
View File
@@ -21,6 +21,6 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGeometricSet* inst) {
return map_to_collection(this, inst->Elements());
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGeometricSet& inst) {
return map_to_collection(this, inst.Elements());
}
+9 -9
View File
@@ -24,18 +24,18 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcGradientCurve
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGradientCurve* inst) {
if (!inst->BaseCurve()->as<IfcSchema::IfcCompositeCurve>())
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGradientCurve& inst) {
if (!inst.BaseCurve().as<IfcSchema::IfcCompositeCurve>())
Logger::Warning("Expected IfcGradientCurve.BaseCurve to be IfcCompositeCurve", inst); // CT 4.1.7.1.1.2
auto segments = inst->Segments();
auto segments = inst.Segments();
taxonomy::piecewise_function::spans_t spans;
for (auto& segment : *segments) {
if (segment->as<IfcSchema::IfcCurveSegment>()) {
for (auto& segment : segments) {
if (segment.as<IfcSchema::IfcCurveSegment>()) {
// @todo check that we don't get a mixture of implicit and explicit definitions
auto crv = map(segment->as<IfcSchema::IfcCurveSegment>());
auto crv = map(segment.as<IfcSchema::IfcCurveSegment>());
if (auto fi = taxonomy::dcast<taxonomy::function_item>(crv); crv && fi /*crv->kind() == taxonomy::FUNCTION_ITEM*/) {
// crv->kind() is polymorphic and the kind of the actual function_item is returned. PWF can have spans of any FUNCTION_ITEM
// for this reason, a dynamic cast is used and if crv is a function_item it is added to the span
@@ -52,10 +52,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGradientCurve* inst) {
// Get starting position of gradient curve, which is relative to the base curve
// The gradient curve can start before or after the start of the base curve
auto first_segment = *(segments->begin());
auto& first_segment = segments.front();
taxonomy::matrix4::ptr p;
#ifdef SCHEMA_IfcCurveSegment_HAS_Placement
p = taxonomy::cast<taxonomy::matrix4>(map(first_segment->as<IfcSchema::IfcCurveSegment>()->Placement()));
p = taxonomy::cast<taxonomy::matrix4>(map(first_segment.as<IfcSchema::IfcCurveSegment>().Placement()));
#else
throw std::runtime_error("Unsupported schema");
#endif
@@ -66,7 +66,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGradientCurve* inst) {
auto vertical = taxonomy::make<taxonomy::piecewise_function>(gradient_start, spans);
// create the horizontal pwf
auto horizontal = taxonomy::cast<taxonomy::piecewise_function>(map(inst->BaseCurve()));
auto horizontal = taxonomy::cast<taxonomy::piecewise_function>(map(inst.BaseCurve()));
// create the composite gradient curve function
auto gradient_function = taxonomy::make<taxonomy::gradient_function>(horizontal, vertical, inst);
+6 -5
View File
@@ -21,16 +21,17 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcHalfSpaceSolid* inst) {
IfcSchema::IfcSurface* surface = inst->BaseSurface();
if (!surface->declaration().is(IfcSchema::IfcPlane::Class())) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcHalfSpaceSolid& inst) {
auto surface = inst.BaseSurface();
auto plane = surface.as<IfcSchema::IfcPlane>();
if (!plane) {
Logger::Message(Logger::LOG_ERROR, "Unsupported BaseSurface:", surface);
return nullptr;
}
auto p = taxonomy::make<taxonomy::plane>();
p->matrix = taxonomy::cast<taxonomy::matrix4>(map(((IfcSchema::IfcPlane*)surface)->Position()));
p->matrix = taxonomy::cast<taxonomy::matrix4>(map(plane.Position()));
auto f = taxonomy::make<taxonomy::face>();
f->orientation.reset(!inst->AgreementFlag());
f->orientation.emplace(!inst.AgreementFlag());
f->basis = p;
auto sh = taxonomy::make<taxonomy::shell>();
sh->children.push_back(f);
+19 -20
View File
@@ -23,21 +23,21 @@ using namespace ifcopenshell::geometry;
#include "../profile_helper.h"
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIShapeProfileDef* inst) {
const bool doFillet1 = !!inst->FilletRadius();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIShapeProfileDef& inst) {
const bool doFillet1 = !!inst.FilletRadius();
#ifdef SCHEMA_IfcIShapeProfileDef_HAS_FlangeEdgeRadius
const bool doFlangeEdgeRadius = !!inst->FlangeEdgeRadius();
const bool hasSlope = !!inst->FlangeSlope();
const bool doFlangeEdgeRadius = !!inst.FlangeEdgeRadius();
const bool hasSlope = !!inst.FlangeSlope();
#else
const bool doFlangeEdgeRadius = false;
#endif
const double x1 = inst->OverallWidth() / 2.0f * length_unit_;
const double y = inst->OverallDepth() / 2.0f * length_unit_;
const double d1 = inst->WebThickness() / 2.0f * length_unit_;
const double ft1 = inst->FlangeThickness() * length_unit_;
const double x1 = inst.OverallWidth() / 2.0f * length_unit_;
const double y = inst.OverallDepth() / 2.0f * length_unit_;
const double d1 = inst.WebThickness() / 2.0f * length_unit_;
const double ft1 = inst.FlangeThickness() * length_unit_;
#ifdef SCHEMA_IfcIShapeProfileDef_HAS_FlangeEdgeRadius
const double slope = inst->FlangeSlope().get_value_or(0.) * angle_unit_;
const double slope = inst.FlangeSlope().value_or(0.) * angle_unit_;
#endif
double dy = 0.;
@@ -49,11 +49,11 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIShapeProfileDef* inst) {
double ft2 = ft1;
if (doFillet1) {
f1 = *inst->FilletRadius() * length_unit_;
f1 = *inst.FilletRadius() * length_unit_;
}
#ifdef SCHEMA_IfcIShapeProfileDef_HAS_FlangeEdgeRadius
if (doFlangeEdgeRadius) {
fe1 = *inst->FlangeEdgeRadius() * length_unit_;
fe1 = *inst.FlangeEdgeRadius() * length_unit_;
}
if (hasSlope) {
dy = (x1 - d1) * tan(slope);
@@ -63,15 +63,14 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIShapeProfileDef* inst) {
bool doFillet2 = doFillet1;
// @todo in IFC4 a IfcAsymmetricIShapeProfileDef is not a subtype anymore of IfcIShapeProfileDef!
if (inst->declaration().is(IfcSchema::IfcAsymmetricIShapeProfileDef::Class())) {
IfcSchema::IfcAsymmetricIShapeProfileDef* assym = (IfcSchema::IfcAsymmetricIShapeProfileDef*) inst;
x2 = assym->TopFlangeWidth() / 2. * length_unit_;
doFillet2 = !!assym->TopFlangeFilletRadius();
if (auto assym = inst.as<IfcSchema::IfcAsymmetricIShapeProfileDef>()) {
x2 = assym.TopFlangeWidth() / 2. * length_unit_;
doFillet2 = !!assym.TopFlangeFilletRadius();
if (doFillet2) {
f2 = *assym->TopFlangeFilletRadius() * length_unit_;
f2 = *assym.TopFlangeFilletRadius() * length_unit_;
}
if (assym->TopFlangeThickness()) {
ft2 = *assym->TopFlangeThickness() * length_unit_;
if (assym.TopFlangeThickness()) {
ft2 = *assym.TopFlangeThickness() * length_unit_;
}
} else {
f2 = f1;
@@ -88,10 +87,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIShapeProfileDef* inst) {
taxonomy::matrix4::ptr m4;
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
return profile_helper(m4, {
+14 -17
View File
@@ -23,14 +23,14 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcIndexedPolyCurve
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIndexedPolyCurve* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIndexedPolyCurve& inst) {
IfcSchema::IfcCartesianPointList* point_list = inst->Points();
auto point_list = inst.Points();
std::vector< std::vector<double> > coordinates;
if (point_list->as<IfcSchema::IfcCartesianPointList2D>()) {
coordinates = point_list->as<IfcSchema::IfcCartesianPointList2D>()->CoordList();
} else if (point_list->as<IfcSchema::IfcCartesianPointList3D>()) {
coordinates = point_list->as<IfcSchema::IfcCartesianPointList3D>()->CoordList();
if (point_list.as<IfcSchema::IfcCartesianPointList2D>()) {
coordinates = point_list.as<IfcSchema::IfcCartesianPointList2D>().CoordList();
} else if (point_list.as<IfcSchema::IfcCartesianPointList3D>()) {
coordinates = point_list.as<IfcSchema::IfcCartesianPointList3D>().CoordList();
}
std::vector<taxonomy::point3::ptr> points;
@@ -50,13 +50,11 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIndexedPolyCurve* inst) {
auto loop = taxonomy::make<taxonomy::loop>();
if(inst->Segments()) {
auto segments = *inst->Segments();
for (auto it = segments->begin(); it != segments->end(); ++it) {
auto segment = *it;
if (segment->as<IfcSchema::IfcLineIndex>()) {
IfcSchema::IfcLineIndex* line = segment->as<IfcSchema::IfcLineIndex>();
std::vector<int> indices = *line;
if(inst.Segments()) {
auto segments = inst.Segments();
for (auto& segment : *segments) {
if (auto line = segment.as<IfcSchema::IfcLineIndex>()) {
std::vector<int> indices = line;
taxonomy::point3::ptr previous;
for (std::vector<int>::const_iterator jt = indices.begin(); jt != indices.end(); ++jt) {
if (*jt < 1 || *jt > max_index) {
@@ -68,9 +66,8 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIndexedPolyCurve* inst) {
}
previous = current;
}
} else if (segment->as<IfcSchema::IfcArcIndex>()) {
IfcSchema::IfcArcIndex* arc = segment->as<IfcSchema::IfcArcIndex>();
std::vector<int> indices = *arc;
} else if (auto arc = segment.as<IfcSchema::IfcArcIndex>()) {
std::vector<int> indices = arc;
if (indices.size() != 3) {
throw IfcParse::IfcException("Invalid IfcArcIndex encountered");
}
@@ -93,7 +90,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIndexedPolyCurve* inst) {
Logger::Warning("Ignoring segment on", inst);
}
} else {
throw IfcParse::IfcException("Unexpected IfcIndexedPolyCurve segment of type " + segment->as<IfcUtil::IfcBaseClass>()->declaration().name());
throw IfcParse::IfcException("Unexpected IfcIndexedPolyCurve segment of type " + segment.concrete().declaration().name());
}
}
} else if (points.begin() < points.end()) {
+12 -12
View File
@@ -23,23 +23,23 @@ using namespace ifcopenshell::geometry;
#include "../profile_helper.h"
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcLShapeProfileDef* inst) {
const bool hasSlope = !!inst->LegSlope();
const bool doEdgeFillet = !!inst->EdgeRadius();
const bool doFillet = !!inst->FilletRadius();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcLShapeProfileDef& inst) {
const bool hasSlope = !!inst.LegSlope();
const bool doEdgeFillet = !!inst.EdgeRadius();
const bool doFillet = !!inst.FilletRadius();
const double y = inst->Depth() / 2.0f * length_unit_;
const double x = inst->Width().get_value_or(inst->Depth()) / 2.0f * length_unit_;
const double d = inst->Thickness() * length_unit_;
const double slope = inst->LegSlope().get_value_or(0.) * angle_unit_;
const double y = inst.Depth() / 2.0f * length_unit_;
const double x = inst.Width().value_or(inst.Depth()) / 2.0f * length_unit_;
const double d = inst.Thickness() * length_unit_;
const double slope = inst.LegSlope().value_or(0.) * angle_unit_;
double f1 = 0.0f;
double f2 = 0.0f;
if (doFillet) {
f1 = *inst->FilletRadius() * length_unit_;
f1 = *inst.FilletRadius() * length_unit_;
}
if ( doEdgeFillet) {
f2 = *inst->EdgeRadius() * length_unit_;
f2 = *inst.EdgeRadius() * length_unit_;
}
const double tol = settings_.get<settings::Precision>().get();
@@ -88,10 +88,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcLShapeProfileDef* inst) {
taxonomy::matrix4::ptr m4;
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
return profile_helper(m4, {
+3 -3
View File
@@ -21,11 +21,11 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcLine* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcLine& inst) {
// @todo test with trimmed curve on non-normalized direction
auto l = taxonomy::make<taxonomy::line>();
auto pnt = taxonomy::cast<taxonomy::point3>(map(inst->Pnt()));
auto dir = taxonomy::cast<taxonomy::direction3>(map(inst->Dir()));
auto pnt = taxonomy::cast<taxonomy::point3>(map(inst.Pnt()));
auto dir = taxonomy::cast<taxonomy::direction3>(map(inst.Dir()));
l->matrix = taxonomy::make<taxonomy::matrix4>(pnt->ccomponents(), dir->ccomponents());
return l;
}
+8 -8
View File
@@ -21,24 +21,24 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcManifoldSolidBrep* inst) {
IfcSchema::IfcClosedShell::list::ptr voids(new IfcSchema::IfcClosedShell::list);
if (inst->declaration().is(IfcSchema::IfcFacetedBrepWithVoids::Class())) {
voids = inst->as<IfcSchema::IfcFacetedBrepWithVoids>()->Voids();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcManifoldSolidBrep& inst) {
std::vector<IfcSchema::IfcClosedShell> voids;
if (inst.declaration().is(IfcSchema::IfcFacetedBrepWithVoids::Class())) {
voids = inst.as<IfcSchema::IfcFacetedBrepWithVoids>().Voids();
}
#ifdef SCHEMA_HAS_IfcAdvancedBrepWithVoids
if (inst->declaration().is(IfcSchema::IfcAdvancedBrepWithVoids::Class())) {
voids = inst->as<IfcSchema::IfcAdvancedBrepWithVoids>()->Voids();
if (inst.declaration().is(IfcSchema::IfcAdvancedBrepWithVoids::Class())) {
voids = inst.as<IfcSchema::IfcAdvancedBrepWithVoids>().Voids();
}
#endif
taxonomy::solid::ptr solid;
if (voids->size()) {
if (!voids.empty()) {
solid = map_to_collection<taxonomy::solid>(this, voids);
} else {
solid = taxonomy::make<taxonomy::solid>();
}
solid->children.insert(solid->children.begin(), taxonomy::cast<taxonomy::shell>(map(inst->Outer())));
solid->children.insert(solid->children.begin(), taxonomy::cast<taxonomy::shell>(map(inst.Outer())));
return solid;
}
+6 -6
View File
@@ -21,19 +21,19 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcMappedItem* inst) {
IfcSchema::IfcCartesianTransformationOperator* transform = inst->MappingTarget();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcMappedItem& inst) {
auto transform = inst.MappingTarget();
taxonomy::matrix4::ptr gtrsf = taxonomy::cast<taxonomy::matrix4>(map(transform));
IfcSchema::IfcRepresentationMap* rmap = inst->MappingSource();
IfcSchema::IfcAxis2Placement* placement = rmap->MappingOrigin();
auto rmap = inst.MappingSource();
auto placement = rmap.MappingOrigin();
taxonomy::matrix4::ptr trsf2 = taxonomy::cast<taxonomy::matrix4>(map(placement));
Eigen::Matrix4d res = gtrsf->ccomponents() * trsf2->ccomponents();
// @todo immutable for caching?
// @todo allow for multiple levels of matrix?
auto shapes = taxonomy::dcast<taxonomy::collection>(map(rmap->MappedRepresentation()));
auto shapes = taxonomy::dcast<taxonomy::collection>(map(rmap.MappedRepresentation()));
if (shapes == nullptr) {
if (failed_on_purpose_.find(rmap->MappedRepresentation()) != failed_on_purpose_.end()) {
if (failed_on_purpose_.find(rmap.MappedRepresentation()) != failed_on_purpose_.end()) {
// propagate
failed_on_purpose_.insert(inst);
}
+18 -18
View File
@@ -21,45 +21,45 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcObjectPlacement* inst) {
const IfcSchema::IfcObjectPlacement* relative_to = nullptr;
const IfcUtil::IfcBaseInterface* transform;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcObjectPlacement& inst) {
IfcSchema::IfcObjectPlacement relative_to;
express::Base transform;
const IfcSchema::IfcAxis2Placement3D* fallback = nullptr;
IfcSchema::IfcAxis2Placement3D fallback;
if (inst->as<IfcSchema::IfcLocalPlacement>()) {
transform = inst->as<IfcSchema::IfcLocalPlacement>()->RelativePlacement();
if (inst.as<IfcSchema::IfcLocalPlacement>()) {
transform = inst.as<IfcSchema::IfcLocalPlacement>().RelativePlacement();
}
#ifdef SCHEMA_HAS_IfcLinearPlacement
else if (inst->as<IfcSchema::IfcLinearPlacement>()) {
else if (inst.as<IfcSchema::IfcLinearPlacement>()) {
#ifdef SCHEMA_IfcLinearPlacement_HAS_RelativePlacement
transform = inst->as<IfcSchema::IfcLinearPlacement>()->RelativePlacement();
fallback = inst->as<IfcSchema::IfcLinearPlacement>()->CartesianPosition();
transform = inst.as<IfcSchema::IfcLinearPlacement>().RelativePlacement();
fallback = inst.as<IfcSchema::IfcLinearPlacement>().CartesianPosition();
#else
// @todo Ifc4x1 and Ifc4x2 don't have RelativePlacement
return nullptr;
#endif
}
#endif
else if (inst->as<IfcSchema::IfcGridPlacement>()) {
else if (inst.as<IfcSchema::IfcGridPlacement>()) {
// @todo a bit harder to map without kernel
return nullptr;
}
#ifdef SCHEMA_IfcObjectPlacement_HAS_PlacementRelTo
relative_to = inst->PlacementRelTo();
relative_to = inst.PlacementRelTo();
#else
if (inst->as<IfcSchema::IfcLocalPlacement>()) {
relative_to = inst->as<IfcSchema::IfcLocalPlacement>()->PlacementRelTo();
if (inst.as<IfcSchema::IfcLocalPlacement>()) {
relative_to = inst.as<IfcSchema::IfcLocalPlacement>()->PlacementRelTo();
}
#endif
bool parent_placement_ignored = false;
if (relative_to && (placement_rel_to_type_ || placement_rel_to_instance_)) {
IfcSchema::IfcProduct::list::ptr parent_places = relative_to->PlacesObject();
for (auto iter = parent_places->begin(); iter != parent_places->end(); ++iter) {
if ((placement_rel_to_type_ && (*iter)->declaration().is(*placement_rel_to_type_)) ||
(placement_rel_to_instance_ && (*iter)->as<IfcUtil::IfcBaseEntity>() == placement_rel_to_instance_)) {
std::vector<IfcSchema::IfcProduct> parent_places = relative_to.PlacesObject();
for (auto& pp : parent_places) {
if ((placement_rel_to_type_ && pp.declaration().is(*placement_rel_to_type_)) ||
(placement_rel_to_instance_ && pp == placement_rel_to_instance_)) {
parent_placement_ignored = true;
}
}
@@ -108,7 +108,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcObjectPlacement* inst) {
/*
// @todo
if (gridp = inst->as<IfcSchema::IfcGridPlacement>()) {
if (gridp = inst.as<IfcSchema::IfcGridPlacement>()) {
gp_Trsf grid_position;
auto axes = gridp->PlacementLocation()->IntersectingAxes();
@@ -30,15 +30,15 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcOffsetCurveByDistances
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst) {
auto offset_values = inst->OffsetValues();
if (offset_values->size() == 0) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances& inst) {
auto offset_values = inst.OffsetValues();
if (offset_values.empty()) {
Logger::Error("IfcOffsetCurveByDistances must have at least one offset value");
}
auto first_offset_value = *(offset_values->begin());
auto& first_offset_value = offset_values.front();
auto basis_curve = inst->BasisCurve();
auto basis_curve = inst.BasisCurve();
// // IfcOffsetCurveByDistances can be based on another IfcOffsetCurveByDistances, an IfcGradientCurve, or an IfcCompositeCurve
// // When based on IfcOffsetCurveByDistances, it creates a chain of curves that we must navigate down to the base curve.
@@ -66,9 +66,9 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst
taxonomy::piecewise_function::spans_t offset_spans;
#if defined SCHEMA_HAS_IfcDistanceExpression
double first_distance = first_offset_value->DistanceAlong();
double first_distance = first_offset_value.DistanceAlong();
#else
double first_distance = *first_offset_value->DistanceAlong()->as<IfcSchema::IfcLengthMeasure>();
double first_distance = first_offset_value.DistanceAlong().as<IfcSchema::IfcLengthMeasure>();
#endif
first_distance *= length_unit_;
@@ -80,8 +80,8 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst
{
// First offset is defined after the start of the curve so the lateral and vertical offsets
// implicitly continue with the same value towards the start of the basis curve
double py = first_offset_value->OffsetLateral().get_value_or(0.0);
double pz = first_offset_value->OffsetVertical().get_value_or(0.0);
double py = first_offset_value.OffsetLateral().value_or(0.0);
double pz = first_offset_value.OffsetVertical().value_or(0.0);
py *= length_unit_;
pz *= length_unit_;
@@ -93,17 +93,17 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst
offset_spans.emplace_back(taxonomy::make<taxonomy::functor_item>(first_distance, fn));
}
auto iter = offset_values->begin();
auto iter = offset_values.begin();
auto next = std::next(iter);
auto prev = std::prev(next);
auto end = offset_values->end();
auto end = offset_values.end();
for (; next != end; prev++, next++) {
#if defined SCHEMA_HAS_IfcDistanceExpression
double dp = (*prev)->DistanceAlong();
double dn = (*next)->DistanceAlong();
double dp = (*prev).DistanceAlong();
double dn = (*next).DistanceAlong();
#else
double dp = *(*prev)->DistanceAlong()->as<IfcSchema::IfcLengthMeasure>();
double dn = *(*next)->DistanceAlong()->as<IfcSchema::IfcLengthMeasure>();
double dp = prev->DistanceAlong().as<IfcSchema::IfcLengthMeasure>();
double dn = next->DistanceAlong().as<IfcSchema::IfcLengthMeasure>();
#endif
dp *= length_unit_;
dn *= length_unit_;
@@ -115,10 +115,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst
}
double l = (dn - dp);
double yn = (*next)->OffsetLateral().get_value_or(0.0) * length_unit_;
double yp = (*prev)->OffsetLateral().get_value_or(0.0) * length_unit_;
double zn = (*next)->OffsetVertical().get_value_or(0.0) * length_unit_;
double zp = (*prev)->OffsetVertical().get_value_or(0.0) * length_unit_;
double yn = next->OffsetLateral().value_or(0.0) * length_unit_;
double yp = prev->OffsetLateral().value_or(0.0) * length_unit_;
double zn = next->OffsetVertical().value_or(0.0) * length_unit_;
double zp = prev->OffsetVertical().value_or(0.0) * length_unit_;
if ( (dp < 0.0 && dn < 0.0) || (basis_curve_length < dp && basis_curve_length < dn) ) {
// both points are either before the start of the curve or after the end of the curve. ignore them.
@@ -160,14 +160,14 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst
#if defined SCHEMA_HAS_IfcDistanceExpression
double last_distance = (*prev)->DistanceAlong() * length_unit_;
#else
double last_distance = *(*prev)->DistanceAlong()->as<IfcSchema::IfcLengthMeasure>() * length_unit_;
double last_distance = (double) prev->DistanceAlong().as<IfcSchema::IfcLengthMeasure>() * length_unit_;
#endif
if (last_distance < basis_curve_length) {
// Last offset is defined before the end of the curve so the lateral and vertical offsets
// implicitly continue with the same value towards the end of the basis curve
double py = (*prev)->OffsetLateral().get_value_or(0.0);
double pz = (*prev)->OffsetVertical().get_value_or(0.0);
double py = prev->OffsetLateral().value_or(0.0);
double pz = prev->OffsetVertical().value_or(0.0);
py *= length_unit_;
pz *= length_unit_;
double l = basis_curve_length - last_distance;
+13 -13
View File
@@ -30,37 +30,37 @@ const double PI = boost::math::constants::pi<double>();
#ifdef SCHEMA_HAS_IfcOpenCrossProfileDef
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOpenCrossProfileDef* inst) {
if (inst->ProfileType() != IfcSchema::IfcProfileTypeEnum::IfcProfileType_CURVE) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOpenCrossProfileDef& inst) {
if (inst.ProfileType() != IfcSchema::IfcProfileTypeEnum::IfcProfileType_CURVE) {
Logger::Warning("Expected IfcOpenCrossProfileDef.ProfileType to be CURVE", inst);
return nullptr;
}
std::vector<taxonomy::point3::ptr> points;
taxonomy::point3::ptr start;
if (inst->OffsetPoint()) {
start = taxonomy::cast<taxonomy::point3>(map(inst->OffsetPoint()));
if (inst.OffsetPoint()) {
start = taxonomy::cast<taxonomy::point3>(map(inst.OffsetPoint()));
} else {
start = taxonomy::make<taxonomy::point3>(0., 0., 0.);
}
points.push_back(start);
boost::optional<std::vector<std::string>> tags = inst->Tags();
boost::optional<std::string> tag = boost::none;
if (tags.has_value() && !tags.get().empty()) {
tag = tags.get()[0];
std::optional<std::vector<std::string>> tags = inst.Tags();
std::optional<std::string> tag;
if (tags.has_value() && !tags.value().empty()) {
tag = tags.value()[0];
}
// start->tag = tag;
auto widths = inst->Widths();
auto angles = inst->Slopes(); // these are actually angles, but the attribute is called Slopes
auto widths = inst.Widths();
auto angles = inst.Slopes(); // these are actually angles, but the attribute is called Slopes
if (widths.size() != angles.size()) {
Logger::Warning("Expected Widths and Slopes to be equal length, but got " + std::to_string(widths.size()) + " and " + std::to_string(angles.size()) + " respectively", inst);
return nullptr;
}
auto horizontal_widths = inst->HorizontalWidths();
auto horizontal_widths = inst.HorizontalWidths();
double x = start->ccomponents().x();
double y = start->ccomponents().y();
@@ -75,8 +75,8 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOpenCrossProfileDef* inst) {
y += dy;
z += dz;
if (tags.has_value() && !tags.get().empty()) {
tag = tags.get()[i+1];
if (tags.has_value() && !tags.value().empty()) {
tag = tags.value()[i+1];
}
points.push_back(taxonomy::make<taxonomy::point3>(x, y, z));
+3 -3
View File
@@ -21,10 +21,10 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOrientedEdge* inst) {
auto e = taxonomy::cast<taxonomy::edge>(map(inst->EdgeElement()));
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOrientedEdge& inst) {
auto e = taxonomy::cast<taxonomy::edge>(map(inst.EdgeElement()));
e.reset(e->clone_());
if (!inst->Orientation()) {
if (!inst.Orientation()) {
e->reverse();
}
return e;
+2 -2
View File
@@ -21,8 +21,8 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPlane* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPlane& inst) {
auto p = taxonomy::make<taxonomy::plane>();
p->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
p->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
return p;
}
@@ -26,9 +26,9 @@ using namespace ifcopenshell::geometry;
#if defined SCHEMA_HAS_IfcPointByDistanceExpression
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPointByDistanceExpression* inst) {
auto u = (*inst->DistanceAlong()->as<IfcSchema::IfcLengthMeasure>()) * length_unit_;
auto basis_curve = map(inst->BasisCurve());
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPointByDistanceExpression& inst) {
auto u = (double) inst.DistanceAlong().as<IfcSchema::IfcLengthMeasure>() * length_unit_;
auto basis_curve = map(inst.BasisCurve());
taxonomy::function_item::ptr curve = taxonomy::dcast<taxonomy::function_item>(basis_curve);
if (!curve) {
// if the basis curve is not a function_item, the cast it to piecewise_function. the casting operator
@@ -43,19 +43,19 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPointByDistanceExpression* i
auto z = m.col(2).head<3>();
auto x = m.col(0).head<3>();
if (inst->OffsetLateral().has_value()) {
auto offset_lateral = inst->OffsetLateral().get() * length_unit_;
if (inst.OffsetLateral().has_value()) {
auto offset_lateral = inst.OffsetLateral().value() * length_unit_;
auto y = Eigen::Vector3d(m.col(1)(0), m.col(1)(1), m.col(1)(2));
o += offset_lateral * y;
}
if (inst->OffsetVertical().has_value()) {
auto offset_vertical = inst->OffsetVertical().get() * length_unit_;
if (inst.OffsetVertical().has_value()) {
auto offset_vertical = inst.OffsetVertical().value() * length_unit_;
o += offset_vertical * z;
}
if (inst->OffsetLongitudinal().has_value()) {
auto offset_longitudinal = inst->OffsetLongitudinal().get() * length_unit_;
if (inst.OffsetLongitudinal().has_value()) {
auto offset_longitudinal = inst.OffsetLongitudinal().value() * length_unit_;
o += offset_longitudinal* x;
}
+4 -4
View File
@@ -23,13 +23,13 @@ using namespace ifcopenshell::geometry;
#include "../profile_helper.h"
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyLoop* inst) {
IfcSchema::IfcCartesianPoint::list::ptr points = inst->Polygon();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyLoop& inst) {
std::vector<IfcSchema::IfcCartesianPoint> points = inst.Polygon();
// Parse and store the points in a sequence
std::vector<taxonomy::point3::ptr> polygon;
polygon.reserve(points->size());
std::transform(points->begin(), points->end(), std::back_inserter(polygon), [this](const IfcSchema::IfcCartesianPoint* p) {
polygon.reserve(points.size());
std::transform(points.begin(), points.end(), std::back_inserter(polygon), [this](const IfcSchema::IfcCartesianPoint& p) {
return taxonomy::cast<taxonomy::point3>(map(p));
});
@@ -21,10 +21,10 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolygonalBoundedHalfSpace* inst) {
auto s = taxonomy::cast<taxonomy::solid>(map_impl((IfcSchema::IfcHalfSpaceSolid*) inst));
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolygonalBoundedHalfSpace& inst) {
auto s = taxonomy::cast<taxonomy::solid>(map_impl((IfcSchema::IfcHalfSpaceSolid&) inst));
auto f = s->children[0]->children[0];
f->children = { taxonomy::cast<taxonomy::loop>(map(inst->PolygonalBoundary())) };
f->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
f->children = { taxonomy::cast<taxonomy::loop>(map(inst.PolygonalBoundary())) };
f->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
return s;
}
+8 -8
View File
@@ -23,10 +23,10 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcPolygonalFaceSet
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolygonalFaceSet* inst) {
IfcSchema::IfcCartesianPointList3D* point_list = inst->Coordinates();
auto coordinates = point_list->CoordList();
auto polygonal_faces = inst->Faces();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolygonalFaceSet& inst) {
auto point_list = inst.Coordinates();
auto coordinates = point_list.CoordList();
auto polygonal_faces = inst.Faces();
std::vector<taxonomy::point3::ptr> points;
points.reserve(coordinates.size());
@@ -41,7 +41,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolygonalFaceSet* inst) {
auto shell = taxonomy::make<taxonomy::shell>();
for (auto& f : *polygonal_faces) {
for (auto& f : polygonal_faces) {
auto fa = taxonomy::make<taxonomy::face>();
shell->children.push_back(fa);
@@ -49,7 +49,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolygonalFaceSet* inst) {
auto loop = taxonomy::make<taxonomy::loop>();
fa->children = { loop };
loop->external = true;
auto indices = f->CoordIndex();
auto indices = f.CoordIndex();
taxonomy::point3::ptr previous;
for (std::vector<int>::const_iterator jt = indices.begin(); jt != indices.end(); ++jt) {
if (*jt < 1 || *jt > max_index) {
@@ -67,8 +67,8 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolygonalFaceSet* inst) {
}
}
if (f->as<IfcSchema::IfcIndexedPolygonalFaceWithVoids>()) {
auto indices = f->as<IfcSchema::IfcIndexedPolygonalFaceWithVoids>()->InnerCoordIndices();
if (auto withvoids = f.as<IfcSchema::IfcIndexedPolygonalFaceWithVoids>()) {
auto indices = withvoids.InnerCoordIndices();
{
taxonomy::point3::ptr previous;
for (auto& li : indices) {
+4 -4
View File
@@ -23,13 +23,13 @@ using namespace ifcopenshell::geometry;
#include "../profile_helper.h"
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyline* inst) {
IfcSchema::IfcCartesianPoint::list::ptr points = inst->Points();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyline& inst) {
std::vector<IfcSchema::IfcCartesianPoint> points = inst.Points();
// Parse and store the points in a sequence
std::vector<taxonomy::point3::ptr> polygon;
polygon.reserve(points->size());
std::transform(points->begin(), points->end(), std::back_inserter(polygon), [this](const IfcSchema::IfcCartesianPoint* p) {
polygon.reserve(points.size());
std::transform(points.begin(), points.end(), std::back_inserter(polygon), [this](const IfcSchema::IfcCartesianPoint& p) {
return taxonomy::cast<taxonomy::point3>(map(p));
});
+6 -6
View File
@@ -4,12 +4,12 @@ using namespace ifcopenshell::geometry;
using namespace IfcGeom;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcProduct* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcProduct& inst) {
// @todo decide on this, what happens in the product mapping?
// currently things like openings, layers and materials are processed in the converter
auto c = taxonomy::make<taxonomy::collection>();
if (inst->ObjectPlacement()) {
c->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->ObjectPlacement()));
if (inst.ObjectPlacement()) {
c->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.ObjectPlacement()));
} else {
// @todo Otherwise we get crashes in the serializer, but maybe fix them there..?
c->matrix = taxonomy::make<taxonomy::matrix4>();
@@ -21,7 +21,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcProduct* inst) {
auto openings = find_openings(inst);
// @todo const cast
auto reps = inst->data().file->traverse((IfcSchema::IfcProduct*) inst, 2)->as<IfcSchema::IfcRepresentation>();
auto reps = inst.data().file->traverse((IfcSchema::IfcProduct*) inst, 2)->as<IfcSchema::IfcRepresentation>();
IfcSchema::IfcRepresentation* body = nullptr;
for (auto& rep : *reps) {
if (rep->RepresentationIdentifier()) {
@@ -35,7 +35,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcProduct* inst) {
}
auto c = new taxonomy::collection;
c->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->ObjectPlacement()));
c->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.ObjectPlacement()));
const auto single_material = get_single_material_association(inst);
if (single_material) {
@@ -54,7 +54,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcProduct* inst) {
ci.setIdentity();
}
aggregate_of_instance::ptr operands(new aggregate_of_instance);
std::vector<express::Base> operands(new aggregate_of_instance);
operands->push(body);
operands->push(openings);
auto n = map_to_collection<taxonomy::boolean_result>(this, operands);
@@ -23,16 +23,16 @@ using namespace ifcopenshell::geometry;
#include "../profile_helper.h"
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangleHollowProfileDef* inst) {
const double x = inst->XDim() / 2.0f * length_unit_;
const double y = inst->YDim() / 2.0f * length_unit_;
const double d = inst->WallThickness() * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangleHollowProfileDef& inst) {
const double x = inst.XDim() / 2.0f * length_unit_;
const double y = inst.YDim() / 2.0f * length_unit_;
const double d = inst.WallThickness() * length_unit_;
const bool fr1 = !!inst->OuterFilletRadius();
const bool fr2 = !!inst->InnerFilletRadius();
const bool fr1 = !!inst.OuterFilletRadius();
const bool fr2 = !!inst.InnerFilletRadius();
const double r1 = fr1 ? (*inst->OuterFilletRadius()) * length_unit_ : 0.;
const double r2 = fr2 ? (*inst->InnerFilletRadius()) * length_unit_ : 0.;
const double r1 = fr1 ? (*inst.OuterFilletRadius()) * length_unit_ : 0.;
const double r2 = fr2 ? (*inst.InnerFilletRadius()) * length_unit_ : 0.;
const double tol = settings_.get<settings::Precision>().get();
@@ -44,10 +44,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangleHollowProfileDef* i
taxonomy::matrix4::ptr m4;
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
auto s1 = profile_helper(m4, {
@@ -23,9 +23,9 @@ using namespace ifcopenshell::geometry;
#include "../profile_helper.h"
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangleProfileDef* inst) {
const double x = inst->XDim() / 2.0f * length_unit_;
const double y = inst->YDim() / 2.0f * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangleProfileDef& inst) {
const double x = inst.XDim() / 2.0f * length_unit_;
const double y = inst.YDim() / 2.0f * length_unit_;
const double tol = settings_.get<settings::Precision>().get();
@@ -37,10 +37,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangleProfileDef* inst) {
taxonomy::matrix4::ptr m4;
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
return profile_helper(m4, {

Some files were not shown because too many files have changed in this diff Show More