mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Isolate (most of the) geometry processing code into separate opencascade kernel
This commit is contained in:
+11
-20
@@ -536,7 +536,7 @@ if(NOT Boost_VERSION LESS 105800)
|
||||
add_definitions(-DBOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE)
|
||||
endif()
|
||||
|
||||
set(IFCOPENSHELL_LIBRARIES IfcParse IfcGeom IfcGeom IfcGeom_CGAL Serializers Serializers)
|
||||
set(IFCOPENSHELL_LIBRARIES IfcParse IfcGeom Serializers)
|
||||
|
||||
# IfcParse
|
||||
file(GLOB IFCPARSE_H_FILES ../src/ifcparse/*.h)
|
||||
@@ -561,11 +561,6 @@ file(GLOB IFCGEOM_H_FILES ../src/ifcgeom/*.h)
|
||||
file(GLOB IFCGEOM_CPP_FILES ../src/ifcgeom/*.cpp)
|
||||
set(IFCGEOM_FILES ${IFCGEOM_CPP_FILES} ${IFCGEOM_H_FILES})
|
||||
|
||||
# IfcGeom, schema agnostic, OCCT
|
||||
file(GLOB SCHEMA_AGNOSTIC_H_FILES ../src/ifcgeom_schema_agnostic/*.h)
|
||||
file(GLOB SCHEMA_AGNOSTIC_CPP_FILES ../src/ifcgeom_schema_agnostic/*.cpp)
|
||||
set(SCHEMA_AGNOSTIC_FILES ${SCHEMA_AGNOSTIC_H_FILES} ${SCHEMA_AGNOSTIC_CPP_FILES})
|
||||
|
||||
foreach(schema 2x3 4)
|
||||
add_library(IfcGeom_ifc${schema} ${IFCGEOM_FILES})
|
||||
set_target_properties(IfcGeom_ifc${schema} PROPERTIES COMPILE_FLAGS "-DIFC_GEOM_EXPORTS -DIfcSchema=Ifc${schema} -DUSE_IFC${schema}")
|
||||
@@ -573,32 +568,28 @@ TARGET_LINK_LIBRARIES(IfcGeom_ifc${schema} IfcParse ${OPENCASCADE_LIBRARIES})
|
||||
list(APPEND IfcGeom_libraries IfcGeom_ifc${schema})
|
||||
endforeach()
|
||||
|
||||
add_library(IfcGeom ${SCHEMA_AGNOSTIC_FILES})
|
||||
set_target_properties(IfcGeom PROPERTIES COMPILE_FLAGS -DIFC_GEOM_EXPORTS)
|
||||
TARGET_LINK_LIBRARIES(IfcGeom ${IfcGeom_libraries})
|
||||
|
||||
### CGAL
|
||||
|
||||
# IfcGeom, schema dependent, OCCT
|
||||
# IfcGeom, schema dependent, CGAL
|
||||
file(GLOB IFCGEOM_H_FILES ../src/ifcgeom/kernels/cgal/*.h)
|
||||
file(GLOB IFCGEOM_CPP_FILES ../src/ifcgeom/kernels/cgal/*.cpp)
|
||||
set(IFCGEOM_FILES ${IFCGEOM_CPP_FILES} ${IFCGEOM_H_FILES})
|
||||
|
||||
# IfcGeom, schema agnostic, OCCT
|
||||
file(GLOB SCHEMA_AGNOSTIC_H_FILES ../src/ifcgeom_schema_agnostic_cgal/*.h)
|
||||
file(GLOB SCHEMA_AGNOSTIC_CPP_FILES ../src/ifcgeom_schema_agnostic_cgal/*.cpp)
|
||||
set(SCHEMA_AGNOSTIC_FILES ${SCHEMA_AGNOSTIC_H_FILES} ${SCHEMA_AGNOSTIC_CPP_FILES})
|
||||
|
||||
foreach(schema 2x3 4)
|
||||
add_library(IfcGeom_ifc${schema} ${IFCGEOM_FILES})
|
||||
add_library(IfcGeom_CGAL_ifc${schema} ${IFCGEOM_FILES})
|
||||
set_target_properties(IfcGeom_CGAL_ifc${schema} PROPERTIES COMPILE_FLAGS "-DIFC_GEOM_EXPORTS -DIfcSchema=Ifc${schema} -DUSE_IFC${schema}")
|
||||
TARGET_LINK_LIBRARIES(IfcGeom_CGAL_ifc${schema} IfcParse ${OPENCASCADE_LIBRARIES})
|
||||
list(APPEND IfcGeom_CGAL_libraries IfcGeom_CGAL_ifc${schema})
|
||||
endforeach()
|
||||
|
||||
add_library(IfcGeom_CGAL ${SCHEMA_AGNOSTIC_FILES})
|
||||
set_target_properties(IfcGeom_CGAL PROPERTIES COMPILE_FLAGS -DIFC_GEOM_EXPORTS)
|
||||
TARGET_LINK_LIBRARIES(IfcGeom_CGAL ${IfcGeom_CGAL_libraries})
|
||||
# IfcGeom, schema and kernel agnostic
|
||||
file(GLOB SCHEMA_AGNOSTIC_H_FILES ../src/ifcgeom_schema_agnostic/*.h)
|
||||
file(GLOB SCHEMA_AGNOSTIC_CPP_FILES ../src/ifcgeom_schema_agnostic/*.cpp)
|
||||
set(SCHEMA_AGNOSTIC_FILES ${SCHEMA_AGNOSTIC_H_FILES} ${SCHEMA_AGNOSTIC_CPP_FILES})
|
||||
|
||||
add_library(IfcGeom ${SCHEMA_AGNOSTIC_FILES})
|
||||
set_target_properties(IfcGeom PROPERTIES COMPILE_FLAGS -DIFC_GEOM_EXPORTS)
|
||||
TARGET_LINK_LIBRARIES(IfcGeom ${IfcGeom_libraries})
|
||||
|
||||
endif(BUILD_IFCGEOM)
|
||||
|
||||
|
||||
@@ -711,7 +711,7 @@ int main(int argc, char** argv)
|
||||
// The functions IfcGeom::Iterator::get() and IfcGeom::Iterator::next()
|
||||
// wrap an iterator of all geometrical products in the Ifc file.
|
||||
// IfcGeom::Iterator::get() returns an IfcGeom::TriangulationElement or
|
||||
// -BRepElement pointer, based on current settings. (see IfcGeomIterator.h
|
||||
// -NativeElement pointer, based on current settings. (see IfcGeomIterator.h
|
||||
// for definition) IfcGeom::Iterator::next() is used to poll whether more
|
||||
// geometrical entities are available. None of these functions throw
|
||||
// exceptions, neither for parsing errors or geometrical errors. Upon
|
||||
@@ -729,7 +729,7 @@ int main(int argc, char** argv)
|
||||
}
|
||||
else
|
||||
{
|
||||
serializer->write(static_cast<const IfcGeom::BRepElement<real_t>*>(geom_object));
|
||||
serializer->write(static_cast<const IfcGeom::NativeElement<real_t>*>(geom_object));
|
||||
}
|
||||
|
||||
if (!no_progress) {
|
||||
@@ -1152,7 +1152,7 @@ void fix_quantities(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool std
|
||||
if (num_created) {
|
||||
has_more = context_iterator.next();
|
||||
}
|
||||
IfcGeom::BRepElement<double>* geom_object = nullptr;
|
||||
IfcGeom::NativeElement<double>* geom_object = nullptr;
|
||||
if (has_more) {
|
||||
geom_object = context_iterator.get_native();
|
||||
}
|
||||
@@ -1205,7 +1205,7 @@ void fix_quantities(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool std
|
||||
auto quantity_count = latebound_access::create(f, "IfcQuantityCount");
|
||||
latebound_access::set(quantity_count, "Name", std::string("Surface Genus"));
|
||||
latebound_access::set(quantity_count, "Description", '#' + boost::lexical_cast<std::string>(part.ItemId()));
|
||||
latebound_access::set(quantity_count, "CountValue", IfcGeom::Kernel::surface_genus(part.Shape()));
|
||||
latebound_access::set(quantity_count, "CountValue", part.Shape()->surface_genus());
|
||||
|
||||
quantities_2->push(quantity_count);
|
||||
}
|
||||
|
||||
+19
-17
@@ -52,14 +52,15 @@ inline static bool ALMOST_THE_SAME(const T& a, const T& b, double tolerance=ALMO
|
||||
#include "../ifcparse/IfcParse.h"
|
||||
#include "../ifcparse/IfcBaseClass.h"
|
||||
|
||||
#include "../ifcgeom/IfcGeomElement.h"
|
||||
#include "../ifcgeom/IfcGeomRepresentation.h"
|
||||
#include "../ifcgeom/IfcRepresentationShapeItem.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomElement.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomRepresentation.h"
|
||||
#include "../ifcgeom_schema_agnostic/ConversionResult.h"
|
||||
#include "../ifcgeom/IfcGeomShapeType.h"
|
||||
|
||||
#include "../ifcgeom_schema_agnostic/Kernel.h"
|
||||
#include "OpenCascadeConversionResult.h"
|
||||
|
||||
#include "ifc_geom_api.h"
|
||||
#include "../ifcgeom_schema_agnostic/ifc_geom_api.h"
|
||||
|
||||
// Define this in case you want to conserve memory usage at all cost. This has been
|
||||
// benchmarked extensively: https://github.com/IfcOpenShell/IfcOpenShell/pull/47
|
||||
@@ -258,21 +259,21 @@ public:
|
||||
|
||||
bool convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face);
|
||||
bool convert_curve_to_wire(const Handle(Geom_Curve)& curve, TopoDS_Wire& wire);
|
||||
bool convert_shapes(const IfcUtil::IfcBaseClass* L, IfcRepresentationShapeItems& result);
|
||||
bool convert_shapes(const IfcUtil::IfcBaseClass* L, ConversionResults& result);
|
||||
IfcGeom::ShapeType shape_type(const IfcUtil::IfcBaseClass* L);
|
||||
bool convert_shape(const IfcUtil::IfcBaseClass* L, TopoDS_Shape& result);
|
||||
bool flatten_shape_list(const IfcGeom::IfcRepresentationShapeItems& shapes, TopoDS_Shape& result, bool fuse);
|
||||
bool flatten_shape_list(const IfcGeom::ConversionResults& shapes, TopoDS_Shape& result, bool fuse);
|
||||
bool convert_wire(const IfcUtil::IfcBaseClass* L, TopoDS_Wire& result);
|
||||
bool convert_curve(const IfcUtil::IfcBaseClass* L, Handle(Geom_Curve)& result);
|
||||
bool convert_face(const IfcUtil::IfcBaseClass* L, TopoDS_Shape& result);
|
||||
bool convert_openings(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings, const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes);
|
||||
bool convert_openings_fast(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings, const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes);
|
||||
bool convert_openings(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings, const ConversionResults& entity_shapes, const gp_Trsf& entity_trsf, ConversionResults& cut_shapes);
|
||||
bool convert_openings_fast(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings, const ConversionResults& entity_shapes, const gp_Trsf& entity_trsf, ConversionResults& cut_shapes);
|
||||
void assert_closed_wire(TopoDS_Wire& wire);
|
||||
|
||||
bool convert_layerset(const IfcSchema::IfcProduct*, std::vector<Handle_Geom_Surface>&, std::vector<const SurfaceStyle*>&, std::vector<double>&);
|
||||
bool apply_layerset(const IfcRepresentationShapeItems&, const std::vector<Handle_Geom_Surface>&, const std::vector<const SurfaceStyle*>&, IfcRepresentationShapeItems&);
|
||||
bool apply_folded_layerset(const IfcRepresentationShapeItems&, const std::vector< std::vector<Handle_Geom_Surface> >&, const std::vector<const SurfaceStyle*>&, IfcRepresentationShapeItems&);
|
||||
bool fold_layers(const IfcSchema::IfcWall*, const IfcRepresentationShapeItems&, const std::vector<Handle_Geom_Surface>&, const std::vector<double>&, std::vector< std::vector<Handle_Geom_Surface> >&);
|
||||
bool apply_layerset(const ConversionResults&, const std::vector<Handle_Geom_Surface>&, const std::vector<const SurfaceStyle*>&, ConversionResults&);
|
||||
bool apply_folded_layerset(const ConversionResults&, const std::vector< std::vector<Handle_Geom_Surface> >&, const std::vector<const SurfaceStyle*>&, ConversionResults&);
|
||||
bool fold_layers(const IfcSchema::IfcWall*, const ConversionResults&, const std::vector<Handle_Geom_Surface>&, const std::vector<double>&, std::vector< std::vector<Handle_Geom_Surface> >&);
|
||||
|
||||
bool split_solid_by_surface(const TopoDS_Shape&, const Handle_Geom_Surface&, TopoDS_Shape&, TopoDS_Shape&);
|
||||
bool split_solid_by_shell(const TopoDS_Shape&, const TopoDS_Shape& s, TopoDS_Shape&, TopoDS_Shape&);
|
||||
@@ -326,6 +327,7 @@ public:
|
||||
static double shape_volume(const TopoDS_Shape& s);
|
||||
static double face_area(const TopoDS_Face& f);
|
||||
|
||||
static TopoDS_Shape apply_transformation(const TopoDS_Shape&, const OpenCascadePlacement*);
|
||||
static TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_Trsf&);
|
||||
static TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_GTrsf&);
|
||||
|
||||
@@ -338,12 +340,12 @@ public:
|
||||
std::pair<std::string, double> initializeUnits(IfcSchema::IfcUnitAssignment*);
|
||||
|
||||
template <typename P, typename PP>
|
||||
IfcGeom::BRepElement<P, PP>* create_brep_for_representation_and_product(
|
||||
IfcGeom::NativeElement<P, PP>* create_brep_for_representation_and_product(
|
||||
const IteratorSettings&, IfcSchema::IfcRepresentation*, IfcSchema::IfcProduct*);
|
||||
|
||||
template <typename P, typename PP>
|
||||
IfcGeom::BRepElement<P, PP>* create_brep_for_processed_representation(
|
||||
const IteratorSettings&, IfcSchema::IfcRepresentation*, IfcSchema::IfcProduct*, IfcGeom::BRepElement<P, PP>*);
|
||||
IfcGeom::NativeElement<P, PP>* create_brep_for_processed_representation(
|
||||
const IteratorSettings&, IfcSchema::IfcRepresentation*, IfcSchema::IfcProduct*, IfcGeom::NativeElement<P, PP>*);
|
||||
|
||||
const IfcSchema::IfcMaterial* get_single_material_association(const IfcSchema::IfcProduct*);
|
||||
IfcSchema::IfcRepresentation* representation_mapped_to(const IfcSchema::IfcRepresentation* representation);
|
||||
@@ -416,15 +418,15 @@ public:
|
||||
virtual void setValue(GeomValue var, double value);
|
||||
virtual double getValue(GeomValue var) const;
|
||||
|
||||
virtual IfcGeom::BRepElement<double>* convert(
|
||||
virtual IfcGeom::NativeElement<double>* convert(
|
||||
const IteratorSettings& settings, IfcUtil::IfcBaseClass* representation,
|
||||
IfcUtil::IfcBaseClass* product)
|
||||
{
|
||||
return create_brep_for_representation_and_product<double, double>(settings, (IfcSchema::IfcRepresentation*) representation, (IfcSchema::IfcProduct*) product);
|
||||
}
|
||||
|
||||
virtual IfcRepresentationShapeItems convert(IfcUtil::IfcBaseClass* item) {
|
||||
IfcRepresentationShapeItems items;
|
||||
virtual ConversionResults convert(IfcUtil::IfcBaseClass* item) {
|
||||
ConversionResults items;
|
||||
bool success = convert_shapes(item, items);
|
||||
if (!success) {
|
||||
throw IfcParse::IfcException("Failed to process representation item");
|
||||
|
||||
@@ -507,13 +507,13 @@ const TopoDS_Shape& IfcGeom::Kernel::ensure_fit_for_subtraction(const TopoDS_Sha
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings,
|
||||
const IfcGeom::IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcGeom::IfcRepresentationShapeItems& cut_shapes) {
|
||||
const IfcGeom::ConversionResults& entity_shapes, const gp_Trsf& entity_trsf, IfcGeom::ConversionResults& cut_shapes) {
|
||||
|
||||
// TODO: Refactor convert_openings() convert_openings_fast() and convert(IfcBooleanResult) to use
|
||||
// the same code base and conform to the same checks and logging messages.
|
||||
|
||||
// Iterate over IfcOpeningElements
|
||||
IfcGeom::IfcRepresentationShapeItems opening_shapes;
|
||||
IfcGeom::ConversionResults opening_shapes;
|
||||
unsigned int last_size = 0;
|
||||
for ( IfcSchema::IfcRelVoidsElement::list::it it = openings->begin(); it != openings->end(); ++ it ) {
|
||||
IfcSchema::IfcRelVoidsElement* v = *it;
|
||||
@@ -545,30 +545,26 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
|
||||
|
||||
const unsigned int current_size = (const unsigned int) opening_shapes.size();
|
||||
for ( unsigned int i = last_size; i < current_size; ++ i ) {
|
||||
opening_shapes[i].prepend(opening_trsf);
|
||||
OpenCascadePlacement p((gp_GTrsf)opening_trsf);
|
||||
opening_shapes[i].prepend(&p);
|
||||
}
|
||||
last_size = current_size;
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate over the shapes of the IfcProduct
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) {
|
||||
for ( IfcGeom::ConversionResults::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) {
|
||||
TopoDS_Shape entity_shape_solid;
|
||||
const TopoDS_Shape& entity_shape_unlocated = ensure_fit_for_subtraction(it3->Shape(),entity_shape_solid);
|
||||
const gp_GTrsf& entity_shape_gtrsf = it3->Placement();
|
||||
if ( entity_shape_gtrsf.Form() == gp_Other ) {
|
||||
Logger::Message(Logger::LOG_WARNING, "Applying non uniform transformation to:", entity);
|
||||
}
|
||||
const TopoDS_Shape& entity_shape_unlocated = ensure_fit_for_subtraction(*(OpenCascadeShape*) it3->Shape(), entity_shape_solid);
|
||||
const OpenCascadePlacement* entity_shape_gtrsf = (OpenCascadePlacement*) it3->Placement();
|
||||
|
||||
TopoDS_Shape entity_shape = apply_transformation(entity_shape_unlocated, entity_shape_gtrsf);
|
||||
|
||||
// Iterate over the shapes of the IfcOpeningElements
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it4 = opening_shapes.begin(); it4 != opening_shapes.end(); ++ it4 ) {
|
||||
for ( IfcGeom::ConversionResults::const_iterator it4 = opening_shapes.begin(); it4 != opening_shapes.end(); ++ it4 ) {
|
||||
TopoDS_Shape opening_shape_solid;
|
||||
const TopoDS_Shape& opening_shape_unlocated = ensure_fit_for_subtraction(it4->Shape(),opening_shape_solid);
|
||||
const gp_GTrsf& opening_shape_gtrsf = it4->Placement();
|
||||
if ( opening_shape_gtrsf.Form() == gp_Other ) {
|
||||
Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to opening of:",entity);
|
||||
}
|
||||
const TopoDS_Shape& opening_shape_unlocated = ensure_fit_for_subtraction(*(OpenCascadeShape*) it4->Shape(),opening_shape_solid);
|
||||
const OpenCascadePlacement* opening_shape_gtrsf = (OpenCascadePlacement*)it4->Placement();
|
||||
TopoDS_Shape opening_shape = apply_transformation(opening_shape_unlocated, opening_shape_gtrsf);
|
||||
|
||||
double opening_volume;
|
||||
@@ -673,7 +669,7 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
|
||||
}
|
||||
|
||||
}
|
||||
cut_shapes.push_back(IfcGeom::IfcRepresentationShapeItem(it3->ItemId(), it3->Placement(), entity_shape, &it3->Style()));
|
||||
cut_shapes.push_back(IfcGeom::ConversionResult(it3->ItemId(), it3->Placement()->clone(), new OpenCascadeShape(entity_shape), &it3->Style()));
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -681,7 +677,7 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
|
||||
|
||||
#if OCC_VERSION_HEX < 0x60900
|
||||
bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings,
|
||||
const IfcGeom::IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcGeom::IfcRepresentationShapeItems& cut_shapes) {
|
||||
const IfcGeom::ConversionResults& entity_shapes, const gp_Trsf& entity_trsf, IfcGeom::ConversionResults& cut_shapes) {
|
||||
|
||||
// Create a compound of all opening shapes in order to speed up the boolean operations
|
||||
TopoDS_Compound opening_compound;
|
||||
@@ -712,7 +708,7 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
|
||||
IfcSchema::IfcProductRepresentation* prodrep = fes->Representation();
|
||||
IfcSchema::IfcRepresentation::list::ptr reps = prodrep->Representations();
|
||||
|
||||
IfcGeom::IfcRepresentationShapeItems opening_shapes;
|
||||
IfcGeom::ConversionResults opening_shapes;
|
||||
|
||||
for ( IfcSchema::IfcRepresentation::list::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) {
|
||||
convert_shapes(*it2,opening_shapes);
|
||||
@@ -729,7 +725,7 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
|
||||
}
|
||||
|
||||
// Iterate over the shapes of the IfcProduct
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) {
|
||||
for ( IfcGeom::ConversionResults::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) {
|
||||
TopoDS_Shape entity_shape_solid;
|
||||
const TopoDS_Shape& entity_shape_unlocated = ensure_fit_for_subtraction(it3->Shape(),entity_shape_solid);
|
||||
const gp_GTrsf& entity_shape_gtrsf = it3->Placement();
|
||||
@@ -747,7 +743,7 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
|
||||
BRepCheck_Analyzer analyser(brep_cut_result);
|
||||
is_valid = analyser.IsValid() != 0;
|
||||
if ( is_valid ) {
|
||||
cut_shapes.push_back(IfcGeom::IfcRepresentationShapeItem(it3->ItemId(), brep_cut_result, &it3->Style()));
|
||||
cut_shapes.push_back(IfcGeom::ConversionResult(it3->ItemId(), brep_cut_result, &it3->Style()));
|
||||
}
|
||||
}
|
||||
if ( !is_valid ) {
|
||||
@@ -772,7 +768,7 @@ namespace {
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings,
|
||||
const IfcGeom::IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcGeom::IfcRepresentationShapeItems& cut_shapes) {
|
||||
const IfcGeom::ConversionResults& entity_shapes, const gp_Trsf& entity_trsf, IfcGeom::ConversionResults& cut_shapes) {
|
||||
|
||||
std::vector< std::pair<double, TopoDS_Shape> > opening_vector;
|
||||
|
||||
@@ -800,7 +796,7 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
|
||||
IfcSchema::IfcProductRepresentation* prodrep = fes->Representation();
|
||||
IfcSchema::IfcRepresentation::list::ptr reps = prodrep->Representations();
|
||||
|
||||
IfcGeom::IfcRepresentationShapeItems opening_shapes;
|
||||
IfcGeom::ConversionResults opening_shapes;
|
||||
|
||||
for (IfcSchema::IfcRepresentation::list::it it2 = reps->begin(); it2 != reps->end(); ++it2) {
|
||||
convert_shapes(*it2, opening_shapes);
|
||||
@@ -808,9 +804,12 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
|
||||
|
||||
for (unsigned int i = 0; i < opening_shapes.size(); ++i) {
|
||||
TopoDS_Shape opening_shape_solid;
|
||||
const TopoDS_Shape& opening_shape_unlocated = ensure_fit_for_subtraction(opening_shapes[i].Shape(), opening_shape_solid);
|
||||
const TopoDS_Shape& opening_shape_unlocated = ensure_fit_for_subtraction(*(OpenCascadeShape*)opening_shapes[i].Shape(), opening_shape_solid);
|
||||
|
||||
gp_GTrsf gtrsf = opening_shapes[i].Placement();
|
||||
gp_GTrsf gtrsf;
|
||||
if (opening_shapes[i].Placement()) {
|
||||
gtrsf = ((OpenCascadePlacement*)opening_shapes[i].Placement())->trsf();
|
||||
}
|
||||
gtrsf.PreMultiply(opening_trsf);
|
||||
TopoDS_Shape opening_shape = apply_transformation(opening_shape_unlocated, gtrsf);
|
||||
opening_vector.push_back(std::make_pair(min_edge_length(opening_shape), opening_shape));
|
||||
@@ -822,13 +821,10 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
|
||||
std::sort(opening_vector.begin(), opening_vector.end(), opening_sorter());
|
||||
|
||||
// Iterate over the shapes of the IfcProduct
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) {
|
||||
for ( IfcGeom::ConversionResults::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) {
|
||||
TopoDS_Shape entity_shape_solid;
|
||||
const TopoDS_Shape& entity_shape_unlocated = ensure_fit_for_subtraction(it3->Shape(),entity_shape_solid);
|
||||
const gp_GTrsf& entity_shape_gtrsf = it3->Placement();
|
||||
if (entity_shape_gtrsf.Form() == gp_Other) {
|
||||
Logger::Message(Logger::LOG_WARNING, "Applying non uniform transformation to:", entity);
|
||||
}
|
||||
const TopoDS_Shape& entity_shape_unlocated = ensure_fit_for_subtraction(*(OpenCascadeShape*) it3->Shape(),entity_shape_solid);
|
||||
const OpenCascadePlacement* entity_shape_gtrsf = (OpenCascadePlacement*)it3->Placement();
|
||||
TopoDS_Shape entity_shape = apply_transformation(entity_shape_unlocated, entity_shape_gtrsf);
|
||||
|
||||
TopoDS_Shape result = entity_shape;
|
||||
@@ -859,7 +855,7 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
|
||||
}
|
||||
}
|
||||
|
||||
cut_shapes.push_back(IfcGeom::IfcRepresentationShapeItem(it3->ItemId(), result, &it3->Style()));
|
||||
cut_shapes.push_back(IfcGeom::ConversionResult(it3->ItemId(), new OpenCascadeShape(result), &it3->Style()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1263,22 +1259,22 @@ bool IfcGeom::Kernel::fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& sha
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::flatten_shape_list(const IfcGeom::IfcRepresentationShapeItems& shapes, TopoDS_Shape& result, bool fuse) {
|
||||
bool IfcGeom::Kernel::flatten_shape_list(const IfcGeom::ConversionResults& shapes, TopoDS_Shape& result, bool fuse) {
|
||||
TopoDS_Compound compound;
|
||||
BRep_Builder builder;
|
||||
builder.MakeCompound(compound);
|
||||
|
||||
result = TopoDS_Shape();
|
||||
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
||||
for ( IfcGeom::ConversionResults::const_iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
||||
TopoDS_Shape merged;
|
||||
const TopoDS_Shape& s = it->Shape();
|
||||
const TopoDS_Shape& s = *(OpenCascadeShape*)it->Shape();
|
||||
if (fuse) {
|
||||
ensure_fit_for_subtraction(s, merged);
|
||||
} else {
|
||||
merged = s;
|
||||
}
|
||||
const gp_GTrsf& trsf = it->Placement();
|
||||
const OpenCascadePlacement* trsf = (const OpenCascadePlacement*) it->Placement();
|
||||
const TopoDS_Shape moved_shape = apply_transformation(merged, trsf);
|
||||
|
||||
if (shapes.size() == 1) {
|
||||
@@ -1463,7 +1459,7 @@ const IfcSchema::IfcMaterial* IfcGeom::Kernel::get_single_material_association(c
|
||||
}
|
||||
|
||||
template <typename P, typename PP>
|
||||
IfcGeom::BRepElement<P, PP>* IfcGeom::Kernel::create_brep_for_representation_and_product(
|
||||
IfcGeom::NativeElement<P, PP>* IfcGeom::Kernel::create_brep_for_representation_and_product(
|
||||
const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product)
|
||||
{
|
||||
std::stringstream representation_id_builder;
|
||||
@@ -1471,7 +1467,7 @@ IfcGeom::BRepElement<P, PP>* IfcGeom::Kernel::create_brep_for_representation_and
|
||||
representation_id_builder << representation->data().id();
|
||||
|
||||
IfcGeom::Representation::BRep* shape;
|
||||
IfcGeom::IfcRepresentationShapeItems shapes, shapes2;
|
||||
IfcGeom::ConversionResults shapes, shapes2;
|
||||
|
||||
if ( !convert_shapes(representation, shapes) ) {
|
||||
return 0;
|
||||
@@ -1526,7 +1522,7 @@ IfcGeom::BRepElement<P, PP>* IfcGeom::Kernel::create_brep_for_representation_and
|
||||
const IfcSchema::IfcMaterial* single_material = get_single_material_association(product);
|
||||
if (single_material) {
|
||||
const IfcGeom::SurfaceStyle* s = get_style(single_material);
|
||||
for (IfcGeom::IfcRepresentationShapeItems::iterator it = shapes.begin(); it != shapes.end(); ++it) {
|
||||
for (IfcGeom::ConversionResults::iterator it = shapes.begin(); it != shapes.end(); ++it) {
|
||||
if (!it->hasStyle() && s) {
|
||||
it->setStyle(s);
|
||||
material_style_applied = true;
|
||||
@@ -1534,7 +1530,7 @@ IfcGeom::BRepElement<P, PP>* IfcGeom::Kernel::create_brep_for_representation_and
|
||||
}
|
||||
} else {
|
||||
bool some_items_without_style = false;
|
||||
for (IfcGeom::IfcRepresentationShapeItems::iterator it = shapes.begin(); it != shapes.end(); ++it) {
|
||||
for (IfcGeom::ConversionResults::iterator it = shapes.begin(); it != shapes.end(); ++it) {
|
||||
if (!it->hasStyle()) {
|
||||
some_items_without_style = true;
|
||||
break;
|
||||
@@ -1584,7 +1580,7 @@ IfcGeom::BRepElement<P, PP>* IfcGeom::Kernel::create_brep_for_representation_and
|
||||
representation_id_builder << "-" << (*it)->data().id();
|
||||
}
|
||||
|
||||
IfcGeom::IfcRepresentationShapeItems opened_shapes;
|
||||
IfcGeom::ConversionResults opened_shapes;
|
||||
bool caught_error = false;
|
||||
try {
|
||||
#if OCC_VERSION_HEX < 0x60900
|
||||
@@ -1617,16 +1613,18 @@ IfcGeom::BRepElement<P, PP>* IfcGeom::Kernel::create_brep_for_representation_and
|
||||
}
|
||||
|
||||
if (settings.get(IteratorSettings::USE_WORLD_COORDS)) {
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::iterator it = opened_shapes.begin(); it != opened_shapes.end(); ++ it ) {
|
||||
it->prepend(trsf);
|
||||
for ( IfcGeom::ConversionResults::iterator it = opened_shapes.begin(); it != opened_shapes.end(); ++ it ) {
|
||||
OpenCascadePlacement p(trsf);
|
||||
it->prepend(&p);
|
||||
}
|
||||
trsf = gp_Trsf();
|
||||
representation_id_builder << "-world-coords";
|
||||
}
|
||||
shape = new IfcGeom::Representation::BRep(element_settings, representation_id_builder.str(), opened_shapes);
|
||||
} else if (settings.get(IteratorSettings::USE_WORLD_COORDS)) {
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
||||
it->prepend(trsf);
|
||||
for ( IfcGeom::ConversionResults::iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
||||
OpenCascadePlacement p(trsf);
|
||||
it->prepend(&p);
|
||||
}
|
||||
trsf = gp_Trsf();
|
||||
representation_id_builder << "-world-coords";
|
||||
@@ -1642,14 +1640,14 @@ IfcGeom::BRepElement<P, PP>* IfcGeom::Kernel::create_brep_for_representation_and
|
||||
context_string = representation->ContextOfItems()->ContextType();
|
||||
}
|
||||
|
||||
auto elem = new BRepElement<P, PP>(
|
||||
auto elem = new NativeElement<P, PP>(
|
||||
product->data().id(),
|
||||
parent_id,
|
||||
name,
|
||||
product_type,
|
||||
guid,
|
||||
context_string,
|
||||
trsf,
|
||||
new OpenCascadePlacement(trsf),
|
||||
boost::shared_ptr<IfcGeom::Representation::BRep>(shape),
|
||||
product
|
||||
);
|
||||
@@ -1703,7 +1701,7 @@ IfcGeom::BRepElement<P, PP>* IfcGeom::Kernel::create_brep_for_representation_and
|
||||
int genus = q2->as<IfcSchema::IfcQuantityCount>()->CountValue();
|
||||
for (auto& part : elem->geometry()) {
|
||||
if (part.ItemId() == item_id) {
|
||||
if (surface_genus(part.Shape()) != genus) {
|
||||
if (surface_genus(*(OpenCascadeShape*)part.Shape()) != genus) {
|
||||
all_succeeded = false;
|
||||
}
|
||||
}
|
||||
@@ -1792,9 +1790,9 @@ IfcSchema::IfcProduct::list::ptr IfcGeom::Kernel::products_represented_by(const
|
||||
}
|
||||
|
||||
template <typename P, typename PP>
|
||||
IfcGeom::BRepElement<P, PP>* IfcGeom::Kernel::create_brep_for_processed_representation(
|
||||
IfcGeom::NativeElement<P, PP>* IfcGeom::Kernel::create_brep_for_processed_representation(
|
||||
const IteratorSettings& /*settings*/, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product,
|
||||
IfcGeom::BRepElement<P, PP>* brep)
|
||||
IfcGeom::NativeElement<P, PP>* brep)
|
||||
{
|
||||
int parent_id = -1;
|
||||
try {
|
||||
@@ -1827,32 +1825,32 @@ IfcGeom::BRepElement<P, PP>* IfcGeom::Kernel::create_brep_for_processed_represen
|
||||
|
||||
const std::string product_type = product->declaration().name();
|
||||
|
||||
return new BRepElement<P, PP>(
|
||||
return new NativeElement<P, PP>(
|
||||
product->data().id(),
|
||||
parent_id,
|
||||
name,
|
||||
product_type,
|
||||
guid,
|
||||
context_string,
|
||||
trsf,
|
||||
new OpenCascadePlacement(trsf),
|
||||
brep->geometry_pointer(),
|
||||
product
|
||||
);
|
||||
}
|
||||
|
||||
template IFC_GEOM_API IfcGeom::BRepElement<float, float>* IfcGeom::Kernel::create_brep_for_representation_and_product<float, float>(
|
||||
template IFC_GEOM_API IfcGeom::NativeElement<float, float>* IfcGeom::Kernel::create_brep_for_representation_and_product<float, float>(
|
||||
const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product);
|
||||
template IFC_GEOM_API IfcGeom::BRepElement<float, double>* IfcGeom::Kernel::create_brep_for_representation_and_product<float, double>(
|
||||
template IFC_GEOM_API IfcGeom::NativeElement<float, double>* IfcGeom::Kernel::create_brep_for_representation_and_product<float, double>(
|
||||
const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product);
|
||||
template IFC_GEOM_API IfcGeom::BRepElement<double, double>* IfcGeom::Kernel::create_brep_for_representation_and_product<double, double>(
|
||||
template IFC_GEOM_API IfcGeom::NativeElement<double, double>* IfcGeom::Kernel::create_brep_for_representation_and_product<double, double>(
|
||||
const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product);
|
||||
|
||||
template IFC_GEOM_API IfcGeom::BRepElement<float, float>* IfcGeom::Kernel::create_brep_for_processed_representation<float, float>(
|
||||
const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product, IfcGeom::BRepElement<float, float>* brep);
|
||||
template IFC_GEOM_API IfcGeom::BRepElement<float, double>* IfcGeom::Kernel::create_brep_for_processed_representation<float, double>(
|
||||
const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product, IfcGeom::BRepElement<float, double>* brep);
|
||||
template IFC_GEOM_API IfcGeom::BRepElement<double, double>* IfcGeom::Kernel::create_brep_for_processed_representation<double, double>(
|
||||
const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product, IfcGeom::BRepElement<double, double>* brep);
|
||||
template IFC_GEOM_API IfcGeom::NativeElement<float, float>* IfcGeom::Kernel::create_brep_for_processed_representation<float, float>(
|
||||
const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product, IfcGeom::NativeElement<float, float>* brep);
|
||||
template IFC_GEOM_API IfcGeom::NativeElement<float, double>* IfcGeom::Kernel::create_brep_for_processed_representation<float, double>(
|
||||
const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product, IfcGeom::NativeElement<float, double>* brep);
|
||||
template IFC_GEOM_API IfcGeom::NativeElement<double, double>* IfcGeom::Kernel::create_brep_for_processed_representation<double, double>(
|
||||
const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product, IfcGeom::NativeElement<double, double>* brep);
|
||||
|
||||
std::pair<std::string, double> IfcGeom::Kernel::initializeUnits(IfcSchema::IfcUnitAssignment* unit_assignment) {
|
||||
// Set default units, set length to meters, angles to undefined
|
||||
@@ -1952,7 +1950,7 @@ bool IfcGeom::Kernel::convert_layerset(const IfcSchema::IfcProduct* product, std
|
||||
return false;
|
||||
}
|
||||
|
||||
IfcRepresentationShapeItems axis_items;
|
||||
ConversionResults axis_items;
|
||||
{
|
||||
Kernel temp = *this;
|
||||
temp.setValue(GV_DIMENSIONALITY, -1.);
|
||||
@@ -2144,7 +2142,7 @@ bool IfcGeom::Kernel::find_wall_end_points(const IfcSchema::IfcWall* wall, gp_Pn
|
||||
return false;
|
||||
}
|
||||
|
||||
IfcRepresentationShapeItems items;
|
||||
ConversionResults items;
|
||||
{
|
||||
Kernel temp = *this;
|
||||
temp.setValue(GV_DIMENSIONALITY, -1.);
|
||||
@@ -2152,8 +2150,8 @@ bool IfcGeom::Kernel::find_wall_end_points(const IfcSchema::IfcWall* wall, gp_Pn
|
||||
}
|
||||
|
||||
TopoDS_Vertex a, b;
|
||||
for (IfcRepresentationShapeItems::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
TopExp_Explorer exp(it->Shape(), TopAbs_VERTEX);
|
||||
for (ConversionResults::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
TopExp_Explorer exp(*(OpenCascadeShape*)it->Shape(), TopAbs_VERTEX);
|
||||
for (; exp.More(); exp.Next()) {
|
||||
b = TopoDS::Vertex(exp.Current());
|
||||
if (a.IsNull()) {
|
||||
@@ -2172,7 +2170,7 @@ bool IfcGeom::Kernel::find_wall_end_points(const IfcSchema::IfcWall* wall, gp_Pn
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepresentationShapeItems& items, const std::vector<Handle_Geom_Surface>& surfaces, const std::vector<double>& thicknesses, std::vector< std::vector<Handle_Geom_Surface> >& result) {
|
||||
bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const ConversionResults& items, const std::vector<Handle_Geom_Surface>& surfaces, const std::vector<double>& thicknesses, std::vector< std::vector<Handle_Geom_Surface> >& result) {
|
||||
bool folds_made = false;
|
||||
|
||||
IfcSchema::IfcRelConnectsPathElements::list::ptr connections(new IfcSchema::IfcRelConnectsPathElements::list);
|
||||
@@ -2321,7 +2319,7 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre
|
||||
continue;
|
||||
}
|
||||
|
||||
IfcRepresentationShapeItems axis_items;
|
||||
ConversionResults axis_items;
|
||||
{
|
||||
Kernel temp = *this;
|
||||
temp.setValue(GV_DIMENSIONALITY, -1.);
|
||||
@@ -2605,7 +2603,7 @@ namespace {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::apply_folded_layerset(const IfcRepresentationShapeItems& items, const std::vector< std::vector<Handle_Geom_Surface> >& surfaces, const std::vector<const SurfaceStyle*>& styles, IfcRepresentationShapeItems& result) {
|
||||
bool IfcGeom::Kernel::apply_folded_layerset(const ConversionResults& items, const std::vector< std::vector<Handle_Geom_Surface> >& surfaces, const std::vector<const SurfaceStyle*>& styles, ConversionResults& result) {
|
||||
Bnd_Box bb;
|
||||
TopoDS_Shape input;
|
||||
flatten_shape_list(items, input, false);
|
||||
@@ -2681,11 +2679,11 @@ bool IfcGeom::Kernel::apply_folded_layerset(const IfcRepresentationShapeItems& i
|
||||
|
||||
} else if (shells.Extent() == 1) {
|
||||
|
||||
for (IfcRepresentationShapeItems::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
for (ConversionResults::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
TopoDS_Shape a,b;
|
||||
if (split_solid_by_shell(it->Shape(), shells.First(), a, b)) {
|
||||
result.push_back(IfcRepresentationShapeItem(it->ItemId(), it->Placement(), b, styles[0] ? styles[0] : &it->Style()));
|
||||
result.push_back(IfcRepresentationShapeItem(it->ItemId(), it->Placement(), a, styles[1] ? styles[1] : &it->Style()));
|
||||
if (split_solid_by_shell(*(OpenCascadeShape*)it->Shape(), shells.First(), a, b)) {
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement()->clone(), new OpenCascadeShape(b), styles[0] ? styles[0] : &it->Style()));
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement()->clone(), new OpenCascadeShape(a), styles[1] ? styles[1] : &it->Style()));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
@@ -2695,16 +2693,16 @@ bool IfcGeom::Kernel::apply_folded_layerset(const IfcRepresentationShapeItems& i
|
||||
|
||||
} else {
|
||||
|
||||
for (IfcRepresentationShapeItems::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
for (ConversionResults::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
|
||||
const TopoDS_Shape& s = it->Shape();
|
||||
const TopoDS_Shape& s = *(OpenCascadeShape*)it->Shape();
|
||||
TopoDS_Solid sld;
|
||||
ensure_fit_for_subtraction(s, sld);
|
||||
|
||||
std::vector<TopoDS_Shape> slices;
|
||||
if (split(*this, it->Shape(), shells, getValue(GV_PRECISION), slices) && slices.size() == styles.size()) {
|
||||
if (split(*this, *(OpenCascadeShape*)it->Shape(), shells, getValue(GV_PRECISION), slices) && slices.size() == styles.size()) {
|
||||
for (size_t i = 0; i < slices.size(); ++i) {
|
||||
result.push_back(IfcRepresentationShapeItem(it->ItemId(), it->Placement(), slices[i], styles[i] ? styles[i] : &it->Style()));
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement()->clone(), new OpenCascadeShape(slices[i]), styles[i] ? styles[i] : &it->Style()));
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
@@ -2717,18 +2715,18 @@ bool IfcGeom::Kernel::apply_folded_layerset(const IfcRepresentationShapeItems& i
|
||||
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::apply_layerset(const IfcRepresentationShapeItems& items, const std::vector<Handle_Geom_Surface>& surfaces, const std::vector<const SurfaceStyle*>& styles, IfcRepresentationShapeItems& result) {
|
||||
bool IfcGeom::Kernel::apply_layerset(const ConversionResults& items, const std::vector<Handle_Geom_Surface>& surfaces, const std::vector<const SurfaceStyle*>& styles, ConversionResults& result) {
|
||||
if (surfaces.size() < 3) {
|
||||
|
||||
return false;
|
||||
|
||||
} else if (surfaces.size() == 3) {
|
||||
|
||||
for (IfcRepresentationShapeItems::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
for (ConversionResults::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
TopoDS_Shape a,b;
|
||||
if (split_solid_by_surface(it->Shape(), surfaces[1], a, b)) {
|
||||
result.push_back(IfcRepresentationShapeItem(it->ItemId(), it->Placement(), b, styles[0] ? styles[0] : &it->Style()));
|
||||
result.push_back(IfcRepresentationShapeItem(it->ItemId(), it->Placement(), a, styles[1] ? styles[1] : &it->Style()));
|
||||
if (split_solid_by_surface(*(OpenCascadeShape*)it->Shape(), surfaces[1], a, b)) {
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement()->clone(), new OpenCascadeShape(b), styles[0] ? styles[0] : &it->Style()));
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement()->clone(), new OpenCascadeShape(a), styles[1] ? styles[1] : &it->Style()));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
@@ -2742,7 +2740,7 @@ bool IfcGeom::Kernel::apply_layerset(const IfcRepresentationShapeItems& items, c
|
||||
// Determine whether sequence of surfaces is consistent with surface normal, so that
|
||||
// layer operations are applied in the correct order. This seems to be always the case.
|
||||
Bnd_Box bb;
|
||||
for (IfcRepresentationShapeItems::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
for (ConversionResults::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
BRepBndLib::Add(it->Shape(), bb);
|
||||
}
|
||||
|
||||
@@ -2767,9 +2765,9 @@ bool IfcGeom::Kernel::apply_layerset(const IfcRepresentationShapeItems& items, c
|
||||
mass.ChangeCoord() += n1.XYZ();
|
||||
*/
|
||||
|
||||
for (IfcRepresentationShapeItems::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
for (ConversionResults::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
|
||||
const TopoDS_Shape& s = it->Shape();
|
||||
const TopoDS_Shape& s = *(OpenCascadeShape*)it->Shape();
|
||||
TopoDS_Solid sld;
|
||||
ensure_fit_for_subtraction(s, sld);
|
||||
|
||||
@@ -2786,9 +2784,9 @@ bool IfcGeom::Kernel::apply_layerset(const IfcRepresentationShapeItems& items, c
|
||||
}
|
||||
|
||||
std::vector<TopoDS_Shape> slices;
|
||||
if (split(*this, it->Shape(), operands, getValue(GV_PRECISION), slices) && slices.size() == styles.size()) {
|
||||
if (split(*this, *(OpenCascadeShape*)it->Shape(), operands, getValue(GV_PRECISION), slices) && slices.size() == styles.size()) {
|
||||
for (size_t i = 0; i < slices.size(); ++i) {
|
||||
result.push_back(IfcRepresentationShapeItem(it->ItemId(), it->Placement(), slices[i], styles[i] ? styles[i] : &it->Style()));
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement()->clone(), new OpenCascadeShape(slices[i]), styles[i] ? styles[i] : &it->Style()));
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
@@ -3201,28 +3199,32 @@ bool IfcGeom::Kernel::triangulate_wire(const TopoDS_Wire& wire, TopTools_ListOfS
|
||||
return true;
|
||||
}
|
||||
|
||||
TopoDS_Shape IfcGeom::Kernel::apply_transformation(const TopoDS_Shape& s, const gp_Trsf& t) {
|
||||
if (t.Form() == gp_Identity) {
|
||||
TopoDS_Shape IfcGeom::Kernel::apply_transformation(const TopoDS_Shape& s, const OpenCascadePlacement* t) {
|
||||
if (t == nullptr) {
|
||||
return s;
|
||||
} else {
|
||||
/// @todo set to 1. and exactly 1. or use epsilon?
|
||||
if (t.ScaleFactor() != 1.) {
|
||||
return BRepBuilderAPI_Transform(s, t, true);
|
||||
} else {
|
||||
return s.Moved(t);
|
||||
}
|
||||
return apply_transformation(s, t->trsf());
|
||||
}
|
||||
}
|
||||
|
||||
TopoDS_Shape IfcGeom::Kernel::apply_transformation(const TopoDS_Shape& s, const gp_GTrsf& t) {
|
||||
if (t.Form() == gp_Other) {
|
||||
Logger::Message(Logger::LOG_WARNING, "Applying non uniform transformation");
|
||||
return BRepBuilderAPI_GTransform(s, t, true);
|
||||
} else {
|
||||
|
||||
return apply_transformation(s, t.Trsf());
|
||||
}
|
||||
}
|
||||
|
||||
TopoDS_Shape IfcGeom::Kernel::apply_transformation(const TopoDS_Shape& s, const gp_Trsf& t) {
|
||||
/// @todo set to 1. and exactly 1. or use epsilon?
|
||||
if (t.ScaleFactor() != 1.) {
|
||||
return BRepBuilderAPI_Transform(s, t, true);
|
||||
} else {
|
||||
return s.Moved(t);
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/*
|
||||
|
||||
@@ -76,10 +76,10 @@
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
#include "../ifcgeom/IfcGeomElement.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomElement.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomMaterial.h"
|
||||
#include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||
#include "../ifcgeom/IfcRepresentationShapeItem.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomIteratorSettings.h"
|
||||
#include "../ifcgeom_schema_agnostic/ConversionResult.h"
|
||||
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomFilter.h"
|
||||
#include "../ifcgeom_schema_agnostic/IteratorImplementation.h"
|
||||
@@ -112,7 +112,7 @@ namespace IfcGeom {
|
||||
|
||||
// The object is fetched beforehand to be sure that get() returns a valid element
|
||||
TriangulationElement<P, PP>* current_triangulation;
|
||||
BRepElement<P, PP>* current_shape_model;
|
||||
NativeElement<P, PP>* current_shape_model;
|
||||
SerializedElement<P, PP>* current_serialization;
|
||||
|
||||
// A container and iterator for IfcBuildingElements for the current IfcRepresentation referenced by *representation_iterator
|
||||
@@ -403,7 +403,7 @@ namespace IfcGeom {
|
||||
return associated_single_materials.size() == 1;
|
||||
}
|
||||
|
||||
BRepElement<P, PP>* create_shape_model_for_next_entity() {
|
||||
NativeElement<P, PP>* create_shape_model_for_next_entity() {
|
||||
for (;;) {
|
||||
IfcSchema::IfcRepresentation* representation;
|
||||
|
||||
@@ -474,7 +474,7 @@ namespace IfcGeom {
|
||||
IfcSchema::IfcProduct* product = *ifcproduct_iterator;
|
||||
Logger::SetProduct(product);
|
||||
|
||||
BRepElement<P, PP>* element;
|
||||
NativeElement<P, PP>* element;
|
||||
if (ifcproduct_iterator == ifcproducts->begin() || !geometry_reuse_ok_for_current_representation_) {
|
||||
element = kernel.create_brep_for_representation_and_product<P, PP>(settings, representation, product);
|
||||
} else {
|
||||
@@ -588,7 +588,7 @@ namespace IfcGeom {
|
||||
}
|
||||
|
||||
/// Gets the native (Open Cascade) representation of the current geometrical entity.
|
||||
BRepElement<P, PP>* get_native()
|
||||
NativeElement<P, PP>* get_native()
|
||||
{
|
||||
// TODO: Test settings and throw
|
||||
return current_shape_model;
|
||||
@@ -646,12 +646,12 @@ namespace IfcGeom {
|
||||
|
||||
ElementSettings element_settings(settings, unit_magnitude, instance_type);
|
||||
|
||||
Element<P, PP>* ifc_object = new Element<P, PP>(element_settings, id, parent_id, product_name, instance_type, product_guid, "", trsf, ifc_product);
|
||||
Element<P, PP>* ifc_object = new Element<P, PP>(element_settings, id, parent_id, product_name, instance_type, product_guid, "", new OpenCascadePlacement(trsf), ifc_product);
|
||||
return ifc_object;
|
||||
}
|
||||
|
||||
IfcUtil::IfcBaseClass* create() {
|
||||
IfcGeom::BRepElement<P, PP>* next_shape_model = 0;
|
||||
IfcGeom::NativeElement<P, PP>* next_shape_model = 0;
|
||||
IfcGeom::SerializedElement<P, PP>* next_serialization = 0;
|
||||
IfcGeom::TriangulationElement<P, PP>* next_triangulation = 0;
|
||||
|
||||
|
||||
@@ -366,7 +366,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcRevolvedAreaSolid* l, TopoDS_S
|
||||
return !shape.IsNull();
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcManifoldSolidBrep* l, IfcRepresentationShapeItems& shape) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcManifoldSolidBrep* l, ConversionResults& shape) {
|
||||
TopoDS_Shape s;
|
||||
const SurfaceStyle* collective_style = get_style(l);
|
||||
if (convert_shape(l->Outer(),s) ) {
|
||||
@@ -391,13 +391,13 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcManifoldSolidBrep* l, IfcRepre
|
||||
}
|
||||
}
|
||||
|
||||
shape.push_back(IfcRepresentationShapeItem(l->data().id(), s, indiv_style ? indiv_style : collective_style));
|
||||
shape.push_back(ConversionResult(l->data().id(), new OpenCascadeShape(s), indiv_style ? indiv_style : collective_style));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcFaceBasedSurfaceModel* l, IfcRepresentationShapeItems& shapes) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcFaceBasedSurfaceModel* l, ConversionResults& shapes) {
|
||||
bool part_success = false;
|
||||
IfcSchema::IfcConnectedFaceSet::list::ptr facesets = l->FbsmFaces();
|
||||
const SurfaceStyle* collective_style = get_style(l);
|
||||
@@ -405,7 +405,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcFaceBasedSurfaceModel* l, IfcR
|
||||
TopoDS_Shape s;
|
||||
const SurfaceStyle* shell_style = get_style(*it);
|
||||
if (convert_shape(*it,s)) {
|
||||
shapes.push_back(IfcRepresentationShapeItem(l->data().id(), s, shell_style ? shell_style : collective_style));
|
||||
shapes.push_back(ConversionResult(l->data().id(), new OpenCascadeShape(s), shell_style ? shell_style : collective_style));
|
||||
part_success |= true;
|
||||
}
|
||||
}
|
||||
@@ -459,7 +459,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcPolygonalBoundedHalfSpace* l,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcShellBasedSurfaceModel* l, IfcRepresentationShapeItems& shapes) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcShellBasedSurfaceModel* l, ConversionResults& shapes) {
|
||||
IfcEntityList::ptr shells = l->SbsmBoundary();
|
||||
const SurfaceStyle* collective_style = get_style(l);
|
||||
for( IfcEntityList::it it = shells->begin(); it != shells->end(); ++ it ) {
|
||||
@@ -469,7 +469,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcShellBasedSurfaceModel* l, Ifc
|
||||
shell_style = get_style((IfcSchema::IfcRepresentationItem*)*it);
|
||||
}
|
||||
if (convert_shape(*it,s)) {
|
||||
shapes.push_back(IfcRepresentationShapeItem(l->data().id(), s, shell_style ? shell_style : collective_style));
|
||||
shapes.push_back(ConversionResult(l->data().id(), new OpenCascadeShape(s), shell_style ? shell_style : collective_style));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -478,7 +478,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcShellBasedSurfaceModel* l, Ifc
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape& shape) {
|
||||
|
||||
TopoDS_Shape s1, s2;
|
||||
IfcRepresentationShapeItems items1, items2;
|
||||
ConversionResults items1, items2;
|
||||
TopoDS_Wire boundary_wire;
|
||||
IfcSchema::IfcBooleanOperand* operand1 = l->FirstOperand();
|
||||
IfcSchema::IfcBooleanOperand* operand2 = l->SecondOperand();
|
||||
@@ -664,7 +664,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcConnectedFaceSet* l, TopoDS_Sh
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcMappedItem* l, IfcRepresentationShapeItems& shapes) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcMappedItem* l, ConversionResults& shapes) {
|
||||
gp_GTrsf gtrsf;
|
||||
IfcSchema::IfcCartesianTransformationOperator* transform = l->MappingTarget();
|
||||
if ( transform->declaration().is(IfcSchema::IfcCartesianTransformationOperator3DnonUniform::Class()) ) {
|
||||
@@ -699,7 +699,8 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcMappedItem* l, IfcRepresentati
|
||||
bool b = convert_shapes(map->MappedRepresentation(), shapes);
|
||||
|
||||
for (size_t i = previous_size; i < shapes.size(); ++ i ) {
|
||||
shapes[i].prepend(gtrsf);
|
||||
OpenCascadePlacement p(gtrsf);
|
||||
shapes[i].prepend(&p);
|
||||
|
||||
// Apply styles assigned to the mapped item only if on
|
||||
// a more granular level no styles have been applied
|
||||
@@ -711,7 +712,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcMappedItem* l, IfcRepresentati
|
||||
return b;
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcRepresentation* l, IfcRepresentationShapeItems& shapes) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcRepresentation* l, ConversionResults& shapes) {
|
||||
IfcSchema::IfcRepresentationItem::list::ptr items = l->Items();
|
||||
bool part_succes = false;
|
||||
if ( items->size() ) {
|
||||
@@ -722,7 +723,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcRepresentation* l, IfcRepresen
|
||||
} else {
|
||||
TopoDS_Shape s;
|
||||
if (convert_shape(representation_item,s)) {
|
||||
shapes.push_back(IfcRepresentationShapeItem(representation_item->data().id(), s, get_style(representation_item)));
|
||||
shapes.push_back(ConversionResult(representation_item->data().id(), new OpenCascadeShape(s), get_style(representation_item)));
|
||||
part_succes |= true;
|
||||
}
|
||||
}
|
||||
@@ -731,7 +732,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcRepresentation* l, IfcRepresen
|
||||
return part_succes;
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcGeometricSet* l, IfcRepresentationShapeItems& shapes) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcGeometricSet* l, ConversionResults& shapes) {
|
||||
IfcEntityList::ptr elements = l->Elements();
|
||||
if ( !elements->size() ) return false;
|
||||
bool part_succes = false;
|
||||
@@ -749,7 +750,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcGeometricSet* l, IfcRepresenta
|
||||
} else if (element->declaration().is(IfcSchema::IfcSurface::Class())) {
|
||||
style = get_style((IfcSchema::IfcSurface*) element);
|
||||
}
|
||||
shapes.push_back(IfcRepresentationShapeItem(l->data().id(), s, style ? style : parent_style));
|
||||
shapes.push_back(ConversionResult(l->data().id(), new OpenCascadeShape(s), style ? style : parent_style));
|
||||
}
|
||||
}
|
||||
return part_succes;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#define IFCGEOMTREE_H
|
||||
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
#include "../ifcgeom/IfcGeomElement.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomElement.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomIterator.h"
|
||||
#include "../ifcgeom_schema_agnostic/Kernel.h"
|
||||
|
||||
@@ -267,7 +267,7 @@ namespace IfcGeom {
|
||||
|
||||
if (it.initialize()) {
|
||||
do {
|
||||
IfcGeom::BRepElement<double>* elem = (IfcGeom::BRepElement<double>*)it.get();
|
||||
IfcGeom::NativeElement<double>* elem = (IfcGeom::NativeElement<double>*)it.get();
|
||||
add((IfcUtil::IfcBaseEntity*)f.instance_by_id(elem->id()), elem->geometry().as_compound());
|
||||
} while (it.next());
|
||||
}
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
|
||||
using namespace IfcUtil;
|
||||
|
||||
bool IfcGeom::Kernel::convert_shapes(const IfcBaseClass* l, IfcRepresentationShapeItems& r) {
|
||||
bool IfcGeom::Kernel::convert_shapes(const IfcBaseClass* l, ConversionResults& r) {
|
||||
if (shape_type(l) != ST_SHAPELIST) {
|
||||
TopoDS_Shape shp;
|
||||
if (convert_shape(l, shp)) {
|
||||
r.push_back(IfcGeom::IfcRepresentationShapeItem(l->data().id(), shp, get_style(l->as<IfcSchema::IfcRepresentationItem>())));
|
||||
r.push_back(IfcGeom::ConversionResult(l->data().id(), new OpenCascadeShape(shp), get_style(l->as<IfcSchema::IfcRepresentationItem>())));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -61,7 +61,7 @@ bool IfcGeom::Kernel::convert_shape(const IfcBaseClass* l, TopoDS_Shape& r) {
|
||||
ignored = (!include_solids_and_surfaces && (st == ST_SHAPE || st == ST_FACE)) || (!include_curves && (st == ST_WIRE || st == ST_CURVE));
|
||||
if (st == ST_SHAPELIST) {
|
||||
processed = true;
|
||||
IfcRepresentationShapeItems items;
|
||||
ConversionResults items;
|
||||
success = convert_shapes(l, items) && flatten_shape_list(items, r, false);
|
||||
} else if (st == ST_SHAPE && include_solids_and_surfaces) {
|
||||
#include "IfcRegisterConvertShape.h"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "IfcRegisterUndef.h"
|
||||
#define CLASS(T,V) bool convert(const IfcSchema::T* L, V& r);
|
||||
#define SHAPES(T) CLASS(T,IfcRepresentationShapeItems)
|
||||
#define SHAPES(T) CLASS(T,ConversionResults)
|
||||
#define SHAPE(T) CLASS(T,TopoDS_Shape)
|
||||
#define WIRE(T) CLASS(T,TopoDS_Wire)
|
||||
#define FACE(T) CLASS(T,TopoDS_Shape)
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCSHAPELIST_H
|
||||
#define IFCSHAPELIST_H
|
||||
|
||||
#include <gp_GTrsf.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomRenderStyles.h"
|
||||
|
||||
namespace IfcGeom {
|
||||
class IFC_GEOM_API IfcRepresentationShapeItem {
|
||||
private:
|
||||
int id;
|
||||
gp_GTrsf placement;
|
||||
TopoDS_Shape shape;
|
||||
const SurfaceStyle* style;
|
||||
public:
|
||||
IfcRepresentationShapeItem(int id, const gp_GTrsf& placement, const TopoDS_Shape& shape, const SurfaceStyle* style)
|
||||
: id(id), placement(placement), shape(shape), style(style) {}
|
||||
IfcRepresentationShapeItem(int id, const gp_GTrsf& placement, const TopoDS_Shape& shape)
|
||||
: id(id), placement(placement), shape(shape), style(0) {}
|
||||
IfcRepresentationShapeItem(int id, const TopoDS_Shape& shape, const SurfaceStyle* style)
|
||||
: id(id), shape(shape), style(style) {}
|
||||
IfcRepresentationShapeItem(int id, const TopoDS_Shape& shape)
|
||||
: id(id), shape(shape), style(0) {}
|
||||
void append(const gp_GTrsf& trsf) { placement.Multiply(trsf); }
|
||||
void prepend(const gp_GTrsf& trsf) { placement.PreMultiply(trsf); }
|
||||
const TopoDS_Shape& Shape() const { return shape; }
|
||||
const gp_GTrsf& Placement() const { return placement; }
|
||||
bool hasStyle() const { return style != 0; }
|
||||
const SurfaceStyle& Style() const { return *style; }
|
||||
void setStyle(const SurfaceStyle* style) { this->style = style; }
|
||||
int ItemId() const { return id; }
|
||||
};
|
||||
typedef std::vector<IfcRepresentationShapeItem> IfcRepresentationShapeItems;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,104 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCGEOMOPENCASCADEREPRESENTATION_H
|
||||
#define IFCGEOMOPENCASCADEREPRESENTATION_H
|
||||
|
||||
#include <BRepMesh_IncrementalMesh.hxx>
|
||||
#include <BRepGProp_Face.hxx>
|
||||
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
|
||||
#include <gp_GTrsf.hxx>
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
#include <GCPnts_QuasiUniformDeflection.hxx>
|
||||
|
||||
#include "../ifcgeom_schema_agnostic/ConversionResult.h"
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
class OpenCascadePlacement : public ConversionResultPlacement {
|
||||
public:
|
||||
OpenCascadePlacement(const gp_GTrsf& trsf)
|
||||
: trsf_(trsf) {}
|
||||
|
||||
const gp_GTrsf& trsf() const { return trsf_; }
|
||||
operator const gp_GTrsf& () { return trsf_; }
|
||||
|
||||
virtual double Value(int i, int j) const {
|
||||
return trsf_.Value(i, j);
|
||||
}
|
||||
|
||||
virtual void Multiply(const ConversionResultPlacement* other) {
|
||||
trsf_.Multiply(((OpenCascadePlacement*)other)->trsf_);
|
||||
}
|
||||
|
||||
virtual void PreMultiply(const ConversionResultPlacement* other) {
|
||||
trsf_.PreMultiply(((OpenCascadePlacement*)other)->trsf_);
|
||||
}
|
||||
|
||||
virtual ConversionResultPlacement* clone() const {
|
||||
return new OpenCascadePlacement(trsf_);
|
||||
}
|
||||
|
||||
virtual ConversionResultPlacement* inverted() const {
|
||||
return new OpenCascadePlacement(trsf_.Inverted());
|
||||
}
|
||||
|
||||
virtual ConversionResultPlacement* multiplied(const ConversionResultPlacement* other) const {
|
||||
return new OpenCascadePlacement(trsf_.Multiplied(((OpenCascadePlacement*)other)->trsf_));
|
||||
}
|
||||
private:
|
||||
gp_GTrsf trsf_;
|
||||
};
|
||||
|
||||
class OpenCascadeShape : public ConversionResultShape {
|
||||
public:
|
||||
OpenCascadeShape(const TopoDS_Shape& shape)
|
||||
: shape_(shape)
|
||||
{}
|
||||
|
||||
const TopoDS_Shape& shape() const { return shape_; }
|
||||
operator const TopoDS_Shape& () { return shape_; }
|
||||
|
||||
virtual void Triangulate(const IfcGeom::IteratorSettings & settings, const IfcGeom::ConversionResultPlacement * place, IfcGeom::Representation::Triangulation<float>* t, int surface_style_id) const;
|
||||
|
||||
virtual void Triangulate(const IfcGeom::IteratorSettings & settings, const IfcGeom::ConversionResultPlacement * place, IfcGeom::Representation::Triangulation<double>* t, int surface_style_id) const;
|
||||
|
||||
virtual void Serialize(std::string&) const {
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
virtual ConversionResultShape* clone() const {
|
||||
return new OpenCascadeShape(shape_);
|
||||
}
|
||||
|
||||
virtual int surface_genus() const;
|
||||
private:
|
||||
TopoDS_Shape shape_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,202 @@
|
||||
#include "OpenCascadeConversionResult.h"
|
||||
|
||||
#include "../ifcparse/IfcLogger.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomRepresentation.h"
|
||||
|
||||
#include "IfcGeom.h"
|
||||
|
||||
#include <TopoDS.hxx>
|
||||
|
||||
#include <map>
|
||||
|
||||
template <typename Precision>
|
||||
void triangulate_helper(const TopoDS_Shape& s, const IfcGeom::IteratorSettings& settings, const IfcGeom::ConversionResultPlacement* place, IfcGeom::Representation::Triangulation<Precision>* t, int surface_style_id) {
|
||||
|
||||
gp_GTrsf trsf;
|
||||
if (place) {
|
||||
trsf = dynamic_cast<const IfcGeom::OpenCascadePlacement*>(place)->trsf();
|
||||
}
|
||||
|
||||
// Triangulate the shape
|
||||
try {
|
||||
BRepMesh_IncrementalMesh(s, settings.deflection_tolerance());
|
||||
} catch (...) {
|
||||
|
||||
// TODO: Catch outside
|
||||
// Logger::Message(Logger::LOG_ERROR,"Failed to triangulate shape:",ifc_file->entityById(_id)->entity);
|
||||
Logger::Message(Logger::LOG_ERROR, "Failed to triangulate shape");
|
||||
return;
|
||||
}
|
||||
|
||||
// Iterates over the faces of the shape
|
||||
int num_faces = 0;
|
||||
TopExp_Explorer exp;
|
||||
for (exp.Init(s, TopAbs_FACE); exp.More(); exp.Next(), ++num_faces) {
|
||||
TopoDS_Face face = TopoDS::Face(exp.Current());
|
||||
TopLoc_Location loc;
|
||||
Handle_Poly_Triangulation tri = BRep_Tool::Triangulation(face, loc);
|
||||
|
||||
if (!tri.IsNull()) {
|
||||
|
||||
// A 3x3 matrix to rotate the vertex normals
|
||||
const gp_Mat rotation_matrix = trsf.VectorialPart();
|
||||
|
||||
// Keep track of the number of times an edge is used
|
||||
// Manifold edges (i.e. edges used twice) are deemed invisible
|
||||
std::map<std::pair<int, int>, int> edgecount;
|
||||
std::vector<std::pair<int, int> > edges_temp;
|
||||
|
||||
const TColgp_Array1OfPnt& nodes = tri->Nodes();
|
||||
const TColgp_Array1OfPnt2d& uvs = tri->UVNodes();
|
||||
std::vector<gp_XYZ> coords;
|
||||
BRepGProp_Face prop(face);
|
||||
std::map<int, int> dict;
|
||||
|
||||
// Vertex normals are only calculated if vertices are not welded and calculation is not disable explicitly.
|
||||
const bool calculate_normals = !settings.get(IfcGeom::IteratorSettings::WELD_VERTICES) &&
|
||||
!settings.get(IfcGeom::IteratorSettings::NO_NORMALS);
|
||||
|
||||
for (int i = 1; i <= nodes.Length(); ++i) {
|
||||
coords.push_back(nodes(i).Transformed(loc).XYZ());
|
||||
trsf.Transforms(*coords.rbegin());
|
||||
const gp_XYZ& last = *coords.rbegin();
|
||||
dict[i] = t->addVertex(surface_style_id, last.X(), last.Y(), last.Z());
|
||||
|
||||
if (calculate_normals) {
|
||||
const gp_Pnt2d& uv = uvs(i);
|
||||
gp_Pnt p;
|
||||
gp_Vec normal_direction;
|
||||
prop.Normal(uv.X(), uv.Y(), p, normal_direction);
|
||||
gp_Vec normal(0., 0., 0.);
|
||||
if (normal_direction.Magnitude() > 1.e-9) {
|
||||
normal = gp_Dir(normal_direction.XYZ() * rotation_matrix);
|
||||
}
|
||||
t->addNormal(normal.X(), normal.Y(), normal.Z());
|
||||
}
|
||||
}
|
||||
|
||||
const Poly_Array1OfTriangle& triangles = tri->Triangles();
|
||||
for (int i = 1; i <= triangles.Length(); ++i) {
|
||||
int n1, n2, n3;
|
||||
if (face.Orientation() == TopAbs_REVERSED)
|
||||
triangles(i).Get(n3, n2, n1);
|
||||
else triangles(i).Get(n1, n2, n3);
|
||||
|
||||
/* An alternative would be to calculate normals based
|
||||
* on the coordinates of the mesh vertices */
|
||||
/*
|
||||
const gp_XYZ pt1 = coords[n1-1];
|
||||
const gp_XYZ pt2 = coords[n2-1];
|
||||
const gp_XYZ pt3 = coords[n3-1];
|
||||
const gp_XYZ v1 = pt2-pt1;
|
||||
const gp_XYZ v2 = pt3-pt2;
|
||||
gp_Dir normal = gp_Dir(v1^v2);
|
||||
_normals.push_back((float)normal.X());
|
||||
_normals.push_back((float)normal.Y());
|
||||
_normals.push_back((float)normal.Z());
|
||||
*/
|
||||
|
||||
t->addFace(surface_style_id, dict[n1], dict[n2], dict[n3]);
|
||||
|
||||
t->addEdge(dict[n1], dict[n2], edgecount, edges_temp);
|
||||
t->addEdge(dict[n2], dict[n3], edgecount, edges_temp);
|
||||
t->addEdge(dict[n3], dict[n1], edgecount, edges_temp);
|
||||
}
|
||||
for (std::vector<std::pair<int, int> >::const_iterator jt = edges_temp.begin(); jt != edges_temp.end(); ++jt) {
|
||||
if (edgecount[*jt] == 1) {
|
||||
// non manifold edge, face boundary
|
||||
t->registerEdge(jt->first, jt->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: Unimplemented
|
||||
if (!t.normals().empty() && settings().get(IfcGeom::IteratorSettings::GENERATE_UVS)) {
|
||||
t.uvs() = box_project_uvs(t.verts(), t.normals());
|
||||
}
|
||||
|
||||
if (num_faces == 0) {
|
||||
// Edges are only emitted if there are no faces. A mixed representation of faces
|
||||
// and loose edges is discouraged by the standard. An alternative would be to use
|
||||
// TopExp_Explorer texp(s, TopAbs_EDGE, TopAbs_FACE) to find edges that do not
|
||||
// belong to any face.
|
||||
for (TopExp_Explorer texp(s, TopAbs_EDGE); texp.More(); texp.Next()) {
|
||||
BRepAdaptor_Curve crv(TopoDS::Edge(texp.Current()));
|
||||
GCPnts_QuasiUniformDeflection tessellater(crv, settings.deflection_tolerance());
|
||||
int n = tessellater.NbPoints();
|
||||
int start = (int)t->verts().size() / 3;
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
gp_XYZ p = tessellater.Value(i).XYZ();
|
||||
|
||||
// // In case you want direction arrows on your edges
|
||||
// double u = tessellater.Parameter(i);
|
||||
// gp_XYZ p2, p3;
|
||||
// gp_Pnt tmp;
|
||||
// gp_Vec tmp2;
|
||||
// crv.D1(u, tmp, tmp2);
|
||||
// gp_Dir d1, d2, d3, d4;
|
||||
// d1 = tmp2;
|
||||
// if (texp.Current().Orientation() == TopAbs_REVERSED) {
|
||||
// d1 = -d1;
|
||||
// }
|
||||
// if (fabs(d1.Z()) < 0.5) {
|
||||
// d2 = d1.Crossed(gp::DZ());
|
||||
// } else {
|
||||
// d2 = d1.Crossed(gp::DY());
|
||||
// }
|
||||
// d3 = d1.XYZ() + d2.XYZ();
|
||||
// d4 = d1.XYZ() - d2.XYZ();
|
||||
// p2 = p - d3.XYZ() / 10.;
|
||||
// p3 = p - d4.XYZ() / 10.;
|
||||
// trsf.Transforms(p2);
|
||||
// trsf.Transforms(p3);
|
||||
// _material_ids.push_back(surface_style_id);
|
||||
// _material_ids.push_back(surface_style_id);
|
||||
// _verts.push_back(static_cast<P>(p2.X()));
|
||||
// _verts.push_back(static_cast<P>(p2.Y()));
|
||||
// _verts.push_back(static_cast<P>(p2.Z()));
|
||||
// _verts.push_back(static_cast<P>(p3.X()));
|
||||
// _verts.push_back(static_cast<P>(p3.Y()));
|
||||
// _verts.push_back(static_cast<P>(p3.Z()));
|
||||
|
||||
trsf.Transforms(p);
|
||||
|
||||
t->material_ids().push_back(surface_style_id);
|
||||
|
||||
t->verts().push_back(static_cast<double>(p.X()));
|
||||
t->verts().push_back(static_cast<double>(p.Y()));
|
||||
t->verts().push_back(static_cast<double>(p.Z()));
|
||||
|
||||
if (i > 1) {
|
||||
t->edges().push_back(start + i - 2);
|
||||
t->edges().push_back(start + i - 1);
|
||||
// _edges.push_back(start + 3 * (i - 2) + 2);
|
||||
// _edges.push_back(start + 3 * (i - 1) + 2);
|
||||
}
|
||||
|
||||
// _edges.push_back(start + 3 * (i - 1) + 0);
|
||||
// _edges.push_back(start + 3 * (i - 1) + 2);
|
||||
// _edges.push_back(start + 3 * (i - 1) + 1);
|
||||
// _edges.push_back(start + 3 * (i - 1) + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
BRepTools::Clean(s);
|
||||
}
|
||||
|
||||
void IfcGeom::OpenCascadeShape::Triangulate(const IfcGeom::IteratorSettings & settings, const IfcGeom::ConversionResultPlacement * place, IfcGeom::Representation::Triangulation<float>* t, int surface_style_id) const {
|
||||
triangulate_helper(shape_, settings, place, t, surface_style_id);
|
||||
}
|
||||
|
||||
void IfcGeom::OpenCascadeShape::Triangulate(const IfcGeom::IteratorSettings & settings, const IfcGeom::ConversionResultPlacement * place, IfcGeom::Representation::Triangulation<double>* t, int surface_style_id) const {
|
||||
triangulate_helper(shape_, settings, place, t, surface_style_id);
|
||||
}
|
||||
|
||||
int IfcGeom::OpenCascadeShape::surface_genus() const {
|
||||
return IfcGeom::Kernel::surface_genus(shape_);
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCSHAPELIST_H
|
||||
#define IFCSHAPELIST_H
|
||||
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomRenderStyles.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomIteratorSettings.h"
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
namespace Representation {
|
||||
template <typename P>
|
||||
class IFC_GEOM_API Triangulation;
|
||||
}
|
||||
|
||||
class IFC_GEOM_API ConversionResultPlacement {
|
||||
public:
|
||||
virtual void Multiply(const ConversionResultPlacement*) = 0;
|
||||
virtual void PreMultiply(const ConversionResultPlacement*) = 0;
|
||||
virtual ConversionResultPlacement* inverted() const = 0;
|
||||
virtual ConversionResultPlacement* multiplied(const ConversionResultPlacement*) const = 0;
|
||||
virtual double Value(int i, int j) const = 0;
|
||||
virtual ConversionResultPlacement* clone() const = 0;
|
||||
virtual ~ConversionResultPlacement() {}
|
||||
};
|
||||
|
||||
class IFC_GEOM_API ConversionResultShape {
|
||||
public:
|
||||
virtual void Triangulate(const IfcGeom::IteratorSettings & settings, const IfcGeom::ConversionResultPlacement* place, IfcGeom::Representation::Triangulation<float>* t, int surface_style_id) const = 0;
|
||||
virtual void Triangulate(const IfcGeom::IteratorSettings & settings, const IfcGeom::ConversionResultPlacement* place, IfcGeom::Representation::Triangulation<double>* t, int surface_style_id) const = 0;
|
||||
virtual void Serialize(std::string&) const = 0;
|
||||
virtual ConversionResultShape* clone() const = 0;
|
||||
virtual int surface_genus() const = 0;
|
||||
virtual ~ConversionResultShape() {}
|
||||
};
|
||||
|
||||
class IFC_GEOM_API ConversionResult {
|
||||
private:
|
||||
int id;
|
||||
ConversionResultPlacement* placement;
|
||||
ConversionResultShape* shape;
|
||||
const SurfaceStyle* style;
|
||||
public:
|
||||
ConversionResult(int id, const ConversionResultPlacement* placement, const ConversionResultShape* shape, const SurfaceStyle* style)
|
||||
: id(id), placement(placement->clone()), shape(shape->clone()), style(style) {}
|
||||
ConversionResult(int id, const ConversionResultPlacement* placement, const ConversionResultShape* shape)
|
||||
: id(id), placement(placement->clone()), shape(shape->clone()), style(0) {}
|
||||
ConversionResult(int id, const ConversionResultShape* shape, const SurfaceStyle* style)
|
||||
: id(id), placement(0), shape(shape->clone()), style(style) {}
|
||||
ConversionResult(int id, const ConversionResultShape* shape)
|
||||
: id(id), placement(0), shape(shape->clone()), style(0) {}
|
||||
void append(const ConversionResultPlacement* trsf) {
|
||||
if (placement == 0) {
|
||||
placement = trsf->clone();
|
||||
} else {
|
||||
placement->Multiply(trsf);
|
||||
}
|
||||
}
|
||||
void prepend(const ConversionResultPlacement* trsf) {
|
||||
if (placement == 0) {
|
||||
placement = trsf->clone();
|
||||
} else {
|
||||
placement->PreMultiply(trsf);
|
||||
}
|
||||
}
|
||||
const ConversionResultShape* Shape() const { return shape; }
|
||||
const ConversionResultPlacement* Placement() const { return placement; }
|
||||
bool hasStyle() const { return style != 0; }
|
||||
const SurfaceStyle& Style() const { return *style; }
|
||||
void setStyle(const SurfaceStyle* style) { this->style = style; }
|
||||
int ItemId() const { return id; }
|
||||
};
|
||||
|
||||
typedef std::vector<ConversionResult> ConversionResults;
|
||||
}
|
||||
#endif
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
#include "../ifcparse/IfcGlobalId.h"
|
||||
|
||||
#include "../ifcgeom/IfcGeomRepresentation.h"
|
||||
#include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomRepresentation.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomIteratorSettings.h"
|
||||
#include "ifc_geom_api.h"
|
||||
|
||||
namespace IfcGeom {
|
||||
@@ -36,7 +36,7 @@ namespace IfcGeom {
|
||||
private:
|
||||
std::vector<P> _data;
|
||||
public:
|
||||
Matrix(const ElementSettings& settings, const gp_Trsf& trsf) {
|
||||
Matrix(const ElementSettings& settings, const ConversionResultPlacement* trsf) {
|
||||
// Convert the gp_Trsf into a 4x3 Matrix
|
||||
// Note that in case the CONVERT_BACK_UNITS setting is enabled
|
||||
// the translation component of the matrix needs to be divided
|
||||
@@ -44,7 +44,7 @@ namespace IfcGeom {
|
||||
// internally in IfcOpenShell everything is measured in meters.
|
||||
for(int i = 1; i < 5; ++i) {
|
||||
for (int j = 1; j < 4; ++j) {
|
||||
const double trsf_value = trsf.Value(j,i);
|
||||
const double trsf_value = trsf->Value(j,i);
|
||||
const double matrix_value = i == 4 && settings.get(IteratorSettings::CONVERT_BACK_UNITS)
|
||||
? trsf_value / settings.unit_magnitude()
|
||||
: trsf_value;
|
||||
@@ -59,23 +59,23 @@ namespace IfcGeom {
|
||||
class Transformation {
|
||||
private:
|
||||
ElementSettings settings_;
|
||||
gp_Trsf trsf_;
|
||||
ConversionResultPlacement* trsf_;
|
||||
Matrix<P> matrix_;
|
||||
public:
|
||||
Transformation(const ElementSettings& settings, const gp_Trsf& trsf)
|
||||
Transformation(const ElementSettings& settings, const ConversionResultPlacement* trsf)
|
||||
: settings_(settings)
|
||||
, trsf_(trsf)
|
||||
, trsf_(trsf->clone())
|
||||
, matrix_(settings, trsf)
|
||||
{}
|
||||
const gp_Trsf& data() const { return trsf_; }
|
||||
const ConversionResultPlacement* data() const { return trsf_; }
|
||||
const Matrix<P>& matrix() const { return matrix_; }
|
||||
|
||||
Transformation inverted() const {
|
||||
return Transformation(settings_, trsf_.Inverted());
|
||||
return Transformation(settings_, trsf_->inverted());
|
||||
}
|
||||
|
||||
Transformation multiplied(const Transformation& other) const {
|
||||
return Transformation(settings_, trsf_.Multiplied(other.data()));
|
||||
return Transformation(settings_, trsf_->multiplied(other.data()));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -129,7 +129,7 @@ namespace IfcGeom {
|
||||
void SetParents(std::vector<const IfcGeom::Element<P, PP>*> 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::IfcBaseEntity* product)
|
||||
const std::string& guid, const std::string& context, const ConversionResultPlacement* trsf, IfcUtil::IfcBaseEntity* product)
|
||||
: _id(id), _parent_id(parent_id), _name(name), _type(type), _guid(guid), _context(context), _transformation(settings, trsf)
|
||||
, product_(product)
|
||||
{
|
||||
@@ -159,28 +159,25 @@ namespace IfcGeom {
|
||||
};
|
||||
|
||||
template <typename P = double, typename PP = P>
|
||||
class BRepElement : public Element<P, PP> {
|
||||
class NativeElement : public Element<P, PP> {
|
||||
private:
|
||||
boost::shared_ptr<Representation::BRep> _geometry;
|
||||
public:
|
||||
const boost::shared_ptr<Representation::BRep>& geometry_pointer() const { return _geometry; }
|
||||
const Representation::BRep& geometry() const { return *_geometry; }
|
||||
BRepElement(int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid,
|
||||
const std::string& context, const gp_Trsf& trsf, const boost::shared_ptr<Representation::BRep>& geometry,
|
||||
NativeElement(int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid,
|
||||
const std::string& context, const ConversionResultPlacement* trsf, const boost::shared_ptr<Representation::BRep>& geometry,
|
||||
IfcUtil::IfcBaseEntity* product)
|
||||
: Element<P, PP>(geometry->settings() ,id, parent_id, name, type, guid, context, trsf, product)
|
||||
, _geometry(geometry)
|
||||
{}
|
||||
|
||||
bool calculate_projected_surface_area(double& along_x, double& along_y, double& along_z) const {
|
||||
const auto& trsf = this->transformation().data();
|
||||
const gp_Mat& mat = trsf.HVectorialPart();
|
||||
gp_Ax3 ax(trsf.TranslationPart(), mat.Column(3), mat.Column(1));
|
||||
return geometry().calculate_projected_surface_area(ax, along_x, along_y, along_z);
|
||||
return geometry().calculate_projected_surface_area(this->transformation().data(), along_x, along_y, along_z);
|
||||
}
|
||||
private:
|
||||
BRepElement(const BRepElement& other);
|
||||
BRepElement& operator=(const BRepElement& other);
|
||||
NativeElement(const NativeElement& other);
|
||||
NativeElement& operator=(const NativeElement& other);
|
||||
};
|
||||
|
||||
template <typename P = double, typename PP = P>
|
||||
@@ -190,7 +187,7 @@ namespace IfcGeom {
|
||||
public:
|
||||
const Representation::Triangulation<P>& geometry() const { return *_geometry; }
|
||||
const boost::shared_ptr< Representation::Triangulation<P> >& geometry_pointer() const { return _geometry; }
|
||||
TriangulationElement(const BRepElement<P, PP>& shape_model)
|
||||
TriangulationElement(const NativeElement<P, PP>& shape_model)
|
||||
: Element<P, PP>(shape_model)
|
||||
, _geometry(boost::shared_ptr<Representation::Triangulation<P> >(new Representation::Triangulation<P>(shape_model.geometry())))
|
||||
{}
|
||||
@@ -209,7 +206,7 @@ namespace IfcGeom {
|
||||
Representation::Serialization* _geometry;
|
||||
public:
|
||||
const Representation::Serialization& geometry() const { return *_geometry; }
|
||||
SerializedElement(const BRepElement<P, PP>& shape_model)
|
||||
SerializedElement(const NativeElement<P, PP>& shape_model)
|
||||
: Element<P, PP>(shape_model)
|
||||
, _geometry(new Representation::Serialization(shape_model.geometry()))
|
||||
{}
|
||||
@@ -119,7 +119,7 @@ namespace IfcGeom {
|
||||
|
||||
Element<P, PP>* get() { return implementation_->get(); }
|
||||
|
||||
BRepElement<P, PP>* get_native() { return implementation_->get_native(); }
|
||||
NativeElement<P, PP>* get_native() { return implementation_->get_native(); }
|
||||
|
||||
const Element<P, PP>* get_object(int id) { return implementation_->get_object(id); }
|
||||
|
||||
|
||||
+1
@@ -23,6 +23,7 @@
|
||||
#include "ifc_geom_api.h"
|
||||
#include "../ifcparse/IfcException.h"
|
||||
#include "../ifcparse/IfcBaseClass.h"
|
||||
#include "../ifcparse/IfcLogger.h"
|
||||
|
||||
namespace IfcGeom
|
||||
{
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef IFCGEOMRENDERSTYLES_H
|
||||
#define IFCGEOMRENDERSTYLES_H
|
||||
|
||||
#include "../ifcgeom/ifc_geom_api.h"
|
||||
#include "../ifcgeom_schema_agnostic/ifc_geom_api.h"
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
|
||||
+25
-17
@@ -26,16 +26,16 @@
|
||||
#include <GProp_GProps.hxx>
|
||||
#include <BRepGProp.hxx>
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
|
||||
#include "IfcGeomRepresentation.h"
|
||||
#include "../ifcgeom/OpenCascadeConversionResult.h"
|
||||
#include "../ifcgeom_schema_agnostic/Kernel.h"
|
||||
|
||||
IfcGeom::Representation::Serialization::Serialization(const BRep& brep)
|
||||
: Representation(brep.settings())
|
||||
, id_(brep.id())
|
||||
{
|
||||
TopoDS_Compound compound = brep.as_compound();
|
||||
for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = brep.begin(); it != brep.end(); ++ it) {
|
||||
for (IfcGeom::ConversionResults::const_iterator it = brep.begin(); it != brep.end(); ++ it) {
|
||||
if (it->hasStyle() && it->Style().Diffuse()) {
|
||||
const IfcGeom::SurfaceStyle::ColorComponent& clr = *it->Style().Diffuse();
|
||||
surface_styles_.push_back(clr.R());
|
||||
@@ -57,7 +57,7 @@ IfcGeom::Representation::Serialization::Serialization(const BRep& brep)
|
||||
brep_data_ = sstream.str();
|
||||
}
|
||||
|
||||
// todo copied from kernel
|
||||
// @todo copied from kernel
|
||||
#include <BRepBuilderAPI_Transform.hxx>
|
||||
#include <BRepBuilderAPI_GTransform.hxx>
|
||||
|
||||
@@ -86,9 +86,13 @@ TopoDS_Compound IfcGeom::Representation::BRep::as_compound() const {
|
||||
TopoDS_Compound compound;
|
||||
BRep_Builder builder;
|
||||
builder.MakeCompound(compound);
|
||||
for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = begin(); it != end(); ++it) {
|
||||
const TopoDS_Shape& s = it->Shape();
|
||||
gp_GTrsf trsf = it->Placement();
|
||||
|
||||
for (IfcGeom::ConversionResults::const_iterator it = begin(); it != end(); ++it) {
|
||||
const TopoDS_Shape& s = *(OpenCascadeShape*) it->Shape();
|
||||
gp_GTrsf trsf;
|
||||
if (it->Placement()) {
|
||||
trsf = ((OpenCascadePlacement*)it->Placement())->trsf();
|
||||
}
|
||||
|
||||
if (settings().get(IteratorSettings::CONVERT_BACK_UNITS)) {
|
||||
gp_Trsf scale;
|
||||
@@ -166,7 +170,7 @@ namespace {
|
||||
const gp_Vec v2 = pt3 - pt2;
|
||||
const gp_Vec v3 = pt1 - pt3;
|
||||
const gp_Vec normal_vector = v1 ^ v2;
|
||||
if (normal_vector.Magnitude() > ALMOST_ZERO) {
|
||||
if (normal_vector.Magnitude() > 1.e-9) {
|
||||
gp_Dir normal = gp_Dir();
|
||||
|
||||
double edge_lengths[3] = { v1.Magnitude(), v2.Magnitude(), v3.Magnitude() };
|
||||
@@ -190,9 +194,9 @@ bool IfcGeom::Representation::BRep::calculate_surface_area(double& area) const {
|
||||
try {
|
||||
area = 0.;
|
||||
|
||||
for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = begin(); it != end(); ++it) {
|
||||
for (IfcGeom::ConversionResults::const_iterator it = begin(); it != end(); ++it) {
|
||||
GProp_GProps prop;
|
||||
BRepGProp::SurfaceProperties(it->Shape(), prop);
|
||||
BRepGProp::SurfaceProperties(*(OpenCascadeShape*)it->Shape(), prop);
|
||||
area += prop.Mass();
|
||||
}
|
||||
|
||||
@@ -207,10 +211,10 @@ bool IfcGeom::Representation::BRep::calculate_volume(double& volume) const {
|
||||
try {
|
||||
volume = 0.;
|
||||
|
||||
for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = begin(); it != end(); ++it) {
|
||||
if (Kernel::is_manifold(it->Shape())) {
|
||||
for (IfcGeom::ConversionResults::const_iterator it = begin(); it != end(); ++it) {
|
||||
if (Kernel::is_manifold(*(OpenCascadeShape*)it->Shape())) {
|
||||
GProp_GProps prop;
|
||||
BRepGProp::VolumeProperties(it->Shape(), prop);
|
||||
BRepGProp::VolumeProperties(*(OpenCascadeShape*)it->Shape(), prop);
|
||||
volume += prop.Mass();
|
||||
} else {
|
||||
return false;
|
||||
@@ -224,15 +228,19 @@ bool IfcGeom::Representation::BRep::calculate_volume(double& volume) const {
|
||||
}
|
||||
}
|
||||
|
||||
bool IfcGeom::Representation::BRep::calculate_projected_surface_area(const gp_Ax3 & ax, double & along_x, double & along_y, double & along_z) const {
|
||||
bool IfcGeom::Representation::BRep::calculate_projected_surface_area(const ConversionResultPlacement* place, double & along_x, double & along_y, double & along_z) const {
|
||||
try {
|
||||
gp_Trsf trsf = ((OpenCascadePlacement*)place)->trsf().Trsf();
|
||||
gp_Mat mat = trsf.HVectorialPart();
|
||||
gp_Ax3 ax(trsf.TranslationPart(), mat.Column(3), mat.Column(1));
|
||||
|
||||
along_x = along_y = along_z = 0.;
|
||||
|
||||
for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = begin(); it != end(); ++it) {
|
||||
for (IfcGeom::ConversionResults::const_iterator it = begin(); it != end(); ++it) {
|
||||
double x, y, z;
|
||||
surface_area_along_direction(settings().deflection_tolerance(), it->Shape(), ax, x, y, z);
|
||||
surface_area_along_direction(settings().deflection_tolerance(), *(OpenCascadeShape*)it->Shape(), ax, x, y, z);
|
||||
|
||||
if (Kernel::is_manifold(it->Shape())) {
|
||||
if (Kernel::is_manifold(*(OpenCascadeShape*)it->Shape())) {
|
||||
x /= 2.;
|
||||
y /= 2.;
|
||||
z /= 2.;
|
||||
+40
-200
@@ -35,12 +35,14 @@
|
||||
#include <GCPnts_QuasiUniformDeflection.hxx>
|
||||
#include <Geom_SphericalSurface.hxx>
|
||||
|
||||
#include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomIteratorSettings.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomMaterial.h"
|
||||
#include "../ifcgeom/IfcRepresentationShapeItem.h"
|
||||
#include "../ifcgeom_schema_agnostic/ConversionResult.h"
|
||||
|
||||
#include <TopoDS_Compound.hxx>
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
namespace Representation {
|
||||
@@ -61,25 +63,25 @@ namespace IfcGeom {
|
||||
class IFC_GEOM_API BRep : public Representation {
|
||||
private:
|
||||
std::string id_;
|
||||
const IfcGeom::IfcRepresentationShapeItems shapes_;
|
||||
const IfcGeom::ConversionResults shapes_;
|
||||
BRep(const BRep& other);
|
||||
BRep& operator=(const BRep& other);
|
||||
public:
|
||||
BRep(const ElementSettings& settings, const std::string& id, const IfcGeom::IfcRepresentationShapeItems& shapes)
|
||||
BRep(const ElementSettings& settings, const std::string& id, const IfcGeom::ConversionResults& shapes)
|
||||
: Representation(settings)
|
||||
, id_(id)
|
||||
, shapes_(shapes)
|
||||
{}
|
||||
virtual ~BRep() {}
|
||||
IfcGeom::IfcRepresentationShapeItems::const_iterator begin() const { return shapes_.begin(); }
|
||||
IfcGeom::IfcRepresentationShapeItems::const_iterator end() const { return shapes_.end(); }
|
||||
const IfcGeom::IfcRepresentationShapeItems& shapes() const { return shapes_; }
|
||||
IfcGeom::ConversionResults::const_iterator begin() const { return shapes_.begin(); }
|
||||
IfcGeom::ConversionResults::const_iterator end() const { return shapes_.end(); }
|
||||
const IfcGeom::ConversionResults& shapes() const { return shapes_; }
|
||||
const std::string& id() const { return id_; }
|
||||
TopoDS_Compound as_compound() const;
|
||||
|
||||
bool calculate_volume(double&) const;
|
||||
bool calculate_surface_area(double&) const;
|
||||
bool calculate_projected_surface_area(const gp_Ax3& ax, double& along_x, double& along_y, double& along_z) const;
|
||||
bool calculate_projected_surface_area(const ConversionResultPlacement* ax, double& along_x, double& along_y, double& along_z) const;
|
||||
};
|
||||
|
||||
class IFC_GEOM_API Serialization : public Representation {
|
||||
@@ -133,7 +135,7 @@ namespace IfcGeom {
|
||||
: Representation(shape_model.settings())
|
||||
, id_(shape_model.id())
|
||||
{
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator iit = shape_model.begin(); iit != shape_model.end(); ++ iit ) {
|
||||
for ( IfcGeom::ConversionResults::const_iterator iit = shape_model.begin(); iit != shape_model.end(); ++ iit ) {
|
||||
|
||||
int surface_style_id = -1;
|
||||
if (iit->hasStyle()) {
|
||||
@@ -158,192 +160,7 @@ namespace IfcGeom {
|
||||
}
|
||||
}
|
||||
|
||||
const TopoDS_Shape& s = iit->Shape();
|
||||
const gp_GTrsf& trsf = iit->Placement();
|
||||
|
||||
// Triangulate the shape
|
||||
try {
|
||||
BRepMesh_IncrementalMesh(s, settings().deflection_tolerance());
|
||||
} catch(...) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Failed to triangulate shape");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Iterates over the faces of the shape
|
||||
int num_faces = 0;
|
||||
TopExp_Explorer exp;
|
||||
for ( exp.Init(s,TopAbs_FACE); exp.More(); exp.Next(), ++num_faces ) {
|
||||
TopoDS_Face face = TopoDS::Face(exp.Current());
|
||||
TopLoc_Location loc;
|
||||
Handle_Poly_Triangulation tri = BRep_Tool::Triangulation(face,loc);
|
||||
|
||||
if ( ! tri.IsNull() ) {
|
||||
|
||||
// A 3x3 matrix to rotate the vertex normals
|
||||
const gp_Mat rotation_matrix = trsf.VectorialPart();
|
||||
|
||||
// Keep track of the number of times an edge is used
|
||||
// Manifold edges (i.e. edges used twice) are deemed invisible
|
||||
std::map<std::pair<int,int>,int> edgecount;
|
||||
std::vector<std::pair<int,int> > edges_temp;
|
||||
|
||||
const TColgp_Array1OfPnt& nodes = tri->Nodes();
|
||||
const TColgp_Array1OfPnt2d& uvs = tri->UVNodes();
|
||||
std::vector<gp_XYZ> coords;
|
||||
BRepGProp_Face prop(face);
|
||||
std::map<int,int> dict;
|
||||
|
||||
// Vertex normals are only calculated if vertices are not welded and calculation is not disable explicitly.
|
||||
const bool calculate_normals = !settings().get(IteratorSettings::WELD_VERTICES) &&
|
||||
!settings().get(IteratorSettings::NO_NORMALS);
|
||||
|
||||
for( int i = 1; i <= nodes.Length(); ++ i ) {
|
||||
coords.push_back(nodes(i).Transformed(loc).XYZ());
|
||||
trsf.Transforms(*coords.rbegin());
|
||||
dict[i] = addVertex(surface_style_id, *coords.rbegin());
|
||||
|
||||
if ( calculate_normals ) {
|
||||
const gp_Pnt2d& uv = uvs(i);
|
||||
gp_Pnt p;
|
||||
gp_Vec normal_direction;
|
||||
prop.Normal(uv.X(),uv.Y(),p,normal_direction);
|
||||
gp_Vec normal(0., 0., 0.);
|
||||
if (normal_direction.Magnitude() > 1.e-9) {
|
||||
normal = gp_Dir(normal_direction.XYZ() * rotation_matrix);
|
||||
} else {
|
||||
Handle_Geom_Surface surf = BRep_Tool::Surface(face);
|
||||
// Special case the normal at the poles of a spherical surface
|
||||
if (surf->DynamicType() == STANDARD_TYPE(Geom_SphericalSurface)) {
|
||||
if (fabs(fabs(uv.Y()) - M_PI / 2.) < 1.e-9) {
|
||||
const bool is_top = uv.Y() > 0;
|
||||
const bool is_forward = face.Orientation() == TopAbs_FORWARD;
|
||||
const double z = (is_top == is_forward) ? 1. : -1.;
|
||||
normal = gp_Dir(gp_XYZ(0, 0, z) * rotation_matrix);
|
||||
}
|
||||
}
|
||||
// TODO: Do the same for conical surfaces, but they are rare in IFC.
|
||||
}
|
||||
_normals.push_back(static_cast<P>(normal.X()));
|
||||
_normals.push_back(static_cast<P>(normal.Y()));
|
||||
_normals.push_back(static_cast<P>(normal.Z()));
|
||||
}
|
||||
}
|
||||
|
||||
const Poly_Array1OfTriangle& triangles = tri->Triangles();
|
||||
for( int i = 1; i <= triangles.Length(); ++ i ) {
|
||||
int n1,n2,n3;
|
||||
if ( face.Orientation() == TopAbs_REVERSED )
|
||||
triangles(i).Get(n3,n2,n1);
|
||||
else triangles(i).Get(n1,n2,n3);
|
||||
|
||||
/* An alternative would be to calculate normals based
|
||||
* on the coordinates of the mesh vertices */
|
||||
/*
|
||||
const gp_XYZ pt1 = coords[n1-1];
|
||||
const gp_XYZ pt2 = coords[n2-1];
|
||||
const gp_XYZ pt3 = coords[n3-1];
|
||||
const gp_XYZ v1 = pt2-pt1;
|
||||
const gp_XYZ v2 = pt3-pt2;
|
||||
gp_Dir normal = gp_Dir(v1^v2);
|
||||
_normals.push_back((float)normal.X());
|
||||
_normals.push_back((float)normal.Y());
|
||||
_normals.push_back((float)normal.Z());
|
||||
*/
|
||||
|
||||
_faces.push_back(dict[n1]);
|
||||
_faces.push_back(dict[n2]);
|
||||
_faces.push_back(dict[n3]);
|
||||
|
||||
_material_ids.push_back(surface_style_id);
|
||||
|
||||
addEdge(dict[n1], dict[n2], edgecount, edges_temp);
|
||||
addEdge(dict[n2], dict[n3], edgecount, edges_temp);
|
||||
addEdge(dict[n3], dict[n1], edgecount, edges_temp);
|
||||
}
|
||||
for ( std::vector<std::pair<int,int> >::const_iterator jt = edges_temp.begin(); jt != edges_temp.end(); ++jt ) {
|
||||
if (edgecount[*jt] == 1) {
|
||||
// non manifold edge, face boundary
|
||||
_edges.push_back(jt->first);
|
||||
_edges.push_back(jt->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!_normals.empty() && settings().get(IfcGeom::IteratorSettings::GENERATE_UVS)) {
|
||||
uvs_ = box_project_uvs(_verts, _normals);
|
||||
}
|
||||
|
||||
if (num_faces == 0) {
|
||||
// Edges are only emitted if there are no faces. A mixed representation of faces
|
||||
// and loose edges is discouraged by the standard. An alternative would be to use
|
||||
// TopExp_Explorer texp(s, TopAbs_EDGE, TopAbs_FACE) to find edges that do not
|
||||
// belong to any face.
|
||||
for (TopExp_Explorer texp(s, TopAbs_EDGE); texp.More(); texp.Next()) {
|
||||
BRepAdaptor_Curve crv(TopoDS::Edge(texp.Current()));
|
||||
GCPnts_QuasiUniformDeflection tessellater(crv, settings().deflection_tolerance());
|
||||
int n = tessellater.NbPoints();
|
||||
int start = (int)_verts.size() / 3;
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
gp_XYZ p = tessellater.Value(i).XYZ();
|
||||
|
||||
/*
|
||||
// In case you want direction arrows on your edges
|
||||
double u = tessellater.Parameter(i);
|
||||
gp_XYZ p2, p3;
|
||||
gp_Pnt tmp;
|
||||
gp_Vec tmp2;
|
||||
crv.D1(u, tmp, tmp2);
|
||||
gp_Dir d1, d2, d3, d4;
|
||||
d1 = tmp2;
|
||||
if (texp.Current().Orientation() == TopAbs_REVERSED) {
|
||||
d1 = -d1;
|
||||
}
|
||||
if (fabs(d1.Z()) < 0.5) {
|
||||
d2 = d1.Crossed(gp::DZ());
|
||||
} else {
|
||||
d2 = d1.Crossed(gp::DY());
|
||||
}
|
||||
d3 = d1.XYZ() + d2.XYZ();
|
||||
d4 = d1.XYZ() - d2.XYZ();
|
||||
p2 = p - d3.XYZ() / 10.;
|
||||
p3 = p - d4.XYZ() / 10.;
|
||||
trsf.Transforms(p2);
|
||||
trsf.Transforms(p3);
|
||||
_material_ids.push_back(surface_style_id);
|
||||
_material_ids.push_back(surface_style_id);
|
||||
_verts.push_back(static_cast<P>(p2.X()));
|
||||
_verts.push_back(static_cast<P>(p2.Y()));
|
||||
_verts.push_back(static_cast<P>(p2.Z()));
|
||||
_verts.push_back(static_cast<P>(p3.X()));
|
||||
_verts.push_back(static_cast<P>(p3.Y()));
|
||||
_verts.push_back(static_cast<P>(p3.Z()));
|
||||
*/
|
||||
|
||||
trsf.Transforms(p);
|
||||
|
||||
_material_ids.push_back(surface_style_id);
|
||||
|
||||
_verts.push_back(static_cast<P>(p.X()));
|
||||
_verts.push_back(static_cast<P>(p.Y()));
|
||||
_verts.push_back(static_cast<P>(p.Z()));
|
||||
|
||||
if (i > 1) {
|
||||
_edges.push_back(start + i - 2);
|
||||
_edges.push_back(start + i - 1);
|
||||
// _edges.push_back(start + 3 * (i - 2) + 2);
|
||||
// _edges.push_back(start + 3 * (i - 1) + 2);
|
||||
}
|
||||
|
||||
// _edges.push_back(start + 3 * (i - 1) + 0);
|
||||
// _edges.push_back(start + 3 * (i - 1) + 2);
|
||||
// _edges.push_back(start + 3 * (i - 1) + 1);
|
||||
// _edges.push_back(start + 3 * (i - 1) + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BRepTools::Clean(s);
|
||||
iit->Shape()->Triangulate(settings(), iit->Placement(), this, surface_style_id);
|
||||
}
|
||||
}
|
||||
virtual ~Triangulation() {}
|
||||
@@ -378,13 +195,14 @@ namespace IfcGeom {
|
||||
return uvs;
|
||||
}
|
||||
|
||||
private:
|
||||
public:
|
||||
|
||||
// Welds vertices that belong to different faces
|
||||
int addVertex(int material_index, const gp_XYZ& p) {
|
||||
int addVertex(int material_index, P X, P Y, P Z) {
|
||||
const bool convert = settings().get(IteratorSettings::CONVERT_BACK_UNITS);
|
||||
const P X = static_cast<P>(convert ? (p.X() / settings().unit_magnitude()) : p.X());
|
||||
const P Y = static_cast<P>(convert ? (p.Y() / settings().unit_magnitude()) : p.Y());
|
||||
const P Z = static_cast<P>(convert ? (p.Z() / settings().unit_magnitude()) : p.Z());
|
||||
X = static_cast<P>(convert ? (X / settings().unit_magnitude()) : X);
|
||||
Y = static_cast<P>(convert ? (Y / settings().unit_magnitude()) : Y);
|
||||
Z = static_cast<P>(convert ? (Z / settings().unit_magnitude()) : Z);
|
||||
int i = (int) _verts.size() / 3;
|
||||
if (settings().get(IteratorSettings::WELD_VERTICES)) {
|
||||
const VertexKey key = std::make_pair(material_index, std::make_pair(X, std::make_pair(Y, Z)));
|
||||
@@ -398,12 +216,34 @@ namespace IfcGeom {
|
||||
_verts.push_back(Z);
|
||||
return i;
|
||||
}
|
||||
|
||||
inline void addEdge(int n1, int n2, std::map<std::pair<int,int>,int>& edgecount, std::vector<std::pair<int,int> >& edges_temp) {
|
||||
const Edge e = Edge( (std::min)(n1,n2),(std::max)(n1,n2) );
|
||||
if ( edgecount.find(e) == edgecount.end() ) edgecount[e] = 1;
|
||||
else edgecount[e] ++;
|
||||
edges_temp.push_back(e);
|
||||
}
|
||||
|
||||
inline void addNormal(P X, P Y, P Z) {
|
||||
_normals.push_back(X);
|
||||
_normals.push_back(Y);
|
||||
_normals.push_back(Z);
|
||||
}
|
||||
|
||||
inline void addFace(int style, int i0, int i1, int i2) {
|
||||
_faces.push_back(i0);
|
||||
_faces.push_back(i1);
|
||||
_faces.push_back(i2);
|
||||
|
||||
_material_ids.push_back(style);
|
||||
}
|
||||
|
||||
inline void registerEdge(int i0, int i1) {
|
||||
_edges.push_back(i0);
|
||||
_edges.push_back(i1);
|
||||
}
|
||||
|
||||
private:
|
||||
Triangulation();
|
||||
Triangulation(const Triangulation&);
|
||||
Triangulation& operator=(const Triangulation&);
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomFilter.h"
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
#include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomIteratorSettings.h"
|
||||
|
||||
#include <gp_XYZ.hxx>
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace IfcGeom {
|
||||
class Element;
|
||||
|
||||
template <typename P, typename PP>
|
||||
class BRepElement;
|
||||
class NativeElement;
|
||||
}
|
||||
|
||||
typedef boost::function3<IfcGeom::IteratorImplementation<float, float>*, const IfcGeom::IteratorSettings&, IfcParse::IfcFile*, const std::vector<IfcGeom::filter_t>&> iterator_float_float_fn;
|
||||
@@ -71,7 +71,7 @@ namespace IfcGeom {
|
||||
virtual IfcParse::IfcFile* file() const = 0;
|
||||
virtual IfcUtil::IfcBaseClass* next() = 0;
|
||||
virtual Element<P, PP>* get() = 0;
|
||||
virtual BRepElement<P, PP>* get_native() = 0;
|
||||
virtual NativeElement<P, PP>* get_native() = 0;
|
||||
virtual const Element<P, PP>* get_object(int id) = 0;
|
||||
virtual IfcUtil::IfcBaseClass* create() = 0;
|
||||
};
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#define ITERATOR_KERNEL_H
|
||||
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
#include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||
#include "../ifcgeom/IfcRepresentationShapeItem.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomIteratorSettings.h"
|
||||
#include "../ifcgeom_schema_agnostic/ConversionResult.h"
|
||||
|
||||
#include "../ifcparse/Ifc2x3.h"
|
||||
#include "../ifcparse/Ifc4.h"
|
||||
@@ -15,7 +15,7 @@
|
||||
namespace IfcGeom {
|
||||
|
||||
template <typename P, typename PP>
|
||||
class BRepElement;
|
||||
class NativeElement;
|
||||
|
||||
class Kernel {
|
||||
private:
|
||||
@@ -64,14 +64,14 @@ namespace IfcGeom {
|
||||
return implementation_->getValue(var);
|
||||
}
|
||||
|
||||
virtual BRepElement<double, double>* convert(
|
||||
virtual NativeElement<double, double>* convert(
|
||||
const IteratorSettings& settings, IfcUtil::IfcBaseClass* representation,
|
||||
IfcUtil::IfcBaseClass* product)
|
||||
{
|
||||
return implementation_->convert(settings, representation, product);
|
||||
}
|
||||
|
||||
virtual IfcRepresentationShapeItems convert(IfcUtil::IfcBaseClass* item) {
|
||||
virtual ConversionResults convert(IfcUtil::IfcBaseClass* item) {
|
||||
return implementation_->convert(item);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../ifcgeom/ifc_geom_api.h"
|
||||
#include "../ifcgeom_schema_agnostic/ifc_geom_api.h"
|
||||
#include "../ifcparse/IfcBaseClass.h"
|
||||
|
||||
#include <TopoDS_Shape.hxx>
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#endif
|
||||
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomIterator.h"
|
||||
#include "../ifcgeom/IfcGeomElement.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomElement.h"
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
#include "../ifcparse/IfcLogger.h"
|
||||
|
||||
@@ -404,9 +404,9 @@ static const std::string WALKABLE_SURFACE_AREA = "WALKABLE_SURFACE_AREA";
|
||||
|
||||
class QuantityWriter_v0 : public EntityExtension {
|
||||
private:
|
||||
const IfcGeom::BRepElement<float, double>* elem_;
|
||||
const IfcGeom::NativeElement<float, double>* elem_;
|
||||
public:
|
||||
QuantityWriter_v0(const IfcGeom::BRepElement<float, double>* elem) :
|
||||
QuantityWriter_v0(const IfcGeom::NativeElement<float, double>* elem) :
|
||||
elem_(elem)
|
||||
{
|
||||
put_json(TOTAL_SURFACE_AREA, 0.);
|
||||
@@ -419,9 +419,9 @@ public:
|
||||
|
||||
class QuantityWriter_v1 : public EntityExtension {
|
||||
private:
|
||||
const IfcGeom::BRepElement<float, double>* elem_;
|
||||
const IfcGeom::NativeElement<float, double>* elem_;
|
||||
public:
|
||||
QuantityWriter_v1(const IfcGeom::BRepElement<float, double>* elem) :
|
||||
QuantityWriter_v1(const IfcGeom::NativeElement<float, double>* elem) :
|
||||
elem_(elem)
|
||||
{
|
||||
double a, b, c;
|
||||
|
||||
@@ -369,7 +369,7 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
|
||||
}
|
||||
}
|
||||
|
||||
IfcGeom::BRepElement<double>* brep = kernel.convert(settings, ifc_representation, product);
|
||||
IfcGeom::NativeElement<double>* brep = kernel.convert(settings, ifc_representation, product);
|
||||
if (!brep) {
|
||||
throw IfcParse::IfcException("Failed to process shape");
|
||||
}
|
||||
@@ -387,7 +387,7 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
|
||||
} else {
|
||||
if (!representation) {
|
||||
if (instance->declaration().is(Schema::IfcRepresentationItem::Class()) || instance->declaration().is(Schema::IfcRepresentation::Class())) {
|
||||
IfcGeom::IfcRepresentationShapeItems shapes = kernel.convert(instance);
|
||||
IfcGeom::ConversionResults shapes = kernel.convert(instance);
|
||||
|
||||
IfcGeom::ElementSettings element_settings(settings, kernel.getValue(IfcGeom::Kernel::GV_LENGTH_UNIT), instance->declaration().name());
|
||||
IfcGeom::Representation::BRep brep(element_settings, boost::lexical_cast<std::string>(instance->data().id()), shapes);
|
||||
|
||||
@@ -230,7 +230,7 @@ public:
|
||||
bool ready();
|
||||
void writeHeader();
|
||||
void write(const IfcGeom::TriangulationElement<real_t>* o);
|
||||
void write(const IfcGeom::BRepElement<real_t>* /*o*/) {}
|
||||
void write(const IfcGeom::NativeElement<real_t>* /*o*/) {}
|
||||
void finalize();
|
||||
bool isTesselated() const { return true; }
|
||||
void setUnitNameAndMagnitude(const std::string& name, float magnitude) {
|
||||
|
||||
@@ -28,7 +28,7 @@ typedef float real_t;
|
||||
|
||||
#include "../serializers/Serializer.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomIterator.h"
|
||||
#include "../ifcgeom/IfcGeomElement.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomElement.h"
|
||||
|
||||
class SerializerSettings : public IfcGeom::IteratorSettings
|
||||
{
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
|
||||
virtual bool isTesselated() const = 0;
|
||||
virtual void write(const IfcGeom::TriangulationElement<real_t>* o) = 0;
|
||||
virtual void write(const IfcGeom::BRepElement<real_t>* o) = 0;
|
||||
virtual void write(const IfcGeom::NativeElement<real_t>* o) = 0;
|
||||
virtual void setUnitNameAndMagnitude(const std::string& name, float magnitude) = 0;
|
||||
|
||||
const SerializerSettings& settings() const { return settings_; }
|
||||
|
||||
@@ -42,8 +42,8 @@ public:
|
||||
: OpenCascadeBasedSerializer(out_filename, settings)
|
||||
{}
|
||||
virtual ~IgesSerializer() {}
|
||||
void writeShape(const TopoDS_Shape& shape) {
|
||||
writer.AddShape(shape);
|
||||
void writeShape(const IfcGeom::ConversionResultShape* shape) {
|
||||
writer.AddShape(*(IfcGeom::OpenCascadeShape*)shape);
|
||||
}
|
||||
void finalize() {
|
||||
writer.Write(out_filename.c_str());
|
||||
|
||||
@@ -34,7 +34,7 @@ bool OpenCascadeBasedSerializer::ready() {
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
void OpenCascadeBasedSerializer::write(const IfcGeom::BRepElement<real_t>* o) {
|
||||
void OpenCascadeBasedSerializer::write(const IfcGeom::NativeElement<real_t>* o) {
|
||||
TopoDS_Shape compound = o->geometry().as_compound();
|
||||
|
||||
if (o->geometry().settings().get(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS)) {
|
||||
@@ -44,7 +44,8 @@ void OpenCascadeBasedSerializer::write(const IfcGeom::BRepElement<real_t>* o) {
|
||||
compound = BRepBuilderAPI_Transform(compound, scale, true).Shape();
|
||||
}
|
||||
|
||||
writeShape(compound);
|
||||
IfcGeom::OpenCascadeShape s(compound);
|
||||
writeShape(&s);
|
||||
}
|
||||
|
||||
#define RATHER_SMALL (1e-3)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#define OPENCASCADEBASEDSERIALIZER_H
|
||||
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomIterator.h"
|
||||
|
||||
#include "../ifcgeom/OpenCascadeConversionResult.h"
|
||||
#include "../serializers/GeometrySerializer.h"
|
||||
|
||||
class OpenCascadeBasedSerializer : public GeometrySerializer {
|
||||
@@ -38,9 +38,9 @@ public:
|
||||
virtual ~OpenCascadeBasedSerializer() {}
|
||||
void writeHeader() {}
|
||||
bool ready();
|
||||
virtual void writeShape(const TopoDS_Shape& shape) = 0;
|
||||
virtual void writeShape(const IfcGeom::ConversionResultShape* shape) = 0;
|
||||
void write(const IfcGeom::TriangulationElement<real_t>* /*o*/) {}
|
||||
void write(const IfcGeom::BRepElement<real_t>* o);
|
||||
void write(const IfcGeom::NativeElement<real_t>* o);
|
||||
bool isTesselated() const { return false; }
|
||||
void setFile(IfcParse::IfcFile*) {}
|
||||
};
|
||||
|
||||
@@ -36,10 +36,10 @@ public:
|
||||
: OpenCascadeBasedSerializer(out_filename, settings)
|
||||
{}
|
||||
virtual ~StepSerializer() {}
|
||||
void writeShape(const TopoDS_Shape& shape) {
|
||||
void writeShape(const IfcGeom::ConversionResultShape* shape) {
|
||||
std::stringstream ss;
|
||||
std::streambuf *sb = std::cout.rdbuf(ss.rdbuf());
|
||||
writer.Transfer(shape, STEPControl_AsIs);
|
||||
writer.Transfer(((IfcGeom::OpenCascadeShape*)shape)->shape(), STEPControl_AsIs);
|
||||
std::cout.rdbuf(sb);
|
||||
}
|
||||
void finalize() {
|
||||
|
||||
@@ -283,14 +283,14 @@ SvgSerializer::path_object& SvgSerializer::start_path(IfcUtil::IfcBaseEntity* st
|
||||
return p;
|
||||
}
|
||||
|
||||
void SvgSerializer::write(const IfcGeom::BRepElement<real_t>* o)
|
||||
void SvgSerializer::write(const IfcGeom::NativeElement<real_t>* o)
|
||||
{
|
||||
IfcUtil::IfcBaseEntity* storey = storey_;
|
||||
boost::optional<double> storey_elevation = boost::none;
|
||||
|
||||
/*
|
||||
|
||||
TODO: based on BRepElement::parent()
|
||||
TODO: based on NativeElement::parent()
|
||||
|
||||
IfcSchema::IfcObjectDefinition* obdef = static_cast<IfcSchema::IfcObjectDefinition*>(file->entityById(o->id()));
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
void writeHeader();
|
||||
bool ready();
|
||||
void write(const IfcGeom::TriangulationElement<real_t>* /*o*/) {}
|
||||
void write(const IfcGeom::BRepElement<real_t>* o);
|
||||
void write(const IfcGeom::NativeElement<real_t>* o);
|
||||
void write(path_object& p, const TopoDS_Wire& wire);
|
||||
path_object& start_path(IfcUtil::IfcBaseEntity* storey, const std::string& id);
|
||||
bool isTesselated() const { return false; }
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
void writeHeader();
|
||||
void writeMaterial(const IfcGeom::Material& style);
|
||||
void write(const IfcGeom::TriangulationElement<real_t>* o);
|
||||
void write(const IfcGeom::BRepElement<real_t>* /*o*/) {}
|
||||
void write(const IfcGeom::NativeElement<real_t>* /*o*/) {}
|
||||
void finalize() {}
|
||||
bool isTesselated() const { return true; }
|
||||
void setUnitNameAndMagnitude(const std::string& /*name*/, float /*magnitude*/) {}
|
||||
|
||||
Reference in New Issue
Block a user