mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-12 06:32:09 +00:00
IFC file successfully parsed and loaded in Qt OpenGL widget
This commit is contained in:
@@ -64,8 +64,6 @@ set_source_files_properties(${app_icon_macos} PROPERTIES
|
|||||||
|
|
||||||
add_executable(${targetName}
|
add_executable(${targetName}
|
||||||
MessageLogger.h
|
MessageLogger.h
|
||||||
MouseHandler.h
|
|
||||||
MouseHandler.cpp
|
|
||||||
IfcViewerWidget.h
|
IfcViewerWidget.h
|
||||||
IfcViewerWidget.cpp
|
IfcViewerWidget.cpp
|
||||||
ParseIfcFile.h
|
ParseIfcFile.h
|
||||||
|
|||||||
@@ -1,16 +1,20 @@
|
|||||||
#include "IfcViewerWidget.h"
|
#include "IfcViewerWidget.h"
|
||||||
#include <OpenGL/OpenGL.h>
|
#include <OpenGL/OpenGL.h>
|
||||||
#include <osgGA/TrackballManipulator>
|
|
||||||
#include <osgGA/FirstPersonManipulator>
|
|
||||||
#include <osg/ShapeDrawable>
|
#include <osg/ShapeDrawable>
|
||||||
#include <osg/Material>
|
#include <osg/Material>
|
||||||
#include <osg/MatrixTransform>
|
#include <osg/MatrixTransform>
|
||||||
|
#include <osg/ComputeBoundsVisitor>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QWheelEvent>
|
#include <QWheelEvent>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "MainWindow.h"
|
||||||
#include "MessageLogger.h"
|
#include "MessageLogger.h"
|
||||||
#include "MouseHandler.h"
|
#include "osg/Geode"
|
||||||
|
#include "osg/Geometry"
|
||||||
|
#include "osg/Vec3"
|
||||||
#include "osg/ref_ptr"
|
#include "osg/ref_ptr"
|
||||||
|
#include "osgGA/TrackballManipulator"
|
||||||
|
|
||||||
IfcViewerWidget::IfcViewerWidget(qreal dpiScale, QWidget *parent) :
|
IfcViewerWidget::IfcViewerWidget(qreal dpiScale, QWidget *parent) :
|
||||||
QOpenGLWidget(parent),
|
QOpenGLWidget(parent),
|
||||||
@@ -21,16 +25,21 @@ IfcViewerWidget::IfcViewerWidget(qreal dpiScale, QWidget *parent) :
|
|||||||
)),
|
)),
|
||||||
m_viewer(new osgViewer::Viewer),
|
m_viewer(new osgViewer::Viewer),
|
||||||
root(new osg::Group)
|
root(new osg::Group)
|
||||||
{ }
|
{
|
||||||
|
m_mouseHandler = new osgGA::TrackballManipulator;
|
||||||
|
m_clearColor = osg::Vec4(0.7, 0.7, 0.7, 1.0);
|
||||||
|
|
||||||
|
//debug - override
|
||||||
|
//std::string filePath = "/Users/onizudb/Downloads/IFC/wallAtOrigin.ifc";
|
||||||
|
//this->loadFile(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
void IfcViewerWidget::initializeGL()
|
void IfcViewerWidget::initializeGL()
|
||||||
{
|
{
|
||||||
|
MessageLogger::log("Press `Cmd/Ctrl + o` or use the File menu to open an IFC file");
|
||||||
|
|
||||||
// Set up the rendering context, load shaders and other resources, etc.:
|
// Set up the rendering context, load shaders and other resources, etc.:
|
||||||
|
|
||||||
MessageLogger::log("devicePixelRatio: " + std::to_string(m_dpiScale));
|
|
||||||
|
|
||||||
this->buildSceneData();
|
|
||||||
|
|
||||||
// Set the root node as the scene data for the viewer
|
// Set the root node as the scene data for the viewer
|
||||||
m_viewer->setSceneData(root);
|
m_viewer->setSceneData(root);
|
||||||
|
|
||||||
@@ -38,20 +47,16 @@ void IfcViewerWidget::initializeGL()
|
|||||||
state->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
|
state->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
|
||||||
|
|
||||||
m_viewer->getCamera()->setViewport(0, 0, this->width(), this->height());
|
m_viewer->getCamera()->setViewport(0, 0, this->width(), this->height());
|
||||||
m_viewer->getCamera()->setClearColor(osg::Vec4(0.8f, 0.8f, 0.8f, 1.0f));
|
m_viewer->getCamera()->setClearColor(m_clearColor);
|
||||||
m_viewer->getCamera()->setGraphicsContext(m_graphicsWindow);
|
m_viewer->getCamera()->setGraphicsContext(m_graphicsWindow);
|
||||||
|
|
||||||
// Add event handlers
|
// Add event handlers
|
||||||
|
|
||||||
this->setMouseTracking(false);
|
this->setMouseTracking(false);
|
||||||
|
|
||||||
//osg::ref_ptr<osgGA::TrackballManipulator> trackballManipulator = new osgGA::TrackballManipulator;
|
|
||||||
//trackballManipulator->setAllowThrow(false);
|
|
||||||
//m_viewer->setCameraManipulator(trackballManipulator);
|
|
||||||
|
|
||||||
osg::ref_ptr<MouseHandler> mouseHandler = new MouseHandler(m_viewer);
|
m_mouseHandler->setAllowThrow(false);
|
||||||
mouseHandler->setAllowThrow(false);
|
|
||||||
m_viewer->setCameraManipulator(mouseHandler);
|
m_viewer->setCameraManipulator(m_mouseHandler);
|
||||||
|
|
||||||
m_viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
|
m_viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
|
||||||
m_viewer->realize();
|
m_viewer->realize();
|
||||||
@@ -70,16 +75,6 @@ void IfcViewerWidget::resizeGL(int w, int h)
|
|||||||
|
|
||||||
void IfcViewerWidget::paintGL()
|
void IfcViewerWidget::paintGL()
|
||||||
{
|
{
|
||||||
// Render geometries from the parsed IFC file
|
|
||||||
// Draw the scene:
|
|
||||||
//QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
|
|
||||||
//f->glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
//MessageLogger::log("paintGL called");
|
|
||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
//glClearColor(0.2f, 0.6f, 0.9f, 0.5f);
|
|
||||||
|
|
||||||
// Render OSG scene
|
// Render OSG scene
|
||||||
m_viewer->frame();
|
m_viewer->frame();
|
||||||
}
|
}
|
||||||
@@ -141,32 +136,35 @@ unsigned int IfcViewerWidget::getMouseButtonNum(QMouseEvent* event)
|
|||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IfcViewerWidget::buildSceneData()
|
void IfcViewerWidget::loadFile(const std::string& filePath)
|
||||||
{
|
{
|
||||||
// Cube
|
std::vector<osg::ref_ptr<osg::Geometry>> geometries;
|
||||||
osg::ref_ptr<osg::Box> box = new osg::Box(osg::Vec3(0, 0, 0), 1.0f);
|
|
||||||
osg::ref_ptr<osg::ShapeDrawable> shapeDrawable = new osg::ShapeDrawable(box);
|
|
||||||
|
|
||||||
// Set material properties (optional)
|
if(!m_parser.Parse(filePath, geometries)) {
|
||||||
osg::ref_ptr<osg::Material> material = new osg::Material;
|
MessageLogger::log("Failed to prepare IFC geometry");
|
||||||
material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); // Red color
|
return;
|
||||||
shapeDrawable->getOrCreateStateSet()->setAttributeAndModes(material.get());
|
}
|
||||||
|
|
||||||
|
MessageLogger::log("\nIFC geometry prepared");
|
||||||
|
|
||||||
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
|
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
|
||||||
geode->addDrawable(shapeDrawable);
|
for (auto geometry : geometries) {
|
||||||
|
geode->addDrawable(geometry);
|
||||||
|
}
|
||||||
|
|
||||||
// Apply a rotation to the cube to make it 3D
|
prepareSceneWithGeometry(geode);
|
||||||
osg::ref_ptr<osg::MatrixTransform> cubeTransform = new osg::MatrixTransform;
|
|
||||||
osg::ref_ptr<osg::MatrixTransform> rotationTransform = new osg::MatrixTransform;
|
|
||||||
rotationTransform->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(45.0), osg::Vec3(1.0, 1.0, 0.0)));
|
|
||||||
cubeTransform->addChild(geode);
|
|
||||||
rotationTransform->addChild(cubeTransform);
|
|
||||||
|
|
||||||
// Translate the cube to a proper position
|
m_viewer->setCameraManipulator(m_mouseHandler);
|
||||||
osg::ref_ptr<osg::MatrixTransform> translationTransform = new osg::MatrixTransform;
|
}
|
||||||
translationTransform->setMatrix(osg::Matrix::translate(osg::Vec3(0.0, 0.0, -5.0)));
|
|
||||||
translationTransform->addChild(rotationTransform);
|
void IfcViewerWidget::prepareSceneWithGeometry(osg::ref_ptr<osg::Geode> geode)
|
||||||
|
{
|
||||||
// Add the cube to the root node
|
// Apply a rotation to the model
|
||||||
root->addChild(translationTransform);
|
// MatrixTransform allows applying transformations (translation, rotation, scaling) to its children
|
||||||
|
osg::ref_ptr<osg::MatrixTransform> rotationTransform = new osg::MatrixTransform;
|
||||||
|
rotationTransform->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(45.0), osg::Vec3(0.0, 0.0, 1.0)));
|
||||||
|
rotationTransform->addChild(geode);
|
||||||
|
|
||||||
|
// Add the model to the root node
|
||||||
|
root->addChild(rotationTransform);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,13 +9,25 @@
|
|||||||
#include <osg/ref_ptr>
|
#include <osg/ref_ptr>
|
||||||
#include <osgViewer/GraphicsWindow>
|
#include <osgViewer/GraphicsWindow>
|
||||||
#include <osgViewer/Viewer>
|
#include <osgViewer/Viewer>
|
||||||
|
#include <osgGA/TrackballManipulator>
|
||||||
#include <osg/Group>
|
#include <osg/Group>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "ParseIfcFile.h"
|
||||||
|
#include "osg/Vec4"
|
||||||
|
|
||||||
class IfcViewerWidget : public QOpenGLWidget
|
class IfcViewerWidget : public QOpenGLWidget
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IfcViewerWidget(qreal dpiScale, QWidget *parent = nullptr);
|
IfcViewerWidget(
|
||||||
|
qreal dpiScale,
|
||||||
|
QWidget *parent = nullptr
|
||||||
|
);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void loadFile(const std::string& filePath);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void initializeGL() override; // to set up resources, state
|
virtual void initializeGL() override; // to set up resources, state
|
||||||
@@ -31,13 +43,18 @@ protected:
|
|||||||
private:
|
private:
|
||||||
qreal m_dpiScale;
|
qreal m_dpiScale;
|
||||||
QMatrix4x4 m_projection;
|
QMatrix4x4 m_projection;
|
||||||
|
osg::Vec4 m_clearColor;
|
||||||
|
osg::ref_ptr<osgGA::TrackballManipulator> m_mouseHandler;
|
||||||
osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> m_graphicsWindow;
|
osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> m_graphicsWindow;
|
||||||
osg::ref_ptr<osgViewer::Viewer> m_viewer;
|
osg::ref_ptr<osgViewer::Viewer> m_viewer;
|
||||||
osg::ref_ptr<osg::Group> root; // OSG root node
|
osg::ref_ptr<osg::Group> root; // OSG root node
|
||||||
|
|
||||||
|
ParseIfcFile m_parser;
|
||||||
|
|
||||||
osgGA::EventQueue* getEventQueue() const;
|
osgGA::EventQueue* getEventQueue() const;
|
||||||
unsigned int getMouseButtonNum(QMouseEvent* event);
|
unsigned int getMouseButtonNum(QMouseEvent* event);
|
||||||
void buildSceneData();
|
|
||||||
|
void prepareSceneWithGeometry(osg::ref_ptr<osg::Geode> geode);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // IFCVIEWERWIDGET_H
|
#endif // IFCVIEWERWIDGET_H
|
||||||
|
|||||||
@@ -84,6 +84,8 @@ void MainWindow::createConnections()
|
|||||||
|
|
||||||
//connect(&m_parser, &ParseIfcFile::parsingInfo, this, &MainWindow::appendToOutputText);
|
//connect(&m_parser, &ParseIfcFile::parsingInfo, this, &MainWindow::appendToOutputText);
|
||||||
connect(&MessageLogger::getInstance(), SIGNAL(logMessage(QString)), this, SLOT(appendToOutputText(QString)));
|
connect(&MessageLogger::getInstance(), SIGNAL(logMessage(QString)), this, SLOT(appendToOutputText(QString)));
|
||||||
|
|
||||||
|
connect(this, SIGNAL(loadFileInViewerWidget(const std::string&)), m_glWidget, SLOT(loadFile(const std::string&)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::appendToOutputText(const QString& message)
|
void MainWindow::appendToOutputText(const QString& message)
|
||||||
@@ -119,11 +121,10 @@ void MainWindow::openFile()
|
|||||||
QString message = tr("Opening file: %1\n").arg(filePath);
|
QString message = tr("Opening file: %1\n").arg(filePath);
|
||||||
appendToOutputText(message);
|
appendToOutputText(message);
|
||||||
|
|
||||||
m_parser.Parse(filePath.toStdString());
|
|
||||||
|
|
||||||
m_currentPath = filePath;
|
|
||||||
setWindowTitle(tr("%1 - IFCViewer").arg(fileName));
|
setWindowTitle(tr("%1 - IFCViewer").arg(fileName));
|
||||||
|
|
||||||
m_outlineAction->setEnabled(true);
|
m_outlineAction->setEnabled(true);
|
||||||
m_backgroundAction->setEnabled(true);
|
m_backgroundAction->setEnabled(true);
|
||||||
|
|
||||||
|
emit loadFileInViewerWidget(filePath.toStdString());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,7 @@
|
|||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QOpenGLWidget>
|
#include <QOpenGLWidget>
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
|
#include <string>
|
||||||
#include "ParseIfcFile.h"
|
|
||||||
|
|
||||||
class MainWindow : public QMainWindow
|
class MainWindow : public QMainWindow
|
||||||
{
|
{
|
||||||
@@ -17,6 +16,9 @@ class MainWindow : public QMainWindow
|
|||||||
public:
|
public:
|
||||||
MainWindow(qreal dpiScale, QWidget *parent = nullptr);
|
MainWindow(qreal dpiScale, QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void loadFileInViewerWidget(const std::string& filePath);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void openFile();
|
void openFile();
|
||||||
void appendToOutputText(const QString& message);
|
void appendToOutputText(const QString& message);
|
||||||
@@ -40,12 +42,8 @@ private:
|
|||||||
QAction *m_backgroundAction;
|
QAction *m_backgroundAction;
|
||||||
QAction *m_outlineAction;
|
QAction *m_outlineAction;
|
||||||
|
|
||||||
QString m_currentPath;
|
|
||||||
|
|
||||||
QOpenGLWidget *m_glWidget;
|
QOpenGLWidget *m_glWidget;
|
||||||
QPlainTextEdit *m_outputText;
|
QPlainTextEdit *m_outputText;
|
||||||
|
|
||||||
ParseIfcFile m_parser;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAINWINDOW_H
|
#endif // MAINWINDOW_H
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
#include "MouseHandler.h"
|
|
||||||
#include <osgGA/CameraManipulator>
|
|
||||||
#include "MessageLogger.h"
|
|
||||||
|
|
||||||
MouseHandler::MouseHandler(osgViewer::Viewer* viewer) :
|
|
||||||
osgGA::TrackballManipulator(),
|
|
||||||
viewer(viewer)
|
|
||||||
{
|
|
||||||
MessageLogger::log("MouseHandler constructed");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MouseHandler::handle (
|
|
||||||
const osgGA::GUIEventAdapter& ea,
|
|
||||||
const osgGA::GUIActionAdapter& aa)
|
|
||||||
{
|
|
||||||
MessageLogger::log("MouseHandler::handle() called");
|
|
||||||
switch (ea.getEventType()) {
|
|
||||||
case (osgGA::GUIEventAdapter::DRAG):
|
|
||||||
{
|
|
||||||
if (ea.getButton() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)
|
|
||||||
{ // pan view
|
|
||||||
// Calculate the delta movement
|
|
||||||
float deltaX = ea.getX() - _ga_t0->getXnormalized();
|
|
||||||
float deltaY = ea.getY() - _ga_t1->getYnormalized();
|
|
||||||
|
|
||||||
// Implement panning logic
|
|
||||||
osg::Vec3d eye, center, up;
|
|
||||||
getInverseMatrix().getLookAt(eye, center, up);
|
|
||||||
osg::Vec3d right = (eye - center) ^ up;
|
|
||||||
osg::Matrixd rotationMatrix = osg::Matrix::rotate(-deltaX * 0.1, up) * osg::Matrix::rotate(deltaY * 0.1, right);
|
|
||||||
|
|
||||||
osg::Matrixd newMatrix = getMatrix() * rotationMatrix;
|
|
||||||
setByMatrix(newMatrix);
|
|
||||||
|
|
||||||
return true; // Event handled
|
|
||||||
}
|
|
||||||
if (ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// If not a right mouse button drag, let the base class handle it
|
|
||||||
//return osgGA::TrackballManipulator::handle(ea, aa);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
#ifndef MOUSEHANDLER_H
|
|
||||||
#define MOUSEHANDLER_H
|
|
||||||
|
|
||||||
#include <osgViewer/Viewer>
|
|
||||||
#include <osgGA/TrackballManipulator>
|
|
||||||
|
|
||||||
class MouseHandler : public osgGA::TrackballManipulator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MouseHandler(osgViewer::Viewer* viewer);
|
|
||||||
|
|
||||||
using osgGA::GUIEventHandler::handle;
|
|
||||||
virtual bool handle(
|
|
||||||
const osgGA::GUIEventAdapter& ea,
|
|
||||||
const osgGA::GUIActionAdapter& aa
|
|
||||||
);
|
|
||||||
private:
|
|
||||||
osgViewer::Viewer* viewer;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MOUSEHANDLER_H
|
|
||||||
@@ -1,14 +1,28 @@
|
|||||||
#include "ParseIfcFile.h"
|
#include "ParseIfcFile.h"
|
||||||
#include "MessageLogger.h"
|
#include "MessageLogger.h"
|
||||||
|
|
||||||
#include "../ifcgeom_schema_agnostic/IfcGeomIterator.h"
|
#include "osg/Array"
|
||||||
|
#include "osg/Geometry"
|
||||||
|
#include "osg/Material"
|
||||||
|
#include "osg/PrimitiveSet"
|
||||||
|
#include "osg/StateAttribute"
|
||||||
|
#include "osg/Vec4"
|
||||||
|
#include "osg/ref_ptr"
|
||||||
|
#include <OpenGL/OpenGL.h>
|
||||||
|
#include <cstddef> // size_t
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <osg/Vec3>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
ParseIfcFile::ParseIfcFile() {}
|
ParseIfcFile::ParseIfcFile() {}
|
||||||
|
|
||||||
ParseIfcFile::~ParseIfcFile() {}
|
ParseIfcFile::~ParseIfcFile() {}
|
||||||
|
|
||||||
void ParseIfcFile::Parse(const std::string& filePath)
|
bool ParseIfcFile::Parse(
|
||||||
{
|
const std::string& filePath,
|
||||||
|
std::vector<osg::ref_ptr<osg::Geometry>>& geometries
|
||||||
|
) {
|
||||||
IfcParse::IfcFile file(filePath);
|
IfcParse::IfcFile file(filePath);
|
||||||
|
|
||||||
IfcGeom::IteratorSettings settings;
|
IfcGeom::IteratorSettings settings;
|
||||||
@@ -19,7 +33,7 @@ void ParseIfcFile::Parse(const std::string& filePath)
|
|||||||
if (!it->initialize()) {
|
if (!it->initialize()) {
|
||||||
MessageLogger::log("Error: Iterator failed to initialize! Aborting.");
|
MessageLogger::log("Error: Iterator failed to initialize! Aborting.");
|
||||||
delete it;
|
delete it;
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@@ -29,10 +43,133 @@ void ParseIfcFile::Parse(const std::string& filePath)
|
|||||||
|
|
||||||
const boost::shared_ptr<IfcGeom::Representation::Triangulation>& triElemGeom = triElem->geometry_pointer();
|
const boost::shared_ptr<IfcGeom::Representation::Triangulation>& triElemGeom = triElem->geometry_pointer();
|
||||||
|
|
||||||
|
const std::vector<int>& elemFaces = triElemGeom->faces();
|
||||||
|
const std::vector<double>& elemVertices = triElemGeom->verts();
|
||||||
|
const std::vector<double>& elemNormals = triElemGeom->normals();
|
||||||
|
|
||||||
|
std::vector<Triangle> triangles = this->createTriangles(elemFaces, elemVertices, elemNormals);
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Vec3Array> osgVertices = new osg::Vec3Array;
|
||||||
|
osg::ref_ptr<osg::Vec3Array> osgNormals = new osg::Vec3Array;
|
||||||
|
|
||||||
|
// Combine the triangles from the vector into a single Vec3Array
|
||||||
|
for (const auto& triangle : triangles) {
|
||||||
|
osgVertices->push_back(triangle.vn1.vertex);
|
||||||
|
osgVertices->push_back(triangle.vn2.vertex);
|
||||||
|
osgVertices->push_back(triangle.vn3.vertex);
|
||||||
|
|
||||||
|
osgNormals->push_back(triangle.vn1.normal);
|
||||||
|
osgNormals->push_back(triangle.vn2.normal);
|
||||||
|
osgNormals->push_back(triangle.vn3.normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Geometry> elemGeom = new osg::Geometry;
|
||||||
|
elemGeom->setVertexArray(osgVertices);
|
||||||
|
elemGeom->setNormalArray(osgNormals);
|
||||||
|
elemGeom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::DrawArrays> drawArrays = new osg::DrawArrays(
|
||||||
|
osg::PrimitiveSet::TRIANGLES, 0, osgVertices->size());
|
||||||
|
elemGeom->addPrimitiveSet(drawArrays);
|
||||||
|
|
||||||
// materials
|
// materials
|
||||||
const std::vector<IfcGeom::Material>& elemMats = triElemGeom->materials();
|
const std::vector<IfcGeom::Material>& elemMats = triElemGeom->materials();
|
||||||
for (auto mat : elemMats) {
|
std::vector<osg::ref_ptr<osg::Material>> elemOsgMats;
|
||||||
MessageLogger::log(" " + mat.original_name());
|
for (const IfcGeom::Material& mat : elemMats) {
|
||||||
|
//MessageLogger::log(" " + mat.original_name());
|
||||||
|
elemOsgMats.push_back(getOsgMaterial(mat));
|
||||||
}
|
}
|
||||||
|
if (elemOsgMats.size()) {
|
||||||
|
// Todo: set respective material for each part of the element
|
||||||
|
elemGeom->getOrCreateStateSet()->setAttributeAndModes(elemOsgMats[0].get());
|
||||||
|
} else { // sometimes material values are not available (like for IfcOpeningElement)
|
||||||
|
osg::ref_ptr<osg::Material> osgMaterial = new osg::Material;
|
||||||
|
osgMaterial->setDiffuse(osg::Material::FRONT_AND_BACK, this->getDefaultOsgDiffuseColor());
|
||||||
|
elemGeom->getOrCreateStateSet()->setAttributeAndModes(osgMaterial.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
geometries.push_back(elemGeom);
|
||||||
|
|
||||||
} while (it->next());
|
} while (it->next());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Triangle> ParseIfcFile::createTriangles(
|
||||||
|
const std::vector<int>& elemFaces,
|
||||||
|
const std::vector<double>& elemVertices,
|
||||||
|
const std::vector<double>& elemNormals
|
||||||
|
) {
|
||||||
|
|
||||||
|
std::vector<Triangle> triangles;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < elemFaces.size(); i += 3) {
|
||||||
|
|
||||||
|
auto createVertexWithNormal = [elemFaces, elemVertices, elemNormals](size_t fi) {
|
||||||
|
|
||||||
|
VertexWithNormal vn;
|
||||||
|
|
||||||
|
size_t initVertIndex = 3 * elemFaces[fi];
|
||||||
|
size_t x_vertIndex = initVertIndex;
|
||||||
|
size_t y_vertIndex = initVertIndex + 1;
|
||||||
|
size_t z_vertIndex = initVertIndex + 2;
|
||||||
|
|
||||||
|
vn.vertex = osg::Vec3 (
|
||||||
|
elemVertices[x_vertIndex],
|
||||||
|
elemVertices[y_vertIndex],
|
||||||
|
elemVertices[z_vertIndex]
|
||||||
|
);
|
||||||
|
|
||||||
|
vn.normal = osg::Vec3 (
|
||||||
|
elemNormals[x_vertIndex],
|
||||||
|
elemNormals[y_vertIndex],
|
||||||
|
elemNormals[z_vertIndex]
|
||||||
|
);
|
||||||
|
|
||||||
|
return vn;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto createTriangle = [createVertexWithNormal, i]() {
|
||||||
|
|
||||||
|
Triangle triangle;
|
||||||
|
|
||||||
|
triangle.vn1 = createVertexWithNormal(i);
|
||||||
|
triangle.vn2 = createVertexWithNormal(i + 1);
|
||||||
|
triangle.vn3 = createVertexWithNormal(i + 2);
|
||||||
|
|
||||||
|
return triangle;
|
||||||
|
};
|
||||||
|
|
||||||
|
triangles.push_back(createTriangle());
|
||||||
|
}
|
||||||
|
|
||||||
|
return triangles;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::Vec4 ParseIfcFile::getDefaultOsgDiffuseColor()
|
||||||
|
{
|
||||||
|
osg::Vec4 osgDiffuseColor(0.4f, 0.4f, 0.8f, 1.0f);
|
||||||
|
return osgDiffuseColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Material> ParseIfcFile::getOsgMaterial(const IfcGeom::Material& material)
|
||||||
|
{
|
||||||
|
osg::Vec4 osgDiffuseColor = getDefaultOsgDiffuseColor();
|
||||||
|
|
||||||
|
if(material.hasDiffuse()) {
|
||||||
|
const double* diffuseColor = material.diffuse();
|
||||||
|
osg::Vec4 matOsgDiffuseColor(
|
||||||
|
diffuseColor[0],
|
||||||
|
diffuseColor[1],
|
||||||
|
diffuseColor[2],
|
||||||
|
material.transparency()
|
||||||
|
);
|
||||||
|
osgDiffuseColor = matOsgDiffuseColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Material> osgMaterial = new osg::Material;
|
||||||
|
osgMaterial->setDiffuse(osg::Material::FRONT_AND_BACK, osgDiffuseColor);
|
||||||
|
|
||||||
|
return osgMaterial;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,14 +4,43 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "../ifcgeom_schema_agnostic/IfcGeomIterator.h"
|
||||||
|
#include "osg/Material"
|
||||||
|
#include "osg/ref_ptr"
|
||||||
|
#include "osg/Geometry"
|
||||||
|
|
||||||
|
struct VertexWithNormal {
|
||||||
|
osg::Vec3 vertex;
|
||||||
|
osg::Vec3 normal;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Triangle {
|
||||||
|
VertexWithNormal vn1;
|
||||||
|
VertexWithNormal vn2;
|
||||||
|
VertexWithNormal vn3;
|
||||||
|
};
|
||||||
|
|
||||||
class ParseIfcFile : public QObject
|
class ParseIfcFile : public QObject
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ParseIfcFile();
|
ParseIfcFile();
|
||||||
~ParseIfcFile();
|
~ParseIfcFile();
|
||||||
|
|
||||||
void Parse(const std::string& filePath);
|
bool Parse(
|
||||||
|
const std::string& filePath,
|
||||||
|
std::vector<osg::ref_ptr<osg::Geometry>>& geometries
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<Triangle> createTriangles(
|
||||||
|
const std::vector<int>& elemFaces,
|
||||||
|
const std::vector<double>& elemVertices,
|
||||||
|
const std::vector<double>& elemNormals
|
||||||
|
);
|
||||||
|
osg::Vec4 getDefaultOsgDiffuseColor();
|
||||||
|
osg::ref_ptr<osg::Material> getOsgMaterial(const IfcGeom::Material& material);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PARSEIFCFILE_H
|
#endif // PARSEIFCFILE_H
|
||||||
|
|||||||
Reference in New Issue
Block a user