void checkPropertyUpdates() { // GIVEN TestArbiter arbiter; QScopedPointer<Qt3DRender::QGeometry> geometry(new Qt3DRender::QGeometry()); arbiter.setArbiterOnNode(geometry.data()); // WHEN Qt3DRender::QAttribute attr; geometry->addAttribute(&attr); QCoreApplication::processEvents(); // THEN QCOMPARE(arbiter.events.size(), 1); Qt3DCore::QPropertyNodeAddedChangePtr nodeAddedChange = arbiter.events.first().staticCast<Qt3DCore::QPropertyNodeAddedChange>(); QCOMPARE(nodeAddedChange->propertyName(), "attribute"); QCOMPARE(nodeAddedChange->addedNodeId(), attr.id()); QCOMPARE(nodeAddedChange->type(), Qt3DCore::PropertyValueAdded); arbiter.events.clear(); // WHEN geometry->addAttribute(&attr); QCoreApplication::processEvents(); // THEN QCOMPARE(arbiter.events.size(), 0); // WHEN geometry->removeAttribute(&attr); QCoreApplication::processEvents(); // THEN QCOMPARE(arbiter.events.size(), 1); Qt3DCore::QPropertyNodeRemovedChangePtr nodeRemovedChange = arbiter.events.first().staticCast<Qt3DCore::QPropertyNodeRemovedChange>(); QCOMPARE(nodeRemovedChange->propertyName(), "attribute"); QCOMPARE(nodeRemovedChange->removedNodeId(), attr.id()); QCOMPARE(nodeRemovedChange->type(), Qt3DCore::PropertyValueRemoved); arbiter.events.clear(); }
bool CustomMesh::updateVertColors(const Matrix<float, Dynamic, 3, RowMajor> &tMatColors) { //Check dimensions if(tMatColors.rows() != m_iNumVert) { qDebug()<<"CustomMesh::updateVertColors - new color and vertices dimensions do not match!"; return false; } Qt3DRender::QAttributeList list = this->geometry()->attributes(); Qt3DRender::QAttribute* colorAttribute; for(int i = 0; i<list.size(); i++) if(list.at(i)->name() == Qt3DRender::QAttribute::defaultColorAttributeName()) colorAttribute = dynamic_cast<Qt3DRender::QAttribute*>(list.at(i)); //Update color QByteArray newColorData; newColorData.resize(tMatColors.rows() * 3 * (int)sizeof(float)); Map<Matrix<float, Dynamic, 3, RowMajor>> (reinterpret_cast<float *>(newColorData.data()), tMatColors.rows(), tMatColors.cols()) = tMatColors; colorAttribute->buffer()->setData(newColorData); return true; }
Qt3DRender::QGeometryRenderer *QgsLine3DSymbolEntityNode::rendererSimple( const Qgs3DMapSettings &map, const QgsLine3DSymbol &symbol, const QgsVectorLayer *layer, const QgsFeatureRequest &request ) { QVector<QVector3D> vertices; vertices << QVector3D(); // the first index is invalid, we use it for primitive restart QVector<unsigned int> indexes; QgsPoint centroid; QgsPointXY origin( map.origin().x(), map.origin().y() ); QgsFeature f; QgsFeatureIterator fi = layer->getFeatures( request ); while ( fi.nextFeature( f ) ) { if ( f.geometry().isNull() ) continue; if ( symbol.altitudeBinding() == AltBindCentroid ) centroid = QgsPoint( f.geometry().centroid().asPoint() ); QgsGeometry geom = f.geometry(); const QgsAbstractGeometry *g = geom.constGet(); if ( const QgsLineString *ls = qgsgeometry_cast<const QgsLineString *>( g ) ) { for ( int i = 0; i < ls->vertexCount(); ++i ) { QgsPoint p = ls->pointN( i ); float z = Qgs3DUtils::clampAltitude( p, symbol.altitudeClamping(), symbol.altitudeBinding(), symbol.height(), centroid, map ); vertices << QVector3D( p.x() - map.origin().x(), z, -( p.y() - map.origin().y() ) ); indexes << vertices.count() - 1; } } else if ( const QgsMultiLineString *mls = qgsgeometry_cast<const QgsMultiLineString *>( g ) ) { for ( int nGeom = 0; nGeom < mls->numGeometries(); ++nGeom ) { const QgsLineString *ls = qgsgeometry_cast<const QgsLineString *>( mls->geometryN( nGeom ) ); for ( int i = 0; i < ls->vertexCount(); ++i ) { QgsPoint p = ls->pointN( i ); float z = Qgs3DUtils::clampAltitude( p, symbol.altitudeClamping(), symbol.altitudeBinding(), symbol.height(), centroid, map ); vertices << QVector3D( p.x() - map.origin().x(), z, -( p.y() - map.origin().y() ) ); indexes << vertices.count() - 1; } indexes << 0; // add primitive restart } } indexes << 0; // add primitive restart } QByteArray vertexBufferData; vertexBufferData.resize( vertices.size() * 3 * sizeof( float ) ); float *rawVertexArray = reinterpret_cast<float *>( vertexBufferData.data() ); int idx = 0; for ( const auto &v : vertices ) { rawVertexArray[idx++] = v.x(); rawVertexArray[idx++] = v.y(); rawVertexArray[idx++] = v.z(); } QByteArray indexBufferData; indexBufferData.resize( indexes.size() * sizeof( int ) ); unsigned int *rawIndexArray = reinterpret_cast<unsigned int *>( indexBufferData.data() ); idx = 0; for ( unsigned int indexVal : indexes ) { rawIndexArray[idx++] = indexVal; } Qt3DRender::QBuffer *vertexBuffer = new Qt3DRender::QBuffer( Qt3DRender::QBuffer::VertexBuffer, this ); vertexBuffer->setData( vertexBufferData ); Qt3DRender::QBuffer *indexBuffer = new Qt3DRender::QBuffer( Qt3DRender::QBuffer::IndexBuffer, this ); indexBuffer->setData( indexBufferData ); Qt3DRender::QAttribute *positionAttribute = new Qt3DRender::QAttribute( this ); positionAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute ); positionAttribute->setBuffer( vertexBuffer ); positionAttribute->setVertexBaseType( Qt3DRender::QAttribute::Float ); positionAttribute->setVertexSize( 3 ); positionAttribute->setName( Qt3DRender::QAttribute::defaultPositionAttributeName() ); Qt3DRender::QAttribute *indexAttribute = new Qt3DRender::QAttribute( this ); indexAttribute->setAttributeType( Qt3DRender::QAttribute::IndexAttribute ); indexAttribute->setBuffer( indexBuffer ); indexAttribute->setVertexBaseType( Qt3DRender::QAttribute::UnsignedInt ); Qt3DRender::QGeometry *geom = new Qt3DRender::QGeometry; geom->addAttribute( positionAttribute ); geom->addAttribute( indexAttribute ); Qt3DRender::QGeometryRenderer *renderer = new Qt3DRender::QGeometryRenderer; renderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::LineStrip ); renderer->setGeometry( geom ); renderer->setVertexCount( vertices.count() ); renderer->setPrimitiveRestartEnabled( true ); renderer->setRestartIndexValue( 0 ); return renderer; }
void QgsSimpleLine3DSymbolHandler::makeEntity( Qt3DCore::QEntity *parent, const Qgs3DRenderContext &context, LineData &out, bool selected ) { if ( out.indexes.isEmpty() ) return; // material (only ambient color is used for the color) Qt3DExtras::QPhongMaterial *mat = _material( mSymbol ); if ( selected ) { // update the material with selection colors mat->setAmbient( context.map().selectionColor() ); } // geometry renderer QByteArray vertexBufferData; vertexBufferData.resize( out.vertices.size() * 3 * sizeof( float ) ); float *rawVertexArray = reinterpret_cast<float *>( vertexBufferData.data() ); int idx = 0; for ( const auto &v : qgis::as_const( out.vertices ) ) { rawVertexArray[idx++] = v.x(); rawVertexArray[idx++] = v.y(); rawVertexArray[idx++] = v.z(); } QByteArray indexBufferData; indexBufferData.resize( out.indexes.size() * sizeof( int ) ); unsigned int *rawIndexArray = reinterpret_cast<unsigned int *>( indexBufferData.data() ); idx = 0; for ( unsigned int indexVal : qgis::as_const( out.indexes ) ) { rawIndexArray[idx++] = indexVal; } Qt3DCore::QEntity *entity = new Qt3DCore::QEntity; Qt3DRender::QBuffer *vertexBuffer = new Qt3DRender::QBuffer( Qt3DRender::QBuffer::VertexBuffer, entity ); vertexBuffer->setData( vertexBufferData ); Qt3DRender::QBuffer *indexBuffer = new Qt3DRender::QBuffer( Qt3DRender::QBuffer::IndexBuffer, entity ); indexBuffer->setData( indexBufferData ); Qt3DRender::QAttribute *positionAttribute = new Qt3DRender::QAttribute( entity ); positionAttribute->setAttributeType( Qt3DRender::QAttribute::VertexAttribute ); positionAttribute->setBuffer( vertexBuffer ); positionAttribute->setVertexBaseType( Qt3DRender::QAttribute::Float ); positionAttribute->setVertexSize( 3 ); positionAttribute->setName( Qt3DRender::QAttribute::defaultPositionAttributeName() ); Qt3DRender::QAttribute *indexAttribute = new Qt3DRender::QAttribute( entity ); indexAttribute->setAttributeType( Qt3DRender::QAttribute::IndexAttribute ); indexAttribute->setBuffer( indexBuffer ); indexAttribute->setVertexBaseType( Qt3DRender::QAttribute::UnsignedInt ); Qt3DRender::QGeometry *geom = new Qt3DRender::QGeometry; geom->addAttribute( positionAttribute ); geom->addAttribute( indexAttribute ); Qt3DRender::QGeometryRenderer *renderer = new Qt3DRender::QGeometryRenderer; renderer->setPrimitiveType( Qt3DRender::QGeometryRenderer::LineStrip ); renderer->setGeometry( geom ); renderer->setVertexCount( out.vertices.count() ); renderer->setPrimitiveRestartEnabled( true ); renderer->setRestartIndexValue( 0 ); // make entity entity->addComponent( renderer ); entity->addComponent( mat ); entity->setParent( parent ); }
CustomMesh::CustomMesh(const MatrixX3f &tMatVert, const MatrixX3f tMatNorm, const MatrixX3i &tMatTris, const Vector3f &tVecOffset) : Qt3DRender::QGeometryRenderer() , m_iNumVert(tMatVert.rows()) { Qt3DRender::QGeometry* customGeometry = new Qt3DRender::QGeometry(this); m_pVertexDataBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, customGeometry);//QSharedPointer<Qt3DRender::QBuffer>(new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, customGeometry)); m_pNormalDataBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, customGeometry);//QSharedPointer<Qt3DRender::QBuffer>(new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, customGeometry)); m_pColorDataBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, customGeometry);//QSharedPointer<Qt3DRender::QBuffer>(new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, customGeometry)); m_pIndexDataBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, customGeometry);//QSharedPointer<Qt3DRender::QBuffer>(new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, customGeometry)); //Fill vertexBuffer with data which hold the vertices, normals and colors QByteArray vertexBufferData; vertexBufferData.resize(tMatVert.rows() * 3 * (int)sizeof(float)); float *rawVertexArray = reinterpret_cast<float *>(vertexBufferData.data()); QByteArray normalBufferData; normalBufferData.resize(tMatVert.rows() * 3 * (int)sizeof(float)); float *rawNormalArray = reinterpret_cast<float *>(normalBufferData.data()); QByteArray colorBufferData; colorBufferData.resize(tMatVert.rows() * 3 * (int)sizeof(float)); float *rawColorArray = reinterpret_cast<float *>(colorBufferData.data()); int idxVert = 0; int idxNorm = 0; int idxColor = 0; for(int i = 0; i<tMatVert.rows(); i++) { //Vertex rawVertexArray[idxVert++] = tMatVert(i,0) + tVecOffset(0); rawVertexArray[idxVert++] = tMatVert(i,1) + tVecOffset(1); rawVertexArray[idxVert++] = tMatVert(i,2) + tVecOffset(2); //Normal rawNormalArray[idxNorm++] = tMatNorm(i,0); rawNormalArray[idxNorm++] = tMatNorm(i,1); rawNormalArray[idxNorm++] = tMatNorm(i,2); //Color (this is the default color and will be used until the updateVertColor function was called) rawColorArray[idxColor++] = 0.5f; rawColorArray[idxColor++] = 0.2f; rawColorArray[idxColor++] = 0.2f; } //Fill indexBufferData with data which holds the triangulation information (faces/tris) QByteArray indexBufferData; indexBufferData.resize(tMatTris.rows() * 3 * (int)sizeof(uint)); uint *rawIndexArray = reinterpret_cast<uint *>(indexBufferData.data()); int idxTris = 0; for(int i = 0; i<tMatTris.rows(); i++) { //Faces/Tris rawIndexArray[idxTris++] = tMatTris(i,0); rawIndexArray[idxTris++] = tMatTris(i,1); rawIndexArray[idxTris++] = tMatTris(i,2); } //Set data to buffers m_pVertexDataBuffer->setData(vertexBufferData); m_pNormalDataBuffer->setData(normalBufferData); m_pColorDataBuffer->setData(colorBufferData); m_pIndexDataBuffer->setData(indexBufferData); // Attributes Qt3DRender::QAttribute *positionAttribute = new Qt3DRender::QAttribute(); positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); positionAttribute->setBuffer(m_pVertexDataBuffer); positionAttribute->setDataType(Qt3DRender::QAttribute::Float); positionAttribute->setDataSize(3); positionAttribute->setByteOffset(0); positionAttribute->setByteStride(3 * sizeof(float)); positionAttribute->setCount(tMatVert.rows()); positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName()); Qt3DRender::QAttribute *normalAttribute = new Qt3DRender::QAttribute(); normalAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); normalAttribute->setBuffer(m_pNormalDataBuffer); normalAttribute->setDataType(Qt3DRender::QAttribute::Float); normalAttribute->setDataSize(3); normalAttribute->setByteOffset(0); normalAttribute->setByteStride(3 * sizeof(float)); normalAttribute->setCount(tMatVert.rows()); normalAttribute->setName(Qt3DRender::QAttribute::defaultNormalAttributeName()); Qt3DRender::QAttribute *colorAttribute = new Qt3DRender::QAttribute(); colorAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); colorAttribute->setBuffer(m_pColorDataBuffer); colorAttribute->setDataType(Qt3DRender::QAttribute::Float); colorAttribute->setDataSize(3); colorAttribute->setByteOffset(0); colorAttribute->setByteStride(3 * sizeof(float)); colorAttribute->setCount(tMatVert.rows()); colorAttribute->setName(Qt3DRender::QAttribute::defaultColorAttributeName()); Qt3DRender::QAttribute *indexAttribute = new Qt3DRender::QAttribute(); indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute); indexAttribute->setBuffer(m_pIndexDataBuffer); indexAttribute->setDataType(Qt3DRender::QAttribute::UnsignedInt); indexAttribute->setDataSize(1); indexAttribute->setByteOffset(0); indexAttribute->setByteStride(0); indexAttribute->setCount(tMatTris.rows()); customGeometry->addAttribute(positionAttribute); customGeometry->addAttribute(normalAttribute); customGeometry->addAttribute(colorAttribute); customGeometry->addAttribute(indexAttribute); this->setInstanceCount(1); this->setBaseVertex(0); this->setBaseInstance(0); this->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles); this->setGeometry(customGeometry); this->setPrimitiveCount(tMatTris.rows()*3); }