const ccGenericPrimitive& ccGenericPrimitive::operator += (const ccGenericPrimitive& prim) { ccPointCloud* verts = vertices(); unsigned vertCount = verts->size(); unsigned facesCount = size(); unsigned triFacesNormCount = (m_triNormals ? m_triNormals->currentSize() : 0); //count new number of vertices & faces unsigned newVertCount = vertCount + prim.getAssociatedCloud()->size(); unsigned newFacesCount = facesCount + prim.size(); bool primHasVertNorms = prim.getAssociatedCloud()->hasNormals(); bool primHasFaceNorms = prim.hasTriNormals(); //reserve memory if ( verts->reserve(newVertCount) && (!primHasVertNorms || verts->reserveTheNormsTable()) && reserve(newFacesCount) && (!primHasFaceNorms || m_triNormalIndexes || reservePerTriangleNormalIndexes())) { //copy vertices & normals ccGenericPointCloud* cloud = prim.getAssociatedCloud(); for (unsigned i = 0; i < cloud->size(); ++i) { verts->addPoint(*cloud->getPoint(i)); if (primHasVertNorms) { verts->addNormIndex(cloud->getPointNormalIndex(i)); } } //copy face normals if (primHasFaceNorms) { const NormsIndexesTableType* primNorms = prim.getTriNormsTable(); assert(primNorms); unsigned primTriNormCount = primNorms->currentSize(); NormsIndexesTableType* normsTable = (m_triNormals ? m_triNormals : new NormsIndexesTableType()); if (!normsTable || !normsTable->reserveSafe(triFacesNormCount + primTriNormCount)) { ccLog::Error("[ccGenericPrimitive::operator +] Not enough memory!"); return *this; } //attach table if not done already if (!m_triNormals) { setTriNormsTable(normsTable); assert(m_triNormals); } for (unsigned i = 0; i < primTriNormCount; ++i) { normsTable->addElement(primNorms->getValue(i)); } } //copy faces for (unsigned i = 0; i < prim.size(); ++i) { const CCLib::VerticesIndexes* tsi = prim.getTriangleVertIndexes(i); addTriangle(vertCount + tsi->i1, vertCount + tsi->i2, vertCount + tsi->i3); if (primHasFaceNorms) { const Tuple3i& normIndexes = prim.m_triNormalIndexes->at(i); addTriangleNormalIndexes(triFacesNormCount + normIndexes.u[0], triFacesNormCount + normIndexes.u[1], triFacesNormCount + normIndexes.u[2]); } } } else { ccLog::Error("[ccGenericPrimitive::operator +] Not enough memory!"); } return *this; }
bool ccGenericPrimitive::init(unsigned vertCount, bool vertNormals, unsigned faceCounts, unsigned faceNormCounts) { ccPointCloud* verts = vertices(); assert(verts); if (!verts) return false; /*** clear existing structures ***/ //clear vertices & normals bool keepOtherProps = (vertCount == verts->size()); if (keepOtherProps) { verts->unallocatePoints(); verts->unallocateNorms(); } else { verts->clear(); } //clear triangles indexes assert(m_triVertIndexes); m_triVertIndexes->clear(); //clear per triangle normals removePerTriangleNormalIndexes(); if (m_triNormals) m_triNormals->clear(); //DGM: if we do this we'll have issues with the DB tree depending on where when we call this method! //{ // removeChild(m_triNormals); // setTriNormsTable(0); // assert(!m_triNormals); //} /*** init necessary structures ***/ if (vertCount && !verts->reserve(vertCount)) return false; if (vertNormals && !verts->reserveTheNormsTable()) { verts->clear(); return false; } if (faceCounts && !reserve(faceCounts)) { verts->clear(); return false; } if (faceNormCounts) { NormsIndexesTableType* normsTable = (m_triNormals ? m_triNormals : new NormsIndexesTableType()); if (!normsTable || !normsTable->reserveSafe(faceNormCounts) || !reservePerTriangleNormalIndexes()) { verts->clear(); m_triVertIndexes->clear(); delete normsTable; return false; } //attach table if not done already if (!m_triNormals) { setTriNormsTable(normsTable); assert(m_triNormals); } } return true; }