mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-11 06:18:09 +00:00
Generalize IfcGeom::Iterator filtering and move make the filter specification external to the Iterator.
This commit is contained in:
committed by
Thomas Krijnen
parent
d8a11dd096
commit
195d68cd0a
@@ -116,18 +116,17 @@ bool rename_file(const std::string& old_filename, const std::string& new_filenam
|
|||||||
static std::stringstream log_stream;
|
static std::stringstream log_stream;
|
||||||
void write_log();
|
void write_log();
|
||||||
|
|
||||||
/// @todo Make this a feature of IfcGeom::Iterator instead.
|
|
||||||
struct geom_filter
|
struct geom_filter
|
||||||
{
|
{
|
||||||
bool include;
|
geom_filter() : type(UNUSED) {}
|
||||||
enum filter_type { ENTITY_TYPE, ENTITY_NAME, ENTITY_GUID, LAYER_NAME };
|
enum filter_type { UNUSED, ENTITY_TYPE, ENTITY_NAME, ENTITY_GUID, LAYER_NAME };
|
||||||
filter_type type;
|
filter_type type;
|
||||||
std::set<std::string> values;
|
std::set<std::string> values;
|
||||||
};
|
};
|
||||||
// Specialized classes for knowing which type of filter we are validating within validate().
|
// Specialized classes for knowing which type of filter we are validating within validate().
|
||||||
// Could not figure out easily how else to know it if using single type for both.
|
// Could not figure out easily how else to know it if using single type for both.
|
||||||
struct inclusion_filter : public geom_filter { inclusion_filter() { include = true; } };
|
struct inclusion_filter : public IfcGeom::filter, public geom_filter { inclusion_filter() : filter(true, false) {} };
|
||||||
struct exclusion_filter : public geom_filter { exclusion_filter() { include = false; } };
|
struct exclusion_filter : public IfcGeom::filter, public geom_filter { exclusion_filter() : filter(false, false) {} };
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
@@ -271,7 +270,6 @@ int main(int argc, char** argv)
|
|||||||
std::cerr << "[Error] Invalid usage of '" << e.get_option_name() << "': " << e.what() << "\n\n";
|
std::cerr << "[Error] Invalid usage of '" << e.get_option_name() << "': " << e.what() << "\n\n";
|
||||||
print_usage();
|
print_usage();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
return EXIT_FAILURE;
|
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
std::cerr << "[Error] " << e.what() << "\n\n";
|
std::cerr << "[Error] " << e.what() << "\n\n";
|
||||||
print_usage();
|
print_usage();
|
||||||
@@ -295,18 +293,6 @@ int main(int argc, char** argv)
|
|||||||
print_usage();
|
print_usage();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (include_filter.type == geom_filter::ENTITY_GUID) {
|
|
||||||
guids = include_filter.values;
|
|
||||||
} else if (exclude_filter.type == geom_filter::ENTITY_GUID) {
|
|
||||||
guids = exclude_filter.values;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (include_filter.type == geom_filter::LAYER_NAME) {
|
|
||||||
layers = include_filter.values;
|
|
||||||
} else if (exclude_filter.type == geom_filter::LAYER_NAME) {
|
|
||||||
layers = exclude_filter.values;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool verbose = vmap.count("verbose") != 0;
|
const bool verbose = vmap.count("verbose") != 0;
|
||||||
const bool weld_vertices = vmap.count("weld-vertices") != 0;
|
const bool weld_vertices = vmap.count("weld-vertices") != 0;
|
||||||
const bool use_world_coords = vmap.count("use-world-coords") != 0;
|
const bool use_world_coords = vmap.count("use-world-coords") != 0;
|
||||||
@@ -316,10 +302,6 @@ int main(int argc, char** argv)
|
|||||||
const bool merge_boolean_operands = vmap.count("merge-boolean-operands") != 0;
|
const bool merge_boolean_operands = vmap.count("merge-boolean-operands") != 0;
|
||||||
#endif
|
#endif
|
||||||
const bool disable_opening_subtractions = vmap.count("disable-opening-subtractions") != 0;
|
const bool disable_opening_subtractions = vmap.count("disable-opening-subtractions") != 0;
|
||||||
bool include_entities = include_filter.type == geom_filter::ENTITY_TYPE && !include_filter.values.empty();
|
|
||||||
const bool include_names = include_filter.type == geom_filter::ENTITY_NAME && !include_filter.values.empty();
|
|
||||||
const bool include_guids = include_filter.type == geom_filter::ENTITY_GUID && !include_filter.values.empty();
|
|
||||||
const bool include_layers = include_filter.type == geom_filter::LAYER_NAME && !include_filter.values.empty();
|
|
||||||
const bool include_plan = vmap.count("plan") != 0;
|
const bool include_plan = vmap.count("plan") != 0;
|
||||||
const bool include_model = vmap.count("model") != 0 || (!include_plan);
|
const bool include_model = vmap.count("model") != 0 || (!include_plan);
|
||||||
const bool enable_layerset_slicing = vmap.count("enable-layerset-slicing") != 0;
|
const bool enable_layerset_slicing = vmap.count("enable-layerset-slicing") != 0;
|
||||||
@@ -330,6 +312,7 @@ int main(int argc, char** argv)
|
|||||||
const bool center_model = vmap.count("center-model") != 0 ;
|
const bool center_model = vmap.count("center-model") != 0 ;
|
||||||
const bool model_offset = vmap.count("model-offset") != 0 ;
|
const bool model_offset = vmap.count("model-offset") != 0 ;
|
||||||
const bool generate_uvs = vmap.count("generate-uvs") != 0 ;
|
const bool generate_uvs = vmap.count("generate-uvs") != 0 ;
|
||||||
|
/// @todo For now traversal is a global option for all filters but we could easily make it filter-specific.
|
||||||
const bool traverse = vmap.count("traverse") != 0;
|
const bool traverse = vmap.count("traverse") != 0;
|
||||||
|
|
||||||
#ifdef HAVE_ICU
|
#ifdef HAVE_ICU
|
||||||
@@ -392,6 +375,67 @@ int main(int argc, char** argv)
|
|||||||
boost::to_lower(output_extension);
|
boost::to_lower(output_extension);
|
||||||
|
|
||||||
|
|
||||||
|
// Set up filters. Entity filter is used always by default.
|
||||||
|
|
||||||
|
IfcGeom::entity_filter entity_filter;
|
||||||
|
entity_filter.traverse = traverse;
|
||||||
|
try {
|
||||||
|
if (include_filter.type == geom_filter::ENTITY_TYPE) {
|
||||||
|
entity_filter.include = true;
|
||||||
|
entity_filter.populate(include_filter.values);
|
||||||
|
} else if (exclude_filter.type == geom_filter::ENTITY_TYPE) {
|
||||||
|
entity_filter.include = false;
|
||||||
|
entity_filter.populate(exclude_filter.values);
|
||||||
|
}
|
||||||
|
// If no entity names are specified these are the defaults to skip from output
|
||||||
|
if (entity_filter.values.empty()) {
|
||||||
|
std::set<std::string> entities;
|
||||||
|
entities.insert("IfcSpace");
|
||||||
|
if (output_extension == ".svg") {
|
||||||
|
entity_filter.include = true;
|
||||||
|
} else {
|
||||||
|
entities.insert("IfcOpeningElement");
|
||||||
|
}
|
||||||
|
entity_filter.populate(entities);
|
||||||
|
|
||||||
|
Logger::Message(Logger::LOG_NOTICE, entity_filter.include ? "Including" : "Excluding" +
|
||||||
|
std::string(" by default entities ") + boost::algorithm::join(entities, ", "));
|
||||||
|
}
|
||||||
|
} catch (const IfcParse::IfcException& e) {
|
||||||
|
std::cout << "[Error] " << e.what() << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
IfcGeom::arg_filter<IfcSchema::IfcRoot, 2, std::string> name_filter;
|
||||||
|
name_filter.traverse = traverse;
|
||||||
|
if (include_filter.type == geom_filter::ENTITY_NAME) {
|
||||||
|
name_filter.include = true;
|
||||||
|
name_filter.populate(include_filter.values);
|
||||||
|
} else if (exclude_filter.type == geom_filter::ENTITY_NAME) {
|
||||||
|
name_filter.include = false;
|
||||||
|
name_filter.populate(exclude_filter.values);
|
||||||
|
}
|
||||||
|
|
||||||
|
IfcGeom::arg_filter<IfcSchema::IfcRoot, 0, std::string> guid_filter;
|
||||||
|
guid_filter.traverse = traverse;
|
||||||
|
if (include_filter.type == geom_filter::ENTITY_GUID) {
|
||||||
|
guid_filter.include = true;
|
||||||
|
guid_filter.populate(include_filter.values);
|
||||||
|
} else if (exclude_filter.type == geom_filter::ENTITY_GUID) {
|
||||||
|
guid_filter.include = false;
|
||||||
|
guid_filter.populate(include_filter.values);
|
||||||
|
}
|
||||||
|
|
||||||
|
IfcGeom::layer_filter layer_filter;
|
||||||
|
layer_filter.traverse = traverse;
|
||||||
|
if (include_filter.type == geom_filter::LAYER_NAME) {
|
||||||
|
layer_filter.include = true;
|
||||||
|
layer_filter.populate(include_filter.values);
|
||||||
|
} else if (exclude_filter.type == geom_filter::LAYER_NAME) {
|
||||||
|
layer_filter.include = false;
|
||||||
|
layer_filter.populate(exclude_filter.values);
|
||||||
|
}
|
||||||
|
|
||||||
if (output_extension == ".xml") {
|
if (output_extension == ".xml") {
|
||||||
int exit_code = 1;
|
int exit_code = 1;
|
||||||
try {
|
try {
|
||||||
@@ -482,16 +526,18 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
IfcGeom::Iterator<real_t> context_iterator(settings, input_filename);
|
IfcGeom::Iterator<real_t> context_iterator(settings, input_filename);
|
||||||
|
|
||||||
try {
|
if (!guid_filter.values.empty()) {
|
||||||
context_iterator.filter_entities(include_entities, entities, traverse);
|
context_iterator.filters().push_back(boost::ref(guid_filter));
|
||||||
} catch (const IfcParse::IfcException& e) {
|
}
|
||||||
std::cout << "[Error] " << e.what() << std::endl;
|
if (!name_filter.values.empty()) {
|
||||||
return 1;
|
context_iterator.filters().push_back(boost::ref(name_filter));
|
||||||
|
}
|
||||||
|
if (!entity_filter.values.empty()) {
|
||||||
|
context_iterator.filters().push_back(boost::ref(entity_filter));
|
||||||
|
}
|
||||||
|
if (!layer_filter.values.empty()) {
|
||||||
|
context_iterator.filters().push_back(boost::ref(layer_filter));
|
||||||
}
|
}
|
||||||
|
|
||||||
context_iterator.filter_entity_names(include_names, names, traverse);
|
|
||||||
context_iterator.filter_entity_guids(include_guids, guids, traverse);
|
|
||||||
context_iterator.filter_layer_names(include_layers, layers, traverse);
|
|
||||||
|
|
||||||
if (!serializer->ready()) {
|
if (!serializer->ready()) {
|
||||||
write_log();
|
write_log();
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ public:
|
|||||||
|
|
||||||
std::pair<std::string, double> initializeUnits(IfcSchema::IfcUnitAssignment*);
|
std::pair<std::string, double> initializeUnits(IfcSchema::IfcUnitAssignment*);
|
||||||
|
|
||||||
IfcSchema::IfcObjectDefinition* get_decomposing_entity(IfcSchema::IfcProduct*);
|
static IfcSchema::IfcObjectDefinition* get_decomposing_entity(IfcSchema::IfcProduct*);
|
||||||
|
|
||||||
static std::map<std::string, IfcSchema::IfcPresentationLayerAssignment*> get_layers(IfcSchema::IfcProduct* prod);
|
static std::map<std::string, IfcSchema::IfcPresentationLayerAssignment*> get_layers(IfcSchema::IfcProduct* prod);
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ namespace IfcGeom {
|
|||||||
std::string _context;
|
std::string _context;
|
||||||
std::string _unique_id;
|
std::string _unique_id;
|
||||||
Transformation<P> _transformation;
|
Transformation<P> _transformation;
|
||||||
|
IfcSchema::IfcProduct* product_;
|
||||||
public:
|
public:
|
||||||
int id() const { return _id; }
|
int id() const { return _id; }
|
||||||
int parent_id() const { return _parent_id; }
|
int parent_id() const { return _parent_id; }
|
||||||
@@ -89,8 +90,12 @@ namespace IfcGeom {
|
|||||||
const std::string& context() const { return _context; }
|
const std::string& context() const { return _context; }
|
||||||
const std::string& unique_id() const { return _unique_id; }
|
const std::string& unique_id() const { return _unique_id; }
|
||||||
const Transformation<P>& transformation() const { return _transformation; }
|
const Transformation<P>& transformation() const { return _transformation; }
|
||||||
Element(const ElementSettings& settings, int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid, const std::string& context, const gp_Trsf& trsf)
|
IfcSchema::IfcProduct* product() const { return product_; }
|
||||||
|
|
||||||
|
Element(const ElementSettings& settings, int id, int parent_id, const std::string& name, const std::string& type,
|
||||||
|
const std::string& guid, const std::string& context, const gp_Trsf& trsf, IfcSchema::IfcProduct *product)
|
||||||
: _id(id), _parent_id(parent_id), _name(name), _type(type), _guid(guid), _context(context), _transformation(settings, trsf)
|
: _id(id), _parent_id(parent_id), _name(name), _type(type), _guid(guid), _context(context), _transformation(settings, trsf)
|
||||||
|
, product_(product)
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "product-" << IfcParse::IfcGlobalId(guid).formatted();
|
oss << "product-" << IfcParse::IfcGlobalId(guid).formatted();
|
||||||
@@ -112,8 +117,10 @@ namespace IfcGeom {
|
|||||||
public:
|
public:
|
||||||
const boost::shared_ptr<Representation::BRep>& geometry_pointer() const { return _geometry; }
|
const boost::shared_ptr<Representation::BRep>& geometry_pointer() const { return _geometry; }
|
||||||
const Representation::BRep& geometry() const { return *_geometry; }
|
const 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 gp_Trsf& trsf, const boost::shared_ptr<Representation::BRep>& geometry)
|
BRepElement(int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid,
|
||||||
: Element<P>(geometry->settings(),id,parent_id,name,type,guid,context,trsf)
|
const std::string& context, const gp_Trsf& trsf, const boost::shared_ptr<Representation::BRep>& geometry,
|
||||||
|
IfcSchema::IfcProduct* product)
|
||||||
|
: Element<P>(geometry->settings(),id,parent_id,name,type,guid,context,trsf, product)
|
||||||
, _geometry(geometry)
|
, _geometry(geometry)
|
||||||
{}
|
{}
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -0,0 +1,241 @@
|
|||||||
|
/********************************************************************************
|
||||||
|
* *
|
||||||
|
* This file is part of IfcOpenShell. *
|
||||||
|
* *
|
||||||
|
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the Lesser GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* Lesser GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the Lesser GNU General Public License *
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
|
* *
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
/** @file IfcGeomFilter.h
|
||||||
|
@brief A set of predefined product filters for IfcGeom::Iterator */
|
||||||
|
|
||||||
|
#ifndef IFCGEOMFILTER_H
|
||||||
|
#define IFCGEOMFILTER_H
|
||||||
|
|
||||||
|
#include "IfcGeom.h"
|
||||||
|
#include <boost/regex.hpp>
|
||||||
|
|
||||||
|
namespace IfcGeom
|
||||||
|
{
|
||||||
|
typedef boost::function<bool(IfcSchema::IfcProduct*)> filter_t;
|
||||||
|
|
||||||
|
struct filter
|
||||||
|
{
|
||||||
|
filter() : include(false), traverse(false) {}
|
||||||
|
filter(bool incl, bool trav) : include(incl), traverse(trav) {}
|
||||||
|
/// Should the product be included (true) or excluded (false).
|
||||||
|
bool include;
|
||||||
|
/// If traversal requested, traverse to the parents to see if they satisfy the criteria. E.g. we might be looking for
|
||||||
|
/// children of a storey named "Level 20", or children of entities that have no representation, e.g. IfcCurtainWall.
|
||||||
|
bool traverse;
|
||||||
|
|
||||||
|
//static bool traverse_match(IfcSchema::IfcProduct* prod, filter_t pred)
|
||||||
|
//{
|
||||||
|
// bool is_match = false;
|
||||||
|
// IfcSchema::IfcProduct* parent, *current = prod;
|
||||||
|
// while ((parent = static_cast<IfcSchema::IfcProduct*>(IfcGeom::Kernel::get_decomposing_entity(current))) != 0) {
|
||||||
|
// if (pred(parent)) {
|
||||||
|
// is_match = true;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// current = parent;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wildcard_filter : public filter
|
||||||
|
{
|
||||||
|
wildcard_filter() : filter(false, false) {}
|
||||||
|
wildcard_filter(bool include, bool traverse, const std::set<std::string>& patterns)
|
||||||
|
: filter(include, traverse)
|
||||||
|
{
|
||||||
|
populate(patterns);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<boost::regex> values;
|
||||||
|
|
||||||
|
void populate(const std::set<std::string>& patterns)
|
||||||
|
{
|
||||||
|
values.clear();
|
||||||
|
foreach(const std::string &pattern, patterns) {
|
||||||
|
values.insert(wildcard_string_to_regex(pattern));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool match(const std::string &str) const
|
||||||
|
{
|
||||||
|
foreach(const boost::regex& r, values) {
|
||||||
|
if (boost::regex_match(str, r)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boost::regex wildcard_string_to_regex(std::string str)
|
||||||
|
{
|
||||||
|
// Escape all non-"*?" regex special chars
|
||||||
|
std::string special_chars = "\\^.$|()[]+/";
|
||||||
|
foreach(char c, special_chars) {
|
||||||
|
std::string char_str(1, c);
|
||||||
|
boost::replace_all(str, char_str, "\\" + char_str);
|
||||||
|
}
|
||||||
|
// Convert "*?" to their regex equivalents
|
||||||
|
boost::replace_all(str, "?", ".");
|
||||||
|
boost::replace_all(str, "*", ".*");
|
||||||
|
return boost::regex(str);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// @todo Maybe not use template class for this after all. Attribute name would be better
|
||||||
|
/// than index, but IfcBaseClass doesn't have getArgument(name) (IfcLateBoundEntity would have though).
|
||||||
|
template<class ClassType, unsigned short ArgIndex, typename ArgType>
|
||||||
|
struct arg_filter : public wildcard_filter
|
||||||
|
{
|
||||||
|
arg_filter()
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
ClassType dummy(0);
|
||||||
|
assert(ArgIndex < dummy.getArgumentCount());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
arg_filter(bool include, bool traverse, const std::set<std::string>& patterns)
|
||||||
|
: wildcard_filter(include, traverse, patterns)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
ClassType dummy(0);
|
||||||
|
assert(ArgIndex < dummy.getArgumentCount());
|
||||||
|
#endif
|
||||||
|
populate(patterns);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArgType value(IfcSchema::IfcProduct* prod) const
|
||||||
|
{
|
||||||
|
Argument *arg = prod->entity->getArgument(ArgIndex);
|
||||||
|
return !arg->isNull() ? *arg : ArgType();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(IfcSchema::IfcProduct* prod) const
|
||||||
|
{
|
||||||
|
bool is_match = match(value(prod));
|
||||||
|
if (is_match != include && traverse) {
|
||||||
|
IfcSchema::IfcProduct* parent, *current = prod;
|
||||||
|
while ((parent = static_cast<IfcSchema::IfcProduct*>(IfcGeom::Kernel::get_decomposing_entity(current))) != 0) {
|
||||||
|
if (match(value(parent))) {
|
||||||
|
is_match = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
current = parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return is_match == include;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct layer_filter : public wildcard_filter
|
||||||
|
{
|
||||||
|
layer_filter() {}
|
||||||
|
layer_filter(bool include, bool traverse, const std::set<std::string>& patterns)
|
||||||
|
: wildcard_filter(include, traverse, patterns)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(IfcSchema::IfcProduct* prod) const
|
||||||
|
{
|
||||||
|
bool is_match = false;
|
||||||
|
std::map<std::string, IfcSchema::IfcPresentationLayerAssignment*> layers = IfcGeom::Kernel::get_layers(prod);
|
||||||
|
std::map<std::string, IfcSchema::IfcPresentationLayerAssignment*>::const_iterator lit;
|
||||||
|
for (lit = layers.begin(); lit != layers.end(); ++lit) {
|
||||||
|
if (match(lit->first)) {
|
||||||
|
is_match = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_match != include && traverse) {
|
||||||
|
for (lit = layers.begin(); lit != layers.end(); ++lit) {
|
||||||
|
IfcSchema::IfcProduct* parent, *current = prod;
|
||||||
|
while ((parent = static_cast<IfcSchema::IfcProduct*>(IfcGeom::Kernel::get_decomposing_entity(current))) != 0) {
|
||||||
|
if (match(lit->first)) {
|
||||||
|
is_match = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
current = parent;
|
||||||
|
}
|
||||||
|
if (is_match) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return is_match == include;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct entity_filter : public filter
|
||||||
|
{
|
||||||
|
entity_filter() {}
|
||||||
|
entity_filter(bool include, bool traverse/*, const std::set<std::string>& types*/)
|
||||||
|
: filter(include, traverse)
|
||||||
|
{
|
||||||
|
//populate(types);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<IfcSchema::Type::Enum> values;
|
||||||
|
|
||||||
|
void populate(const std::set<std::string>& types)
|
||||||
|
{
|
||||||
|
values.clear();
|
||||||
|
foreach(const std::string& type, types) {
|
||||||
|
IfcSchema::Type::Enum ty;
|
||||||
|
try {
|
||||||
|
ty = IfcSchema::Type::FromString(boost::to_upper_copy(type));
|
||||||
|
} catch (const IfcParse::IfcException&) {
|
||||||
|
throw IfcParse::IfcException("'" + type + "' does not name a valid IFC entity");
|
||||||
|
}
|
||||||
|
values.insert(ty);
|
||||||
|
// TODO: Add child classes so that containment in set can be in O(log n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool match(IfcSchema::IfcProduct* prod) const
|
||||||
|
{
|
||||||
|
// The set is iterated over to able to filter on subtypes.
|
||||||
|
foreach(IfcSchema::Type::Enum type, values) {
|
||||||
|
if (prod->is(type)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(IfcSchema::IfcProduct* prod) const
|
||||||
|
{
|
||||||
|
bool is_match = match(prod);
|
||||||
|
if (is_match != include && traverse) {
|
||||||
|
IfcSchema::IfcProduct* parent, *current = prod;
|
||||||
|
while ((parent = static_cast<IfcSchema::IfcProduct*>(IfcGeom::Kernel::get_decomposing_entity(current))) != 0) {
|
||||||
|
if (match(parent)) {
|
||||||
|
is_match = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
current = parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return is_match == include;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1174,7 +1174,8 @@ IfcGeom::BRepElement<P>* IfcGeom::Kernel::create_brep_for_representation_and_pro
|
|||||||
guid,
|
guid,
|
||||||
context_string,
|
context_string,
|
||||||
trsf,
|
trsf,
|
||||||
boost::shared_ptr<IfcGeom::Representation::BRep>(shape)
|
boost::shared_ptr<IfcGeom::Representation::BRep>(shape),
|
||||||
|
product
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1216,7 +1217,8 @@ IfcGeom::BRepElement<P>* IfcGeom::Kernel::create_brep_for_processed_representati
|
|||||||
guid,
|
guid,
|
||||||
context_string,
|
context_string,
|
||||||
trsf,
|
trsf,
|
||||||
brep->geometry_pointer()
|
brep->geometry_pointer(),
|
||||||
|
product
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1234,7 +1236,7 @@ IfcSchema::IfcObjectDefinition* IfcGeom::Kernel::get_decomposing_entity(IfcSchem
|
|||||||
} else if ( product->is(IfcSchema::Type::IfcElement ) ) {
|
} else if ( product->is(IfcSchema::Type::IfcElement ) ) {
|
||||||
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)product;
|
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)product;
|
||||||
IfcSchema::IfcRelFillsElement::list::ptr fills = element->FillsVoids();
|
IfcSchema::IfcRelFillsElement::list::ptr fills = element->FillsVoids();
|
||||||
// Incase of a RelatedBuildingElement parent to the opening element
|
// In case of a RelatedBuildingElement parent to the opening element
|
||||||
if ( fills->size() ) {
|
if ( fills->size() ) {
|
||||||
for ( IfcSchema::IfcRelFillsElement::list::it it = fills->begin(); it != fills->end(); ++ it ) {
|
for ( IfcSchema::IfcRelFillsElement::list::it it = fills->begin(); it != fills->end(); ++ it ) {
|
||||||
IfcSchema::IfcRelFillsElement* fill = *it;
|
IfcSchema::IfcRelFillsElement* fill = *it;
|
||||||
|
|||||||
+44
-247
@@ -65,7 +65,6 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/regex.hpp>
|
|
||||||
|
|
||||||
#include <gp_Mat.hxx>
|
#include <gp_Mat.hxx>
|
||||||
#include <gp_Mat2d.hxx>
|
#include <gp_Mat2d.hxx>
|
||||||
@@ -81,6 +80,7 @@
|
|||||||
#include "../ifcgeom/IfcGeomMaterial.h"
|
#include "../ifcgeom/IfcGeomMaterial.h"
|
||||||
#include "../ifcgeom/IfcGeomIteratorSettings.h"
|
#include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||||
#include "../ifcgeom/IfcRepresentationShapeItem.h"
|
#include "../ifcgeom/IfcRepresentationShapeItem.h"
|
||||||
|
#include "../ifcgeom/IfcGeomFilter.h"
|
||||||
|
|
||||||
// The infamous min & max Win32 #defines can leak here from OCE depending on the build configuration
|
// The infamous min & max Win32 #defines can leak here from OCE depending on the build configuration
|
||||||
#ifdef min
|
#ifdef min
|
||||||
@@ -125,6 +125,16 @@ namespace IfcGeom {
|
|||||||
gp_XYZ bounds_min_;
|
gp_XYZ bounds_min_;
|
||||||
gp_XYZ bounds_max_;
|
gp_XYZ bounds_max_;
|
||||||
|
|
||||||
|
std::vector<filter_t> filters_;
|
||||||
|
|
||||||
|
struct filter_match
|
||||||
|
{
|
||||||
|
filter_match(IfcSchema::IfcProduct *prod) : product(prod) {}
|
||||||
|
bool operator()(const filter_t& filter) const { return filter(product); }
|
||||||
|
|
||||||
|
IfcSchema::IfcProduct* product;
|
||||||
|
};
|
||||||
|
|
||||||
void initUnits() {
|
void initUnits() {
|
||||||
IfcSchema::IfcProject::list::ptr projects = ifc_file->entitiesByType<IfcSchema::IfcProject>();
|
IfcSchema::IfcProject::list::ptr projects = ifc_file->entitiesByType<IfcSchema::IfcProject>();
|
||||||
if (projects->size() == 1) {
|
if (projects->size() == 1) {
|
||||||
@@ -135,67 +145,6 @@ namespace IfcGeom {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct filter
|
|
||||||
{
|
|
||||||
/// Should the product be included (true) or excluded (false).
|
|
||||||
bool include;
|
|
||||||
/// If traversal requested, traverse to the parents to see if they satisfy the criteria. E.g. we might be looking for
|
|
||||||
/// children of a storey named "Level 20", or children of entities that have no representation, e.g. IfcCurtainWall.
|
|
||||||
bool traverse;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct wildcard_filter : public filter
|
|
||||||
{
|
|
||||||
std::set<boost::regex> values;
|
|
||||||
|
|
||||||
void populate(const std::set<std::string>& patterns)
|
|
||||||
{
|
|
||||||
values.clear();
|
|
||||||
foreach(const std::string &pattern, patterns) {
|
|
||||||
values.insert(wildcard_string_to_regex(pattern));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static boost::regex wildcard_string_to_regex(std::string str)
|
|
||||||
{
|
|
||||||
// Escape all non-"*?" regex special chars
|
|
||||||
std::string special_chars = "\\^.$|()[]+/";
|
|
||||||
foreach(char c, special_chars) {
|
|
||||||
std::string char_str(1, c);
|
|
||||||
boost::replace_all(str, char_str, "\\" + char_str);
|
|
||||||
}
|
|
||||||
// Convert "*?" to their regex equivalents
|
|
||||||
boost::replace_all(str, "?", ".");
|
|
||||||
boost::replace_all(str, "*", ".*");
|
|
||||||
return boost::regex(str);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
wildcard_filter name_filter_;
|
|
||||||
wildcard_filter guid_filter_;
|
|
||||||
wildcard_filter layer_filter_;
|
|
||||||
|
|
||||||
struct entity_filter : public filter
|
|
||||||
{
|
|
||||||
std::set<IfcSchema::Type::Enum> values;
|
|
||||||
|
|
||||||
void populate(const std::set<std::string>& types)
|
|
||||||
{
|
|
||||||
values.clear();
|
|
||||||
foreach(const std::string& type, types) {
|
|
||||||
IfcSchema::Type::Enum ty;
|
|
||||||
try {
|
|
||||||
ty = IfcSchema::Type::FromString(boost::to_upper_copy(type));
|
|
||||||
} catch (const IfcParse::IfcException&) {
|
|
||||||
throw IfcParse::IfcException("'" + type + "' does not name a valid IFC entity");
|
|
||||||
}
|
|
||||||
values.insert(ty);
|
|
||||||
// TODO: Add child classes so that containment in set can be in O(log n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
entity_filter entity_filter_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool initialize() {
|
bool initialize() {
|
||||||
try {
|
try {
|
||||||
@@ -358,37 +307,8 @@ namespace IfcGeom {
|
|||||||
|
|
||||||
IfcParse::IfcFile* getFile() const { return ifc_file; }
|
IfcParse::IfcFile* getFile() const { return ifc_file; }
|
||||||
|
|
||||||
/// @note Entity names are handled case-insensitively.
|
const std::vector<filter_t> &filters() const { return filters_; }
|
||||||
void filter_entities(bool include, const std::set<std::string>& entities, bool traverse)
|
std::vector<filter_t> &filters() { return filters_; }
|
||||||
{
|
|
||||||
entity_filter_.populate(entities);
|
|
||||||
entity_filter_.include = include;
|
|
||||||
entity_filter_.traverse = traverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @note Arbitrary names or wildcard expressions are handled case-sensitively.
|
|
||||||
void filter_entity_names(bool include, const std::set<std::string>& names, bool traverse)
|
|
||||||
{
|
|
||||||
name_filter_.populate(names);
|
|
||||||
name_filter_.include = include;
|
|
||||||
name_filter_.traverse = traverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @note GUIDs (wildcard expressions allowed) are handled case-sensitively.
|
|
||||||
void filter_entity_guids(bool include, const std::set<std::string>& guids, bool traverse)
|
|
||||||
{
|
|
||||||
guid_filter_.populate(guids);
|
|
||||||
guid_filter_.include = include;
|
|
||||||
guid_filter_.traverse = traverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @note Arbitrary names or wildcard expressions are handled case-sensitively.
|
|
||||||
void filter_layer_names(bool include, const std::set<std::string>& names, bool traverse)
|
|
||||||
{
|
|
||||||
layer_filter_.populate(names);
|
|
||||||
layer_filter_.include = include;
|
|
||||||
layer_filter_.traverse = traverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
const gp_XYZ& bounds_min() const { return bounds_min_; }
|
const gp_XYZ& bounds_min() const { return bounds_min_; }
|
||||||
const gp_XYZ& bounds_max() const { return bounds_max_; }
|
const gp_XYZ& bounds_max() const { return bounds_max_; }
|
||||||
@@ -410,17 +330,14 @@ namespace IfcGeom {
|
|||||||
|
|
||||||
std::set<IfcSchema::IfcRepresentation*> mapped_representations_processed;
|
std::set<IfcSchema::IfcRepresentation*> mapped_representations_processed;
|
||||||
|
|
||||||
struct shape_model { BRepElement<P>* element; IfcSchema::IfcProduct* product; };
|
BRepElement<P>* create_shape_model_for_next_entity() {
|
||||||
|
|
||||||
shape_model create_shape_model_for_next_entity() {
|
|
||||||
shape_model ret = {0};
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
IfcSchema::IfcRepresentation* representation;
|
IfcSchema::IfcRepresentation* representation;
|
||||||
|
|
||||||
// Have we reached the end of our list of representations?
|
// Have we reached the end of our list of representations?
|
||||||
if ( representation_iterator == representations->end() ) {
|
if ( representation_iterator == representations->end() ) {
|
||||||
representations.reset();
|
representations.reset();
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
representation = *representation_iterator;
|
representation = *representation_iterator;
|
||||||
|
|
||||||
@@ -565,124 +482,7 @@ namespace IfcGeom {
|
|||||||
// Filter the products based on the set of entities and/or names being included or excluded for processing.
|
// Filter the products based on the set of entities and/or names being included or excluded for processing.
|
||||||
for (IfcSchema::IfcProduct::list::it jt = unfiltered_products->begin(); jt != unfiltered_products->end(); ++jt) {
|
for (IfcSchema::IfcProduct::list::it jt = unfiltered_products->begin(); jt != unfiltered_products->end(); ++jt) {
|
||||||
IfcSchema::IfcProduct* prod = *jt;
|
IfcSchema::IfcProduct* prod = *jt;
|
||||||
/// @todo Horrible copy-pasta, refactor.
|
if (boost::all(filters_, filter_match(prod))) {
|
||||||
bool type_found = false;
|
|
||||||
if (!entity_filter_.values.empty()) {
|
|
||||||
// The set is iterated over to able to filter on subtypes.
|
|
||||||
foreach(IfcSchema::Type::Enum type, entity_filter_.values) {
|
|
||||||
if (prod->is(type)) {
|
|
||||||
type_found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type_found != entity_filter_.include && entity_filter_.traverse) {
|
|
||||||
foreach(IfcSchema::Type::Enum type, entity_filter_.values) {
|
|
||||||
IfcSchema::IfcProduct* parent, *current = prod;
|
|
||||||
while ((parent = static_cast<IfcSchema::IfcProduct*>(kernel.get_decomposing_entity(current))) != 0) {
|
|
||||||
if (parent->is(type)) {
|
|
||||||
type_found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
current = parent;
|
|
||||||
}
|
|
||||||
if (type_found) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool name_found = false;
|
|
||||||
if (!name_filter_.values.empty()) {
|
|
||||||
foreach(const boost::regex& r, name_filter_.values) {
|
|
||||||
if (prod->hasName() && boost::regex_match(prod->Name(), r)) {
|
|
||||||
name_found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name_found != name_filter_.include && name_filter_.traverse) {
|
|
||||||
foreach(const boost::regex& r, name_filter_.values) {
|
|
||||||
IfcSchema::IfcProduct* parent, *current = prod;
|
|
||||||
while ((parent = static_cast<IfcSchema::IfcProduct*>(kernel.get_decomposing_entity(current))) != 0) {
|
|
||||||
if (parent->hasName() && boost::regex_match(parent->Name(), r)) {
|
|
||||||
name_found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
current = parent;
|
|
||||||
}
|
|
||||||
if (name_found) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool guid_found = false;
|
|
||||||
if (!guid_filter_.values.empty()) {
|
|
||||||
foreach(const boost::regex& r, guid_filter_.values) {
|
|
||||||
if (boost::regex_match(prod->GlobalId(), r)) {
|
|
||||||
std::cout << prod->GlobalId() << std::endl;
|
|
||||||
guid_found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (guid_found != guid_filter_.include && guid_filter_.traverse) {
|
|
||||||
foreach(const boost::regex& r, guid_filter_.values) {
|
|
||||||
IfcSchema::IfcProduct* parent, *current = prod;
|
|
||||||
while ((parent = static_cast<IfcSchema::IfcProduct*>(kernel.get_decomposing_entity(current))) != 0) {
|
|
||||||
if (boost::regex_match(parent->GlobalId(), r)) {
|
|
||||||
guid_found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
current = parent;
|
|
||||||
}
|
|
||||||
if (guid_found) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool layer_found = false;
|
|
||||||
if (!layer_filter_.values.empty()) {
|
|
||||||
std::map<std::string, IfcSchema::IfcPresentationLayerAssignment*> layers = IfcGeom::Kernel::get_layers(prod);
|
|
||||||
std::map<std::string, IfcSchema::IfcPresentationLayerAssignment*>::const_iterator lit;
|
|
||||||
foreach(const boost::regex& r, layer_filter_.values) {
|
|
||||||
for (lit = layers.begin(); lit != layers.end(); ++lit) {
|
|
||||||
if (boost::regex_match(lit->first, r)) {
|
|
||||||
layer_found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (layer_found) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (layer_found != layer_filter_.include && layer_filter_.traverse) {
|
|
||||||
foreach(const boost::regex& r, layer_filter_.values) {
|
|
||||||
for (lit = layers.begin(); lit != layers.end(); ++lit) {
|
|
||||||
IfcSchema::IfcProduct* parent, *current = prod;
|
|
||||||
while ((parent = static_cast<IfcSchema::IfcProduct*>(kernel.get_decomposing_entity(current))) != 0) {
|
|
||||||
if (boost::regex_match(lit->first, r)) {
|
|
||||||
layer_found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
current = parent;
|
|
||||||
}
|
|
||||||
if (layer_found) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type_found == entity_filter_.include && name_found == name_filter_.include &&
|
|
||||||
guid_found == guid_filter_.include && layer_found == layer_filter_.include) {
|
|
||||||
ifcproducts->push(prod);
|
ifcproducts->push(prod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -696,24 +496,25 @@ namespace IfcGeom {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.product = *ifcproduct_iterator;
|
IfcSchema::IfcProduct* product = *ifcproduct_iterator;
|
||||||
|
|
||||||
Logger::SetProduct(ret.product);
|
Logger::SetProduct(product);
|
||||||
|
|
||||||
|
BRepElement<P>* element;
|
||||||
if (ifcproduct_iterator == ifcproducts->begin() || !settings.get(IteratorSettings::USE_WORLD_COORDS)) {
|
if (ifcproduct_iterator == ifcproducts->begin() || !settings.get(IteratorSettings::USE_WORLD_COORDS)) {
|
||||||
ret.element = kernel.create_brep_for_representation_and_product<P>(settings, representation, ret.product);
|
element = kernel.create_brep_for_representation_and_product<P>(settings, representation, product);
|
||||||
} else {
|
} else {
|
||||||
ret.element = kernel.create_brep_for_processed_representation(settings, representation, ret.product, current_shape_model);
|
element = kernel.create_brep_for_processed_representation(settings, representation, product, current_shape_model);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::SetProduct(boost::none);
|
Logger::SetProduct(boost::none);
|
||||||
|
|
||||||
if (!ret.element) {
|
if (!element) {
|
||||||
_nextShape();
|
_nextShape();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -727,19 +528,22 @@ namespace IfcGeom {
|
|||||||
current_shape_model = 0;
|
current_shape_model = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// Returns what would be the product for the next shape representation
|
/// Returns what would be the product for the next shape representation
|
||||||
IfcSchema::IfcProduct* peek_next() const
|
/// @todo Double-check and test the impl.
|
||||||
{
|
//IfcSchema::IfcProduct* peek_next() const
|
||||||
if (ifcproducts && ifcproduct_iterator + 1 != ifcproducts->end()){
|
//{
|
||||||
return *(ifcproduct_iterator + 1);
|
// if (ifcproducts && ifcproduct_iterator + 1 != ifcproducts->end()){
|
||||||
} else {
|
// return *(ifcproduct_iterator + 1);
|
||||||
return 0;
|
// } else {
|
||||||
}
|
// return 0;
|
||||||
}
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
/// Moves to the next shape representation and returns the associated product.
|
/// @todo Would this be as simple as the following code?
|
||||||
|
//void skip_next() { if (ifcproducts) { ++ifcproduct_iterator; } }
|
||||||
|
|
||||||
|
/// Moves to the next shape representation, create its geometry, and returns the associated product.
|
||||||
/// Use get() to retrieve the created geometry.
|
/// Use get() to retrieve the created geometry.
|
||||||
IfcSchema::IfcProduct* next() {
|
IfcSchema::IfcProduct* next() {
|
||||||
// Increment the iterator over the list of products using the current
|
// Increment the iterator over the list of products using the current
|
||||||
@@ -805,7 +609,7 @@ namespace IfcGeom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IfcSchema::IfcProduct* create() {
|
IfcSchema::IfcProduct* create() {
|
||||||
shape_model next_shape_model = {0};
|
IfcGeom::BRepElement<P>* next_shape_model = 0;
|
||||||
IfcGeom::SerializedElement<P>* next_serialization = 0;
|
IfcGeom::SerializedElement<P>* next_serialization = 0;
|
||||||
IfcGeom::TriangulationElement<P>* next_triangulation = 0;
|
IfcGeom::TriangulationElement<P>* next_triangulation = 0;
|
||||||
|
|
||||||
@@ -813,19 +617,19 @@ namespace IfcGeom {
|
|||||||
next_shape_model = create_shape_model_for_next_entity();
|
next_shape_model = create_shape_model_for_next_entity();
|
||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
|
|
||||||
if (next_shape_model.element) {
|
if (next_shape_model) {
|
||||||
if (settings.get(IteratorSettings::USE_BREP_DATA)) {
|
if (settings.get(IteratorSettings::USE_BREP_DATA)) {
|
||||||
try {
|
try {
|
||||||
next_serialization = new SerializedElement<P>(*next_shape_model.element);
|
next_serialization = new SerializedElement<P>(*next_shape_model);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
Logger::Message(Logger::LOG_ERROR, "Getting a serialized element from model failed.");
|
Logger::Message(Logger::LOG_ERROR, "Getting a serialized element from model failed.");
|
||||||
}
|
}
|
||||||
} else if (!settings.get(IteratorSettings::DISABLE_TRIANGULATION)) {
|
} else if (!settings.get(IteratorSettings::DISABLE_TRIANGULATION)) {
|
||||||
try {
|
try {
|
||||||
if (ifcproduct_iterator == ifcproducts->begin() || settings.get(IteratorSettings::USE_WORLD_COORDS)) {
|
if (ifcproduct_iterator == ifcproducts->begin() || settings.get(IteratorSettings::USE_WORLD_COORDS)) {
|
||||||
next_triangulation = new TriangulationElement<P>(*next_shape_model.element);
|
next_triangulation = new TriangulationElement<P>(*next_shape_model);
|
||||||
} else {
|
} else {
|
||||||
next_triangulation = new TriangulationElement<P>(*next_shape_model.element, current_triangulation->geometry_pointer());
|
next_triangulation = new TriangulationElement<P>(*next_shape_model, current_triangulation->geometry_pointer());
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
Logger::Message(Logger::LOG_ERROR, "Getting a triangulation element from model failed.");
|
Logger::Message(Logger::LOG_ERROR, "Getting a triangulation element from model failed.");
|
||||||
@@ -835,11 +639,11 @@ namespace IfcGeom {
|
|||||||
|
|
||||||
free_shapes();
|
free_shapes();
|
||||||
|
|
||||||
current_shape_model = next_shape_model.element;
|
current_shape_model = next_shape_model;
|
||||||
current_serialization = next_serialization;
|
current_serialization = next_serialization;
|
||||||
current_triangulation = next_triangulation;
|
current_triangulation = next_triangulation;
|
||||||
|
|
||||||
return next_shape_model.product;
|
return next_shape_model ? next_shape_model->product() : 0;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
void _initialize() {
|
void _initialize() {
|
||||||
@@ -847,13 +651,6 @@ namespace IfcGeom {
|
|||||||
current_shape_model = 0;
|
current_shape_model = 0;
|
||||||
current_serialization = 0;
|
current_serialization = 0;
|
||||||
|
|
||||||
// Upon initialisation, the (empty) set of entity names,
|
|
||||||
// should be excluded, or no products would be processed.
|
|
||||||
entity_filter_.include = false;
|
|
||||||
name_filter_.include = false;
|
|
||||||
guid_filter_.include = false;
|
|
||||||
layer_filter_.include = false;
|
|
||||||
|
|
||||||
unit_name = "METER";
|
unit_name = "METER";
|
||||||
unit_magnitude = 1.f;
|
unit_magnitude = 1.f;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user