mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Work on serializers
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
*/
|
||||
@@ -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)
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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)
|
||||
{}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user