Work on serializers

This commit is contained in:
Thomas Krijnen
2017-12-20 12:40:15 +01:00
parent 830a03ffcd
commit d46dfb6061
9 changed files with 146 additions and 129 deletions
+13 -24
View File
@@ -32,8 +32,6 @@
#include <string>
#include <cmath>
using namespace IfcSchema;
static std::string& collada_id(std::string& s)
{
IfcUtil::sanitate_material_name(s);
@@ -431,31 +429,22 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme
}
std::string ColladaSerializer::ColladaExporter::differentiateSlabTypes(const IfcGeom::TriangulationElement<real_t>* o) {
IfcSlab* slab = (IfcSlab*)o->product();
std::string result;
switch (slab->PredefinedType())
{
case (IfcSlabTypeEnum::IfcSlabType_FLOOR):
result = "_Floor";
break;
case (IfcSlabTypeEnum::IfcSlabType_ROOF):
result = "_Roof";
break;
case (IfcSlabTypeEnum::IfcSlabType_LANDING):
result = "_Landing";
break;
case (IfcSlabTypeEnum::IfcSlabType_BASESLAB):
result = "_BaseSlab";
break;
case (IfcSlabTypeEnum::IfcSlabType_NOTDEFINED):
result = "_NotDefined";
break;
default:
if (slab->hasObjectType()) { result = "_" + slab->ObjectType(); }
else { result = "_Unknown"; }
break;
if (!o->product()->get("ObjectType")->isNull()) {
const std::string object_type = *o->product()->get("ObjectType");
result = "_" + object_type;
} else {
result = "_Unknown";
}
const std::string slabtype = *o->product()->get("PredefinedType");
if (slabtype != "NOTDEFINED" && slabtype != "USERDEFINED") {
result = "_" + slabtype;
}
collada_id(result);
return result;
}
+66 -50
View File
@@ -56,7 +56,7 @@ namespace po = boost::program_options;
void print_version()
{
std::cout << "IfcOpenShell " << IfcSchema::Identifier << " IfcConvert " << IFCOPENSHELL_VERSION << " (OCC " << OCC_VERSION_STRING_EXT << ")\n";
std::cout << "IfcOpenShell " << " IfcConvert " << IFCOPENSHELL_VERSION << " (OCC " << OCC_VERSION_STRING_EXT << ")\n";
}
void print_usage(bool suggest_help = true)
@@ -116,6 +116,7 @@ static std::stringstream log_stream;
void write_log();
/// @todo make the filters non-global
/*
IfcGeom::entity_filter entity_filter; // Entity filter is used always by default.
IfcGeom::layer_filter layer_filter;
const std::string NAME_ARG = "Name", GUID_ARG = "GlobalId", DESC_ARG = "Description", TAG_ARG = "Tag";
@@ -147,6 +148,7 @@ struct exclusion_traverse_filter : public geom_filter { exclusion_traverse_filte
size_t read_filters_from_file(const std::string&, inclusion_filter&, inclusion_traverse_filter&, exclusion_filter&, exclusion_traverse_filter&);
void parse_filter(geom_filter &, const std::vector<std::string>&);
std::vector<IfcGeom::filter_t> setup_filters(const std::vector<geom_filter>&, const std::string&);
*/
bool init_input_file(const std::string& filename, IfcParse::IfcFile& ifc_file, bool no_progress, bool mmap);
@@ -170,11 +172,13 @@ int main(int argc, char** argv)
double deflection_tolerance;
inclusion_filter include_filter;
/*
inclusion_filter include_filter;
inclusion_traverse_filter include_traverse_filter;
exclusion_filter exclude_filter;
exclusion_traverse_filter exclude_traverse_filter;
std::string filter_filename;
*/
po::options_description geom_options("Geometry options");
geom_options.add_options()
@@ -190,7 +194,7 @@ int main(int argc, char** argv)
"vector will only contain unique xyz-triplets. This results in a "
"manifold mesh which is useful for modelling applications, but might "
"result in unwanted shading artefacts in rendering applications.")
("use-world-coords",
("use-world-coords",
"Specifies whether to apply the local placements of building elements "
"directly to the coordinates of the representation mesh rather than "
"to represent the local placement in the 4x3 matrix, which will in that "
@@ -199,7 +203,7 @@ int main(int argc, char** argv)
"Specifies whether to convert back geometrical output back to the "
"unit of measure in which it is defined in the IFC file. Default is "
"to use meters.")
("sew-shells",
("sew-shells",
"Specifies whether to sew the faces of IfcConnectedFaceSets together. "
"This is a potentially time consuming operation, but guarantees a "
"consistent orientation of surface normals, even if the faces are not "
@@ -209,53 +213,56 @@ int main(int argc, char** argv)
// arguments where not introduced yet and a work-around was implemented to
// subtract multiple openings as a single compound. This hack is obsolete
// for newer versions of Open CASCADE.
("merge-boolean-operands",
("merge-boolean-operands",
"Specifies whether to merge all IfcOpeningElement operands into a single "
"operand before applying the subtraction operation. This may "
"introduce a performance improvement at the risk of failing, in "
"which case the subtraction is applied one-by-one.")
#endif
("disable-opening-subtractions",
("disable-opening-subtractions",
"Specifies whether to disable the boolean subtraction of "
"IfcOpeningElement Representations from their RelatingElements.")
("enable-layerset-slicing",
("enable-layerset-slicing",
"Specifies whether to enable the slicing of products according "
"to their associated IfcMaterialLayerSet.")
("include", po::value<inclusion_filter>(&include_filter)->multitoken(),
"Specifies that the entities that match a specific filtering criteria are to be included in the geometrical output:\n"
"1) 'entities': the following list of types should be included. SVG output defaults "
"to IfcSpace to be included. The entity names are handled case-insensitively.\n"
"2) 'layers': the entities that are assigned to presentation layers of which names "
"match the given values should be included.\n"
"3) 'arg <ArgumentName>': the following list of values for that specific argument should be included. "
"Currently supported arguments are GlobalId, Name, Description, and Tag.\n\n"
"The values for 'layers' and 'arg' are handled case-sensitively (wildcards supported)."
"--include and --exclude cannot be placed right before input file argument and "
"only single of each argument supported for now. See also --exclude.")
("include+", po::value<inclusion_traverse_filter>(&include_traverse_filter)->multitoken(),
"Same as --include but applies filtering also to the decomposition and/or containment (IsDecomposedBy, "
"HasOpenings, FillsVoid, ContainedInStructure) of the filtered entity, e.g. --include+=arg Name \"Level 1\" "
"includes entity with name \"Level 1\" and all of its children. See --include for more information. ")
("exclude", po::value<exclusion_filter>(&exclude_filter)->multitoken(),
"Specifies that the entities that match a specific filtering criteria are to be excluded in the geometrical output."
"See --include for syntax and more details. The default value is '--exclude=entities IfcOpeningElement IfcSpace'.")
("exclude+", po::value<exclusion_traverse_filter>(&exclude_traverse_filter)->multitoken(),
"Same as --exclude but applies filtering also to the decomposition and/or containment "
"of the filtered entity. See --include+ for more details.")
("no-normals",
"Disables computation of normals. Saves time and file size and is useful "
"in instances where you're going to recompute normals for the exported "
"model in other modelling application in any case.")
("deflection-tolerance", po::value<double>(&deflection_tolerance)->default_value(1e-3),
"Sets the deflection tolerance of the mesher, 1e-3 by default if not specified.")
("generate-uvs",
"Generates UVs (texture coordinates) by using simple box projection. Requires normals. "
"Not guaranteed to work properly if used with --weld-vertices.")
("filter-file", po::value<std::string>(&filter_filename),
"Specifies a filter file that describes the used filtering criteria. Supported formats "
"are '--include=arg GlobalId ...' and 'include arg GlobalId ...'. Spaces and tabs can be used as delimeters."
"Multiple filters of same type with different values can be inserted on their own lines. "
"See --include, --include+, --exclude, and --exclude+ for more details.");
/*
("include", po::value<inclusion_filter>(&include_filter)->multitoken(),
"Specifies that the entities that match a specific filtering criteria are to be included in the geometrical output:\n"
"1) 'entities': the following list of types should be included. SVG output defaults "
"to IfcSpace to be included. The entity names are handled case-insensitively.\n"
"2) 'layers': the entities that are assigned to presentation layers of which names "
"match the given values should be included.\n"
"3) 'arg <ArgumentName>': the following list of values for that specific argument should be included. "
"Currently supported arguments are GlobalId, Name, Description, and Tag.\n\n"
"The values for 'layers' and 'arg' are handled case-sensitively (wildcards supported)."
"--include and --exclude cannot be placed right before input file argument and "
"only single of each argument supported for now. See also --exclude.")
("include+", po::value<inclusion_traverse_filter>(&include_traverse_filter)->multitoken(),
"Same as --include but applies filtering also to the decomposition and/or containment (IsDecomposedBy, "
"HasOpenings, FillsVoid, ContainedInStructure) of the filtered entity, e.g. --include+=arg Name \"Level 1\" "
"includes entity with name \"Level 1\" and all of its children. See --include for more information. ")
("exclude", po::value<exclusion_filter>(&exclude_filter)->multitoken(),
"Specifies that the entities that match a specific filtering criteria are to be excluded in the geometrical output."
"See --include for syntax and more details. The default value is '--exclude=entities IfcOpeningElement IfcSpace'.")
("exclude+", po::value<exclusion_traverse_filter>(&exclude_traverse_filter)->multitoken(),
"Same as --exclude but applies filtering also to the decomposition and/or containment "
"of the filtered entity. See --include+ for more details.")
("filter-file", po::value<std::string>(&filter_filename),
"Specifies a filter file that describes the used filtering criteria. Supported formats "
"are '--include=arg GlobalId ...' and 'include arg GlobalId ...'. Spaces and tabs can be used as delimeters."
"Multiple filters of same type with different values can be inserted on their own lines. "
"See --include, --include+, --exclude, and --exclude+ for more details.");
*/
("no-normals",
"Disables computation of normals. Saves time and file size and is useful "
"in instances where you're going to recompute normals for the exported "
"model in other modelling application in any case.")
("deflection-tolerance", po::value<double>(&deflection_tolerance)->default_value(1e-3),
"Sets the deflection tolerance of the mesher, 1e-3 by default if not specified.")
("generate-uvs",
"Generates UVs (texture coordinates) by using simple box projection. Requires normals. "
"Not guaranteed to work properly if used with --weld-vertices.");
std::string bounds, offset_str;
#ifdef HAVE_ICU
@@ -456,6 +463,7 @@ int main(int argc, char** argv)
return exit_code;
}
/*
if (!filter_filename.empty()) {
size_t num_filters = read_filters_from_file(filter_filename, include_filter, include_traverse_filter, exclude_filter, exclude_traverse_filter);
if (num_filters) {
@@ -465,7 +473,7 @@ int main(int argc, char** argv)
return EXIT_FAILURE;
}
}
/// @todo Clean up this filter code further.
std::vector<geom_filter> used_filters;
if (include_filter.type != geom_filter::UNUSED) { used_filters.push_back(include_filter); }
@@ -485,6 +493,7 @@ int main(int argc, char** argv)
if (!name_filter.values.empty()) { name_filter.update_description(); Logger::Notice(name_filter.description); }
if (!desc_filter.values.empty()) { desc_filter.update_description(); Logger::Notice(desc_filter.description); }
if (!tag_filter.values.empty()) { tag_filter.update_description(); Logger::Notice(tag_filter.description); }
*/
SerializerSettings settings;
/// @todo Make APPLY_DEFAULT_MATERIALS configurable? Quickly tested setting this to false and using obj exporter caused the program to crash and burn.
@@ -588,7 +597,7 @@ int main(int argc, char** argv)
return EXIT_FAILURE;
}
IfcGeom::Iterator<real_t> context_iterator(settings, &ifc_file, filter_funcs);
IfcGeom::Iterator<real_t> context_iterator(settings, &ifc_file);
if (!context_iterator.initialize()) {
/// @todo It would be nice to know and print separate error prints for a case where we found no entities
/// and for a case we found no entities that satisfy our filtering criteria.
@@ -599,10 +608,10 @@ int main(int argc, char** argv)
return EXIT_FAILURE;
}
serializer->setFile(context_iterator.getFile());
serializer->setFile(context_iterator.file());
if (convert_back_units) {
serializer->setUnitNameAndMagnitude(context_iterator.getUnitName(), static_cast<float>(context_iterator.getUnitMagnitude()));
serializer->setUnitNameAndMagnitude(context_iterator.unit_name(), static_cast<float>(context_iterator.unit_magnitude()));
} else {
serializer->setUnitNameAndMagnitude("METER", 1.0f);
}
@@ -619,10 +628,13 @@ int main(int argc, char** argv)
delete serializer;
return EXIT_FAILURE;
}
throw std::runtime_error("needs more work");
/*
gp_XYZ center = (context_iterator.bounds_min() + context_iterator.bounds_max()) * 0.5;
offset[0] = -center.X();
offset[1] = -center.Y();
offset[2] = -center.Z();
*/
} else {
if (sscanf(offset_str.c_str(), "%lf;%lf;%lf", &offset[0], &offset[1], &offset[2]) != 3) {
std::cerr << "[Error] Invalid use of --model-offset\n";
@@ -716,16 +728,17 @@ void write_log() {
}
}
bool init_input_file(const std::string &filename, IfcParse::IfcFile &ifc_file, bool no_progress, bool mmap)
{
bool init_input_file(const std::string& filename, IfcParse::IfcFile* ifc_file, bool no_progress, bool mmap) {
// Prevent IfcFile::Init() prints by setting output to null temporarily
if (no_progress) { Logger::SetOutput(NULL, &log_stream); }
#ifdef USE_MMAP
if (!ifc_file.Init(filename, mmap)) {
ifc_file = new IfcParse::IfcFile(filename, mmap);
#else
(void)mmap;
if (!ifc_file.Init(filename)) {
ifc_file = new IfcParse::IfcFile(filename);
if (!ifc_file->good()) {
#endif
Logger::Error("Unable to parse input file '" + filename + "'");
return false;
@@ -734,8 +747,10 @@ bool init_input_file(const std::string &filename, IfcParse::IfcFile &ifc_file, b
if (no_progress) { Logger::SetOutput(&std::cout, &log_stream); }
return true;
}
/*
bool append_filter(const std::string& type, const std::vector<std::string>& values, geom_filter& filter)
{
geom_filter temp;
@@ -928,3 +943,4 @@ std::vector<IfcGeom::filter_t> setup_filters(const std::vector<geom_filter>& fil
return filter_funcs;
}
*/
+8 -14
View File
@@ -22,6 +22,7 @@
#include <cstdio>
#include <Standard_Version.hxx>
#include <BRepBuilderAPI_Transform.hxx>
#include "OpenCascadeBasedSerializer.h"
@@ -34,23 +35,16 @@ bool OpenCascadeBasedSerializer::ready() {
}
void OpenCascadeBasedSerializer::write(const IfcGeom::BRepElement<real_t>* o) {
for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = o->geometry().begin(); it != o->geometry().end(); ++ it) {
gp_GTrsf gtrsf = it->Placement();
TopoDS_Shape compound = o->geometry().as_compound();
const gp_Trsf& o_trsf = o->transformation().data();
gtrsf.PreMultiply(o_trsf);
if (o->geometry().settings().get(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS)) {
gp_Trsf scale;
scale.SetScaleFactor(1.0 / o->geometry().settings().unit_magnitude());
gtrsf.PreMultiply(scale);
}
if (o->geometry().settings().get(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS)) {
gp_Trsf scale;
scale.SetScaleFactor(1.0 / o->geometry().settings().unit_magnitude());
const TopoDS_Shape& s = it->Shape();
const TopoDS_Shape moved_shape = IfcGeom::Kernel::apply_transformation(s, gtrsf);
writeShape(moved_shape);
compound = BRepBuilderAPI_Transform(compound, scale, true).Shape();
}
writeShape(compound);
}
#define RATHER_SMALL (1e-3)
+39 -22
View File
@@ -50,6 +50,7 @@
#include <gp_Ax22d.hxx>
#include <Standard_Version.hxx>
#include <GeomAPI.hxx>
#include <TopoDS_Wire.hxx>
#include "../ifcparse/IfcGlobalId.h"
@@ -103,7 +104,9 @@ void SvgSerializer::write(path_object& p, const TopoDS_Wire& wire) {
Handle(Standard_Type) ty = curve->DynamicType();
bool conical = (ty == STANDARD_TYPE(Geom_Circle) || ty == STANDARD_TYPE(Geom_Ellipse));
bool closed = ALMOST_THE_SAME(u1 + PI2, u2);
// TODO: ALMOST_THE_SAME utilities in separate header
bool closed = fabs((u1 + PI2) - u2) < 1.e-9;
if (conical && closed) {
if (first) {
@@ -274,7 +277,7 @@ void SvgSerializer::write(path_object& p, const TopoDS_Wire& wire) {
p.second.push_back(path);
}
SvgSerializer::path_object& SvgSerializer::start_path(IfcSchema::IfcBuildingStorey* storey, const std::string& id) {
SvgSerializer::path_object& SvgSerializer::start_path(IfcUtil::IfcBaseEntity* storey, const std::string& id) {
SvgSerializer::path_object& p = paths.insert(std::make_pair(storey, path_object()))->second;
p.first = id;
return p;
@@ -282,8 +285,13 @@ SvgSerializer::path_object& SvgSerializer::start_path(IfcSchema::IfcBuildingStor
void SvgSerializer::write(const IfcGeom::BRepElement<real_t>* o)
{
IfcSchema::IfcBuildingStorey* storey = storey_;
IfcUtil::IfcBaseEntity* storey = storey_;
boost::optional<double> storey_elevation = boost::none;
/*
TODO: based on BRepElement::parent()
IfcSchema::IfcObjectDefinition* obdef = static_cast<IfcSchema::IfcObjectDefinition*>(file->entityById(o->id()));
#ifndef USE_IFC4
@@ -327,25 +335,25 @@ void SvgSerializer::write(const IfcGeom::BRepElement<real_t>* o)
break;
}
}
*/
// With a global section height, building storeys are not a requirement.
if (!storey && !section_height) return;
path_object& p = start_path(storey, nameElement(o));
for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = o->geometry().begin(); it != o->geometry().end(); ++ it) {
gp_GTrsf gtrsf = it->Placement();
const gp_Trsf& o_trsf = o->transformation().data();
gtrsf.PreMultiply(o_trsf);
TopoDS_Shape compound = o->geometry().as_compound();
TopoDS_Iterator it(compound);
// Iterate over components of compound to have better chance of matching section edges to closed wires
for (; it.More(); it.Next()) {
const TopoDS_Shape& subshape = it.Value();
const TopoDS_Shape& s = it->Shape();
const TopoDS_Shape moved_shape = IfcGeom::Kernel::apply_transformation(s, gtrsf);
const double inf = std::numeric_limits<double>::infinity();
double zmin = inf;
double zmax = -inf;
{TopExp_Explorer exp(moved_shape, TopAbs_VERTEX);
{TopExp_Explorer exp(subshape, TopAbs_VERTEX);
for (; exp.More(); exp.Next()) {
const TopoDS_Vertex& vertex = TopoDS::Vertex(exp.Current());
gp_Pnt pnt = BRep_Tool::Pnt(vertex);
@@ -373,13 +381,13 @@ void SvgSerializer::write(const IfcGeom::BRepElement<real_t>* o)
}
// Create a horizontal cross section 1 meter above the bottom point of the shape
TopoDS_Shape result = BRepAlgoAPI_Section(moved_shape, gp_Pln(gp_Pnt(0, 0, cut_z), gp::DZ()));
TopoDS_Shape result = BRepAlgoAPI_Section(subshape, gp_Pln(gp_Pnt(0, 0, cut_z), gp::DZ()));
Handle(TopTools_HSequenceOfShape) edges = new TopTools_HSequenceOfShape();
Handle(TopTools_HSequenceOfShape) wires = new TopTools_HSequenceOfShape();
{TopExp_Explorer exp(result, TopAbs_EDGE);
for (; exp.More(); exp.Next()) {
edges->Append(exp.Current());
edges->Append(exp.Current());
}}
ShapeAnalysis_FreeBounds::ConnectEdgesToWires(edges, 1e-5, false, wires);
@@ -389,7 +397,7 @@ void SvgSerializer::write(const IfcGeom::BRepElement<real_t>* o)
const TopoDS_Wire& wire = TopoDS::Wire(wires->Value(i));
write(p, wire);
}
}
}
}
void SvgSerializer::setBoundingRectangle(double width, double height) {
@@ -430,9 +438,9 @@ void SvgSerializer::finalize() {
}}
}
std::multimap<IfcSchema::IfcBuildingStorey*, path_object>::const_iterator it;
std::multimap<IfcUtil::IfcBaseEntity*, path_object>::const_iterator it;
IfcSchema::IfcBuildingStorey* previous = 0;
IfcUtil::IfcBaseEntity* previous = 0;
bool first = true;
for (it = paths.begin(); it != paths.end(); ++it) {
if (it->first != previous || first) {
@@ -473,19 +481,27 @@ std::string SvgSerializer::nameElement(const IfcGeom::Element<real_t>* elem)
return oss.str();
}
std::string SvgSerializer::nameElement(const IfcSchema::IfcProduct* elem) {
std::string SvgSerializer::nameElement(const IfcUtil::IfcBaseEntity* elem) {
if (elem == 0) { return ""; }
std::ostringstream oss;
const std::string type = elem->declaration().is(IfcSchema::Type::IfcBuildingStorey) ? "storey" : "product";
const std::string name = (settings().get(SerializerSettings::USE_ELEMENT_GUIDS)
? elem->GlobalId() : (settings().get(SerializerSettings::USE_ELEMENT_NAMES)
? elem->Name() : IfcParse::IfcGlobalId(elem->GlobalId()).formatted()));
const std::string type = elem->declaration().is("IfcBuildingStorey") ? "storey" : "product";
const std::string name =
(settings().get(SerializerSettings::USE_ELEMENT_GUIDS)
? static_cast<std::string>(*elem->get("GlobalId"))
: ((settings().get(SerializerSettings::USE_ELEMENT_NAMES) && !elem->get("Name")->isNull()))
? static_cast<std::string>(*elem->get("Name"))
: IfcParse::IfcGlobalId(*elem->get("GlobalId")).formatted());
oss << "id=\"" << type << "-" << name << "\"";
return oss.str();
}
void SvgSerializer::setFile(IfcParse::IfcFile* f) {
throw std::runtime_error("todo");
/*
file = f;
IfcSchema::IfcBuildingStorey::list::ptr storeys = f->entitiesByType<IfcSchema::IfcBuildingStorey>();
if (!storeys || storeys->size() == 0) {
@@ -526,4 +542,5 @@ void SvgSerializer::setFile(IfcParse::IfcFile* f) {
Logger::Error("No building storeys encountered, output might be invalid or missing");
}
*/
}
+5 -5
View File
@@ -37,12 +37,12 @@ protected:
double xmin, ymin, xmax, ymax, width, height;
boost::optional<double> section_height;
bool rescale;
std::multimap<IfcSchema::IfcBuildingStorey*, path_object> paths;
std::multimap<IfcUtil::IfcBaseEntity*, path_object> paths;
std::vector< boost::shared_ptr<util::string_buffer::float_item> > xcoords;
std::vector< boost::shared_ptr<util::string_buffer::float_item> > ycoords;
std::vector< boost::shared_ptr<util::string_buffer::float_item> > radii;
IfcParse::IfcFile* file;
IfcSchema::IfcBuildingStorey* storey_;
IfcUtil::IfcBaseEntity* storey_;
public:
SvgSerializer(const std::string& out_filename, const SerializerSettings& settings)
: GeometrySerializer(settings)
@@ -64,15 +64,15 @@ public:
void write(const IfcGeom::TriangulationElement<real_t>* /*o*/) {}
void write(const IfcGeom::BRepElement<real_t>* o);
void write(path_object& p, const TopoDS_Wire& wire);
path_object& start_path(IfcSchema::IfcBuildingStorey* storey, const std::string& id);
path_object& start_path(IfcUtil::IfcBaseEntity* storey, const std::string& id);
bool isTesselated() const { return false; }
void finalize();
void setUnitNameAndMagnitude(const std::string& /*name*/, float /*magnitude*/) {}
void setFile(IfcParse::IfcFile* f);
void setBoundingRectangle(double width, double height);
void setSectionHeight(double h, IfcSchema::IfcBuildingStorey* storey = 0) { section_height = h; storey_ = storey; }
void setSectionHeight(double h, IfcUtil::IfcBaseEntity* storey = 0) { section_height = h; storey_ = storey; }
std::string nameElement(const IfcGeom::Element<real_t>* elem);
std::string nameElement(const IfcSchema::IfcProduct* elem);
std::string nameElement(const IfcUtil::IfcBaseEntity* elem);
};
#endif
+3 -2
View File
@@ -28,10 +28,11 @@
#include <algorithm>
#include "../ifcparse/IfcSIPrefix.h"
#include "../ifcgeom/IfcGeom.h"
// #include "../ifcgeom/IfcGeom.h"
using boost::property_tree::ptree;
using namespace IfcSchema;
// using namespace IfcSchema;
namespace {
+7 -7
View File
@@ -90,7 +90,7 @@ namespace IfcGeom {
std::string _context;
std::string _unique_id;
Transformation<P> _transformation;
IfcUtil::IfcBaseClass* product_;
IfcUtil::IfcBaseEntity* product_;
std::vector<const IfcGeom::Element<P>*> _parents;
public:
@@ -101,9 +101,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<P> & element1, const Element<P> & element2) {
if (element1.type() == "IfcBuildingStorey" && element2.type() == "IfcBuildingStorey") {
size_t attr_index = product_->declaration().as_entity->attribute_index("Elevation");
Argument* elev_attr1 = storey1->data().getArgument(attr_index);
Argument* elev_attr2 = storey2->data().getArgument(attr_index);
size_t attr_index = element1.product()->declaration().attribute_index("Elevation");
Argument* elev_attr1 = element1.product()->data().getArgument(attr_index);
Argument* elev_attr2 = element2.product()->data().getArgument(attr_index);
if (!elev_attr1->isNull() && !elev_attr2->isNull()) {
double elev1 = *elev_attr1;
@@ -124,12 +124,12 @@ namespace IfcGeom {
const std::string& context() const { return _context; }
const std::string& unique_id() const { return _unique_id; }
const Transformation<P>& transformation() const { return _transformation; }
IfcUtil::IfcBaseClass* product() const { return product_; }
IfcUtil::IfcBaseEntity* product() const { return product_; }
const std::vector<const IfcGeom::Element<P>*> parents() const { return _parents; }
void SetParents(std::vector<const IfcGeom::Element<P>*> newparents) { _parents = newparents; }
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, IfcUtil::IfcBaseClass* product)
const std::string& guid, const std::string& context, const gp_Trsf& trsf, IfcUtil::IfcBaseEntity* product)
: _id(id), _parent_id(parent_id), _name(name), _type(type), _guid(guid), _context(context), _transformation(settings, trsf)
, product_(product)
{
@@ -167,7 +167,7 @@ namespace IfcGeom {
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,
IfcUtil::IfcBaseClass* product)
IfcUtil::IfcBaseEntity* product)
: Element<P>(geometry->settings() ,id, parent_id, name, type, guid, context, trsf, product)
, _geometry(geometry)
{}
+1 -1
View File
@@ -72,7 +72,7 @@ namespace IfcUtil {
virtual const IfcParse::entity& declaration() const = 0;
Argument* getArgumentByName(const std::string& name) const;
Argument* get(const std::string& name) const;
};
// TODO: Investigate whether these should be template classes instead
+4 -4
View File
@@ -78,14 +78,14 @@ namespace IfcGeom {
IfcParse::IfcFile* file_;
IfcGeom::IteratorSettings settings_;
IteratorImplementation* implementation_;
IteratorImplementation<P>* implementation_;
public:
Iterator(const IfcGeom::IteratorSettings& settings, IfcParse::IfcFile* file)
: file_(file)
, settings_(settings)
{
implementation_ = iterator_implementations().construct(file_->schema()->name());
implementation_ = iterator_implementations<P>().construct(file_->schema()->name(), settings, file);
}
bool initialize() {
@@ -94,11 +94,11 @@ namespace IfcGeom {
int progress() const { return implementation_->progress(); }
std::string& unit_name() const { return implementation_->getUnitName(); }
const std::string& unit_name() const { return implementation_->getUnitName(); }
double unit_magnitude() const { return implementation_->getUnitMagnitude(); }
IfcParse::IfcFile* file() const { return implementation_->getFile(); }
IfcParse::IfcFile* file() const { return implementation_->file(); }
IfcUtil::IfcBaseClass* next() const { return implementation_->next(); }