diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2014-09-12 11:27:24 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2014-09-12 12:15:02 +0300 |
commit | e5f6ab99b413ad9b8481ad923c5a4a5bc6513ff2 (patch) | |
tree | 85fd24fe13281b882e989a5f6826bc3cdad41446 /src/datavisualization/data | |
parent | ddb9be979d93b7e17f1067dc6056de54d9828b29 (diff) |
Implement volume slice frames
Change-Id: I409f3c95892b26ca6097dd4509109fc9978b9900
Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'src/datavisualization/data')
-rw-r--r-- | src/datavisualization/data/abstractrenderitem_p.h | 6 | ||||
-rw-r--r-- | src/datavisualization/data/customrenderitem.cpp | 32 | ||||
-rw-r--r-- | src/datavisualization/data/customrenderitem_p.h | 78 | ||||
-rw-r--r-- | src/datavisualization/data/qcustom3ditem.cpp | 10 | ||||
-rw-r--r-- | src/datavisualization/data/qcustom3dvolume.cpp | 303 | ||||
-rw-r--r-- | src/datavisualization/data/qcustom3dvolume.h | 26 | ||||
-rw-r--r-- | src/datavisualization/data/qcustom3dvolume_p.h | 11 |
7 files changed, 405 insertions, 61 deletions
diff --git a/src/datavisualization/data/abstractrenderitem_p.h b/src/datavisualization/data/abstractrenderitem_p.h index 57977a3c..ccee2b00 100644 --- a/src/datavisualization/data/abstractrenderitem_p.h +++ b/src/datavisualization/data/abstractrenderitem_p.h @@ -48,10 +48,12 @@ public: inline void setTranslation(const QVector3D &translation) { m_translation = translation; } inline const QVector3D &translation() const {return m_translation; } - inline QQuaternion rotation() const { return m_rotation; } + inline const QQuaternion &rotation() const { return m_rotation; } inline void setRotation(const QQuaternion &rotation) { - if (m_rotation != rotation) + if (rotation.isNull()) + m_rotation = identityQuaternion; + else m_rotation = rotation; } diff --git a/src/datavisualization/data/customrenderitem.cpp b/src/datavisualization/data/customrenderitem.cpp index 64194bac..f56ca86e 100644 --- a/src/datavisualization/data/customrenderitem.cpp +++ b/src/datavisualization/data/customrenderitem.cpp @@ -45,7 +45,10 @@ CustomRenderItem::CustomRenderItem() m_sliceIndexZ(-1), m_alphaMultiplier(1.0f), m_preserveOpacity(true), - m_useHighDefShader(true) + m_useHighDefShader(true), + m_drawSlices(false), + m_drawSliceFrames(false) + { } @@ -75,4 +78,31 @@ void CustomRenderItem::setColorTable(const QVector<QRgb> &colors) } } +void CustomRenderItem::setMinBounds(const QVector3D &bounds) +{ + m_minBounds = bounds; + m_minBoundsNormal = m_minBounds; + m_minBoundsNormal.setY(-m_minBoundsNormal.y()); + m_minBoundsNormal.setZ(-m_minBoundsNormal.z()); + m_minBoundsNormal = 0.5f * (m_minBoundsNormal + oneVector); +} + +void CustomRenderItem::setMaxBounds(const QVector3D &bounds) +{ + m_maxBounds = bounds; + m_maxBoundsNormal = m_maxBounds; + m_maxBoundsNormal.setY(-m_maxBoundsNormal.y()); + m_maxBoundsNormal.setZ(-m_maxBoundsNormal.z()); + m_maxBoundsNormal = 0.5f * (m_maxBoundsNormal + oneVector); +} + +void CustomRenderItem::setSliceFrameColor(const QColor &color) +{ + const QRgb &rgb = color.rgba(); + m_sliceFrameColor = QVector4D(float(qRed(rgb)) / 255.0f, + float(qGreen(rgb)) / 255.0f, + float(qBlue(rgb)) / 255.0f, + float(1.0f)); // Alpha not supported for frames +} + QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/customrenderitem_p.h b/src/datavisualization/data/customrenderitem_p.h index 84fc898a..ad868fac 100644 --- a/src/datavisualization/data/customrenderitem_p.h +++ b/src/datavisualization/data/customrenderitem_p.h @@ -33,6 +33,7 @@ #include "objecthelper_p.h" #include <QtGui/QRgb> #include <QtGui/QImage> +#include <QtGui/QColor> QT_BEGIN_NAMESPACE_DATAVISUALIZATION @@ -50,13 +51,13 @@ public: void setMesh(const QString &meshFile); inline ObjectHelper *mesh() const { return m_object; } inline void setScaling(const QVector3D &scaling) { m_scaling = scaling; } - inline QVector3D scaling() const { return m_scaling; } + inline const QVector3D &scaling() const { return m_scaling; } inline void setOrigScaling(const QVector3D &scaling) { m_origScaling = scaling; } - inline QVector3D origScaling() const { return m_origScaling; } + inline const QVector3D &origScaling() const { return m_origScaling; } inline void setPosition(const QVector3D &position) { m_position = position; } - inline QVector3D position() const { return m_position; } + inline const QVector3D &position() const { return m_position; } inline void setOrigPosition(const QVector3D &position) { m_origPosition = position; } - inline QVector3D origPosition() const { return m_origPosition; } + inline const QVector3D &origPosition() const { return m_origPosition; } inline void setPositionAbsolute(bool absolute) { m_positionAbsolute = absolute; } inline bool isPositionAbsolute() const { return m_positionAbsolute; } inline void setScalingAbsolute(bool absolute) { m_scalingAbsolute = absolute; } @@ -80,11 +81,11 @@ public: inline bool isLabel() const { return m_labelItem; } // Volume specific - inline void setTextureWidth(int width) { m_textureWidth = width; } + inline void setTextureWidth(int width) { m_textureWidth = width; setSliceIndexX(m_sliceIndexX); } inline int textureWidth() const { return m_textureWidth; } - inline void setTextureHeight(int height) { m_textureHeight = height; } + inline void setTextureHeight(int height) { m_textureHeight = height; setSliceIndexY(m_sliceIndexY); } inline int textureHeight() const { return m_textureHeight; } - inline void setTextureDepth(int depth) { m_textureDepth = depth; } + inline void setTextureDepth(int depth) { m_textureDepth = depth; setSliceIndexZ(m_sliceIndexZ); } inline int textureDepth() const { return m_textureDepth; } inline int textureSize() const { return m_textureWidth * m_textureHeight * m_textureDepth; } inline void setColorTable(const QVector<QVector4D> &colors) { m_colorTable = colors; } @@ -94,9 +95,22 @@ public: inline bool isVolume() const { return m_isVolume; } inline void setTextureFormat(QImage::Format format) { m_textureFormat = format; } inline QImage::Format textureFormat() const { return m_textureFormat; } - inline void setSliceIndexX(int index) { m_sliceIndexX = index; } - inline void setSliceIndexY(int index) { m_sliceIndexY = index; } - inline void setSliceIndexZ(int index) { m_sliceIndexZ = index; } + inline void setSliceIndexX(int index) + { + m_sliceIndexX = index; + m_sliceFractions.setX((float(index) + 0.5f) / float(m_textureWidth) * 2.0 - 1.0); + } + inline void setSliceIndexY(int index) + { + m_sliceIndexY = index; + m_sliceFractions.setY((float(index) + 0.5f) / float(m_textureHeight) * 2.0 - 1.0); + } + inline void setSliceIndexZ(int index) + { + m_sliceIndexZ = index; + m_sliceFractions.setZ((float(index) + 0.5f) / float(m_textureDepth) * 2.0 - 1.0); + } + inline const QVector3D &sliceFractions() const { return m_sliceFractions; } inline int sliceIndexX() const { return m_sliceIndexX; } inline int sliceIndexY() const { return m_sliceIndexY; } inline int sliceIndexZ() const { return m_sliceIndexZ; } @@ -106,25 +120,24 @@ public: inline bool preserveOpacity() const { return m_preserveOpacity; } inline void setUseHighDefShader(bool enable) { m_useHighDefShader = enable; } inline bool useHighDefShader() const {return m_useHighDefShader; } - inline void setMinBounds(const QVector3D &bounds) { - m_minBounds = bounds; - m_minBoundsNormal = m_minBounds; - m_minBoundsNormal.setY(-m_minBoundsNormal.y()); - m_minBoundsNormal.setZ(-m_minBoundsNormal.z()); - m_minBoundsNormal = 0.5f * (m_minBoundsNormal + oneVector); - - } - inline QVector3D minBounds() const { return m_minBounds; } - inline void setMaxBounds(const QVector3D &bounds) { - m_maxBounds = bounds; - m_maxBoundsNormal = m_maxBounds; - m_maxBoundsNormal.setY(-m_maxBoundsNormal.y()); - m_maxBoundsNormal.setZ(-m_maxBoundsNormal.z()); - m_maxBoundsNormal = 0.5f * (m_maxBoundsNormal + oneVector); - } - inline QVector3D maxBounds() const { return m_maxBounds; } - inline QVector3D minBoundsNormal() const { return m_minBoundsNormal; } - inline QVector3D maxBoundsNormal() const { return m_maxBoundsNormal; } + void setMinBounds(const QVector3D &bounds); + inline const QVector3D &minBounds() const { return m_minBounds; } + void setMaxBounds(const QVector3D &bounds); + inline const QVector3D &maxBounds() const { return m_maxBounds; } + inline const QVector3D &minBoundsNormal() const { return m_minBoundsNormal; } + inline const QVector3D &maxBoundsNormal() const { return m_maxBoundsNormal; } + inline void setDrawSlices(bool enable) { m_drawSlices = enable; } + inline bool drawSlices() const {return m_drawSlices; } + inline void setDrawSliceFrames(bool enable) { m_drawSliceFrames = enable; } + inline bool drawSliceFrames() const {return m_drawSliceFrames; } + void setSliceFrameColor(const QColor &color); + inline const QVector4D &sliceFrameColor() const { return m_sliceFrameColor; } + inline void setSliceFrameWidths(const QVector3D &widths) { m_sliceFrameWidths = widths * 2.0f; } + inline const QVector3D &sliceFrameWidths() const { return m_sliceFrameWidths; } + inline void setSliceFrameGaps(const QVector3D &gaps) { m_sliceFrameGaps = gaps * 2.0f; } + inline const QVector3D &sliceFrameGaps() const { return m_sliceFrameGaps; } + inline void setSliceFrameThicknesses(const QVector3D &thicknesses) { m_sliceFrameThicknesses = thicknesses; } + inline const QVector3D &sliceFrameThicknesses() const { return m_sliceFrameThicknesses; } private: Q_DISABLE_COPY(CustomRenderItem) @@ -157,6 +170,7 @@ private: int m_sliceIndexX; int m_sliceIndexY; int m_sliceIndexZ; + QVector3D m_sliceFractions; float m_alphaMultiplier; bool m_preserveOpacity; bool m_useHighDefShader; @@ -164,6 +178,12 @@ private: QVector3D m_maxBounds; QVector3D m_minBoundsNormal; QVector3D m_maxBoundsNormal; + bool m_drawSlices; + bool m_drawSliceFrames; + QVector4D m_sliceFrameColor; + QVector3D m_sliceFrameWidths; + QVector3D m_sliceFrameGaps; + QVector3D m_sliceFrameThicknesses; }; typedef QHash<QCustom3DItem *, CustomRenderItem *> CustomRenderItemArray; diff --git a/src/datavisualization/data/qcustom3ditem.cpp b/src/datavisualization/data/qcustom3ditem.cpp index 4e82d47a..b9825732 100644 --- a/src/datavisualization/data/qcustom3ditem.cpp +++ b/src/datavisualization/data/qcustom3ditem.cpp @@ -101,7 +101,9 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION * values. Defaults to \c{true}. Items with absolute scaling will be rendered at the same * size, regardless of axis ranges. Items with data scaling will change their apparent size * according to the axis ranges. If positionAbsolute value is \c{true}, this property is ignored - * and scaling is interpreted as an absolute value. + * and scaling is interpreted as an absolute value. If the item has rotation, the data scaling + * is calculated on the unrotated item. Similarly, for Custom3DVolume items, the range clipping + * is calculated on the unrotated item. * * \note: Only absolute scaling is supported for Custom3DLabel items or for custom items used in * \l{AbstractGraph3D::polar}{polar} graphs. @@ -282,7 +284,9 @@ QVector3D QCustom3DItem::scaling() const * values. Defaults to \c{true}. Items with absolute scaling will be rendered at the same * size, regardless of axis ranges. Items with data scaling will change their apparent size * according to the axis ranges. If positionAbsolute value is \c{true}, this property is ignored - * and scaling is interpreted as an absolute value. + * and scaling is interpreted as an absolute value. If the item has rotation, the data scaling + * is calculated on the unrotated item. Similarly, for QCustom3DVolume items, the range clipping + * is calculated on the unrotated item. * * \note: Only absolute scaling is supported for QCustom3DLabel items or for custom items used in * \l{QAbstract3DGraph::polar}{polar} graphs. @@ -438,7 +442,7 @@ QCustom3DItemPrivate::QCustom3DItemPrivate(QCustom3DItem *q) : m_positionAbsolute(false), m_scaling(QVector3D(0.1f, 0.1f, 0.1f)), m_scalingAbsolute(true), - m_rotation(QQuaternion(0.0f, 0.0f, 0.0f, 0.0f)), + m_rotation(identityQuaternion), m_visible(true), m_shadowCasting(true), m_isLabelItem(false), diff --git a/src/datavisualization/data/qcustom3dvolume.cpp b/src/datavisualization/data/qcustom3dvolume.cpp index 78c91802..563af31a 100644 --- a/src/datavisualization/data/qcustom3dvolume.cpp +++ b/src/datavisualization/data/qcustom3dvolume.cpp @@ -104,31 +104,34 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION /*! \qmlproperty int Custom3DVolume::sliceIndexX * * The X dimension index into the texture data indicating which vertical slice to show. - * Setting any dimension to negative indicates no slice for that dimension is drawn. - * If all dimensions are negative, no slices are drawn and the volume is drawn normally. + * Setting any dimension to negative indicates no slice or slice frame for that dimension is drawn. + * If all dimensions are negative, no slices or slice frames are drawn and the volume is drawn + * normally. * Defaults to \c{-1}. * - * \sa QCustom3DVolume::textureData + * \sa QCustom3DVolume::textureData, drawSlices, drawSliceFrames */ /*! \qmlproperty int Custom3DVolume::sliceIndexY * * The Y dimension index into the texture data indicating which horizontal slice to show. - * Setting any dimension to negative indicates no slice for that dimension is drawn. - * If all dimensions are negative, no slices are drawn and the volume is drawn normally. + * Setting any dimension to negative indicates no slice or slice frame for that dimension is drawn. + * If all dimensions are negative, no slices or slice frames are drawn and the volume is drawn + * normally. * Defaults to \c{-1}. * - * \sa QCustom3DVolume::textureData + * \sa QCustom3DVolume::textureData, drawSlices, drawSliceFrames */ /*! \qmlproperty int Custom3DVolume::sliceIndexZ * * The Z dimension index into the texture data indicating which vertical slice to show. - * Setting any dimension to negative indicates no slice for that dimension is drawn. - * If all dimensions are negative, no slices are drawn and the volume is drawn normally. + * Setting any dimension to negative indicates no slice or slice frame for that dimension is drawn. + * If all dimensions are negative, no slices or slice frames are drawn and the volume is drawn + * normally. * Defaults to \c{-1}. * - * \sa QCustom3DVolume::textureData + * \sa QCustom3DVolume::textureData, drawSlices, drawSliceFrames */ /*! @@ -174,6 +177,79 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION */ /*! + * \qmlproperty bool Custom3DVolume::drawSlices + * + * If this property value is \c{true}, the slices indicated by slice index properties + * will be drawn instead of the full volume. + * If it is \c{false}, the full volume will always be drawn. + * Defaults to \c{false}. + * + * \note The slices are always drawn along the item axes, so if the item is rotated, the slices are + * rotated as well. + * + * \sa sliceIndexX, sliceIndexY, sliceIndexZ + */ + +/*! + * \qmlproperty bool Custom3DVolume::drawSliceFrames + * + * If this property value is \c{true}, the frames of slices indicated by slice index properties + * will be drawn around the volume. + * If it is \c{false}, no slice frames will be drawn. + * Drawing slice frames is independent of drawing slices, so you can show the full volume and + * still draw the slice frames around it. + * Defaults to \c{false}. + * + * \sa sliceIndexX, sliceIndexY, sliceIndexZ, drawSlices + */ + +/*! + * \qmlproperty color Custom3DVolume::sliceFrameColor + * + * Indicates the color of the slice frame. Transparent slice frame color is not supported. + * + * Defaults to black. + * + * \sa drawSliceFrames + */ + +/*! + * \qmlproperty vector3d Custom3DVolume::sliceFrameWidths + * + * Indicates the widths of the slice frame. The width can be different on different dimensions, + * so you can for example omit drawing the frames on certain sides of the volume by setting the + * value for that dimension to zero. The values are fractions of the volume thickness in the same + * dimension. The values cannot be negative. + * + * Defaults to \c{vector3d(0.01, 0.01, 0.01)}. + * + * \sa drawSliceFrames + */ + +/*! + * \qmlproperty vector3d Custom3DVolume::sliceFrameGaps + * + * Indicates the amount of air gap left between the volume itself and the frame in each dimension. + * The gap can be different on different dimensions. The values are fractions of the volume + * thickness in the same dimension. The values cannot be negative. + * + * Defaults to \c{vector3d(0.01, 0.01, 0.01)}. + * + * \sa drawSliceFrames + */ + +/*! + * \qmlproperty vector3d Custom3DVolume::sliceFrameThicknesses + * + * Indicates the thickness of the slice frames for each dimension. The values are fractions of + * the volume thickness in the same dimension. The values cannot be negative. + * + * Defaults to \c{vector3d(0.01, 0.01, 0.01)}. + * + * \sa drawSliceFrames + */ + +/*! * Constructs QCustom3DVolume with given \a parent. */ QCustom3DVolume::QCustom3DVolume(QObject *parent) : @@ -324,17 +400,18 @@ int QCustom3DVolume::textureDataWidth() const /*! \property QCustom3DVolume::sliceIndexX * * The X dimension index into the texture data indicating which vertical slice to show. - * Setting any dimension to negative indicates no slice for that dimension is drawn. - * If all dimensions are negative, no slices are drawn and the volume is drawn normally. + * Setting any dimension to negative indicates no slice or slice frame for that dimension is drawn. + * If all dimensions are negative, no slices or slice frames are drawn and the volume is drawn + * normally. * Defaults to \c{-1}. * - * \sa textureData + * \sa textureData, drawSlices, drawSliceFrames */ void QCustom3DVolume::setSliceIndexX(int value) { if (dptr()->m_sliceIndexX != value) { dptr()->m_sliceIndexX = value; - dptr()->m_dirtyBitsVolume.sliceIndicesDirty = true; + dptr()->m_dirtyBitsVolume.slicesDirty = true; emit sliceIndexXChanged(value); emit dptr()->needUpdate(); } @@ -348,17 +425,18 @@ int QCustom3DVolume::sliceIndexX() const /*! \property QCustom3DVolume::sliceIndexY * * The Y dimension index into the texture data indicating which horizontal slice to show. - * Setting any dimension to negative indicates no slice for that dimension is drawn. - * If all dimensions are negative, no slices are drawn and the volume is drawn normally. + * Setting any dimension to negative indicates no slice or slice frame for that dimension is drawn. + * If all dimensions are negative, no slices or slice frames are drawn and the volume is drawn + * normally. * Defaults to \c{-1}. * - * \sa textureData + * \sa textureData, drawSlices, drawSliceFrames */ void QCustom3DVolume::setSliceIndexY(int value) { if (dptr()->m_sliceIndexY != value) { dptr()->m_sliceIndexY = value; - dptr()->m_dirtyBitsVolume.sliceIndicesDirty = true; + dptr()->m_dirtyBitsVolume.slicesDirty = true; emit sliceIndexYChanged(value); emit dptr()->needUpdate(); } @@ -372,17 +450,18 @@ int QCustom3DVolume::sliceIndexY() const /*! \property QCustom3DVolume::sliceIndexZ * * The Z dimension index into the texture data indicating which vertical slice to show. - * Setting any dimension to negative indicates no slice for that dimension is drawn. - * If all dimensions are negative, no slices are drawn and the volume is drawn normally. + * Setting any dimension to negative indicates no slice or slice frame for that dimension is drawn. + * If all dimensions are negative, no slices or slice frames are drawn and the volume is drawn + * normally. * Defaults to \c{-1}. * - * \sa textureData + * \sa textureData, drawSlices, drawSliceFrames */ void QCustom3DVolume::setSliceIndexZ(int value) { if (dptr()->m_sliceIndexZ != value) { dptr()->m_sliceIndexZ = value; - dptr()->m_dirtyBitsVolume.sliceIndicesDirty = true; + dptr()->m_dirtyBitsVolume.slicesDirty = true; emit sliceIndexZChanged(value); emit dptr()->needUpdate(); } @@ -817,6 +896,170 @@ bool QCustom3DVolume::useHighDefShader() const } /*! + * \property QCustom3DVolume::drawSlices + * + * If this property value is \c{true}, the slices indicated by slice index properties + * will be drawn instead of the full volume. + * If it is \c{false}, the full volume will always be drawn. + * Defaults to \c{false}. + * + * \note The slices are always drawn along the item axes, so if the item is rotated, the slices are + * rotated as well. + * + * \sa sliceIndexX, sliceIndexY, sliceIndexZ + */ +void QCustom3DVolume::setDrawSlices(bool enable) +{ + if (dptr()->m_drawSlices != enable) { + dptr()->m_drawSlices = enable; + dptr()->m_dirtyBitsVolume.slicesDirty = true; + emit drawSlicesChanged(enable); + emit dptr()->needUpdate(); + } +} + +bool QCustom3DVolume::drawSlices() const +{ + return dptrc()->m_drawSlices; +} + +/*! + * \property QCustom3DVolume::drawSliceFrames + * + * If this property value is \c{true}, the frames of slices indicated by slice index properties + * will be drawn around the volume. + * If it is \c{false}, no slice frames will be drawn. + * Drawing slice frames is independent of drawing slices, so you can show the full volume and + * still draw the slice frames around it. This is useful when using renderSlice() to display the + * slices outside the graph itself. + * Defaults to \c{false}. + * + * \sa sliceIndexX, sliceIndexY, sliceIndexZ, drawSlices, renderSlice() + */ +void QCustom3DVolume::setDrawSliceFrames(bool enable) +{ + if (dptr()->m_drawSliceFrames != enable) { + dptr()->m_drawSliceFrames = enable; + dptr()->m_dirtyBitsVolume.slicesDirty = true; + emit drawSliceFramesChanged(enable); + emit dptr()->needUpdate(); + } +} + +bool QCustom3DVolume::drawSliceFrames() const +{ + return dptrc()->m_drawSliceFrames; +} + +/*! + * \property QCustom3DVolume::sliceFrameColor + * + * Indicates the color of the slice frame. Transparent slice frame color is not supported. + * + * Defaults to black. + * + * \sa drawSliceFrames + */ +void QCustom3DVolume::setSliceFrameColor(const QColor &color) +{ + if (dptr()->m_sliceFrameColor != color) { + dptr()->m_sliceFrameColor = color; + dptr()->m_dirtyBitsVolume.slicesDirty = true; + emit sliceFrameColorChanged(color); + emit dptr()->needUpdate(); + } +} + +QColor QCustom3DVolume::sliceFrameColor() const +{ + return dptrc()->m_sliceFrameColor; +} + +/*! + * \property QCustom3DVolume::sliceFrameWidths + * + * Indicates the widths of the slice frame. The width can be different on different dimensions, + * so you can for example omit drawing the frames on certain sides of the volume by setting the + * value for that dimension to zero. The values are fractions of the volume thickness in the same + * dimension. The values cannot be negative. + * + * Defaults to \c{QVector3D(0.01, 0.01, 0.01)}. + * + * \sa drawSliceFrames + */ +void QCustom3DVolume::setSliceFrameWidths(const QVector3D &values) +{ + if (values.x() < 0.0f || values.y() < 0.0f || values.z() < 0.0f) { + qWarning() << __FUNCTION__ << "Attempted to set negative values."; + } else if (dptr()->m_sliceFrameWidths != values) { + dptr()->m_sliceFrameWidths = values; + dptr()->m_dirtyBitsVolume.slicesDirty = true; + emit sliceFrameWidthsChanged(values); + emit dptr()->needUpdate(); + } +} + +QVector3D QCustom3DVolume::sliceFrameWidths() const +{ + return dptrc()->m_sliceFrameWidths; +} + +/*! + * \property QCustom3DVolume::sliceFrameGaps + * + * Indicates the amount of air gap left between the volume itself and the frame in each dimension. + * The gap can be different on different dimensions. The values are fractions of the volume + * thickness in the same dimension. The values cannot be negative. + * + * Defaults to \c{QVector3D(0.01, 0.01, 0.01)}. + * + * \sa drawSliceFrames + */ +void QCustom3DVolume::setSliceFrameGaps(const QVector3D &values) +{ + if (values.x() < 0.0f || values.y() < 0.0f || values.z() < 0.0f) { + qWarning() << __FUNCTION__ << "Attempted to set negative values."; + } else if (dptr()->m_sliceFrameGaps != values) { + dptr()->m_sliceFrameGaps = values; + dptr()->m_dirtyBitsVolume.slicesDirty = true; + emit sliceFrameGapsChanged(values); + emit dptr()->needUpdate(); + } +} + +QVector3D QCustom3DVolume::sliceFrameGaps() const +{ + return dptrc()->m_sliceFrameGaps; +} + +/*! + * \property QCustom3DVolume::sliceFrameThicknesses + * + * Indicates the thickness of the slice frames for each dimension. The values are fractions of + * the volume thickness in the same dimension. The values cannot be negative. + * + * Defaults to \c{QVector3D(0.01, 0.01, 0.01)}. + * + * \sa drawSliceFrames + */ +void QCustom3DVolume::setSliceFrameThicknesses(const QVector3D &values) +{ + if (values.x() < 0.0f || values.y() < 0.0f || values.z() < 0.0f) { + qWarning() << __FUNCTION__ << "Attempted to set negative values."; + } else if (dptr()->m_sliceFrameThicknesses != values) { + dptr()->m_sliceFrameThicknesses = values; + dptr()->m_dirtyBitsVolume.slicesDirty = true; + emit sliceFrameThicknessesChanged(values); + emit dptr()->needUpdate(); + } +} + +QVector3D QCustom3DVolume::sliceFrameThicknesses() const +{ + return dptrc()->m_sliceFrameThicknesses; +} + +/*! * Renders the slice specified by \a index along \a axis into an image. * The texture format of this object is used. * @@ -857,7 +1100,13 @@ QCustom3DVolumePrivate::QCustom3DVolumePrivate(QCustom3DVolume *q) : m_textureData(0), m_alphaMultiplier(1.0f), m_preserveOpacity(true), - m_useHighDefShader(true) + m_useHighDefShader(true), + m_drawSlices(false), + m_drawSliceFrames(false), + m_sliceFrameColor(Qt::black), + m_sliceFrameWidths(QVector3D(0.01f, 0.01f, 0.01f)), + m_sliceFrameGaps(QVector3D(0.01f, 0.01f, 0.01f)), + m_sliceFrameThicknesses(QVector3D(0.01f, 0.01f, 0.01f)) { m_isVolumeItem = true; m_meshFile = QStringLiteral(":/defaultMeshes/barFull"); @@ -882,7 +1131,13 @@ QCustom3DVolumePrivate::QCustom3DVolumePrivate(QCustom3DVolume *q, const QVector m_textureData(textureData), m_alphaMultiplier(1.0f), m_preserveOpacity(true), - m_useHighDefShader(true) + m_useHighDefShader(true), + m_drawSlices(false), + m_drawSliceFrames(false), + m_sliceFrameColor(Qt::black), + m_sliceFrameWidths(QVector3D(0.01f, 0.01f, 0.01f)), + m_sliceFrameGaps(QVector3D(0.01f, 0.01f, 0.01f)), + m_sliceFrameThicknesses(QVector3D(0.01f, 0.01f, 0.01f)) { m_isVolumeItem = true; m_shadowCasting = false; @@ -909,7 +1164,7 @@ void QCustom3DVolumePrivate::resetDirtyBits() QCustom3DItemPrivate::resetDirtyBits(); m_dirtyBitsVolume.textureDimensionsDirty = false; - m_dirtyBitsVolume.sliceIndicesDirty = false; + m_dirtyBitsVolume.slicesDirty = false; m_dirtyBitsVolume.colorTableDirty = false; m_dirtyBitsVolume.textureDataDirty = false; m_dirtyBitsVolume.textureFormatDirty = false; diff --git a/src/datavisualization/data/qcustom3dvolume.h b/src/datavisualization/data/qcustom3dvolume.h index 04434263..a9dfda86 100644 --- a/src/datavisualization/data/qcustom3dvolume.h +++ b/src/datavisualization/data/qcustom3dvolume.h @@ -42,6 +42,12 @@ class QT_DATAVISUALIZATION_EXPORT QCustom3DVolume : public QCustom3DItem Q_PROPERTY(float alphaMultiplier READ alphaMultiplier WRITE setAlphaMultiplier NOTIFY alphaMultiplierChanged) Q_PROPERTY(bool preserveOpacity READ preserveOpacity WRITE setPreserveOpacity NOTIFY preserveOpacityChanged) Q_PROPERTY(bool useHighDefShader READ useHighDefShader WRITE setUseHighDefShader NOTIFY useHighDefShaderChanged) + Q_PROPERTY(bool drawSlices READ drawSlices WRITE setDrawSlices NOTIFY drawSlicesChanged) + Q_PROPERTY(bool drawSliceFrames READ drawSliceFrames WRITE setDrawSliceFrames NOTIFY drawSliceFramesChanged) + Q_PROPERTY(QColor sliceFrameColor READ sliceFrameColor WRITE setSliceFrameColor NOTIFY sliceFrameColorChanged) + Q_PROPERTY(QVector3D sliceFrameWidths READ sliceFrameWidths WRITE setSliceFrameWidths NOTIFY sliceFrameWidthsChanged) + Q_PROPERTY(QVector3D sliceFrameGaps READ sliceFrameGaps WRITE setSliceFrameGaps NOTIFY sliceFrameGapsChanged) + Q_PROPERTY(QVector3D sliceFrameThicknesses READ sliceFrameThicknesses WRITE setSliceFrameThicknesses NOTIFY sliceFrameThicknessesChanged) public: @@ -90,6 +96,20 @@ public: void setUseHighDefShader(bool enable); bool useHighDefShader() const; + void setDrawSlices(bool enable); + bool drawSlices() const; + void setDrawSliceFrames(bool enable); + bool drawSliceFrames() const; + + void setSliceFrameColor(const QColor &color); + QColor sliceFrameColor() const; + void setSliceFrameWidths(const QVector3D &values); + QVector3D sliceFrameWidths() const; + void setSliceFrameGaps(const QVector3D &values); + QVector3D sliceFrameGaps() const; + void setSliceFrameThicknesses(const QVector3D &values); + QVector3D sliceFrameThicknesses() const; + QImage renderSlice(Qt::Axis axis, int index); signals: @@ -105,6 +125,12 @@ signals: void alphaMultiplierChanged(float mult); void preserveOpacityChanged(bool enabled); void useHighDefShaderChanged(bool enabled); + void drawSlicesChanged(bool enabled); + void drawSliceFramesChanged(bool enabled); + void sliceFrameColorChanged(const QColor &color); + void sliceFrameWidthsChanged(const QVector3D &values); + void sliceFrameGapsChanged(const QVector3D &values); + void sliceFrameThicknessesChanged(const QVector3D &values); protected: QCustom3DVolumePrivate *dptr(); diff --git a/src/datavisualization/data/qcustom3dvolume_p.h b/src/datavisualization/data/qcustom3dvolume_p.h index 8b0b439e..642d2af5 100644 --- a/src/datavisualization/data/qcustom3dvolume_p.h +++ b/src/datavisualization/data/qcustom3dvolume_p.h @@ -36,7 +36,7 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION struct QCustomVolumeDirtyBitField { bool textureDimensionsDirty : 1; - bool sliceIndicesDirty : 1; + bool slicesDirty : 1; bool colorTableDirty : 1; bool textureDataDirty : 1; bool textureFormatDirty : 1; @@ -45,7 +45,7 @@ struct QCustomVolumeDirtyBitField { QCustomVolumeDirtyBitField() : textureDimensionsDirty(false), - sliceIndicesDirty(false), + slicesDirty(false), colorTableDirty(false), textureDataDirty(false), textureFormatDirty(false), @@ -88,6 +88,13 @@ public: bool m_preserveOpacity; bool m_useHighDefShader; + bool m_drawSlices; + bool m_drawSliceFrames; + QColor m_sliceFrameColor; + QVector3D m_sliceFrameWidths; + QVector3D m_sliceFrameGaps; + QVector3D m_sliceFrameThicknesses; + QCustomVolumeDirtyBitField m_dirtyBitsVolume; private: |