mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 10:23:41 +00:00
[Work in progress] Start adding support for IfcSurfaceStyleShading and -Rendering
This commit is contained in:
@@ -112,6 +112,7 @@ ADD_LIBRARY(IfcGeom STATIC
|
|||||||
../src/ifcgeom/IfcGeomFunctions.cpp
|
../src/ifcgeom/IfcGeomFunctions.cpp
|
||||||
../src/ifcgeom/IfcGeomHelpers.cpp
|
../src/ifcgeom/IfcGeomHelpers.cpp
|
||||||
../src/ifcgeom/IfcGeomObjects.cpp
|
../src/ifcgeom/IfcGeomObjects.cpp
|
||||||
|
../src/ifcgeom/IfcGeomRenderStyles.cpp
|
||||||
../src/ifcgeom/IfcGeomShapes.cpp
|
../src/ifcgeom/IfcGeomShapes.cpp
|
||||||
../src/ifcgeom/IfcGeomWires.cpp
|
../src/ifcgeom/IfcGeomWires.cpp
|
||||||
../src/ifcgeom/IfcRegister.cpp
|
../src/ifcgeom/IfcRegister.cpp
|
||||||
|
|||||||
@@ -17,8 +17,22 @@
|
|||||||
* *
|
* *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "ColladaSerializer.h"
|
#include "ColladaSerializer.h"
|
||||||
|
|
||||||
|
std::string collada_id(const std::string& s) {
|
||||||
|
std::string id;
|
||||||
|
id.reserve(s.size());
|
||||||
|
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
|
||||||
|
const std::string::value_type c = *it;
|
||||||
|
if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_')) {
|
||||||
|
id.push_back(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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<float>& floats, const char* coords /* = "XYZ" */) {
|
||||||
COLLADASW::FloatSource source(mSW);
|
COLLADASW::FloatSource source(mSW);
|
||||||
source.setId(mesh_id + suffix);
|
source.setId(mesh_id + suffix);
|
||||||
@@ -35,13 +49,15 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::addFloatSource(const
|
|||||||
source.finish();
|
source.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaSerializer::ColladaExporter::ColladaGeometries::write(const std::string mesh_id, const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<int>& indices) {
|
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<const IfcGeom::SurfaceStyle*>& materials) {
|
||||||
openMesh(mesh_id);
|
openMesh(mesh_id);
|
||||||
|
|
||||||
|
// The normals vector can be empty for example when the WELD_VERTICES setting is used.
|
||||||
|
// IfcOpenShell does not provide them with multiple face normals collapsed into a single vertex.
|
||||||
|
const bool has_normals = !normals.empty();
|
||||||
|
|
||||||
addFloatSource(mesh_id, COLLADASW::LibraryGeometries::POSITIONS_SOURCE_ID_SUFFIX, positions);
|
addFloatSource(mesh_id, COLLADASW::LibraryGeometries::POSITIONS_SOURCE_ID_SUFFIX, positions);
|
||||||
if (!normals.empty()) {
|
if (has_normals) {
|
||||||
// The normals vector can be empty for example when the WELD_VERTICES setting is used.
|
|
||||||
// IfcOpenShell does not provide them with multiple face normals collapsed into a single vertex.
|
|
||||||
addFloatSource(mesh_id, COLLADASW::LibraryGeometries::NORMALS_SOURCE_ID_SUFFIX, normals);
|
addFloatSource(mesh_id, COLLADASW::LibraryGeometries::NORMALS_SOURCE_ID_SUFFIX, normals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,23 +66,42 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::write(const std::str
|
|||||||
vertices.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::POSITION, "#" + mesh_id + COLLADASW::LibraryGeometries::POSITIONS_SOURCE_ID_SUFFIX));
|
vertices.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::POSITION, "#" + mesh_id + COLLADASW::LibraryGeometries::POSITIONS_SOURCE_ID_SUFFIX));
|
||||||
vertices.add();
|
vertices.add();
|
||||||
|
|
||||||
COLLADASW::Triangles triangles(mSW);
|
std::vector<int>::const_iterator index_range_start = indices.begin();
|
||||||
triangles.setCount(indices.size() / 3);
|
std::vector<int>::const_iterator material_it = material_ids.begin();
|
||||||
int offset = 0;
|
int previous_material_id = -2;
|
||||||
triangles.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::VERTEX,"#" + mesh_id + COLLADASW::LibraryGeometries::VERTICES_ID_SUFFIX, offset++ ) );
|
for (std::vector<int>::const_iterator it = indices.begin(); ; it += 3) {
|
||||||
if (!normals.empty()) {
|
const int current_material_id = material_it == material_ids.end()
|
||||||
triangles.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::NORMAL,"#" + mesh_id + COLLADASW::LibraryGeometries::NORMALS_SOURCE_ID_SUFFIX, offset++ ) );
|
? -3
|
||||||
}
|
: *(material_it++);
|
||||||
triangles.prepareToAppendValues();
|
const int num_triangles = std::distance(index_range_start, it) / 3;
|
||||||
for (auto it = indices.begin(); it != indices.end(); ++it) {
|
if ((previous_material_id != current_material_id && num_triangles > 0) || (it == indices.end())) {
|
||||||
const auto& idx = *it;
|
COLLADASW::Triangles triangles(mSW);
|
||||||
if (!normals.empty()) {
|
triangles.setMaterial(collada_id(previous_material_id == -1
|
||||||
triangles.appendValues(idx, idx);
|
? default_material_name
|
||||||
} else {
|
: materials[previous_material_id]->Name()));
|
||||||
triangles.appendValues(idx);
|
triangles.setCount(num_triangles);
|
||||||
|
int offset = 0;
|
||||||
|
triangles.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::VERTEX,"#" + mesh_id + COLLADASW::LibraryGeometries::VERTICES_ID_SUFFIX, offset++ ) );
|
||||||
|
if (has_normals) {
|
||||||
|
triangles.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::NORMAL,"#" + mesh_id + COLLADASW::LibraryGeometries::NORMALS_SOURCE_ID_SUFFIX, offset++ ) );
|
||||||
|
}
|
||||||
|
triangles.prepareToAppendValues();
|
||||||
|
for (std::vector<int>::const_iterator jt = index_range_start; jt != it; ++jt) {
|
||||||
|
const int idx = *jt;
|
||||||
|
if (has_normals) {
|
||||||
|
triangles.appendValues(idx, idx);
|
||||||
|
} else {
|
||||||
|
triangles.appendValues(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
triangles.finish();
|
||||||
|
index_range_start = it;
|
||||||
|
}
|
||||||
|
previous_material_id = current_material_id;
|
||||||
|
if (it == indices.end()) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
triangles.finish();
|
|
||||||
|
|
||||||
closeMesh();
|
closeMesh();
|
||||||
closeGeometry();
|
closeGeometry();
|
||||||
@@ -76,7 +111,7 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::close() {
|
|||||||
closeLibrary();
|
closeLibrary();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaSerializer::ColladaExporter::ColladaScene::add(const std::string& node_id, const std::string& node_name, const std::string& geom_id, const std::string& material_id, 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<float>& matrix) {
|
||||||
if (!scene_opened) {
|
if (!scene_opened) {
|
||||||
openVisualScene(scene_id);
|
openVisualScene(scene_id);
|
||||||
scene_opened = true;
|
scene_opened = true;
|
||||||
@@ -85,7 +120,7 @@ void ColladaSerializer::ColladaExporter::ColladaScene::add(const std::string& no
|
|||||||
COLLADASW::Node node(mSW);
|
COLLADASW::Node node(mSW);
|
||||||
node.setNodeId(node_id);
|
node.setNodeId(node_id);
|
||||||
node.setNodeName(node_name);
|
node.setNodeName(node_name);
|
||||||
node.setType(COLLADASW::Node::DEFAULT);
|
node.setType(COLLADASW::Node::NODE);
|
||||||
|
|
||||||
// The matrix attribute of an entity is basically a 4x3 representation of its ObjectPlacement.
|
// The matrix attribute of an entity is basically a 4x3 representation of its ObjectPlacement.
|
||||||
// Note that this placement is absolute, ie it is multiplied with all parent placements.
|
// Note that this placement is absolute, ie it is multiplied with all parent placements.
|
||||||
@@ -98,11 +133,12 @@ void ColladaSerializer::ColladaExporter::ColladaScene::add(const std::string& no
|
|||||||
|
|
||||||
node.start();
|
node.start();
|
||||||
node.addMatrix(matrix_array);
|
node.addMatrix(matrix_array);
|
||||||
|
|
||||||
COLLADASW::InstanceGeometry instanceGeometry(mSW);
|
COLLADASW::InstanceGeometry instanceGeometry(mSW);
|
||||||
instanceGeometry.setUrl ("#" + geom_id);
|
instanceGeometry.setUrl ("#" + geom_name);
|
||||||
COLLADASW::InstanceMaterial material ("ColorMaterial", "#" + material_id);
|
for (std::vector<std::string>::const_iterator it = material_ids.begin(); it != material_ids.end(); ++it) {
|
||||||
instanceGeometry.getBindMaterial().getInstanceMaterialList().push_back(material);
|
COLLADASW::InstanceMaterial material (*it, "#" + *it);
|
||||||
|
instanceGeometry.getBindMaterial().getInstanceMaterialList().push_back(material);
|
||||||
|
}
|
||||||
instanceGeometry.add();
|
instanceGeometry.add();
|
||||||
node.end();
|
node.end();
|
||||||
}
|
}
|
||||||
@@ -117,36 +153,50 @@ void ColladaSerializer::ColladaExporter::ColladaScene::write() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::write(const SurfaceStyle& style) {
|
void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::write(const IfcGeom::SurfaceStyle* style) {
|
||||||
openEffect(style.Name() + "-fx");
|
openEffect(collada_id(style->Name()) + "-fx");
|
||||||
COLLADASW::EffectProfile effect(mSW);
|
COLLADASW::EffectProfile effect(mSW);
|
||||||
effect.setShaderType(COLLADASW::EffectProfile::LAMBERT);
|
effect.setShaderType(COLLADASW::EffectProfile::LAMBERT);
|
||||||
effect.setDiffuse(COLLADASW::ColorOrTexture(COLLADASW::Color(style.Diffuse().R(),style.Diffuse().G(),style.Diffuse().B())));
|
if (style->Diffuse()) {
|
||||||
|
const IfcGeom::SurfaceStyle::ColorComponent& diffuse = *style->Diffuse();
|
||||||
|
effect.setDiffuse(COLLADASW::ColorOrTexture(COLLADASW::Color(diffuse.R(),diffuse.G(),diffuse.B())));
|
||||||
|
}
|
||||||
|
if (style->Specular()) {
|
||||||
|
const IfcGeom::SurfaceStyle::ColorComponent& specular = *style->Specular();
|
||||||
|
effect.setSpecular(COLLADASW::ColorOrTexture(COLLADASW::Color(specular.R(),specular.G(),specular.B())));
|
||||||
|
}
|
||||||
|
if (style->Specularity()) {
|
||||||
|
effect.setShininess(*style->Specularity());
|
||||||
|
}
|
||||||
|
if (style->Transparency()) {
|
||||||
|
const double transparency = *style->Transparency();
|
||||||
|
if (transparency > 0) {
|
||||||
|
effect.setTransparency(transparency);
|
||||||
|
}
|
||||||
|
}
|
||||||
addEffectProfile(effect);
|
addEffectProfile(effect);
|
||||||
|
closeEffect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::close() {
|
void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::close() {
|
||||||
closeLibrary();
|
closeLibrary();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaSerializer::ColladaExporter::ColladaMaterials::add(const SurfaceStyle& style) {
|
void ColladaSerializer::ColladaExporter::ColladaMaterials::add(const IfcGeom::SurfaceStyle* style) {
|
||||||
if (!contains(style.Name())) {
|
if (!contains(style)) {
|
||||||
effects.write(style);
|
effects.write(style);
|
||||||
surface_styles.push_back(style);
|
surface_styles.push_back(style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ColladaSerializer::ColladaExporter::ColladaMaterials::contains(const std::string& name) {
|
bool ColladaSerializer::ColladaExporter::ColladaMaterials::contains(const IfcGeom::SurfaceStyle* style) {
|
||||||
for (auto it = surface_styles.begin(); it != surface_styles.end(); ++it) {
|
return std::find(surface_styles.begin(), surface_styles.end(), style) != surface_styles.end();
|
||||||
if (it->Name() == name) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaSerializer::ColladaExporter::ColladaMaterials::write() {
|
void ColladaSerializer::ColladaExporter::ColladaMaterials::write() {
|
||||||
effects.close();
|
effects.close();
|
||||||
for (auto it = surface_styles.begin(); it != surface_styles.end(); ++it) {
|
for (auto it = surface_styles.begin(); it != surface_styles.end(); ++it) {
|
||||||
const std::string& material_name = it->Name();
|
const std::string& material_name = collada_id((*it)->Name());
|
||||||
openMaterial(material_name);
|
openMaterial(material_name);
|
||||||
addInstanceEffect("#" + material_name + "-fx");
|
addInstanceEffect("#" + material_name + "-fx");
|
||||||
closeLibrary();
|
closeLibrary();
|
||||||
@@ -164,9 +214,34 @@ void ColladaSerializer::ColladaExporter::startDocument() {
|
|||||||
asset.add();
|
asset.add();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaSerializer::ColladaExporter::writeTesselated(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) {
|
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<const IfcGeom::SurfaceStyle*>& _materials) {
|
||||||
if (!materials.contains(type)) materials.add(GetDefaultMaterial(type));
|
const IfcGeom::SurfaceStyle* default_for_type = IfcGeom::get_default_style(type);
|
||||||
deferreds.push_back(DeferedObject(type, obj_id, matrix, vertices, normals, indices));
|
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<const IfcGeom::SurfaceStyle*>::const_iterator it = _materials.begin(); it != _materials.end(); ++it) {
|
||||||
|
const IfcGeom::SurfaceStyle* const surface_style_pointer = *it;
|
||||||
|
if (!materials.contains(surface_style_pointer)) {
|
||||||
|
materials.add(surface_style_pointer);
|
||||||
|
}
|
||||||
|
material_references.push_back(collada_id(surface_style_pointer->Name()));
|
||||||
|
}
|
||||||
|
deferreds.push_back(DeferredObject(guid, name, type, obj_id, matrix, vertices, normals, indices, material_ids, _materials, material_references));
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string ColladaSerializer::ColladaExporter::DeferredObject::Name() const {
|
||||||
|
std::stringstream ss;
|
||||||
|
if (!this->name.empty()) {
|
||||||
|
ss << this->obj_id << "_" << this->name;
|
||||||
|
} else {
|
||||||
|
ss << this->guid;
|
||||||
|
}
|
||||||
|
return collada_id(ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaSerializer::ColladaExporter::endDocument() {
|
void ColladaSerializer::ColladaExporter::endDocument() {
|
||||||
@@ -174,15 +249,13 @@ void ColladaSerializer::ColladaExporter::endDocument() {
|
|||||||
// only at this point all objects are written to the stream.
|
// only at this point all objects are written to the stream.
|
||||||
materials.write();
|
materials.write();
|
||||||
for (auto it = deferreds.begin(); it != deferreds.end(); ++it) {
|
for (auto it = deferreds.begin(); it != deferreds.end(); ++it) {
|
||||||
std::stringstream ss; ss << "object" << it->obj_id;
|
const std::string object_name = it->Name();
|
||||||
const std::string object_id = ss.str();
|
geometries.write(object_name, it->type, it->vertices, it->normals, it->indices, it->material_ids, it->materials);
|
||||||
geometries.write(object_id, it->vertices, it->normals, it->indices);
|
|
||||||
}
|
}
|
||||||
geometries.close();
|
geometries.close();
|
||||||
for (auto it = deferreds.begin(); it != deferreds.end(); ++it) {
|
for (auto it = deferreds.begin(); it != deferreds.end(); ++it) {
|
||||||
std::stringstream ss; ss << "object" << it->obj_id;
|
const std::string object_name = it->Name();
|
||||||
const std::string object_id = ss.str();
|
scene.add(object_name, object_name, object_name, it->material_references, it->matrix);
|
||||||
scene.add(object_id, object_id, object_id, it->type, it->matrix);
|
|
||||||
}
|
}
|
||||||
scene.write();
|
scene.write();
|
||||||
stream.endDocument();
|
stream.endDocument();
|
||||||
@@ -197,7 +270,7 @@ void ColladaSerializer::writeHeader() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ColladaSerializer::writeTesselated(const IfcGeomObjects::IfcGeomObject* o) {
|
void ColladaSerializer::writeTesselated(const IfcGeomObjects::IfcGeomObject* o) {
|
||||||
exporter.writeTesselated(o->type, o->id, o->matrix, o->mesh->verts, o->mesh->normals, o->mesh->faces);
|
exporter.writeTesselated(o->guid, o->name, o->type, o->id, o->matrix, o->mesh->verts, o->mesh->normals, o->mesh->faces, o->mesh->materials, o->mesh->surface_styles);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaSerializer::finalize() {
|
void ColladaSerializer::finalize() {
|
||||||
|
|||||||
@@ -36,7 +36,6 @@
|
|||||||
#include "../ifcgeom/IfcGeomObjects.h"
|
#include "../ifcgeom/IfcGeomObjects.h"
|
||||||
|
|
||||||
#include "../ifcconvert/GeometrySerializer.h"
|
#include "../ifcconvert/GeometrySerializer.h"
|
||||||
#include "../ifcconvert/SurfaceStyle.h"
|
|
||||||
|
|
||||||
class ColladaSerializer : public GeometrySerializer
|
class ColladaSerializer : public GeometrySerializer
|
||||||
{
|
{
|
||||||
@@ -51,7 +50,7 @@ private:
|
|||||||
: COLLADASW::LibraryGeometries(&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 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::vector<float>& positions, const std::vector<float>& normals, const std::vector<int>& indices);
|
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<const IfcGeom::SurfaceStyle*>& materials);
|
||||||
void close();
|
void close();
|
||||||
};
|
};
|
||||||
class ColladaScene : public COLLADASW::LibraryVisualScenes
|
class ColladaScene : public COLLADASW::LibraryVisualScenes
|
||||||
@@ -65,7 +64,7 @@ private:
|
|||||||
, scene_id(scene_id)
|
, scene_id(scene_id)
|
||||||
, scene_opened(false)
|
, scene_opened(false)
|
||||||
{}
|
{}
|
||||||
void add(const std::string& node_id, const std::string& node_name, const std::string& geom_id, const std::string& material_id, 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<float>& matrix);
|
||||||
void write();
|
void write();
|
||||||
};
|
};
|
||||||
class ColladaMaterials : public COLLADASW::LibraryMaterials
|
class ColladaMaterials : public COLLADASW::LibraryMaterials
|
||||||
@@ -77,37 +76,47 @@ private:
|
|||||||
explicit ColladaEffects(COLLADASW::StreamWriter& stream)
|
explicit ColladaEffects(COLLADASW::StreamWriter& stream)
|
||||||
: COLLADASW::LibraryEffects(&stream)
|
: COLLADASW::LibraryEffects(&stream)
|
||||||
{}
|
{}
|
||||||
void write(const SurfaceStyle& style);
|
void write(const IfcGeom::SurfaceStyle* style);
|
||||||
void close();
|
void close();
|
||||||
};
|
};
|
||||||
std::vector<SurfaceStyle> surface_styles;
|
std::vector<const IfcGeom::SurfaceStyle*> surface_styles;
|
||||||
ColladaEffects effects;
|
ColladaEffects effects;
|
||||||
public:
|
public:
|
||||||
explicit ColladaMaterials(COLLADASW::StreamWriter& stream)
|
explicit ColladaMaterials(COLLADASW::StreamWriter& stream)
|
||||||
: COLLADASW::LibraryMaterials(&stream)
|
: COLLADASW::LibraryMaterials(&stream)
|
||||||
, effects(stream)
|
, effects(stream)
|
||||||
{}
|
{}
|
||||||
void add(const SurfaceStyle& style);
|
void add(const IfcGeom::SurfaceStyle* style);
|
||||||
bool contains(const std::string& name);
|
bool contains(const IfcGeom::SurfaceStyle* style);
|
||||||
void write();
|
void write();
|
||||||
};
|
};
|
||||||
class DeferedObject {
|
class DeferredObject {
|
||||||
public:
|
public:
|
||||||
const std::string type;
|
const std::string guid, name, type;
|
||||||
int obj_id;
|
int obj_id;
|
||||||
const std::vector<float> matrix;
|
const std::vector<float> matrix;
|
||||||
const std::vector<float> vertices;
|
const std::vector<float> vertices;
|
||||||
const std::vector<float> normals;
|
const std::vector<float> normals;
|
||||||
const std::vector<int> indices;
|
const std::vector<int> indices;
|
||||||
DeferedObject(const std::string& type, int obj_id, const std::vector<float>& matrix, const std::vector<float>& vertices,
|
const std::vector<int> material_ids;
|
||||||
const std::vector<float>& normals, const std::vector<int>& indices)
|
const std::vector<const IfcGeom::SurfaceStyle*> materials;
|
||||||
: type(type)
|
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<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<const IfcGeom::SurfaceStyle*>& materials, const std::vector<std::string>& material_references)
|
||||||
|
: guid(guid)
|
||||||
|
, name(name)
|
||||||
|
, type(type)
|
||||||
, obj_id(obj_id)
|
, obj_id(obj_id)
|
||||||
, matrix(matrix)
|
, matrix(matrix)
|
||||||
, vertices(vertices)
|
, vertices(vertices)
|
||||||
, normals(normals)
|
, normals(normals)
|
||||||
, indices(indices)
|
, indices(indices)
|
||||||
|
, material_ids(material_ids)
|
||||||
|
, materials(materials)
|
||||||
|
, material_references(material_references)
|
||||||
{}
|
{}
|
||||||
|
const std::string Name() const;
|
||||||
};
|
};
|
||||||
COLLADABU::NativeString filename;
|
COLLADABU::NativeString filename;
|
||||||
COLLADASW::StreamWriter stream;
|
COLLADASW::StreamWriter stream;
|
||||||
@@ -122,10 +131,10 @@ private:
|
|||||||
, scene(scene_name, stream)
|
, scene(scene_name, stream)
|
||||||
, materials(stream)
|
, materials(stream)
|
||||||
{}
|
{}
|
||||||
std::vector<DeferedObject> deferreds;
|
std::vector<DeferredObject> deferreds;
|
||||||
virtual ~ColladaExporter() {}
|
virtual ~ColladaExporter() {}
|
||||||
void startDocument();
|
void startDocument();
|
||||||
void writeTesselated(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);
|
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<const IfcGeom::SurfaceStyle*>& materials);
|
||||||
void endDocument();
|
void endDocument();
|
||||||
};
|
};
|
||||||
ColladaExporter exporter;
|
ColladaExporter exporter;
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
|
|
||||||
#include "../ifcgeom/IfcGeomObjects.h"
|
#include "../ifcgeom/IfcGeomObjects.h"
|
||||||
|
|
||||||
#include "../ifcconvert/SurfaceStyle.h"
|
|
||||||
#include "../ifcconvert/ColladaSerializer.h"
|
#include "../ifcconvert/ColladaSerializer.h"
|
||||||
#include "../ifcconvert/IgesSerializer.h"
|
#include "../ifcconvert/IgesSerializer.h"
|
||||||
#include "../ifcconvert/StepSerializer.h"
|
#include "../ifcconvert/StepSerializer.h"
|
||||||
@@ -271,18 +270,4 @@ int main(int argc, char** argv) {
|
|||||||
time(&end);
|
time(&end);
|
||||||
int dif = (int) difftime (end,start);
|
int dif = (int) difftime (end,start);
|
||||||
printf ("\nConversion took %d seconds\n", dif );
|
printf ("\nConversion took %d seconds\n", dif );
|
||||||
}
|
}
|
||||||
|
|
||||||
SurfaceStyle GetDefaultMaterial(const std::string& s) {
|
|
||||||
if (s == "IfcSite" ) { return SurfaceStyle("IfcSite", 0.75,0.8,0.65); }
|
|
||||||
if (s == "IfcSlab" ) { return SurfaceStyle("IfcSlab", 0.4, 0.4,0.4 ); }
|
|
||||||
if (s == "IfcWallStandardCase") { return SurfaceStyle("IfcWallStandardCase",0.9, 0.9,0.9 ); }
|
|
||||||
if (s == "IfcWall" ) { return SurfaceStyle("IfcWall", 0.9, 0.9,0.9 ); }
|
|
||||||
if (s == "IfcWindow" ) { return SurfaceStyle("IfcWindow", 0.75,0.8,0.75, 1.0,1.0,1.0, 0.0,0.0,0.0, 500.0, 0.3); }
|
|
||||||
if (s == "IfcDoor" ) { return SurfaceStyle("IfcDoor", 0.55,0.3,0.15); }
|
|
||||||
if (s == "IfcBeam" ) { return SurfaceStyle("IfcBeam", 0.75,0.7,0.7 ); }
|
|
||||||
if (s == "IfcRailing" ) { return SurfaceStyle("IfcRailing", 0.65,0.6,0.6 ); }
|
|
||||||
if (s == "IfcMember" ) { return SurfaceStyle("IfcMember", 0.65,0.6,0.6 ); }
|
|
||||||
if (s == "IfcPlate" ) { return SurfaceStyle("IfcPlate", 0.8, 0.8,0.8 ); }
|
|
||||||
return SurfaceStyle(s);
|
|
||||||
}
|
|
||||||
@@ -35,10 +35,10 @@ bool OpenCascadeBasedSerializer::ready() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OpenCascadeBasedSerializer::writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o) {
|
void OpenCascadeBasedSerializer::writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o) {
|
||||||
for (IfcGeom::ShapeList::const_iterator it = o->mesh->begin(); it != o->mesh->end(); ++ it) {
|
for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = o->mesh->begin(); it != o->mesh->end(); ++ it) {
|
||||||
gp_GTrsf gtrsf = *it->first;
|
gp_GTrsf gtrsf = it->Placement();
|
||||||
gtrsf.PreMultiply(o->trsf);
|
gtrsf.PreMultiply(o->trsf);
|
||||||
const TopoDS_Shape& s = *it->second;
|
const TopoDS_Shape& s = it->Shape();
|
||||||
|
|
||||||
bool trsf_valid = false;
|
bool trsf_valid = false;
|
||||||
gp_Trsf trsf;
|
gp_Trsf trsf;
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
#include "../ifcgeom/IfcGeomObjects.h"
|
#include "../ifcgeom/IfcGeomObjects.h"
|
||||||
|
|
||||||
#include "../ifcconvert/GeometrySerializer.h"
|
#include "../ifcconvert/GeometrySerializer.h"
|
||||||
#include "../ifcconvert/SurfaceStyle.h"
|
|
||||||
|
|
||||||
class OpenCascadeBasedSerializer : public GeometrySerializer {
|
class OpenCascadeBasedSerializer : public GeometrySerializer {
|
||||||
protected:
|
protected:
|
||||||
@@ -35,7 +34,7 @@ public:
|
|||||||
{}
|
{}
|
||||||
virtual ~OpenCascadeBasedSerializer() {}
|
virtual ~OpenCascadeBasedSerializer() {}
|
||||||
void writeHeader() {}
|
void writeHeader() {}
|
||||||
void writeMaterial(const SurfaceStyle& style) {}
|
void writeMaterial(const IfcGeom::SurfaceStyle& style) {}
|
||||||
bool ready();
|
bool ready();
|
||||||
virtual void writeShape(const TopoDS_Shape& shape) = 0;
|
virtual void writeShape(const TopoDS_Shape& shape) = 0;
|
||||||
void writeTesselated(const IfcGeomObjects::IfcGeomObject* o) {}
|
void writeTesselated(const IfcGeomObjects::IfcGeomObject* o) {}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
* *
|
* *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
#include "../ifcconvert/SurfaceStyle.h"
|
#include "../ifcgeom/IfcGeomRenderStyles.h"
|
||||||
|
|
||||||
#include "WavefrontOBJSerializer.h"
|
#include "WavefrontOBJSerializer.h"
|
||||||
|
|
||||||
@@ -41,40 +41,69 @@ void WaveFrontOBJSerializer::writeHeader() {
|
|||||||
mtl_stream << "# File generated by IfcOpenShell " << IFCOPENSHELL_VERSION << std::endl;
|
mtl_stream << "# File generated by IfcOpenShell " << IFCOPENSHELL_VERSION << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaveFrontOBJSerializer::writeMaterial(const SurfaceStyle& style) {
|
void WaveFrontOBJSerializer::writeMaterial(const IfcGeom::SurfaceStyle& style) {
|
||||||
mtl_stream << "newmtl " << style.Name() << std::endl
|
mtl_stream << "newmtl " << style.Name() << std::endl;
|
||||||
<< "Kd " << style.Diffuse().R() << " " << style.Diffuse().G() << " " << style.Diffuse().B() << std::endl
|
if (style.Diffuse()) {
|
||||||
<< "Ks " << style.Specular().R() << " " << style.Specular().G() << " " << style.Specular().B() << std::endl
|
const IfcGeom::SurfaceStyle::ColorComponent& diffuse = *style.Diffuse();
|
||||||
<< "Ka " << style.Ambient().R() << " " << style.Ambient().G() << " " << style.Ambient().B() << std::endl
|
mtl_stream << "Kd " << diffuse.R() << " " << diffuse.G() << " " << diffuse.B() << std::endl;
|
||||||
<< "Ns " << style.Specularity() << std::endl
|
}
|
||||||
<< "Tr " << style.Transparency() << std::endl
|
if (style.Specular()) {
|
||||||
<< "d " << style.Transparency() << std::endl
|
const IfcGeom::SurfaceStyle::ColorComponent& specular = *style.Specular();
|
||||||
<< "D " << style.Transparency() << std::endl;
|
mtl_stream << "Ks " << specular.R() << " " << specular.G() << " " << specular.B() << std::endl;
|
||||||
|
}
|
||||||
|
if (style.Specularity()) {
|
||||||
|
mtl_stream << "Ns " << (*style.Specularity()) << std::endl;
|
||||||
|
}
|
||||||
|
if (style.Transparency()) {
|
||||||
|
const double transparency = 1.0 - *style.Transparency();
|
||||||
|
if (transparency < 1) {
|
||||||
|
mtl_stream << "Tr " << transparency << std::endl;
|
||||||
|
mtl_stream << "d " << transparency << std::endl;
|
||||||
|
mtl_stream << "D " << transparency << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaveFrontOBJSerializer::writeTesselated(const IfcGeomObjects::IfcGeomObject* o) {
|
void WaveFrontOBJSerializer::writeTesselated(const IfcGeomObjects::IfcGeomObject* o) {
|
||||||
const std::string name = o->name.empty() ? o->guid : o->name;
|
const std::string name = o->name.empty() ? o->guid : o->name;
|
||||||
obj_stream << "g " << name << std::endl;
|
obj_stream << "g " << name << std::endl;
|
||||||
obj_stream << "s 1" << std::endl;
|
obj_stream << "s 1" << std::endl;
|
||||||
obj_stream << "usemtl " << o->type << std::endl;
|
|
||||||
if (materials.find(o->type) == materials.end()) {
|
|
||||||
writeMaterial(GetDefaultMaterial(o->type));
|
|
||||||
materials.insert(o->type);
|
|
||||||
}
|
|
||||||
const int vcount = o->mesh->verts.size() / 3;
|
const int vcount = o->mesh->verts.size() / 3;
|
||||||
for ( IfcGeomObjects::FltIt it = o->mesh->verts.begin(); it != o->mesh->verts.end(); ) {
|
for ( std::vector<float>::const_iterator it = o->mesh->verts.begin(); it != o->mesh->verts.end(); ) {
|
||||||
const double x = *(it++);
|
const double x = *(it++);
|
||||||
const double y = *(it++);
|
const double y = *(it++);
|
||||||
const double z = *(it++);
|
const double z = *(it++);
|
||||||
obj_stream << "v " << x << " " << y << " " << z << std::endl;
|
obj_stream << "v " << x << " " << y << " " << z << std::endl;
|
||||||
}
|
}
|
||||||
for ( IfcGeomObjects::FltIt it = o->mesh->normals.begin(); it != o->mesh->normals.end(); ) {
|
for ( std::vector<float>::const_iterator it = o->mesh->normals.begin(); it != o->mesh->normals.end(); ) {
|
||||||
const double x = *(it++);
|
const double x = *(it++);
|
||||||
const double y = *(it++);
|
const double y = *(it++);
|
||||||
const double z = *(it++);
|
const double z = *(it++);
|
||||||
obj_stream << "vn " << x << " " << y << " " << z << std::endl;
|
obj_stream << "vn " << x << " " << y << " " << z << std::endl;
|
||||||
}
|
}
|
||||||
for ( IfcGeomObjects::IntIt it = o->mesh->faces.begin(); it != o->mesh->faces.end(); ) {
|
|
||||||
|
int previous_material_id = -2;
|
||||||
|
std::vector<int>::const_iterator material_it = o->mesh->materials.begin();
|
||||||
|
|
||||||
|
for ( std::vector<int>::const_iterator it = o->mesh->faces.begin(); it != o->mesh->faces.end(); ) {
|
||||||
|
|
||||||
|
const int material_id = *(material_it++);
|
||||||
|
if (material_id != previous_material_id) {
|
||||||
|
const IfcGeom::SurfaceStyle* material_style = 0;
|
||||||
|
if (material_id >= 0) {
|
||||||
|
material_style = o->mesh->surface_styles[material_id];
|
||||||
|
} else {
|
||||||
|
material_style = IfcGeom::get_default_style(o->type);
|
||||||
|
}
|
||||||
|
const std::string material_name = material_style->Name();
|
||||||
|
obj_stream << "usemtl " << material_name << std::endl;
|
||||||
|
if (materials.find(material_name) == materials.end()) {
|
||||||
|
writeMaterial(*material_style);
|
||||||
|
materials.insert(material_name);
|
||||||
|
}
|
||||||
|
previous_material_id = material_id;
|
||||||
|
}
|
||||||
|
|
||||||
const int v1 = *(it++)+vcount_total;
|
const int v1 = *(it++)+vcount_total;
|
||||||
const int v2 = *(it++)+vcount_total;
|
const int v2 = *(it++)+vcount_total;
|
||||||
const int v3 = *(it++)+vcount_total;
|
const int v3 = *(it++)+vcount_total;
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include "../ifcconvert/GeometrySerializer.h"
|
#include "../ifcconvert/GeometrySerializer.h"
|
||||||
#include "../ifcconvert/SurfaceStyle.h"
|
|
||||||
|
|
||||||
class WaveFrontOBJSerializer : public GeometrySerializer {
|
class WaveFrontOBJSerializer : public GeometrySerializer {
|
||||||
private:
|
private:
|
||||||
@@ -45,7 +44,7 @@ public:
|
|||||||
virtual ~WaveFrontOBJSerializer() {}
|
virtual ~WaveFrontOBJSerializer() {}
|
||||||
bool ready();
|
bool ready();
|
||||||
void writeHeader();
|
void writeHeader();
|
||||||
void writeMaterial(const SurfaceStyle& style);
|
void writeMaterial(const IfcGeom::SurfaceStyle& style);
|
||||||
void writeTesselated(const IfcGeomObjects::IfcGeomObject* o);
|
void writeTesselated(const IfcGeomObjects::IfcGeomObject* o);
|
||||||
void writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o) {}
|
void writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o) {}
|
||||||
void finalize() {}
|
void finalize() {}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
#include "../ifcparse/IfcParse.h"
|
#include "../ifcparse/IfcParse.h"
|
||||||
#include "../ifcparse/IfcUtil.h"
|
#include "../ifcparse/IfcUtil.h"
|
||||||
|
|
||||||
#include "../ifcgeom/IfcShapeList.h"
|
#include "../ifcgeom/IfcRepresentationShapeItem.h"
|
||||||
|
|
||||||
namespace IfcGeom {
|
namespace IfcGeom {
|
||||||
|
|
||||||
@@ -76,14 +76,15 @@ namespace IfcGeom {
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face);
|
bool convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face);
|
||||||
bool convert_shapes(const IfcUtil::IfcBaseClass* L, ShapeList& result);
|
bool convert_shapes(const IfcUtil::IfcBaseClass* L, IfcRepresentationShapeItems& result);
|
||||||
bool is_shape_collection(const IfcUtil::IfcBaseClass* L);
|
bool is_shape_collection(const IfcUtil::IfcBaseClass* L);
|
||||||
const TopoDS_Shape* convert_shape(const IfcUtil::IfcBaseClass* L, TopoDS_Shape& result);
|
bool convert_shape(const IfcUtil::IfcBaseClass* L, TopoDS_Shape& result);
|
||||||
bool convert_wire(const IfcUtil::IfcBaseClass* L, TopoDS_Wire& result);
|
bool convert_wire(const IfcUtil::IfcBaseClass* L, TopoDS_Wire& result);
|
||||||
bool convert_curve(const IfcUtil::IfcBaseClass* L, Handle(Geom_Curve)& result);
|
bool convert_curve(const IfcUtil::IfcBaseClass* L, Handle(Geom_Curve)& result);
|
||||||
bool convert_face(const IfcUtil::IfcBaseClass* L, TopoDS_Face& result);
|
bool convert_face(const IfcUtil::IfcBaseClass* L, TopoDS_Face& result);
|
||||||
bool convert_openings(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x3::IfcRelVoidsElement::list& openings, const ShapeList& entity_shapes, const gp_Trsf& entity_trsf, ShapeList& cut_shapes);
|
bool convert_openings(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x3::IfcRelVoidsElement::list& openings, const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes);
|
||||||
bool convert_openings_fast(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x3::IfcRelVoidsElement::list& openings, const ShapeList& entity_shapes, const gp_Trsf& entity_trsf, ShapeList& cut_shapes);
|
bool convert_openings_fast(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x3::IfcRelVoidsElement::list& openings, const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes);
|
||||||
|
Ifc2x3::IfcSurfaceStyleShading* get_surface_style(Ifc2x3::IfcRepresentationItem* item);
|
||||||
bool create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& solid);
|
bool create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& solid);
|
||||||
bool is_compound(const TopoDS_Shape& shape);
|
bool is_compound(const TopoDS_Shape& shape);
|
||||||
bool is_convex(const TopoDS_Wire& wire);
|
bool is_convex(const TopoDS_Wire& wire);
|
||||||
@@ -97,6 +98,8 @@ namespace IfcGeom {
|
|||||||
void SetValue(GeomValue var, double value);
|
void SetValue(GeomValue var, double value);
|
||||||
double GetValue(GeomValue var);
|
double GetValue(GeomValue var);
|
||||||
Ifc2x3::IfcProductDefinitionShape* tesselate(TopoDS_Shape& shape, double deflection, IfcEntities es);
|
Ifc2x3::IfcProductDefinitionShape* tesselate(TopoDS_Shape& shape, double deflection, IfcEntities es);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Cache {
|
namespace Cache {
|
||||||
void Purge();
|
void Purge();
|
||||||
|
|||||||
@@ -131,9 +131,9 @@ const TopoDS_Shape& IfcGeom::ensure_fit_for_subtraction(const TopoDS_Shape& shap
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool IfcGeom::convert_openings(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x3::IfcRelVoidsElement::list& openings,
|
bool IfcGeom::convert_openings(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x3::IfcRelVoidsElement::list& openings,
|
||||||
const ShapeList& entity_shapes, const gp_Trsf& entity_trsf, ShapeList& cut_shapes) {
|
const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes) {
|
||||||
// Iterate over IfcOpeningElements
|
// Iterate over IfcOpeningElements
|
||||||
IfcGeom::ShapeList opening_shapes;
|
IfcGeom::IfcRepresentationShapeItems opening_shapes;
|
||||||
unsigned int last_size = 0;
|
unsigned int last_size = 0;
|
||||||
for ( Ifc2x3::IfcRelVoidsElement::it it = openings->begin(); it != openings->end(); ++ it ) {
|
for ( Ifc2x3::IfcRelVoidsElement::it it = openings->begin(); it != openings->end(); ++ it ) {
|
||||||
Ifc2x3::IfcRelVoidsElement::ptr v = *it;
|
Ifc2x3::IfcRelVoidsElement::ptr v = *it;
|
||||||
@@ -156,17 +156,17 @@ bool IfcGeom::convert_openings(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x
|
|||||||
|
|
||||||
const unsigned int current_size = (const unsigned int) opening_shapes.size();
|
const unsigned int current_size = (const unsigned int) opening_shapes.size();
|
||||||
for ( unsigned int i = last_size; i < current_size; ++ i ) {
|
for ( unsigned int i = last_size; i < current_size; ++ i ) {
|
||||||
opening_shapes[i].first->PreMultiply(opening_trsf);
|
opening_shapes[i].move(opening_trsf);
|
||||||
}
|
}
|
||||||
last_size = current_size;
|
last_size = current_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate over the shapes of the IfcProduct
|
// Iterate over the shapes of the IfcProduct
|
||||||
for ( IfcGeom::ShapeList::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) {
|
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) {
|
||||||
TopoDS_Shape entity_shape_solid;
|
TopoDS_Shape entity_shape_solid;
|
||||||
const TopoDS_Shape& entity_shape_unlocated = IfcGeom::ensure_fit_for_subtraction(*(it3->second),entity_shape_solid);
|
const TopoDS_Shape& entity_shape_unlocated = IfcGeom::ensure_fit_for_subtraction(it3->Shape(),entity_shape_solid);
|
||||||
const gp_GTrsf& entity_shape_gtrsf = *(it3->first);
|
const gp_GTrsf& entity_shape_gtrsf = it3->Placement();
|
||||||
TopoDS_Shape entity_shape;
|
TopoDS_Shape entity_shape;
|
||||||
if ( entity_shape_gtrsf.Form() == gp_Other ) {
|
if ( entity_shape_gtrsf.Form() == gp_Other ) {
|
||||||
Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to:",entity->entity);
|
Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to:",entity->entity);
|
||||||
@@ -176,10 +176,10 @@ bool IfcGeom::convert_openings(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Iterate over the shapes of the IfcOpeningElements
|
// Iterate over the shapes of the IfcOpeningElements
|
||||||
for ( IfcGeom::ShapeList::const_iterator it4 = opening_shapes.begin(); it4 != opening_shapes.end(); ++ it4 ) {
|
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it4 = opening_shapes.begin(); it4 != opening_shapes.end(); ++ it4 ) {
|
||||||
TopoDS_Shape opening_shape_solid;
|
TopoDS_Shape opening_shape_solid;
|
||||||
const TopoDS_Shape& opening_shape_unlocated = IfcGeom::ensure_fit_for_subtraction(*(it4->second),opening_shape_solid);
|
const TopoDS_Shape& opening_shape_unlocated = IfcGeom::ensure_fit_for_subtraction(it4->Shape(),opening_shape_solid);
|
||||||
const gp_GTrsf& opening_shape_gtrsf = *(it4->first);
|
const gp_GTrsf& opening_shape_gtrsf = it4->Placement();
|
||||||
if ( opening_shape_gtrsf.Form() == gp_Other ) {
|
if ( opening_shape_gtrsf.Form() == gp_Other ) {
|
||||||
Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to opening of:",entity->entity);
|
Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to opening of:",entity->entity);
|
||||||
}
|
}
|
||||||
@@ -218,19 +218,14 @@ bool IfcGeom::convert_openings(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
cut_shapes.push_back(IfcGeom::LocationShape(new gp_GTrsf(),new TopoDS_Shape(entity_shape)));
|
cut_shapes.push_back(IfcGeom::IfcRepresentationShapeItem(entity_shape, &it3->Style()));
|
||||||
}
|
|
||||||
|
|
||||||
// Delete references to opening transformations, but keep shapes in the cache
|
|
||||||
for ( IfcGeom::ShapeList::const_iterator it5 = opening_shapes.begin(); it5 != opening_shapes.end(); ++ it5 ) {
|
|
||||||
delete it5->first;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IfcGeom::convert_openings_fast(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x3::IfcRelVoidsElement::list& openings,
|
bool IfcGeom::convert_openings_fast(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x3::IfcRelVoidsElement::list& openings,
|
||||||
const ShapeList& entity_shapes, const gp_Trsf& entity_trsf, ShapeList& cut_shapes) {
|
const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes) {
|
||||||
|
|
||||||
// Create a compound of all opening shapes in order to speed up the boolean operations
|
// Create a compound of all opening shapes in order to speed up the boolean operations
|
||||||
TopoDS_Compound opening_compound;
|
TopoDS_Compound opening_compound;
|
||||||
@@ -252,32 +247,29 @@ bool IfcGeom::convert_openings_fast(const Ifc2x3::IfcProduct::ptr entity, const
|
|||||||
Ifc2x3::IfcProductRepresentation::ptr prodrep = fes->Representation();
|
Ifc2x3::IfcProductRepresentation::ptr prodrep = fes->Representation();
|
||||||
Ifc2x3::IfcRepresentation::list reps = prodrep->Representations();
|
Ifc2x3::IfcRepresentation::list reps = prodrep->Representations();
|
||||||
|
|
||||||
IfcGeom::ShapeList opening_shapes;
|
IfcGeom::IfcRepresentationShapeItems opening_shapes;
|
||||||
|
|
||||||
for ( Ifc2x3::IfcRepresentation::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) {
|
for ( Ifc2x3::IfcRepresentation::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) {
|
||||||
IfcGeom::convert_shapes(*it2,opening_shapes);
|
IfcGeom::convert_shapes(*it2,opening_shapes);
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( unsigned int i = 0; i < opening_shapes.size(); ++ i ) {
|
for ( unsigned int i = 0; i < opening_shapes.size(); ++ i ) {
|
||||||
gp_GTrsf& gtrsf = *opening_shapes[i].first;
|
gp_GTrsf gtrsf = opening_shapes[i].Placement();
|
||||||
gtrsf.PreMultiply(opening_trsf);
|
gtrsf.PreMultiply(opening_trsf);
|
||||||
const TopoDS_Shape& opening_shape = gtrsf.Form() == gp_Other
|
const TopoDS_Shape& opening_shape = gtrsf.Form() == gp_Other
|
||||||
? BRepBuilderAPI_GTransform(*opening_shapes[i].second,gtrsf,true).Shape()
|
? BRepBuilderAPI_GTransform(opening_shapes[i].Shape(),gtrsf,true).Shape()
|
||||||
: (*opening_shapes[i].second).Moved(gtrsf.Trsf());
|
: (opening_shapes[i].Shape()).Moved(gtrsf.Trsf());
|
||||||
builder.Add(opening_compound,opening_shape);
|
builder.Add(opening_compound,opening_shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( IfcGeom::ShapeList::const_iterator it5 = opening_shapes.begin(); it5 != opening_shapes.end(); ++ it5 ) {
|
|
||||||
delete it5->first;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate over the shapes of the IfcProduct
|
// Iterate over the shapes of the IfcProduct
|
||||||
for ( IfcGeom::ShapeList::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) {
|
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) {
|
||||||
TopoDS_Shape entity_shape_solid;
|
TopoDS_Shape entity_shape_solid;
|
||||||
const TopoDS_Shape& entity_shape_unlocated = IfcGeom::ensure_fit_for_subtraction(*(it3->second),entity_shape_solid);
|
const TopoDS_Shape& entity_shape_unlocated = IfcGeom::ensure_fit_for_subtraction(it3->Shape(),entity_shape_solid);
|
||||||
const gp_GTrsf& entity_shape_gtrsf = *(it3->first);
|
const gp_GTrsf& entity_shape_gtrsf = it3->Placement();
|
||||||
TopoDS_Shape entity_shape;
|
TopoDS_Shape entity_shape;
|
||||||
if ( entity_shape_gtrsf.Form() == gp_Other ) {
|
if ( entity_shape_gtrsf.Form() == gp_Other ) {
|
||||||
Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to:",entity->entity);
|
Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to:",entity->entity);
|
||||||
@@ -294,7 +286,7 @@ bool IfcGeom::convert_openings_fast(const Ifc2x3::IfcProduct::ptr entity, const
|
|||||||
BRepCheck_Analyzer analyser(brep_cut_result);
|
BRepCheck_Analyzer analyser(brep_cut_result);
|
||||||
is_valid = analyser.IsValid() != 0;
|
is_valid = analyser.IsValid() != 0;
|
||||||
if ( is_valid ) {
|
if ( is_valid ) {
|
||||||
cut_shapes.push_back(IfcGeom::LocationShape(new gp_GTrsf(),new TopoDS_Shape(brep_cut_result)));
|
cut_shapes.push_back(IfcGeom::IfcRepresentationShapeItem(brep_cut_result, &it3->Style()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( !is_valid ) {
|
if ( !is_valid ) {
|
||||||
|
|||||||
@@ -53,13 +53,13 @@ bool use_faster_booleans = false;
|
|||||||
bool disable_subtractions = false;
|
bool disable_subtractions = false;
|
||||||
bool disable_triangulation = false;
|
bool disable_triangulation = false;
|
||||||
|
|
||||||
int IfcGeomObjects::IfcRepresentationTriangulation::addvert(const gp_XYZ& p) {
|
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 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 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();
|
const float Z = convert_back_units ? (float) (p.Z() / IfcGeom::GetValue(IfcGeom::GV_LENGTH_UNIT)) : (float)p.Z();
|
||||||
int i = (int) verts.size() / 3;
|
int i = (int) verts.size() / 3;
|
||||||
if ( weld_vertices ) {
|
if ( weld_vertices ) {
|
||||||
const VertKey key = VertKey(X,std::pair<float,float>(Y,Z));
|
const VertKey key = std::make_pair(material_index, std::make_pair(X, std::make_pair(Y, Z)));
|
||||||
VertKeyMap::const_iterator it = welds.find(key);
|
VertKeyMap::const_iterator it = welds.find(key);
|
||||||
if ( it != welds.end() ) return it->second;
|
if ( it != welds.end() ) return it->second;
|
||||||
i = (int) welds.size();
|
i = (int) welds.size();
|
||||||
@@ -83,9 +83,9 @@ IfcGeomObjects::IfcRepresentationBrepData::IfcRepresentationBrepData(const IfcRe
|
|||||||
TopoDS_Compound compound;
|
TopoDS_Compound compound;
|
||||||
BRep_Builder builder;
|
BRep_Builder builder;
|
||||||
builder.MakeCompound(compound);
|
builder.MakeCompound(compound);
|
||||||
for ( IfcGeom::ShapeList::const_iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
||||||
const TopoDS_Shape& s = *(*it).second;
|
const TopoDS_Shape& s = it->Shape();
|
||||||
const gp_GTrsf& trsf = *(*it).first;
|
const gp_GTrsf& trsf = it->Placement();
|
||||||
bool trsf_valid = false;
|
bool trsf_valid = false;
|
||||||
gp_Trsf _trsf;
|
gp_Trsf _trsf;
|
||||||
try {
|
try {
|
||||||
@@ -107,10 +107,21 @@ IfcGeomObjects::IfcRepresentationBrepData::IfcRepresentationBrepData(const IfcRe
|
|||||||
IfcGeomObjects::IfcRepresentationTriangulation::IfcRepresentationTriangulation(const IfcRepresentationShapeModel& shapes)
|
IfcGeomObjects::IfcRepresentationTriangulation::IfcRepresentationTriangulation(const IfcRepresentationShapeModel& shapes)
|
||||||
: id(shapes.getId())
|
: id(shapes.getId())
|
||||||
{
|
{
|
||||||
for ( IfcGeom::ShapeList::const_iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
||||||
|
|
||||||
const TopoDS_Shape& s = *it->second;
|
int surface_style_id = -1;
|
||||||
const gp_GTrsf& trsf = *it->first;
|
if (it->hasStyle()) {
|
||||||
|
std::vector<const IfcGeom::SurfaceStyle*>::const_iterator jt = std::find(surface_styles.begin(), surface_styles.end(), &it->Style());
|
||||||
|
if (jt == surface_styles.end()) {
|
||||||
|
surface_style_id = surface_styles.size();
|
||||||
|
surface_styles.push_back(&it->Style());
|
||||||
|
} else {
|
||||||
|
surface_style_id = jt - surface_styles.begin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const TopoDS_Shape& s = it->Shape();
|
||||||
|
const gp_GTrsf& trsf = it->Placement();
|
||||||
|
|
||||||
// Triangulate the shape
|
// Triangulate the shape
|
||||||
try {
|
try {
|
||||||
@@ -150,7 +161,7 @@ IfcGeomObjects::IfcRepresentationTriangulation::IfcRepresentationTriangulation(c
|
|||||||
for( int i = 1; i <= nodes.Length(); ++ i ) {
|
for( int i = 1; i <= nodes.Length(); ++ i ) {
|
||||||
coords.push_back(nodes(i).Transformed(loc).XYZ());
|
coords.push_back(nodes(i).Transformed(loc).XYZ());
|
||||||
trsf.Transforms(*coords.rbegin());
|
trsf.Transforms(*coords.rbegin());
|
||||||
dict[i] = addvert(*coords.rbegin());
|
dict[i] = addvert(surface_style_id, *coords.rbegin());
|
||||||
|
|
||||||
if ( calculate_normals ) {
|
if ( calculate_normals ) {
|
||||||
const gp_Pnt2d& uv = uvs(i);
|
const gp_Pnt2d& uv = uvs(i);
|
||||||
@@ -189,6 +200,8 @@ IfcGeomObjects::IfcRepresentationTriangulation::IfcRepresentationTriangulation(c
|
|||||||
faces.push_back(dict[n2]);
|
faces.push_back(dict[n2]);
|
||||||
faces.push_back(dict[n3]);
|
faces.push_back(dict[n3]);
|
||||||
|
|
||||||
|
materials.push_back(surface_style_id);
|
||||||
|
|
||||||
addedge(n1,n2,edgecount,edges_temp);
|
addedge(n1,n2,edgecount,edges_temp);
|
||||||
addedge(n2,n3,edgecount,edges_temp);
|
addedge(n2,n3,edgecount,edges_temp);
|
||||||
addedge(n3,n1,edgecount,edges_temp);
|
addedge(n3,n1,edgecount,edges_temp);
|
||||||
@@ -369,7 +382,7 @@ IfcGeomObjects::IfcGeomShapeModelObject* create_shape_model_for_next_entity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IfcGeomObjects::IfcRepresentationShapeModel* shape;
|
IfcGeomObjects::IfcRepresentationShapeModel* shape;
|
||||||
IfcGeom::ShapeList shapes;
|
IfcGeom::IfcRepresentationShapeItems shapes;
|
||||||
|
|
||||||
if ( !IfcGeom::convert_shapes(shaperep,shapes) ) {
|
if ( !IfcGeom::convert_shapes(shaperep,shapes) ) {
|
||||||
_nextShape();
|
_nextShape();
|
||||||
@@ -412,15 +425,11 @@ IfcGeomObjects::IfcGeomShapeModelObject* create_shape_model_for_next_entity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( !disable_subtractions && openings && openings->Size() ) {
|
if ( !disable_subtractions && openings && openings->Size() ) {
|
||||||
IfcGeom::ShapeList opened_shapes;
|
IfcGeom::IfcRepresentationShapeItems opened_shapes;
|
||||||
try {
|
try {
|
||||||
if ( use_faster_booleans ) {
|
if ( use_faster_booleans ) {
|
||||||
bool succes = IfcGeom::convert_openings_fast(ifc_product,openings,shapes,trsf,opened_shapes);
|
bool succes = IfcGeom::convert_openings_fast(ifc_product,openings,shapes,trsf,opened_shapes);
|
||||||
if ( ! succes ) {
|
if ( ! succes ) {
|
||||||
for ( IfcGeom::ShapeList::const_iterator it = opened_shapes.begin(); it != opened_shapes.end(); ++ it ) {
|
|
||||||
delete it->first;
|
|
||||||
delete it->second;
|
|
||||||
}
|
|
||||||
opened_shapes.clear();
|
opened_shapes.clear();
|
||||||
IfcGeom::convert_openings(ifc_product,openings,shapes,trsf,opened_shapes);
|
IfcGeom::convert_openings(ifc_product,openings,shapes,trsf,opened_shapes);
|
||||||
}
|
}
|
||||||
@@ -431,18 +440,15 @@ IfcGeomObjects::IfcGeomShapeModelObject* create_shape_model_for_next_entity() {
|
|||||||
Logger::Message(Logger::LOG_ERROR,"Error processing openings for:",ifc_product->entity);
|
Logger::Message(Logger::LOG_ERROR,"Error processing openings for:",ifc_product->entity);
|
||||||
}
|
}
|
||||||
if ( use_world_coords ) {
|
if ( use_world_coords ) {
|
||||||
for ( IfcGeom::ShapeList::const_iterator it = opened_shapes.begin(); it != opened_shapes.end(); ++ it ) {
|
for ( IfcGeom::IfcRepresentationShapeItems::iterator it = opened_shapes.begin(); it != opened_shapes.end(); ++ it ) {
|
||||||
it->first->PreMultiply(trsf);
|
it->move(trsf);
|
||||||
}
|
}
|
||||||
trsf = gp_Trsf();
|
trsf = gp_Trsf();
|
||||||
}
|
}
|
||||||
shape = new IfcGeomObjects::IfcRepresentationShapeModel(shaperep->entity->id(),opened_shapes,true);
|
shape = new IfcGeomObjects::IfcRepresentationShapeModel(shaperep->entity->id(),opened_shapes,true);
|
||||||
for ( IfcGeom::ShapeList::const_iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
|
||||||
delete it->first;
|
|
||||||
}
|
|
||||||
} else if ( use_world_coords ) {
|
} else if ( use_world_coords ) {
|
||||||
for ( IfcGeom::ShapeList::const_iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
for ( IfcGeom::IfcRepresentationShapeItems::iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
||||||
it->first->PreMultiply(trsf);
|
it->move(trsf);
|
||||||
}
|
}
|
||||||
trsf = gp_Trsf();
|
trsf = gp_Trsf();
|
||||||
shape = new IfcGeomObjects::IfcRepresentationShapeModel(shaperep->entity->id(),shapes);
|
shape = new IfcGeomObjects::IfcRepresentationShapeModel(shaperep->entity->id(),shapes);
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
#include <gp_Trsf2d.hxx>
|
#include <gp_Trsf2d.hxx>
|
||||||
|
|
||||||
#include "../ifcparse/IfcParse.h"
|
#include "../ifcparse/IfcParse.h"
|
||||||
#include "../ifcgeom/IfcShapeList.h"
|
#include "../ifcgeom/IfcRepresentationShapeItem.h"
|
||||||
|
|
||||||
namespace IfcGeomObjects {
|
namespace IfcGeomObjects {
|
||||||
|
|
||||||
@@ -107,11 +107,9 @@ namespace IfcGeomObjects {
|
|||||||
|
|
||||||
// End of settings enumeration.
|
// End of settings enumeration.
|
||||||
|
|
||||||
// Some typedefs for convenience
|
// A nested pair of floats and a material index to be able to store an XYZ coordinate in a map.
|
||||||
typedef std::vector<int>::const_iterator IntIt;
|
// TODO: Make this a std::tuple when compilers add support for that.
|
||||||
typedef std::vector<float>::const_iterator FltIt;
|
typedef std::pair<int, std::pair<float,std::pair<float,float> > > VertKey;
|
||||||
// A nested pair of doubles to be able to store an XYZ coordinate in a map.
|
|
||||||
typedef std::pair< float,std::pair<float,float> > VertKey;
|
|
||||||
typedef std::map<VertKey,int> VertKeyMap;
|
typedef std::map<VertKey,int> VertKeyMap;
|
||||||
typedef std::pair<int,int> Edge;
|
typedef std::pair<int,int> Edge;
|
||||||
|
|
||||||
@@ -119,25 +117,18 @@ namespace IfcGeomObjects {
|
|||||||
private:
|
private:
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
bool owns_shapes;
|
bool owns_shapes;
|
||||||
const IfcGeom::ShapeList shapes;
|
const IfcGeom::IfcRepresentationShapeItems shapes;
|
||||||
IfcRepresentationShapeModel(const IfcRepresentationShapeModel& other);
|
IfcRepresentationShapeModel(const IfcRepresentationShapeModel& other);
|
||||||
IfcRepresentationShapeModel& operator=(const IfcRepresentationShapeModel& other);
|
IfcRepresentationShapeModel& operator=(const IfcRepresentationShapeModel& other);
|
||||||
public:
|
public:
|
||||||
IfcRepresentationShapeModel(unsigned int id, const IfcGeom::ShapeList& shapes, bool owns_shapes = false)
|
IfcRepresentationShapeModel(unsigned int id, const IfcGeom::IfcRepresentationShapeItems& shapes, bool owns_shapes = false)
|
||||||
: id(id)
|
: id(id)
|
||||||
, shapes(shapes)
|
, shapes(shapes)
|
||||||
, owns_shapes(owns_shapes)
|
, owns_shapes(owns_shapes)
|
||||||
{}
|
{}
|
||||||
~IfcRepresentationShapeModel() {
|
virtual ~IfcRepresentationShapeModel() {}
|
||||||
for ( IfcGeom::ShapeList::const_iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
IfcGeom::IfcRepresentationShapeItems::const_iterator begin() const { return shapes.begin(); }
|
||||||
delete it->first;
|
IfcGeom::IfcRepresentationShapeItems::const_iterator end() const { return shapes.end(); }
|
||||||
if (owns_shapes) {
|
|
||||||
delete it->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IfcGeom::ShapeList::const_iterator begin() const { return shapes.begin(); }
|
|
||||||
IfcGeom::ShapeList::const_iterator end() const { return shapes.end(); }
|
|
||||||
const unsigned int& getId() const { return id; }
|
const unsigned int& getId() const { return id; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -146,6 +137,7 @@ namespace IfcGeomObjects {
|
|||||||
int id;
|
int id;
|
||||||
std::string brep_data;
|
std::string brep_data;
|
||||||
IfcRepresentationBrepData(const IfcRepresentationShapeModel& s);
|
IfcRepresentationBrepData(const IfcRepresentationShapeModel& s);
|
||||||
|
virtual ~IfcRepresentationBrepData() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class IfcRepresentationTriangulation {
|
class IfcRepresentationTriangulation {
|
||||||
@@ -155,11 +147,14 @@ namespace IfcGeomObjects {
|
|||||||
std::vector<int> faces;
|
std::vector<int> faces;
|
||||||
std::vector<int> edges;
|
std::vector<int> edges;
|
||||||
std::vector<float> normals;
|
std::vector<float> normals;
|
||||||
|
std::vector<int> materials;
|
||||||
|
std::vector<const IfcGeom::SurfaceStyle*> surface_styles;
|
||||||
VertKeyMap welds;
|
VertKeyMap welds;
|
||||||
|
|
||||||
IfcRepresentationTriangulation(const IfcRepresentationShapeModel& s);
|
IfcRepresentationTriangulation(const IfcRepresentationShapeModel& s);
|
||||||
|
virtual ~IfcRepresentationTriangulation() {}
|
||||||
private:
|
private:
|
||||||
int addvert(const gp_XYZ& p);
|
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) {
|
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) );
|
const Edge e = Edge( (std::min)(n1,n2),(std::max)(n1,n2) );
|
||||||
if ( edgecount.find(e) == edgecount.end() ) edgecount[e] = 1;
|
if ( edgecount.find(e) == edgecount.end() ) edgecount[e] = 1;
|
||||||
|
|||||||
@@ -92,20 +92,22 @@ bool IfcGeom::convert(const Ifc2x3::IfcExtrudedAreaSolid::ptr l, TopoDS_Shape& s
|
|||||||
shape.Move(trsf);
|
shape.Move(trsf);
|
||||||
return ! shape.IsNull();
|
return ! shape.IsNull();
|
||||||
}
|
}
|
||||||
bool IfcGeom::convert(const Ifc2x3::IfcFacetedBrep::ptr l, ShapeList& shape) {
|
bool IfcGeom::convert(const Ifc2x3::IfcFacetedBrep::ptr l, IfcRepresentationShapeItems& shape) {
|
||||||
TopoDS_Shape s;
|
TopoDS_Shape s;
|
||||||
if ( const TopoDS_Shape* shape_id = IfcGeom::convert_shape(l->Outer(),s) ) {
|
if (IfcGeom::convert_shape(l->Outer(),s) ) {
|
||||||
shape.push_back(LocationShape(new gp_GTrsf(),shape_id));
|
shape.push_back(IfcRepresentationShapeItem(s, get_style(l->Outer())));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool IfcGeom::convert(const Ifc2x3::IfcFaceBasedSurfaceModel::ptr l, ShapeList& shapes) {
|
bool IfcGeom::convert(const Ifc2x3::IfcFaceBasedSurfaceModel::ptr l, IfcRepresentationShapeItems& shapes) {
|
||||||
Ifc2x3::IfcConnectedFaceSet::list facesets = l->FbsmFaces();
|
Ifc2x3::IfcConnectedFaceSet::list facesets = l->FbsmFaces();
|
||||||
|
const SurfaceStyle* collective_style = get_style(l);
|
||||||
for( Ifc2x3::IfcConnectedFaceSet::it it = facesets->begin(); it != facesets->end(); ++ it ) {
|
for( Ifc2x3::IfcConnectedFaceSet::it it = facesets->begin(); it != facesets->end(); ++ it ) {
|
||||||
TopoDS_Shape s;
|
TopoDS_Shape s;
|
||||||
if ( const TopoDS_Shape* shape_id = IfcGeom::convert_shape(*it,s) ) {
|
const SurfaceStyle* shell_style = get_style(*it);
|
||||||
shapes.push_back(LocationShape(new gp_GTrsf(),shape_id));
|
if (IfcGeom::convert_shape(*it,s)) {
|
||||||
|
shapes.push_back(IfcRepresentationShapeItem(s, shell_style ? shell_style : collective_style));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -135,12 +137,17 @@ bool IfcGeom::convert(const Ifc2x3::IfcPolygonalBoundedHalfSpace::ptr l, TopoDS_
|
|||||||
shape = BRepAlgoAPI_Common(halfspace,prism);
|
shape = BRepAlgoAPI_Common(halfspace,prism);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool IfcGeom::convert(const Ifc2x3::IfcShellBasedSurfaceModel::ptr l, ShapeList& shapes) {
|
bool IfcGeom::convert(const Ifc2x3::IfcShellBasedSurfaceModel::ptr l, IfcRepresentationShapeItems& shapes) {
|
||||||
IfcUtil::IfcAbstractSelect::list shells = l->SbsmBoundary();
|
IfcUtil::IfcAbstractSelect::list shells = l->SbsmBoundary();
|
||||||
|
const SurfaceStyle* collective_style = get_style(l);
|
||||||
for( IfcUtil::IfcAbstractSelect::it it = shells->begin(); it != shells->end(); ++ it ) {
|
for( IfcUtil::IfcAbstractSelect::it it = shells->begin(); it != shells->end(); ++ it ) {
|
||||||
TopoDS_Shape s;
|
TopoDS_Shape s;
|
||||||
if ( const TopoDS_Shape* shape_id = IfcGeom::convert_shape(*it,s) ) {
|
const SurfaceStyle* shell_style = 0;
|
||||||
shapes.push_back(LocationShape(new gp_GTrsf(),shape_id));
|
if ((*it)->is(Ifc2x3::Type::IfcRepresentationItem)) {
|
||||||
|
shell_style = get_style((Ifc2x3::IfcRepresentationItem*)*it);
|
||||||
|
}
|
||||||
|
if (IfcGeom::convert_shape(*it,s)) {
|
||||||
|
shapes.push_back(IfcRepresentationShapeItem(s, shell_style ? shell_style : collective_style));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -334,7 +341,7 @@ bool IfcGeom::convert(const Ifc2x3::IfcConnectedFaceSet::ptr l, TopoDS_Shape& sh
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool IfcGeom::convert(const Ifc2x3::IfcMappedItem::ptr l, ShapeList& shapes) {
|
bool IfcGeom::convert(const Ifc2x3::IfcMappedItem::ptr l, IfcRepresentationShapeItems& shapes) {
|
||||||
gp_GTrsf gtrsf;
|
gp_GTrsf gtrsf;
|
||||||
Ifc2x3::IfcCartesianTransformationOperator::ptr transform = l->MappingTarget();
|
Ifc2x3::IfcCartesianTransformationOperator::ptr transform = l->MappingTarget();
|
||||||
if ( transform->is(Ifc2x3::Type::IfcCartesianTransformationOperator3DnonUniform) ) {
|
if ( transform->is(Ifc2x3::Type::IfcCartesianTransformationOperator3DnonUniform) ) {
|
||||||
@@ -367,19 +374,22 @@ bool IfcGeom::convert(const Ifc2x3::IfcMappedItem::ptr l, ShapeList& shapes) {
|
|||||||
const unsigned int previous_size = (const unsigned int) shapes.size();
|
const unsigned int previous_size = (const unsigned int) shapes.size();
|
||||||
bool b = IfcGeom::convert_shapes(map->MappedRepresentation(),shapes);
|
bool b = IfcGeom::convert_shapes(map->MappedRepresentation(),shapes);
|
||||||
for ( unsigned int i = previous_size; i < shapes.size(); ++ i ) {
|
for ( unsigned int i = previous_size; i < shapes.size(); ++ i ) {
|
||||||
shapes[i].first->Multiply(gtrsf);
|
shapes[i].move(gtrsf);
|
||||||
}
|
}
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
bool IfcGeom::convert(const Ifc2x3::IfcShapeRepresentation::ptr l, ShapeList& shapes) {
|
|
||||||
|
bool IfcGeom::convert(const Ifc2x3::IfcShapeRepresentation::ptr l, IfcRepresentationShapeItems& shapes) {
|
||||||
Ifc2x3::IfcRepresentationItem::list items = l->Items();
|
Ifc2x3::IfcRepresentationItem::list items = l->Items();
|
||||||
if ( ! items->Size() ) return false;
|
if ( ! items->Size() ) return false;
|
||||||
for ( Ifc2x3::IfcRepresentationItem::it it = items->begin(); it != items->end(); ++ it ) {
|
for ( Ifc2x3::IfcRepresentationItem::it it = items->begin(); it != items->end(); ++ it ) {
|
||||||
if ( IfcGeom::is_shape_collection(*it) ) IfcGeom::convert_shapes(*it,shapes);
|
Ifc2x3::IfcRepresentationItem* representation_item = *it;
|
||||||
|
if ( IfcGeom::is_shape_collection(representation_item) ) IfcGeom::convert_shapes(*it,shapes);
|
||||||
else {
|
else {
|
||||||
TopoDS_Shape s;
|
TopoDS_Shape s;
|
||||||
if ( const TopoDS_Shape* shape_id = IfcGeom::convert_shape(*it,s))
|
if (IfcGeom::convert_shape(representation_item,s)) {
|
||||||
shapes.push_back(LocationShape(new gp_GTrsf(),shape_id));
|
shapes.push_back(IfcRepresentationShapeItem(s, get_style(representation_item)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace IfcGeom {
|
|||||||
using namespace Ifc2x3;
|
using namespace Ifc2x3;
|
||||||
using namespace IfcUtil;
|
using namespace IfcUtil;
|
||||||
|
|
||||||
bool IfcGeom::convert_shapes(const IfcBaseClass* l, ShapeList& r) {
|
bool IfcGeom::convert_shapes(const IfcBaseClass* l, IfcRepresentationShapeItems& r) {
|
||||||
#include "IfcRegisterConvertShapes.h"
|
#include "IfcRegisterConvertShapes.h"
|
||||||
Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity);
|
Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity);
|
||||||
return false;
|
return false;
|
||||||
@@ -40,10 +40,10 @@ bool IfcGeom::is_shape_collection(const IfcBaseClass* l) {
|
|||||||
#include "IfcRegisterIsShapeCollection.h"
|
#include "IfcRegisterIsShapeCollection.h"
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const TopoDS_Shape* IfcGeom::convert_shape(const IfcBaseClass* l, TopoDS_Shape& r) {
|
bool IfcGeom::convert_shape(const IfcBaseClass* l, TopoDS_Shape& r) {
|
||||||
const unsigned int id = l->entity->id();
|
const unsigned int id = l->entity->id();
|
||||||
std::map<int,TopoDS_Shape>::const_iterator it = Cache::Shape.find(id);
|
std::map<int,TopoDS_Shape>::const_iterator it = Cache::Shape.find(id);
|
||||||
if ( it != Cache::Shape.end() ) { r = it->second; return &(it->second); }
|
if ( it != Cache::Shape.end() ) { r = it->second; return true; }
|
||||||
#include "IfcRegisterConvertShape.h"
|
#include "IfcRegisterConvertShape.h"
|
||||||
Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity);
|
Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
try { \
|
try { \
|
||||||
if ( convert((T*)l,r) ) { \
|
if ( convert((T*)l,r) ) { \
|
||||||
Cache::Shape[id] = r; \
|
Cache::Shape[id] = r; \
|
||||||
return &(Cache::Shape[id]); \
|
return true; \
|
||||||
} \
|
} \
|
||||||
} catch(...) { } \
|
} catch(...) { } \
|
||||||
Logger::Message(Logger::LOG_ERROR,"Failed to convert:",l->entity); \
|
Logger::Message(Logger::LOG_ERROR,"Failed to convert:",l->entity); \
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "IfcRegisterUndef.h"
|
#include "IfcRegisterUndef.h"
|
||||||
#define CLASS(T,V) bool convert(const T::ptr L, V& r);
|
#define CLASS(T,V) bool convert(const T::ptr L, V& r);
|
||||||
#define SHAPES(T) CLASS(T,ShapeList)
|
#define SHAPES(T) CLASS(T,IfcRepresentationShapeItems)
|
||||||
#define SHAPE(T) CLASS(T,TopoDS_Shape)
|
#define SHAPE(T) CLASS(T,TopoDS_Shape)
|
||||||
#define WIRE(T) CLASS(T,TopoDS_Wire)
|
#define WIRE(T) CLASS(T,TopoDS_Wire)
|
||||||
#define FACE(T) CLASS(T,TopoDS_Face)
|
#define FACE(T) CLASS(T,TopoDS_Face)
|
||||||
|
|||||||
@@ -170,6 +170,10 @@
|
|||||||
RelativePath="..\src\ifcgeom\IfcGeomObjects.cpp"
|
RelativePath="..\src\ifcgeom\IfcGeomObjects.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\ifcgeom\IfcGeomRenderStyles.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\src\ifcgeom\IfcGeomShapes.cpp"
|
RelativePath="..\src\ifcgeom\IfcGeomShapes.cpp"
|
||||||
>
|
>
|
||||||
@@ -196,6 +200,10 @@
|
|||||||
RelativePath="..\src\ifcgeom\IfcGeomObjects.h"
|
RelativePath="..\src\ifcgeom\IfcGeomObjects.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\ifcgeom\IfcGeomRenderStyles.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\src\ifcgeom\IfcRegister.h"
|
RelativePath="..\src\ifcgeom\IfcRegister.h"
|
||||||
>
|
>
|
||||||
@@ -236,6 +244,10 @@
|
|||||||
RelativePath="..\src\ifcgeom\IfcRegisterUndef.h"
|
RelativePath="..\src\ifcgeom\IfcRegisterUndef.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\ifcgeom\IfcRepresentationShapeItem.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Resource Files"
|
Name="Resource Files"
|
||||||
|
|||||||
Reference in New Issue
Block a user