From 21f741667eaaf3cf8e962a2b40bb87df50a8add2 Mon Sep 17 00:00:00 2001 From: dushyant basson <39452934+dushyant-basson@users.noreply.github.com> Date: Wed, 20 Dec 2023 01:19:36 +0530 Subject: [PATCH] Using transformation-matrix data; Turned off world-coords; Re-using geometry of repeating IDs --- src/qtviewer/IfcViewerWidget.cpp | 23 ++++++------- src/qtviewer/IfcViewerWidget.h | 2 +- src/qtviewer/ParseIfcFile.cpp | 58 ++++++++++++++++++++++++++------ src/qtviewer/ParseIfcFile.h | 3 +- 4 files changed, 62 insertions(+), 24 deletions(-) diff --git a/src/qtviewer/IfcViewerWidget.cpp b/src/qtviewer/IfcViewerWidget.cpp index 742d3835a3..ff9109ba62 100644 --- a/src/qtviewer/IfcViewerWidget.cpp +++ b/src/qtviewer/IfcViewerWidget.cpp @@ -12,6 +12,7 @@ #include "MessageLogger.h" #include "osg/Geode" #include "osg/Geometry" +#include "osg/Group" #include "osg/StateSet" #include "osg/Vec3" #include "osg/ref_ptr" @@ -142,33 +143,31 @@ void IfcViewerWidget::setupViewController() void IfcViewerWidget::loadFile(const std::string& filePath) { - std::vector> geometries; + std::vector> matrixTransforms; - if(!m_parser.Parse(filePath, geometries)) { + if(!m_parser.Parse(filePath, matrixTransforms)) { MessageLogger::log("Failed to prepare IFC geometry"); return; } MessageLogger::log("\nIFC geometry prepared"); - osg::ref_ptr geode = new osg::Geode; - for (auto geometry : geometries) { - geode->addDrawable(geometry); + for (auto matrixTransform : matrixTransforms) { + root->addChild(matrixTransform); } - // Add the model to the root node - root->addChild(geode); - // set initial camera position - orientScene(geode); + orientScene(root); + + // request redraw + update(); } -void IfcViewerWidget::orientScene(osg::ref_ptr geode) +void IfcViewerWidget::orientScene(osg::ref_ptr rootGroup) { // Get the bounding-box osg::ComputeBoundsVisitor cbv; - geode->accept(cbv); - //root.get()->accept(cbv); + rootGroup->accept(cbv); const osg::BoundingBox& bb = cbv.getBoundingBox(); // Center (average of opposite corners of bb) diff --git a/src/qtviewer/IfcViewerWidget.h b/src/qtviewer/IfcViewerWidget.h index ec9158ed2d..3b0b1c15c9 100644 --- a/src/qtviewer/IfcViewerWidget.h +++ b/src/qtviewer/IfcViewerWidget.h @@ -56,7 +56,7 @@ private: void setupViewController(); - void orientScene(osg::ref_ptr geode); + void orientScene(osg::ref_ptr rootGroup); }; #endif // IFCVIEWERWIDGET_H diff --git a/src/qtviewer/ParseIfcFile.cpp b/src/qtviewer/ParseIfcFile.cpp index dfbe059efb..8e1967b42c 100644 --- a/src/qtviewer/ParseIfcFile.cpp +++ b/src/qtviewer/ParseIfcFile.cpp @@ -4,6 +4,8 @@ #include "osg/Array" #include "osg/Geometry" #include "osg/Material" +#include "osg/MatrixTransform" +#include "osg/Matrixd" #include "osg/PrimitiveSet" #include "osg/StateAttribute" #include "osg/StateSet" @@ -22,12 +24,12 @@ ParseIfcFile::~ParseIfcFile() {} bool ParseIfcFile::Parse( const std::string& filePath, - std::vector>& geometries + std::vector>& matrixTransforms ) { IfcParse::IfcFile file(filePath); IfcGeom::IteratorSettings settings; - settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, true); + settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, false); settings.set(IfcGeom::IteratorSettings::WELD_VERTICES, false); settings.set(IfcGeom::IteratorSettings::APPLY_DEFAULT_MATERIALS, true); @@ -38,6 +40,9 @@ bool ParseIfcFile::Parse( return false; } + std::string lastId; + std::vector> lastGeometrySet; + do { //const IfcGeom::BRepElement* bRepElem = it->get_native(); const IfcGeom::TriangulationElement* triElem = static_cast(it->get()); @@ -46,22 +51,46 @@ bool ParseIfcFile::Parse( std::string elemInfo = triElem->type(); elemInfo += triElem->name() == "" ? "" : ": " + triElem->name(); MessageLogger::log(elemInfo); + + const std::string id = triElem->geometry().id(); + + //MessageLogger::log("id: " + id); // Transformation Matrix const std::vector& matrixData = triElem->transformation().matrix().data(); + + // Debugging: std::string matrixStr = ""; - int di = 0; + int col = 0; + int row = 0; for (auto d : matrixData) { - if (di == 4) { - matrixStr += "\n"; - di = 0; - } matrixStr += std::to_string(d) + " "; - di++; + if (++col == 3) { + std::string lastCol = (row == 3) ? "1" : "0"; + matrixStr += lastCol + "\n"; + col = 0; + row++; + } } //MessageLogger::log(matrixStr); // Print matrix data + + const osg::Matrixd matrixd ( + matrixData[0], matrixData[1], matrixData[2], 0, + matrixData[3], matrixData[4], matrixData[5], 0, + matrixData[6], matrixData[7], matrixData[8], 0, + matrixData[9], matrixData[10], matrixData[11], 1 + ); - //MessageLogger::log(triElem->geometry().id()); + const osg::ref_ptr matrixTransform = new osg::MatrixTransform; + matrixTransform->setMatrix(matrixd); + + if (id == lastId) { + for (auto geometry : lastGeometrySet) { + matrixTransform->addChild(geometry); + } + matrixTransforms.push_back(matrixTransform); + continue; + } const boost::shared_ptr& triElemGeom = triElem->geometry_pointer(); @@ -84,6 +113,8 @@ bool ParseIfcFile::Parse( if (fit != elemFaces.end()) MessageLogger::log("** Failed to map the faces to material IDs!"); + std::vector> geometrySet; + for (const auto& group : elemFaces_grouped) { int matId = group.first; const std::vector& fVertIds = group.second; @@ -111,9 +142,16 @@ bool ParseIfcFile::Parse( osg::ref_ptr osgMaterial = getOsgMaterial(elemMats[matId]); geometry->getOrCreateStateSet()->setAttributeAndModes(osgMaterial.get()); - geometries.push_back(geometry); + matrixTransform->addChild(geometry); + + geometrySet.push_back(geometry); } + matrixTransforms.push_back(matrixTransform); + + lastId = id; + lastGeometrySet = geometrySet; + } while (it->next()); return true; diff --git a/src/qtviewer/ParseIfcFile.h b/src/qtviewer/ParseIfcFile.h index 17ed490e72..548b4ec487 100644 --- a/src/qtviewer/ParseIfcFile.h +++ b/src/qtviewer/ParseIfcFile.h @@ -7,6 +7,7 @@ #include #include "../ifcgeom_schema_agnostic/IfcGeomIterator.h" #include "osg/Material" +#include "osg/MatrixTransform" #include "osg/ref_ptr" #include "osg/Geometry" @@ -19,7 +20,7 @@ public: bool Parse( const std::string& filePath, - std::vector>& geometries + std::vector>& matrixTransforms ); private: