Ejemplo n.º 1
0
/*===========================================================================*/
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 );
    }
}