//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- TEST(ModelBasicListTest, MergePartsWithTransformation) { Vec3fArray* verts = new Vec3fArray; verts->reserve(3); verts->add(Vec3f(0, 0, 0)); verts->add(Vec3f(1, 0, 0)); verts->add(Vec3f(1, 1, 0)); Vec3fArray* norms = new Vec3fArray; norms->resize(3); norms->set(0, Vec3f::Z_AXIS); norms->set(1, Vec3f::Z_AXIS); norms->set(2, Vec3f::Z_AXIS); DrawableGeo* myGeo = new DrawableGeo; myGeo->setFromTriangleVertexArray(verts); myGeo->setNormalArray(norms); Part* myPart = new Part; myPart->setDrawable(myGeo); Part* myPart2 = new Part; myPart2->setDrawable(myGeo); ref<ModelBasicList> myModel = new ModelBasicList; myModel->addPart(myPart); myModel->addPart(myPart2); EXPECT_EQ(2, myModel->partCount()); Mat4d matrix; matrix.setTranslation(Vec3d(10, 20, 30)); Transform* transform = new Transform; transform->setLocalTransform(matrix); myPart2->setTransform(transform); myModel->mergeParts(1000, 1000); EXPECT_EQ(1, myModel->partCount()); Part* mergedPart = myModel->part(0); DrawableGeo* mergedGeo = dynamic_cast<DrawableGeo*>(mergedPart->drawable()); const Vec3fArray* vertices = mergedGeo->vertexArray(); EXPECT_EQ(6, vertices->size()); Vec3f v5 = vertices->get(5); EXPECT_EQ(11, v5.x()); EXPECT_EQ(21, v5.y()); EXPECT_EQ(30, v5.z()); }
//-------------------------------------------------------------------------------------------------- /// Count primitives of part in this node - do not recurse //-------------------------------------------------------------------------------------------------- size_t ModelBasicTreeNode::primitiveCount() { size_t totalPrimitiveCount = 0; size_t j; for (j = 0; j < m_partList->partCount(); j++) { Part* part = m_partList->part(j); DrawableGeo* drawable = dynamic_cast<DrawableGeo*>(part->drawable()); if (drawable) { totalPrimitiveCount += drawable->faceCount(); } } return totalPrimitiveCount; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- TEST(ModelBasicListTest, MergeParts) { Vec3fArray* verts = new Vec3fArray; verts->reserve(3); verts->add(Vec3f(0, 0, 0)); verts->add(Vec3f(1, 0, 0)); verts->add(Vec3f(1, 1, 0)); Vec3fArray* norms = new Vec3fArray; norms->resize(3); norms->set(0, Vec3f::Z_AXIS); norms->set(1, Vec3f::Z_AXIS); norms->set(2, Vec3f::Z_AXIS); DrawableGeo* myGeo = new DrawableGeo; myGeo->setFromTriangleVertexArray(verts); myGeo->setNormalArray(norms); Part* myPart = new Part; myPart->setDrawable(myGeo); Part* myPart2 = new Part; myPart2->setDrawable(myGeo); ref<ModelBasicList> myModel = new ModelBasicList; myModel->addPart(myPart); myModel->addPart(myPart2); EXPECT_EQ(2, myModel->partCount()); myModel->mergeParts(1000, 1000); EXPECT_EQ(1, myModel->partCount()); Part* mergedPart = myModel->part(0); DrawableGeo* mergedGeo = dynamic_cast<DrawableGeo*>(mergedPart->drawable()); const Vec3fArray* vertices = mergedGeo->vertexArray(); EXPECT_EQ(6, vertices->size()); Vec3f v5 = vertices->get(5); EXPECT_EQ(1, v5.x()); EXPECT_EQ(1, v5.y()); EXPECT_EQ(0, v5.z()); }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void QSRSnippetWidget::setRenderMode(DrawableGeo::RenderMode mode) { m_lastSetRenderMode = mode; Collection<Part> allParts; RenderSequence* renderSeq = m_snippet->renderSequence(); CVF_ASSERT(renderSeq); int numPasses = renderSeq->renderingCount(); int i; for (i = 0; i < numPasses; i++) { Rendering* rendering = renderSeq->rendering(i); CVF_ASSERT(rendering); Scene* scene = rendering->scene(); CVF_ASSERT(scene); scene->allParts(&allParts); } size_t numParts = allParts.size(); size_t partIdx; for (partIdx = 0; partIdx < numParts; partIdx++) { Part* part = allParts.at(partIdx); cvf::uint lod; for (lod = 0; lod < cvf::Part::MAX_NUM_LOD_LEVELS; lod++) { DrawableGeo* drawableGeo = dynamic_cast<DrawableGeo*>(part->drawable(lod)); if (drawableGeo) { drawableGeo->setRenderMode(m_lastSetRenderMode); } } } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void QSRSnippetWidget::convertDrawablesToShort() { RenderSequence* renderSeq = m_snippet->renderSequence(); CVF_ASSERT(renderSeq); int numPasses = renderSeq->renderingCount(); int i; for (i = 0; i < numPasses; i++) { Rendering* rendering = renderSeq->rendering(i); CVF_ASSERT(rendering); Scene* scene = rendering->scene(); CVF_ASSERT(scene); int numModels = scene->modelCount(); int j; for (j = 0; j < numModels; j++) { Model* model = scene->model(j); Collection<Part> partCollection; model->allParts(&partCollection); size_t numParts = partCollection.size(); size_t i; for (i = 0; i < numParts; i++) { DrawableGeo* drawable = dynamic_cast<DrawableGeo*>(partCollection.at(i)->drawable()); if (drawable) { drawable->convertFromUIntToUShort(); } } } } }
//-------------------------------------------------------------------------------------------------- /// Merge a drawable geometry object with this drawable possibly with transformation. /// /// \param drawableGeo Drawable geometries to be merged /// \param transformation Transformation matrix used to modify vertices /// /// Vertices are converted if a transformation matrix is given. /// Vertex arrays are appended to the merged vertex array. Primitives are copied and indices updated. /// /// \warning All other vertex attribute data such as normals, texture coordinates etc will be set to NULL //-------------------------------------------------------------------------------------------------- void DrawableGeo::mergeInto(const DrawableGeo& drawableGeo, const Mat4d* transformation) { size_t totalVertexCount = m_vertexBundle->vertexCount(); totalVertexCount += drawableGeo.vertexCount(); // Nothing to do if no existing vertices and no new vertices if (totalVertexCount == 0) { return; } // Create a new vertex array and copy data from our array cref<Vec3fArray> oldVertexArray = m_vertexBundle->vertexArray(); ref<Vec3fArray> newVertexArr = new Vec3fArray(totalVertexCount); size_t currentVertexIndex = 0; if (oldVertexArray.notNull() && oldVertexArray->size() > 0) { newVertexArr->copyData(*oldVertexArray, oldVertexArray->size(), 0, 0); currentVertexIndex = oldVertexArray->size(); } // Do the primitive set size_t i = 0; for (i = 0; i < drawableGeo.primitiveSetCount(); i++) { const PrimitiveSet* primSet = drawableGeo.primitiveSet(i); CVF_ASSERT(primSet); ref<UIntArray> indices = new UIntArray; indices->resize(primSet->indexCount()); uint k; for (k = 0; k < primSet->indexCount(); k++) { uint val = primSet->index(k); val += static_cast<uint>(currentVertexIndex); indices->set(k, val); } ref<PrimitiveSetIndexedUInt> prim = new PrimitiveSetIndexedUInt(primSet->primitiveType()); prim->setIndices(indices.p()); m_primitiveSets.push_back(prim.p()); } const Vec3fArray* srcVertices = drawableGeo.vertexArray(); CVF_ASSERT(srcVertices); if (transformation) { size_t j; for (j = 0; j < srcVertices->size(); j++) { // Transform to double vector to be able to do a transform using a double matrix Vec3d tmpDoubleVec(srcVertices->get(j)); tmpDoubleVec.transformPoint(*transformation); newVertexArr->set(currentVertexIndex, Vec3f(tmpDoubleVec)); currentVertexIndex++; } } else { // Append other drawable vertices vertex array and update vertex index newVertexArr->copyData(*srcVertices, srcVertices->size(), currentVertexIndex, 0); } // Clear all vertex attributes and set new vertex array m_vertexBundle->clear(); m_vertexBundle->setVertexArray(newVertexArr.p()); recomputeBoundingBox(); }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- TEST(ModelBasicListTest, MergePartsCheckBB) { Vec3fArray* verts = new Vec3fArray; verts->reserve(3); verts->add(Vec3f(0, 0, 0)); verts->add(Vec3f(1, 0, 0)); verts->add(Vec3f(1, 1, 0)); Vec3fArray* norms = new Vec3fArray; norms->resize(3); norms->set(0, Vec3f::Z_AXIS); norms->set(1, Vec3f::Z_AXIS); norms->set(2, Vec3f::Z_AXIS); DrawableGeo* myGeo = new DrawableGeo; myGeo->setFromTriangleVertexArray(verts); myGeo->setNormalArray(norms); ref<ModelBasicList> myModel = new ModelBasicList; { Part* myPart = new Part; myPart->setDrawable(myGeo); Mat4d matrix; matrix.setTranslation(Vec3d(10, 20, 30)); Transform* transform = new Transform; transform->setLocalTransform(matrix); myPart->setTransform(transform); myModel->addPart(myPart); } { Part* myPart2 = new Part; myPart2->setDrawable(myGeo); Mat4d matrix; matrix.setTranslation(Vec3d(20, 20, 30)); Transform* transform2 = new Transform; transform2->setLocalTransform(matrix); myPart2->setTransform(transform2); myModel->addPart(myPart2); } { Part* myPart3 = new Part; myPart3->setDrawable(myGeo); Mat4d matrix; matrix.setTranslation(Vec3d(100, 20, 30)); Transform* transform3 = new Transform; transform3->setLocalTransform(matrix); myPart3->setTransform(transform3); myModel->addPart(myPart3); } { Part* myPart4 = new Part; myPart4->setDrawable(myGeo); Mat4d matrix; matrix.setTranslation(Vec3d(110, 20, 30)); Transform* transform4 = new Transform; transform4->setLocalTransform(matrix); myPart4->setTransform(transform4); myModel->addPart(myPart4); } EXPECT_EQ(4, myModel->partCount()); myModel->mergeParts(1, 1000); EXPECT_EQ(4, myModel->partCount()); myModel->mergeParts(20, 1000); EXPECT_EQ(2, myModel->partCount()); myModel->mergeParts(200, 1000); EXPECT_EQ(1, myModel->partCount()); }