void copy( VertexAttributeSetSharedPtr const& src, VertexAttributeSetSharedPtr const& dst ) { if ( src != dst ) { dst->setName( src->getName() ); dst->setAnnotation( src->getAnnotation() ); dst->setHints( src->getHints() ); dst->setUserData( src->getUserData() ); for ( unsigned int i=0 ; i<2*static_cast<unsigned int>(VertexAttributeSet::AttributeID::VERTEX_ATTRIB_COUNT) ; ++i ) { VertexAttributeSet::AttributeID id = static_cast<VertexAttributeSet::AttributeID>(i); if ( src->getSizeOfVertexData( id ) ) { DP_ASSERT( ( src->getOffsetOfVertexData( id ) == 0 ) && src->isContiguousVertexData( id ) ); dst->setVertexData( id, src->getSizeOfVertexData( id ), src->getTypeOfVertexData( id ) , src->getVertexBuffer( id ), src->getOffsetOfVertexData( id ) , src->getStrideOfVertexData( id ), src->getNumberOfVertexData( id ) ); dst->setEnabled( id, src->isEnabled( id ) ); if ( id >= VertexAttributeSet::AttributeID::VERTEX_ATTRIB_COUNT ) { dst->setNormalizeEnabled( id, src->isNormalizeEnabled( id ) ); } } } } }
void deIndexPrimitiveT( Primitive * p ) { Buffer::DataReadLock indexBuffer( p->getIndexSet()->getBuffer() ); VertexAttributeSetSharedPtr const& vas = p->getVertexAttributeSet(); unsigned int nov = vas->getNumberOfVertices(); unsigned int noi = p->getIndexSet()->getNumberOfIndices(); if ( ( nov != noi ) || ! checkFlat( (const T *)indexBuffer.getPtr(), noi ) || ! checkTrivial( (const T *)indexBuffer.getPtr(), noi ) ) { VertexAttributeSetSharedPtr newVASH = VertexAttributeSet::create(); for ( unsigned int i=0 ; i<VertexAttributeSet::DP_SG_VERTEX_ATTRIB_COUNT ; i++ ) { if ( vas->getSizeOfVertexData(i) ) { Buffer::DataReadLock indexBufferLock( p->getIndexSet()->getBuffer() ); const T * idxPtr = indexBufferLock.getPtr<T>(); dp::DataType type = vas->getTypeOfVertexData(i); unsigned int size = dp::checked_cast<unsigned int>(vas->getSizeOfVertexData(i) * dp::getSizeOf( type )); unsigned int stride = vas->getStrideOfVertexData(i); DP_ASSERT( size <= stride ); unsigned int numIndices = p->getIndexSet()->getNumberOfIndices(); BufferHostSharedPtr newVertexBuffer = BufferHost::create(); newVertexBuffer->setSize( numIndices * size ); { Buffer::DataReadLock oldBufferLock( vas->getVertexData( i ) ); const unsigned char * oldBuffPtr = oldBufferLock.getPtr<unsigned char>(); Buffer::DataWriteLock newBufferLock( newVertexBuffer, Buffer::MAP_WRITE ); unsigned char * newBuffPtr = newBufferLock.getPtr<unsigned char>(); for ( unsigned int idx=0 ; idx < numIndices ; idx++ ) { memcpy( newBuffPtr, oldBuffPtr + stride * idxPtr[idx], size ); newBuffPtr += size; } } newVASH->setVertexData( i, vas->getSizeOfVertexData(i), type, newVertexBuffer, 0, stride, numIndices ); // inherit enable states from source attrib // normalize-enable state only meaningful for generic aliases! newVASH->setEnabled(i, vas->isEnabled(i)); // conventional newVASH->setEnabled(i+16, vas->isEnabled(i+16)); // generic newVASH->setNormalizeEnabled(i+16, vas->isNormalizeEnabled(i+16)); // only generic } } p->setVertexAttributeSet( newVASH ); } }
void copySelectedVertices( const VertexAttributeSetSharedPtr & from, const VertexAttributeSetSharedPtr & to , std::vector<std::vector<unsigned int> > &indices ) { // indexMap below is intended to hold vertex indices, which should not exceed 32-bit precision by definition! std::vector<unsigned int> indexMap( from->getNumberOfVertices(), ~0 ); std::vector<unsigned int> iFrom; iFrom.reserve(from->getNumberOfVertices()); for ( size_t i=0 ; i<indices.size() ; i++ ) { for ( size_t j=0 ; j<indices[i].size() ; j++ ) { if ( indexMap[indices[i][j]] == ~0 ) { indexMap[indices[i][j]] = dp::checked_cast<unsigned int>(iFrom.size()); iFrom.push_back(indices[i][j]); } } } for ( unsigned int slot=0 ; slot<static_cast<unsigned int>(VertexAttributeSet::AttributeID::VERTEX_ATTRIB_COUNT) ; slot++ ) { VertexAttributeSet::AttributeID id = static_cast<VertexAttributeSet::AttributeID>(slot); if ( from->getSizeOfVertexData( id ) ) { BufferSharedPtr oldData = from->getVertexBuffer(id); Buffer::DataReadLock lock( oldData ); unsigned int size = from->getSizeOfVertexData( id ); dp::DataType type = from->getTypeOfVertexData( id ); to->setVertexData( id, NULL, &iFrom[0], size, type, lock.getPtr() , from->getStrideOfVertexData( id ) , dp::checked_cast<unsigned int>(iFrom.size()) ); // inherit enable states from source id // normalize-enable state only meaningful for generic aliases! to->setEnabled(id, from->isEnabled(id)); // conventional id = static_cast<VertexAttributeSet::AttributeID>(slot+16); // generic to->setEnabled(id, from->isEnabled(id)); to->setNormalizeEnabled(id, from->isNormalizeEnabled(id)); } } for ( size_t i=0 ; i<indices.size() ; i++ ) { for ( size_t j=0 ; j<indices[i].size() ; j++ ) { indices[i][j] = indexMap[indices[i][j]]; } } }
void UnifyTraverser::handleVertexAttributeSet( VertexAttributeSet * p ) { pair<set<const void *>::iterator,bool> pitb = m_objects.insert( p ); if ( pitb.second ) { OptimizeTraverser::handleVertexAttributeSet( p ); // Check if optimization is allowed if ( optimizationAllowed( p->getSharedPtr<VertexAttributeSet>() ) && (m_unifyTargets & UT_VERTICES) ) { VertexAttributeSetSharedPtr vas = p->getSharedPtr<VertexAttributeSet>(); unsigned int n = p->getNumberOfVertices(); // handle VAS with more than one vertex only if ( 1 < n ) { // *************************************************************** // the algorithm currently only works for float-typed vertex data! // *************************************************************** for ( unsigned int i=0 ; i<VertexAttributeSet::DP_SG_VERTEX_ATTRIB_COUNT ; i++ ) { unsigned int type = p->getTypeOfVertexData(i); if ( type != dp::DT_UNKNOWN // no data is ok! && type != dp::DT_FLOAT_32 ) { DP_ASSERT( !"This algorithm currently only works for float-typed vertex data!" ); return; } } // *************************************************************** // *************************************************************** // count the dimension of the VertexAttributeSet unsigned int dimension = 0; for ( unsigned int i=0 ; i<VertexAttributeSet::DP_SG_VERTEX_ATTRIB_COUNT ; i++ ) { if ( p->getNumberOfVertexData( i ) ) { dimension += p->getSizeOfVertexData( i ); } } vector<float> valueDataIn( n * dimension ); vector<float*> valuesIn( n ); for ( size_t i=0, j=0 ; i<valuesIn.size() ; i++, j+=dimension ) { valuesIn[i] = &valueDataIn[j]; } // fill valuesIn with the vertex attribute data for ( unsigned int i=0, j=0 ; i<VertexAttributeSet::DP_SG_VERTEX_ATTRIB_COUNT ; i++ ) { if ( p->getNumberOfVertexData( i ) != 0 ) { unsigned int dim = p->getSizeOfVertexData( i ); Buffer::ConstIterator<float>::Type vad = p->getVertexData<float>( i ); for ( unsigned int k=0 ; k<n ; k++ ) { const float *value = &vad[k]; for ( unsigned int l=0 ; l<dim ; l++ ) { valuesIn[k][j+l] = value[l]; } } j += dim; } } VUTOctreeNode * octree = new VUTOctreeNode(); octree->init( boundingBox<3, float, Buffer::ConstIterator<Vec3f>::Type >( p->getVertices(), p->getNumberOfVertices() ) , std::max( (unsigned int)32, (unsigned int)pow( p->getNumberOfVertices(), 0.25 ) ) ); unsigned int count = dp::checked_cast<unsigned int>(valuesIn.size()); for ( unsigned int i=0 ; i<count ; i++ ) { octree->addVertex( valuesIn, i, dimension, m_epsilon ); } unsigned int pointCount = octree->getNumberOfPoints(); // if there are less points only if ( pointCount < n ) { // initialize the index mapping to undefined vector<unsigned int> indexMap( n ); for ( unsigned int i=0 ; i<n ; i++ ) { indexMap[i] = ~0; } // create the vector of vertex attribute valuesIn vector<float> valueDataOut( pointCount * dimension ); vector<float*> valuesOut( pointCount ); for ( size_t i=0, j=0 ; i<valuesOut.size() ; i++, j+=dimension ) { valuesOut[i] = &valueDataOut[j]; } // fill valuesOut and the indexMap unsigned int index = 0; octree->mapValues( valuesIn, valuesOut, dimension, indexMap, index ); delete octree; // create a new VertexAttributeSet with the condensed data VertexAttributeSetSharedPtr newVAS = VertexAttributeSet::create(); for ( unsigned int i=0, j=0 ; i<VertexAttributeSet::DP_SG_VERTEX_ATTRIB_COUNT ; i++ ) { if ( p->getNumberOfVertexData( i ) ) { unsigned int dim = p->getSizeOfVertexData( i ); vector<float> vad( dim * valuesOut.size() ); for ( size_t k=0 ; k<valuesOut.size() ; k++ ) { for ( unsigned int l=0 ; l<dim ; l++ ) { vad[dim*k+l] = valuesOut[k][j+l]; } } newVAS->setVertexData( i, dim, dp::DT_FLOAT_32, &vad[0], 0, dp::checked_cast<unsigned int>(vad.size()/dim) ); // inherit enable states from source attrib // normalize-enable state only meaningful for generic aliases! newVAS->setEnabled(i, p->isEnabled(i)); // conventional newVAS->setEnabled(i+16, p->isEnabled(i+16)); // generic newVAS->setNormalizeEnabled(i+16, p->isNormalizeEnabled(i+16)); // generic only! j += dim; } } DP_ASSERT( m_vasReplacements.find( vas ) == m_vasReplacements.end() ); m_vasReplacements[vas] = VASReplacement( newVAS, indexMap ); } else { delete octree; } } } } }