QML support for volume items

Change-Id: I4061bfd4d288aabaea76847c9f692e71ecf5f94c
Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
This commit is contained in:
Miikka Heikkinen 2014-09-02 16:15:08 +03:00
parent 57726e6752
commit d85e665b11
10 changed files with 422 additions and 1 deletions

View File

@ -119,6 +119,7 @@ void QtDataVisualizationQml2Plugin::registerTypes(const char *uri)
// New types
qmlRegisterType<Q3DInputHandler>(uri, 1, 2, "InputHandler3D");
qmlRegisterType<QTouch3DInputHandler>(uri, 1, 2, "TouchInputHandler3D");
qmlRegisterType<QCustom3DVolume>(uri, 1, 2, "Custom3DVolume");
}
QT_END_NAMESPACE_DATAVISUALIZATION

View File

@ -48,6 +48,7 @@
#include "declarativescene_p.h"
#include "qcustom3ditem.h"
#include "qcustom3dlabel.h"
#include "qcustom3dvolume.h"
#include <QtQml/QQmlExtensionPlugin>
@ -103,6 +104,7 @@ QML_DECLARE_TYPE(QTouch3DInputHandler)
QML_DECLARE_TYPE(QCustom3DItem)
QML_DECLARE_TYPE(QCustom3DLabel)
QML_DECLARE_TYPE(QCustom3DVolume)
QT_BEGIN_NAMESPACE_DATAVISUALIZATION

View File

@ -0,0 +1,90 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc
** All rights reserved.
** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.
**
** If you have questions regarding the use of this file, please use
** contact form at http://qt.digia.com
**
****************************************************************************/
#include "datasource.h"
#include <QtCore/qmath.h>
#include <QtGui/QRgb>
#include <QtGui/QVector3D>
using namespace QtDataVisualization;
Q_DECLARE_METATYPE(QCustom3DVolume *)
DataSource::DataSource(QObject *parent) :
QObject(parent)
{
qRegisterMetaType<QCustom3DVolume *>();
}
DataSource::~DataSource()
{
}
void DataSource::fillVolume(QCustom3DVolume *volumeItem)
{
// Generate example texture data for an half-ellipsoid with a section missing.
// This can take a while if the dimensions are large, so we support incremental data generation.
int index = 0;
int textureSize = 256;
QVector3D midPoint(float(textureSize) / 2.0f,
float(textureSize) / 2.0f,
float(textureSize) / 2.0f);
QVector<uchar> *textureData = new QVector<uchar>(textureSize * textureSize * textureSize / 2);
for (int i = 0; i < textureSize; i++) {
for (int j = 0; j < textureSize / 2; j++) {
for (int k = 0; k < textureSize; k++) {
int colorIndex = 0;
// Take a section out of the ellipsoid
if (i >= textureSize / 2 || j >= textureSize / 4 || k >= textureSize / 2) {
QVector3D distVec = QVector3D(float(k), float(j * 2), float(i)) - midPoint;
float adjLen = qMin(255.0f, (distVec.length() * 512.0f / float(textureSize)));
colorIndex = 255 - int(adjLen);
}
(*textureData)[index] = colorIndex;
index++;
}
}
}
volumeItem->setScaling(QVector3D(2.0f, 1.0f, 2.0f));
volumeItem->setTextureWidth(textureSize);
volumeItem->setTextureHeight(textureSize / 2);
volumeItem->setTextureDepth(textureSize);
volumeItem->setTextureFormat(QImage::Format_Indexed8);
volumeItem->setTextureData(textureData);
QVector<QRgb> colorTable(256);
for (int i = 1; i < 256; i++) {
if (i < 15)
colorTable[i] = qRgba(0, 0, 0, 0);
else if (i < 60)
colorTable[i] = qRgba((i * 2) + 120, 0, 0, 15);
else if (i < 120)
colorTable[i] = qRgba(0, ((i - 60) * 2) + 120, 0, 50);
else if (i < 180)
colorTable[i] = qRgba(0, 0, ((i - 120) * 2) + 120, 255);
else
colorTable[i] = qRgba(i, i, i, 255);
}
volumeItem->setColorTable(colorTable);
}

View File

@ -0,0 +1,38 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc
** All rights reserved.
** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.
**
** If you have questions regarding the use of this file, please use
** contact form at http://qt.digia.com
**
****************************************************************************/
#ifndef DATASOURCE_H
#define DATASOURCE_H
#include <QtDataVisualization/QCustom3DVolume>
#include <QtCore/QObject>
using namespace QtDataVisualization;
class DataSource : public QObject
{
Q_OBJECT
public:
explicit DataSource(QObject *parent = 0);
virtual ~DataSource();
public:
Q_INVOKABLE void fillVolume(QCustom3DVolume *volumeItem);
};
#endif

56
tests/qmlvolume/main.cpp Normal file
View File

@ -0,0 +1,56 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc
** All rights reserved.
** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.
**
** If you have questions regarding the use of this file, please use
** contact form at http://qt.digia.com
**
****************************************************************************/
#include "datasource.h"
#include <QtDataVisualization/qutils.h>
#include <QtGui/QGuiApplication>
#include <QtCore/QDir>
#include <QtQml/QQmlContext>
#include <QtQuick/QQuickView>
#include <QtQml/QQmlEngine>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQuickView viewer;
// The following are needed to make examples run without having to install the module
// in desktop environments.
#ifdef Q_OS_WIN
QString extraImportPath(QStringLiteral("%1/../../../%2"));
#else
QString extraImportPath(QStringLiteral("%1/../../%2"));
#endif
viewer.engine()->addImportPath(extraImportPath.arg(QGuiApplication::applicationDirPath(),
QString::fromLatin1("qml")));
QObject::connect(viewer.engine(), &QQmlEngine::quit, &viewer, &QWindow::close);
viewer.setTitle(QStringLiteral("QML volume example"));
DataSource dataSource;
viewer.rootContext()->setContextProperty("dataSource", &dataSource);
viewer.setSource(QUrl("qrc:/qml/qmlvolume/main.qml"));
viewer.setResizeMode(QQuickView::SizeRootObjectToView);
viewer.show();
return app.exec();
}

View File

@ -0,0 +1,52 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc
** All rights reserved.
** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.
**
** If you have questions regarding the use of this file, please use
** contact form at http://qt.digia.com
**
****************************************************************************/
import QtQuick 2.1
import QtQuick.Controls 1.0
import QtQuick.Controls.Styles 1.0
Item {
id: newbutton
property alias text: buttonText.text
signal clicked
implicitWidth: buttonText.implicitWidth + 5
implicitHeight: buttonText.implicitHeight + 10
Button {
id: buttonText
width: parent.width
height: parent.height
style: ButtonStyle {
label: Component {
Text {
text: buttonText.text
clip: true
wrapMode: Text.WordWrap
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
anchors.fill: parent
}
}
}
onClicked: newbutton.clicked()
}
}

View File

@ -0,0 +1,159 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc
** All rights reserved.
** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.
**
** If you have questions regarding the use of this file, please use
** contact form at http://qt.digia.com
**
****************************************************************************/
import QtQuick 2.1
import QtQuick.Layouts 1.0
import QtQuick.Controls 1.0
import QtDataVisualization 1.2
import "."
Item {
id: mainView
width: 1280
height: 1024
Item {
id: dataView
anchors.bottom: parent.bottom
width: parent.width
height: parent.height - buttonLayout.height
Surface3D {
id: surfaceGraph
width: dataView.width
height: dataView.height
orthoProjection: true
measureFps: true
onCurrentFpsChanged: {
if (fps > 10)
fpsText.text = "FPS: " + Math.round(surfaceGraph.currentFps)
else
fpsText.text = "FPS: " + Math.round(surfaceGraph.currentFps * 10.0) / 10.0
}
Surface3DSeries {
id: surfaceSeries
drawMode: Surface3DSeries.DrawSurface;
flatShadingEnabled: false;
meshSmooth: true
itemLabelFormat: "@xLabel, @zLabel: @yLabel"
itemLabelVisible: false
onItemLabelChanged: {
if (surfaceSeries.selectedPoint === surfaceSeries.invalidSelectionPosition)
selectionText.text = "No selection"
else
selectionText.text = surfaceSeries.itemLabel
}
}
Component.onCompleted: {
mainView.createVolume();
}
}
}
Rectangle {
width: parent.width
height: 50
anchors.left: parent.left
anchors.top: parent.top
color: surfaceGraph.theme.backgroundColor
ColumnLayout {
anchors.fill: parent
RowLayout {
id: sliderLayout
anchors.top: parent.top
Layout.fillHeight: true
Layout.fillWidth: true
Layout.minimumHeight: 150
spacing: 0
Rectangle {
Layout.fillHeight: true
Layout.fillWidth: true
Layout.minimumWidth: fpsText.implicitWidth + 10
Layout.maximumWidth: fpsText.implicitWidth + 10
Layout.minimumHeight: 50
Layout.maximumHeight: 50
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
border.color: "gray"
border.width: 1
radius: 4
Text {
id: fpsText
anchors.fill: parent
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
}
}
RowLayout {
id: buttonLayout
Layout.fillHeight: true
Layout.fillWidth: true
Layout.minimumHeight: 50
anchors.bottom: parent.bottom
spacing: 0
NewButton {
id: sliceButton
Layout.fillHeight: true
Layout.fillWidth: true
text: "Slice"
onClicked: {
if (volumeItem.sliceIndexZ == -1)
volumeItem.sliceIndexZ = 128
else
volumeItem.sliceIndexZ = -1
}
}
NewButton {
id: exitButton
Layout.fillHeight: true
Layout.fillWidth: true
text: "Quit"
onClicked: Qt.quit(0);
}
}
}
}
Custom3DVolume {
id: volumeItem
alphaMultiplier: 0.3
preserveOpacity: true
useHighDefShader: false
}
function createVolume() {
surfaceGraph.addCustomItem(volumeItem)
dataSource.fillVolume(volumeItem)
}
}

View File

@ -0,0 +1,16 @@
!include( ../tests.pri ) {
error( "Couldn't find the tests.pri file!" )
}
QT += datavisualization
# The .cpp file which was generated for your project. Feel free to hack it.
SOURCES += main.cpp \
datasource.cpp
HEADERS += datasource.h
RESOURCES += qmlvolume.qrc
OTHER_FILES += doc/src/* \
doc/images/* \
qml/qmlvolume/*

View File

@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/">
<file>qml/qmlvolume/main.qml</file>
<file>qml/qmlvolume/NewButton.qml</file>
</qresource>
</RCC>

View File

@ -17,7 +17,8 @@ SUBDIRS += barstest \
qmlmultiwindow \
itemmodeltest \
qmlmultitest \
volumetrictest
volumetrictest \
qmlvolume
#SUBDIRS += kinectsurface