mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 22:50:21 +00:00
@@ -195,43 +195,46 @@ int main() {
|
|||||||
file.addBuildingProduct(north_wall);
|
file.addBuildingProduct(north_wall);
|
||||||
file.setSurfaceColour(north_wall->Representation(), wall_colour);
|
file.setSurfaceColour(north_wall->Representation(), wall_colour);
|
||||||
|
|
||||||
IfcSchema::IfcShapeRepresentation* clipped_wall_body_rep = file.addEmptyRepresentation();
|
// Two identical representations are created for the two remaining walls. Mapped items
|
||||||
file.addBox(clipped_wall_body_rep, 5000, 360, 6000);
|
// are not used, because it is not allowed by the standard for wall body representations.
|
||||||
// The east wall geometry is clipped using two IfcHalfSpaceSolids, created from an
|
// MappedItems are not allowed for Axis representations as per CV-2x3-161
|
||||||
// 'axis 3d placement' that specifies the plane against which the geometry is clipped.
|
IfcSchema::IfcProductDefinitionShape* clipped_wall_body_reps[2];
|
||||||
file.clipRepresentation(clipped_wall_body_rep, file.addPlacement3d(-2500, 0, 3000, -1, 0, 1), false);
|
for (int i = 0; i < 2; ++i) {
|
||||||
file.clipRepresentation(clipped_wall_body_rep, file.addPlacement3d(2500, 0, 3000, 1, 0, 1), false);
|
IfcSchema::IfcShapeRepresentation* body = file.addEmptyRepresentation();
|
||||||
|
file.addBox(body, 5000, 360, 6000);
|
||||||
|
// The wall geometry is clipped using two IfcHalfSpaceSolids, created from an
|
||||||
|
// 'axis 3d placement' that specifies the plane against which the geometry is clipped.
|
||||||
|
file.clipRepresentation(body, file.addPlacement3d(-2500, 0, 3000, -1, 0, 1), false);
|
||||||
|
file.clipRepresentation(body, file.addPlacement3d(2500, 0, 3000, 1, 0, 1), false);
|
||||||
|
file.setSurfaceColour(body, wall_colour);
|
||||||
|
|
||||||
|
IfcSchema::IfcShapeRepresentation* axis = file.addEmptyRepresentation("Axis", "Curve2D");
|
||||||
|
file.addAxis(axis, 5000);
|
||||||
|
|
||||||
|
IfcSchema::IfcRepresentation::list::ptr reps(new IfcSchema::IfcRepresentation::list);
|
||||||
|
reps->push(body);
|
||||||
|
reps->push(axis);
|
||||||
|
clipped_wall_body_reps[i] = new IfcSchema::IfcProductDefinitionShape(null, null, reps);
|
||||||
|
}
|
||||||
|
|
||||||
// Now create a wall on the east of the building, again starting with just a box shape
|
// Now create a wall on the east of the building, again starting with just a box shape
|
||||||
IfcSchema::IfcWallStandardCase* east_wall = new IfcSchema::IfcWallStandardCase(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(),
|
IfcSchema::IfcWallStandardCase* east_wall = new IfcSchema::IfcWallStandardCase(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(),
|
||||||
S("East wall"), null, null, file.addLocalPlacement(storey_placement, 4820, 2500, 0, 0, 0, 1, 0, 1, 0), file.addMappedItem(clipped_wall_body_rep), null
|
S("East wall"), null, null, file.addLocalPlacement(storey_placement, 4820, 2500, 0, 0, 0, 1, 0, 1, 0), clipped_wall_body_reps[0], null
|
||||||
#ifdef USE_IFC4
|
#ifdef USE_IFC4
|
||||||
, IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD
|
, IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
file.addBuildingProduct(east_wall);
|
file.addBuildingProduct(east_wall);
|
||||||
|
|
||||||
file.setSurfaceColour(clipped_wall_body_rep, wall_colour);
|
|
||||||
|
|
||||||
// The east wall is copied to the west location of the house
|
// The east wall is copied to the west location of the house
|
||||||
IfcSchema::IfcWallStandardCase* west_wall = new IfcSchema::IfcWallStandardCase(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(),
|
IfcSchema::IfcWallStandardCase* west_wall = new IfcSchema::IfcWallStandardCase(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(),
|
||||||
S("West wall"), null, null, file.addLocalPlacement(storey_placement, -4820, 2500, 0, 0, 0, 1, 0, -1, 0), file.addMappedItem(clipped_wall_body_rep), null
|
S("West wall"), null, null, file.addLocalPlacement(storey_placement, -4820, 2500, 0, 0, 0, 1, 0, -1, 0), clipped_wall_body_reps[1], null
|
||||||
#ifdef USE_IFC4
|
#ifdef USE_IFC4
|
||||||
, IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD
|
, IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
file.addBuildingProduct(west_wall);
|
file.addBuildingProduct(west_wall);
|
||||||
|
|
||||||
for (int i = 0; i < 2; ++i) {
|
|
||||||
// CV-2x3-161: MappedItems are not allowed for Axis representations
|
|
||||||
IfcSchema::IfcWallStandardCase* wall = i == 0 ? east_wall : west_wall;
|
|
||||||
IfcSchema::IfcShapeRepresentation* wall_axis_rep = file.addEmptyRepresentation("Axis", "Curve2D");
|
|
||||||
file.addAxis(wall_axis_rep, 5000);
|
|
||||||
IfcSchema::IfcRepresentation::list::ptr reps = wall->Representation()->Representations();
|
|
||||||
reps->push(wall_axis_rep);
|
|
||||||
wall->Representation()->setRepresentations(reps);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The west wall is assigned an opening element we created for the south wall, opening elements are
|
// The west wall is assigned an opening element we created for the south wall, opening elements are
|
||||||
// not shared accross building elements, even if they share the same representation. Hence, the east
|
// not shared accross building elements, even if they share the same representation. Hence, the east
|
||||||
// wall will not feature this opening.
|
// wall will not feature this opening.
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
#include "../ifcgeom/IfcGeomIterator.h"
|
#include "../ifcgeom/IfcGeomIterator.h"
|
||||||
|
|
||||||
@@ -199,9 +200,8 @@ int main(int argc, char** argv) {
|
|||||||
// Gets the set ifc types to be ignored from the command line.
|
// Gets the set ifc types to be ignored from the command line.
|
||||||
std::set<std::string> entities;
|
std::set<std::string> entities;
|
||||||
for (std::vector<std::string>::const_iterator it = entity_vector.begin(); it != entity_vector.end(); ++it) {
|
for (std::vector<std::string>::const_iterator it = entity_vector.begin(); it != entity_vector.end(); ++it) {
|
||||||
std::string lowercase_type = *it;
|
const std::string& mixed_case_type = *it;
|
||||||
std::transform(lowercase_type.begin(), lowercase_type.end(), lowercase_type.begin(), ::tolower);
|
entities.insert(boost::to_lower_copy(mixed_case_type));
|
||||||
entities.insert(lowercase_type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string input_filename = vmap["input-file"].as<std::string>();
|
const std::string input_filename = vmap["input-file"].as<std::string>();
|
||||||
@@ -217,7 +217,7 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string output_extension = output_filename.substr(output_filename.size()-4);
|
std::string output_extension = output_filename.substr(output_filename.size()-4);
|
||||||
std::transform(output_extension.begin(), output_extension.end(), output_extension.begin(), ::tolower);
|
boost::to_lower(output_extension);
|
||||||
|
|
||||||
// If no entities are specified these are the defaults to skip from output
|
// If no entities are specified these are the defaults to skip from output
|
||||||
if (entity_vector.empty()) {
|
if (entity_vector.empty()) {
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ public:
|
|||||||
void setUnitNameAndMagnitude(const std::string& /*name*/, float magnitude) {
|
void setUnitNameAndMagnitude(const std::string& /*name*/, float magnitude) {
|
||||||
const char* symbol = getSymbolForUnitMagnitude(magnitude);
|
const char* symbol = getSymbolForUnitMagnitude(magnitude);
|
||||||
if (symbol) {
|
if (symbol) {
|
||||||
|
Interface_Static::SetCVal("xstep.cascade.unit", symbol);
|
||||||
Interface_Static::SetCVal("write.iges.unit", symbol);
|
Interface_Static::SetCVal("write.iges.unit", symbol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,20 +40,14 @@ void OpenCascadeBasedSerializer::write(const IfcGeom::BRepElement<double>* o) {
|
|||||||
for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = o->geometry().begin(); it != o->geometry().end(); ++ it) {
|
for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = o->geometry().begin(); it != o->geometry().end(); ++ it) {
|
||||||
gp_GTrsf gtrsf = it->Placement();
|
gp_GTrsf gtrsf = it->Placement();
|
||||||
|
|
||||||
const std::vector<double>& matrix = o->transformation().matrix().data();
|
const gp_Trsf& o_trsf = o->transformation().data();
|
||||||
|
|
||||||
// Convert the matrix back into a transformation object. The tolerance values
|
|
||||||
// are taken into consideration to reconstruct the form of the transformation.
|
|
||||||
gp_Trsf o_trsf;
|
|
||||||
o_trsf.SetValues(
|
|
||||||
matrix[0], matrix[3], matrix[6], matrix[ 9],
|
|
||||||
matrix[1], matrix[4], matrix[7], matrix[10],
|
|
||||||
matrix[2], matrix[5], matrix[8], matrix[11]
|
|
||||||
#if OCC_VERSION_HEX < 0x60800
|
|
||||||
, Precision::Angular(), Precision::Confusion()
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
gtrsf.PreMultiply(o_trsf);
|
gtrsf.PreMultiply(o_trsf);
|
||||||
|
|
||||||
|
if (o->geometry().settings().convert_back_units()) {
|
||||||
|
gp_Trsf scale;
|
||||||
|
scale.SetScaleFactor(1.0 / o->geometry().settings().unit_magnitude());
|
||||||
|
gtrsf.PreMultiply(scale);
|
||||||
|
}
|
||||||
|
|
||||||
const TopoDS_Shape& s = it->Shape();
|
const TopoDS_Shape& s = it->Shape();
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ public:
|
|||||||
void setUnitNameAndMagnitude(const std::string& /*name*/, float magnitude) {
|
void setUnitNameAndMagnitude(const std::string& /*name*/, float magnitude) {
|
||||||
const char* symbol = getSymbolForUnitMagnitude(magnitude);
|
const char* symbol = getSymbolForUnitMagnitude(magnitude);
|
||||||
if (symbol) {
|
if (symbol) {
|
||||||
|
Interface_Static::SetCVal("xstep.cascade.unit", symbol);
|
||||||
Interface_Static::SetCVal("write.step.unit", symbol);
|
Interface_Static::SetCVal("write.step.unit", symbol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -217,17 +217,7 @@ void SvgSerializer::write(const IfcGeom::BRepElement<double>* o) {
|
|||||||
for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = o->geometry().begin(); it != o->geometry().end(); ++ it) {
|
for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = o->geometry().begin(); it != o->geometry().end(); ++ it) {
|
||||||
gp_GTrsf gtrsf = it->Placement();
|
gp_GTrsf gtrsf = it->Placement();
|
||||||
|
|
||||||
gp_Trsf o_trsf;
|
const gp_Trsf& o_trsf = o->transformation().data();
|
||||||
const std::vector<double>& matrix = o->transformation().matrix().data();
|
|
||||||
o_trsf.SetValues(
|
|
||||||
matrix[0], matrix[3], matrix[6], matrix[ 9],
|
|
||||||
matrix[1], matrix[4], matrix[7], matrix[10],
|
|
||||||
matrix[2], matrix[5], matrix[8], matrix[11]
|
|
||||||
#if OCC_VERSION_HEX < 0x60800
|
|
||||||
, Precision::Angular(), Precision::Confusion()
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
gtrsf.PreMultiply(o_trsf);
|
|
||||||
const TopoDS_Shape& s = it->Shape();
|
const TopoDS_Shape& s = it->Shape();
|
||||||
|
|
||||||
bool trsf_valid = false;
|
bool trsf_valid = false;
|
||||||
|
|||||||
@@ -17,12 +17,13 @@
|
|||||||
* *
|
* *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
#include "../ifcgeom/IfcGeomRenderStyles.h"
|
#include "../ifcgeom/IfcGeomRenderStyles.h"
|
||||||
|
|
||||||
#include "WavefrontObjSerializer.h"
|
#include "WavefrontObjSerializer.h"
|
||||||
|
|
||||||
#include <iomanip>
|
|
||||||
|
|
||||||
bool WaveFrontOBJSerializer::ready() {
|
bool WaveFrontOBJSerializer::ready() {
|
||||||
return obj_stream.is_open() && mtl_stream.is_open();
|
return obj_stream.is_open() && mtl_stream.is_open();
|
||||||
}
|
}
|
||||||
@@ -70,6 +71,8 @@ void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement<double>*
|
|||||||
obj_stream << "g " << o->unique_id() << "\n";
|
obj_stream << "g " << o->unique_id() << "\n";
|
||||||
obj_stream << "s 1" << "\n";
|
obj_stream << "s 1" << "\n";
|
||||||
|
|
||||||
|
obj_stream << std::setprecision(std::numeric_limits<double>::digits10);
|
||||||
|
|
||||||
const IfcGeom::Representation::Triangulation<double>& mesh = o->geometry();
|
const IfcGeom::Representation::Triangulation<double>& mesh = o->geometry();
|
||||||
|
|
||||||
const int vcount = (int)mesh.verts().size() / 3;
|
const int vcount = (int)mesh.verts().size() / 3;
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ public:
|
|||||||
double face_area(const TopoDS_Face& f);
|
double face_area(const TopoDS_Face& f);
|
||||||
void apply_tolerance(TopoDS_Shape& s, double t);
|
void apply_tolerance(TopoDS_Shape& s, double t);
|
||||||
void setValue(GeomValue var, double value);
|
void setValue(GeomValue var, double value);
|
||||||
double getValue(GeomValue var);
|
double getValue(GeomValue var) const;
|
||||||
bool fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& shape);
|
bool fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& shape);
|
||||||
void remove_redundant_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol=-1.);
|
void remove_redundant_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol=-1.);
|
||||||
|
|
||||||
|
|||||||
@@ -160,10 +160,15 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
|
|||||||
IfcSchema::IfcRelVoidsElement* v = *it;
|
IfcSchema::IfcRelVoidsElement* v = *it;
|
||||||
IfcSchema::IfcFeatureElementSubtraction* fes = v->RelatedOpeningElement();
|
IfcSchema::IfcFeatureElementSubtraction* fes = v->RelatedOpeningElement();
|
||||||
if ( fes->is(IfcSchema::Type::IfcOpeningElement) ) {
|
if ( fes->is(IfcSchema::Type::IfcOpeningElement) ) {
|
||||||
|
if (!fes->hasRepresentation()) continue;
|
||||||
|
|
||||||
// Convert the IfcRepresentation of the IfcOpeningElement
|
// Convert the IfcRepresentation of the IfcOpeningElement
|
||||||
gp_Trsf opening_trsf;
|
gp_Trsf opening_trsf;
|
||||||
IfcGeom::Kernel::convert(fes->ObjectPlacement(),opening_trsf);
|
if (fes->hasObjectPlacement()) {
|
||||||
|
try {
|
||||||
|
convert(fes->ObjectPlacement(),opening_trsf);
|
||||||
|
} catch (...) {}
|
||||||
|
}
|
||||||
|
|
||||||
// Move the opening into the coordinate system of the IfcProduct
|
// Move the opening into the coordinate system of the IfcProduct
|
||||||
opening_trsf.PreMultiply(entity_trsf.Inverted());
|
opening_trsf.PreMultiply(entity_trsf.Inverted());
|
||||||
@@ -302,10 +307,15 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
|
|||||||
IfcSchema::IfcRelVoidsElement* v = *it;
|
IfcSchema::IfcRelVoidsElement* v = *it;
|
||||||
IfcSchema::IfcFeatureElementSubtraction* fes = v->RelatedOpeningElement();
|
IfcSchema::IfcFeatureElementSubtraction* fes = v->RelatedOpeningElement();
|
||||||
if ( fes->is(IfcSchema::Type::IfcOpeningElement) ) {
|
if ( fes->is(IfcSchema::Type::IfcOpeningElement) ) {
|
||||||
|
if (!fes->hasRepresentation()) continue;
|
||||||
|
|
||||||
// Convert the IfcRepresentation of the IfcOpeningElement
|
// Convert the IfcRepresentation of the IfcOpeningElement
|
||||||
gp_Trsf opening_trsf;
|
gp_Trsf opening_trsf;
|
||||||
IfcGeom::Kernel::convert(fes->ObjectPlacement(),opening_trsf);
|
if (fes->hasObjectPlacement()) {
|
||||||
|
try {
|
||||||
|
convert(fes->ObjectPlacement(),opening_trsf);
|
||||||
|
} catch (...) {}
|
||||||
|
}
|
||||||
|
|
||||||
// Move the opening into the coordinate system of the IfcProduct
|
// Move the opening into the coordinate system of the IfcProduct
|
||||||
opening_trsf.PreMultiply(entity_trsf.Inverted());
|
opening_trsf.PreMultiply(entity_trsf.Inverted());
|
||||||
@@ -553,7 +563,7 @@ void IfcGeom::Kernel::setValue(GeomValue var, double value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double IfcGeom::Kernel::getValue(GeomValue var) {
|
double IfcGeom::Kernel::getValue(GeomValue var) const {
|
||||||
switch (var) {
|
switch (var) {
|
||||||
case GV_DEFLECTION_TOLERANCE:
|
case GV_DEFLECTION_TOLERANCE:
|
||||||
return deflection_tolerance;
|
return deflection_tolerance;
|
||||||
@@ -774,8 +784,14 @@ bool IfcGeom::Kernel::flatten_shape_list(const IfcGeom::IfcRepresentationShapeIt
|
|||||||
_trsf = trsf.Trsf();
|
_trsf = trsf.Trsf();
|
||||||
trsf_valid = true;
|
trsf_valid = true;
|
||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
const TopoDS_Shape moved_shape = trsf_valid ? merged.Moved(_trsf) :
|
|
||||||
BRepBuilderAPI_GTransform(merged,trsf,true).Shape();
|
const TopoDS_Shape moved_shape = trsf.Form() == gp_Identity
|
||||||
|
? merged
|
||||||
|
: (
|
||||||
|
trsf_valid
|
||||||
|
? merged.Moved(_trsf)
|
||||||
|
: BRepBuilderAPI_GTransform(merged,trsf,true).Shape()
|
||||||
|
);
|
||||||
|
|
||||||
if (shapes.size() == 1) {
|
if (shapes.size() == 1) {
|
||||||
result = moved_shape;
|
result = moved_shape;
|
||||||
@@ -807,6 +823,10 @@ bool IfcGeom::Kernel::flatten_shape_list(const IfcGeom::IfcRepresentationShapeIt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!fuse) {
|
||||||
|
result = compound;
|
||||||
|
}
|
||||||
|
|
||||||
const bool success = !result.IsNull();
|
const bool success = !result.IsNull();
|
||||||
if (success) {
|
if (success) {
|
||||||
const double precision = getValue(GV_PRECISION);
|
const double precision = getValue(GV_PRECISION);
|
||||||
|
|||||||
@@ -180,13 +180,15 @@ namespace IfcGeom {
|
|||||||
// by the parent's context inverse attributes.
|
// by the parent's context inverse attributes.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (context->hasContextType()) {
|
try {
|
||||||
std::string context_type_lc = context->ContextType();
|
if (context->hasContextType()) {
|
||||||
std::transform(context_type_lc.begin(), context_type_lc.end(), context_type_lc.begin(), ::tolower);
|
std::string context_type = context->ContextType();
|
||||||
if (context_types.find(context_type_lc) != context_types.end()) {
|
boost::to_lower(context_type);
|
||||||
filtered_contexts->push(context);
|
if (context_types.find(context_type) != context_types.end()) {
|
||||||
|
filtered_contexts->push(context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
} catch (const IfcParse::IfcException&) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// In case no contexts are identified based on their ContextType, all contexts are
|
// In case no contexts are identified based on their ContextType, all contexts are
|
||||||
@@ -204,10 +206,12 @@ namespace IfcGeom {
|
|||||||
IfcSchema::IfcGeometricRepresentationContext* context = *it;
|
IfcSchema::IfcGeometricRepresentationContext* context = *it;
|
||||||
|
|
||||||
representations->push(context->RepresentationsInContext());
|
representations->push(context->RepresentationsInContext());
|
||||||
if (context->hasPrecision() && context->Precision() < lowest_precision_encountered) {
|
try {
|
||||||
lowest_precision_encountered = context->Precision();
|
if (context->hasPrecision() && context->Precision() < lowest_precision_encountered) {
|
||||||
any_precision_encountered = true;
|
lowest_precision_encountered = context->Precision();
|
||||||
}
|
any_precision_encountered = true;
|
||||||
|
}
|
||||||
|
} catch (const IfcParse::IfcException&) {}
|
||||||
IfcSchema::IfcGeometricRepresentationSubContext::list::ptr sub_contexts = context->HasSubContexts();
|
IfcSchema::IfcGeometricRepresentationSubContext::list::ptr sub_contexts = context->HasSubContexts();
|
||||||
for (jt = sub_contexts->begin(); jt != sub_contexts->end(); ++jt) {
|
for (jt = sub_contexts->begin(); jt != sub_contexts->end(); ++jt) {
|
||||||
representations->push((*jt)->RepresentationsInContext());
|
representations->push((*jt)->RepresentationsInContext());
|
||||||
|
|||||||
@@ -99,10 +99,15 @@
|
|||||||
#include "../ifcgeom/IfcGeom.h"
|
#include "../ifcgeom/IfcGeom.h"
|
||||||
|
|
||||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcExtrudedAreaSolid* l, TopoDS_Shape& shape) {
|
bool IfcGeom::Kernel::convert(const IfcSchema::IfcExtrudedAreaSolid* l, TopoDS_Shape& shape) {
|
||||||
|
const double height = l->Depth() * getValue(GV_LENGTH_UNIT);
|
||||||
|
if (height < getValue(GV_PRECISION)) {
|
||||||
|
Logger::Message(Logger::LOG_ERROR, "Non-positive extrusion height encountered for:", l->entity);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
TopoDS_Shape face;
|
TopoDS_Shape face;
|
||||||
if ( !convert_face(l->SweptArea(),face) ) return false;
|
if ( !convert_face(l->SweptArea(),face) ) return false;
|
||||||
|
|
||||||
const double height = l->Depth() * getValue(GV_LENGTH_UNIT);
|
|
||||||
gp_Trsf trsf;
|
gp_Trsf trsf;
|
||||||
IfcGeom::Kernel::convert(l->Position(),trsf);
|
IfcGeom::Kernel::convert(l->Position(),trsf);
|
||||||
|
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire&
|
|||||||
flts[1] -= M_PI / 2.;
|
flts[1] -= M_PI / 2.;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( isConic && ALMOST_THE_SAME(fmod(flts[1]-flts[0],(double)(M_PI*2.0)),0.0f) ) {
|
if ( isConic && ALMOST_THE_SAME(fmod(flts[1]-flts[0],M_PI*2.),0.) ) {
|
||||||
w.Add(BRepBuilderAPI_MakeEdge(curve));
|
w.Add(BRepBuilderAPI_MakeEdge(curve));
|
||||||
} else {
|
} else {
|
||||||
BRepBuilderAPI_MakeEdge e (curve,flts[0],flts[1]);
|
BRepBuilderAPI_MakeEdge e (curve,flts[0],flts[1]);
|
||||||
|
|||||||
@@ -24,6 +24,15 @@ using namespace IfcSchema;
|
|||||||
using namespace IfcUtil;
|
using namespace IfcUtil;
|
||||||
|
|
||||||
bool IfcGeom::Kernel::convert_shapes(const IfcBaseClass* l, IfcRepresentationShapeItems& r) {
|
bool IfcGeom::Kernel::convert_shapes(const IfcBaseClass* l, IfcRepresentationShapeItems& r) {
|
||||||
|
if (shape_type(l) != ST_SHAPELIST) {
|
||||||
|
TopoDS_Shape shp;
|
||||||
|
if (convert_shape(l, shp)) {
|
||||||
|
r.push_back(IfcGeom::IfcRepresentationShapeItem(shp, get_style(l->as<IfcSchema::IfcRepresentationItem>())));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#include "IfcRegisterConvertShapes.h"
|
#include "IfcRegisterConvertShapes.h"
|
||||||
Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity);
|
Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ def has_occ():
|
|||||||
has_occ = has_occ()
|
has_occ = has_occ()
|
||||||
wrap_shape_creation = lambda settings, shape: shape
|
wrap_shape_creation = lambda settings, shape: shape
|
||||||
if has_occ:
|
if has_occ:
|
||||||
import occ_utils as utils
|
from . import occ_utils as utils
|
||||||
wrap_shape_creation = lambda settings, shape: utils.create_shape_from_serialization(shape) if getattr(settings, 'use_python_opencascade', False) else shape
|
wrap_shape_creation = lambda settings, shape: utils.create_shape_from_serialization(shape) if getattr(settings, 'use_python_opencascade', False) else shape
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -52,8 +52,14 @@ def get_bounding_box_center(bbox):
|
|||||||
def create_shape_from_serialization(brep_object):
|
def create_shape_from_serialization(brep_object):
|
||||||
brep_data, occ_shape = None, None
|
brep_data, occ_shape = None, None
|
||||||
|
|
||||||
try: brep_data = brep_object.geometry.brep_data
|
is_product_shape = True
|
||||||
except: pass
|
try:
|
||||||
|
brep_data = brep_object.geometry.brep_data
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
brep_data = brep_object.brep_data
|
||||||
|
is_product_shape = False
|
||||||
|
except: pass
|
||||||
if not brep_data: return tuple(brep_object, None)
|
if not brep_data: return tuple(brep_object, None)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -62,5 +68,8 @@ def create_shape_from_serialization(brep_object):
|
|||||||
occ_shape = ss.Shape(ss.NbShapes())
|
occ_shape = ss.Shape(ss.NbShapes())
|
||||||
except: pass
|
except: pass
|
||||||
|
|
||||||
return tuple(brep_object, occ_shape)
|
if is_product_shape:
|
||||||
|
return tuple(brep_object, occ_shape)
|
||||||
|
else:
|
||||||
|
return occ_shape
|
||||||
|
|
||||||
|
|||||||
@@ -970,7 +970,7 @@ bool IfcFile::Init(IfcParse::IfcSpfStream* s) {
|
|||||||
const std::string guid = ifc_root->GlobalId();
|
const std::string guid = ifc_root->GlobalId();
|
||||||
if ( byguid.find(guid) != byguid.end() ) {
|
if ( byguid.find(guid) != byguid.end() ) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "Overwriting entity with guid " << guid;
|
ss << "Instance encountered with non-unique GlobalId " << guid;
|
||||||
Logger::Message(Logger::LOG_WARNING,ss.str());
|
Logger::Message(Logger::LOG_WARNING,ss.str());
|
||||||
}
|
}
|
||||||
byguid[guid] = ifc_root;
|
byguid[guid] = ifc_root;
|
||||||
@@ -992,7 +992,7 @@ bool IfcFile::Init(IfcParse::IfcSpfStream* s) {
|
|||||||
|
|
||||||
if ( byid.find(currentId) != byid.end() ) {
|
if ( byid.find(currentId) != byid.end() ) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "Overwriting entity with id " << currentId;
|
ss << "Overwriting instance with name #" << currentId;
|
||||||
Logger::Message(Logger::LOG_WARNING,ss.str());
|
Logger::Message(Logger::LOG_WARNING,ss.str());
|
||||||
}
|
}
|
||||||
byid[currentId] = entity;
|
byid[currentId] = entity;
|
||||||
|
|||||||
@@ -89,6 +89,13 @@ namespace IfcUtil {
|
|||||||
? static_cast<T*>(this)
|
? static_cast<T*>(this)
|
||||||
: static_cast<T*>(0);
|
: static_cast<T*>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
const T* as() const {
|
||||||
|
return is(T::Class())
|
||||||
|
? static_cast<const T*>(this)
|
||||||
|
: static_cast<const T*>(0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class IfcBaseEntity : public IfcBaseClass {
|
class IfcBaseEntity : public IfcBaseClass {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
@@ -328,7 +329,7 @@ private:
|
|||||||
std::string format_double(const double& d) {
|
std::string format_double(const double& d) {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss.imbue(std::locale::classic());
|
oss.imbue(std::locale::classic());
|
||||||
oss << std::setprecision(15) << d;
|
oss << std::setprecision(std::numeric_limits<double>::digits10) << d;
|
||||||
const std::string str = oss.str();
|
const std::string str = oss.str();
|
||||||
oss.str("");
|
oss.str("");
|
||||||
std::string::size_type e = str.find('e');
|
std::string::size_type e = str.find('e');
|
||||||
|
|||||||
@@ -72,17 +72,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A visitor
|
||||||
|
%{
|
||||||
|
struct ShapeRTTI : public boost::static_visitor<PyObject*>
|
||||||
|
{
|
||||||
|
PyObject* operator()(IfcGeom::Element<double>* elem) const {
|
||||||
|
IfcGeom::SerializedElement<double>* serialized_elem = dynamic_cast<IfcGeom::SerializedElement<double>*>(elem);
|
||||||
|
IfcGeom::TriangulationElement<double>* triangulation_elem = dynamic_cast<IfcGeom::TriangulationElement<double>*>(elem);
|
||||||
|
if (triangulation_elem) {
|
||||||
|
return SWIG_NewPointerObj(SWIG_as_voidptr(triangulation_elem), SWIGTYPE_p_IfcGeom__TriangulationElementT_double_t, SWIG_POINTER_OWN);
|
||||||
|
} else if (serialized_elem) {
|
||||||
|
return SWIG_NewPointerObj(SWIG_as_voidptr(serialized_elem), SWIGTYPE_p_IfcGeom__SerializedElementT_double_t, SWIG_POINTER_OWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PyObject* operator()(IfcGeom::Representation::Representation* representation) const {
|
||||||
|
IfcGeom::Representation::Serialization* serialized_representation = dynamic_cast<IfcGeom::Representation::Serialization*>(representation);
|
||||||
|
IfcGeom::Representation::Triangulation<double>* triangulated_representation = dynamic_cast<IfcGeom::Representation::Triangulation<double>*>(representation);
|
||||||
|
if (serialized_representation) {
|
||||||
|
return SWIG_NewPointerObj(SWIG_as_voidptr(serialized_representation), SWIGTYPE_p_IfcGeom__Representation__Serialization, SWIG_POINTER_OWN);
|
||||||
|
} else if (triangulated_representation) {
|
||||||
|
return SWIG_NewPointerObj(SWIG_as_voidptr(triangulated_representation), SWIGTYPE_p_IfcGeom__Representation__TriangulationT_double_t, SWIG_POINTER_OWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
// Note that these elements ARE to be owned by SWIG/Python
|
// Note that these elements ARE to be owned by SWIG/Python
|
||||||
%typemap(out) boost::variant<IfcGeom::Element<double>*, IfcGeom::Representation::Representation*> {
|
%typemap(out) boost::variant<IfcGeom::Element<double>*, IfcGeom::Representation::Representation*> {
|
||||||
// See which type is set and return appropriate
|
// See which type is set and return appropriate
|
||||||
IfcGeom::Element<double>* elem = boost::get<IfcGeom::Element<double>*>($1);
|
$result = boost::apply_visitor(ShapeRTTI(), $1);
|
||||||
IfcGeom::SerializedElement<double>* serialized_elem = dynamic_cast<IfcGeom::SerializedElement<double>*>(elem);
|
|
||||||
IfcGeom::TriangulationElement<double>* triangulation_elem = dynamic_cast<IfcGeom::TriangulationElement<double>*>(elem);
|
|
||||||
if (triangulation_elem) {
|
|
||||||
$result = SWIG_NewPointerObj(SWIG_as_voidptr(triangulation_elem), SWIGTYPE_p_IfcGeom__TriangulationElementT_double_t, SWIG_POINTER_OWN);
|
|
||||||
} else if (serialized_elem) {
|
|
||||||
$result = SWIG_NewPointerObj(SWIG_as_voidptr(serialized_elem), SWIGTYPE_p_IfcGeom__SerializedElementT_double_t, SWIG_POINTER_OWN);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This does not seem to work:
|
// This does not seem to work:
|
||||||
@@ -218,25 +236,25 @@
|
|||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
boost::variant<IfcGeom::Element<double>*, IfcGeom::Representation::Representation*> create_shape(IfcGeom::IteratorSettings& settings, IfcParse::IfcLateBoundEntity* instance, IfcParse::IfcLateBoundEntity* representation = 0) {
|
boost::variant<IfcGeom::Element<double>*, IfcGeom::Representation::Representation*> create_shape(IfcGeom::IteratorSettings& settings, IfcParse::IfcLateBoundEntity* instance, IfcParse::IfcLateBoundEntity* representation = 0) {
|
||||||
|
IfcParse::IfcFile* file = instance->entity->file;
|
||||||
|
IfcSchema::IfcProject::list::ptr projects = file->entitiesByType<IfcSchema::IfcProject>();
|
||||||
|
if (projects->size() != 1) {
|
||||||
|
throw IfcParse::IfcException("Not a single IfcProject instance");
|
||||||
|
}
|
||||||
|
IfcSchema::IfcProject* project = *projects->begin();
|
||||||
|
|
||||||
|
IfcGeom::Kernel kernel;
|
||||||
|
kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.sew_shells() ? 1000 : -1);
|
||||||
|
kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.include_curves() ? (settings.exclude_solids_and_surfaces() ? -1. : 0.) : +1.));
|
||||||
|
std::pair<std::string, double> length_unit = kernel.initializeUnits(project->UnitsInContext());
|
||||||
|
|
||||||
if (instance->is(IfcSchema::Type::IfcProduct)) {
|
if (instance->is(IfcSchema::Type::IfcProduct)) {
|
||||||
if (representation) {
|
if (representation) {
|
||||||
if (!representation->is(IfcSchema::Type::IfcRepresentation)) {
|
if (!representation->is(IfcSchema::Type::IfcRepresentation)) {
|
||||||
throw IfcParse::IfcException("Supplied representation not of type IfcRepresentation");
|
throw IfcParse::IfcException("Supplied representation not of type IfcRepresentation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IfcParse::IfcFile* file = instance->entity->file;
|
|
||||||
|
|
||||||
IfcSchema::IfcProject::list::ptr projects = file->entitiesByType<IfcSchema::IfcProject>();
|
|
||||||
if (projects->size() != 1) {
|
|
||||||
throw IfcParse::IfcException("Not a single IfcProject instance");
|
|
||||||
}
|
|
||||||
IfcSchema::IfcProject* project = *projects->begin();
|
|
||||||
|
|
||||||
IfcGeom::Kernel kernel;
|
|
||||||
kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.sew_shells() ? 1000 : -1);
|
|
||||||
kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.include_curves() ? (settings.exclude_solids_and_surfaces() ? -1. : 0.) : +1.));
|
|
||||||
|
|
||||||
IfcSchema::IfcProduct* product = (IfcSchema::IfcProduct*) instance;
|
IfcSchema::IfcProduct* product = (IfcSchema::IfcProduct*) instance;
|
||||||
|
|
||||||
if (!representation && !product->hasRepresentation()) {
|
if (!representation && !product->hasRepresentation()) {
|
||||||
@@ -318,7 +336,6 @@
|
|||||||
if (context->hasPrecision()) {
|
if (context->hasPrecision()) {
|
||||||
precision = context->Precision();
|
precision = context->Precision();
|
||||||
}
|
}
|
||||||
std::pair<std::string, double> length_unit = kernel.initializeUnits(project->UnitsInContext());
|
|
||||||
precision *= length_unit.second;
|
precision *= length_unit.second;
|
||||||
|
|
||||||
// Some arbitrary factor that has proven to work better for the models in the set of test files.
|
// Some arbitrary factor that has proven to work better for the models in the set of test files.
|
||||||
@@ -342,7 +359,28 @@
|
|||||||
throw IfcParse::IfcException("No element to return based on provided settings");
|
throw IfcParse::IfcException("No element to return based on provided settings");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw IfcParse::IfcException("Only obtaining representations for IfcProduct instances is currently supported");
|
if (!representation) {
|
||||||
|
if (instance->is(IfcSchema::Type::IfcRepresentationItem) || instance->is(IfcSchema::Type::IfcRepresentation)) {
|
||||||
|
IfcGeom::IfcRepresentationShapeItems shapes;
|
||||||
|
if (kernel.convert_shapes(instance, shapes)) {
|
||||||
|
IfcGeom::ElementSettings element_settings(settings, kernel.getValue(IfcGeom::Kernel::GV_LENGTH_UNIT), IfcSchema::Type::ToString(instance->type()));
|
||||||
|
IfcGeom::Representation::BRep brep(element_settings, instance->entity->id(), shapes);
|
||||||
|
try {
|
||||||
|
if (settings.use_brep_data()) {
|
||||||
|
return new IfcGeom::Representation::Serialization(brep);
|
||||||
|
} else if (!settings.disable_triangulation()) {
|
||||||
|
return new IfcGeom::Representation::Triangulation<double>(brep);
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
throw IfcParse::IfcException("Error during shape serialization");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw IfcParse::IfcException("Geometrical element not understood");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw IfcParse::IfcException("Invalid additional representation specified");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|||||||
Reference in New Issue
Block a user