diff --git a/src/widgets/3dview/CMakeLists.txt b/src/widgets/3dview/CMakeLists.txt index 898d031..90d8ce5 100644 --- a/src/widgets/3dview/CMakeLists.txt +++ b/src/widgets/3dview/CMakeLists.txt @@ -1,23 +1,24 @@ set(3d_SRCS + axisgnomonentity.cpp fileloader.cpp gcodeto4d.cpp gridmesh.cpp linemesh.cpp linemeshgeometry.cpp viewer3d.cpp ) qt5_add_resources(3dfiles_RCS viewer3d.qrc) add_library(Atelier3D STATIC ${3d_SRCS} ${3dfiles_RCS}) target_link_libraries(Atelier3D Qt5::Core Qt5::Qml Qt5::Quick Qt5::Widgets Qt5::3DCore Qt5::3DExtras Qt5::3DRender Qt5::3DInput ) diff --git a/src/widgets/3dview/SceneEntity.qml b/src/widgets/3dview/SceneEntity.qml index c75fa5b..29a56ee 100644 --- a/src/widgets/3dview/SceneEntity.qml +++ b/src/widgets/3dview/SceneEntity.qml @@ -1,71 +1,77 @@ /* Atelier KDE Printer Host for 3D Printing Copyright (C) <2017-2018> Author: Patrick José Pereira - patrickjp@kde.org Kevin Ottens - ervin@kde.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ import QtQuick 2.7 import Qt3D.Core 2.0 import Qt3D.Render 2.0 import Qt3D.Input 2.0 import Qt3D.Extras 2.0 import Atelier 1.0 Entity { id: sceneRoot property string currentFile Camera { id: camera fieldOfView: 45 position: Qt.vector3d( 10.0, -10.0, 35.0 ) upVector: Qt.vector3d( 0.0, 0.85, 0.75 ) viewCenter: Qt.vector3d( 10.0, 10.0, 0.0 ) } FirstPersonCameraController { camera: camera } components: [ RenderSettings { activeFrameGraph: ForwardRenderer { camera: camera + frustumCulling: false } }, InputSettings { } ] Entity { id: gridEntity components: [ PhongMaterial { ambient: "darkBlue" }, GridMesh {} ] } Entity { id: lineEntity components: [ PhongMaterial { ambient: "darkGreen" }, LineMesh { readonly property string currentFile: sceneRoot.currentFile onCurrentFileChanged: readAndRun(currentFile) } ] } + + AxisGnomonEntity { + scale: 0.05 + position: Qt.vector2d(0.075, 0.075) + } } diff --git a/src/widgets/3dview/axisgnomon.bin b/src/widgets/3dview/axisgnomon.bin new file mode 100644 index 0000000..eb617b1 Binary files /dev/null and b/src/widgets/3dview/axisgnomon.bin differ diff --git a/src/widgets/3dview/axisgnomon.gltf b/src/widgets/3dview/axisgnomon.gltf new file mode 100644 index 0000000..e868c26 --- /dev/null +++ b/src/widgets/3dview/axisgnomon.gltf @@ -0,0 +1,138 @@ +{ + "accessors" : [ + { + "bufferView" : 0, + "componentType" : 5121, + "count" : 459, + "max" : [ + 167 + ], + "min" : [ + 0 + ], + "type" : "SCALAR" + }, + { + "bufferView" : 1, + "componentType" : 5126, + "count" : 168, + "max" : [ + 1.3900001049041748, + 1.3900001049041748, + 0.15000000596046448 + ], + "min" : [ + -0.15000000596046448, + -0.15000000596046448, + -1.3900001049041748 + ], + "type" : "VEC3" + }, + { + "bufferView" : 2, + "componentType" : 5126, + "count" : 168, + "max" : [ + 1.0, + 1.0, + 1.0 + ], + "min" : [ + -1.0, + -1.0, + -1.0 + ], + "type" : "VEC3" + }, + { + "bufferView" : 3, + "componentType" : 5126, + "count" : 168, + "max" : [ + 1.0, + 1.0, + 1.0, + 1.0 + ], + "min" : [ + 0.0, + 0.0, + 0.0, + 1.0 + ], + "type" : "VEC4" + } + ], + "asset" : { + "generator" : "Khronos Blender glTF 2.0 exporter", + "version" : "2.0" + }, + "bufferViews" : [ + { + "buffer" : 0, + "byteLength" : 459, + "byteOffset" : 0, + "target" : 34963 + }, + { + "buffer" : 0, + "byteLength" : 2016, + "byteOffset" : 460, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 2016, + "byteOffset" : 2476, + "target" : 34962 + }, + { + "buffer" : 0, + "byteLength" : 2688, + "byteOffset" : 4492, + "target" : 34962 + } + ], + "buffers" : [ + { + "byteLength" : 7180, + "uri" : "axisgnomon.bin" + } + ], + "meshes" : [ + { + "name" : "red", + "primitives" : [ + { + "attributes" : { + "COLOR_0" : 3, + "NORMAL" : 2, + "POSITION" : 1 + }, + "indices" : 0 + } + ] + } + ], + "nodes" : [ + { + "mesh" : 0, + "name" : "red", + "rotation" : [ + 0.7071068286895752, + 0.0, + -0.0, + 0.7071068286895752 + ] + } + ], + "scene" : 0, + "scenes" : [ + { + "name" : "Scene", + "nodes" : [ + 0 + ] + } + ] +} diff --git a/src/widgets/3dview/axisgnomon.vert b/src/widgets/3dview/axisgnomon.vert new file mode 100644 index 0000000..6316b09 --- /dev/null +++ b/src/widgets/3dview/axisgnomon.vert @@ -0,0 +1,54 @@ +/* Atelier KDE Printer Host for 3D Printing + Copyright (C) <2018> + Author: Kevin Ottens - ervin@kde.org + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 3 of + the License or any later version accepted by the membership of + KDE e.V. (or its successor approved by the membership of KDE + e.V.), which shall act as a proxy defined in Section 14 of + version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#version 150 core + +in vec3 vertexPosition; +in vec3 vertexNormal; +in vec4 vertexColor; + +out vec3 worldPosition; +out vec3 worldNormal; +out vec4 color; + +uniform mat4 modelMatrix; +uniform mat3 modelNormalMatrix; +uniform mat4 inverseViewMatrix; + +uniform float aspectRatio; + +uniform mat4 axisGnomonModelMatrix; +uniform mat4 axisGnomonProjectionMatrix; + +void main() +{ + worldNormal = normalize(modelNormalMatrix * vertexNormal); + worldPosition = vec3(modelMatrix * vec4(vertexPosition, 1.0)); + color = vertexColor; + + mat4 projectionMatrix = axisGnomonProjectionMatrix; + projectionMatrix[0][0] = projectionMatrix[0][0] / aspectRatio; + projectionMatrix[0][3] = projectionMatrix[0][3] / aspectRatio; + + mat4 viewRotation = mat4(transpose(mat3(inverseViewMatrix))); + mat4 mvp = projectionMatrix * axisGnomonModelMatrix * viewRotation; + gl_Position = mvp * vec4(vertexPosition, 1.0); +} diff --git a/src/widgets/3dview/axisgnomonentity.cpp b/src/widgets/3dview/axisgnomonentity.cpp new file mode 100644 index 0000000..0718644 --- /dev/null +++ b/src/widgets/3dview/axisgnomonentity.cpp @@ -0,0 +1,127 @@ +/* Atelier KDE Printer Host for 3D Printing + Copyright (C) <2018> + Author: Kevin Ottens - ervin@kde.org + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 3 of + the License or any later version accepted by the membership of + KDE e.V. (or its successor approved by the membership of KDE + e.V.), which shall act as a proxy defined in Section 14 of + version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "axisgnomonentity.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace Qt3DCore; +using namespace Qt3DRender; + +AxisGnomonEntity::AxisGnomonEntity(QNode *parent) + : QEntity(parent), + _modelMatrixParameter(new QParameter(QStringLiteral("axisGnomonModelMatrix"), QMatrix4x4())), + _position(0.1f, 0.1f), + _scale(0.1f) +{ + auto mesh = new QMesh(this); + mesh->setSource(QUrl("qrc:/axisgnomon.gltf")); + addComponent(mesh); + + auto material = new QMaterial(this); + + // Specify the arguments to QMatrix4x4::ortho() in OpenGL window coords. + // Thus the position property is specified in OpenGL window coordinates + // (origin at lower left of window). + QMatrix4x4 projectionMatrix; + projectionMatrix.ortho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f); + material->addParameter(new QParameter(QStringLiteral("axisGnomonProjectionMatrix"), projectionMatrix)); + applyModelMatrix(); + material->addParameter(_modelMatrixParameter); + + auto shaderProgram = new QShaderProgram(material); + shaderProgram->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/axisgnomon.vert")))); + shaderProgram->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/pervertexcolor.frag")))); + + auto technique = new QTechnique(material); + technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL); + technique->graphicsApiFilter()->setMajorVersion(3); + technique->graphicsApiFilter()->setMinorVersion(1); + technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile); + + auto m_filterKey = new QFilterKey(material); + m_filterKey->setName(QStringLiteral("renderingStyle")); + m_filterKey->setValue(QStringLiteral("forward")); + + technique->addFilterKey(m_filterKey); + + auto renderPass = new QRenderPass(material); + renderPass->setShaderProgram(shaderProgram); + + technique->addRenderPass(renderPass); + + auto effect = new QEffect(material); + effect->addTechnique(technique); + + material->setEffect(effect); + + addComponent(material); +} + +AxisGnomonEntity::~AxisGnomonEntity() +{ +} + +QVector2D AxisGnomonEntity::position() const +{ + return _position; +} + +float AxisGnomonEntity::scale() const +{ + return _scale; +} + +void AxisGnomonEntity::setPosition(const QVector2D &position) +{ + if (_position != position) { + _position = position; + applyModelMatrix(); + emit positionChanged(position); + } +} + +void AxisGnomonEntity::setScale(float scale) +{ + if (!qFuzzyCompare(_scale, scale)) { + _scale = scale; + applyModelMatrix(); + emit scaleChanged(scale); + } +} + +void AxisGnomonEntity::applyModelMatrix() +{ + QMatrix4x4 modelMatrix; + modelMatrix.translate(QVector3D(_position, 0.0f)); + modelMatrix.scale(_scale); + _modelMatrixParameter->setValue(modelMatrix); +} + diff --git a/src/widgets/3dview/axisgnomonentity.h b/src/widgets/3dview/axisgnomonentity.h new file mode 100644 index 0000000..1c4f8a9 --- /dev/null +++ b/src/widgets/3dview/axisgnomonentity.h @@ -0,0 +1,58 @@ +/* Atelier KDE Printer Host for 3D Printing + Copyright (C) <2018> + Author: Kevin Ottens - ervin@kde.org + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 3 of + the License or any later version accepted by the membership of + KDE e.V. (or its successor approved by the membership of KDE + e.V.), which shall act as a proxy defined in Section 14 of + version 3 of the license. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include +#include + +namespace Qt3DRender +{ +class QParameter; +} + +class AxisGnomonEntity : public Qt3DCore::QEntity +{ + Q_OBJECT + Q_PROPERTY(QVector2D position READ position WRITE setPosition NOTIFY positionChanged) + Q_PROPERTY(float scale READ scale WRITE setScale NOTIFY scaleChanged) +public: + explicit AxisGnomonEntity(Qt3DCore::QNode *parent = nullptr); + ~AxisGnomonEntity(); + + QVector2D position() const; + float scale() const; + +public Q_SLOTS: + void setPosition(const QVector2D &position); + void setScale(float scale); + +Q_SIGNALS: + void positionChanged(const QVector2D &position); + void scaleChanged(float scale); + +private: + void applyModelMatrix(); + + Qt3DRender::QParameter *_modelMatrixParameter; + QVector2D _position; + float _scale; +}; diff --git a/src/widgets/3dview/viewer3d.cpp b/src/widgets/3dview/viewer3d.cpp index b4e7470..b8f7a15 100644 --- a/src/widgets/3dview/viewer3d.cpp +++ b/src/widgets/3dview/viewer3d.cpp @@ -1,75 +1,78 @@ /* Atelier KDE Printer Host for 3D Printing Copyright (C) <2017> Author: Patrick José Pereira - patrickjp@kde.org Chris Rizzitello - rizzitello@kde.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include + +#include "axisgnomonentity.h" #include "gridmesh.h" #include "viewer3d.h" #include "linemesh.h" Viewer3D::Viewer3D(QWidget *parent) : QWidget(parent) , _lineMesh(new LineMesh) { Q_INIT_RESOURCE(viewer3d); + qmlRegisterType("Atelier", 1, 0, "AxisGnomonEntity"); qmlRegisterType("Atelier", 1, 0, "GridMesh"); qmlRegisterType("Atelier", 1, 0, "LineMesh"); _view = new QQuickView(&_engine, nullptr); auto format = QSurfaceFormat(); format.setVersion(3, 1); format.setProfile(QSurfaceFormat::CoreProfile); _view->setFormat(format); _view->setResizeMode(QQuickView::SizeRootObjectToView); _view->setSource(QUrl(QStringLiteral("qrc:/viewer3d.qml"))); QHBoxLayout *mainLayout = new QHBoxLayout; mainLayout->addWidget(QWidget::createWindowContainer(_view)); QObject *item = _view->rootObject(); //Connect the drop pass from the QML part. connect(item, SIGNAL(droppedUrls(QVariant)), this, SLOT(dropCatch(QVariant))); this->setLayout(mainLayout); } Viewer3D::~Viewer3D() { } void Viewer3D::dropCatch(const QVariant &var) { emit droppedUrls(var.value >()); } void Viewer3D::drawModel(QString file) { QObject *object = _view->rootObject(); QObject *fileName = object->findChild(QStringLiteral("fileName")); fileName->setProperty("text", QVariant(file)); } diff --git a/src/widgets/3dview/viewer3d.qrc b/src/widgets/3dview/viewer3d.qrc index 2c53003..fc864bd 100644 --- a/src/widgets/3dview/viewer3d.qrc +++ b/src/widgets/3dview/viewer3d.qrc @@ -1,6 +1,9 @@ SceneEntity.qml viewer3d.qml + axisgnomon.gltf + axisgnomon.bin + axisgnomon.vert