mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-14 11:24:19 +00:00
Massive refactor of the IfcGeomObjects module, which is now the IfcGeom::Iterator class.
This commit is contained in:
@@ -41,8 +41,8 @@ bl_info = {
|
||||
|
||||
if "bpy" in locals():
|
||||
import imp
|
||||
if "IfcImport" in locals():
|
||||
imp.reload(IfcImport)
|
||||
if "ifcopenshell" in locals():
|
||||
imp.reload(ifcopenshell)
|
||||
|
||||
import bpy
|
||||
import mathutils
|
||||
@@ -63,11 +63,12 @@ bpy.types.Object.ifc_type = StringProperty(name="IFC Entity Type",
|
||||
|
||||
|
||||
def import_ifc(filename, use_names, process_relations):
|
||||
from . import IfcImport
|
||||
from . import ifcopenshell
|
||||
print("Reading %s..."%bpy.path.basename(filename))
|
||||
valid_file = IfcImport.Init(filename)
|
||||
settings = ifcopenshell.IteratorSettings()
|
||||
iterator = ifcopenshell.Iterator(settings, filename)
|
||||
valid_file = iterator.findContext()
|
||||
if not valid_file:
|
||||
IfcImport.CleanUp()
|
||||
return False
|
||||
print("Done reading file")
|
||||
id_to_object = {}
|
||||
@@ -76,13 +77,13 @@ def import_ifc(filename, use_names, process_relations):
|
||||
old_progress = -1
|
||||
print("Creating geometry...")
|
||||
while True:
|
||||
ob = IfcImport.Get()
|
||||
ob = iterator.get()
|
||||
|
||||
f = ob.mesh.faces
|
||||
v = ob.mesh.verts
|
||||
mats = ob.mesh.materials
|
||||
matids = ob.mesh.material_ids
|
||||
m = ob.matrix
|
||||
f = ob.geometry.faces
|
||||
v = ob.geometry.verts
|
||||
mats = ob.geometry.materials
|
||||
matids = ob.geometry.material_ids
|
||||
m = ob.transformation.matrix.data
|
||||
t = ob.type[0:21]
|
||||
nm = ob.name if len(ob.name) and use_names else ob.guid
|
||||
|
||||
@@ -91,7 +92,7 @@ def import_ifc(filename, use_names, process_relations):
|
||||
faces = [[f[i], f[i + 1], f[i + 2]] \
|
||||
for i in range(0, len(f), 3)]
|
||||
|
||||
me = bpy.data.meshes.new('mesh%d' % ob.mesh.id)
|
||||
me = bpy.data.meshes.new('mesh%d' % ob.geometry.id)
|
||||
me.from_pydata(verts, [], faces)
|
||||
|
||||
def add_material(mname, props):
|
||||
@@ -152,11 +153,11 @@ def import_ifc(filename, use_names, process_relations):
|
||||
for face, matid in zip(faces, matids):
|
||||
face.material_index = matid + (1 if needs_default else 0)
|
||||
|
||||
progress = IfcImport.Progress() // 2
|
||||
progress = iterator.progress() // 2
|
||||
if progress > old_progress:
|
||||
print("\r[" + "#" * progress + " " * (50 - progress) + "]", end="")
|
||||
old_progress = progress
|
||||
if not IfcImport.Next():
|
||||
if not iterator.next():
|
||||
break
|
||||
|
||||
print("\rDone creating geometry" + " " * 30)
|
||||
@@ -172,7 +173,7 @@ def import_ifc(filename, use_names, process_relations):
|
||||
if parent_id in id_to_object:
|
||||
bob = id_to_object[parent_id][0]
|
||||
else:
|
||||
parent_ob = IfcImport.GetObject(parent_id)
|
||||
parent_ob = iterator.GetObject(parent_id)
|
||||
if parent_ob.id == -1:
|
||||
bob = None
|
||||
else:
|
||||
@@ -220,10 +221,8 @@ def import_ifc(filename, use_names, process_relations):
|
||||
print("Done processing relations")
|
||||
|
||||
txt = bpy.data.texts.new("%s.log"%bpy.path.basename(filename))
|
||||
txt.from_string(IfcImport.GetLog())
|
||||
txt.from_string(iterator.getLog())
|
||||
|
||||
IfcImport.CleanUp()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ std::string collada_id(const std::string& s) {
|
||||
return id;
|
||||
}
|
||||
|
||||
void ColladaSerializer::ColladaExporter::ColladaGeometries::addFloatSource(const std::string& mesh_id, const std::string& suffix, const std::vector<float>& floats, const char* coords /* = "XYZ" */) {
|
||||
void ColladaSerializer::ColladaExporter::ColladaGeometries::addFloatSource(const std::string& mesh_id, const std::string& suffix, const std::vector<double>& floats, const char* coords /* = "XYZ" */) {
|
||||
COLLADASW::FloatSource source(mSW);
|
||||
source.setId(mesh_id + suffix);
|
||||
source.setArrayId(mesh_id + suffix + COLLADASW::LibraryGeometries::ARRAY_ID_SUFFIX);
|
||||
@@ -45,13 +45,18 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::addFloatSource(const
|
||||
source.getParameterNameList().push_back(std::string(1, coords[i]));
|
||||
}
|
||||
source.prepareToAppendValues();
|
||||
for (std::vector<float>::const_iterator it = floats.begin(); it != floats.end(); ++it) {
|
||||
for (std::vector<double>::const_iterator it = floats.begin(); it != floats.end(); ++it) {
|
||||
source.appendValues(*it);
|
||||
}
|
||||
source.finish();
|
||||
}
|
||||
|
||||
void ColladaSerializer::ColladaExporter::ColladaGeometries::write(const std::string mesh_id, const std::string& default_material_name, const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<int>& indices, const std::vector<int> material_ids, const std::vector<IfcGeomObjects::Material>& materials) {
|
||||
void ColladaSerializer::ColladaExporter::ColladaGeometries::write(const std::string mesh_id, const std::string& default_material_name, const std::vector<double>& positions, const std::vector<double>& normals, const std::vector<int>& indices, const std::vector<int> material_ids, const std::vector<IfcGeom::Material>& materials) {
|
||||
// The goal of the IfcGeom::Iterator is to filter out empty geometries, but
|
||||
// since this function would crash trying to deference the material_ids in
|
||||
// that case, a hard return statement is added just in case.
|
||||
if (indices.empty()) return;
|
||||
|
||||
openMesh(mesh_id);
|
||||
|
||||
// The normals vector can be empty for example when the WELD_VERTICES setting is used.
|
||||
@@ -70,17 +75,13 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::write(const std::str
|
||||
|
||||
std::vector<int>::const_iterator index_range_start = indices.begin();
|
||||
std::vector<int>::const_iterator material_it = material_ids.begin();
|
||||
int previous_material_id = -2;
|
||||
int previous_material_id = -1;
|
||||
for (std::vector<int>::const_iterator it = indices.begin(); ; it += 3) {
|
||||
const int current_material_id = material_it == material_ids.end()
|
||||
? -3
|
||||
: *(material_it++);
|
||||
const int current_material_id = *(material_it++);
|
||||
const int num_triangles = std::distance(index_range_start, it) / 3;
|
||||
if ((previous_material_id != current_material_id && num_triangles > 0) || (it == indices.end())) {
|
||||
COLLADASW::Triangles triangles(mSW);
|
||||
triangles.setMaterial(collada_id(previous_material_id < 0
|
||||
? default_material_name
|
||||
: materials[previous_material_id].name()));
|
||||
triangles.setMaterial(materials[previous_material_id].name());
|
||||
triangles.setCount(num_triangles);
|
||||
int offset = 0;
|
||||
triangles.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::VERTEX,"#" + mesh_id + COLLADASW::LibraryGeometries::VERTICES_ID_SUFFIX, offset++ ) );
|
||||
@@ -113,7 +114,7 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::close() {
|
||||
closeLibrary();
|
||||
}
|
||||
|
||||
void ColladaSerializer::ColladaExporter::ColladaScene::add(const std::string& node_id, const std::string& node_name, const std::string& geom_name, const std::vector<std::string>& material_ids, const std::vector<float>& matrix) {
|
||||
void ColladaSerializer::ColladaExporter::ColladaScene::add(const std::string& node_id, const std::string& node_name, const std::string& geom_name, const std::vector<std::string>& material_ids, const std::vector<double>& matrix) {
|
||||
if (!scene_opened) {
|
||||
openVisualScene(scene_id);
|
||||
scene_opened = true;
|
||||
@@ -155,7 +156,7 @@ void ColladaSerializer::ColladaExporter::ColladaScene::write() {
|
||||
}
|
||||
}
|
||||
|
||||
void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::write(const IfcGeomObjects::Material& material) {
|
||||
void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::write(const IfcGeom::Material& material) {
|
||||
openEffect(collada_id(material.name()) + "-fx");
|
||||
COLLADASW::EffectProfile effect(mSW);
|
||||
effect.setShaderType(COLLADASW::EffectProfile::LAMBERT);
|
||||
@@ -186,20 +187,20 @@ void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::close
|
||||
closeLibrary();
|
||||
}
|
||||
|
||||
void ColladaSerializer::ColladaExporter::ColladaMaterials::add(const IfcGeomObjects::Material& material) {
|
||||
void ColladaSerializer::ColladaExporter::ColladaMaterials::add(const IfcGeom::Material& material) {
|
||||
if (!contains(material)) {
|
||||
effects.write(material);
|
||||
materials.push_back(material);
|
||||
}
|
||||
}
|
||||
|
||||
bool ColladaSerializer::ColladaExporter::ColladaMaterials::contains(const IfcGeomObjects::Material& material) {
|
||||
bool ColladaSerializer::ColladaExporter::ColladaMaterials::contains(const IfcGeom::Material& material) {
|
||||
return std::find(materials.begin(), materials.end(), material) != materials.end();
|
||||
}
|
||||
|
||||
void ColladaSerializer::ColladaExporter::ColladaMaterials::write() {
|
||||
effects.close();
|
||||
for (std::vector<IfcGeomObjects::Material>::const_iterator it = materials.begin(); it != materials.end(); ++it) {
|
||||
for (std::vector<IfcGeom::Material>::const_iterator it = materials.begin(); it != materials.end(); ++it) {
|
||||
const std::string& material_name = collada_id((*it).name());
|
||||
openMaterial(material_name);
|
||||
addInstanceEffect("#" + material_name + "-fx");
|
||||
@@ -218,18 +219,10 @@ void ColladaSerializer::ColladaExporter::startDocument(const std::string& unit_n
|
||||
asset.add();
|
||||
}
|
||||
|
||||
void ColladaSerializer::ColladaExporter::writeTesselated(const std::string& guid, const std::string& name, const std::string& type, int obj_id, const std::vector<float>& matrix, const std::vector<float>& vertices, const std::vector<float>& normals, const std::vector<int>& indices, const std::vector<int>& material_ids, const std::vector<IfcGeomObjects::Material>& _materials) {
|
||||
const IfcGeomObjects::Material default_for_type = IfcGeomObjects::Material(IfcGeom::get_default_style(type));
|
||||
void ColladaSerializer::ColladaExporter::write(const std::string& guid, const std::string& name, const std::string& type, int obj_id, const std::vector<double>& matrix, const std::vector<double>& vertices, const std::vector<double>& normals, const std::vector<int>& indices, const std::vector<int>& material_ids, const std::vector<IfcGeom::Material>& _materials) {
|
||||
std::vector<std::string> material_references;
|
||||
const bool needs_default = std::find(material_ids.begin(), material_ids.end(), -1) != material_ids.end();
|
||||
if (needs_default) {
|
||||
if (!materials.contains(default_for_type)) {
|
||||
materials.add(default_for_type);
|
||||
}
|
||||
material_references.push_back(collada_id(default_for_type.name()));
|
||||
}
|
||||
for (std::vector<IfcGeomObjects::Material>::const_iterator it = _materials.begin(); it != _materials.end(); ++it) {
|
||||
const IfcGeomObjects::Material& material = *it;
|
||||
for (std::vector<IfcGeom::Material>::const_iterator it = _materials.begin(); it != _materials.end(); ++it) {
|
||||
const IfcGeom::Material& material = *it;
|
||||
if (!materials.contains(material)) {
|
||||
materials.add(material);
|
||||
}
|
||||
@@ -273,9 +266,9 @@ void ColladaSerializer::writeHeader() {
|
||||
exporter.startDocument(unit_name, unit_magnitude);
|
||||
}
|
||||
|
||||
void ColladaSerializer::writeTesselated(const IfcGeomObjects::IfcGeomObject* o) {
|
||||
const IfcGeomObjects::IfcRepresentationTriangulation& mesh = o->mesh();
|
||||
exporter.writeTesselated(o->guid(), o->name(), o->type(), o->id(), o->matrix(), mesh.verts(), mesh.normals(), mesh.faces(), mesh.material_ids(), mesh.materials());
|
||||
void ColladaSerializer::write(const IfcGeom::TriangulationElement<double>* o) {
|
||||
const IfcGeom::Representation::Triangulation<double>& mesh = o->geometry();
|
||||
exporter.write(o->guid(), o->name(), o->type(), o->id(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), mesh.faces(), mesh.material_ids(), mesh.materials());
|
||||
}
|
||||
|
||||
void ColladaSerializer::finalize() {
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include <COLLADASWBaseInputElement.h>
|
||||
#include <COLLADASWAsset.h>
|
||||
|
||||
#include "../ifcgeom/IfcGeomObjects.h"
|
||||
#include "../ifcgeom/IfcGeomIterator.h"
|
||||
|
||||
#include "../ifcconvert/GeometrySerializer.h"
|
||||
|
||||
@@ -51,8 +51,8 @@ private:
|
||||
explicit ColladaGeometries(COLLADASW::StreamWriter& stream)
|
||||
: COLLADASW::LibraryGeometries(&stream)
|
||||
{}
|
||||
void addFloatSource(const std::string& mesh_id, const std::string& suffix, const std::vector<float>& floats, const char* coords = "XYZ");
|
||||
void write(const std::string mesh_id, const std::string& default_material_name, const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<int>& indices, const std::vector<int> material_ids, const std::vector<IfcGeomObjects::Material>& materials);
|
||||
void addFloatSource(const std::string& mesh_id, const std::string& suffix, const std::vector<double>& floats, const char* coords = "XYZ");
|
||||
void write(const std::string mesh_id, const std::string& default_material_name, const std::vector<double>& positions, const std::vector<double>& normals, const std::vector<int>& indices, const std::vector<int> material_ids, const std::vector<IfcGeom::Material>& materials);
|
||||
void close();
|
||||
};
|
||||
class ColladaScene : public COLLADASW::LibraryVisualScenes
|
||||
@@ -66,7 +66,7 @@ private:
|
||||
, scene_id(scene_id)
|
||||
, scene_opened(false)
|
||||
{}
|
||||
void add(const std::string& node_id, const std::string& node_name, const std::string& geom_name, const std::vector<std::string>& material_ids, const std::vector<float>& matrix);
|
||||
void add(const std::string& node_id, const std::string& node_name, const std::string& geom_name, const std::vector<std::string>& material_ids, const std::vector<double>& matrix);
|
||||
void write();
|
||||
};
|
||||
class ColladaMaterials : public COLLADASW::LibraryMaterials
|
||||
@@ -78,34 +78,34 @@ private:
|
||||
explicit ColladaEffects(COLLADASW::StreamWriter& stream)
|
||||
: COLLADASW::LibraryEffects(&stream)
|
||||
{}
|
||||
void write(const IfcGeomObjects::Material& material);
|
||||
void write(const IfcGeom::Material& material);
|
||||
void close();
|
||||
};
|
||||
std::vector<IfcGeomObjects::Material> materials;
|
||||
std::vector<IfcGeom::Material> materials;
|
||||
ColladaEffects effects;
|
||||
public:
|
||||
explicit ColladaMaterials(COLLADASW::StreamWriter& stream)
|
||||
: COLLADASW::LibraryMaterials(&stream)
|
||||
, effects(stream)
|
||||
{}
|
||||
void add(const IfcGeomObjects::Material& material);
|
||||
bool contains(const IfcGeomObjects::Material& material);
|
||||
void add(const IfcGeom::Material& material);
|
||||
bool contains(const IfcGeom::Material& material);
|
||||
void write();
|
||||
};
|
||||
class DeferredObject {
|
||||
public:
|
||||
std::string guid, name, type;
|
||||
int obj_id;
|
||||
std::vector<float> matrix;
|
||||
std::vector<float> vertices;
|
||||
std::vector<float> normals;
|
||||
std::vector<double> matrix;
|
||||
std::vector<double> vertices;
|
||||
std::vector<double> normals;
|
||||
std::vector<int> indices;
|
||||
std::vector<int> material_ids;
|
||||
std::vector<IfcGeomObjects::Material> materials;
|
||||
std::vector<IfcGeom::Material> materials;
|
||||
std::vector<std::string> material_references;
|
||||
DeferredObject(const std::string& guid, const std::string& name, const std::string& type, int obj_id, const std::vector<float>& matrix, const std::vector<float>& vertices,
|
||||
const std::vector<float>& normals, const std::vector<int>& indices, const std::vector<int>& material_ids,
|
||||
const std::vector<IfcGeomObjects::Material>& materials, const std::vector<std::string>& material_references)
|
||||
DeferredObject(const std::string& guid, const std::string& name, const std::string& type, int obj_id, const std::vector<double>& matrix, const std::vector<double>& vertices,
|
||||
const std::vector<double>& normals, const std::vector<int>& indices, const std::vector<int>& material_ids,
|
||||
const std::vector<IfcGeom::Material>& materials, const std::vector<std::string>& material_references)
|
||||
: guid(guid)
|
||||
, name(name)
|
||||
, type(type)
|
||||
@@ -136,7 +136,7 @@ private:
|
||||
std::vector<DeferredObject> deferreds;
|
||||
virtual ~ColladaExporter() {}
|
||||
void startDocument(const std::string& unit_name, float unit_magnitude);
|
||||
void writeTesselated(const std::string& guid, const std::string& name, const std::string& type, int obj_id, const std::vector<float>& matrix, const std::vector<float>& vertices, const std::vector<float>& normals, const std::vector<int>& indices, const std::vector<int>& material_ids, const std::vector<IfcGeomObjects::Material>& materials);
|
||||
void write(const std::string& guid, const std::string& name, const std::string& type, int obj_id, const std::vector<double>& matrix, const std::vector<double>& vertices, const std::vector<double>& normals, const std::vector<int>& indices, const std::vector<int>& material_ids, const std::vector<IfcGeom::Material>& materials);
|
||||
void endDocument();
|
||||
};
|
||||
ColladaExporter exporter;
|
||||
@@ -149,8 +149,8 @@ public:
|
||||
{}
|
||||
bool ready();
|
||||
void writeHeader();
|
||||
void writeTesselated(const IfcGeomObjects::IfcGeomObject* o);
|
||||
void writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o) {}
|
||||
void write(const IfcGeom::TriangulationElement<double>* o);
|
||||
void write(const IfcGeom::ShapeModelElement<double>* o) {}
|
||||
void finalize();
|
||||
bool isTesselated() const { return true; }
|
||||
void setUnitNameAndMagnitude(const std::string& name, float magnitude) {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef GEOMETRYSERIALIZER_H
|
||||
#define GEOMETRYSERIALIZER_H
|
||||
|
||||
#include "../ifcgeom/IfcGeomObjects.h"
|
||||
#include "../ifcgeom/IfcGeomIterator.h"
|
||||
|
||||
class GeometrySerializer {
|
||||
public:
|
||||
@@ -29,8 +29,8 @@ public:
|
||||
virtual void finalize() = 0;
|
||||
virtual bool isTesselated() const = 0;
|
||||
virtual ~GeometrySerializer() {}
|
||||
virtual void writeTesselated(const IfcGeomObjects::IfcGeomObject* o) = 0;
|
||||
virtual void writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o) = 0;
|
||||
virtual void write(const IfcGeom::TriangulationElement<double>* o) = 0;
|
||||
virtual void write(const IfcGeom::ShapeModelElement<double>* o) = 0;
|
||||
virtual void setUnitNameAndMagnitude(const std::string& name, float magnitude) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
#include "../ifcgeom/IfcGeomObjects.h"
|
||||
#include "../ifcgeom/IfcGeomIterator.h"
|
||||
|
||||
#include "../ifcconvert/ColladaSerializer.h"
|
||||
#include "../ifcconvert/IgesSerializer.h"
|
||||
@@ -177,13 +177,16 @@ int main(int argc, char** argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::USE_WORLD_COORDS, use_world_coords);
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::WELD_VERTICES, weld_vertices);
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::SEW_SHELLS, sew_shells);
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::CONVERT_BACK_UNITS, convert_back_units);
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::FASTER_BOOLEANS, merge_boolean_operands);
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::FORCE_CCW_FACE_ORIENTATION, force_ccw_face_orientation);
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::DISABLE_OPENING_SUBTRACTIONS, disable_opening_subtractions);
|
||||
IfcGeom::IteratorSettings settings;
|
||||
|
||||
settings.set(IfcGeom::IteratorSettings::APPLY_DEFAULT_MATERIALS, true);
|
||||
settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, use_world_coords);
|
||||
settings.set(IfcGeom::IteratorSettings::WELD_VERTICES, weld_vertices);
|
||||
settings.set(IfcGeom::IteratorSettings::SEW_SHELLS, sew_shells);
|
||||
settings.set(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS, convert_back_units);
|
||||
settings.set(IfcGeom::IteratorSettings::FASTER_BOOLEANS, merge_boolean_operands);
|
||||
settings.set(IfcGeom::IteratorSettings::FORCE_CCW_FACE_ORIENTATION, force_ccw_face_orientation);
|
||||
settings.set(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS, disable_opening_subtractions);
|
||||
|
||||
std::string output_extension = output_filename.substr(output_filename.size()-4);
|
||||
for (std::string::iterator c = output_extension.begin(); c != output_extension.end(); ++c) {
|
||||
@@ -198,7 +201,7 @@ int main(int argc, char** argv) {
|
||||
const std::string mtl_filename = output_filename.substr(0,output_filename.size()-3) + "mtl";
|
||||
if (!use_world_coords) {
|
||||
Logger::Message(Logger::LOG_NOTICE, "Using world coords when writing WaveFront OBJ files");
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::USE_WORLD_COORDS, true);
|
||||
settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, true);
|
||||
}
|
||||
serializer = new WaveFrontOBJSerializer(output_filename, mtl_filename);
|
||||
#ifdef WITH_OPENCOLLADA
|
||||
@@ -219,6 +222,8 @@ int main(int argc, char** argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
IfcGeom::Iterator<double> context_iterator(settings, input_filename);
|
||||
|
||||
if (!serializer->ready()) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Unable to open output file for writing");
|
||||
write_log();
|
||||
@@ -226,7 +231,7 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
if (!serializer->isTesselated()) {
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::DISABLE_TRIANGULATION, true);
|
||||
|
||||
if (weld_vertices) {
|
||||
Logger::Message(Logger::LOG_NOTICE, "Weld vertices setting ignored when writing STEP or IGES files");
|
||||
}
|
||||
@@ -235,14 +240,14 @@ int main(int argc, char** argv) {
|
||||
time_t start,end;
|
||||
time(&start);
|
||||
// Parse the file supplied in argv[1]. Returns true on succes.
|
||||
if ( ! IfcGeomObjects::Init(input_filename, &std::cout, &log_stream) ) {
|
||||
if (!context_iterator.findContext()) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Unable to parse .ifc file or no geometrical entities found");
|
||||
write_log();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (convert_back_units) {
|
||||
serializer->setUnitNameAndMagnitude(IfcGeomObjects::GetUnitName(), IfcGeomObjects::GetUnitMagnitude());
|
||||
serializer->setUnitNameAndMagnitude(context_iterator.getUnitName(), context_iterator.getUnitMagnitude());
|
||||
} else {
|
||||
serializer->setUnitNameAndMagnitude("METER", 1.0f);
|
||||
}
|
||||
@@ -255,16 +260,10 @@ int main(int argc, char** argv) {
|
||||
Logger::Status("Creating geometry...");
|
||||
|
||||
// The functions IfcGeomObjects::Get() and IfcGeomObjects::Next() wrap an iterator of all geometrical entities in the Ifc file.
|
||||
// IfcGeomObjects::Get() returns an IfcGeomObjects::IfcGeomObject (see IfcGeomObjects.h for definition)
|
||||
// IfcGeomObjects::Get() returns an IfcGeom::TriangulationElement (see IfcGeomIterator.h for definition)
|
||||
// IfcGeomObjects::Next() is used to poll whether more geometrical entities are available
|
||||
do {
|
||||
const IfcGeomObjects::IfcObject* geom_object;
|
||||
|
||||
if (serializer->isTesselated()) {
|
||||
geom_object = IfcGeomObjects::Get();
|
||||
} else {
|
||||
geom_object = IfcGeomObjects::GetShapeModel();
|
||||
}
|
||||
const IfcGeom::Element<double>* geom_object = context_iterator.get();
|
||||
|
||||
std::string lowercase_type = geom_object->type();
|
||||
for (std::string::iterator c = lowercase_type.begin(); c != lowercase_type.end(); ++c) {
|
||||
@@ -273,16 +272,16 @@ int main(int argc, char** argv) {
|
||||
if (ignore_types.find(lowercase_type) != ignore_types.end()) continue;
|
||||
|
||||
if (serializer->isTesselated()) {
|
||||
serializer->writeTesselated(static_cast<const IfcGeomObjects::IfcGeomObject*>(geom_object));
|
||||
serializer->write(static_cast<const IfcGeom::TriangulationElement<double>*>(geom_object));
|
||||
} else {
|
||||
serializer->writeShapeModel(static_cast<const IfcGeomObjects::IfcGeomShapeModelObject*>(geom_object));
|
||||
serializer->write(static_cast<const IfcGeom::ShapeModelElement<double>*>(geom_object));
|
||||
}
|
||||
|
||||
const int progress = IfcGeomObjects::Progress() / 2;
|
||||
if ( old_progress!= progress ) Logger::ProgressBar(progress);
|
||||
|
||||
const int progress = context_iterator.progress() / 2;
|
||||
if (old_progress!= progress) Logger::ProgressBar(progress);
|
||||
old_progress = progress;
|
||||
|
||||
} while ( IfcGeomObjects::Next() );
|
||||
} while (context_iterator.next());
|
||||
|
||||
serializer->finalize();
|
||||
delete serializer;
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <IGESControl_Writer.hxx>
|
||||
#include <Interface_Static.hxx>
|
||||
|
||||
#include "../ifcgeom/IfcGeomObjects.h"
|
||||
#include "../ifcgeom/IfcGeomIterator.h"
|
||||
|
||||
#include "../ifcconvert/OpenCascadeBasedSerializer.h"
|
||||
|
||||
|
||||
@@ -34,17 +34,19 @@ bool OpenCascadeBasedSerializer::ready() {
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
void OpenCascadeBasedSerializer::writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o) {
|
||||
for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = o->mesh().begin(); it != o->mesh().end(); ++ it) {
|
||||
void OpenCascadeBasedSerializer::write(const IfcGeom::ShapeModelElement<double>* o) {
|
||||
for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = o->geometry().begin(); it != o->geometry().end(); ++ it) {
|
||||
gp_GTrsf gtrsf = it->Placement();
|
||||
|
||||
const std::vector<double>& matrix = o->transformation().matrix().data();
|
||||
|
||||
// Convert the matrix back into a transformation object. The tolerance values
|
||||
// are taken into consideration to reconstruct the form of the transformation.
|
||||
gp_Trsf o_trsf;
|
||||
o_trsf.SetValues(
|
||||
o->matrix()[0], o->matrix()[3], o->matrix()[6], o->matrix()[ 9],
|
||||
o->matrix()[1], o->matrix()[4], o->matrix()[7], o->matrix()[10],
|
||||
o->matrix()[2], o->matrix()[5], o->matrix()[8], o->matrix()[11],
|
||||
matrix[0], matrix[3], matrix[6], matrix[ 9],
|
||||
matrix[1], matrix[4], matrix[7], matrix[10],
|
||||
matrix[2], matrix[5], matrix[8], matrix[11],
|
||||
1e-5, 1e-5
|
||||
);
|
||||
gtrsf.PreMultiply(o_trsf);
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef OPENCASCADEBASEDSERIALIZER_H
|
||||
#define OPENCASCADEBASEDSERIALIZER_H
|
||||
|
||||
#include "../ifcgeom/IfcGeomObjects.h"
|
||||
#include "../ifcgeom/IfcGeomIterator.h"
|
||||
|
||||
#include "../ifcconvert/GeometrySerializer.h"
|
||||
|
||||
@@ -38,8 +38,8 @@ public:
|
||||
void writeMaterial(const IfcGeom::SurfaceStyle& style) {}
|
||||
bool ready();
|
||||
virtual void writeShape(const TopoDS_Shape& shape) = 0;
|
||||
void writeTesselated(const IfcGeomObjects::IfcGeomObject* o) {}
|
||||
void writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o);
|
||||
void write(const IfcGeom::TriangulationElement<double>* o) {}
|
||||
void write(const IfcGeom::ShapeModelElement<double>* o);
|
||||
bool isTesselated() const { return false; }
|
||||
};
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <STEPControl_Writer.hxx>
|
||||
#include <Interface_Static.hxx>
|
||||
|
||||
#include "../ifcgeom/IfcGeomObjects.h"
|
||||
#include "../ifcgeom/IfcGeomIterator.h"
|
||||
|
||||
#include "../ifcconvert/OpenCascadeBasedSerializer.h"
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ void WaveFrontOBJSerializer::writeHeader() {
|
||||
mtl_stream << "# File generated by IfcOpenShell " << IFCOPENSHELL_VERSION << "\n";
|
||||
}
|
||||
|
||||
void WaveFrontOBJSerializer::writeMaterial(const IfcGeomObjects::Material& style) {
|
||||
void WaveFrontOBJSerializer::writeMaterial(const IfcGeom::Material& style) {
|
||||
mtl_stream << "newmtl " << style.name() << "\n";
|
||||
if (style.hasDiffuse()) {
|
||||
const double* diffuse = style.diffuse();
|
||||
@@ -65,7 +65,7 @@ void WaveFrontOBJSerializer::writeMaterial(const IfcGeomObjects::Material& style
|
||||
}
|
||||
}
|
||||
}
|
||||
void WaveFrontOBJSerializer::writeTesselated(const IfcGeomObjects::IfcGeomObject* o) {
|
||||
void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement<double>* o) {
|
||||
|
||||
std::string tmp = o->name().empty() ? o->guid() : o->name();
|
||||
|
||||
@@ -74,16 +74,16 @@ void WaveFrontOBJSerializer::writeTesselated(const IfcGeomObjects::IfcGeomObject
|
||||
obj_stream << "g " << name << "\n";
|
||||
obj_stream << "s 1" << "\n";
|
||||
|
||||
const IfcGeomObjects::IfcRepresentationTriangulation& mesh = o->mesh();
|
||||
const IfcGeom::Representation::Triangulation<double>& mesh = o->geometry();
|
||||
|
||||
const int vcount = mesh.verts().size() / 3;
|
||||
for ( std::vector<float>::const_iterator it = mesh.verts().begin(); it != mesh.verts().end(); ) {
|
||||
for ( std::vector<double>::const_iterator it = mesh.verts().begin(); it != mesh.verts().end(); ) {
|
||||
const double x = *(it++);
|
||||
const double y = *(it++);
|
||||
const double z = *(it++);
|
||||
obj_stream << "v " << x << " " << y << " " << z << "\n";
|
||||
}
|
||||
for ( std::vector<float>::const_iterator it = mesh.normals().begin(); it != mesh.normals().end(); ) {
|
||||
for ( std::vector<double>::const_iterator it = mesh.normals().begin(); it != mesh.normals().end(); ) {
|
||||
const double x = *(it++);
|
||||
const double y = *(it++);
|
||||
const double z = *(it++);
|
||||
@@ -97,12 +97,7 @@ void WaveFrontOBJSerializer::writeTesselated(const IfcGeomObjects::IfcGeomObject
|
||||
|
||||
const int material_id = *(material_it++);
|
||||
if (material_id != previous_material_id) {
|
||||
IfcGeomObjects::Material material(0);
|
||||
if (material_id >= 0) {
|
||||
material = mesh.materials()[material_id];
|
||||
} else {
|
||||
material = IfcGeomObjects::Material(IfcGeom::get_default_style(o->type()));
|
||||
}
|
||||
const IfcGeom::Material& material = mesh.materials()[material_id];
|
||||
const std::string material_name = material.name();
|
||||
obj_stream << "usemtl " << material_name << "\n";
|
||||
if (materials.find(material_name) == materials.end()) {
|
||||
|
||||
@@ -44,9 +44,9 @@ public:
|
||||
virtual ~WaveFrontOBJSerializer() {}
|
||||
bool ready();
|
||||
void writeHeader();
|
||||
void writeMaterial(const IfcGeomObjects::Material& style);
|
||||
void writeTesselated(const IfcGeomObjects::IfcGeomObject* o);
|
||||
void writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o) {}
|
||||
void writeMaterial(const IfcGeom::Material& style);
|
||||
void write(const IfcGeom::TriangulationElement<double>* o);
|
||||
void write(const IfcGeom::ShapeModelElement<double>* o) {}
|
||||
void finalize() {}
|
||||
bool isTesselated() const { return true; }
|
||||
void setUnitNameAndMagnitude(const std::string& name, float magnitude) {}
|
||||
|
||||
+61
-6
@@ -43,8 +43,23 @@
|
||||
|
||||
#include "../ifcgeom/IfcRepresentationShapeItem.h"
|
||||
|
||||
#define IN_CACHE(T,E,t,e) std::map<int,t>::const_iterator it = cache.T.find(E->entity->id());\
|
||||
if ( it != cache.T.end() ) { e = it->second; return true; }
|
||||
#define CACHE(T,E,e) cache.T[E->entity->id()] = e;
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
class Cache {
|
||||
public:
|
||||
#include "IfcRegisterCreateCache.h"
|
||||
std::map<int, SurfaceStyle> Style;
|
||||
std::map<int, TopoDS_Shape> Shape;
|
||||
};
|
||||
|
||||
class Kernel {
|
||||
private:
|
||||
Cache cache;
|
||||
public:
|
||||
// Tolerances and settings for various geometrical operations:
|
||||
enum GeomValue {
|
||||
// Specifies the deflection of the mesher
|
||||
@@ -103,17 +118,57 @@ namespace IfcGeom {
|
||||
double shape_volume(const TopoDS_Shape& s);
|
||||
double face_area(const TopoDS_Face& f);
|
||||
void apply_tolerance(TopoDS_Shape& s, double t);
|
||||
void SetValue(GeomValue var, double value);
|
||||
double GetValue(GeomValue var);
|
||||
void setValue(GeomValue var, double value);
|
||||
double getValue(GeomValue var);
|
||||
bool fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& shape);
|
||||
IfcSchema::IfcProductDefinitionShape* tesselate(TopoDS_Shape& shape, double deflection, IfcEntityList::ptr es);
|
||||
void remove_redundant_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol=-1.);
|
||||
|
||||
const SurfaceStyle* get_style(const IfcSchema::IfcRepresentationItem* representation_item);
|
||||
|
||||
|
||||
namespace Cache {
|
||||
void Purge();
|
||||
void PurgeShapeCache();
|
||||
template <typename T> std::pair<IfcSchema::IfcSurfaceStyle*, T*> get_surface_style(const IfcSchema::IfcRepresentationItem* representation_item) {
|
||||
IfcSchema::IfcStyledItem::list::ptr styled_items = representation_item->StyledByItem();
|
||||
for (IfcSchema::IfcStyledItem::list::it jt = styled_items->begin(); jt != styled_items->end(); ++jt) {
|
||||
#ifdef USE_IFC4
|
||||
IfcUtil::IfcAbstractSelect::list::ptr style_assignments = (*jt)->Styles();
|
||||
for (IfcUtil::IfcAbstractSelect::list::it kt = style_assignments->begin(); kt != style_assignments->end(); ++kt) {
|
||||
if (!(*kt)->is(IfcSchema::Type::IfcPresentationStyleAssignment)) {
|
||||
continue;
|
||||
}
|
||||
IfcSchema::IfcPresentationStyleAssignment* style_assignment = (IfcSchema::IfcPresentationStyleAssignment*) *kt;
|
||||
#else
|
||||
IfcSchema::IfcPresentationStyleAssignment::list::ptr style_assignments = (*jt)->Styles();
|
||||
for (IfcSchema::IfcPresentationStyleAssignment::list::it kt = style_assignments->begin(); kt != style_assignments->end(); ++kt) {
|
||||
IfcSchema::IfcPresentationStyleAssignment* style_assignment = *kt;
|
||||
#endif
|
||||
IfcUtil::IfcAbstractSelect::list::ptr styles = style_assignment->Styles();
|
||||
for (IfcUtil::IfcAbstractSelect::list::it lt = styles->begin(); lt != styles->end(); ++lt) {
|
||||
IfcUtil::IfcAbstractSelect* style = *lt;
|
||||
if (style->is(IfcSchema::Type::IfcSurfaceStyle)) {
|
||||
IfcSchema::IfcSurfaceStyle* surface_style = (IfcSchema::IfcSurfaceStyle*) style;
|
||||
if (surface_style->Side() != IfcSchema::IfcSurfaceSide::IfcSurfaceSide_NEGATIVE) {
|
||||
IfcUtil::IfcAbstractSelect::list::ptr styles_elements = surface_style->Styles();
|
||||
for (IfcUtil::IfcAbstractSelect::list::it mt = styles_elements->begin(); mt != styles_elements->end(); ++mt) {
|
||||
if ((*mt)->is(T::Class())) {
|
||||
return std::make_pair(surface_style, (T*) *mt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StyledByItem is a SET [0:1] OF IfcStyledItem, so we
|
||||
// break after encountering the first IfcStyledItem
|
||||
break;
|
||||
}
|
||||
|
||||
return std::make_pair<IfcSchema::IfcSurfaceStyle*, T*>(0,0);
|
||||
}
|
||||
|
||||
#include "IfcRegisterGeomHeader.h"
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -79,8 +79,8 @@
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcCircle* l, Handle(Geom_Curve)& curve) {
|
||||
const double r = l->Radius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCircle* l, Handle(Geom_Curve)& curve) {
|
||||
const double r = l->Radius() * getValue(GV_LENGTH_UNIT);
|
||||
if ( r < ALMOST_ZERO ) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Radius not greater than zero for:", l->entity);
|
||||
return false;
|
||||
@@ -88,19 +88,19 @@ bool IfcGeom::convert(const IfcSchema::IfcCircle* l, Handle(Geom_Curve)& curve)
|
||||
gp_Trsf trsf;
|
||||
IfcSchema::IfcAxis2Placement placement = l->Position();
|
||||
if (placement->is(IfcSchema::Type::IfcAxis2Placement3D)) {
|
||||
IfcGeom::convert((IfcSchema::IfcAxis2Placement3D*)placement,trsf);
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcAxis2Placement3D*)placement,trsf);
|
||||
} else {
|
||||
gp_Trsf2d trsf2d;
|
||||
IfcGeom::convert((IfcAxis2Placement2D*)placement,trsf2d);
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcAxis2Placement2D*)placement,trsf2d);
|
||||
trsf = trsf2d;
|
||||
}
|
||||
gp_Ax2 ax = gp_Ax2().Transformed(trsf);
|
||||
curve = new Geom_Circle(ax, r);
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const IfcSchema::IfcEllipse* l, Handle(Geom_Curve)& curve) {
|
||||
double x = l->SemiAxis1() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
double y = l->SemiAxis2() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcEllipse* l, Handle(Geom_Curve)& curve) {
|
||||
double x = l->SemiAxis1() * getValue(GV_LENGTH_UNIT);
|
||||
double y = l->SemiAxis2() * getValue(GV_LENGTH_UNIT);
|
||||
if (x < ALMOST_ZERO || y < ALMOST_ZERO) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Radius not greater than zero for:", l->entity);
|
||||
return false;
|
||||
@@ -113,10 +113,10 @@ bool IfcGeom::convert(const IfcSchema::IfcEllipse* l, Handle(Geom_Curve)& curve)
|
||||
gp_Trsf trsf;
|
||||
IfcSchema::IfcAxis2Placement placement = l->Position();
|
||||
if (placement->is(IfcSchema::Type::IfcAxis2Placement3D)) {
|
||||
IfcGeom::convert((IfcSchema::IfcAxis2Placement3D*)placement,trsf);
|
||||
convert((IfcSchema::IfcAxis2Placement3D*)placement,trsf);
|
||||
} else {
|
||||
gp_Trsf2d trsf2d;
|
||||
IfcGeom::convert((IfcSchema::IfcAxis2Placement2D*)placement,trsf2d);
|
||||
convert((IfcSchema::IfcAxis2Placement2D*)placement,trsf2d);
|
||||
trsf = trsf2d;
|
||||
}
|
||||
gp_Ax2 ax = gp_Ax2();
|
||||
@@ -128,10 +128,10 @@ bool IfcGeom::convert(const IfcSchema::IfcEllipse* l, Handle(Geom_Curve)& curve)
|
||||
curve = new Geom_Ellipse(ax, x, y);
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const IfcSchema::IfcLine* l, Handle(Geom_Curve)& curve) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcLine* l, Handle(Geom_Curve)& curve) {
|
||||
gp_Pnt pnt;gp_Vec vec;
|
||||
IfcGeom::convert(l->Pnt(),pnt);
|
||||
IfcGeom::convert(l->Dir(),vec);
|
||||
convert(l->Pnt(),pnt);
|
||||
convert(l->Dir(),vec);
|
||||
// See note at IfcGeomWires.cpp:237
|
||||
curve = new Geom_Line(pnt,vec);
|
||||
return true;
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 IFCGEOMELEMENT_H
|
||||
#define IFCGEOMELEMENT_H
|
||||
|
||||
#include "../ifcgeom/IfcGeomRepresentation.h"
|
||||
#include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
template <typename P>
|
||||
class Matrix {
|
||||
private:
|
||||
std::vector<P> _data;
|
||||
public:
|
||||
Matrix(const ElementSettings& settings, const gp_Trsf& 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
|
||||
// by the magnitude of the IFC model length unit because
|
||||
// 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 matrix_value = i == 4 && settings.convert_back_units()
|
||||
? trsf_value / settings.unit_magnitude()
|
||||
: trsf_value;
|
||||
_data.push_back(static_cast<P>(matrix_value));
|
||||
}
|
||||
}
|
||||
}
|
||||
const std::vector<P>& data() const { return _data; }
|
||||
};
|
||||
|
||||
template <typename P>
|
||||
class Transformation {
|
||||
private:
|
||||
gp_Trsf trsf;
|
||||
Matrix<P> _matrix;
|
||||
public:
|
||||
Transformation(const ElementSettings& settings, const gp_Trsf& trsf)
|
||||
: trsf(trsf)
|
||||
, _matrix(settings, trsf)
|
||||
{}
|
||||
const gp_Trsf& data() const { return trsf; }
|
||||
const Matrix<P>& matrix() const { return _matrix; }
|
||||
};
|
||||
|
||||
template <typename P>
|
||||
class Element {
|
||||
private:
|
||||
int _id;
|
||||
int _parent_id;
|
||||
std::string _name;
|
||||
std::string _type;
|
||||
std::string _guid;
|
||||
Transformation<P> _transformation;
|
||||
public:
|
||||
int id() const { return _id; }
|
||||
int parent_id() const { return _parent_id; }
|
||||
const std::string& name() const { return _name; }
|
||||
const std::string& type() const { return _type; }
|
||||
const std::string& guid() const { return _guid; }
|
||||
const Transformation<P>& transformation() const { return _transformation; }
|
||||
Element(const ElementSettings& settings, int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid, const gp_Trsf& trsf)
|
||||
: _id(id), _parent_id(parent_id), _name(name), _type(type), _guid(guid), _transformation(settings, trsf)
|
||||
{}
|
||||
virtual ~Element() {}
|
||||
};
|
||||
|
||||
template <typename P>
|
||||
class ShapeModelElement : public Element<P> {
|
||||
private:
|
||||
Representation::BRep* _geometry;
|
||||
public:
|
||||
const Representation::BRep& geometry() const { return *_geometry; }
|
||||
ShapeModelElement(int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid, const gp_Trsf& trsf, Representation::BRep* geometry)
|
||||
: Element(geometry->settings(),id,parent_id,name,type,guid,trsf)
|
||||
, _geometry(geometry)
|
||||
{}
|
||||
virtual ~ShapeModelElement() {
|
||||
delete _geometry;
|
||||
}
|
||||
private:
|
||||
ShapeModelElement(const ShapeModelElement& other);
|
||||
ShapeModelElement& operator=(const ShapeModelElement& other);
|
||||
};
|
||||
|
||||
template <typename P>
|
||||
class TriangulationElement : public Element<P> {
|
||||
private:
|
||||
Representation::Triangulation<P>* _geometry;
|
||||
public:
|
||||
const Representation::Triangulation<P>& geometry() const { return *_geometry; }
|
||||
TriangulationElement(const ShapeModelElement<P>& shape_model)
|
||||
: Element<P>(shape_model)
|
||||
, _geometry(new Representation::Triangulation<P>(shape_model.geometry()))
|
||||
{}
|
||||
virtual ~TriangulationElement() {
|
||||
delete _geometry;
|
||||
}
|
||||
private:
|
||||
TriangulationElement(const TriangulationElement& other);
|
||||
TriangulationElement& operator=(const TriangulationElement& other);
|
||||
};
|
||||
|
||||
template <typename P>
|
||||
class SerializedElement : public Element<P> {
|
||||
private:
|
||||
Representation::Serialization* _geometry;
|
||||
public:
|
||||
const Representation::Serialization& geometry() const { return *_geometry; }
|
||||
SerializedElement(const ShapeModelElement<P>& shape_model)
|
||||
: Element<P>(shape_model)
|
||||
, _geometry(new Representation::Serialization(shape_model.geometry()))
|
||||
{}
|
||||
virtual ~SerializedElement() {
|
||||
delete _geometry;
|
||||
}
|
||||
private:
|
||||
SerializedElement(const SerializedElement& other);
|
||||
SerializedElement& operator=(const SerializedElement& other);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
+120
-120
@@ -97,12 +97,12 @@
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcFace* l, TopoDS_Shape& face) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcFace* l, TopoDS_Shape& face) {
|
||||
IfcSchema::IfcFaceBound::list::ptr bounds = l->Bounds();
|
||||
IfcSchema::IfcFaceBound::list::it it = bounds->begin();
|
||||
IfcSchema::IfcLoop* loop = (*it)->Bound();
|
||||
TopoDS_Wire outer_wire;
|
||||
if ( ! IfcGeom::convert_wire(loop,outer_wire) ) return false;
|
||||
if ( ! convert_wire(loop,outer_wire) ) return false;
|
||||
BRepBuilderAPI_MakeFace mf (outer_wire);
|
||||
BRepBuilderAPI_FaceError er = mf.Error();
|
||||
if ( er == BRepBuilderAPI_NotPlanar ) {
|
||||
@@ -119,7 +119,7 @@ bool IfcGeom::convert(const IfcSchema::IfcFace* l, TopoDS_Shape& face) {
|
||||
for( ++it; it != bounds->end(); ++ it) {
|
||||
IfcSchema::IfcLoop* loop = (*it)->Bound();
|
||||
TopoDS_Wire wire;
|
||||
if ( ! IfcGeom::convert_wire(loop,wire) ) return false;
|
||||
if ( ! convert_wire(loop,wire) ) return false;
|
||||
mf.Add(wire);
|
||||
}
|
||||
if ( mf.IsDone() ) {
|
||||
@@ -137,7 +137,7 @@ bool IfcGeom::convert(const IfcSchema::IfcFace* l, TopoDS_Shape& face) {
|
||||
}
|
||||
}
|
||||
|
||||
if ( IfcGeom::GetValue(GV_FORCE_CCW_FACE_ORIENTATION)>0 ) {
|
||||
if ( getValue(GV_FORCE_CCW_FACE_ORIENTATION)>0 ) {
|
||||
// Check the orientation of the face by comparing the
|
||||
// normal of the topological surface to the Newell's Method's
|
||||
// normal. Newell's Method is used for the normal calculation
|
||||
@@ -206,24 +206,24 @@ bool IfcGeom::convert(const IfcSchema::IfcFace* l, TopoDS_Shape& face) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcArbitraryClosedProfileDef* l, TopoDS_Shape& face) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcArbitraryClosedProfileDef* l, TopoDS_Shape& face) {
|
||||
TopoDS_Wire wire;
|
||||
if ( ! IfcGeom::convert_wire(l->OuterCurve(),wire) ) return false;
|
||||
if ( ! convert_wire(l->OuterCurve(),wire) ) return false;
|
||||
|
||||
TopoDS_Face f;
|
||||
bool success = IfcGeom::convert_wire_to_face(wire, f);
|
||||
bool success = convert_wire_to_face(wire, f);
|
||||
if (success) face = f;
|
||||
return success;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcArbitraryProfileDefWithVoids* l, TopoDS_Shape& face) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcArbitraryProfileDefWithVoids* l, TopoDS_Shape& face) {
|
||||
TopoDS_Wire profile;
|
||||
if ( ! IfcGeom::convert_wire(l->OuterCurve(),profile) ) return false;
|
||||
if ( ! convert_wire(l->OuterCurve(),profile) ) return false;
|
||||
BRepBuilderAPI_MakeFace mf(profile);
|
||||
IfcSchema::IfcCurve::list::ptr voids = l->InnerCurves();
|
||||
for( IfcSchema::IfcCurve::list::it it = voids->begin(); it != voids->end(); ++ it ) {
|
||||
TopoDS_Wire hole;
|
||||
if ( IfcGeom::convert_wire(*it,hole) ) {
|
||||
if ( convert_wire(*it,hole) ) {
|
||||
mf.Add(hole);
|
||||
}
|
||||
}
|
||||
@@ -233,9 +233,9 @@ bool IfcGeom::convert(const IfcSchema::IfcArbitraryProfileDefWithVoids* l, TopoD
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcRectangleProfileDef* l, TopoDS_Shape& face) {
|
||||
const double x = l->XDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double y = l->YDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcRectangleProfileDef* l, TopoDS_Shape& face) {
|
||||
const double x = l->XDim() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
const double y = l->YDim() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
|
||||
if ( x < ALMOST_ZERO || y < ALMOST_ZERO ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
@@ -243,15 +243,15 @@ bool IfcGeom::convert(const IfcSchema::IfcRectangleProfileDef* l, TopoDS_Shape&
|
||||
}
|
||||
|
||||
gp_Trsf2d trsf2d;
|
||||
IfcGeom::convert(l->Position(),trsf2d);
|
||||
IfcGeom::Kernel::convert(l->Position(),trsf2d);
|
||||
double coords[8] = {-x,-y,x,-y,x,y,-x,y};
|
||||
return IfcGeom::profile_helper(4,coords,0,0,0,trsf2d,face);
|
||||
return profile_helper(4,coords,0,0,0,trsf2d,face);
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcRoundedRectangleProfileDef* l, TopoDS_Shape& face) {
|
||||
const double x = l->XDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double y = l->YDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double r = l->RoundingRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcRoundedRectangleProfileDef* l, TopoDS_Shape& face) {
|
||||
const double x = l->XDim() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
const double y = l->YDim() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
const double r = l->RoundingRadius() * getValue(GV_LENGTH_UNIT);
|
||||
|
||||
if ( x < ALMOST_ZERO || y < ALMOST_ZERO || r < ALMOST_ZERO ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
@@ -259,23 +259,23 @@ bool IfcGeom::convert(const IfcSchema::IfcRoundedRectangleProfileDef* l, TopoDS_
|
||||
}
|
||||
|
||||
gp_Trsf2d trsf2d;
|
||||
IfcGeom::convert(l->Position(),trsf2d);
|
||||
IfcGeom::Kernel::convert(l->Position(),trsf2d);
|
||||
double coords[8] = {-x,-y, x,-y, x,y, -x,y};
|
||||
int fillets[4] = {0,1,2,3};
|
||||
double radii[4] = {r,r,r,r};
|
||||
return IfcGeom::profile_helper(4,coords,4,fillets,radii,trsf2d,face);
|
||||
return profile_helper(4,coords,4,fillets,radii,trsf2d,face);
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcRectangleHollowProfileDef* l, TopoDS_Shape& face) {
|
||||
const double x = l->XDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double y = l->YDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double d = l->WallThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcRectangleHollowProfileDef* l, TopoDS_Shape& face) {
|
||||
const double x = l->XDim() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
const double y = l->YDim() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
const double d = l->WallThickness() * getValue(GV_LENGTH_UNIT);
|
||||
|
||||
const bool fr1 = l->hasOuterFilletRadius();
|
||||
const bool fr2 = l->hasInnerFilletRadius();
|
||||
|
||||
const double r1 = fr1 ? l->OuterFilletRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT) : 0.;
|
||||
const double r2 = fr2 ? l->InnerFilletRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT) : 0.;
|
||||
const double r1 = fr1 ? l->OuterFilletRadius() * getValue(GV_LENGTH_UNIT) : 0.;
|
||||
const double r2 = fr2 ? l->InnerFilletRadius() * getValue(GV_LENGTH_UNIT) : 0.;
|
||||
|
||||
if ( x < ALMOST_ZERO || y < ALMOST_ZERO ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
@@ -286,15 +286,15 @@ bool IfcGeom::convert(const IfcSchema::IfcRectangleHollowProfileDef* l, TopoDS_S
|
||||
TopoDS_Face f2;
|
||||
|
||||
gp_Trsf2d trsf2d;
|
||||
IfcGeom::convert(l->Position(),trsf2d);
|
||||
IfcGeom::Kernel::convert(l->Position(),trsf2d);
|
||||
double coords1[8] = {-x ,-y, x ,-y, x, y, -x, y };
|
||||
double coords2[8] = {-x+d,-y+d, x-d,-y+d, x-d,y-d, -x+d,y-d};
|
||||
double radii1[4] = {r1,r1,r1,r1};
|
||||
double radii2[4] = {r2,r2,r2,r2};
|
||||
int fillets[4] = {0,1,2,3};
|
||||
|
||||
bool s1 = IfcGeom::profile_helper(4,coords1,fr1 ? 4 : 0,fillets,radii1,trsf2d,f1);
|
||||
bool s2 = IfcGeom::profile_helper(4,coords2,fr2 ? 4 : 0,fillets,radii2,trsf2d,f2);
|
||||
bool s1 = profile_helper(4,coords1,fr1 ? 4 : 0,fillets,radii1,trsf2d,f1);
|
||||
bool s2 = profile_helper(4,coords2,fr2 ? 4 : 0,fillets,radii2,trsf2d,f2);
|
||||
|
||||
if (!s1 || !s2) return false;
|
||||
|
||||
@@ -313,11 +313,11 @@ bool IfcGeom::convert(const IfcSchema::IfcRectangleHollowProfileDef* l, TopoDS_S
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcTrapeziumProfileDef* l, TopoDS_Shape& face) {
|
||||
const double x1 = l->BottomXDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double w = l->TopXDim() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double dx = l->TopXOffset() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double y = l->YDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcTrapeziumProfileDef* l, TopoDS_Shape& face) {
|
||||
const double x1 = l->BottomXDim() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
const double w = l->TopXDim() * getValue(GV_LENGTH_UNIT);
|
||||
const double dx = l->TopXOffset() * getValue(GV_LENGTH_UNIT);
|
||||
const double y = l->YDim() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
|
||||
if ( x1 < ALMOST_ZERO || w < ALMOST_ZERO || y < ALMOST_ZERO ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
@@ -325,21 +325,21 @@ bool IfcGeom::convert(const IfcSchema::IfcTrapeziumProfileDef* l, TopoDS_Shape&
|
||||
}
|
||||
|
||||
gp_Trsf2d trsf2d;
|
||||
IfcGeom::convert(l->Position(),trsf2d);
|
||||
IfcGeom::Kernel::convert(l->Position(),trsf2d);
|
||||
double coords[8] = {-x1,-y, x1,-y, dx+w-x1,y, dx-x1,y};
|
||||
return IfcGeom::profile_helper(4,coords,0,0,0,trsf2d,face);
|
||||
return profile_helper(4,coords,0,0,0,trsf2d,face);
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcIShapeProfileDef* l, TopoDS_Shape& face) {
|
||||
const double x1 = l->OverallWidth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double y = l->OverallDepth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double d1 = l->WebThickness() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double dy1 = l->FlangeThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcIShapeProfileDef* l, TopoDS_Shape& face) {
|
||||
const double x1 = l->OverallWidth() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
const double y = l->OverallDepth() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
const double d1 = l->WebThickness() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
const double dy1 = l->FlangeThickness() * getValue(GV_LENGTH_UNIT);
|
||||
|
||||
bool doFillet1 = l->hasFilletRadius();
|
||||
double f1 = 0.;
|
||||
if ( doFillet1 ) {
|
||||
f1 = l->FilletRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
f1 = l->FilletRadius() * getValue(GV_LENGTH_UNIT);
|
||||
}
|
||||
|
||||
bool doFillet2 = doFillet1;
|
||||
@@ -347,13 +347,13 @@ bool IfcGeom::convert(const IfcSchema::IfcIShapeProfileDef* l, TopoDS_Shape& fac
|
||||
|
||||
if (l->is(IfcSchema::Type::IfcAsymmetricIShapeProfileDef)) {
|
||||
IfcSchema::IfcAsymmetricIShapeProfileDef* assym = (IfcSchema::IfcAsymmetricIShapeProfileDef*) l;
|
||||
x2 = assym->TopFlangeWidth() / 2. * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
x2 = assym->TopFlangeWidth() / 2. * getValue(GV_LENGTH_UNIT);
|
||||
doFillet2 = assym->hasTopFlangeFilletRadius();
|
||||
if (doFillet2) {
|
||||
f2 = assym->TopFlangeFilletRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
f2 = assym->TopFlangeFilletRadius() * getValue(GV_LENGTH_UNIT);
|
||||
}
|
||||
if (assym->hasTopFlangeThickness()) {
|
||||
dy2 = assym->TopFlangeThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
dy2 = assym->TopFlangeThickness() * getValue(GV_LENGTH_UNIT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,19 +363,19 @@ bool IfcGeom::convert(const IfcSchema::IfcIShapeProfileDef* l, TopoDS_Shape& fac
|
||||
}
|
||||
|
||||
gp_Trsf2d trsf2d;
|
||||
IfcGeom::convert(l->Position(),trsf2d);
|
||||
convert(l->Position(),trsf2d);
|
||||
|
||||
double coords[24] = {-x1,-y, x1,-y, x1,-y+dy1, d1,-y+dy1, d1,y-dy2, x2,y-dy2, x2,y, -x2,y, -x2,y-dy2, -d1,y-dy2, -d1,-y+dy1, -x1,-y+dy1};
|
||||
int fillets[4] = {3,4,9,10};
|
||||
double radii[4] = {f1,f1,f2,f2};
|
||||
return IfcGeom::profile_helper(12,coords,(doFillet1||doFillet2) ? 4 : 0,fillets,radii,trsf2d,face);
|
||||
return profile_helper(12,coords,(doFillet1||doFillet2) ? 4 : 0,fillets,radii,trsf2d,face);
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcZShapeProfileDef* l, TopoDS_Shape& face) {
|
||||
const double x = l->FlangeWidth() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double y = l->Depth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double dx = l->WebThickness() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double dy = l->FlangeThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcZShapeProfileDef* l, TopoDS_Shape& face) {
|
||||
const double x = l->FlangeWidth() * getValue(GV_LENGTH_UNIT);
|
||||
const double y = l->Depth() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
const double dx = l->WebThickness() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
const double dy = l->FlangeThickness() * getValue(GV_LENGTH_UNIT);
|
||||
|
||||
bool doFillet = l->hasFilletRadius();
|
||||
bool doEdgeFillet = l->hasEdgeRadius();
|
||||
@@ -384,10 +384,10 @@ bool IfcGeom::convert(const IfcSchema::IfcZShapeProfileDef* l, TopoDS_Shape& fac
|
||||
double f2 = 0.;
|
||||
|
||||
if ( doFillet ) {
|
||||
f1 = l->FilletRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
f1 = l->FilletRadius() * getValue(GV_LENGTH_UNIT);
|
||||
}
|
||||
if ( doEdgeFillet ) {
|
||||
f2 = l->EdgeRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
f2 = l->EdgeRadius() * getValue(GV_LENGTH_UNIT);
|
||||
}
|
||||
|
||||
if ( x == 0.0f || y == 0.0f || dx == 0.0f || dy == 0.0f ) {
|
||||
@@ -396,24 +396,24 @@ bool IfcGeom::convert(const IfcSchema::IfcZShapeProfileDef* l, TopoDS_Shape& fac
|
||||
}
|
||||
|
||||
gp_Trsf2d trsf2d;
|
||||
IfcGeom::convert(l->Position(),trsf2d);
|
||||
IfcGeom::Kernel::convert(l->Position(),trsf2d);
|
||||
|
||||
double coords[16] = {-dx,-y, x,-y, x,-y+dy, dx,-y+dy, dx,y, -x,y, -x,y-dy, -dx,y-dy};
|
||||
int fillets[4] = {2,3,6,7};
|
||||
double radii[4] = {f2,f1,f2,f1};
|
||||
return IfcGeom::profile_helper(8,coords,(doFillet || doEdgeFillet) ? 4 : 0,fillets,radii,trsf2d,face);
|
||||
return profile_helper(8,coords,(doFillet || doEdgeFillet) ? 4 : 0,fillets,radii,trsf2d,face);
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcCShapeProfileDef* l, TopoDS_Shape& face) {
|
||||
const double y = l->Depth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double x = l->Width() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double d1 = l->WallThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double d2 = l->Girth() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCShapeProfileDef* l, TopoDS_Shape& face) {
|
||||
const double y = l->Depth() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
const double x = l->Width() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
const double d1 = l->WallThickness() * getValue(GV_LENGTH_UNIT);
|
||||
const double d2 = l->Girth() * getValue(GV_LENGTH_UNIT);
|
||||
bool doFillet = l->hasInternalFilletRadius();
|
||||
double f1 = 0;
|
||||
double f2 = 0;
|
||||
if ( doFillet ) {
|
||||
f1 = l->InternalFilletRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
f1 = l->InternalFilletRadius() * getValue(GV_LENGTH_UNIT);
|
||||
f2 = f1 + d1;
|
||||
}
|
||||
|
||||
@@ -423,31 +423,31 @@ bool IfcGeom::convert(const IfcSchema::IfcCShapeProfileDef* l, TopoDS_Shape& fac
|
||||
}
|
||||
|
||||
gp_Trsf2d trsf2d;
|
||||
IfcGeom::convert(l->Position(),trsf2d);
|
||||
IfcGeom::Kernel::convert(l->Position(),trsf2d);
|
||||
|
||||
double coords[24] = {-x,-y,x,-y,x,-y+d2,x-d1,-y+d2,x-d1,-y+d1,-x+d1,-y+d1,-x+d1,y-d1,x-d1,y-d1,x-d1,y-d2,x,y-d2,x,y,-x,y};
|
||||
int fillets[8] = {0,1,4,5,6,7,10,11};
|
||||
double radii[8] = {f2,f2,f1,f1,f1,f1,f2,f2};
|
||||
return IfcGeom::profile_helper(12,coords,doFillet ? 8 : 0,fillets,radii,trsf2d,face);
|
||||
return profile_helper(12,coords,doFillet ? 8 : 0,fillets,radii,trsf2d,face);
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcLShapeProfileDef* l, TopoDS_Shape& face) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcLShapeProfileDef* l, TopoDS_Shape& face) {
|
||||
const bool hasSlope = l->hasLegSlope();
|
||||
const bool doEdgeFillet = l->hasEdgeRadius();
|
||||
const bool doFillet = l->hasFilletRadius();
|
||||
|
||||
const double y = l->Depth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double x = (l->hasWidth() ? l->Width() : l->Depth()) / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double d = l->Thickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double slope = hasSlope ? (l->LegSlope() * IfcGeom::GetValue(GV_PLANEANGLE_UNIT)) : 0.;
|
||||
const double y = l->Depth() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
const double x = (l->hasWidth() ? l->Width() : l->Depth()) / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
const double d = l->Thickness() * getValue(GV_LENGTH_UNIT);
|
||||
const double slope = hasSlope ? (l->LegSlope() * getValue(GV_PLANEANGLE_UNIT)) : 0.;
|
||||
|
||||
double f1 = 0.0f;
|
||||
double f2 = 0.0f;
|
||||
if (doFillet) {
|
||||
f1 = l->FilletRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
f1 = l->FilletRadius() * getValue(GV_LENGTH_UNIT);
|
||||
}
|
||||
if ( doEdgeFillet) {
|
||||
f2 = l->EdgeRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
f2 = l->EdgeRadius() * getValue(GV_LENGTH_UNIT);
|
||||
}
|
||||
|
||||
if ( x < ALMOST_ZERO || y < ALMOST_ZERO || d < ALMOST_ZERO ) {
|
||||
@@ -492,24 +492,24 @@ bool IfcGeom::convert(const IfcSchema::IfcLShapeProfileDef* l, TopoDS_Shape& fac
|
||||
}
|
||||
|
||||
gp_Trsf2d trsf2d;
|
||||
IfcGeom::convert(l->Position(),trsf2d);
|
||||
convert(l->Position(),trsf2d);
|
||||
|
||||
double coords[12] = {-x,-y, x,-y, x,-y+d-dy1, xx, xy, -x+d-dx1,y, -x,y};
|
||||
int fillets[3] = {2,3,4};
|
||||
double radii[3] = {f2,f1,f2};
|
||||
return IfcGeom::profile_helper(6,coords,doFillet ? 3 : 0,fillets,radii,trsf2d,face);
|
||||
return profile_helper(6,coords,doFillet ? 3 : 0,fillets,radii,trsf2d,face);
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcUShapeProfileDef* l, TopoDS_Shape& face) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcUShapeProfileDef* l, TopoDS_Shape& face) {
|
||||
const bool doEdgeFillet = l->hasEdgeRadius();
|
||||
const bool doFillet = l->hasFilletRadius();
|
||||
const bool hasSlope = l->hasFlangeSlope();
|
||||
|
||||
const double y = l->Depth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double x = l->FlangeWidth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double d1 = l->WebThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double d2 = l->FlangeThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double slope = hasSlope ? (l->FlangeSlope() * IfcGeom::GetValue(GV_PLANEANGLE_UNIT)) : 0.;
|
||||
const double y = l->Depth() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
const double x = l->FlangeWidth() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
const double d1 = l->WebThickness() * getValue(GV_LENGTH_UNIT);
|
||||
const double d2 = l->FlangeThickness() * getValue(GV_LENGTH_UNIT);
|
||||
const double slope = hasSlope ? (l->FlangeSlope() * getValue(GV_PLANEANGLE_UNIT)) : 0.;
|
||||
|
||||
double dy1 = 0.0f;
|
||||
double dy2 = 0.0f;
|
||||
@@ -517,10 +517,10 @@ bool IfcGeom::convert(const IfcSchema::IfcUShapeProfileDef* l, TopoDS_Shape& fac
|
||||
double f2 = 0.0f;
|
||||
|
||||
if (doFillet) {
|
||||
f1 = l->FilletRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
f1 = l->FilletRadius() * getValue(GV_LENGTH_UNIT);
|
||||
}
|
||||
if (doEdgeFillet) {
|
||||
f2 = l->EdgeRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
f2 = l->EdgeRadius() * getValue(GV_LENGTH_UNIT);
|
||||
}
|
||||
|
||||
if (hasSlope) {
|
||||
@@ -534,27 +534,27 @@ bool IfcGeom::convert(const IfcSchema::IfcUShapeProfileDef* l, TopoDS_Shape& fac
|
||||
}
|
||||
|
||||
gp_Trsf2d trsf2d;
|
||||
IfcGeom::convert(l->Position(),trsf2d);
|
||||
convert(l->Position(),trsf2d);
|
||||
|
||||
double coords[16] = {-x,-y, x,-y, x,-y+d2-dy2, -x+d1,-y+d2+dy1, -x+d1,y-d2-dy1, x,y-d2+dy2, x,y, -x,y};
|
||||
int fillets[4] = {2,3,4,5};
|
||||
double radii[4] = {f2,f1,f1,f2};
|
||||
return IfcGeom::profile_helper(8, coords, (doFillet || doEdgeFillet) ? 4 : 0, fillets, radii, trsf2d, face);
|
||||
return profile_helper(8, coords, (doFillet || doEdgeFillet) ? 4 : 0, fillets, radii, trsf2d, face);
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcTShapeProfileDef* l, TopoDS_Shape& face) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcTShapeProfileDef* l, TopoDS_Shape& face) {
|
||||
const bool doFlangeEdgeFillet = l->hasFlangeEdgeRadius();
|
||||
const bool doWebEdgeFillet = l->hasWebEdgeRadius();
|
||||
const bool doFillet = l->hasFilletRadius();
|
||||
const bool hasFlangeSlope = l->hasFlangeSlope();
|
||||
const bool hasWebSlope = l->hasWebSlope();
|
||||
|
||||
const double y = l->Depth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double x = l->FlangeWidth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double d1 = l->WebThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double d2 = l->FlangeThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double flangeSlope = hasFlangeSlope ? (l->FlangeSlope() * IfcGeom::GetValue(GV_PLANEANGLE_UNIT)) : 0.;
|
||||
const double webSlope = hasWebSlope ? (l->WebSlope() * IfcGeom::GetValue(GV_PLANEANGLE_UNIT)) : 0.;
|
||||
const double y = l->Depth() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
const double x = l->FlangeWidth() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||
const double d1 = l->WebThickness() * getValue(GV_LENGTH_UNIT);
|
||||
const double d2 = l->FlangeThickness() * getValue(GV_LENGTH_UNIT);
|
||||
const double flangeSlope = hasFlangeSlope ? (l->FlangeSlope() * getValue(GV_PLANEANGLE_UNIT)) : 0.;
|
||||
const double webSlope = hasWebSlope ? (l->WebSlope() * getValue(GV_PLANEANGLE_UNIT)) : 0.;
|
||||
|
||||
if ( x < ALMOST_ZERO || y < ALMOST_ZERO || d1 < ALMOST_ZERO || d2 < ALMOST_ZERO ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
@@ -570,13 +570,13 @@ bool IfcGeom::convert(const IfcSchema::IfcTShapeProfileDef* l, TopoDS_Shape& fac
|
||||
double f3 = 0.0f;
|
||||
|
||||
if (doFillet) {
|
||||
f1 = l->FilletRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
f1 = l->FilletRadius() * getValue(GV_LENGTH_UNIT);
|
||||
}
|
||||
if (doWebEdgeFillet) {
|
||||
f2 = l->WebEdgeRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
f2 = l->WebEdgeRadius() * getValue(GV_LENGTH_UNIT);
|
||||
}
|
||||
if (doFlangeEdgeFillet) {
|
||||
f3 = l->FlangeEdgeRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
f3 = l->FlangeEdgeRadius() * getValue(GV_LENGTH_UNIT);
|
||||
}
|
||||
|
||||
double xx, xy;
|
||||
@@ -617,23 +617,23 @@ bool IfcGeom::convert(const IfcSchema::IfcTShapeProfileDef* l, TopoDS_Shape& fac
|
||||
}
|
||||
|
||||
gp_Trsf2d trsf2d;
|
||||
IfcGeom::convert(l->Position(),trsf2d);
|
||||
convert(l->Position(),trsf2d);
|
||||
|
||||
double coords[16] = {d1/2.-dx2,-y, xx,xy, x,y-d2+dy2, x,y, -x,y, -x,y-d2+dy2, -xx,xy, -d1/2.+dx2,-y};
|
||||
int fillets[6] = {0,1,2,5,6,7};
|
||||
double radii[6] = {f2,f1,f3,f3,f1,f2};
|
||||
return IfcGeom::profile_helper(8, coords, (doFillet || doWebEdgeFillet || doFlangeEdgeFillet) ? 6 : 0, fillets, radii, trsf2d, face);
|
||||
return profile_helper(8, coords, (doFillet || doWebEdgeFillet || doFlangeEdgeFillet) ? 6 : 0, fillets, radii, trsf2d, face);
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcCircleProfileDef* l, TopoDS_Shape& face) {
|
||||
const double r = l->Radius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCircleProfileDef* l, TopoDS_Shape& face) {
|
||||
const double r = l->Radius() * getValue(GV_LENGTH_UNIT);
|
||||
if ( r == 0.0f ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
return false;
|
||||
}
|
||||
|
||||
gp_Trsf2d trsf;
|
||||
IfcGeom::convert(l->Position(),trsf);
|
||||
convert(l->Position(),trsf);
|
||||
|
||||
BRepBuilderAPI_MakeWire w;
|
||||
gp_Ax2 ax = gp_Ax2().Transformed(trsf);
|
||||
@@ -642,14 +642,14 @@ bool IfcGeom::convert(const IfcSchema::IfcCircleProfileDef* l, TopoDS_Shape& fac
|
||||
w.Add(edge);
|
||||
|
||||
TopoDS_Face f;
|
||||
bool success = IfcGeom::convert_wire_to_face(w, f);
|
||||
bool success = convert_wire_to_face(w, f);
|
||||
if (success) face = f;
|
||||
return success;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcCircleHollowProfileDef* l, TopoDS_Shape& face) {
|
||||
const double r = l->Radius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double t = l->WallThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCircleHollowProfileDef* l, TopoDS_Shape& face) {
|
||||
const double r = l->Radius() * getValue(GV_LENGTH_UNIT);
|
||||
const double t = l->WallThickness() * getValue(GV_LENGTH_UNIT);
|
||||
|
||||
if ( r == 0.0f || t == 0.0f ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
@@ -657,7 +657,7 @@ bool IfcGeom::convert(const IfcSchema::IfcCircleHollowProfileDef* l, TopoDS_Shap
|
||||
}
|
||||
|
||||
gp_Trsf2d trsf;
|
||||
IfcGeom::convert(l->Position(),trsf);
|
||||
convert(l->Position(),trsf);
|
||||
gp_Ax2 ax = gp_Ax2().Transformed(trsf);
|
||||
|
||||
BRepBuilderAPI_MakeWire outer;
|
||||
@@ -676,9 +676,9 @@ bool IfcGeom::convert(const IfcSchema::IfcCircleHollowProfileDef* l, TopoDS_Shap
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcEllipseProfileDef* l, TopoDS_Shape& face) {
|
||||
double rx = l->SemiAxis1() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
double ry = l->SemiAxis2() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcEllipseProfileDef* l, TopoDS_Shape& face) {
|
||||
double rx = l->SemiAxis1() * getValue(GV_LENGTH_UNIT);
|
||||
double ry = l->SemiAxis2() * getValue(GV_LENGTH_UNIT);
|
||||
|
||||
if ( rx < ALMOST_ZERO || ry < ALMOST_ZERO ) {
|
||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||
@@ -687,7 +687,7 @@ bool IfcGeom::convert(const IfcSchema::IfcEllipseProfileDef* l, TopoDS_Shape& fa
|
||||
|
||||
const bool rotated = ry > rx;
|
||||
gp_Trsf2d trsf;
|
||||
IfcGeom::convert(l->Position(),trsf);
|
||||
convert(l->Position(),trsf);
|
||||
|
||||
gp_Ax2 ax = gp_Ax2();
|
||||
if (rotated) {
|
||||
@@ -702,16 +702,16 @@ bool IfcGeom::convert(const IfcSchema::IfcEllipseProfileDef* l, TopoDS_Shape& fa
|
||||
w.Add(edge);
|
||||
|
||||
TopoDS_Face f;
|
||||
bool success = IfcGeom::convert_wire_to_face(w, f);
|
||||
bool success = convert_wire_to_face(w, f);
|
||||
if (success) face = f;
|
||||
return success;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcCenterLineProfileDef* l, TopoDS_Shape& face) {
|
||||
const double d = l->Thickness() * IfcGeom::GetValue(GV_LENGTH_UNIT) / 2.;
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCenterLineProfileDef* l, TopoDS_Shape& face) {
|
||||
const double d = l->Thickness() * getValue(GV_LENGTH_UNIT) / 2.;
|
||||
|
||||
TopoDS_Wire wire;
|
||||
if (!IfcGeom::convert_wire(l->Curve(), wire)) return false;
|
||||
if (!convert_wire(l->Curve(), wire)) return false;
|
||||
|
||||
// BRepOffsetAPI_MakeOffset insists on creating circular arc
|
||||
// segments for joining the curves that constitute the center
|
||||
@@ -756,7 +756,7 @@ bool IfcGeom::convert(const IfcSchema::IfcCenterLineProfileDef* l, TopoDS_Shape&
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcCompositeProfileDef* l, TopoDS_Shape& face) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCompositeProfileDef* l, TopoDS_Shape& face) {
|
||||
// BRepBuilderAPI_MakeFace mf;
|
||||
|
||||
TopoDS_Compound compound;
|
||||
@@ -767,7 +767,7 @@ bool IfcGeom::convert(const IfcSchema::IfcCompositeProfileDef* l, TopoDS_Shape&
|
||||
bool first = true;
|
||||
for (IfcSchema::IfcProfileDef::list::it it = profiles->begin(); it != profiles->end(); ++it) {
|
||||
TopoDS_Face f;
|
||||
if (IfcGeom::convert_face(*it, f)) {
|
||||
if (convert_face(*it, f)) {
|
||||
builder.Add(compound, f);
|
||||
/* TopExp_Explorer exp(f, TopAbs_WIRE);
|
||||
for (; exp.More(); exp.Next()) {
|
||||
@@ -786,10 +786,10 @@ bool IfcGeom::convert(const IfcSchema::IfcCompositeProfileDef* l, TopoDS_Shape&
|
||||
return !face.IsNull();
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcDerivedProfileDef* l, TopoDS_Shape& face) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcDerivedProfileDef* l, TopoDS_Shape& face) {
|
||||
TopoDS_Face f;
|
||||
gp_Trsf2d trsf2d;
|
||||
if (IfcGeom::convert_face(l->ParentProfile(), f) && IfcGeom::convert(l->Operator(), trsf2d)) {
|
||||
if (convert_face(l->ParentProfile(), f) && IfcGeom::Kernel::convert(l->Operator(), trsf2d)) {
|
||||
gp_Trsf trsf = trsf2d;
|
||||
face = TopoDS::Face(BRepBuilderAPI_Transform(f, trsf));
|
||||
return true;
|
||||
@@ -821,7 +821,7 @@ bool convert_surf(IfcSchema::IfcBSplineSurfaceWithKnots* l, Handle_Geom_Surface&
|
||||
for (IfcTemplatedEntityListList<IfcSchema::IfcCartesianPoint>::inner_it jt = (*it).begin(); jt != (*it).end(); ++jt, ++j) {
|
||||
IfcSchema::IfcCartesianPoint* p = *jt;
|
||||
gp_Pnt pnt;
|
||||
if (!IfcGeom::convert(p, pnt)) return false;
|
||||
if (!convert(p, pnt)) return false;
|
||||
Poles(i, j) = pnt;
|
||||
}
|
||||
}
|
||||
@@ -847,12 +847,12 @@ bool convert_surf(IfcSchema::IfcBSplineSurfaceWithKnots* l, Handle_Geom_Surface&
|
||||
|
||||
bool convert_surf(IfcSchema::IfcPlane* l, Handle_Geom_Surface& surf) {
|
||||
gp_Pln pln;
|
||||
IfcGeom::convert(l, pln);
|
||||
convert(l, pln);
|
||||
surf = new Geom_Plane(pln);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcAdvancedFace* l, TopoDS_Shape& face) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcAdvancedFace* l, TopoDS_Shape& face) {
|
||||
IfcSchema::IfcSurface* s = l->FaceSurface();
|
||||
Handle_Geom_Surface surf(0);
|
||||
if (s->is(IfcSchema::Type::IfcBSplineSurfaceWithKnots)) {
|
||||
@@ -868,7 +868,7 @@ bool IfcGeom::convert(const IfcSchema::IfcAdvancedFace* l, TopoDS_Shape& face) {
|
||||
for (IfcSchema::IfcFaceBound::list::it it = bounds->begin(); it != bounds->end(); ++it) {
|
||||
IfcSchema::IfcLoop* loop = (*it)->Bound();
|
||||
TopoDS_Wire outer_wire;
|
||||
if (!IfcGeom::convert_wire(loop, outer_wire)) return false;
|
||||
if (!convert_wire(loop, outer_wire)) return false;
|
||||
|
||||
TopoDS_Face temp = BRepBuilderAPI_MakeFace(surf, outer_wire);
|
||||
|
||||
|
||||
@@ -102,11 +102,11 @@
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
|
||||
bool IfcGeom::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& shape) {
|
||||
bool IfcGeom::Kernel::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& shape) {
|
||||
BRepOffsetAPI_Sewing builder;
|
||||
builder.SetTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||
builder.SetMaxTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||
builder.SetMinTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||
builder.SetTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||
builder.SetMaxTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||
builder.SetMinTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||
TopExp_Explorer exp(compound,TopAbs_FACE);
|
||||
if ( ! exp.More() ) return false;
|
||||
for ( ; exp.More(); exp.Next() ) {
|
||||
@@ -117,13 +117,13 @@ bool IfcGeom::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Sh
|
||||
shape = builder.SewedShape();
|
||||
try {
|
||||
ShapeFix_Solid sf_solid;
|
||||
sf_solid.LimitTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||
sf_solid.LimitTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||
shape = sf_solid.SolidFromShell(TopoDS::Shell(shape));
|
||||
} catch(...) {}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::is_compound(const TopoDS_Shape& shape) {
|
||||
bool IfcGeom::Kernel::is_compound(const TopoDS_Shape& shape) {
|
||||
bool has_solids = TopExp_Explorer(shape,TopAbs_SOLID).More() != 0;
|
||||
bool has_shells = TopExp_Explorer(shape,TopAbs_SHELL).More() != 0;
|
||||
bool has_compounds = TopExp_Explorer(shape,TopAbs_COMPOUND).More() != 0;
|
||||
@@ -131,21 +131,21 @@ bool IfcGeom::is_compound(const TopoDS_Shape& shape) {
|
||||
return has_compounds && has_faces && !has_solids && !has_shells;
|
||||
}
|
||||
|
||||
const TopoDS_Shape& IfcGeom::ensure_fit_for_subtraction(const TopoDS_Shape& shape, TopoDS_Shape& solid) {
|
||||
const bool is_comp = IfcGeom::is_compound(shape);
|
||||
const TopoDS_Shape& IfcGeom::Kernel::ensure_fit_for_subtraction(const TopoDS_Shape& shape, TopoDS_Shape& solid) {
|
||||
const bool is_comp = is_compound(shape);
|
||||
if ( ! is_comp ) return shape;
|
||||
IfcGeom::create_solid_from_compound(shape, solid);
|
||||
create_solid_from_compound(shape, solid);
|
||||
|
||||
// If the SEW_SHELLS option had been set this precision had been applied
|
||||
// at the end of the generic IfcGeom::convert_shape() call.
|
||||
const double precision = IfcGeom::GetValue(GV_PRECISION);
|
||||
IfcGeom::apply_tolerance(solid, precision);
|
||||
// at the end of the generic convert_shape() call.
|
||||
const double precision = getValue(GV_PRECISION);
|
||||
apply_tolerance(solid, precision);
|
||||
|
||||
return solid;
|
||||
}
|
||||
|
||||
bool IfcGeom::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 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) {
|
||||
// Iterate over IfcOpeningElements
|
||||
IfcGeom::IfcRepresentationShapeItems opening_shapes;
|
||||
unsigned int last_size = 0;
|
||||
@@ -156,7 +156,7 @@ bool IfcGeom::convert_openings(const IfcSchema::IfcProduct* entity, const IfcSch
|
||||
|
||||
// Convert the IfcRepresentation of the IfcOpeningElement
|
||||
gp_Trsf opening_trsf;
|
||||
IfcGeom::convert(fes->ObjectPlacement(),opening_trsf);
|
||||
IfcGeom::Kernel::convert(fes->ObjectPlacement(),opening_trsf);
|
||||
|
||||
// Move the opening into the coordinate system of the IfcProduct
|
||||
opening_trsf.PreMultiply(entity_trsf.Inverted());
|
||||
@@ -165,7 +165,7 @@ bool IfcGeom::convert_openings(const IfcSchema::IfcProduct* entity, const IfcSch
|
||||
IfcSchema::IfcRepresentation::list::ptr reps = prodrep->Representations();
|
||||
|
||||
for ( IfcSchema::IfcRepresentation::list::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) {
|
||||
IfcGeom::convert_shapes(*it2,opening_shapes);
|
||||
convert_shapes(*it2,opening_shapes);
|
||||
}
|
||||
|
||||
const unsigned int current_size = (const unsigned int) opening_shapes.size();
|
||||
@@ -179,7 +179,7 @@ bool IfcGeom::convert_openings(const IfcSchema::IfcProduct* entity, const IfcSch
|
||||
// Iterate over the shapes of the IfcProduct
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) {
|
||||
TopoDS_Shape entity_shape_solid;
|
||||
const TopoDS_Shape& entity_shape_unlocated = IfcGeom::ensure_fit_for_subtraction(it3->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();
|
||||
TopoDS_Shape entity_shape;
|
||||
if ( entity_shape_gtrsf.Form() == gp_Other ) {
|
||||
@@ -192,7 +192,7 @@ bool IfcGeom::convert_openings(const IfcSchema::IfcProduct* entity, const IfcSch
|
||||
// Iterate over the shapes of the IfcOpeningElements
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it4 = opening_shapes.begin(); it4 != opening_shapes.end(); ++ it4 ) {
|
||||
TopoDS_Shape opening_shape_solid;
|
||||
const TopoDS_Shape& opening_shape_unlocated = IfcGeom::ensure_fit_for_subtraction(it4->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->entity);
|
||||
@@ -276,8 +276,8 @@ bool IfcGeom::convert_openings(const IfcSchema::IfcProduct* entity, const IfcSch
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::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 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) {
|
||||
|
||||
// Create a compound of all opening shapes in order to speed up the boolean operations
|
||||
TopoDS_Compound opening_compound;
|
||||
@@ -291,7 +291,7 @@ bool IfcGeom::convert_openings_fast(const IfcSchema::IfcProduct* entity, const I
|
||||
|
||||
// Convert the IfcRepresentation of the IfcOpeningElement
|
||||
gp_Trsf opening_trsf;
|
||||
IfcGeom::convert(fes->ObjectPlacement(),opening_trsf);
|
||||
IfcGeom::Kernel::convert(fes->ObjectPlacement(),opening_trsf);
|
||||
|
||||
// Move the opening into the coordinate system of the IfcProduct
|
||||
opening_trsf.PreMultiply(entity_trsf.Inverted());
|
||||
@@ -302,7 +302,7 @@ bool IfcGeom::convert_openings_fast(const IfcSchema::IfcProduct* entity, const I
|
||||
IfcGeom::IfcRepresentationShapeItems opening_shapes;
|
||||
|
||||
for ( IfcSchema::IfcRepresentation::list::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) {
|
||||
IfcGeom::convert_shapes(*it2,opening_shapes);
|
||||
convert_shapes(*it2,opening_shapes);
|
||||
}
|
||||
|
||||
for ( unsigned int i = 0; i < opening_shapes.size(); ++ i ) {
|
||||
@@ -320,7 +320,7 @@ bool IfcGeom::convert_openings_fast(const IfcSchema::IfcProduct* entity, const I
|
||||
// Iterate over the shapes of the IfcProduct
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) {
|
||||
TopoDS_Shape entity_shape_solid;
|
||||
const TopoDS_Shape& entity_shape_unlocated = IfcGeom::ensure_fit_for_subtraction(it3->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();
|
||||
TopoDS_Shape entity_shape;
|
||||
if ( entity_shape_gtrsf.Form() == gp_Other ) {
|
||||
@@ -353,7 +353,7 @@ bool IfcGeom::convert_openings_fast(const IfcSchema::IfcProduct* entity, const I
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face) {
|
||||
bool IfcGeom::Kernel::convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face) {
|
||||
BRepBuilderAPI_MakeFace mf(wire, false);
|
||||
BRepBuilderAPI_FaceError er = mf.Error();
|
||||
if ( er == BRepBuilderAPI_NotPlanar ) {
|
||||
@@ -368,12 +368,12 @@ bool IfcGeom::convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert_curve_to_wire(const Handle(Geom_Curve)& curve, TopoDS_Wire& wire) {
|
||||
bool IfcGeom::Kernel::convert_curve_to_wire(const Handle(Geom_Curve)& curve, TopoDS_Wire& wire) {
|
||||
wire = BRepBuilderAPI_MakeWire(BRepBuilderAPI_MakeEdge(curve));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::profile_helper(int numVerts, double* verts, int numFillets, int* filletIndices, double* filletRadii, gp_Trsf2d trsf, TopoDS_Shape& face_shape) {
|
||||
bool IfcGeom::Kernel::profile_helper(int numVerts, double* verts, int numFillets, int* filletIndices, double* filletRadii, gp_Trsf2d trsf, TopoDS_Shape& face_shape) {
|
||||
TopoDS_Vertex* vertices = new TopoDS_Vertex[numVerts];
|
||||
|
||||
for ( int i = 0; i < numVerts; i ++ ) {
|
||||
@@ -387,7 +387,7 @@ bool IfcGeom::profile_helper(int numVerts, double* verts, int numFillets, int* f
|
||||
w.Add(BRepBuilderAPI_MakeEdge(vertices[i],vertices[(i+1)%numVerts]));
|
||||
|
||||
TopoDS_Face face;
|
||||
IfcGeom::convert_wire_to_face(w.Wire(),face);
|
||||
convert_wire_to_face(w.Wire(),face);
|
||||
|
||||
if ( numFillets && *std::max_element(filletRadii, filletRadii + numFillets) > ALMOST_ZERO ) {
|
||||
BRepFilletAPI_MakeFillet2d fillet (face);
|
||||
@@ -409,17 +409,17 @@ bool IfcGeom::profile_helper(int numVerts, double* verts, int numFillets, int* f
|
||||
delete[] vertices;
|
||||
return true;
|
||||
}
|
||||
double IfcGeom::shape_volume(const TopoDS_Shape& s) {
|
||||
double IfcGeom::Kernel::shape_volume(const TopoDS_Shape& s) {
|
||||
GProp_GProps prop;
|
||||
BRepGProp::VolumeProperties(s, prop);
|
||||
return prop.Mass();
|
||||
}
|
||||
double IfcGeom::face_area(const TopoDS_Face& f) {
|
||||
double IfcGeom::Kernel::face_area(const TopoDS_Face& f) {
|
||||
GProp_GProps prop;
|
||||
BRepGProp::SurfaceProperties(f,prop);
|
||||
return prop.Mass();
|
||||
}
|
||||
bool IfcGeom::is_convex(const TopoDS_Wire& wire) {
|
||||
bool IfcGeom::Kernel::is_convex(const TopoDS_Wire& wire) {
|
||||
for ( TopExp_Explorer exp1(wire,TopAbs_VERTEX); exp1.More(); exp1.Next() ) {
|
||||
TopoDS_Vertex V1 = TopoDS::Vertex(exp1.Current());
|
||||
gp_Pnt P1 = BRep_Tool::Pnt(V1);
|
||||
@@ -434,8 +434,8 @@ bool IfcGeom::is_convex(const TopoDS_Wire& wire) {
|
||||
edge_points.push_back(P2);
|
||||
}
|
||||
if ( edge_points.size() != 2 ) continue;
|
||||
if ( edge_points[0].IsEqual(P1,GetValue(GV_POINT_EQUALITY_TOLERANCE))) neighbors.push_back(edge_points[1]);
|
||||
else if ( edge_points[1].IsEqual(P1, GetValue(GV_POINT_EQUALITY_TOLERANCE))) neighbors.push_back(edge_points[0]);
|
||||
if ( edge_points[0].IsEqual(P1,getValue(GV_POINT_EQUALITY_TOLERANCE))) neighbors.push_back(edge_points[1]);
|
||||
else if ( edge_points[1].IsEqual(P1, getValue(GV_POINT_EQUALITY_TOLERANCE))) neighbors.push_back(edge_points[0]);
|
||||
}
|
||||
// There should be two of these
|
||||
if ( neighbors.size() != 2 ) return false;
|
||||
@@ -444,10 +444,10 @@ bool IfcGeom::is_convex(const TopoDS_Wire& wire) {
|
||||
for ( TopExp_Explorer exp2(wire,TopAbs_VERTEX); exp2.More(); exp2.Next() ) {
|
||||
TopoDS_Vertex V2 = TopoDS::Vertex(exp2.Current());
|
||||
gp_Pnt P2 = BRep_Tool::Pnt(V2);
|
||||
if ( P1.IsEqual(P2,GetValue(GV_POINT_EQUALITY_TOLERANCE)) ) continue;
|
||||
if ( P1.IsEqual(P2,getValue(GV_POINT_EQUALITY_TOLERANCE)) ) continue;
|
||||
bool found = false;
|
||||
for( std::vector<gp_Pnt>::const_iterator it = neighbors.begin(); it != neighbors.end(); ++ it ) {
|
||||
if ( (*it).IsEqual(P2,GetValue(GV_POINT_EQUALITY_TOLERANCE)) ) { found = true; break; }
|
||||
if ( (*it).IsEqual(P2,getValue(GV_POINT_EQUALITY_TOLERANCE)) ) { found = true; break; }
|
||||
}
|
||||
if ( ! found ) non_neighbors.push_back(P2);
|
||||
}
|
||||
@@ -465,11 +465,11 @@ bool IfcGeom::is_convex(const TopoDS_Wire& wire) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
TopoDS_Shape IfcGeom::halfspace_from_plane(const gp_Pln& pln,const gp_Pnt& cent) {
|
||||
TopoDS_Shape IfcGeom::Kernel::halfspace_from_plane(const gp_Pln& pln,const gp_Pnt& cent) {
|
||||
TopoDS_Face face = BRepBuilderAPI_MakeFace(pln).Face();
|
||||
return BRepPrimAPI_MakeHalfSpace(face,cent).Solid();
|
||||
}
|
||||
gp_Pln IfcGeom::plane_from_face(const TopoDS_Face& face) {
|
||||
gp_Pln IfcGeom::Kernel::plane_from_face(const TopoDS_Face& face) {
|
||||
BRepGProp_Face prop(face);
|
||||
Standard_Real u1,u2,v1,v2;
|
||||
prop.Bounds(u1,u2,v1,v2);
|
||||
@@ -480,7 +480,7 @@ gp_Pln IfcGeom::plane_from_face(const TopoDS_Face& face) {
|
||||
prop.Normal(u,v,p,n);
|
||||
return gp_Pln(p,n);
|
||||
}
|
||||
gp_Pnt IfcGeom::point_above_plane(const gp_Pln& pln, bool agree) {
|
||||
gp_Pnt IfcGeom::Kernel::point_above_plane(const gp_Pln& pln, bool agree) {
|
||||
if ( agree ) {
|
||||
return pln.Location().Translated(pln.Axis().Direction());
|
||||
} else {
|
||||
@@ -488,7 +488,7 @@ gp_Pnt IfcGeom::point_above_plane(const gp_Pln& pln, bool agree) {
|
||||
}
|
||||
}
|
||||
|
||||
void IfcGeom::apply_tolerance(TopoDS_Shape& s, double t) {
|
||||
void IfcGeom::Kernel::apply_tolerance(TopoDS_Shape& s, double t) {
|
||||
ShapeFix_ShapeTolerance tol;
|
||||
tol.SetTolerance(s, t);
|
||||
}
|
||||
@@ -503,7 +503,7 @@ static double ifc_planeangle_unit = -1.0;
|
||||
static double force_ccw_face_orientation = -1.0;
|
||||
static double modelling_precision = 0.00001;
|
||||
|
||||
void IfcGeom::SetValue(GeomValue var, double value) {
|
||||
void IfcGeom::Kernel::setValue(GeomValue var, double value) {
|
||||
switch (var) {
|
||||
case GV_DEFLECTION_TOLERANCE:
|
||||
deflection_tolerance = value;
|
||||
@@ -537,7 +537,7 @@ void IfcGeom::SetValue(GeomValue var, double value) {
|
||||
}
|
||||
}
|
||||
|
||||
double IfcGeom::GetValue(GeomValue var) {
|
||||
double IfcGeom::Kernel::getValue(GeomValue var) {
|
||||
switch (var) {
|
||||
case GV_DEFLECTION_TOLERANCE:
|
||||
return deflection_tolerance;
|
||||
@@ -566,7 +566,7 @@ double IfcGeom::GetValue(GeomValue var) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
IfcSchema::IfcProductDefinitionShape* IfcGeom::tesselate(TopoDS_Shape& shape, double deflection, IfcEntityList::ptr es) {
|
||||
IfcSchema::IfcProductDefinitionShape* IfcGeom::Kernel::tesselate(TopoDS_Shape& shape, double deflection, IfcEntityList::ptr es) {
|
||||
BRepMesh::Mesh(shape, deflection);
|
||||
|
||||
IfcSchema::IfcFace::list::ptr faces (new IfcSchema::IfcFace::list);
|
||||
@@ -655,7 +655,7 @@ TopoDS_Edge find_next(const TopTools_IndexedMapOfShape& edge_set, const TopTools
|
||||
return TopoDS_Edge();
|
||||
}
|
||||
|
||||
bool IfcGeom::fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& shape) {
|
||||
bool IfcGeom::Kernel::fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& shape) {
|
||||
BRepOffsetAPI_Sewing sew;
|
||||
sew.Add(shape);
|
||||
|
||||
@@ -730,14 +730,14 @@ bool IfcGeom::fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& shape) {
|
||||
|
||||
try {
|
||||
ShapeFix_Solid solid;
|
||||
solid.LimitTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||
solid.LimitTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||
shape = solid.SolidFromShell(TopoDS::Shell(shape));
|
||||
} catch(...) {}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::flatten_shape_list(const IfcGeom::IfcRepresentationShapeItems& shapes, TopoDS_Shape& result, bool fuse) {
|
||||
bool IfcGeom::Kernel::flatten_shape_list(const IfcGeom::IfcRepresentationShapeItems& shapes, TopoDS_Shape& result, bool fuse) {
|
||||
TopoDS_Compound compound;
|
||||
BRep_Builder builder;
|
||||
builder.MakeCompound(compound);
|
||||
@@ -748,7 +748,7 @@ bool IfcGeom::flatten_shape_list(const IfcGeom::IfcRepresentationShapeItems& sha
|
||||
TopoDS_Shape merged;
|
||||
const TopoDS_Shape& s = it->Shape();
|
||||
if (fuse) {
|
||||
IfcGeom::ensure_fit_for_subtraction(s, merged);
|
||||
ensure_fit_for_subtraction(s, merged);
|
||||
} else {
|
||||
merged = s;
|
||||
}
|
||||
@@ -793,8 +793,8 @@ bool IfcGeom::flatten_shape_list(const IfcGeom::IfcRepresentationShapeItems& sha
|
||||
return !result.IsNull();
|
||||
}
|
||||
|
||||
void IfcGeom::remove_redundant_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol) {
|
||||
if (tol <= 0.) tol = GetValue(GV_POINT_EQUALITY_TOLERANCE);
|
||||
void IfcGeom::Kernel::remove_redundant_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol) {
|
||||
if (tol <= 0.) tol = getValue(GV_POINT_EQUALITY_TOLERANCE);
|
||||
tol *= tol;
|
||||
|
||||
while (true) {
|
||||
|
||||
@@ -77,29 +77,19 @@
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
|
||||
|
||||
namespace IfcGeom {
|
||||
namespace Cache {
|
||||
#include "IfcRegisterCreateCache.h"
|
||||
}
|
||||
}
|
||||
#define IN_CACHE(T,E,t,e) std::map<int,t>::const_iterator it = Cache::T.find(E->entity->id());\
|
||||
if ( it != Cache::T.end() ) { e = it->second; return true; }
|
||||
#define CACHE(T,E,e) Cache::T[E->entity->id()] = e;
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcCartesianPoint* l, gp_Pnt& point) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCartesianPoint* l, gp_Pnt& point) {
|
||||
IN_CACHE(IfcCartesianPoint,l,gp_Pnt,point)
|
||||
std::vector<double> xyz = l->Coordinates();
|
||||
point = gp_Pnt(
|
||||
xyz.size() ? (xyz[0]*IfcGeom::GetValue(GV_LENGTH_UNIT)) : 0.0f,
|
||||
xyz.size() > 1 ? (xyz[1]*IfcGeom::GetValue(GV_LENGTH_UNIT)) : 0.0f,
|
||||
xyz.size() > 2 ? (xyz[2]*IfcGeom::GetValue(GV_LENGTH_UNIT)) : 0.0f
|
||||
xyz.size() ? (xyz[0]*getValue(GV_LENGTH_UNIT)) : 0.0f,
|
||||
xyz.size() > 1 ? (xyz[1]*getValue(GV_LENGTH_UNIT)) : 0.0f,
|
||||
xyz.size() > 2 ? (xyz[2]*getValue(GV_LENGTH_UNIT)) : 0.0f
|
||||
);
|
||||
CACHE(IfcCartesianPoint,l,point)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcDirection* l, gp_Dir& dir) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcDirection* l, gp_Dir& dir) {
|
||||
IN_CACHE(IfcDirection,l,gp_Dir,dir)
|
||||
std::vector<double> xyz = l->DirectionRatios();
|
||||
dir = gp_Dir(
|
||||
@@ -111,22 +101,22 @@ bool IfcGeom::convert(const IfcSchema::IfcDirection* l, gp_Dir& dir) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcVector* l, gp_Vec& v) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcVector* l, gp_Vec& v) {
|
||||
IN_CACHE(IfcVector,l,gp_Vec,v)
|
||||
gp_Dir d;
|
||||
IfcGeom::convert(l->Orientation(),d);
|
||||
v = l->Magnitude() * IfcGeom::GetValue(GV_LENGTH_UNIT) * d;
|
||||
IfcGeom::Kernel::convert(l->Orientation(),d);
|
||||
v = l->Magnitude() * getValue(GV_LENGTH_UNIT) * d;
|
||||
CACHE(IfcVector,l,v)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcAxis2Placement3D* l, gp_Trsf& trsf) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcAxis2Placement3D* l, gp_Trsf& trsf) {
|
||||
IN_CACHE(IfcAxis2Placement3D,l,gp_Trsf,trsf)
|
||||
gp_Pnt o;gp_Dir axis = gp_Dir(0,0,1);gp_Dir refDirection;
|
||||
IfcGeom::convert(l->Location(),o);
|
||||
IfcGeom::Kernel::convert(l->Location(),o);
|
||||
bool hasRef = l->hasRefDirection();
|
||||
if ( l->hasAxis() ) IfcGeom::convert(l->Axis(),axis);
|
||||
if ( hasRef ) IfcGeom::convert(l->RefDirection(),refDirection);
|
||||
if ( l->hasAxis() ) IfcGeom::Kernel::convert(l->Axis(),axis);
|
||||
if ( hasRef ) IfcGeom::Kernel::convert(l->RefDirection(),refDirection);
|
||||
gp_Ax3 ax3;
|
||||
if ( hasRef ) ax3 = gp_Ax3(o,axis,refDirection);
|
||||
else ax3 = gp_Ax3(o,axis);
|
||||
@@ -135,26 +125,26 @@ bool IfcGeom::convert(const IfcSchema::IfcAxis2Placement3D* l, gp_Trsf& trsf) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcAxis1Placement* l, gp_Ax1& ax) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcAxis1Placement* l, gp_Ax1& ax) {
|
||||
IN_CACHE(IfcAxis1Placement,l,gp_Ax1,ax)
|
||||
gp_Pnt o;gp_Dir axis = gp_Dir(0,0,1);
|
||||
IfcGeom::convert(l->Location(),o);
|
||||
if ( l->hasAxis() ) IfcGeom::convert(l->Axis(), axis);
|
||||
IfcGeom::Kernel::convert(l->Location(),o);
|
||||
if ( l->hasAxis() ) IfcGeom::Kernel::convert(l->Axis(), axis);
|
||||
ax = gp_Ax1(o, axis);
|
||||
CACHE(IfcAxis1Placement,l,ax)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcCartesianTransformationOperator3D* l, gp_Trsf& trsf) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCartesianTransformationOperator3D* l, gp_Trsf& trsf) {
|
||||
IN_CACHE(IfcCartesianTransformationOperator3D,l,gp_Trsf,trsf)
|
||||
gp_Pnt origin;
|
||||
IfcGeom::convert(l->LocalOrigin(),origin);
|
||||
IfcGeom::Kernel::convert(l->LocalOrigin(),origin);
|
||||
gp_Dir axis1 (1.,0.,0.);
|
||||
gp_Dir axis2 (0.,1.,0.);
|
||||
gp_Dir axis3 (0.,0.,1.);
|
||||
if ( l->hasAxis1() ) IfcGeom::convert(l->Axis1(),axis1);
|
||||
if ( l->hasAxis2() ) IfcGeom::convert(l->Axis2(),axis2);
|
||||
if ( l->hasAxis3() ) IfcGeom::convert(l->Axis3(),axis3);
|
||||
if ( l->hasAxis1() ) IfcGeom::Kernel::convert(l->Axis1(),axis1);
|
||||
if ( l->hasAxis2() ) IfcGeom::Kernel::convert(l->Axis2(),axis2);
|
||||
if ( l->hasAxis3() ) IfcGeom::Kernel::convert(l->Axis3(),axis3);
|
||||
gp_Ax3 ax3 (origin,axis3,axis1);
|
||||
if ( axis2.Dot(ax3.YDirection()) < 0 ) ax3.YReverse();
|
||||
trsf.SetTransformation(ax3);
|
||||
@@ -164,16 +154,16 @@ bool IfcGeom::convert(const IfcSchema::IfcCartesianTransformationOperator3D* l,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcCartesianTransformationOperator2D* l, gp_Trsf2d& trsf) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCartesianTransformationOperator2D* l, gp_Trsf2d& trsf) {
|
||||
IN_CACHE(IfcCartesianTransformationOperator2D,l,gp_Trsf2d,trsf)
|
||||
|
||||
gp_Pnt origin;
|
||||
gp_Dir axis1 (1.,0.,0.);
|
||||
gp_Dir axis2 (0.,1.,0.);
|
||||
|
||||
IfcGeom::convert(l->LocalOrigin(),origin);
|
||||
if ( l->hasAxis1() ) IfcGeom::convert(l->Axis1(),axis1);
|
||||
if ( l->hasAxis2() ) IfcGeom::convert(l->Axis2(),axis2);
|
||||
IfcGeom::Kernel::convert(l->LocalOrigin(),origin);
|
||||
if ( l->hasAxis1() ) IfcGeom::Kernel::convert(l->Axis1(),axis1);
|
||||
if ( l->hasAxis2() ) IfcGeom::Kernel::convert(l->Axis2(),axis2);
|
||||
|
||||
const gp_Pnt2d origin2d(origin.X(), origin.Y());
|
||||
const gp_Dir2d axis12d(axis1.X(), axis1.Y());
|
||||
@@ -198,17 +188,17 @@ bool IfcGeom::convert(const IfcSchema::IfcCartesianTransformationOperator2D* l,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcCartesianTransformationOperator3DnonUniform* l, gp_GTrsf& gtrsf) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCartesianTransformationOperator3DnonUniform* l, gp_GTrsf& gtrsf) {
|
||||
IN_CACHE(IfcCartesianTransformationOperator3DnonUniform,l,gp_GTrsf,gtrsf)
|
||||
gp_Trsf trsf;
|
||||
gp_Pnt origin;
|
||||
IfcGeom::convert(l->LocalOrigin(),origin);
|
||||
IfcGeom::Kernel::convert(l->LocalOrigin(),origin);
|
||||
gp_Dir axis1 (1.,0.,0.);
|
||||
gp_Dir axis2 (0.,1.,0.);
|
||||
gp_Dir axis3 (0.,0.,1.);
|
||||
if ( l->hasAxis1() ) IfcGeom::convert(l->Axis1(),axis1);
|
||||
if ( l->hasAxis2() ) IfcGeom::convert(l->Axis2(),axis2);
|
||||
if ( l->hasAxis3() ) IfcGeom::convert(l->Axis3(),axis3);
|
||||
if ( l->hasAxis1() ) IfcGeom::Kernel::convert(l->Axis1(),axis1);
|
||||
if ( l->hasAxis2() ) IfcGeom::Kernel::convert(l->Axis2(),axis2);
|
||||
if ( l->hasAxis3() ) IfcGeom::Kernel::convert(l->Axis3(),axis3);
|
||||
gp_Ax3 ax3 (origin,axis3,axis1);
|
||||
if ( axis2.Dot(ax3.YDirection()) < 0 ) ax3.YReverse();
|
||||
trsf.SetTransformation(ax3);
|
||||
@@ -225,7 +215,7 @@ bool IfcGeom::convert(const IfcSchema::IfcCartesianTransformationOperator3DnonUn
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcCartesianTransformationOperator2DnonUniform* l, gp_GTrsf2d& gtrsf) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCartesianTransformationOperator2DnonUniform* l, gp_GTrsf2d& gtrsf) {
|
||||
IN_CACHE(IfcCartesianTransformationOperator2DnonUniform,l,gp_GTrsf2d,gtrsf)
|
||||
|
||||
gp_Trsf2d trsf;
|
||||
@@ -233,9 +223,9 @@ bool IfcGeom::convert(const IfcSchema::IfcCartesianTransformationOperator2DnonUn
|
||||
gp_Dir axis1 (1.,0.,0.);
|
||||
gp_Dir axis2 (0.,1.,0.);
|
||||
|
||||
IfcGeom::convert(l->LocalOrigin(),origin);
|
||||
if ( l->hasAxis1() ) IfcGeom::convert(l->Axis1(),axis1);
|
||||
if ( l->hasAxis2() ) IfcGeom::convert(l->Axis2(),axis2);
|
||||
IfcGeom::Kernel::convert(l->LocalOrigin(),origin);
|
||||
if ( l->hasAxis1() ) IfcGeom::Kernel::convert(l->Axis1(),axis1);
|
||||
if ( l->hasAxis2() ) IfcGeom::Kernel::convert(l->Axis2(),axis2);
|
||||
|
||||
const gp_Pnt2d origin2d(origin.X(), origin.Y());
|
||||
const gp_Dir2d axis12d(axis1.X(), axis1.Y());
|
||||
@@ -261,14 +251,14 @@ bool IfcGeom::convert(const IfcSchema::IfcCartesianTransformationOperator2DnonUn
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcPlane* pln, gp_Pln& plane) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcPlane* pln, gp_Pln& plane) {
|
||||
IN_CACHE(IfcPlane,pln,gp_Pln,plane)
|
||||
IfcSchema::IfcAxis2Placement3D* l = pln->Position();
|
||||
gp_Pnt o;gp_Dir axis = gp_Dir(0,0,1);gp_Dir refDirection;
|
||||
IfcGeom::convert(l->Location(),o);
|
||||
IfcGeom::Kernel::convert(l->Location(),o);
|
||||
bool hasRef = l->hasRefDirection();
|
||||
if ( l->hasAxis() ) IfcGeom::convert(l->Axis(),axis);
|
||||
if ( hasRef ) IfcGeom::convert(l->RefDirection(),refDirection);
|
||||
if ( l->hasAxis() ) IfcGeom::Kernel::convert(l->Axis(),axis);
|
||||
if ( hasRef ) IfcGeom::Kernel::convert(l->RefDirection(),refDirection);
|
||||
gp_Ax3 ax3;
|
||||
if ( hasRef ) ax3 = gp_Ax3(o,axis,refDirection);
|
||||
else ax3 = gp_Ax3(o,axis);
|
||||
@@ -277,12 +267,12 @@ bool IfcGeom::convert(const IfcSchema::IfcPlane* pln, gp_Pln& plane) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcAxis2Placement2D* l, gp_Trsf2d& trsf) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcAxis2Placement2D* l, gp_Trsf2d& trsf) {
|
||||
IN_CACHE(IfcAxis2Placement2D,l,gp_Trsf2d,trsf)
|
||||
gp_Pnt P; gp_Dir V (1,0,0);
|
||||
IfcGeom::convert(l->Location(),P);
|
||||
IfcGeom::Kernel::convert(l->Location(),P);
|
||||
if ( l->hasRefDirection() )
|
||||
IfcGeom::convert(l->RefDirection(),V);
|
||||
IfcGeom::Kernel::convert(l->RefDirection(),V);
|
||||
|
||||
gp_Ax2d axis(gp_Pnt2d(P.X(),P.Y()),gp_Dir2d(V.X(),V.Y()));
|
||||
trsf.SetTransformation(axis,gp_Ax2d());
|
||||
@@ -290,7 +280,7 @@ bool IfcGeom::convert(const IfcSchema::IfcAxis2Placement2D* l, gp_Trsf2d& trsf)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcObjectPlacement* l, gp_Trsf& trsf) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcObjectPlacement* l, gp_Trsf& trsf) {
|
||||
IN_CACHE(IfcObjectPlacement,l,gp_Trsf,trsf)
|
||||
if ( ! l->is(IfcSchema::Type::IfcLocalPlacement) ) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Unsupported IfcObjectPlacement:", l->entity);
|
||||
@@ -301,7 +291,7 @@ bool IfcGeom::convert(const IfcSchema::IfcObjectPlacement* l, gp_Trsf& trsf) {
|
||||
gp_Trsf trsf2;
|
||||
IfcSchema::IfcAxis2Placement relplacement = current->RelativePlacement();
|
||||
if ( relplacement->is(IfcSchema::Type::IfcAxis2Placement3D) ) {
|
||||
IfcGeom::convert((IfcSchema::IfcAxis2Placement3D*)relplacement,trsf2);
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcAxis2Placement3D*)relplacement,trsf2);
|
||||
trsf.PreMultiply(trsf2);
|
||||
}
|
||||
if ( current->hasPlacementRelTo() ) {
|
||||
@@ -313,9 +303,4 @@ bool IfcGeom::convert(const IfcSchema::IfcObjectPlacement* l, gp_Trsf& trsf) {
|
||||
}
|
||||
CACHE(IfcObjectPlacement,l,trsf)
|
||||
return true;
|
||||
}
|
||||
|
||||
void IfcGeom::Cache::Purge() {
|
||||
#include "IfcRegisterPurgeCache.h"
|
||||
IfcGeom::Cache::PurgeShapeCache();
|
||||
}
|
||||
@@ -0,0 +1,635 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* *
|
||||
* Geometrical data in an IFC file consists of shapes (IfcShapeRepresentation) *
|
||||
* and instances (SUBTYPE OF IfcBuildingElement e.g. IfcWindow). *
|
||||
* *
|
||||
* IfcGeom::Representation::Triangulation is a class that represents a *
|
||||
* triangulated IfcShapeRepresentation. *
|
||||
* Triangulation.verts is a 1 dimensional vector of float defining the *
|
||||
* cartesian coordinates of the vertices of the triangulated shape in the *
|
||||
* format of [x1,y1,z1,..,xn,yn,zn] *
|
||||
* Triangulation.faces is a 1 dimensional vector of int containing the *
|
||||
* indices of the triangles referencing positions in Triangulation.verts *
|
||||
* Triangulation.edges is a 1 dimensional vector of int in {0,1} that dictates*
|
||||
* the visibility of the edges that span the faces in Triangulation.faces *
|
||||
* *
|
||||
* IfcGeom::Element represents the actual IfcBuildingElements. *
|
||||
* IfcGeomObject.name is the GUID of the element *
|
||||
* IfcGeomObject.type is the datatype of the element e.g. IfcWindow *
|
||||
* IfcGeomObject.mesh is a pointer to an IfcMesh *
|
||||
* IfcGeomObject.transformation.matrix is a 4x3 matrix that defines the *
|
||||
* orientation and translation of the mesh in relation to the world origin *
|
||||
* *
|
||||
* IfcGeom::Iterator::findContext() *
|
||||
* finds the most suitable representation contexts. Returns true iff *
|
||||
* at least a single representation will process successfully *
|
||||
* *
|
||||
* IfcGeom::Iterator::get() *
|
||||
* returns a pointer to the current IfcGeom::Element *
|
||||
* *
|
||||
* IfcGeom::Iterator::next() *
|
||||
* returns true iff a following entity is available for a successive call to *
|
||||
* IfcGeom::Iterator::get() *
|
||||
* *
|
||||
* IfcGeom::Iterator::progress() *
|
||||
* returns an int in [0..100] that indicates the overall progress *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCGEOMITERATOR_H
|
||||
#define IFCGEOMITERATOR_H
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include <gp_Mat.hxx>
|
||||
#include <gp_Mat2d.hxx>
|
||||
#include <gp_GTrsf.hxx>
|
||||
#include <gp_GTrsf2d.hxx>
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <gp_Trsf2d.hxx>
|
||||
|
||||
#include "../ifcparse/IfcParse.h"
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
#include "../ifcgeom/IfcGeomUtils.h"
|
||||
#include "../ifcgeom/IfcGeomElement.h"
|
||||
#include "../ifcgeom/IfcGeomMaterial.h"
|
||||
#include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||
#include "../ifcgeom/IfcRepresentationShapeItem.h"
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
template <typename P>
|
||||
class Iterator {
|
||||
private:
|
||||
Kernel kernel;
|
||||
IteratorSettings settings;
|
||||
|
||||
IfcParse::IfcFile* ifc_file;
|
||||
|
||||
// A container and iterator for IfcShapeRepresentations
|
||||
IfcSchema::IfcRepresentation::list::ptr representations;
|
||||
IfcSchema::IfcRepresentation::list::it shaperep_iterator;
|
||||
|
||||
// The object is fetched beforehand to be sure that get() returns a valid element
|
||||
TriangulationElement<P>* current_triangulation;
|
||||
ShapeModelElement<P>* current_shape_model;
|
||||
SerializedElement<P>* current_serialization;
|
||||
|
||||
// A container and iterator for IfcBuildingElements for the current IfcRepresentation referenced by *shaperep_iterator
|
||||
IfcSchema::IfcProduct::list::ptr entities;
|
||||
IfcSchema::IfcProduct::list::it ifcproduct_iterator;
|
||||
|
||||
int done;
|
||||
int total;
|
||||
|
||||
std::string unit_name;
|
||||
// double?
|
||||
P unit_magnitude;
|
||||
|
||||
// Store references to all returned non-geometric elements to be freed when the destructor is called
|
||||
std::vector<Element<P>*> returned_elements;
|
||||
|
||||
void initUnits() {
|
||||
// Set default units, set length to meters, angles to undefined
|
||||
kernel.setValue(IfcGeom::Kernel::GV_LENGTH_UNIT, 1.0);
|
||||
kernel.setValue(IfcGeom::Kernel::GV_PLANEANGLE_UNIT, -1.0);
|
||||
|
||||
IfcSchema::IfcUnitAssignment::list::ptr unit_assignments = ifc_file->EntitiesByType<IfcSchema::IfcUnitAssignment>();
|
||||
IfcUtil::IfcAbstractSelect::list::ptr units;
|
||||
try {
|
||||
if ( unit_assignments->Size() ) {
|
||||
IfcSchema::IfcUnitAssignment* unit_assignment = *unit_assignments->begin();
|
||||
units = unit_assignment->Units();
|
||||
}
|
||||
} catch (const IfcParse::IfcException&) {}
|
||||
|
||||
if (!units || !units->Size()) {
|
||||
// No units eh... Since tolerances and deflection are specified internally in meters
|
||||
// we will try to find another indication of the model size.
|
||||
IfcSchema::IfcExtrudedAreaSolid::list::ptr extrusions = ifc_file->EntitiesByType<IfcSchema::IfcExtrudedAreaSolid>();
|
||||
if ( ! extrusions->Size() ) return;
|
||||
double max_height = -1.0f;
|
||||
for ( IfcSchema::IfcExtrudedAreaSolid::list::it it = extrusions->begin(); it != extrusions->end(); ++ it ) {
|
||||
try {
|
||||
const double depth = (*it)->Depth();
|
||||
if ( depth > max_height ) max_height = depth;
|
||||
} catch (const IfcParse::IfcException&) {}
|
||||
}
|
||||
if ( max_height > 100.0f ) {
|
||||
kernel.setValue(IfcGeom::Kernel::GV_LENGTH_UNIT, 0.001);
|
||||
Logger::Message(Logger::LOG_NOTICE, "Guessed length unit to be in millimeters based on extrusion depth");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
for ( IfcUtil::IfcAbstractSelect::list::it it = units->begin(); it != units->end(); ++ it ) {
|
||||
std::string current_unit_name = "";
|
||||
IfcUtil::IfcAbstractSelect* base = *it;
|
||||
IfcSchema::IfcSIUnit* unit = 0;
|
||||
double value = 1.f;
|
||||
if ( base->is(IfcSchema::Type::IfcConversionBasedUnit) ) {
|
||||
IfcSchema::IfcConversionBasedUnit* u = (IfcSchema::IfcConversionBasedUnit*)base;
|
||||
current_unit_name = u->Name();
|
||||
IfcSchema::IfcMeasureWithUnit* u2 = u->ConversionFactor();
|
||||
IfcSchema::IfcUnit u3 = u2->UnitComponent();
|
||||
if ( u3->is(IfcSchema::Type::IfcSIUnit) ) {
|
||||
unit = (IfcSchema::IfcSIUnit*) u3;
|
||||
}
|
||||
IfcSchema::IfcValue v = u2->ValueComponent();
|
||||
IfcUtil::IfcArgumentSelect* v2 = (IfcUtil::IfcArgumentSelect*) v;
|
||||
const double f = *v2->wrappedValue();
|
||||
value *= f;
|
||||
} else if ( base->is(IfcSchema::Type::IfcSIUnit) ) {
|
||||
unit = (IfcSchema::IfcSIUnit*)base;
|
||||
}
|
||||
if ( unit ) {
|
||||
if ( unit->hasPrefix() ) {
|
||||
value *= IfcGeom::Utils::UnitPrefixToValue(unit->Prefix());
|
||||
}
|
||||
IfcSchema::IfcUnitEnum::IfcUnitEnum type = unit->UnitType();
|
||||
if ( type == IfcSchema::IfcUnitEnum::IfcUnit_LENGTHUNIT ) {
|
||||
kernel.setValue(IfcGeom::Kernel::GV_LENGTH_UNIT,value);
|
||||
if (current_unit_name.empty()) {
|
||||
if (unit->hasPrefix()) {
|
||||
current_unit_name = IfcSchema::IfcSIPrefix::ToString(unit->Prefix());
|
||||
}
|
||||
current_unit_name += IfcSchema::IfcSIUnitName::ToString(unit->Name());
|
||||
}
|
||||
unit_magnitude = static_cast<P>(value);
|
||||
unit_name = current_unit_name;
|
||||
} else if ( type == IfcSchema::IfcUnitEnum::IfcUnit_PLANEANGLEUNIT ) {
|
||||
kernel.setValue(IfcGeom::Kernel::GV_PLANEANGLE_UNIT, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (const IfcParse::IfcException& ex) {
|
||||
std::stringstream ss;
|
||||
ss << "Failed to determine unit information '" << ex.what() << "'";
|
||||
Logger::Message(Logger::LOG_ERROR, ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
bool findContext() {
|
||||
|
||||
try {
|
||||
initUnits();
|
||||
} catch (...) {}
|
||||
|
||||
// Really this should only be 'Model', as per
|
||||
// the standard 'Design' is deprecated. So,
|
||||
// just for backwards compatibility:
|
||||
std::set<std::string> context_types;
|
||||
context_types.insert("model");
|
||||
context_types.insert("design");
|
||||
// DDS likes to output 'model view'
|
||||
context_types.insert("model view");
|
||||
|
||||
double lowest_precision_encountered = std::numeric_limits<double>::infinity();
|
||||
bool any_precision_encountered = false;
|
||||
|
||||
representations = IfcSchema::IfcRepresentation::list::ptr(new IfcSchema::IfcRepresentation::list);
|
||||
|
||||
IfcSchema::IfcGeometricRepresentationContext::list::it it;
|
||||
IfcSchema::IfcGeometricRepresentationSubContext::list::it jt;
|
||||
IfcSchema::IfcGeometricRepresentationContext::list::ptr contexts =
|
||||
ifc_file->EntitiesByType<IfcSchema::IfcGeometricRepresentationContext>();
|
||||
|
||||
IfcSchema::IfcGeometricRepresentationContext::list::ptr filtered_contexts (new IfcSchema::IfcGeometricRepresentationContext::list);
|
||||
|
||||
for (it = contexts->begin(); it != contexts->end(); ++it) {
|
||||
IfcSchema::IfcGeometricRepresentationContext* context = *it;
|
||||
if (context->is(IfcSchema::Type::IfcGeometricRepresentationSubContext)) {
|
||||
// Continue, as the list of subcontexts will be considered
|
||||
// by the parent's context inverse attributes.
|
||||
continue;
|
||||
}
|
||||
std::string context_type_lc = context->ContextType();
|
||||
for (std::string::iterator c = context_type_lc.begin(); c != context_type_lc.end(); ++c) {
|
||||
*c = tolower(*c);
|
||||
}
|
||||
if (context->hasContextType() && context_types.find(context_type_lc) != context_types.end()) {
|
||||
filtered_contexts->push(context);
|
||||
}
|
||||
}
|
||||
|
||||
if (filtered_contexts->Size() == 0) {
|
||||
filtered_contexts = contexts;
|
||||
}
|
||||
|
||||
for (it = filtered_contexts->begin(); it != filtered_contexts->end(); ++it) {
|
||||
IfcSchema::IfcGeometricRepresentationContext* context = *it;
|
||||
|
||||
representations->push(context->RepresentationsInContext());
|
||||
if (context->hasPrecision() && context->Precision() < lowest_precision_encountered) {
|
||||
lowest_precision_encountered = context->Precision();
|
||||
any_precision_encountered = true;
|
||||
}
|
||||
IfcSchema::IfcGeometricRepresentationSubContext::list::ptr sub_contexts = context->HasSubContexts();
|
||||
for (jt = sub_contexts->begin(); jt != sub_contexts->end(); ++jt) {
|
||||
representations->push((*jt)->RepresentationsInContext());
|
||||
}
|
||||
// There is no need for full recursion as the following is governed by the schema:
|
||||
// WR31: The parent context shall not be another geometric representation sub context.
|
||||
}
|
||||
|
||||
if (any_precision_encountered) {
|
||||
kernel.setValue(IfcGeom::Kernel::GV_PRECISION, lowest_precision_encountered);
|
||||
} else {
|
||||
kernel.setValue(IfcGeom::Kernel::GV_PRECISION, 1.e-5);
|
||||
}
|
||||
|
||||
if (representations->Size() == 0) return false;
|
||||
|
||||
shaperep_iterator = representations->begin();
|
||||
entities.reset();
|
||||
|
||||
if (!create()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
done = 0;
|
||||
total = representations->Size();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int progress() {
|
||||
return 100 * done / total;
|
||||
}
|
||||
|
||||
const std::string& getUnitName() {
|
||||
return unit_name;
|
||||
}
|
||||
|
||||
const P getUnitMagnitude() {
|
||||
return unit_magnitude;
|
||||
}
|
||||
|
||||
const std::string getLog() {
|
||||
return Logger::GetLog();
|
||||
}
|
||||
|
||||
IfcParse::IfcFile* getFile() {
|
||||
return ifc_file;
|
||||
}
|
||||
|
||||
private:
|
||||
// Move the the next IfcRepresentation
|
||||
void _nextShape() {
|
||||
entities.reset();
|
||||
++ shaperep_iterator;
|
||||
++ done;
|
||||
}
|
||||
|
||||
int _getParentId(IfcSchema::IfcProduct* ifc_product) {
|
||||
int parent_id = -1;
|
||||
// In case of an opening element, parent to the RelatingBuildingElement
|
||||
if ( ifc_product->is(IfcSchema::Type::IfcOpeningElement ) ) {
|
||||
IfcSchema::IfcOpeningElement* opening = (IfcSchema::IfcOpeningElement*)ifc_product;
|
||||
IfcSchema::IfcRelVoidsElement::list::ptr voids = opening->VoidsElements();
|
||||
if ( voids->Size() ) {
|
||||
IfcSchema::IfcRelVoidsElement* ifc_void = *voids->begin();
|
||||
parent_id = ifc_void->RelatingBuildingElement()->entity->id();
|
||||
}
|
||||
} else if ( ifc_product->is(IfcSchema::Type::IfcElement ) ) {
|
||||
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)ifc_product;
|
||||
IfcSchema::IfcRelFillsElement::list::ptr fills = element->FillsVoids();
|
||||
// Incase of a RelatedBuildingElement parent to the opening element
|
||||
if ( fills->Size() ) {
|
||||
for ( IfcSchema::IfcRelFillsElement::list::it it = fills->begin(); it != fills->end(); ++ it ) {
|
||||
IfcSchema::IfcRelFillsElement* fill = *it;
|
||||
IfcSchema::IfcObjectDefinition* ifc_objectdef = fill->RelatingOpeningElement();
|
||||
if ( ifc_product == ifc_objectdef ) continue;
|
||||
parent_id = ifc_objectdef->entity->id();
|
||||
}
|
||||
}
|
||||
// Else simply parent to the containing structure
|
||||
if ( parent_id == -1 ) {
|
||||
IfcSchema::IfcRelContainedInSpatialStructure::list::ptr parents = element->ContainedInStructure();
|
||||
if ( parents->Size() ) {
|
||||
IfcSchema::IfcRelContainedInSpatialStructure* parent = *parents->begin();
|
||||
parent_id = parent->RelatingStructure()->entity->id();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Parent decompositions to the RelatingObject
|
||||
if ( parent_id == -1 ) {
|
||||
IfcEntityList::ptr parents = ifc_product->entity->getInverse(IfcSchema::Type::IfcRelAggregates);
|
||||
parents->push(ifc_product->entity->getInverse(IfcSchema::Type::IfcRelNests));
|
||||
for ( IfcEntityList::it it = parents->begin(); it != parents->end(); ++ it ) {
|
||||
IfcSchema::IfcRelDecomposes* decompose = (IfcSchema::IfcRelDecomposes*)*it;
|
||||
IfcSchema::IfcObjectDefinition* ifc_objectdef;
|
||||
#ifdef USE_IFC4
|
||||
if (decompose->is(IfcSchema::Type::IfcRelAggregates)) {
|
||||
ifc_objectdef = ((IfcSchema::IfcRelAggregates*)decompose)->RelatingObject();
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
ifc_objectdef = decompose->RelatingObject();
|
||||
#endif
|
||||
if ( ifc_product == ifc_objectdef ) continue;
|
||||
parent_id = ifc_objectdef->entity->id();
|
||||
}
|
||||
}
|
||||
return parent_id;
|
||||
}
|
||||
|
||||
ShapeModelElement<P>* create_shape_model_for_next_entity() {
|
||||
while ( true ) {
|
||||
IfcSchema::IfcRepresentation* shaperep;
|
||||
|
||||
// Have we reached the end of our list of representations?
|
||||
if ( shaperep_iterator == representations->end() ) {
|
||||
representations.reset();
|
||||
return 0;
|
||||
}
|
||||
shaperep = *shaperep_iterator;
|
||||
|
||||
// Has the list of IfcProducts for this representation been initialized?
|
||||
if ( ! entities ) {
|
||||
|
||||
IfcSchema::IfcProductRepresentation::list::ptr prodreps = shaperep->OfProductRepresentation();
|
||||
entities = IfcSchema::IfcProduct::list::ptr(new IfcSchema::IfcProduct::list);
|
||||
for ( IfcSchema::IfcProductRepresentation::list::it it = prodreps->begin(); it != prodreps->end(); ++it ) {
|
||||
if ( (*it)->is(IfcSchema::Type::IfcProductDefinitionShape) ) {
|
||||
IfcSchema::IfcProductDefinitionShape* pds = (IfcSchema::IfcProductDefinitionShape*)*it;
|
||||
entities->push(pds->ShapeOfProduct());
|
||||
} else {
|
||||
// http://buildingsmart-tech.org/ifc/IFC2x3/TC1/html/ifcrepresentationresource/lexical/ifcproductrepresentation.htm
|
||||
// IFC2x Edition 3 NOTE Users should not instantiate the entity IfcProductRepresentation from IFC2x Edition 3 onwards.
|
||||
// It will be changed into an ABSTRACT supertype in future releases of IFC.
|
||||
|
||||
// IfcProductRepresentation also lacks the INVERSE relation to IfcProduct
|
||||
// Let's find the IfcProducts that reference the IfcProductRepresentation anyway
|
||||
IfcEntityList::ptr products = (*it)->entity->getInverse(IfcSchema::Type::IfcProduct);
|
||||
for ( IfcEntityList::it it = products->begin(); it != products->end(); ++ it ) {
|
||||
entities->push((IfcSchema::IfcProduct*)*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Does this representation have any IfcProducts?
|
||||
if ( ! entities->Size() ) {
|
||||
_nextShape();
|
||||
continue;
|
||||
}
|
||||
ifcproduct_iterator = entities->begin();
|
||||
}
|
||||
// Have we reached the end of our list of IfcProducts?
|
||||
if ( ifcproduct_iterator == entities->end() ) {
|
||||
_nextShape();
|
||||
continue;
|
||||
}
|
||||
|
||||
IfcGeom::Representation::BRep* shape;
|
||||
IfcGeom::IfcRepresentationShapeItems shapes;
|
||||
|
||||
if ( !kernel.convert_shapes(shaperep,shapes) ) {
|
||||
_nextShape();
|
||||
continue;
|
||||
}
|
||||
|
||||
IfcSchema::IfcProduct* ifc_product = *ifcproduct_iterator;
|
||||
|
||||
int parent_id = -1;
|
||||
try {
|
||||
parent_id = _getParentId(ifc_product);
|
||||
} catch (...) {}
|
||||
|
||||
const std::string name = ifc_product->hasName() ? ifc_product->Name() : "";
|
||||
const std::string guid = ifc_product->GlobalId();
|
||||
|
||||
gp_Trsf trsf;
|
||||
try {
|
||||
kernel.convert(ifc_product->ObjectPlacement(),trsf);
|
||||
} catch (...) {}
|
||||
|
||||
// Does the IfcElement have any IfcOpenings?
|
||||
// Note that openings for IfcOpeningElements are not processed
|
||||
IfcSchema::IfcRelVoidsElement::list::ptr openings;
|
||||
if ( ifc_product->is(IfcSchema::Type::IfcElement) && !ifc_product->is(IfcSchema::Type::IfcOpeningElement) ) {
|
||||
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)ifc_product;
|
||||
openings = element->HasOpenings();
|
||||
}
|
||||
// Is the IfcElement a decomposition of an IfcElement with any IfcOpeningElements?
|
||||
if ( ifc_product->is(IfcSchema::Type::IfcBuildingElementPart ) ) {
|
||||
IfcSchema::IfcBuildingElementPart* part = (IfcSchema::IfcBuildingElementPart*)ifc_product;
|
||||
#ifdef USE_IFC4
|
||||
IfcSchema::IfcRelAggregates::list::ptr decomposes = part->Decomposes();
|
||||
for ( IfcSchema::IfcRelAggregates::list::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
|
||||
#else
|
||||
IfcSchema::IfcRelDecomposes::list::ptr decomposes = part->Decomposes();
|
||||
for ( IfcSchema::IfcRelDecomposes::list::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
|
||||
#endif
|
||||
IfcSchema::IfcObjectDefinition* obdef = (*it)->RelatingObject();
|
||||
if ( obdef->is(IfcSchema::Type::IfcElement) ) {
|
||||
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)obdef;
|
||||
openings->push(element->HasOpenings());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::string product_type = IfcSchema::Type::ToString(ifc_product->type());
|
||||
ElementSettings element_settings(settings, unit_magnitude, product_type);
|
||||
|
||||
if ( !settings.disable_opening_subtractions() && openings && openings->Size() ) {
|
||||
IfcGeom::IfcRepresentationShapeItems opened_shapes;
|
||||
try {
|
||||
if ( settings.faster_booleans() ) {
|
||||
bool succes = kernel.convert_openings_fast(ifc_product,openings,shapes,trsf,opened_shapes);
|
||||
if ( ! succes ) {
|
||||
opened_shapes.clear();
|
||||
kernel.convert_openings(ifc_product,openings,shapes,trsf,opened_shapes);
|
||||
}
|
||||
} else {
|
||||
kernel.convert_openings(ifc_product,openings,shapes,trsf,opened_shapes);
|
||||
}
|
||||
} catch(...) {
|
||||
Logger::Message(Logger::LOG_ERROR,"Error processing openings for:",ifc_product->entity);
|
||||
}
|
||||
if ( settings.use_world_coords() ) {
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::iterator it = opened_shapes.begin(); it != opened_shapes.end(); ++ it ) {
|
||||
it->prepend(trsf);
|
||||
}
|
||||
trsf = gp_Trsf();
|
||||
}
|
||||
shape = new IfcGeom::Representation::BRep(element_settings, shaperep->entity->id(), opened_shapes);
|
||||
} else if ( settings.use_world_coords() ) {
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
||||
it->prepend(trsf);
|
||||
}
|
||||
trsf = gp_Trsf();
|
||||
shape = new IfcGeom::Representation::BRep(element_settings, shaperep->entity->id(), shapes);
|
||||
} else {
|
||||
shape = new IfcGeom::Representation::BRep(element_settings, shaperep->entity->id(), shapes);
|
||||
}
|
||||
|
||||
return new ShapeModelElement<P>(
|
||||
ifc_product->entity->id(),
|
||||
parent_id,
|
||||
name,
|
||||
product_type,
|
||||
guid,
|
||||
trsf,
|
||||
shape
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
bool next() {
|
||||
// Free all possible representations of the current geometrical entity
|
||||
delete current_triangulation;
|
||||
current_triangulation = 0;
|
||||
|
||||
// Increment the iterator over the list of products using the current
|
||||
// shape representation
|
||||
if (entities) {
|
||||
++ifcproduct_iterator;
|
||||
}
|
||||
|
||||
return create();
|
||||
}
|
||||
|
||||
Element<P>* get() {
|
||||
// TODO: Test settings and throw
|
||||
if (current_triangulation) return current_triangulation;
|
||||
else if (current_serialization) return current_serialization;
|
||||
else if (current_shape_model) return current_shape_model;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
const Element<P>* getObject(int id) {
|
||||
|
||||
gp_Trsf trsf;
|
||||
int parent_id = -1;
|
||||
std::string instance_type, product_name, product_guid;
|
||||
|
||||
try {
|
||||
const IfcUtil::IfcBaseClass* ifc_entity = ifc_file->EntityById(id);
|
||||
instance_type = IfcSchema::Type::ToString(ifc_entity->type());
|
||||
if ( ifc_entity->is(IfcSchema::Type::IfcProduct) ) {
|
||||
IfcSchema::IfcProduct* ifc_product = (IfcSchema::IfcProduct*)ifc_entity;
|
||||
|
||||
product_guid = ifc_product->GlobalId();
|
||||
product_name = ifc_product->hasName() ? ifc_product->Name() : "";
|
||||
|
||||
try {
|
||||
parent_id = _getParentId(ifc_product);
|
||||
} catch (...) {}
|
||||
|
||||
try {
|
||||
kernel.convert(ifc_product->ObjectPlacement(), trsf);
|
||||
} catch (...) {}
|
||||
}
|
||||
} catch(...) {}
|
||||
|
||||
ElementSettings element_settings(settings, unit_magnitude, instance_type);
|
||||
Element<P>* ifc_object = new Element<P>(element_settings, id, parent_id, product_name, instance_type, product_guid, trsf);
|
||||
|
||||
returned_elements.push_back(ifc_object);
|
||||
return ifc_object;
|
||||
}
|
||||
|
||||
bool create() {
|
||||
try {
|
||||
current_shape_model = create_shape_model_for_next_entity();
|
||||
} catch (...) {}
|
||||
if (!current_shape_model) return false;
|
||||
if (settings.use_brep_data()) {
|
||||
try {
|
||||
current_serialization = new SerializedElement<P>(*current_shape_model);
|
||||
} catch (...) {}
|
||||
return !!current_serialization;
|
||||
} else if (!settings.disable_triangulation()) {
|
||||
try {
|
||||
current_triangulation = new TriangulationElement<P>(*current_shape_model);
|
||||
} catch (...) {}
|
||||
return !!current_triangulation;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
private:
|
||||
void initialize() {
|
||||
current_triangulation = 0;
|
||||
current_shape_model = 0;
|
||||
current_serialization = 0;
|
||||
|
||||
unit_name = "METER";
|
||||
unit_magnitude = 1.f;
|
||||
|
||||
kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.sew_shells() ? 1000 : -1);
|
||||
kernel.setValue(IfcGeom::Kernel::GV_FORCE_CCW_FACE_ORIENTATION, settings.force_ccw_face_orientation() ? 1 : -1);
|
||||
}
|
||||
public:
|
||||
Iterator(const IteratorSettings& settings, IfcParse::IfcFile* file)
|
||||
: settings(settings)
|
||||
, ifc_file(file)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
Iterator(const IteratorSettings& settings, const std::string& filename)
|
||||
: settings(settings)
|
||||
, ifc_file(new IfcParse::IfcFile)
|
||||
{
|
||||
ifc_file->Init(filename);
|
||||
initialize();
|
||||
}
|
||||
Iterator(const IteratorSettings& settings, void* data, int length)
|
||||
: settings(settings)
|
||||
, ifc_file(new IfcParse::IfcFile)
|
||||
{
|
||||
ifc_file->Init(data, length);
|
||||
initialize();
|
||||
}
|
||||
Iterator(const IteratorSettings& settings, std::istream& filestream, int length)
|
||||
: settings(settings)
|
||||
, ifc_file(new IfcParse::IfcFile)
|
||||
{
|
||||
ifc_file->Init(filestream, length);
|
||||
initialize();
|
||||
}
|
||||
|
||||
~Iterator() {
|
||||
// TODO: Correctly implement destructor for IfcFile
|
||||
delete ifc_file;
|
||||
|
||||
std::vector<Element<P>*>::const_iterator it;
|
||||
for (it = returned_elements.begin(); it != returned_elements.end(); ++ it ) {
|
||||
delete *it;
|
||||
}
|
||||
|
||||
returned_elements.clear();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,171 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 IFCGEOMITERATORSETTINGS_H
|
||||
#define IFCGEOMITERATORSETTINGS_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "../ifcparse/IfcException.h"
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
class IteratorSettings {
|
||||
public:
|
||||
// Enumeration of setting identifiers. These settings define the
|
||||
// behaviour of various aspects of IfcOpenShell.
|
||||
|
||||
// Specifies whether vertices are welded, meaning that the coordinates
|
||||
// vector will only contain unique xyz-triplets. This results in a
|
||||
// manifold mesh which is useful for modelling applications, but might
|
||||
// result in unwanted shading artifacts in rendering applications.
|
||||
static const int WELD_VERTICES = 1;
|
||||
// Specifies whether to apply the local placements of building elements
|
||||
// directly to the coordinates of the representation mesh rather than
|
||||
// to represent the local placement in the 4x3 matrix, which will in that
|
||||
// case be the identity matrix.
|
||||
static const int USE_WORLD_COORDS = 2;
|
||||
// Internally IfcOpenShell measures everything in meters. This settings
|
||||
// specifies whether to convert IfcGeomObjects back to the units in which
|
||||
// the geometry in the IFC file is specified.
|
||||
static const int CONVERT_BACK_UNITS = 3;
|
||||
// Specifies whether to use the Open Cascade BREP format for representation
|
||||
// items rather than to create triangle meshes. This is useful is IfcOpenShell
|
||||
// is used as a library in an application that is also built on Open Cascade.
|
||||
static const int USE_BREP_DATA = 4;
|
||||
// Specifies whether to sew IfcConnectedFaceSets (open and closed shells) to
|
||||
// TopoDS_Shells or whether to keep them as a loose collection of faces.
|
||||
static const int SEW_SHELLS = 5;
|
||||
// Specifies whether to compose IfcOpeningElements into a single compound
|
||||
// in order to speed up the processing of opening subtractions.
|
||||
static const int FASTER_BOOLEANS = 6;
|
||||
// By default singular faces have no explicitly defined orientation, to
|
||||
// force faces to be defined CounterClockWise set this to true.
|
||||
static const int FORCE_CCW_FACE_ORIENTATION = 7;
|
||||
// Disables the subtraction of IfcOpeningElement representations from
|
||||
// the related building element representations.
|
||||
static const int DISABLE_OPENING_SUBTRACTIONS = 8;
|
||||
// Disables the triangulation of the topological representations. Useful if
|
||||
// the client application understands Open Cascade's native format.
|
||||
static const int DISABLE_TRIANGULATION = 9;
|
||||
// Applies default materials to entity instances without a surface style.
|
||||
static const int APPLY_DEFAULT_MATERIALS = 10;
|
||||
|
||||
// End of settings enumeration.
|
||||
|
||||
private:
|
||||
bool _weld_vertices, _use_world_coords, _convert_back_units, _use_brep_data, _sew_shells, _faster_booleans, _force_ccw_face_orientation, _disable_opening_subtractions, _disable_triangulation, _apply_default_materials;
|
||||
double _deflection_tolerance;
|
||||
public:
|
||||
IteratorSettings()
|
||||
: _weld_vertices(true)
|
||||
, _use_world_coords(false)
|
||||
, _convert_back_units(false)
|
||||
, _use_brep_data(false)
|
||||
, _sew_shells(false)
|
||||
, _faster_booleans(false)
|
||||
, _force_ccw_face_orientation(false)
|
||||
, _disable_triangulation(false)
|
||||
, _apply_default_materials(false)
|
||||
// TODO: Make deflection tolerance into a command line argument
|
||||
// For now, stick to one millimeter. Note that this is independent of the IFC length unit.
|
||||
, _deflection_tolerance(1.e-3)
|
||||
{}
|
||||
|
||||
const bool& weld_vertices() const { return _weld_vertices; }
|
||||
bool& weld_vertices() { return _weld_vertices; }
|
||||
const bool& use_world_coords() const { return _use_world_coords; }
|
||||
bool& use_world_coords() { return _use_world_coords; }
|
||||
const bool& convert_back_units() const { return _convert_back_units; }
|
||||
bool& convert_back_units() { return _convert_back_units; }
|
||||
const bool& use_brep_data() const { return _use_brep_data; }
|
||||
bool& use_brep_data() { return _use_brep_data; }
|
||||
const bool& sew_shells() const { return _sew_shells; }
|
||||
bool& sew_shells() { return _sew_shells; }
|
||||
const bool& faster_booleans() const { return _faster_booleans; }
|
||||
bool& faster_booleans() { return _faster_booleans; }
|
||||
const bool& force_ccw_face_orientation() const { return _force_ccw_face_orientation; }
|
||||
bool& force_ccw_face_orientation() { return _force_ccw_face_orientation; }
|
||||
const bool& disable_opening_subtractions() const { return _disable_opening_subtractions; }
|
||||
bool& disable_opening_subtractions() { return _disable_opening_subtractions; }
|
||||
const bool& disable_triangulation() const { return _disable_triangulation; }
|
||||
bool& disable_triangulation() { return _disable_triangulation; }
|
||||
const bool& apply_default_materials() const { return _apply_default_materials; }
|
||||
bool& apply_default_materials() { return _apply_default_materials; }
|
||||
|
||||
const double& deflection_tolerance() const { return _deflection_tolerance; }
|
||||
double& deflection_tolerance() { return _deflection_tolerance; }
|
||||
|
||||
void set(int setting, bool value) {
|
||||
switch (setting) {
|
||||
case USE_WORLD_COORDS:
|
||||
_use_world_coords = value;
|
||||
break;
|
||||
case WELD_VERTICES:
|
||||
_weld_vertices = value;
|
||||
break;
|
||||
case CONVERT_BACK_UNITS:
|
||||
_convert_back_units = value;
|
||||
break;
|
||||
case USE_BREP_DATA:
|
||||
_use_brep_data = value;
|
||||
break;
|
||||
case FASTER_BOOLEANS:
|
||||
_faster_booleans = value;
|
||||
break;
|
||||
case SEW_SHELLS:
|
||||
_sew_shells = value;
|
||||
break;
|
||||
case FORCE_CCW_FACE_ORIENTATION:
|
||||
_force_ccw_face_orientation = value;
|
||||
break;
|
||||
case DISABLE_OPENING_SUBTRACTIONS:
|
||||
_disable_opening_subtractions = value;
|
||||
break;
|
||||
case DISABLE_TRIANGULATION:
|
||||
_disable_triangulation = value;
|
||||
break;
|
||||
case APPLY_DEFAULT_MATERIALS:
|
||||
_apply_default_materials = value;
|
||||
break;
|
||||
default: throw IfcParse::IfcException("Invalid IteratorSetting");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class ElementSettings : public IteratorSettings {
|
||||
private:
|
||||
double _unit_magnitude;
|
||||
std::string _element_type;
|
||||
public:
|
||||
ElementSettings(const IteratorSettings& settings,
|
||||
double unit_magnitude,
|
||||
const std::string& element_type)
|
||||
: IteratorSettings(settings)
|
||||
, _unit_magnitude(unit_magnitude)
|
||||
, _element_type(element_type)
|
||||
{}
|
||||
|
||||
const double& unit_magnitude() const { return _unit_magnitude; }
|
||||
const std::string& element_type() const { return _element_type; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "IfcGeomMaterial.h"
|
||||
|
||||
static double black[3] = {0.,0.,0.};
|
||||
|
||||
IfcGeom::Material::Material(const IfcGeom::SurfaceStyle* style) : style(style) {}
|
||||
bool IfcGeom::Material::hasDiffuse() const { return style->Diffuse(); }
|
||||
bool IfcGeom::Material::hasSpecular() const { return style->Specular(); }
|
||||
bool IfcGeom::Material::hasTransparency() const { return style->Transparency(); }
|
||||
bool IfcGeom::Material::hasSpecularity() const { return style->Specularity(); }
|
||||
const double* IfcGeom::Material::diffuse() const { if (hasDiffuse()) return &((*style->Diffuse()).R()); else return black; }
|
||||
const double* IfcGeom::Material::specular() const { if (hasSpecular()) return &((*style->Specular()).R()); else return black; }
|
||||
double IfcGeom::Material::transparency() const { if (hasTransparency()) return *style->Transparency(); else return 0; }
|
||||
double IfcGeom::Material::specularity() const { if (hasSpecularity()) return *style->Specularity(); else return 0; }
|
||||
const std::string IfcGeom::Material::name() const { return style->Name(); }
|
||||
bool IfcGeom::Material::operator==(const IfcGeom::Material& other) const { return style == other.style; }
|
||||
@@ -0,0 +1,50 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 IFCGEOMMATERIAL_H
|
||||
#define IFCGEOMMATERIAL_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
class Material {
|
||||
private:
|
||||
const IfcGeom::SurfaceStyle* style;
|
||||
public:
|
||||
explicit Material(const IfcGeom::SurfaceStyle* style = 0); // TODO default constructor for vector?
|
||||
// Material(const Material& other);
|
||||
// Material& operator=(const Material& other);
|
||||
bool hasDiffuse() const;
|
||||
bool hasSpecular() const;
|
||||
bool hasTransparency() const;
|
||||
bool hasSpecularity() const;
|
||||
const double* diffuse() const;
|
||||
const double* specular() const;
|
||||
double transparency() const;
|
||||
double specularity() const;
|
||||
const std::string name() const;
|
||||
bool operator==(const Material& other) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,858 +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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <limits>
|
||||
|
||||
#include <gp_Mat.hxx>
|
||||
#include <gp_Mat2d.hxx>
|
||||
#include <gp_GTrsf.hxx>
|
||||
#include <gp_GTrsf2d.hxx>
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <gp_Trsf2d.hxx>
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <BRepMesh.hxx>
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <Poly_PolygonOnTriangulation.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <TShort_Array1OfShortReal.hxx>
|
||||
#include <Poly_Array1OfTriangle.hxx>
|
||||
#include <StdFail_NotDone.hxx>
|
||||
#include <BRepGProp_Face.hxx>
|
||||
#include <BRepBuilderAPI_GTransform.hxx>
|
||||
|
||||
#include "../ifcparse/IfcException.h"
|
||||
#include "../ifcgeom/IfcGeomObjects.h"
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
|
||||
// Welds vertices that belong to different faces
|
||||
static bool weld_vertices = true;
|
||||
|
||||
static bool convert_back_units = false;
|
||||
static bool use_faster_booleans = false;
|
||||
static bool disable_subtractions = false;
|
||||
static bool disable_triangulation = false;
|
||||
|
||||
int IfcGeomObjects::IfcRepresentationTriangulation::addvert(int material_index, const gp_XYZ& p) {
|
||||
const float X = convert_back_units ? (float) (p.X() / IfcGeom::GetValue(IfcGeom::GV_LENGTH_UNIT)) : (float)p.X();
|
||||
const float Y = convert_back_units ? (float) (p.Y() / IfcGeom::GetValue(IfcGeom::GV_LENGTH_UNIT)) : (float)p.Y();
|
||||
const float Z = convert_back_units ? (float) (p.Z() / IfcGeom::GetValue(IfcGeom::GV_LENGTH_UNIT)) : (float)p.Z();
|
||||
int i = (int) _verts.size() / 3;
|
||||
if ( weld_vertices ) {
|
||||
const VertKey key = std::make_pair(material_index, std::make_pair(X, std::make_pair(Y, Z)));
|
||||
VertKeyMap::const_iterator it = welds.find(key);
|
||||
if ( it != welds.end() ) return it->second;
|
||||
i = (int) welds.size();
|
||||
welds[key] = i;
|
||||
}
|
||||
_verts.push_back(X);
|
||||
_verts.push_back(Y);
|
||||
_verts.push_back(Z);
|
||||
return i;
|
||||
}
|
||||
|
||||
static bool use_world_coords = false;
|
||||
static bool use_brep_data = false;
|
||||
|
||||
static IfcParse::IfcFile* ifc_file = 0;
|
||||
|
||||
IfcGeomObjects::IfcRepresentationBrepData::IfcRepresentationBrepData(const IfcRepresentationShapeModel& shapes)
|
||||
: _id(shapes.getId())
|
||||
{
|
||||
try {
|
||||
TopoDS_Compound compound;
|
||||
BRep_Builder builder;
|
||||
builder.MakeCompound(compound);
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
||||
const TopoDS_Shape& s = it->Shape();
|
||||
gp_GTrsf trsf = it->Placement();
|
||||
if (convert_back_units) {
|
||||
gp_Trsf scale;
|
||||
scale.SetScaleFactor(1.0 / IfcGeom::GetValue(IfcGeom::GV_LENGTH_UNIT));
|
||||
trsf.PreMultiply(scale);
|
||||
}
|
||||
bool trsf_valid = false;
|
||||
gp_Trsf _trsf;
|
||||
try {
|
||||
_trsf = trsf.Trsf();
|
||||
trsf_valid = true;
|
||||
} catch (...) {}
|
||||
const TopoDS_Shape moved_shape = trsf_valid ? s.Moved(_trsf) :
|
||||
BRepBuilderAPI_GTransform(s,trsf,true).Shape();
|
||||
builder.Add(compound,moved_shape);
|
||||
}
|
||||
std::stringstream sstream;
|
||||
BRepTools::Write(compound,sstream);
|
||||
_brep_data = sstream.str();
|
||||
} catch(...) {
|
||||
Logger::Message(Logger::LOG_ERROR,"Failed to serialize shape:",ifc_file->EntityById(_id)->entity);
|
||||
}
|
||||
}
|
||||
|
||||
IfcGeomObjects::IfcRepresentationTriangulation::IfcRepresentationTriangulation(const IfcRepresentationShapeModel& shapes)
|
||||
: _id(shapes.getId())
|
||||
{
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
||||
|
||||
int surface_style_id = -1;
|
||||
if (it->hasStyle()) {
|
||||
Material adapter(&it->Style());
|
||||
std::vector<Material>::const_iterator jt = std::find(_materials.begin(), _materials.end(), adapter);
|
||||
if (jt == _materials.end()) {
|
||||
surface_style_id = _materials.size();
|
||||
_materials.push_back(adapter);
|
||||
} else {
|
||||
surface_style_id = jt - _materials.begin();
|
||||
}
|
||||
}
|
||||
|
||||
const TopoDS_Shape& s = it->Shape();
|
||||
const gp_GTrsf& trsf = it->Placement();
|
||||
|
||||
// Triangulate the shape
|
||||
try {
|
||||
// BRepTools::Clean(s);
|
||||
BRepMesh::Mesh(s, IfcGeom::GetValue(IfcGeom::GV_DEFLECTION_TOLERANCE));
|
||||
} catch(...) {
|
||||
Logger::Message(Logger::LOG_ERROR,"Failed to triangulate shape:",ifc_file->EntityById(_id)->entity);
|
||||
continue;
|
||||
}
|
||||
TopExp_Explorer exp;
|
||||
|
||||
// Iterates over the faces of the shape
|
||||
for ( exp.Init(s,TopAbs_FACE); exp.More(); exp.Next() ) {
|
||||
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
|
||||
const bool calculate_normals = ! weld_vertices;
|
||||
|
||||
for( int i = 1; i <= nodes.Length(); ++ i ) {
|
||||
coords.push_back(nodes(i).Transformed(loc).XYZ());
|
||||
trsf.Transforms(*coords.rbegin());
|
||||
dict[i] = addvert(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() > ALMOST_ZERO) {
|
||||
normal = gp_Dir(normal_direction.XYZ() * rotation_matrix);
|
||||
}
|
||||
_normals.push_back((float)normal.X());
|
||||
_normals.push_back((float)normal.Y());
|
||||
_normals.push_back((float)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(n1,n2,edgecount,edges_temp);
|
||||
addedge(n2,n3,edgecount,edges_temp);
|
||||
addedge(n3,n1,edgecount,edges_temp);
|
||||
}
|
||||
for ( std::vector<std::pair<int,int> >::const_iterator it = edges_temp.begin(); it != edges_temp.end(); ++it ) {
|
||||
_edges.push_back(edgecount[*it]==1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IfcGeomObjects::IfcObject::IfcObject(
|
||||
int id,
|
||||
int parent_id,
|
||||
const std::string& name,
|
||||
const std::string& type,
|
||||
const std::string& guid,
|
||||
const gp_Trsf& trsf)
|
||||
: _id(id)
|
||||
, _parent_id(parent_id)
|
||||
, _name(name)
|
||||
, _type(type)
|
||||
, _guid(guid)
|
||||
{
|
||||
// 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
|
||||
// by the magnitude of the IFC model length unit because
|
||||
// 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 matrix_value = i == 4 && convert_back_units
|
||||
? trsf_value / IfcGeom::GetValue(IfcGeom::GV_LENGTH_UNIT)
|
||||
: trsf_value;
|
||||
_matrix.push_back(static_cast<float>(matrix_value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IfcGeomObjects::IfcGeomShapeModelObject::IfcGeomShapeModelObject(
|
||||
int id,
|
||||
int parent_id,
|
||||
const std::string& name,
|
||||
const std::string& type,
|
||||
const std::string& guid,
|
||||
const gp_Trsf& trsf,
|
||||
IfcRepresentationShapeModel* shapes)
|
||||
: IfcObject(id,parent_id,name,type,guid,trsf)
|
||||
, _mesh(shapes)
|
||||
{}
|
||||
|
||||
IfcGeomObjects::IfcGeomBrepDataObject::IfcGeomBrepDataObject(
|
||||
const IfcGeomShapeModelObject& shape_model)
|
||||
: IfcObject(shape_model)
|
||||
, _mesh(new IfcRepresentationBrepData(shape_model.mesh()))
|
||||
{}
|
||||
|
||||
IfcGeomObjects::IfcGeomObject::IfcGeomObject(
|
||||
const IfcGeomShapeModelObject& shape_model)
|
||||
: IfcObject(shape_model)
|
||||
, _mesh(new IfcRepresentationTriangulation(shape_model.mesh()))
|
||||
{}
|
||||
|
||||
// A container and iterator for IfcShapeRepresentations
|
||||
static IfcSchema::IfcShapeRepresentation::list::ptr shapereps;
|
||||
static IfcSchema::IfcShapeRepresentation::list::it shaperep_iterator;
|
||||
|
||||
// The object is fetched beforehand to be positive an entity actually exists
|
||||
static IfcGeomObjects::IfcGeomObject* current_geom_obj = 0;
|
||||
static IfcGeomObjects::IfcGeomShapeModelObject* current_shape_model_obj = 0;
|
||||
static IfcGeomObjects::IfcGeomBrepDataObject* current_brep_data_obj = 0;
|
||||
|
||||
// A container and iterator for IfcBuildingElements for the current IfcShapeRepresentation referenced by *shaperep_iterator
|
||||
static IfcSchema::IfcProduct::list::ptr entities;
|
||||
static IfcSchema::IfcProduct::list::it ifcproduct_iterator;
|
||||
|
||||
static int done;
|
||||
static int total;
|
||||
|
||||
// Move the the next IfcShapeRepresentation
|
||||
void _nextShape() {
|
||||
entities.reset();
|
||||
++ shaperep_iterator;
|
||||
++ done;
|
||||
}
|
||||
|
||||
int _getParentId(IfcSchema::IfcProduct* ifc_product) {
|
||||
int parent_id = -1;
|
||||
// In case of an opening element, parent to the RelatingBuildingElement
|
||||
if ( ifc_product->is(IfcSchema::Type::IfcOpeningElement ) ) {
|
||||
IfcSchema::IfcOpeningElement* opening = (IfcSchema::IfcOpeningElement*)ifc_product;
|
||||
IfcSchema::IfcRelVoidsElement::list::ptr voids = opening->VoidsElements();
|
||||
if ( voids->Size() ) {
|
||||
IfcSchema::IfcRelVoidsElement* ifc_void = *voids->begin();
|
||||
parent_id = ifc_void->RelatingBuildingElement()->entity->id();
|
||||
}
|
||||
} else if ( ifc_product->is(IfcSchema::Type::IfcElement ) ) {
|
||||
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)ifc_product;
|
||||
IfcSchema::IfcRelFillsElement::list::ptr fills = element->FillsVoids();
|
||||
// Incase of a RelatedBuildingElement parent to the opening element
|
||||
if ( fills->Size() ) {
|
||||
for ( IfcSchema::IfcRelFillsElement::list::it it = fills->begin(); it != fills->end(); ++ it ) {
|
||||
IfcSchema::IfcRelFillsElement* fill = *it;
|
||||
IfcSchema::IfcObjectDefinition* ifc_objectdef = fill->RelatingOpeningElement();
|
||||
if ( ifc_product == ifc_objectdef ) continue;
|
||||
parent_id = ifc_objectdef->entity->id();
|
||||
}
|
||||
}
|
||||
// Else simply parent to the containing structure
|
||||
if ( parent_id == -1 ) {
|
||||
IfcSchema::IfcRelContainedInSpatialStructure::list::ptr parents = element->ContainedInStructure();
|
||||
if ( parents->Size() ) {
|
||||
IfcSchema::IfcRelContainedInSpatialStructure* parent = *parents->begin();
|
||||
parent_id = parent->RelatingStructure()->entity->id();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Parent decompositions to the RelatingObject
|
||||
if ( parent_id == -1 ) {
|
||||
IfcEntityList::ptr parents = ifc_product->entity->getInverse(IfcSchema::Type::IfcRelAggregates);
|
||||
parents->push(ifc_product->entity->getInverse(IfcSchema::Type::IfcRelNests));
|
||||
for ( IfcEntityList::it it = parents->begin(); it != parents->end(); ++ it ) {
|
||||
IfcSchema::IfcRelDecomposes* decompose = (IfcSchema::IfcRelDecomposes*)*it;
|
||||
IfcSchema::IfcObjectDefinition* ifc_objectdef;
|
||||
#ifdef USE_IFC4
|
||||
if (decompose->is(IfcSchema::Type::IfcRelAggregates)) {
|
||||
ifc_objectdef = ((IfcSchema::IfcRelAggregates*)decompose)->RelatingObject();
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
ifc_objectdef = decompose->RelatingObject();
|
||||
#endif
|
||||
if ( ifc_product == ifc_objectdef ) continue;
|
||||
parent_id = ifc_objectdef->entity->id();
|
||||
}
|
||||
}
|
||||
return parent_id;
|
||||
}
|
||||
|
||||
IfcGeomObjects::IfcGeomShapeModelObject* create_shape_model_for_next_entity() {
|
||||
while ( true ) {
|
||||
IfcSchema::IfcShapeRepresentation* shaperep;
|
||||
|
||||
// Have we reached the end of our list of representations?
|
||||
if ( shaperep_iterator == shapereps->end() ) {
|
||||
shapereps.reset();
|
||||
return 0;
|
||||
}
|
||||
shaperep = *shaperep_iterator;
|
||||
|
||||
// Has the list of IfcProducts for this representation been initialized?
|
||||
if ( ! entities ) {
|
||||
if ( shaperep->hasRepresentationIdentifier() ) {
|
||||
const std::string representation_identifier = shaperep->RepresentationIdentifier();
|
||||
if ( shaperep->hasRepresentationType() && representation_identifier == "IAI" && shaperep->RepresentationType() != "BoundingBox" ) {
|
||||
// Allow for Ifc 2x compatibility
|
||||
} else if ( representation_identifier != "Body" &&
|
||||
representation_identifier != "Facetation" ) {
|
||||
_nextShape();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
IfcSchema::IfcProductRepresentation::list::ptr prodreps = shaperep->OfProductRepresentation();
|
||||
entities = IfcSchema::IfcProduct::list::ptr(new IfcSchema::IfcProduct::list);
|
||||
for ( IfcSchema::IfcProductRepresentation::list::it it = prodreps->begin(); it != prodreps->end(); ++it ) {
|
||||
if ( (*it)->is(IfcSchema::Type::IfcProductDefinitionShape) ) {
|
||||
IfcSchema::IfcProductDefinitionShape* pds = (IfcSchema::IfcProductDefinitionShape*)*it;
|
||||
entities->push(pds->ShapeOfProduct());
|
||||
} else {
|
||||
// http://buildingsmart-tech.org/ifc/IFC2x3/TC1/html/ifcrepresentationresource/lexical/ifcproductrepresentation.htm
|
||||
// IFC2x Edition 3 NOTE Users should not instantiate the entity IfcProductRepresentation from IFC2x Edition 3 onwards.
|
||||
// It will be changed into an ABSTRACT supertype in future releases of IFC.
|
||||
|
||||
// IfcProductRepresentation also lacks the INVERSE relation to IfcProduct
|
||||
// Let's find the IfcProducts that reference the IfcProductRepresentation anyway
|
||||
IfcEntityList::ptr products = (*it)->entity->getInverse(IfcSchema::Type::IfcProduct);
|
||||
for ( IfcEntityList::it it = products->begin(); it != products->end(); ++ it ) {
|
||||
entities->push((IfcSchema::IfcProduct*)*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Does this representation have any IfcProducts?
|
||||
if ( ! entities->Size() ) {
|
||||
_nextShape();
|
||||
continue;
|
||||
}
|
||||
ifcproduct_iterator = entities->begin();
|
||||
}
|
||||
// Have we reached the end of our list of IfcProducts?
|
||||
if ( ifcproduct_iterator == entities->end() ) {
|
||||
_nextShape();
|
||||
continue;
|
||||
}
|
||||
|
||||
IfcGeomObjects::IfcRepresentationShapeModel* shape;
|
||||
IfcGeom::IfcRepresentationShapeItems shapes;
|
||||
|
||||
if ( !IfcGeom::convert_shapes(shaperep,shapes) ) {
|
||||
_nextShape();
|
||||
continue;
|
||||
}
|
||||
|
||||
IfcSchema::IfcProduct* ifc_product = *ifcproduct_iterator;
|
||||
|
||||
int parent_id = -1;
|
||||
try {
|
||||
parent_id = _getParentId(ifc_product);
|
||||
} catch (...) {}
|
||||
|
||||
const std::string name = ifc_product->hasName() ? ifc_product->Name() : "";
|
||||
const std::string guid = ifc_product->GlobalId();
|
||||
|
||||
gp_Trsf trsf;
|
||||
try {
|
||||
IfcGeom::convert(ifc_product->ObjectPlacement(),trsf);
|
||||
} catch (...) {}
|
||||
|
||||
// Does the IfcElement have any IfcOpenings?
|
||||
// Note that openings for IfcOpeningElements are not processed
|
||||
IfcSchema::IfcRelVoidsElement::list::ptr openings;
|
||||
if ( ifc_product->is(IfcSchema::Type::IfcElement) && !ifc_product->is(IfcSchema::Type::IfcOpeningElement) ) {
|
||||
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)ifc_product;
|
||||
openings = element->HasOpenings();
|
||||
}
|
||||
// Is the IfcElement a decomposition of an IfcElement with any IfcOpeningElements?
|
||||
if ( ifc_product->is(IfcSchema::Type::IfcBuildingElementPart ) ) {
|
||||
IfcSchema::IfcBuildingElementPart* part = (IfcSchema::IfcBuildingElementPart*)ifc_product;
|
||||
#ifdef USE_IFC4
|
||||
IfcSchema::IfcRelAggregates::list::ptr decomposes = part->Decomposes();
|
||||
for ( IfcSchema::IfcRelAggregates::list::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
|
||||
#else
|
||||
IfcSchema::IfcRelDecomposes::list::ptr decomposes = part->Decomposes();
|
||||
for ( IfcSchema::IfcRelDecomposes::list::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
|
||||
#endif
|
||||
IfcSchema::IfcObjectDefinition* obdef = (*it)->RelatingObject();
|
||||
if ( obdef->is(IfcSchema::Type::IfcElement) ) {
|
||||
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)obdef;
|
||||
openings->push(element->HasOpenings());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !disable_subtractions && openings && openings->Size() ) {
|
||||
IfcGeom::IfcRepresentationShapeItems opened_shapes;
|
||||
try {
|
||||
if ( use_faster_booleans ) {
|
||||
bool succes = IfcGeom::convert_openings_fast(ifc_product,openings,shapes,trsf,opened_shapes);
|
||||
if ( ! succes ) {
|
||||
opened_shapes.clear();
|
||||
IfcGeom::convert_openings(ifc_product,openings,shapes,trsf,opened_shapes);
|
||||
}
|
||||
} else {
|
||||
IfcGeom::convert_openings(ifc_product,openings,shapes,trsf,opened_shapes);
|
||||
}
|
||||
} catch(...) {
|
||||
Logger::Message(Logger::LOG_ERROR,"Error processing openings for:",ifc_product->entity);
|
||||
}
|
||||
if ( use_world_coords ) {
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::iterator it = opened_shapes.begin(); it != opened_shapes.end(); ++ it ) {
|
||||
it->prepend(trsf);
|
||||
}
|
||||
trsf = gp_Trsf();
|
||||
}
|
||||
shape = new IfcGeomObjects::IfcRepresentationShapeModel(shaperep->entity->id(),opened_shapes);
|
||||
} else if ( use_world_coords ) {
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
||||
it->prepend(trsf);
|
||||
}
|
||||
trsf = gp_Trsf();
|
||||
shape = new IfcGeomObjects::IfcRepresentationShapeModel(shaperep->entity->id(),shapes);
|
||||
} else {
|
||||
shape = new IfcGeomObjects::IfcRepresentationShapeModel(shaperep->entity->id(),shapes);
|
||||
}
|
||||
|
||||
return new IfcGeomObjects::IfcGeomShapeModelObject(ifc_product->entity->id(), parent_id, name,
|
||||
IfcSchema::Type::ToString(ifc_product->type()), guid, trsf, shape);
|
||||
}
|
||||
}
|
||||
|
||||
bool try_and_create_representations_for_current_entity() {
|
||||
current_shape_model_obj = create_shape_model_for_next_entity();
|
||||
if (current_shape_model_obj == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (use_brep_data) {
|
||||
current_brep_data_obj = new IfcGeomObjects::IfcGeomBrepDataObject(*current_shape_model_obj);
|
||||
if (current_brep_data_obj == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!disable_triangulation) {
|
||||
current_geom_obj = new IfcGeomObjects::IfcGeomObject(*current_shape_model_obj);
|
||||
if (current_geom_obj == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeomObjects::Next() {
|
||||
// Free all possible representations of the current geometrical entity
|
||||
delete current_geom_obj;
|
||||
delete current_brep_data_obj;
|
||||
delete current_shape_model_obj;
|
||||
current_geom_obj = 0;
|
||||
current_brep_data_obj = 0;
|
||||
current_shape_model_obj = 0;
|
||||
|
||||
// Increment the iterator over the list of products using the current
|
||||
// shape representation
|
||||
if (entities) {
|
||||
++ifcproduct_iterator;
|
||||
}
|
||||
|
||||
return try_and_create_representations_for_current_entity();
|
||||
}
|
||||
|
||||
static std::vector<IfcGeomObjects::IfcObject*> returned_objects;
|
||||
bool IfcGeomObjects::CleanUp() {
|
||||
// TODO: Correctly implement destructor for IfcFile
|
||||
delete ifc_file;
|
||||
IfcGeom::Cache::Purge();
|
||||
std::vector<IfcGeomObjects::IfcObject*>::const_iterator it;
|
||||
for (it = returned_objects.begin(); it != returned_objects.end(); ++ it ) {
|
||||
delete *it;
|
||||
}
|
||||
returned_objects.clear();
|
||||
return true;
|
||||
}
|
||||
const IfcGeomObjects::IfcObject* IfcGeomObjects::GetObject(int id) {
|
||||
IfcObject* ifc_object = 0;
|
||||
try {
|
||||
const IfcUtil::IfcBaseClass* ifc_entity = ifc_file->EntityById(id);
|
||||
if ( ifc_entity->is(IfcSchema::Type::IfcProduct) ) {
|
||||
IfcSchema::IfcProduct* ifc_product = (IfcSchema::IfcProduct*)ifc_entity;
|
||||
int parent_id = -1;
|
||||
try {
|
||||
parent_id = _getParentId(ifc_product);
|
||||
} catch (...) {}
|
||||
const std::string name = ifc_product->hasName() ? ifc_product->Name() : "";
|
||||
gp_Trsf trsf;
|
||||
try {
|
||||
IfcGeom::convert(ifc_product->ObjectPlacement(),trsf);
|
||||
} catch (...) {}
|
||||
ifc_object = new IfcObject(ifc_product->entity->id(),parent_id,name,
|
||||
IfcSchema::Type::ToString(ifc_product->type()),ifc_product->GlobalId(),trsf);
|
||||
}
|
||||
} catch(...) {}
|
||||
if ( !ifc_object ) ifc_object = new IfcObject(-1,-1,"","","",gp_Trsf());
|
||||
returned_objects.push_back(ifc_object);
|
||||
return ifc_object;
|
||||
}
|
||||
const IfcGeomObjects::IfcGeomObject* IfcGeomObjects::Get() {
|
||||
if (disable_triangulation) {
|
||||
throw std::runtime_error("No triangulation available");
|
||||
}
|
||||
return current_geom_obj;
|
||||
}
|
||||
const IfcGeomObjects::IfcGeomShapeModelObject* IfcGeomObjects::GetShapeModel() {
|
||||
return current_shape_model_obj;
|
||||
}
|
||||
const IfcGeomObjects::IfcGeomBrepDataObject* IfcGeomObjects::GetBrepData() {
|
||||
if (!use_brep_data) {
|
||||
throw std::runtime_error("No BRep data available");
|
||||
}
|
||||
return current_brep_data_obj;
|
||||
}
|
||||
double UnitPrefixToValue( IfcSchema::IfcSIPrefix::IfcSIPrefix v ) {
|
||||
if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_EXA ) return (double) 1e18;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_PETA ) return (double) 1e15;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_TERA ) return (double) 1e12;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_GIGA ) return (double) 1e9;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_MEGA ) return (double) 1e6;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_KILO ) return (double) 1e3;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_HECTO ) return (double) 1e2;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_DECA ) return (double) 1;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_DECI ) return (double) 1e-1;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_CENTI ) return (double) 1e-2;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_MILLI ) return (double) 1e-3;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_MICRO ) return (double) 1e-6;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_NANO ) return (double) 1e-9;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_PICO ) return (double) 1e-12;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_FEMTO ) return (double) 1e-15;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_ATTO ) return (double) 1e-18;
|
||||
else return 1.0f;
|
||||
}
|
||||
|
||||
static std::string unit_name = "METER";
|
||||
static float unit_magnitude = 1.0f;
|
||||
|
||||
void IfcGeomObjects::InitPrecision() {
|
||||
IfcGeom::SetValue(IfcGeom::GV_PRECISION, 0.00001);
|
||||
|
||||
try {
|
||||
IfcSchema::IfcGeometricRepresentationContext::list::ptr rep_contexts = ifc_file->EntitiesByType<IfcSchema::IfcGeometricRepresentationContext>();
|
||||
// Currently, IfcGeometricRepresentationContext aren't used as much as they should be
|
||||
// in the evaluation of shape representations, hence, we try to find the one with the
|
||||
// lowest precision. Typically, a value of 1e-5 is encountered. This value is applied
|
||||
// to all TopoDS_Shapes generated by one of the IfcGeom::convert() functions.
|
||||
// TODO: Many of the empirically found tolerances should probably be substituted by
|
||||
// one that is defined in the model file.
|
||||
double lowest_precision_encountered = std::numeric_limits<double>::infinity();
|
||||
bool any_precision_encountered = false;
|
||||
for (IfcSchema::IfcGeometricRepresentationContext::list::it it = rep_contexts->begin(); it != rep_contexts->end(); ++it) {
|
||||
IfcSchema::IfcGeometricRepresentationContext* rep_context = *it;
|
||||
if (rep_context->is(IfcSchema::Type::IfcGeometricRepresentationSubContext)) continue;
|
||||
if (rep_context->hasPrecision()) {
|
||||
const double precision = rep_context->Precision();
|
||||
if (precision < lowest_precision_encountered) {
|
||||
any_precision_encountered = true;
|
||||
lowest_precision_encountered = precision;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (any_precision_encountered) {
|
||||
lowest_precision_encountered *= unit_magnitude;
|
||||
if (lowest_precision_encountered < 1.e-8) {
|
||||
Logger::Message(Logger::LOG_WARNING, "Precision lower than 0.00000001 meter not enforced");
|
||||
IfcGeom::SetValue(IfcGeom::GV_PRECISION, 1.e-8);
|
||||
} else {
|
||||
IfcGeom::SetValue(IfcGeom::GV_PRECISION, lowest_precision_encountered);
|
||||
}
|
||||
}
|
||||
} catch (const IfcParse::IfcException& ex) {
|
||||
std::stringstream ss;
|
||||
ss << "Failed to determine precision value '" << ex.what() << "'";
|
||||
Logger::Message(Logger::LOG_ERROR, ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
void IfcGeomObjects::InitUnits() {
|
||||
// Set default units, set length to meters, angles to undefined
|
||||
IfcGeom::SetValue(IfcGeom::GV_LENGTH_UNIT,1.0);
|
||||
IfcGeom::SetValue(IfcGeom::GV_PLANEANGLE_UNIT,-1.0);
|
||||
|
||||
IfcSchema::IfcUnitAssignment::list::ptr unit_assignments = ifc_file->EntitiesByType<IfcSchema::IfcUnitAssignment>();
|
||||
IfcUtil::IfcAbstractSelect::list::ptr units;
|
||||
try {
|
||||
if ( unit_assignments->Size() ) {
|
||||
IfcSchema::IfcUnitAssignment* unit_assignment = *unit_assignments->begin();
|
||||
units = unit_assignment->Units();
|
||||
}
|
||||
} catch (const IfcParse::IfcException&) {}
|
||||
|
||||
if (!units || !units->Size()) {
|
||||
// No units eh... Since tolerances and deflection are specified internally in meters
|
||||
// we will try to find another indication of the model size.
|
||||
IfcSchema::IfcExtrudedAreaSolid::list::ptr extrusions = ifc_file->EntitiesByType<IfcSchema::IfcExtrudedAreaSolid>();
|
||||
if ( ! extrusions->Size() ) return;
|
||||
double max_height = -1.0f;
|
||||
for ( IfcSchema::IfcExtrudedAreaSolid::list::it it = extrusions->begin(); it != extrusions->end(); ++ it ) {
|
||||
try {
|
||||
const double depth = (*it)->Depth();
|
||||
if ( depth > max_height ) max_height = depth;
|
||||
} catch (const IfcParse::IfcException&) {}
|
||||
}
|
||||
if ( max_height > 100.0f ) {
|
||||
IfcGeom::SetValue(IfcGeom::GV_LENGTH_UNIT,0.001);
|
||||
Logger::Message(Logger::LOG_NOTICE, "Guessed length unit to be in millimeters based on extrusion depth");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
for ( IfcUtil::IfcAbstractSelect::list::it it = units->begin(); it != units->end(); ++ it ) {
|
||||
std::string current_unit_name = "";
|
||||
IfcUtil::IfcAbstractSelect* base = *it;
|
||||
IfcSchema::IfcSIUnit* unit = 0;
|
||||
double value = 1.0f;
|
||||
if ( base->is(IfcSchema::Type::IfcConversionBasedUnit) ) {
|
||||
IfcSchema::IfcConversionBasedUnit* u = (IfcSchema::IfcConversionBasedUnit*)base;
|
||||
current_unit_name = u->Name();
|
||||
IfcSchema::IfcMeasureWithUnit* u2 = u->ConversionFactor();
|
||||
IfcSchema::IfcUnit u3 = u2->UnitComponent();
|
||||
if ( u3->is(IfcSchema::Type::IfcSIUnit) ) {
|
||||
unit = (IfcSchema::IfcSIUnit*) u3;
|
||||
}
|
||||
IfcSchema::IfcValue v = u2->ValueComponent();
|
||||
IfcUtil::IfcArgumentSelect* v2 = (IfcUtil::IfcArgumentSelect*) v;
|
||||
const double f = *v2->wrappedValue();
|
||||
value *= f;
|
||||
} else if ( base->is(IfcSchema::Type::IfcSIUnit) ) {
|
||||
unit = (IfcSchema::IfcSIUnit*)base;
|
||||
}
|
||||
if ( unit ) {
|
||||
if ( unit->hasPrefix() ) {
|
||||
value *= UnitPrefixToValue(unit->Prefix());
|
||||
}
|
||||
IfcSchema::IfcUnitEnum::IfcUnitEnum type = unit->UnitType();
|
||||
if ( type == IfcSchema::IfcUnitEnum::IfcUnit_LENGTHUNIT ) {
|
||||
IfcGeom::SetValue(IfcGeom::GV_LENGTH_UNIT,value);
|
||||
if (current_unit_name.empty()) {
|
||||
if (unit->hasPrefix()) {
|
||||
current_unit_name = IfcSchema::IfcSIPrefix::ToString(unit->Prefix());
|
||||
}
|
||||
current_unit_name += IfcSchema::IfcSIUnitName::ToString(unit->Name());
|
||||
}
|
||||
unit_magnitude = value;
|
||||
unit_name = current_unit_name;
|
||||
} else if ( type == IfcSchema::IfcUnitEnum::IfcUnit_PLANEANGLEUNIT ) {
|
||||
IfcGeom::SetValue(IfcGeom::GV_PLANEANGLE_UNIT,value);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (const IfcParse::IfcException& ex) {
|
||||
std::stringstream ss;
|
||||
ss << "Failed to determine unit information '" << ex.what() << "'";
|
||||
Logger::Message(Logger::LOG_ERROR, ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
bool IfcGeomObjects::Init(const std::string fn) {
|
||||
return IfcGeomObjects::Init(fn, 0, 0);
|
||||
}
|
||||
bool _Init() {
|
||||
IfcGeomObjects::InitUnits();
|
||||
IfcGeomObjects::InitPrecision();
|
||||
|
||||
shapereps = ifc_file->EntitiesByType<IfcSchema::IfcShapeRepresentation>();
|
||||
if ( ! shapereps ) return false;
|
||||
|
||||
shaperep_iterator = shapereps->begin();
|
||||
entities.reset();
|
||||
|
||||
if (!try_and_create_representations_for_current_entity()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
done = 0;
|
||||
total = shapereps->Size();
|
||||
return true;
|
||||
}
|
||||
bool IfcGeomObjects::Init(const std::string fn, std::ostream* log1, std::ostream* log2) {
|
||||
Logger::SetOutput(log1,log2);
|
||||
ifc_file = new IfcParse::IfcFile();
|
||||
if ( !ifc_file->Init(fn) ) return false;
|
||||
return _Init();
|
||||
}
|
||||
bool IfcGeomObjects::Init(std::istream& f, int len, std::ostream* log1, std::ostream* log2) {
|
||||
Logger::SetOutput(log1,log2);
|
||||
ifc_file = new IfcParse::IfcFile();
|
||||
if ( !ifc_file->Init(f, len) ) return false;
|
||||
return _Init();
|
||||
}
|
||||
bool IfcGeomObjects::Init(void* data, int len) {
|
||||
Logger::SetOutput(0,0);
|
||||
ifc_file = new IfcParse::IfcFile();
|
||||
if ( !ifc_file->Init(data, len) ) return false;
|
||||
return _Init();
|
||||
}
|
||||
void IfcGeomObjects::Settings(int setting, bool value) {
|
||||
switch ( setting ) {
|
||||
case USE_WORLD_COORDS:
|
||||
use_world_coords = value;
|
||||
break;
|
||||
case WELD_VERTICES:
|
||||
weld_vertices = value;
|
||||
break;
|
||||
case CONVERT_BACK_UNITS:
|
||||
convert_back_units = value;
|
||||
break;
|
||||
case USE_BREP_DATA:
|
||||
use_brep_data = value;
|
||||
break;
|
||||
case FASTER_BOOLEANS:
|
||||
use_faster_booleans = value;
|
||||
break;
|
||||
case SEW_SHELLS:
|
||||
IfcGeom::SetValue(IfcGeom::GV_MAX_FACES_TO_SEW,value ? 1000 : -1);
|
||||
break;
|
||||
case FORCE_CCW_FACE_ORIENTATION:
|
||||
IfcGeom::SetValue(IfcGeom::GV_FORCE_CCW_FACE_ORIENTATION,value ? 1 : -1);
|
||||
break;
|
||||
case DISABLE_OPENING_SUBTRACTIONS:
|
||||
disable_subtractions = value;
|
||||
break;
|
||||
case DISABLE_TRIANGULATION:
|
||||
disable_triangulation = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int IfcGeomObjects::Progress() {
|
||||
return 100 * done / total;
|
||||
}
|
||||
|
||||
const std::string& IfcGeomObjects::GetUnitName() {
|
||||
return unit_name;
|
||||
}
|
||||
|
||||
const float IfcGeomObjects::GetUnitMagnitude() {
|
||||
return unit_magnitude;
|
||||
}
|
||||
|
||||
const std::string IfcGeomObjects::GetLog() {
|
||||
return Logger::GetLog();
|
||||
}
|
||||
|
||||
IfcParse::IfcFile* IfcGeomObjects::GetFile() {
|
||||
return ifc_file;
|
||||
}
|
||||
|
||||
static double black[3] = {0,0,0};
|
||||
|
||||
IfcGeomObjects::Material::Material(const IfcGeom::SurfaceStyle* style) : style(style) {}
|
||||
bool IfcGeomObjects::Material::hasDiffuse() const { return style->Diffuse(); }
|
||||
bool IfcGeomObjects::Material::hasSpecular() const { return style->Specular(); }
|
||||
bool IfcGeomObjects::Material::hasTransparency() const { return style->Transparency(); }
|
||||
bool IfcGeomObjects::Material::hasSpecularity() const { return style->Specularity(); }
|
||||
const double* IfcGeomObjects::Material::diffuse() const { if (hasDiffuse()) return &((*style->Diffuse()).R()); else return black; }
|
||||
const double* IfcGeomObjects::Material::specular() const { if (hasSpecular()) return &((*style->Specular()).R()); else return black; }
|
||||
double IfcGeomObjects::Material::transparency() const { if (hasTransparency()) return *style->Transparency(); else return 0; }
|
||||
double IfcGeomObjects::Material::specularity() const { if (hasSpecularity()) return *style->Specularity(); else return 0; }
|
||||
const std::string IfcGeomObjects::Material::name() const { return style->Name(); }
|
||||
bool IfcGeomObjects::Material::operator==(const IfcGeomObjects::Material& other) const { return style == other.style; }
|
||||
|
||||
int IfcGeomObjects::IfcRepresentationBrepData::id() const { return _id; }
|
||||
const std::string& IfcGeomObjects::IfcRepresentationBrepData::brep_data() const { return _brep_data; }
|
||||
|
||||
int IfcGeomObjects::IfcRepresentationTriangulation::id() const { return _id; }
|
||||
const std::vector<float>& IfcGeomObjects::IfcRepresentationTriangulation::verts() const { return _verts; }
|
||||
const std::vector<int>& IfcGeomObjects::IfcRepresentationTriangulation::faces() const { return _faces; }
|
||||
const std::vector<int>& IfcGeomObjects::IfcRepresentationTriangulation::edges() const { return _edges; }
|
||||
const std::vector<float>& IfcGeomObjects::IfcRepresentationTriangulation::normals() const { return _normals; }
|
||||
const std::vector<int>& IfcGeomObjects::IfcRepresentationTriangulation::material_ids() const { return _material_ids; }
|
||||
const std::vector<IfcGeomObjects::Material>& IfcGeomObjects::IfcRepresentationTriangulation::materials() const { return _materials; }
|
||||
|
||||
int IfcGeomObjects::IfcObject::id() const { return _id; }
|
||||
int IfcGeomObjects::IfcObject::parent_id() const { return _parent_id; }
|
||||
const std::string& IfcGeomObjects::IfcObject::name() const { return _name; }
|
||||
const std::string& IfcGeomObjects::IfcObject::type() const { return _type; }
|
||||
const std::string& IfcGeomObjects::IfcObject::guid() const { return _guid; }
|
||||
const std::vector<float>& IfcGeomObjects::IfcObject::matrix() const { return _matrix; }
|
||||
|
||||
const IfcGeomObjects::IfcRepresentationShapeModel& IfcGeomObjects::IfcGeomShapeModelObject::mesh() const { return *_mesh; }
|
||||
const IfcGeomObjects::IfcRepresentationTriangulation& IfcGeomObjects::IfcGeomObject::mesh() const { return *_mesh; }
|
||||
const IfcGeomObjects::IfcRepresentationBrepData& IfcGeomObjects::IfcGeomBrepDataObject::mesh() const { return *_mesh; }
|
||||
|
||||
@@ -1,286 +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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* *
|
||||
* Geometrical data in an IFC file consists of shapes (IfcShapeRepresentation) *
|
||||
* and instances (SUBTYPE OF IfcBuildingElement e.g. IfcWindow). *
|
||||
* *
|
||||
* IfcMesh is a class that represents a triangulated IfcShapeRepresentation. *
|
||||
* IfcMesh.verts is a 1 dimensional vector of float defining the cartesian *
|
||||
* coordinates of the vertices of the triangulated shape in the format of *
|
||||
* [x1,y1,z1,..,xn,yn,zn] *
|
||||
* IfcMesh.faces is a 1 dimensional vector of int containing the indices of *
|
||||
* the triangles referencing positions in IfcMesh.verts *
|
||||
* IfcMesh.edges is a 1 dimensional vector of int in {0,1} that dictates *
|
||||
* the visibility of the edges that span the faces in IfcMesh.faces *
|
||||
* *
|
||||
* IfcGeomObject represents the actual IfcBuildingElements. *
|
||||
* IfcGeomObject.name is the GUID of the element *
|
||||
* IfcGeomObject.type is the datatype of the element e.g. IfcWindow *
|
||||
* IfcGeomObject.mesh is a pointer to an IfcMesh *
|
||||
* IfcGeomObject.matrix is a 4x3 matrix that defines the orientation and *
|
||||
* translation of the mesh in relation to the world origin *
|
||||
* *
|
||||
* Init(char* fn) parses the IFC file in fn, returns true on succes. *
|
||||
* *
|
||||
* Get() returns a pointer to the current IfcGeomObject *
|
||||
* *
|
||||
* Next() returns true if there is an entity yet available *
|
||||
* *
|
||||
* Progress() returns an int in [0..100] that indicates the overall progress *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCOBJECTS_H
|
||||
#define IFCOBJECTS_H
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include <gp_Mat.hxx>
|
||||
#include <gp_Mat2d.hxx>
|
||||
#include <gp_GTrsf.hxx>
|
||||
#include <gp_GTrsf2d.hxx>
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <gp_Trsf2d.hxx>
|
||||
|
||||
#include "../ifcparse/IfcParse.h"
|
||||
#include "../ifcgeom/IfcRepresentationShapeItem.h"
|
||||
|
||||
namespace IfcGeomObjects {
|
||||
|
||||
// Enumeration of setting identifiers. These settings define the
|
||||
// behaviour of various aspects of IfcOpenShell.
|
||||
|
||||
// Specifies whether vertices are welded, meaning that the coordinates
|
||||
// vector will only contain unique xyz-triplets. This results in a
|
||||
// manifold mesh which is useful for modelling applications, but might
|
||||
// result in unwanted shading artifacts in rendering applications.
|
||||
const int WELD_VERTICES = 1;
|
||||
// Specifies whether to apply the local placements of building elements
|
||||
// directly to the coordinates of the representation mesh rather than
|
||||
// to represent the local placement in the 4x3 matrix, which will in that
|
||||
// case be the identity matrix.
|
||||
const int USE_WORLD_COORDS = 2;
|
||||
// Internally IfcOpenShell measures everything in meters. This settings
|
||||
// specifies whether to convert IfcGeomObjects back to the units in which
|
||||
// the geometry in the IFC file is specified.
|
||||
const int CONVERT_BACK_UNITS = 3;
|
||||
// Specifies whether to use the Open Cascade BREP format for representation
|
||||
// items rather than to create triangle meshes. This is useful is IfcOpenShell
|
||||
// is used as a library in an application that is also built on Open Cascade.
|
||||
const int USE_BREP_DATA = 4;
|
||||
// Specifies whether to sew IfcConnectedFaceSets (open and closed shells) to
|
||||
// TopoDS_Shells or whether to keep them as a loose collection of faces.
|
||||
const int SEW_SHELLS = 5;
|
||||
// Specifies whether to compose IfcOpeningElements into a single compound
|
||||
// in order to speed up the processing of opening subtractions.
|
||||
const int FASTER_BOOLEANS = 6;
|
||||
// By default singular faces have no explicitly defined orientation, to
|
||||
// force faces to be defined CounterClockWise set this to true.
|
||||
const int FORCE_CCW_FACE_ORIENTATION = 7;
|
||||
// Disables the subtraction of IfcOpeningElement representations from
|
||||
// the related building element representations.
|
||||
const int DISABLE_OPENING_SUBTRACTIONS = 8;
|
||||
// Disables the triangulation of the topological representations. Useful if
|
||||
// the client application understands Open Cascade's native format.
|
||||
const int DISABLE_TRIANGULATION = 9;
|
||||
|
||||
// End of settings enumeration.
|
||||
|
||||
// A nested pair of floats and a material index to be able to store an XYZ coordinate in a map.
|
||||
// TODO: Make this a std::tuple when compilers add support for that.
|
||||
typedef std::pair<int, std::pair<float,std::pair<float,float> > > VertKey;
|
||||
typedef std::map<VertKey,int> VertKeyMap;
|
||||
typedef std::pair<int,int> Edge;
|
||||
|
||||
class Material {
|
||||
private:
|
||||
const IfcGeom::SurfaceStyle* style;
|
||||
public:
|
||||
explicit Material(const IfcGeom::SurfaceStyle* style);
|
||||
// Material(const Material& other);
|
||||
// Material& operator=(const Material& other);
|
||||
bool hasDiffuse() const;
|
||||
bool hasSpecular() const;
|
||||
bool hasTransparency() const;
|
||||
bool hasSpecularity() const;
|
||||
const double* diffuse() const;
|
||||
const double* specular() const;
|
||||
double transparency() const;
|
||||
double specularity() const;
|
||||
const std::string name() const;
|
||||
bool operator==(const Material& other) const;
|
||||
};
|
||||
|
||||
class IfcRepresentationShapeModel {
|
||||
private:
|
||||
unsigned int id;
|
||||
const IfcGeom::IfcRepresentationShapeItems shapes;
|
||||
IfcRepresentationShapeModel(const IfcRepresentationShapeModel& other);
|
||||
IfcRepresentationShapeModel& operator=(const IfcRepresentationShapeModel& other);
|
||||
public:
|
||||
IfcRepresentationShapeModel(unsigned int id, const IfcGeom::IfcRepresentationShapeItems& shapes)
|
||||
: id(id)
|
||||
, shapes(shapes)
|
||||
{}
|
||||
virtual ~IfcRepresentationShapeModel() {}
|
||||
IfcGeom::IfcRepresentationShapeItems::const_iterator begin() const { return shapes.begin(); }
|
||||
IfcGeom::IfcRepresentationShapeItems::const_iterator end() const { return shapes.end(); }
|
||||
const unsigned int& getId() const { return id; }
|
||||
};
|
||||
|
||||
class IfcRepresentationBrepData {
|
||||
private:
|
||||
int _id;
|
||||
std::string _brep_data;
|
||||
public:
|
||||
int id() const;
|
||||
const std::string& brep_data() const;
|
||||
IfcRepresentationBrepData(const IfcRepresentationShapeModel& s);
|
||||
virtual ~IfcRepresentationBrepData() {}
|
||||
private:
|
||||
IfcRepresentationBrepData();
|
||||
IfcRepresentationBrepData(const IfcRepresentationBrepData&);
|
||||
IfcRepresentationBrepData& operator=(const IfcRepresentationBrepData&);
|
||||
};
|
||||
|
||||
class IfcRepresentationTriangulation {
|
||||
private:
|
||||
int _id;
|
||||
std::vector<float> _verts;
|
||||
std::vector<int> _faces;
|
||||
std::vector<int> _edges;
|
||||
std::vector<float> _normals;
|
||||
std::vector<int> _material_ids;
|
||||
std::vector<Material> _materials;
|
||||
VertKeyMap welds;
|
||||
public:
|
||||
int id() const;
|
||||
const std::vector<float>& verts() const;
|
||||
const std::vector<int>& faces() const;
|
||||
const std::vector<int>& edges() const;
|
||||
const std::vector<float>& normals() const;
|
||||
const std::vector<int>& material_ids() const;
|
||||
const std::vector<Material>& materials() const;
|
||||
IfcRepresentationTriangulation(const IfcRepresentationShapeModel& s);
|
||||
virtual ~IfcRepresentationTriangulation() {}
|
||||
private:
|
||||
int addvert(int material_index, const gp_XYZ& p);
|
||||
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);
|
||||
}
|
||||
IfcRepresentationTriangulation();
|
||||
IfcRepresentationTriangulation(const IfcRepresentationTriangulation&);
|
||||
IfcRepresentationTriangulation& operator=(const IfcRepresentationTriangulation&);
|
||||
};
|
||||
|
||||
class IfcObject {
|
||||
private:
|
||||
int _id;
|
||||
int _parent_id;
|
||||
std::string _name;
|
||||
std::string _type;
|
||||
std::string _guid;
|
||||
std::vector<float> _matrix;
|
||||
public:
|
||||
int id() const;
|
||||
int parent_id() const;
|
||||
const std::string& name() const;
|
||||
const std::string& type() const;
|
||||
const std::string& guid() const;
|
||||
const std::vector<float>& matrix() const;
|
||||
IfcObject(int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid, const gp_Trsf& trsf);
|
||||
virtual ~IfcObject() {}
|
||||
};
|
||||
|
||||
class IfcGeomShapeModelObject : public IfcObject {
|
||||
private:
|
||||
IfcRepresentationShapeModel* _mesh;
|
||||
public:
|
||||
const IfcRepresentationShapeModel& mesh() const;
|
||||
IfcGeomShapeModelObject(int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid, const gp_Trsf& trsf, IfcRepresentationShapeModel* mesh);
|
||||
virtual ~IfcGeomShapeModelObject() {
|
||||
delete _mesh;
|
||||
}
|
||||
private:
|
||||
IfcGeomShapeModelObject(const IfcGeomShapeModelObject& other);
|
||||
IfcGeomShapeModelObject& operator=(const IfcGeomShapeModelObject& other);
|
||||
};
|
||||
|
||||
class IfcGeomObject : public IfcObject {
|
||||
private:
|
||||
IfcRepresentationTriangulation* _mesh;
|
||||
public:
|
||||
const IfcRepresentationTriangulation& mesh() const;
|
||||
IfcGeomObject(const IfcGeomShapeModelObject& shape_model);
|
||||
virtual ~IfcGeomObject() {
|
||||
delete _mesh;
|
||||
}
|
||||
private:
|
||||
IfcGeomObject(const IfcGeomObject& other);
|
||||
IfcGeomObject& operator=(const IfcGeomObject& other);
|
||||
};
|
||||
|
||||
class IfcGeomBrepDataObject : public IfcObject {
|
||||
private:
|
||||
IfcRepresentationBrepData* _mesh;
|
||||
public:
|
||||
const IfcRepresentationBrepData& mesh() const;
|
||||
IfcGeomBrepDataObject(const IfcGeomShapeModelObject& shape_model);
|
||||
virtual ~IfcGeomBrepDataObject() {
|
||||
delete _mesh;
|
||||
}
|
||||
private:
|
||||
IfcGeomBrepDataObject(const IfcGeomBrepDataObject& other);
|
||||
IfcGeomBrepDataObject& operator=(const IfcGeomBrepDataObject& other);
|
||||
};
|
||||
|
||||
bool Init(const std::string fn);
|
||||
bool Init(void* data, int len);
|
||||
bool Init(const std::string fn, std::ostream* log1= 0, std::ostream* log2= 0);
|
||||
bool Init(std::istream& f, int len, std::ostream* log1= 0, std::ostream* log2= 0);
|
||||
|
||||
void Settings(int setting, bool value);
|
||||
void InitUnits();
|
||||
void InitPrecision();
|
||||
|
||||
const IfcGeomObject* Get();
|
||||
const IfcObject* GetObject(int id);
|
||||
const IfcGeomBrepDataObject* GetBrepData();
|
||||
const IfcGeomShapeModelObject* GetShapeModel();
|
||||
|
||||
bool Next();
|
||||
int Progress();
|
||||
|
||||
const std::string& GetUnitName();
|
||||
const float GetUnitMagnitude();
|
||||
|
||||
const std::string GetLog();
|
||||
IfcParse::IfcFile* GetFile();
|
||||
|
||||
bool CleanUp();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -19,16 +19,7 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "IfcGeomRenderStyles.h"
|
||||
|
||||
namespace IfcGeom {
|
||||
namespace Cache {
|
||||
std::map<int,SurfaceStyle> Style;
|
||||
void PurgeStyleCache() {
|
||||
Style.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
#include "IfcGeom.h"
|
||||
|
||||
bool process_colour(IfcSchema::IfcColourRgb* colour, std::tr1::array<double, 3>& rgb) {
|
||||
if (colour != 0) {
|
||||
@@ -59,14 +50,14 @@ bool process_colour(IfcSchema::IfcColourOrFactor colour_or_factor, std::tr1::arr
|
||||
}
|
||||
}
|
||||
|
||||
const IfcGeom::SurfaceStyle* IfcGeom::get_style(const IfcSchema::IfcRepresentationItem* item) {
|
||||
const IfcGeom::SurfaceStyle* IfcGeom::Kernel::get_style(const IfcSchema::IfcRepresentationItem* item) {
|
||||
std::pair<IfcSchema::IfcSurfaceStyle*, IfcSchema::IfcSurfaceStyleShading*> shading_styles = get_surface_style<IfcSchema::IfcSurfaceStyleShading>(item);
|
||||
if (shading_styles.second == 0) {
|
||||
return 0;
|
||||
}
|
||||
int surface_style_id = shading_styles.first->entity->id();
|
||||
std::map<int,SurfaceStyle>::const_iterator it = Cache::Style.find(surface_style_id);
|
||||
if (it != Cache::Style.end()) {
|
||||
std::map<int,SurfaceStyle>::const_iterator it = cache.Style.find(surface_style_id);
|
||||
if (it != cache.Style.end()) {
|
||||
return &(it->second);
|
||||
}
|
||||
SurfaceStyle surface_style;
|
||||
@@ -113,7 +104,7 @@ const IfcGeom::SurfaceStyle* IfcGeom::get_style(const IfcSchema::IfcRepresentati
|
||||
surface_style.Transparency().reset(d);
|
||||
}
|
||||
}
|
||||
return &(Cache::Style[surface_style_id] = surface_style);
|
||||
return &(cache.Style[surface_style_id] = surface_style);
|
||||
}
|
||||
|
||||
static std::map<std::string, IfcGeom::SurfaceStyle> default_materials;
|
||||
@@ -161,9 +152,11 @@ void InitDefaultMaterials() {
|
||||
const IfcGeom::SurfaceStyle* IfcGeom::get_default_style(const std::string& s) {
|
||||
if (!default_materials_initialized) InitDefaultMaterials();
|
||||
std::map<std::string, IfcGeom::SurfaceStyle>::const_iterator it = default_materials.find(s);
|
||||
if (it == default_materials.end()) return &default_material;
|
||||
else {
|
||||
const IfcGeom::SurfaceStyle& surface_style = it->second;
|
||||
return &surface_style;
|
||||
if (it == default_materials.end()) {
|
||||
default_materials.insert(std::make_pair(s, IfcGeom::SurfaceStyle(s)));
|
||||
default_materials[s].Diffuse().reset(*default_material.Diffuse());
|
||||
it = default_materials.find(s);
|
||||
}
|
||||
const IfcGeom::SurfaceStyle& surface_style = it->second;
|
||||
return &surface_style;
|
||||
}
|
||||
|
||||
@@ -56,10 +56,20 @@ namespace IfcGeom {
|
||||
boost::optional<double> transparency;
|
||||
boost::optional<double> specularity;
|
||||
public:
|
||||
SurfaceStyle() {}
|
||||
SurfaceStyle(int id) : id(id) {}
|
||||
SurfaceStyle() {
|
||||
this->name = "IfcSurfaceStyleShading";
|
||||
}
|
||||
SurfaceStyle(int id) : id(id) {
|
||||
std::stringstream sstr;
|
||||
sstr << "IfcSurfaceStyleShading_" << id;
|
||||
this->name = sstr.str();
|
||||
}
|
||||
SurfaceStyle(const std::string& name) : name(name) {}
|
||||
SurfaceStyle(int id, const std::string& name) : id(id), name(name) {}
|
||||
SurfaceStyle(int id, const std::string& name) : id(id) {
|
||||
std::stringstream sstr;
|
||||
sstr << id << "_" << name;
|
||||
this->name = sstr.str();
|
||||
}
|
||||
|
||||
// Not used at this point. In fact, equality testing in the current
|
||||
// architecture can just as easily be accomplished by comparing the
|
||||
@@ -75,21 +85,7 @@ namespace IfcGeom {
|
||||
}
|
||||
}
|
||||
|
||||
const std::string Name() const {
|
||||
if (name && id) {
|
||||
std::stringstream sstr;
|
||||
sstr << (*id) << "_" << (*name);
|
||||
return sstr.str();
|
||||
} else if (name) {
|
||||
return *name;
|
||||
} else if (id) {
|
||||
std::stringstream sstr;
|
||||
sstr << "IfcSurfaceStyleShading_" << (*id);
|
||||
return sstr.str();
|
||||
} else {
|
||||
return "IfcSurfaceStyleShading";
|
||||
}
|
||||
}
|
||||
const std::string& Name() const { return *name; }
|
||||
|
||||
const boost::optional<ColorComponent>& Diffuse() const { return diffuse; }
|
||||
const boost::optional<ColorComponent>& Specular() const { return specular; }
|
||||
@@ -101,73 +97,7 @@ namespace IfcGeom {
|
||||
boost::optional<double>& Specularity() { return specularity; }
|
||||
};
|
||||
|
||||
template <typename T> std::pair<IfcSchema::IfcSurfaceStyle*, T*> get_surface_style(const IfcSchema::IfcRepresentationItem* representation_item) {
|
||||
IfcSchema::IfcStyledItem::list::ptr styled_items = representation_item->StyledByItem();
|
||||
|
||||
// Preferably this item-specific logic should not be here, but it easier than somehow associating this information
|
||||
// with a bare TopoDS_Shape. Perhaps the real solution is to 'upgrade' IfcBooleanResult from a SHAPE to SHAPES in
|
||||
// IfcRegister.h so that surface style information can be tied to actual implementation of the conversion function.
|
||||
if (styled_items->Size() == 0 && representation_item->is(IfcSchema::Type::IfcBooleanResult)) {
|
||||
IfcSchema::IfcBooleanResult* boolean_result = (IfcSchema::IfcBooleanResult*) representation_item;
|
||||
while (true) {
|
||||
IfcSchema::IfcRepresentationItem* boolean_op = (IfcSchema::IfcRepresentationItem*) boolean_result->FirstOperand();
|
||||
IfcSchema::IfcStyledItem::list::ptr op_styled_items = boolean_op->StyledByItem();
|
||||
if (op_styled_items->Size() > 0) {
|
||||
styled_items = op_styled_items;
|
||||
break;
|
||||
}
|
||||
if (boolean_op->is(IfcSchema::Type::IfcBooleanResult)) {
|
||||
boolean_result = (IfcSchema::IfcBooleanResult*) boolean_op;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (IfcSchema::IfcStyledItem::list::it jt = styled_items->begin(); jt != styled_items->end(); ++jt) {
|
||||
#ifdef USE_IFC4
|
||||
IfcUtil::IfcAbstractSelect::list::ptr style_assignments = (*jt)->Styles();
|
||||
for (IfcUtil::IfcAbstractSelect::list::it kt = style_assignments->begin(); kt != style_assignments->end(); ++kt) {
|
||||
if (!(*kt)->is(IfcSchema::Type::IfcPresentationStyleAssignment)) {
|
||||
continue;
|
||||
}
|
||||
IfcSchema::IfcPresentationStyleAssignment* style_assignment = (IfcSchema::IfcPresentationStyleAssignment*) *kt;
|
||||
#else
|
||||
IfcSchema::IfcPresentationStyleAssignment::list::ptr style_assignments = (*jt)->Styles();
|
||||
for (IfcSchema::IfcPresentationStyleAssignment::list::it kt = style_assignments->begin(); kt != style_assignments->end(); ++kt) {
|
||||
IfcSchema::IfcPresentationStyleAssignment* style_assignment = *kt;
|
||||
#endif
|
||||
IfcUtil::IfcAbstractSelect::list::ptr styles = style_assignment->Styles();
|
||||
for (IfcUtil::IfcAbstractSelect::list::it lt = styles->begin(); lt != styles->end(); ++lt) {
|
||||
IfcUtil::IfcAbstractSelect* style = *lt;
|
||||
if (style->is(IfcSchema::Type::IfcSurfaceStyle)) {
|
||||
IfcSchema::IfcSurfaceStyle* surface_style = (IfcSchema::IfcSurfaceStyle*) style;
|
||||
if (surface_style->Side() != IfcSchema::IfcSurfaceSide::IfcSurfaceSide_NEGATIVE) {
|
||||
IfcUtil::IfcAbstractSelect::list::ptr styles_elements = surface_style->Styles();
|
||||
for (IfcUtil::IfcAbstractSelect::list::it mt = styles_elements->begin(); mt != styles_elements->end(); ++mt) {
|
||||
if ((*mt)->is(T::Class())) {
|
||||
return std::make_pair(surface_style, (T*) *mt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StyledByItem is a SET [0:1] OF IfcStyledItem, so we
|
||||
// break after encountering the first IfcStyledItem
|
||||
break;
|
||||
}
|
||||
|
||||
return std::make_pair<IfcSchema::IfcSurfaceStyle*, T*>(0,0);
|
||||
}
|
||||
|
||||
const SurfaceStyle* get_style(const IfcSchema::IfcRepresentationItem* representation_item);
|
||||
const SurfaceStyle* get_default_style(const std::string& ifc_type);
|
||||
|
||||
namespace Cache {
|
||||
void PurgeStyleCache();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <BRepBuilderAPI_GTransform.hxx>
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
|
||||
#include "IfcGeomRepresentation.h"
|
||||
|
||||
IfcGeom::Representation::Serialization::Serialization(const BRep& brep)
|
||||
: Representation(brep.settings())
|
||||
, _id(brep.getId())
|
||||
{
|
||||
TopoDS_Compound compound;
|
||||
BRep_Builder builder;
|
||||
builder.MakeCompound(compound);
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it = brep.begin(); it != brep.end(); ++ it ) {
|
||||
const TopoDS_Shape& s = it->Shape();
|
||||
gp_GTrsf trsf = it->Placement();
|
||||
if (convert_back_units) {
|
||||
gp_Trsf scale;
|
||||
scale.SetScaleFactor(1.0 / settings().unit_magnitude());
|
||||
trsf.PreMultiply(scale);
|
||||
}
|
||||
bool trsf_valid = false;
|
||||
gp_Trsf _trsf;
|
||||
try {
|
||||
_trsf = trsf.Trsf();
|
||||
trsf_valid = true;
|
||||
} catch (...) {}
|
||||
const TopoDS_Shape moved_shape = trsf_valid ? s.Moved(_trsf) :
|
||||
BRepBuilderAPI_GTransform(s,trsf,true).Shape();
|
||||
builder.Add(compound,moved_shape);
|
||||
}
|
||||
std::stringstream sstream;
|
||||
BRepTools::Write(compound,sstream);
|
||||
_brep_data = sstream.str();
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 IFCGEOMREPRESENTATION_H
|
||||
#define IFCGEOMREPRESENTATION_H
|
||||
|
||||
#include <BRepMesh.hxx>
|
||||
#include <BRepGProp_Face.hxx>
|
||||
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
|
||||
#include <TopExp_Explorer.hxx>
|
||||
|
||||
#include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||
#include "../ifcgeom/IfcGeomMaterial.h"
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
namespace Representation {
|
||||
|
||||
class Representation {
|
||||
protected:
|
||||
const ElementSettings _settings;
|
||||
public:
|
||||
explicit Representation(const ElementSettings& settings) : _settings(settings) {}
|
||||
const ElementSettings& settings() const { return _settings; }
|
||||
};
|
||||
|
||||
class BRep : public Representation {
|
||||
private:
|
||||
unsigned int id;
|
||||
const IfcGeom::IfcRepresentationShapeItems shapes;
|
||||
BRep(const BRep& other);
|
||||
BRep& operator=(const BRep& other);
|
||||
public:
|
||||
BRep(const ElementSettings& settings, unsigned int id, const IfcGeom::IfcRepresentationShapeItems& 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 unsigned int& getId() const { return id; }
|
||||
};
|
||||
|
||||
class Serialization : public Representation {
|
||||
private:
|
||||
int _id;
|
||||
bool convert_back_units;
|
||||
std::string _brep_data;
|
||||
public:
|
||||
int id() const { return _id; }
|
||||
const std::string& brep_data() const { return _brep_data; }
|
||||
Serialization(const BRep& brep);
|
||||
virtual ~Serialization() {}
|
||||
private:
|
||||
Serialization();
|
||||
Serialization(const Serialization&);
|
||||
Serialization& operator=(const Serialization&);
|
||||
};
|
||||
|
||||
template <typename P>
|
||||
class Triangulation : public Representation {
|
||||
private:
|
||||
// A nested pair of floats and a material index to be able to store an XYZ coordinate in a map.
|
||||
// TODO: Make this a std::tuple when compilers add support for that.
|
||||
typedef typename std::pair<P, std::pair<P, P> > Coordinate;
|
||||
typedef typename std::pair<int, Coordinate> VertexKey;
|
||||
typedef std::map<VertexKey, int> VertexKeyMap;
|
||||
typedef std::pair<int, int> Edge;
|
||||
|
||||
int _id;
|
||||
std::vector<P> _verts;
|
||||
std::vector<int> _faces;
|
||||
std::vector<int> _edges;
|
||||
std::vector<P> _normals;
|
||||
std::vector<int> _material_ids;
|
||||
std::vector<Material> _materials;
|
||||
VertexKeyMap welds;
|
||||
|
||||
public:
|
||||
int id() const { return _id; }
|
||||
const std::vector<P>& verts() const { return _verts; }
|
||||
const std::vector<int>& faces() const { return _faces; }
|
||||
const std::vector<int>& edges() const { return _edges; }
|
||||
const std::vector<P>& normals() const { return _normals; }
|
||||
const std::vector<int>& material_ids() const { return _material_ids; }
|
||||
const std::vector<Material>& materials() const { return _materials; }
|
||||
Triangulation(const BRep& shape_model)
|
||||
: Representation(shape_model.settings())
|
||||
, _id(shape_model.getId())
|
||||
{
|
||||
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it = shape_model.begin(); it != shape_model.end(); ++ it ) {
|
||||
|
||||
int surface_style_id = -1;
|
||||
if (it->hasStyle()) {
|
||||
Material adapter(&it->Style());
|
||||
std::vector<Material>::const_iterator jt = std::find(_materials.begin(), _materials.end(), adapter);
|
||||
if (jt == _materials.end()) {
|
||||
surface_style_id = _materials.size();
|
||||
_materials.push_back(adapter);
|
||||
} else {
|
||||
surface_style_id = jt - _materials.begin();
|
||||
}
|
||||
}
|
||||
|
||||
if (settings().apply_default_materials() && surface_style_id == -1) {
|
||||
Material material(IfcGeom::get_default_style(settings().element_type()));
|
||||
std::vector<Material>::const_iterator it = std::find(_materials.begin(), _materials.end(), material);
|
||||
if (it == _materials.end()) {
|
||||
surface_style_id = _materials.size();
|
||||
_materials.push_back(material);
|
||||
} else {
|
||||
surface_style_id = it - _materials.begin();
|
||||
}
|
||||
}
|
||||
|
||||
const TopoDS_Shape& s = it->Shape();
|
||||
const gp_GTrsf& trsf = it->Placement();
|
||||
|
||||
// Triangulate the shape
|
||||
try {
|
||||
// BRepTools::Clean(s);
|
||||
BRepMesh::Mesh(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");
|
||||
continue;
|
||||
}
|
||||
TopExp_Explorer exp;
|
||||
|
||||
// Iterates over the faces of the shape
|
||||
for ( exp.Init(s,TopAbs_FACE); exp.More(); exp.Next() ) {
|
||||
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
|
||||
const bool calculate_normals = !settings().weld_vertices();
|
||||
|
||||
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() > ALMOST_ZERO) {
|
||||
normal = gp_Dir(normal_direction.XYZ() * rotation_matrix);
|
||||
}
|
||||
_normals.push_back((float)normal.X());
|
||||
_normals.push_back((float)normal.Y());
|
||||
_normals.push_back((float)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(n1,n2,edgecount,edges_temp);
|
||||
addEdge(n2,n3,edgecount,edges_temp);
|
||||
addEdge(n3,n1,edgecount,edges_temp);
|
||||
}
|
||||
for ( std::vector<std::pair<int,int> >::const_iterator it = edges_temp.begin(); it != edges_temp.end(); ++it ) {
|
||||
_edges.push_back(edgecount[*it]==1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual ~Triangulation() {}
|
||||
private:
|
||||
// Welds vertices that belong to different faces
|
||||
int addVertex(int material_index, const gp_XYZ& p) {
|
||||
const P X = static_cast<P>(settings().convert_back_units() ? (p.X() / settings().unit_magnitude()) : p.X());
|
||||
const P Y = static_cast<P>(settings().convert_back_units() ? (p.Y() / settings().unit_magnitude()) : p.Y());
|
||||
const P Z = static_cast<P>(settings().convert_back_units() ? (p.Z() / settings().unit_magnitude()) : p.Z());
|
||||
int i = (int) _verts.size() / 3;
|
||||
if (settings().weld_vertices()) {
|
||||
const VertexKey key = std::make_pair(material_index, std::make_pair(X, std::make_pair(Y, Z)));
|
||||
VertexKeyMap::const_iterator it = welds.find(key);
|
||||
if ( it != welds.end() ) return it->second;
|
||||
i = (int) welds.size();
|
||||
welds[key] = i;
|
||||
}
|
||||
_verts.push_back(X);
|
||||
_verts.push_back(Y);
|
||||
_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);
|
||||
}
|
||||
Triangulation();
|
||||
Triangulation(const Triangulation&);
|
||||
Triangulation& operator=(const Triangulation&);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+101
-99
@@ -95,13 +95,13 @@
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcExtrudedAreaSolid* l, TopoDS_Shape& shape) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcExtrudedAreaSolid* l, TopoDS_Shape& shape) {
|
||||
TopoDS_Shape face;
|
||||
if ( ! IfcGeom::convert_face(l->SweptArea(),face) ) return false;
|
||||
if ( !convert_face(l->SweptArea(),face) ) return false;
|
||||
|
||||
const double height = l->Depth() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double height = l->Depth() * getValue(GV_LENGTH_UNIT);
|
||||
gp_Trsf trsf;
|
||||
IfcGeom::convert(l->Position(),trsf);
|
||||
IfcGeom::Kernel::convert(l->Position(),trsf);
|
||||
|
||||
gp_Dir dir;
|
||||
convert(l->ExtrudedDirection(),dir);
|
||||
@@ -138,17 +138,17 @@ bool IfcGeom::convert(const IfcSchema::IfcExtrudedAreaSolid* l, TopoDS_Shape& sh
|
||||
return ! shape.IsNull();
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcSurfaceOfLinearExtrusion* l, TopoDS_Shape& shape) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcSurfaceOfLinearExtrusion* l, TopoDS_Shape& shape) {
|
||||
TopoDS_Wire wire;
|
||||
if ( !IfcGeom::convert_wire(l->SweptCurve(), wire) ) {
|
||||
if ( !convert_wire(l->SweptCurve(), wire) ) {
|
||||
TopoDS_Face face;
|
||||
if ( !IfcGeom::convert_face(l->SweptCurve(),face) ) return false;
|
||||
if ( !convert_face(l->SweptCurve(),face) ) return false;
|
||||
TopExp_Explorer exp(face, TopAbs_WIRE);
|
||||
wire = TopoDS::Wire(exp.Current());
|
||||
}
|
||||
const double height = l->Depth() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double height = l->Depth() * getValue(GV_LENGTH_UNIT);
|
||||
gp_Trsf trsf;
|
||||
IfcGeom::convert(l->Position(),trsf);
|
||||
IfcGeom::Kernel::convert(l->Position(),trsf);
|
||||
|
||||
gp_Dir dir;
|
||||
convert(l->ExtrudedDirection(),dir);
|
||||
@@ -158,20 +158,20 @@ bool IfcGeom::convert(const IfcSchema::IfcSurfaceOfLinearExtrusion* l, TopoDS_Sh
|
||||
return !shape.IsNull();
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcSurfaceOfRevolution* l, TopoDS_Shape& shape) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcSurfaceOfRevolution* l, TopoDS_Shape& shape) {
|
||||
TopoDS_Wire wire;
|
||||
if ( !IfcGeom::convert_wire(l->SweptCurve(), wire) ) {
|
||||
if ( !convert_wire(l->SweptCurve(), wire) ) {
|
||||
TopoDS_Face face;
|
||||
if ( !IfcGeom::convert_face(l->SweptCurve(),face) ) return false;
|
||||
if ( !convert_face(l->SweptCurve(),face) ) return false;
|
||||
TopExp_Explorer exp(face, TopAbs_WIRE);
|
||||
wire = TopoDS::Wire(exp.Current());
|
||||
}
|
||||
|
||||
gp_Ax1 ax1;
|
||||
IfcGeom::convert(l->AxisPosition(), ax1);
|
||||
IfcGeom::Kernel::convert(l->AxisPosition(), ax1);
|
||||
|
||||
gp_Trsf trsf;
|
||||
IfcGeom::convert(l->Position(),trsf);
|
||||
IfcGeom::Kernel::convert(l->Position(),trsf);
|
||||
|
||||
shape = BRepPrimAPI_MakeRevol(wire, ax1);
|
||||
|
||||
@@ -179,17 +179,17 @@ bool IfcGeom::convert(const IfcSchema::IfcSurfaceOfRevolution* l, TopoDS_Shape&
|
||||
return !shape.IsNull();
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcRevolvedAreaSolid* l, TopoDS_Shape& shape) {
|
||||
const double ang = l->Angle() * IfcGeom::GetValue(GV_PLANEANGLE_UNIT);
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcRevolvedAreaSolid* l, TopoDS_Shape& shape) {
|
||||
const double ang = l->Angle() * getValue(GV_PLANEANGLE_UNIT);
|
||||
|
||||
TopoDS_Face face;
|
||||
if ( ! IfcGeom::convert_face(l->SweptArea(),face) ) return false;
|
||||
if ( ! convert_face(l->SweptArea(),face) ) return false;
|
||||
|
||||
gp_Ax1 ax1;
|
||||
IfcGeom::convert(l->Axis(), ax1);
|
||||
IfcGeom::Kernel::convert(l->Axis(), ax1);
|
||||
|
||||
gp_Trsf trsf;
|
||||
IfcGeom::convert(l->Position(),trsf);
|
||||
IfcGeom::Kernel::convert(l->Position(),trsf);
|
||||
|
||||
if (ang >= M_PI * 2. - ALMOST_ZERO) {
|
||||
shape = BRepPrimAPI_MakeRevol(face, ax1);
|
||||
@@ -201,10 +201,10 @@ bool IfcGeom::convert(const IfcSchema::IfcRevolvedAreaSolid* l, TopoDS_Shape& sh
|
||||
return !shape.IsNull();
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcFacetedBrep* l, IfcRepresentationShapeItems& shape) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcFacetedBrep* l, IfcRepresentationShapeItems& shape) {
|
||||
TopoDS_Shape s;
|
||||
const SurfaceStyle* collective_style = get_style(l);
|
||||
if (IfcGeom::convert_shape(l->Outer(),s) ) {
|
||||
if (convert_shape(l->Outer(),s) ) {
|
||||
const SurfaceStyle* indiv_style = get_style(l->Outer());
|
||||
shape.push_back(IfcRepresentationShapeItem(s, indiv_style ? indiv_style : collective_style));
|
||||
return true;
|
||||
@@ -212,37 +212,37 @@ bool IfcGeom::convert(const IfcSchema::IfcFacetedBrep* l, IfcRepresentationShape
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcFaceBasedSurfaceModel* l, IfcRepresentationShapeItems& shapes) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcFaceBasedSurfaceModel* l, IfcRepresentationShapeItems& shapes) {
|
||||
IfcSchema::IfcConnectedFaceSet::list::ptr facesets = l->FbsmFaces();
|
||||
const SurfaceStyle* collective_style = get_style(l);
|
||||
for( IfcSchema::IfcConnectedFaceSet::list::it it = facesets->begin(); it != facesets->end(); ++ it ) {
|
||||
TopoDS_Shape s;
|
||||
const SurfaceStyle* shell_style = get_style(*it);
|
||||
if (IfcGeom::convert_shape(*it,s)) {
|
||||
if (convert_shape(*it,s)) {
|
||||
shapes.push_back(IfcRepresentationShapeItem(s, shell_style ? shell_style : collective_style));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcHalfSpaceSolid* l, TopoDS_Shape& shape) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcHalfSpaceSolid* l, TopoDS_Shape& shape) {
|
||||
IfcSchema::IfcSurface* surface = l->BaseSurface();
|
||||
if ( ! surface->is(IfcSchema::Type::IfcPlane) ) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Unsupported BaseSurface:", surface->entity);
|
||||
return false;
|
||||
}
|
||||
gp_Pln pln;
|
||||
IfcGeom::convert((IfcSchema::IfcPlane*)surface,pln);
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcPlane*)surface,pln);
|
||||
const gp_Pnt pnt = pln.Location().Translated( l->AgreementFlag() ? -pln.Axis().Direction() : pln.Axis().Direction());
|
||||
shape = BRepPrimAPI_MakeHalfSpace(BRepBuilderAPI_MakeFace(pln),pnt).Solid();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcPolygonalBoundedHalfSpace* l, TopoDS_Shape& shape) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcPolygonalBoundedHalfSpace* l, TopoDS_Shape& shape) {
|
||||
TopoDS_Shape halfspace;
|
||||
if ( ! IfcGeom::convert((IfcSchema::IfcHalfSpaceSolid*)l,halfspace) ) return false;
|
||||
if ( ! IfcGeom::Kernel::convert((IfcSchema::IfcHalfSpaceSolid*)l,halfspace) ) return false;
|
||||
TopoDS_Wire wire;
|
||||
if ( ! IfcGeom::convert_wire(l->PolygonalBoundary(),wire) || ! wire.Closed() ) return false;
|
||||
if ( ! convert_wire(l->PolygonalBoundary(),wire) || ! wire.Closed() ) return false;
|
||||
gp_Trsf trsf;
|
||||
convert(l->Position(),trsf);
|
||||
TopoDS_Shape prism = BRepPrimAPI_MakePrism(BRepBuilderAPI_MakeFace(wire),gp_Vec(0,0,200));
|
||||
@@ -252,7 +252,7 @@ bool IfcGeom::convert(const IfcSchema::IfcPolygonalBoundedHalfSpace* l, TopoDS_S
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcShellBasedSurfaceModel* l, IfcRepresentationShapeItems& shapes) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcShellBasedSurfaceModel* l, IfcRepresentationShapeItems& shapes) {
|
||||
IfcUtil::IfcAbstractSelect::list::ptr shells = l->SbsmBoundary();
|
||||
const SurfaceStyle* collective_style = get_style(l);
|
||||
for( IfcUtil::IfcAbstractSelect::list::it it = shells->begin(); it != shells->end(); ++ it ) {
|
||||
@@ -261,14 +261,14 @@ bool IfcGeom::convert(const IfcSchema::IfcShellBasedSurfaceModel* l, IfcRepresen
|
||||
if ((*it)->is(IfcSchema::Type::IfcRepresentationItem)) {
|
||||
shell_style = get_style((IfcSchema::IfcRepresentationItem*)*it);
|
||||
}
|
||||
if (IfcGeom::convert_shape(*it,s)) {
|
||||
if (convert_shape(*it,s)) {
|
||||
shapes.push_back(IfcRepresentationShapeItem(s, shell_style ? shell_style : collective_style));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape& shape) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape& shape) {
|
||||
TopoDS_Shape s1, s2;
|
||||
IfcRepresentationShapeItems items1, items2;
|
||||
TopoDS_Wire boundary_wire;
|
||||
@@ -281,7 +281,7 @@ bool IfcGeom::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape& shape)
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if ( ! IfcGeom::convert_shape(operand1,s1) ) {
|
||||
if ( ! convert_shape(operand1,s1) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -294,7 +294,7 @@ bool IfcGeom::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape& shape)
|
||||
if ( is_shape_collection(operand2) ) {
|
||||
shape2_processed = convert_shapes(operand2, items2) && flatten_shape_list(items2, s2, true);
|
||||
} else {
|
||||
shape2_processed = IfcGeom::convert_shape(operand2,s2);
|
||||
shape2_processed = convert_shape(operand2,s2);
|
||||
}
|
||||
|
||||
if (!shape2_processed) {
|
||||
@@ -381,23 +381,23 @@ bool IfcGeom::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape& shape)
|
||||
}
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcConnectedFaceSet* l, TopoDS_Shape& shape) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcConnectedFaceSet* l, TopoDS_Shape& shape) {
|
||||
IfcSchema::IfcFace::list::ptr faces = l->CfsFaces();
|
||||
bool facesAdded = false;
|
||||
const unsigned int num_faces = faces->Size();
|
||||
bool valid_shell = false;
|
||||
if ( num_faces < GetValue(GV_MAX_FACES_TO_SEW) ) {
|
||||
if ( num_faces < getValue(GV_MAX_FACES_TO_SEW) ) {
|
||||
BRepOffsetAPI_Sewing builder;
|
||||
builder.SetTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||
builder.SetMaxTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||
builder.SetMinTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||
builder.SetTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||
builder.SetMaxTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||
builder.SetMinTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||
for( IfcSchema::IfcFace::list::it it = faces->begin(); it != faces->end(); ++ it ) {
|
||||
TopoDS_Face face;
|
||||
bool converted_face = false;
|
||||
try {
|
||||
converted_face = IfcGeom::convert_face(*it,face);
|
||||
converted_face = convert_face(*it,face);
|
||||
} catch (...) {}
|
||||
if ( converted_face && face_area(face) > GetValue(GV_MINIMAL_FACE_AREA) ) {
|
||||
if ( converted_face && face_area(face) > getValue(GV_MINIMAL_FACE_AREA) ) {
|
||||
builder.Add(face);
|
||||
facesAdded = true;
|
||||
} else {
|
||||
@@ -413,7 +413,7 @@ bool IfcGeom::convert(const IfcSchema::IfcConnectedFaceSet* l, TopoDS_Shape& sha
|
||||
if (valid_shell) {
|
||||
try {
|
||||
ShapeFix_Solid solid;
|
||||
solid.LimitTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||
solid.LimitTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||
TopoDS_Solid solid_shape = solid.SolidFromShell(TopoDS::Shell(shape));
|
||||
if (!solid_shape.IsNull()) {
|
||||
try {
|
||||
@@ -434,9 +434,9 @@ bool IfcGeom::convert(const IfcSchema::IfcConnectedFaceSet* l, TopoDS_Shape& sha
|
||||
TopoDS_Face face;
|
||||
bool converted_face = false;
|
||||
try {
|
||||
converted_face = IfcGeom::convert_face(*it,face);
|
||||
converted_face = convert_face(*it,face);
|
||||
} catch (...) {}
|
||||
if ( converted_face && face_area(face) > GetValue(GV_MINIMAL_FACE_AREA) ) {
|
||||
if ( converted_face && face_area(face) > getValue(GV_MINIMAL_FACE_AREA) ) {
|
||||
builder.Add(compound,face);
|
||||
facesAdded = true;
|
||||
} else {
|
||||
@@ -449,53 +449,53 @@ bool IfcGeom::convert(const IfcSchema::IfcConnectedFaceSet* l, TopoDS_Shape& sha
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcMappedItem* l, IfcRepresentationShapeItems& shapes) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcMappedItem* l, IfcRepresentationShapeItems& shapes) {
|
||||
gp_GTrsf gtrsf;
|
||||
IfcSchema::IfcCartesianTransformationOperator* transform = l->MappingTarget();
|
||||
if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator3DnonUniform) ) {
|
||||
IfcGeom::convert((IfcSchema::IfcCartesianTransformationOperator3DnonUniform*)transform,gtrsf);
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcCartesianTransformationOperator3DnonUniform*)transform,gtrsf);
|
||||
} else if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator2DnonUniform) ) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Unsupported MappingTarget:", transform->entity);
|
||||
return false;
|
||||
} else if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator3D) ) {
|
||||
gp_Trsf trsf;
|
||||
IfcGeom::convert((IfcSchema::IfcCartesianTransformationOperator3D*)transform,trsf);
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcCartesianTransformationOperator3D*)transform,trsf);
|
||||
gtrsf = trsf;
|
||||
} else if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator2D) ) {
|
||||
gp_Trsf2d trsf_2d;
|
||||
IfcGeom::convert((IfcSchema::IfcCartesianTransformationOperator2D*)transform,trsf_2d);
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcCartesianTransformationOperator2D*)transform,trsf_2d);
|
||||
gtrsf = (gp_Trsf) trsf_2d;
|
||||
}
|
||||
IfcSchema::IfcRepresentationMap* map = l->MappingSource();
|
||||
IfcSchema::IfcAxis2Placement placement = map->MappingOrigin();
|
||||
gp_Trsf trsf;
|
||||
if (placement->is(IfcSchema::Type::IfcAxis2Placement3D)) {
|
||||
IfcGeom::convert((IfcSchema::IfcAxis2Placement3D*)placement,trsf);
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcAxis2Placement3D*)placement,trsf);
|
||||
} else {
|
||||
gp_Trsf2d trsf_2d;
|
||||
IfcGeom::convert((IfcSchema::IfcAxis2Placement2D*)placement,trsf_2d);
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcAxis2Placement2D*)placement,trsf_2d);
|
||||
trsf = trsf_2d;
|
||||
}
|
||||
gtrsf.Multiply(trsf);
|
||||
const unsigned int previous_size = (const unsigned int) shapes.size();
|
||||
bool b = IfcGeom::convert_shapes(map->MappedRepresentation(),shapes);
|
||||
bool b = convert_shapes(map->MappedRepresentation(),shapes);
|
||||
for ( unsigned int i = previous_size; i < shapes.size(); ++ i ) {
|
||||
shapes[i].append(gtrsf);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcShapeRepresentation* l, IfcRepresentationShapeItems& shapes) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcShapeRepresentation* l, IfcRepresentationShapeItems& shapes) {
|
||||
IfcSchema::IfcRepresentationItem::list::ptr items = l->Items();
|
||||
bool part_succes = false;
|
||||
if ( items->Size() ) {
|
||||
for ( IfcSchema::IfcRepresentationItem::list::it it = items->begin(); it != items->end(); ++ it ) {
|
||||
IfcSchema::IfcRepresentationItem* representation_item = *it;
|
||||
if ( IfcGeom::is_shape_collection(representation_item) ) {
|
||||
part_succes |= IfcGeom::convert_shapes(*it, shapes);
|
||||
if ( is_shape_collection(representation_item) ) {
|
||||
part_succes |= convert_shapes(*it, shapes);
|
||||
} else {
|
||||
TopoDS_Shape s;
|
||||
if (IfcGeom::convert_shape(representation_item,s)) {
|
||||
if (convert_shape(representation_item,s)) {
|
||||
shapes.push_back(IfcRepresentationShapeItem(s, get_style(representation_item)));
|
||||
part_succes |= true;
|
||||
}
|
||||
@@ -505,40 +505,42 @@ bool IfcGeom::convert(const IfcSchema::IfcShapeRepresentation* l, IfcRepresentat
|
||||
return part_succes;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcGeometricSet* l, IfcRepresentationShapeItems& shapes) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcGeometricSet* l, IfcRepresentationShapeItems& shapes) {
|
||||
IfcUtil::IfcAbstractSelect::list::ptr elements = l->Elements();
|
||||
if ( !elements->Size() ) return false;
|
||||
bool part_succes = false;
|
||||
const IfcGeom::SurfaceStyle* parent_style = get_style(l);
|
||||
for ( IfcUtil::IfcAbstractSelect::list::it it = elements->begin(); it != elements->end(); ++ it ) {
|
||||
IfcSchema::IfcGeometricSetSelect element = *it;
|
||||
if (element->is(IfcSchema::Type::IfcSurface)) {
|
||||
IfcSchema::IfcSurface* surface = (IfcSchema::IfcSurface*) element;
|
||||
TopoDS_Shape s;
|
||||
if (IfcGeom::convert_shape(surface, s)) {
|
||||
if (convert_shape(surface, s)) {
|
||||
part_succes = true;
|
||||
const IfcGeom::SurfaceStyle* style = get_style(surface);
|
||||
shapes.push_back(IfcRepresentationShapeItem(s, style ? style : parent_style));
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return part_succes;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcBlock* l, TopoDS_Shape& shape) {
|
||||
const double dx = l->XLength() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double dy = l->YLength() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double dz = l->ZLength() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcBlock* l, TopoDS_Shape& shape) {
|
||||
const double dx = l->XLength() * getValue(GV_LENGTH_UNIT);
|
||||
const double dy = l->YLength() * getValue(GV_LENGTH_UNIT);
|
||||
const double dz = l->ZLength() * getValue(GV_LENGTH_UNIT);
|
||||
|
||||
BRepPrimAPI_MakeBox builder(dx, dy, dz);
|
||||
gp_Trsf trsf;
|
||||
IfcGeom::convert(l->Position(),trsf);
|
||||
IfcGeom::Kernel::convert(l->Position(),trsf);
|
||||
shape = builder.Solid().Moved(trsf);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcRectangularPyramid* l, TopoDS_Shape& shape) {
|
||||
const double dx = l->XLength() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double dy = l->YLength() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double dz = l->Height() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcRectangularPyramid* l, TopoDS_Shape& shape) {
|
||||
const double dx = l->XLength() * getValue(GV_LENGTH_UNIT);
|
||||
const double dy = l->YLength() * getValue(GV_LENGTH_UNIT);
|
||||
const double dz = l->Height() * getValue(GV_LENGTH_UNIT);
|
||||
|
||||
BRepPrimAPI_MakeWedge builder(dx, dz, dy, dx / 2., dy / 2., dx / 2., dy / 2.);
|
||||
|
||||
@@ -547,56 +549,56 @@ bool IfcGeom::convert(const IfcSchema::IfcRectangularPyramid* l, TopoDS_Shape& s
|
||||
0, 0, 1, 0,
|
||||
0, 1, 0, 0, Precision::Confusion(), Precision::Confusion());
|
||||
|
||||
IfcGeom::convert(l->Position(), trsf1);
|
||||
IfcGeom::Kernel::convert(l->Position(), trsf1);
|
||||
shape = BRepBuilderAPI_Transform(builder.Solid(), trsf1 * trsf2);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcRightCircularCylinder* l, TopoDS_Shape& shape) {
|
||||
const double r = l->Radius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double h = l->Height() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcRightCircularCylinder* l, TopoDS_Shape& shape) {
|
||||
const double r = l->Radius() * getValue(GV_LENGTH_UNIT);
|
||||
const double h = l->Height() * getValue(GV_LENGTH_UNIT);
|
||||
|
||||
BRepPrimAPI_MakeCylinder builder(r, h);
|
||||
gp_Trsf trsf;
|
||||
IfcGeom::convert(l->Position(),trsf);
|
||||
IfcGeom::Kernel::convert(l->Position(),trsf);
|
||||
shape = builder.Solid().Moved(trsf);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcRightCircularCone* l, TopoDS_Shape& shape) {
|
||||
const double r = l->BottomRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double h = l->Height() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcRightCircularCone* l, TopoDS_Shape& shape) {
|
||||
const double r = l->BottomRadius() * getValue(GV_LENGTH_UNIT);
|
||||
const double h = l->Height() * getValue(GV_LENGTH_UNIT);
|
||||
|
||||
BRepPrimAPI_MakeCone builder(r, 0., h);
|
||||
gp_Trsf trsf;
|
||||
IfcGeom::convert(l->Position(),trsf);
|
||||
IfcGeom::Kernel::convert(l->Position(),trsf);
|
||||
shape = builder.Solid().Moved(trsf);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcSphere* l, TopoDS_Shape& shape) {
|
||||
const double r = l->Radius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcSphere* l, TopoDS_Shape& shape) {
|
||||
const double r = l->Radius() * getValue(GV_LENGTH_UNIT);
|
||||
|
||||
BRepPrimAPI_MakeSphere builder(r);
|
||||
gp_Trsf trsf;
|
||||
IfcGeom::convert(l->Position(),trsf);
|
||||
IfcGeom::Kernel::convert(l->Position(),trsf);
|
||||
shape = builder.Solid().Moved(trsf);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcCsgSolid* l, TopoDS_Shape& shape) {
|
||||
return IfcGeom::convert_shape(l->TreeRootExpression(), shape);
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCsgSolid* l, TopoDS_Shape& shape) {
|
||||
return convert_shape(l->TreeRootExpression(), shape);
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcCurveBoundedPlane* l, TopoDS_Shape& face) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCurveBoundedPlane* l, TopoDS_Shape& face) {
|
||||
gp_Pln pln;
|
||||
IfcGeom::convert(l->BasisSurface(), pln);
|
||||
IfcGeom::Kernel::convert(l->BasisSurface(), pln);
|
||||
|
||||
gp_Trsf trsf;
|
||||
trsf.SetTransformation(pln.Position());
|
||||
|
||||
TopoDS_Wire outer;
|
||||
IfcGeom::convert_wire(l->OuterBoundary(), outer);
|
||||
convert_wire(l->OuterBoundary(), outer);
|
||||
|
||||
BRepBuilderAPI_MakeFace mf (outer);
|
||||
mf.Add(outer);
|
||||
@@ -605,7 +607,7 @@ bool IfcGeom::convert(const IfcSchema::IfcCurveBoundedPlane* l, TopoDS_Shape& fa
|
||||
|
||||
for (IfcSchema::IfcCurve::list::it it = inner->begin(); it != inner->end(); ++it) {
|
||||
TopoDS_Wire inner;
|
||||
IfcGeom::convert_wire(*it, inner);
|
||||
convert_wire(*it, inner);
|
||||
|
||||
mf.Add(inner);
|
||||
}
|
||||
@@ -617,13 +619,13 @@ bool IfcGeom::convert(const IfcSchema::IfcCurveBoundedPlane* l, TopoDS_Shape& fa
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcRectangularTrimmedSurface* l, TopoDS_Shape& face) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcRectangularTrimmedSurface* l, TopoDS_Shape& face) {
|
||||
if (!l->BasisSurface()->is(IfcSchema::Type::IfcPlane)) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Unsupported BasisSurface:", l->BasisSurface()->entity);
|
||||
return false;
|
||||
}
|
||||
gp_Pln pln;
|
||||
IfcGeom::convert((IfcSchema::IfcPlane*) l->BasisSurface(), pln);
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcPlane*) l->BasisSurface(), pln);
|
||||
|
||||
BRepBuilderAPI_MakeFace mf(pln, l->U1(), l->U2(), l->V1(), l->V2());
|
||||
|
||||
@@ -632,7 +634,7 @@ bool IfcGeom::convert(const IfcSchema::IfcRectangularTrimmedSurface* l, TopoDS_S
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcSurfaceCurveSweptAreaSolid* l, TopoDS_Shape& shape) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcSurfaceCurveSweptAreaSolid* l, TopoDS_Shape& shape) {
|
||||
gp_Trsf directrix, position;
|
||||
TopoDS_Shape face;
|
||||
TopoDS_Wire wire, section;
|
||||
@@ -642,9 +644,9 @@ bool IfcGeom::convert(const IfcSchema::IfcSurfaceCurveSweptAreaSolid* l, TopoDS_
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IfcGeom::convert(l->Position(), position) ||
|
||||
!IfcGeom::convert_face(l->SweptArea(), face) ||
|
||||
!IfcGeom::convert_wire(l->Directrix(), wire) ) {
|
||||
if (!IfcGeom::Kernel::convert(l->Position(), position) ||
|
||||
!convert_face(l->SweptArea(), face) ||
|
||||
!convert_wire(l->Directrix(), wire) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -652,7 +654,7 @@ bool IfcGeom::convert(const IfcSchema::IfcSurfaceCurveSweptAreaSolid* l, TopoDS_
|
||||
gp_Pnt directrix_origin;
|
||||
gp_Vec directrix_tangent;
|
||||
bool directrix_on_plane = true;
|
||||
IfcGeom::convert((IfcSchema::IfcPlane*) l->ReferenceSurface(), pln);
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcPlane*) l->ReferenceSurface(), pln);
|
||||
|
||||
// As per Informal propositions 2: The Directrix shall lie on the ReferenceSurface.
|
||||
// This is not always the case with the test files in the repository. I am not sure
|
||||
@@ -705,12 +707,12 @@ bool IfcGeom::convert(const IfcSchema::IfcSurfaceCurveSweptAreaSolid* l, TopoDS_
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcSweptDiskSolid* l, TopoDS_Shape& shape) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcSweptDiskSolid* l, TopoDS_Shape& shape) {
|
||||
TopoDS_Wire wire, section1, section2;
|
||||
|
||||
const bool hasInnerRadius = l->hasInnerRadius();
|
||||
|
||||
if (!IfcGeom::convert_wire(l->Directrix(), wire)) {
|
||||
if (!convert_wire(l->Directrix(), wire)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -726,12 +728,12 @@ bool IfcGeom::convert(const IfcSchema::IfcSweptDiskSolid* l, TopoDS_Shape& shape
|
||||
directrix = gp_Ax2(directrix_origin, directrix_tangent);
|
||||
}
|
||||
|
||||
const double r1 = l->Radius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double r1 = l->Radius() * getValue(GV_LENGTH_UNIT);
|
||||
Handle(Geom_Circle) circle = new Geom_Circle(directrix, r1);
|
||||
section1 = BRepBuilderAPI_MakeWire(BRepBuilderAPI_MakeEdge(circle));
|
||||
|
||||
if (hasInnerRadius) {
|
||||
const double r2 = l->InnerRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
const double r2 = l->InnerRadius() * getValue(GV_LENGTH_UNIT);
|
||||
Handle(Geom_Circle) circle = new Geom_Circle(directrix, r2);
|
||||
section2 = BRepBuilderAPI_MakeWire(BRepBuilderAPI_MakeEdge(circle));
|
||||
}
|
||||
@@ -782,15 +784,15 @@ bool IfcGeom::convert(const IfcSchema::IfcSweptDiskSolid* l, TopoDS_Shape& shape
|
||||
|
||||
#ifdef USE_IFC4
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcCylindricalSurface* l, TopoDS_Shape& face) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCylindricalSurface* l, TopoDS_Shape& face) {
|
||||
gp_Trsf trsf;
|
||||
IfcGeom::convert(l->Position(),trsf);
|
||||
IfcGeom::Kernel::convert(l->Position(),trsf);
|
||||
|
||||
face = BRepBuilderAPI_MakeFace(new Geom_CylindricalSurface(gp::XOY(), l->Radius()), GetValue(GV_PRECISION)).Face().Moved(trsf);
|
||||
face = BRepBuilderAPI_MakeFace(new Geom_CylindricalSurface(gp::XOY(), l->Radius()), getValue(GV_PRECISION)).Face().Moved(trsf);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcAdvancedBrep* l, TopoDS_Shape& shape) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcAdvancedBrep* l, TopoDS_Shape& shape) {
|
||||
return convert(l->Outer(), shape);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "../ifcparse/IfcParse.h"
|
||||
|
||||
#include "IfcGeomUtils.h"
|
||||
|
||||
double IfcGeom::Utils::UnitPrefixToValue( IfcSchema::IfcSIPrefix::IfcSIPrefix v ) {
|
||||
if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_EXA ) return 1.e18;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_PETA ) return 1.e15;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_TERA ) return 1.e12;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_GIGA ) return 1.e9;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_MEGA ) return 1.e6;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_KILO ) return 1.e3;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_HECTO ) return 1.e2;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_DECA ) return 1.;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_DECI ) return 1.e-1;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_CENTI ) return 1.e-2;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_MILLI ) return 1.e-3;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_MICRO ) return 1.e-6;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_NANO ) return 1.e-9;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_PICO ) return 1.e-12;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_FEMTO ) return 1.e-15;
|
||||
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_ATTO ) return 1.e-18;
|
||||
else return 1.f;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 IFCGEOMUTILS_H
|
||||
#define IFCGEOMUTILS_H
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
namespace Utils {
|
||||
double UnitPrefixToValue(IfcSchema::IfcSIPrefix::IfcSIPrefix v);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -83,12 +83,12 @@
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcCompositeCurve* l, TopoDS_Wire& wire) {
|
||||
if ( IfcGeom::GetValue(GV_PLANEANGLE_UNIT)<0 ) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCompositeCurve* l, TopoDS_Wire& wire) {
|
||||
if ( getValue(GV_PLANEANGLE_UNIT)<0 ) {
|
||||
Logger::Message(Logger::LOG_WARNING,"Creating a composite curve without unit information:",l->entity);
|
||||
|
||||
// Temporarily pretend we do have unit information
|
||||
IfcGeom::SetValue(GV_PLANEANGLE_UNIT,1.0);
|
||||
setValue(GV_PLANEANGLE_UNIT,1.0);
|
||||
|
||||
bool succes_radians = false;
|
||||
bool succes_degrees = false;
|
||||
@@ -98,17 +98,17 @@ bool IfcGeom::convert(const IfcSchema::IfcCompositeCurve* l, TopoDS_Wire& wire)
|
||||
// First try radians
|
||||
TopoDS_Wire wire_radians, wire_degrees;
|
||||
try {
|
||||
succes_radians = IfcGeom::convert(l,wire_radians);
|
||||
succes_radians = IfcGeom::Kernel::convert(l,wire_radians);
|
||||
} catch (...) {}
|
||||
|
||||
// Now try degrees
|
||||
IfcGeom::SetValue(GV_PLANEANGLE_UNIT,0.0174532925199433);
|
||||
setValue(GV_PLANEANGLE_UNIT,0.0174532925199433);
|
||||
try {
|
||||
succes_degrees = IfcGeom::convert(l,wire_degrees);
|
||||
succes_degrees = IfcGeom::Kernel::convert(l,wire_degrees);
|
||||
} catch (...) {}
|
||||
|
||||
// Restore to unknown unit state
|
||||
IfcGeom::SetValue(GV_PLANEANGLE_UNIT,-1.0);
|
||||
setValue(GV_PLANEANGLE_UNIT,-1.0);
|
||||
|
||||
if ( succes_degrees && ! succes_radians ) {
|
||||
use_degrees = true;
|
||||
@@ -145,13 +145,13 @@ bool IfcGeom::convert(const IfcSchema::IfcCompositeCurve* l, TopoDS_Wire& wire)
|
||||
for( IfcSchema::IfcCompositeCurveSegment::list::it it = segments->begin(); it != segments->end(); ++ it ) {
|
||||
IfcSchema::IfcCurve* curve = (*it)->ParentCurve();
|
||||
TopoDS_Wire wire2;
|
||||
if ( ! IfcGeom::convert_wire(curve,wire2) ) {
|
||||
if ( !convert_wire(curve,wire2) ) {
|
||||
Logger::Message(Logger::LOG_ERROR,"Failed to convert curve:",curve->entity);
|
||||
continue;
|
||||
}
|
||||
if ( ! (*it)->SameSense() ) wire2.Reverse();
|
||||
ShapeFix_ShapeTolerance FTol;
|
||||
FTol.SetTolerance(wire2, GetValue(GV_WIRE_CREATION_TOLERANCE), TopAbs_WIRE);
|
||||
FTol.SetTolerance(wire2, getValue(GV_WIRE_CREATION_TOLERANCE), TopAbs_WIRE);
|
||||
/*if ( it != segments->begin() ) {
|
||||
TopExp_Explorer exp (wire2,TopAbs_VERTEX);
|
||||
const TopoDS_Vertex& first_vertex = TopoDS::Vertex(exp.Current());
|
||||
@@ -173,12 +173,12 @@ bool IfcGeom::convert(const IfcSchema::IfcCompositeCurve* l, TopoDS_Wire& wire)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire& wire) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire& wire) {
|
||||
IfcSchema::IfcCurve* basis_curve = l->BasisCurve();
|
||||
bool isConic = basis_curve->is(IfcSchema::Type::IfcConic);
|
||||
double parameterFactor = isConic ? IfcGeom::GetValue(GV_PLANEANGLE_UNIT) : IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
double parameterFactor = isConic ? getValue(GV_PLANEANGLE_UNIT) : getValue(GV_LENGTH_UNIT);
|
||||
Handle(Geom_Curve) curve;
|
||||
if ( ! IfcGeom::convert_curve(basis_curve,curve) ) return false;
|
||||
if ( !convert_curve(basis_curve,curve) ) return false;
|
||||
bool trim_cartesian = l->MasterRepresentation() == IfcSchema::IfcTrimmingPreference::IfcTrimmingPreference_CARTESIAN;
|
||||
IfcUtil::IfcAbstractSelect::list::ptr trims1 = l->Trim1();
|
||||
IfcUtil::IfcAbstractSelect::list::ptr trims2 = l->Trim2();
|
||||
@@ -193,7 +193,7 @@ bool IfcGeom::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire& wire) {
|
||||
for ( IfcUtil::IfcAbstractSelect::list::it it = trims1->begin(); it != trims1->end(); it ++ ) {
|
||||
IfcUtil::IfcAbstractSelect* i = *it;
|
||||
if ( i->is(IfcSchema::Type::IfcCartesianPoint) ) {
|
||||
IfcGeom::convert((IfcSchema::IfcCartesianPoint*)i, pnts[sense_agreement] );
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcCartesianPoint*)i, pnts[sense_agreement] );
|
||||
has_pnts[sense_agreement] = true;
|
||||
} else if ( i->is(IfcSchema::Type::IfcParameterValue) ) {
|
||||
const double value = *((IfcUtil::IfcArgumentSelect*)i)->wrappedValue();
|
||||
@@ -204,7 +204,7 @@ bool IfcGeom::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire& wire) {
|
||||
for ( IfcUtil::IfcAbstractSelect::list::it it = trims2->begin(); it != trims2->end(); it ++ ) {
|
||||
IfcUtil::IfcAbstractSelect* i = *it;
|
||||
if ( i->is(IfcSchema::Type::IfcCartesianPoint) ) {
|
||||
IfcGeom::convert((IfcSchema::IfcCartesianPoint*)i, pnts[1-sense_agreement] );
|
||||
IfcGeom::Kernel::convert((IfcSchema::IfcCartesianPoint*)i, pnts[1-sense_agreement] );
|
||||
has_pnts[1-sense_agreement] = true;
|
||||
} else if ( i->is(IfcSchema::Type::IfcParameterValue) ) {
|
||||
const double value = *((IfcUtil::IfcArgumentSelect*)i)->wrappedValue();
|
||||
@@ -215,15 +215,15 @@ bool IfcGeom::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire& wire) {
|
||||
trim_cartesian &= has_pnts[0] && has_pnts[1];
|
||||
bool trim_cartesian_failed = !trim_cartesian;
|
||||
if ( trim_cartesian ) {
|
||||
if ( pnts[0].Distance(pnts[1]) < GetValue(GV_WIRE_CREATION_TOLERANCE) ) {
|
||||
if ( pnts[0].Distance(pnts[1]) < getValue(GV_WIRE_CREATION_TOLERANCE) ) {
|
||||
Logger::Message(Logger::LOG_WARNING,"Skipping segment with length below tolerance level:",l->entity);
|
||||
return false;
|
||||
}
|
||||
ShapeFix_ShapeTolerance FTol;
|
||||
TopoDS_Vertex v1 = BRepBuilderAPI_MakeVertex(pnts[0]);
|
||||
TopoDS_Vertex v2 = BRepBuilderAPI_MakeVertex(pnts[1]);
|
||||
FTol.SetTolerance(v1, GetValue(GV_WIRE_CREATION_TOLERANCE), TopAbs_VERTEX);
|
||||
FTol.SetTolerance(v2, GetValue(GV_WIRE_CREATION_TOLERANCE), TopAbs_VERTEX);
|
||||
FTol.SetTolerance(v1, getValue(GV_WIRE_CREATION_TOLERANCE), TopAbs_VERTEX);
|
||||
FTol.SetTolerance(v2, getValue(GV_WIRE_CREATION_TOLERANCE), TopAbs_VERTEX);
|
||||
BRepBuilderAPI_MakeEdge e (curve,v1,v2);
|
||||
if ( ! e.IsDone() ) {
|
||||
BRepBuilderAPI_EdgeError err = e.Error();
|
||||
@@ -247,8 +247,8 @@ bool IfcGeom::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire& wire) {
|
||||
}
|
||||
if ( basis_curve->is(IfcSchema::Type::IfcEllipse) ) {
|
||||
IfcSchema::IfcEllipse* ellipse = static_cast<IfcSchema::IfcEllipse*>(basis_curve);
|
||||
double x = ellipse->SemiAxis1() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
double y = ellipse->SemiAxis2() * IfcGeom::GetValue(GV_LENGTH_UNIT);
|
||||
double x = ellipse->SemiAxis1() * getValue(GV_LENGTH_UNIT);
|
||||
double y = ellipse->SemiAxis2() * getValue(GV_LENGTH_UNIT);
|
||||
const bool rotated = y > x;
|
||||
if (rotated) {
|
||||
flts[0] -= M_PI / 2.;
|
||||
@@ -272,14 +272,14 @@ bool IfcGeom::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire& wire) {
|
||||
}
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcPolyline* l, TopoDS_Wire& result) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcPolyline* l, TopoDS_Wire& result) {
|
||||
IfcSchema::IfcCartesianPoint::list::ptr points = l->Points();
|
||||
|
||||
// Parse and store the points in a sequence
|
||||
TColgp_SequenceOfPnt polygon;
|
||||
for(IfcSchema::IfcCartesianPoint::list::it it = points->begin(); it != points->end(); ++ it) {
|
||||
gp_Pnt pnt;
|
||||
IfcGeom::convert(*it, pnt);
|
||||
IfcGeom::Kernel::convert(*it, pnt);
|
||||
polygon.Append(pnt);
|
||||
}
|
||||
|
||||
@@ -295,14 +295,14 @@ bool IfcGeom::convert(const IfcSchema::IfcPolyline* l, TopoDS_Wire& result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcPolyLoop* l, TopoDS_Wire& result) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcPolyLoop* l, TopoDS_Wire& result) {
|
||||
IfcSchema::IfcCartesianPoint::list::ptr points = l->Polygon();
|
||||
|
||||
// Parse and store the points in a sequence
|
||||
TColgp_SequenceOfPnt polygon;
|
||||
for(IfcSchema::IfcCartesianPoint::list::it it = points->begin(); it != points->end(); ++ it) {
|
||||
gp_Pnt pnt;
|
||||
IfcGeom::convert(*it, pnt);
|
||||
IfcGeom::Kernel::convert(*it, pnt);
|
||||
polygon.Append(pnt);
|
||||
}
|
||||
|
||||
@@ -337,11 +337,11 @@ bool IfcGeom::convert(const IfcSchema::IfcPolyLoop* l, TopoDS_Wire& result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcArbitraryOpenProfileDef* l, TopoDS_Wire& result) {
|
||||
return IfcGeom::convert_wire(l->Curve(), result);
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcArbitraryOpenProfileDef* l, TopoDS_Wire& result) {
|
||||
return convert_wire(l->Curve(), result);
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcEdgeCurve* l, TopoDS_Wire& result) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcEdgeCurve* l, TopoDS_Wire& result) {
|
||||
IfcSchema::IfcPoint* pnt1 = ((IfcSchema::IfcVertexPoint*) l->EdgeStart())->VertexGeometry();
|
||||
IfcSchema::IfcPoint* pnt2 = ((IfcSchema::IfcVertexPoint*) l->EdgeEnd())->VertexGeometry();
|
||||
if (!pnt1->is(IfcSchema::Type::IfcCartesianPoint) || !pnt2->is(IfcSchema::Type::IfcCartesianPoint)) {
|
||||
@@ -350,8 +350,8 @@ bool IfcGeom::convert(const IfcSchema::IfcEdgeCurve* l, TopoDS_Wire& result) {
|
||||
}
|
||||
|
||||
gp_Pnt p1, p2;
|
||||
if (!IfcGeom::convert(((IfcSchema::IfcCartesianPoint*)pnt1), p1) ||
|
||||
!IfcGeom::convert(((IfcSchema::IfcCartesianPoint*)pnt2), p2))
|
||||
if (!IfcGeom::Kernel::convert(((IfcSchema::IfcCartesianPoint*)pnt1), p1) ||
|
||||
!IfcGeom::Kernel::convert(((IfcSchema::IfcCartesianPoint*)pnt2), p2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -366,11 +366,11 @@ bool IfcGeom::convert(const IfcSchema::IfcEdgeCurve* l, TopoDS_Wire& result) {
|
||||
// of the IfcEdgeCurve.
|
||||
const bool is_bounded = l->EdgeGeometry()->is(IfcSchema::Type::IfcBoundedCurve);
|
||||
|
||||
if (!is_bounded && IfcGeom::convert_curve(l->EdgeGeometry(), crv)) {
|
||||
if (!is_bounded && convert_curve(l->EdgeGeometry(), crv)) {
|
||||
mw.Add(BRepBuilderAPI_MakeEdge(crv, p1, p2));
|
||||
result = mw;
|
||||
return true;
|
||||
} else if (is_bounded && IfcGeom::convert_wire(l->EdgeGeometry(), result)) {
|
||||
} else if (is_bounded && convert_wire(l->EdgeGeometry(), result)) {
|
||||
if (!l->SameSense()) std::swap(pnt1, pnt2);
|
||||
TopExp_Explorer exp(result, TopAbs_EDGE);
|
||||
bool first = true;
|
||||
@@ -402,7 +402,7 @@ bool IfcGeom::convert(const IfcSchema::IfcEdgeCurve* l, TopoDS_Wire& result) {
|
||||
}
|
||||
}
|
||||
|
||||
bool IfcGeom::convert(const IfcSchema::IfcEdgeLoop* l, TopoDS_Wire& result) {
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcEdgeLoop* l, TopoDS_Wire& result) {
|
||||
IfcSchema::IfcOrientedEdge::list::ptr li = l->EdgeList();
|
||||
BRepBuilderAPI_MakeWire mw;
|
||||
for (IfcSchema::IfcOrientedEdge::list::it it = li->begin(); it != li->end(); ++it) {
|
||||
@@ -416,8 +416,8 @@ bool IfcGeom::convert(const IfcSchema::IfcEdgeLoop* l, TopoDS_Wire& result) {
|
||||
}
|
||||
|
||||
gp_Pnt p1, p2;
|
||||
if (!IfcGeom::convert(((IfcSchema::IfcCartesianPoint*)pnt1), p1) ||
|
||||
!IfcGeom::convert(((IfcSchema::IfcCartesianPoint*)pnt2), p2))
|
||||
if (!IfcGeom::Kernel::convert(((IfcSchema::IfcCartesianPoint*)pnt1), p1) ||
|
||||
!IfcGeom::Kernel::convert(((IfcSchema::IfcCartesianPoint*)pnt2), p2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
+18
-22
@@ -19,58 +19,54 @@
|
||||
|
||||
#include "IfcGeom.h"
|
||||
|
||||
namespace IfcGeom {
|
||||
namespace Cache {
|
||||
std::map<int,TopoDS_Shape> Shape;
|
||||
void PurgeShapeCache() {
|
||||
Shape.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
using namespace IfcSchema;
|
||||
using namespace IfcUtil;
|
||||
|
||||
bool IfcGeom::convert_shapes(const IfcBaseClass* l, IfcRepresentationShapeItems& r) {
|
||||
bool IfcGeom::Kernel::convert_shapes(const IfcBaseClass* l, IfcRepresentationShapeItems& r) {
|
||||
#include "IfcRegisterConvertShapes.h"
|
||||
Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity);
|
||||
return false;
|
||||
}
|
||||
bool IfcGeom::is_shape_collection(const IfcBaseClass* l) {
|
||||
|
||||
bool IfcGeom::Kernel::is_shape_collection(const IfcBaseClass* l) {
|
||||
#include "IfcRegisterIsShapeCollection.h"
|
||||
return false;
|
||||
}
|
||||
bool IfcGeom::convert_shape(const IfcBaseClass* l, TopoDS_Shape& r) {
|
||||
|
||||
bool IfcGeom::Kernel::convert_shape(const IfcBaseClass* l, TopoDS_Shape& r) {
|
||||
const unsigned int id = l->entity->id();
|
||||
bool success = false;
|
||||
bool processed = false;
|
||||
std::map<int,TopoDS_Shape>::const_iterator it = Cache::Shape.find(id);
|
||||
if ( it != Cache::Shape.end() ) { r = it->second; return true; }
|
||||
std::map<int,TopoDS_Shape>::const_iterator it = cache.Shape.find(id);
|
||||
if ( it != cache.Shape.end() ) { r = it->second; return true; }
|
||||
#include "IfcRegisterConvertShape.h"
|
||||
if ( processed ) {
|
||||
const double precision = IfcGeom::GetValue(GV_PRECISION);
|
||||
IfcGeom::apply_tolerance(r, precision);
|
||||
Cache::Shape[id] = r;
|
||||
const double precision = getValue(GV_PRECISION);
|
||||
apply_tolerance(r, precision);
|
||||
cache.Shape[id] = r;
|
||||
} else {
|
||||
Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
bool IfcGeom::convert_wire(const IfcBaseClass* l, TopoDS_Wire& r) {
|
||||
|
||||
bool IfcGeom::Kernel::convert_wire(const IfcBaseClass* l, TopoDS_Wire& r) {
|
||||
#include "IfcRegisterConvertWire.h"
|
||||
Handle(Geom_Curve) curve;
|
||||
if (IfcGeom::convert_curve(l, curve)) {
|
||||
return IfcGeom::convert_curve_to_wire(curve, r);
|
||||
if (IfcGeom::Kernel::convert_curve(l, curve)) {
|
||||
return IfcGeom::Kernel::convert_curve_to_wire(curve, r);
|
||||
}
|
||||
Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity);
|
||||
return false;
|
||||
}
|
||||
bool IfcGeom::convert_face(const IfcBaseClass* l, TopoDS_Shape& r) {
|
||||
|
||||
bool IfcGeom::Kernel::convert_face(const IfcBaseClass* l, TopoDS_Shape& r) {
|
||||
#include "IfcRegisterConvertFace.h"
|
||||
Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity);
|
||||
return false;
|
||||
}
|
||||
bool IfcGeom::convert_curve(const IfcBaseClass* l, Handle(Geom_Curve)& r) {
|
||||
|
||||
bool IfcGeom::Kernel::convert_curve(const IfcBaseClass* l, Handle(Geom_Curve)& r) {
|
||||
#include "IfcRegisterConvertCurve.h"
|
||||
Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity);
|
||||
return false;
|
||||
|
||||
@@ -41,8 +41,6 @@
|
||||
#include "../ifcparse/IfcUtil.h"
|
||||
#include "../ifcparse/IfcParse.h"
|
||||
|
||||
using namespace IfcSchema;
|
||||
|
||||
SHAPES(IfcShellBasedSurfaceModel);
|
||||
SHAPES(IfcFaceBasedSurfaceModel);
|
||||
SHAPES(IfcShapeRepresentation);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define SHAPES(T) \
|
||||
if ( l->is(T::Class()) ) { \
|
||||
try { \
|
||||
return IfcGeom::convert((T*)l,r); \
|
||||
return convert((T*)l,r); \
|
||||
} catch (...) { } \
|
||||
Logger::Message(Logger::LOG_ERROR,"Failed to convert:",l->entity); \
|
||||
return false; \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "IfcRegisterUndef.h"
|
||||
#define CLASS(T,V) bool convert(const T* L, V& r);
|
||||
#define CLASS(T,V) bool convert(const IfcSchema::T* L, V& r);
|
||||
#define SHAPES(T) CLASS(T,IfcRepresentationShapeItems)
|
||||
#define SHAPE(T) CLASS(T,TopoDS_Shape)
|
||||
#define WIRE(T) CLASS(T,TopoDS_Wire)
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include "../ifcgeom/IfcGeomObjects.h"
|
||||
#include "../ifcgeom/IfcGeomIterator.h"
|
||||
|
||||
using namespace boost;
|
||||
|
||||
@@ -186,7 +186,7 @@ public:
|
||||
|
||||
class Entity : public Command {
|
||||
private:
|
||||
const IfcGeomObjects::IfcGeomObject* geom;
|
||||
const IfcGeom::TriangulationElement<float>* geom;
|
||||
protected:
|
||||
void read_content(std::istream& s) {}
|
||||
void write_content(std::ostream& s) {
|
||||
@@ -195,7 +195,7 @@ protected:
|
||||
swrite(s, geom->name());
|
||||
swrite(s, geom->type());
|
||||
swrite<int32_t>(s, geom->parent_id());
|
||||
const std::vector<float>& m = geom->matrix();
|
||||
const std::vector<float>& m = geom->transformation().matrix().data();
|
||||
const float matrix_array[16] = {
|
||||
m[0], m[3], m[6], m[ 9],
|
||||
m[1], m[4], m[7], m[10],
|
||||
@@ -203,17 +203,17 @@ protected:
|
||||
0, 0, 0, 1
|
||||
};
|
||||
swrite(s, std::string((char*)matrix_array, 16 * sizeof(float)));
|
||||
swrite<int32_t>(s, geom->mesh().id());
|
||||
swrite(s, std::string((char*)geom->mesh().verts().data(), geom->mesh().verts().size() * sizeof(float)));
|
||||
swrite(s, std::string((char*)geom->mesh().normals().data(), geom->mesh().normals().size() * sizeof(float)));
|
||||
swrite<int32_t>(s, geom->geometry().id());
|
||||
swrite(s, std::string((char*)geom->geometry().verts().data(), geom->geometry().verts().size() * sizeof(float)));
|
||||
swrite(s, std::string((char*)geom->geometry().normals().data(), geom->geometry().normals().size() * sizeof(float)));
|
||||
{ std::vector<int32_t> indices;
|
||||
for (std::vector<int>::const_iterator it = geom->mesh().faces().begin(); it != geom->mesh().faces().end(); ++it) {
|
||||
for (std::vector<int>::const_iterator it = geom->geometry().faces().begin(); it != geom->geometry().faces().end(); ++it) {
|
||||
indices.push_back(*it);
|
||||
}
|
||||
swrite(s, std::string((char*) indices.data(), indices.size() * sizeof(int32_t))); }
|
||||
{ std::vector<float> diffuse_color_array;
|
||||
for (std::vector<IfcGeomObjects::Material>::const_iterator it = geom->mesh().materials().begin(); it != geom->mesh().materials().end(); ++it) {
|
||||
const IfcGeomObjects::Material& m = *it;
|
||||
for (std::vector<IfcGeom::Material>::const_iterator it = geom->geometry().materials().begin(); it != geom->geometry().materials().end(); ++it) {
|
||||
const IfcGeom::Material& m = *it;
|
||||
if (m.hasDiffuse()) {
|
||||
const double* color = m.diffuse();
|
||||
diffuse_color_array.push_back(static_cast<float>(color[0]));
|
||||
@@ -232,13 +232,13 @@ protected:
|
||||
}
|
||||
swrite(s, std::string((char*) diffuse_color_array.data(), diffuse_color_array.size() * sizeof(float))); }
|
||||
{ std::vector<int32_t> material_indices;
|
||||
for (std::vector<int>::const_iterator it = geom->mesh().material_ids().begin(); it != geom->mesh().material_ids().end(); ++it) {
|
||||
for (std::vector<int>::const_iterator it = geom->geometry().material_ids().begin(); it != geom->geometry().material_ids().end(); ++it) {
|
||||
material_indices.push_back(*it);
|
||||
}
|
||||
swrite(s, std::string((char*) material_indices.data(), material_indices.size() * sizeof(int32_t))); }
|
||||
}
|
||||
public:
|
||||
Entity(const IfcGeomObjects::IfcGeomObject* geom) : Command(ENTITY), geom(geom) {};
|
||||
Entity(const IfcGeom::TriangulationElement<float>* geom) : Command(ENTITY), geom(geom) {};
|
||||
};
|
||||
|
||||
class Next : public Command {
|
||||
@@ -278,6 +278,8 @@ int main (int argc, char** argv) {
|
||||
|
||||
bool has_more = false;
|
||||
|
||||
IfcGeom::Iterator<float>* iterator = 0;
|
||||
|
||||
Hello().write(std::cout);
|
||||
|
||||
int exit_code = 0;
|
||||
@@ -290,12 +292,15 @@ int main (int argc, char** argv) {
|
||||
char* data = new char[len];
|
||||
memcpy(data, m.string().c_str(), len);
|
||||
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::USE_WORLD_COORDS, false);
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::WELD_VERTICES, false);
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::CONVERT_BACK_UNITS, true);
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::FORCE_CCW_FACE_ORIENTATION, true);
|
||||
IfcGeom::IteratorSettings settings;
|
||||
settings.use_world_coords() = false;
|
||||
settings.weld_vertices() = false;
|
||||
settings.convert_back_units() = true;
|
||||
settings.force_ccw_face_orientation() = true;
|
||||
|
||||
iterator = new IfcGeom::Iterator<float>(settings, data, len);
|
||||
has_more = iterator->findContext();
|
||||
|
||||
has_more = IfcGeomObjects::Init(data, len);
|
||||
More(has_more).write(std::cout);
|
||||
continue;
|
||||
}
|
||||
@@ -305,22 +310,23 @@ int main (int argc, char** argv) {
|
||||
exit_code = 1;
|
||||
break;
|
||||
}
|
||||
const IfcGeomObjects::IfcGeomObject* geom = IfcGeomObjects::Get();
|
||||
const IfcGeom::TriangulationElement<float>* geom = static_cast<const IfcGeom::TriangulationElement<float>*>(iterator->get());
|
||||
Entity(geom).write(std::cout);
|
||||
continue;
|
||||
}
|
||||
case NEXT: {
|
||||
Next n; n.read(std::cin);
|
||||
has_more = IfcGeomObjects::Next();
|
||||
has_more = iterator->next();
|
||||
if (!has_more) {
|
||||
IfcGeomObjects::CleanUp();
|
||||
delete iterator;
|
||||
iterator = 0;
|
||||
}
|
||||
More(has_more).write(std::cout);
|
||||
continue;
|
||||
}
|
||||
case GET_LOG: {
|
||||
GetLog gl; gl.read(std::cin);
|
||||
WriteLog(IfcGeomObjects::GetLog()).write(std::cout);
|
||||
WriteLog(iterator->getLog()).write(std::cout);
|
||||
continue;
|
||||
}
|
||||
case BYE: {
|
||||
|
||||
+24
-23
@@ -22,7 +22,7 @@
|
||||
#include <istdplug.h>
|
||||
|
||||
#include "../ifcmax/IfcMax.h"
|
||||
#include "../ifcgeom/IfcGeomObjects.h"
|
||||
#include "../ifcgeom/IfcGeomIterator.h"
|
||||
|
||||
static const int NUM_MATERIAL_SLOTS = 24;
|
||||
|
||||
@@ -119,7 +119,7 @@ Mtl* FindMaterialByName(MtlBaseLib* library, const std::string& material_name) {
|
||||
return m;
|
||||
}
|
||||
|
||||
Mtl* FindOrCreateMaterial(MtlBaseLib* library, Interface* max_interface, int& slot, const IfcGeomObjects::Material& material) {
|
||||
Mtl* FindOrCreateMaterial(MtlBaseLib* library, Interface* max_interface, int& slot, const IfcGeom::Material& material) {
|
||||
Mtl* m = FindMaterialByName(library, material.name());
|
||||
if (m == 0) {
|
||||
StdMat2* stdm = NewDefaultStdMat();
|
||||
@@ -148,7 +148,7 @@ Mtl* FindOrCreateMaterial(MtlBaseLib* library, Interface* max_interface, int& sl
|
||||
return m;
|
||||
}
|
||||
|
||||
Mtl* ComposeMultiMaterial(std::map<std::vector<std::string>, Mtl*>& multi_mats, MtlBaseLib* library, Interface* max_interface, int& slot, const std::vector<IfcGeomObjects::Material>& materials, const std::string& object_type, const std::vector<int>& material_ids) {
|
||||
Mtl* ComposeMultiMaterial(std::map<std::vector<std::string>, Mtl*>& multi_mats, MtlBaseLib* library, Interface* max_interface, int& slot, const std::vector<IfcGeom::Material>& materials, const std::string& object_type, const std::vector<int>& material_ids) {
|
||||
std::vector<std::string> material_names;
|
||||
bool needs_default = std::find(material_ids.begin(), material_ids.end(), -1) != material_ids.end();
|
||||
if (needs_default) {
|
||||
@@ -200,9 +200,10 @@ Mtl* ComposeMultiMaterial(std::map<std::vector<std::string>, Mtl*>& multi_mats,
|
||||
|
||||
int IFCImp::DoImport(const TCHAR *name, ImpInterface *impitfc, Interface *itfc, BOOL suppressPrompts) {
|
||||
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::USE_WORLD_COORDS,false);
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::WELD_VERTICES,true);
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::SEW_SHELLS,true);
|
||||
IfcGeom::IteratorSettings settings;
|
||||
settings.use_world_coords() = false;
|
||||
settings.weld_vertices() = true;
|
||||
settings.sew_shells() = true;
|
||||
|
||||
#ifdef _UNICODE
|
||||
int fn_buffer_size = WideCharToMultiByte(CP_UTF8, 0, name, -1, 0, 0, 0, 0);
|
||||
@@ -212,7 +213,9 @@ int IFCImp::DoImport(const TCHAR *name, ImpInterface *impitfc, Interface *itfc,
|
||||
const char* fn_mb = name;
|
||||
#endif
|
||||
|
||||
if ( ! IfcGeomObjects::Init(fn_mb,0,0) ) return false;
|
||||
IfcGeom::Iterator<float> iterator(settings, fn_mb);
|
||||
|
||||
if (!iterator.findContext()) return false;
|
||||
|
||||
itfc->ProgressStart(_T("Importing file..."), TRUE, fn, NULL);
|
||||
|
||||
@@ -222,30 +225,29 @@ int IFCImp::DoImport(const TCHAR *name, ImpInterface *impitfc, Interface *itfc,
|
||||
std::map<std::vector<std::string>, Mtl*> material_cache;
|
||||
|
||||
do{
|
||||
|
||||
const IfcGeomObjects::IfcGeomObject* o = IfcGeomObjects::Get();
|
||||
const IfcGeom::TriangulationElement<float>* o = static_cast<const IfcGeom::TriangulationElement<float>*>(iterator.get());
|
||||
|
||||
TSTR o_type = S(o->type());
|
||||
TSTR o_guid = S(o->guid());
|
||||
|
||||
Mtl *m = ComposeMultiMaterial(material_cache, mats, itfc, slot, o->mesh().materials(), o->type(), o->mesh().material_ids());
|
||||
Mtl *m = ComposeMultiMaterial(material_cache, mats, itfc, slot, o->geometry().materials(), o->type(), o->geometry().material_ids());
|
||||
|
||||
TriObject* tri = CreateNewTriObject();
|
||||
|
||||
const int numVerts = o->mesh().verts().size()/3;
|
||||
const int numVerts = o->geometry().verts().size()/3;
|
||||
tri->mesh.setNumVerts(numVerts);
|
||||
for( int i = 0; i < numVerts; i ++ ) {
|
||||
tri->mesh.setVert(i,o->mesh().verts()[3*i+0],o->mesh().verts()[3*i+1],o->mesh().verts()[3*i+2]);
|
||||
tri->mesh.setVert(i,o->geometry().verts()[3*i+0],o->geometry().verts()[3*i+1],o->geometry().verts()[3*i+2]);
|
||||
}
|
||||
const int numFaces = o->mesh().faces().size()/3;
|
||||
const int numFaces = o->geometry().faces().size()/3;
|
||||
tri->mesh.setNumFaces(numFaces);
|
||||
|
||||
bool needs_default = std::find(o->mesh().material_ids().begin(), o->mesh().material_ids().end(), -1) != o->mesh().material_ids().end();
|
||||
bool needs_default = std::find(o->geometry().material_ids().begin(), o->geometry().material_ids().end(), -1) != o->geometry().material_ids().end();
|
||||
|
||||
for( int i = 0; i < numFaces; i ++ ) {
|
||||
tri->mesh.faces[i].setVerts(o->mesh().faces()[3*i+0],o->mesh().faces()[3*i+1],o->mesh().faces()[3*i+2]);
|
||||
tri->mesh.faces[i].setEdgeVisFlags(o->mesh().edges()[3*i+0],o->mesh().edges()[3*i+1],o->mesh().edges()[3*i+2]);
|
||||
MtlID mtlid = o->mesh().material_ids()[i];
|
||||
tri->mesh.faces[i].setVerts(o->geometry().faces()[3*i+0],o->geometry().faces()[3*i+1],o->geometry().faces()[3*i+2]);
|
||||
tri->mesh.faces[i].setEdgeVisFlags(o->geometry().edges()[3*i+0],o->geometry().edges()[3*i+1],o->geometry().edges()[3*i+2]);
|
||||
MtlID mtlid = o->geometry().material_ids()[i];
|
||||
if (needs_default) mtlid ++;
|
||||
tri->mesh.faces[i].setMatID(mtlid);
|
||||
}
|
||||
@@ -267,15 +269,14 @@ int IFCImp::DoImport(const TCHAR *name, ImpInterface *impitfc, Interface *itfc,
|
||||
if (m) {
|
||||
node->GetINode()->SetMtl(m);
|
||||
}
|
||||
node->SetTransform(0,Matrix3 ( Point3(o->matrix()[0],o->matrix()[1],o->matrix()[2]),Point3(o->matrix()[3],o->matrix()[4],o->matrix()[5]),
|
||||
Point3(o->matrix()[6],o->matrix()[7],o->matrix()[8]),Point3(o->matrix()[9],o->matrix()[10],o->matrix()[11]) ));
|
||||
const std::vector<float>& matrix_data = o->transformation().matrix().data();
|
||||
node->SetTransform(0,Matrix3 ( Point3(matrix_data[0],matrix_data[1],matrix_data[2]),Point3(matrix_data[3],matrix_data[4],matrix_data[5]),
|
||||
Point3(matrix_data[6],matrix_data[7],matrix_data[8]),Point3(matrix_data[9],matrix_data[10],matrix_data[11]) ));
|
||||
impitfc->AddNodeToScene(node);
|
||||
|
||||
itfc->ProgressUpdate(IfcGeomObjects::Progress(),true,_T(""));
|
||||
itfc->ProgressUpdate(iterator.progress(), true, _T(""));
|
||||
|
||||
} while ( IfcGeomObjects::Next() );
|
||||
|
||||
IfcGeomObjects::CleanUp();
|
||||
} while (iterator.next());
|
||||
|
||||
itfc->ProgressEnd();
|
||||
|
||||
|
||||
@@ -308,8 +308,6 @@ public:
|
||||
std::string authorOrganisation() const;
|
||||
};
|
||||
|
||||
double UnitPrefixToValue( IfcSchema::IfcSIPrefix::IfcSIPrefix v );
|
||||
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, const IfcParse::IfcFile& f);
|
||||
|
||||
+134
-22
@@ -21,14 +21,45 @@
|
||||
%include "std_string.i"
|
||||
%include "exception.i"
|
||||
|
||||
// This is only used for RGB colours, hence the size of 3
|
||||
%typemap(out) const double* {
|
||||
// This is only used for RGB colours, hence the size of 3
|
||||
$result = PyTuple_New(3);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
PyTuple_SetItem($result, i, PyFloat_FromDouble($1[i]));
|
||||
}
|
||||
}
|
||||
|
||||
// Using RTTI return a more specialized type of Element
|
||||
%typemap(out) IfcGeom::Element<float>* {
|
||||
IfcGeom::SerializedElement<float>* serialized_elem = dynamic_cast<IfcGeom::SerializedElement<float>*>($1);
|
||||
IfcGeom::TriangulationElement<float>* triangulation_elem = dynamic_cast<IfcGeom::TriangulationElement<float>*>($1);
|
||||
if (triangulation_elem) {
|
||||
$result = SWIG_NewPointerObj(SWIG_as_voidptr(triangulation_elem), SWIGTYPE_p_IfcGeom__TriangulationElementT_float_t, 0);
|
||||
} else if (serialized_elem) {
|
||||
$result = SWIG_NewPointerObj(SWIG_as_voidptr(serialized_elem), SWIGTYPE_p_IfcGeom__SerializedElementT_float_t, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Using RTTI return a more specialized type of Element
|
||||
%typemap(out) IfcGeom::Element<double>* {
|
||||
IfcGeom::SerializedElement<double>* serialized_elem = dynamic_cast<IfcGeom::SerializedElement<double>*>($1);
|
||||
IfcGeom::TriangulationElement<double>* triangulation_elem = dynamic_cast<IfcGeom::TriangulationElement<double>*>($1);
|
||||
if (triangulation_elem) {
|
||||
$result = SWIG_NewPointerObj(SWIG_as_voidptr(triangulation_elem), SWIGTYPE_p_IfcGeom__TriangulationElementT_double_t, 0);
|
||||
} else if (serialized_elem) {
|
||||
$result = SWIG_NewPointerObj(SWIG_as_voidptr(serialized_elem), SWIGTYPE_p_IfcGeom__SerializedElementT_double_t, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// SWIG does not support bool references in a meaningful way, so the
|
||||
// IfcGeom::IteratorSettings functions degrade to return a read only value
|
||||
%typemap(out) double& {
|
||||
$result = SWIG_From_double(*$1);
|
||||
}
|
||||
%typemap(out) bool& {
|
||||
$result = PyBool_FromLong(static_cast<long>(*$1));
|
||||
}
|
||||
|
||||
%exception {
|
||||
try {
|
||||
$action
|
||||
@@ -39,14 +70,51 @@
|
||||
}
|
||||
}
|
||||
|
||||
%include "Interface.h"
|
||||
%include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||
%include "../ifcgeom/IfcGeomMaterial.h"
|
||||
%include "../ifcgeom/IfcGeomRepresentation.h"
|
||||
%include "../ifcgeom/IfcGeomElement.h"
|
||||
%include "../ifcgeom/IfcGeomIterator.h"
|
||||
|
||||
%module IfcImport %{
|
||||
#include "Interface.h"
|
||||
using namespace IfcGeomObjects;
|
||||
// This does not seem to work:
|
||||
%ignore IfcGeom::Iterator<float>::Iterator(const IfcGeom::IteratorSettings&, IfcParse::IfcFile*);
|
||||
%ignore IfcGeom::Iterator<float>::Iterator(const IfcGeom::IteratorSettings&, void*, int);
|
||||
%ignore IfcGeom::Iterator<float>::Iterator(const IfcGeom::IteratorSettings&, std::istream&, int);
|
||||
%ignore IfcGeom::Iterator<double>::Iterator(const IfcGeom::IteratorSettings&, IfcParse::IfcFile*);
|
||||
%ignore IfcGeom::Iterator<double>::Iterator(const IfcGeom::IteratorSettings&, void*, int);
|
||||
%ignore IfcGeom::Iterator<double>::Iterator(const IfcGeom::IteratorSettings&, std::istream&, int);
|
||||
|
||||
%extend IfcGeom::IteratorSettings {
|
||||
%pythoncode %{
|
||||
attrs = ("convert_back_units", "deflection_tolerance", "disable_opening_subtractions", "disable_triangulation", "faster_booleans", "force_ccw_face_orientation", "sew_shells", "use_brep_data", "use_world_coords", "weld_vertices")
|
||||
def __repr__(self):
|
||||
return "IteratorSettings(%s)"%(",".join(tuple("%s=%r"%(a, getattr(self, a)()) for a in self.attrs)))
|
||||
%}
|
||||
}
|
||||
|
||||
%module ifcopenshell %{
|
||||
#include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||
#include "../ifcgeom/IfcGeomMaterial.h"
|
||||
#include "../ifcgeom/IfcGeomRepresentation.h"
|
||||
#include "../ifcgeom/IfcGeomElement.h"
|
||||
#include "../ifcgeom/IfcGeomIterator.h"
|
||||
|
||||
using namespace IfcGeom;
|
||||
%}
|
||||
|
||||
%extend IfcGeomObjects::IfcRepresentationTriangulation {
|
||||
%extend IfcGeom::Iterator<float> {
|
||||
static int mantissa_size() {
|
||||
return std::numeric_limits<float>::digits;
|
||||
}
|
||||
};
|
||||
|
||||
%extend IfcGeom::Iterator<double> {
|
||||
static int mantissa_size() {
|
||||
return std::numeric_limits<double>::digits;
|
||||
}
|
||||
};
|
||||
|
||||
%extend IfcGeom::Representation::Triangulation {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
@@ -57,21 +125,19 @@
|
||||
normals = property(normals)
|
||||
material_ids = property(material_ids)
|
||||
materials = property(materials)
|
||||
def __repr__(self): return "RepresentationTriangulation #%d"%self.id
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeomObjects::IfcRepresentationBrepData {
|
||||
%extend IfcGeom::Representation::Serialization {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
id = property(id)
|
||||
brep_data = property(brep_data)
|
||||
def __repr__(self): return "RepresentationBrepData #%d"%self.id
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeomObjects::IfcObject {
|
||||
%extend IfcGeom::Element {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
@@ -80,30 +146,27 @@
|
||||
name = property(name)
|
||||
type = property(type)
|
||||
guid = property(guid)
|
||||
matrix = property(matrix)
|
||||
def __repr__(self): return "Object #%d"%self.id
|
||||
transformation = property(transformation)
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeomObjects::IfcGeomObject {
|
||||
%extend IfcGeom::TriangulationElement {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
mesh = property(mesh)
|
||||
def __repr__(self): return "GeomObject #%d"%self.id
|
||||
geometry = property(geometry)
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeomObjects::IfcGeomBrepDataObject {
|
||||
%extend IfcGeom::SerializedElement {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
mesh = property(mesh)
|
||||
def __repr__(self): return "GeomBrepDataObject #%d"%self.id
|
||||
geometry = property(geometry)
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeomObjects::Material {
|
||||
%extend IfcGeom::Material {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
@@ -116,12 +179,61 @@
|
||||
transparency = property(transparency)
|
||||
specularity = property(specularity)
|
||||
name = property(name)
|
||||
def __repr__(self): return "Material"
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeom::Transformation {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
matrix = property(matrix)
|
||||
%}
|
||||
};
|
||||
|
||||
%extend IfcGeom::Matrix {
|
||||
%pythoncode %{
|
||||
if _newclass:
|
||||
# Hide the getters with read-only property implementations
|
||||
data = property(data)
|
||||
%}
|
||||
};
|
||||
|
||||
namespace std {
|
||||
%template(IntVector) vector<int>;
|
||||
%template(FloatVector) vector<float>;
|
||||
%template(MaterialVector) vector<IfcGeomObjects::Material>;
|
||||
};
|
||||
%template(DoubleVector) vector<double>;
|
||||
%template(MaterialVector) vector<IfcGeom::Material>;
|
||||
};
|
||||
|
||||
namespace IfcGeom {
|
||||
%template(IteratorSinglePrecision) Iterator<float>;
|
||||
%template(IteratorDoublePrecision) Iterator<double>;
|
||||
|
||||
%template(ElementSinglePrecision) Element<float>;
|
||||
%template(ElementDoublePrecision) Element<double>;
|
||||
|
||||
%template(TriangulationElementSinglePrecision) TriangulationElement<float>;
|
||||
%template(TriangulationElementDoublePrecision) TriangulationElement<double>;
|
||||
|
||||
%template(SerializedElementSinglePrecision) SerializedElement<float>;
|
||||
%template(SerializedElementDoublePrecision) SerializedElement<double>;
|
||||
|
||||
%template(TransformationSinglePrecision) Transformation<float>;
|
||||
%template(TransformationDoublePrecision) Transformation<double>;
|
||||
|
||||
%template(MatrixSinglePrecision) Matrix<float>;
|
||||
%template(MatrixDoublePrecision) Matrix<double>;
|
||||
|
||||
namespace Representation {
|
||||
%template(TriangulationSinglePrecision) Triangulation<float>;
|
||||
%template(TriangulationDoublePrecision) Triangulation<double>;
|
||||
};
|
||||
};
|
||||
|
||||
// Hide templating precision to the user by choosing based on Python's
|
||||
// internal float type. This is probably always going to be a double.
|
||||
%pythoncode %{
|
||||
import sys
|
||||
for ty in (IteratorSinglePrecision, IteratorDoublePrecision):
|
||||
if ty.mantissa_size() == sys.float_info.mant_dig: Iterator = ty
|
||||
%}
|
||||
Reference in New Issue
Block a user