/*===========================================================================*/ void PointObject::add( const PointObject& other ) { if ( this->coords().size() == 0 ) { // Copy the object. BaseClass::setCoords( other.coords() ); BaseClass::setNormals( other.normals() ); BaseClass::setColors( other.colors() ); this->setSizes( other.sizes() ); BaseClass::setMinMaxObjectCoords( other.minObjectCoord(), other.maxObjectCoord() ); BaseClass::setMinMaxExternalCoords( other.minExternalCoord(), other.maxExternalCoord() ); } else { if ( !BaseClass::hasMinMaxObjectCoords() ) { BaseClass::updateMinMaxCoords(); } kvs::Vec3 min_object_coord( BaseClass::minObjectCoord() ); kvs::Vec3 max_object_coord( BaseClass::maxObjectCoord() ); min_object_coord.x() = kvs::Math::Min( min_object_coord.x(), other.minObjectCoord().x() ); min_object_coord.y() = kvs::Math::Min( min_object_coord.y(), other.minObjectCoord().y() ); min_object_coord.z() = kvs::Math::Min( min_object_coord.z(), other.minObjectCoord().z() ); max_object_coord.x() = kvs::Math::Max( max_object_coord.x(), other.maxObjectCoord().x() ); max_object_coord.y() = kvs::Math::Max( max_object_coord.y(), other.maxObjectCoord().y() ); max_object_coord.z() = kvs::Math::Max( max_object_coord.z(), other.maxObjectCoord().z() ); BaseClass::setMinMaxObjectCoords( min_object_coord, max_object_coord ); BaseClass::setMinMaxExternalCoords( min_object_coord, max_object_coord ); // Integrate the coordinate values. kvs::ValueArray<kvs::Real32> coords; const size_t ncoords = this->coords().size() + other.coords().size(); coords.allocate( ncoords ); kvs::Real32* pcoords = coords.data(); // x,y,z, ... + x,y,z, ... = x,y,z, ... ,x,y,z, ... memcpy( pcoords, this->coords().data(), this->coords().byteSize() ); memcpy( pcoords + this->coords().size(), other.coords().data(), other.coords().byteSize() ); BaseClass::setCoords( coords ); // Integrate the normal vectors. kvs::ValueArray<kvs::Real32> normals; if ( this->normals().size() > 0 ) { if ( other.normals().size() > 0 ) { // nx,ny,nz, ... + nx,ny,nz, ... = nx,ny,nz, ... ,nx,ny,nz, ... const size_t nnormals = this->normals().size() + other.normals().size(); normals.allocate( nnormals ); kvs::Real32* pnormals = normals.data(); memcpy( pnormals, this->normals().data(), this->normals().byteSize() ); memcpy( pnormals + this->normals().size(), other.normals().data(), other.normals().byteSize() ); } else { // nx,ny,nz, ... + (none) = nx,ny,nz, ... ,0,0,0, ... const size_t nnormals = this->normals().size() + other.coords().size(); normals.allocate( nnormals ); kvs::Real32* pnormals = normals.data(); memcpy( pnormals, this->normals().data(), this->normals().byteSize() ); memset( pnormals + this->normals().size(), 0, other.coords().byteSize() ); } } else { if ( other.normals().size() > 0 ) { const size_t nnormals = this->coords().size() + other.normals().size(); normals.allocate( nnormals ); kvs::Real32* pnormals = normals.data(); // (none) + nx,ny,nz, ... = 0,0,0, ... ,nz,ny,nz, ... memset( pnormals, 0, this->coords().byteSize() ); memcpy( pnormals + this->coords().size(), other.normals().data(), other.normals().byteSize() ); } } BaseClass::setNormals( normals ); // Integrate the color values. kvs::ValueArray<kvs::UInt8> colors; if ( this->colors().size() > 1 ) { if ( other.colors().size() > 1 ) { // r,g,b, ... + r,g,b, ... = r,g,b, ... ,r,g,b, ... const size_t ncolors = this->colors().size() + other.colors().size(); colors.allocate( ncolors ); kvs::UInt8* pcolors = colors.data(); memcpy( pcolors, this->colors().data(), this->colors().byteSize() ); memcpy( pcolors + this->colors().size(), other.colors().data(), other.colors().byteSize() ); } else { // r,g,b, ... + R,G,B = r,g,b, ... ,R,G,B, ... ,R,G,B const size_t ncolors = this->colors().size() + other.coords().size(); colors.allocate( ncolors ); kvs::UInt8* pcolors = colors.data(); memcpy( pcolors, this->colors().data(), this->colors().byteSize() ); pcolors += this->colors().size(); const kvs::RGBColor color = other.color(); for ( size_t i = 0; i < other.coords().size(); i += 3 ) { *(pcolors++) = color.r(); *(pcolors++) = color.g(); *(pcolors++) = color.b(); } } } else { if ( other.colors().size() > 1 ) { // R,G,B + r,g,b, ... = R,G,B, ... ,R,G,B, r,g,b, ... const size_t ncolors = this->coords().size() + other.colors().size(); colors.allocate( ncolors ); kvs::UInt8* pcolors = colors.data(); const kvs::RGBColor color = this->color(); for ( size_t i = 0; i < this->coords().size(); i += 3 ) { *(pcolors++) = color.r(); *(pcolors++) = color.g(); *(pcolors++) = color.b(); } memcpy( pcolors, other.colors().data(), other.colors().byteSize() ); } else { const kvs::RGBColor color1 = this->color(); const kvs::RGBColor color2 = other.color(); if ( color1 == color2 ) { // R,G,B + R,G,B = R,G,B const size_t ncolors = 3; colors.allocate( ncolors ); kvs::UInt8* pcolors = colors.data(); *(pcolors++) = color1.r(); *(pcolors++) = color1.g(); *(pcolors++) = color1.b(); } else { // R,G,B + R,G,B = R,G,B, ... ,R,G,B, ... const size_t ncolors = this->coords().size() + other.coords().size(); colors.allocate( ncolors ); kvs::UInt8* pcolors = colors.data(); for ( size_t i = 0; i < this->coords().size(); i += 3 ) { *(pcolors++) = color1.r(); *(pcolors++) = color1.g(); *(pcolors++) = color1.b(); } for ( size_t i = 0; i < other.coords().size(); i += 3 ) { *(pcolors++) = color2.r(); *(pcolors++) = color2.g(); *(pcolors++) = color2.b(); } } } } BaseClass::setColors( colors ); // Integrate the size values. kvs::ValueArray<kvs::Real32> sizes; if ( this->sizes().size() > 1 ) { if ( other.sizes().size() > 1 ) { // s, ... + s, ... = s, ... ,s, ... const size_t nsizes = this->sizes().size() + other.sizes().size(); sizes.allocate( nsizes ); kvs::Real32* psizes = sizes.data(); memcpy( psizes, this->sizes().data(), this->sizes().byteSize() ); memcpy( psizes + this->sizes().size(), other.sizes().data(), other.sizes().byteSize() ); } else { // s, ... + S = s, ... ,S, ... ,S const size_t nsizes = this->sizes().size() + other.coords().size(); sizes.allocate( nsizes ); kvs::Real32* psizes = sizes.data(); memcpy( psizes, this->sizes().data(), this->sizes().byteSize() ); psizes += this->colors().size(); const kvs::Real32 size = other.size(); for ( size_t i = 0; i < other.coords().size(); i++ ) { *(psizes++) = size; } } } else { if ( other.sizes().size() > 1 ) { // S + s, ... = S, ... ,S, s, ... const size_t nsizes = this->coords().size() + other.sizes().size(); sizes.allocate( nsizes ); kvs::Real32* psizes = sizes.data(); const kvs::Real32 size = this->size(); for ( size_t i = 0; i < this->coords().size(); i++ ) { *(psizes++) = size; } memcpy( psizes, other.sizes().data(), other.sizes().byteSize() ); } else { const kvs::Real32 size1 = this->size(); const kvs::Real32 size2 = other.size(); if ( size1 == size2 ) { // S + S = S const size_t nsizes = 1; sizes.allocate( nsizes ); kvs::Real32* psizes = sizes.data(); *(psizes++) = size1; } else { // S + S = S, ... , S, ... const size_t nsizes = this->coords().size() + other.coords().size(); sizes.allocate( nsizes ); kvs::Real32* psizes = sizes.data(); for ( size_t i = 0; i < this->coords().size(); i++ ) { *(psizes++) = size1; } for ( size_t i = 0; i < other.coords().size(); i++ ) { *(psizes++) = size2; } } } } this->setSizes( sizes ); } }