void
PrimitiveSetTypeCounter::apply(osg::Geode& geode)
{
    const osg::Geode::DrawableList& drawables = geode.getDrawableList();
    for( osg::Geode::DrawableList::const_iterator i = drawables.begin(); i != drawables.end(); ++i )
    {
        osg::Geometry* g = i->get()->asGeometry();
        if ( g )
        {
            const osg::Geometry::PrimitiveSetList& primSets = g->getPrimitiveSetList();
            for( osg::Geometry::PrimitiveSetList::const_iterator j = primSets.begin(); j != primSets.end(); ++j )
            {
                switch( j->get()->getMode() )
                {
                case GL_POINTS:
                    _point++;
                    break;
                case GL_LINES:
                case GL_LINE_LOOP:
                case GL_LINE_STRIP:
                    _line++;
                    break;
                default:
                    _polygon++;
                    break;
                }
            }
        }
    }
}
 void                            apply( osg::Geode& node )
                                 {
                                     node.compileDrawables( *_p_state );
                                     osg::Geode::DrawableList drawableList = node.getDrawableList();
                                     int listsize = drawableList.size();
                                     for ( int cnt = 0; cnt < listsize; ++cnt )
                                     {
                                         ++_numVisited;
                                         compileResource( node.getStateSet() );
                                     }
                                     traverse( node );
                                 }
// apply method for geodes
void GeometryExtractorVisitor::apply( osg::Geode& geode ) {
	// get the drawables from this geode
	osg::Geode::DrawableList drawables = geode.getDrawableList();
	
	// if there are no drawables, then return
	if( drawables.size() <= 0 )
		return;
	
	// iterate over the drawables
	for( osg::Geode::DrawableList::iterator i = drawables.begin(); i != drawables.end(); i++ ) {
		
		// dynamic_cast to geometry
		osg::Geometry* geo = (*i)->asGeometry();
		if(!geo) {
			continue;
		}
		
		// if the cast worked, save it to the cache
		geometries.push_back( geo );
	}
}
        void apply( osg::Geode& geode )
        {
            bool makeECEF = _cx.getSession()->getMapInfo().isGeocentric();
            const SpatialReference* srs = _cx.profile()->getSRS();

            NumericExpression scaleEx = *_symbol->scale();
            osg::Matrixd scaleMatrix;

            // save the geode's drawables..
            osg::Geode::DrawableList old_drawables = geode.getDrawableList();

            // ..and clear out the drawables list.
            geode.removeDrawables( 0, geode.getNumDrawables() );

            // foreach each drawable that was originally in the geode...
            for( osg::Geode::DrawableList::iterator i = old_drawables.begin(); i != old_drawables.end(); i++ )
            {
                osg::Geometry* originalDrawable = dynamic_cast<osg::Geometry*>( i->get() );
                if ( !originalDrawable )
                    continue;

                // go through the list of input features...
                for( FeatureList::const_iterator j = _features.begin(); j != _features.end(); j++ )
                {
                    const Feature* feature = j->get();

                    if ( _symbol->scale().isSet() )
                    {
                        double scale = feature->eval( scaleEx, &_cx );
                        scaleMatrix.makeScale( scale, scale, scale );
                    }

                    ConstGeometryIterator gi( feature->getGeometry(), false );
                    while( gi.hasMore() )
                    {
                        const Geometry* geom = gi.next();

                        for( Geometry::const_iterator k = geom->begin(); k != geom->end(); ++k )
                        {
                            osg::Vec3d   point = *k;
                            osg::Matrixd mat;

                            if ( makeECEF )
                            {
                                osg::Matrixd rotation;
                                ECEF::transformAndGetRotationMatrix( point, srs, point, rotation );
                                mat = rotation * scaleMatrix * osg::Matrixd::translate(point) * _f2n->world2local();
                            }
                            else
                            {
                                mat = scaleMatrix * osg::Matrixd::translate(point) * _f2n->world2local();
                            }

                            // clone the source drawable once for each input feature.
                            osg::ref_ptr<osg::Geometry> newDrawable = osg::clone( 
                                originalDrawable, 
                                osg::CopyOp::DEEP_COPY_ARRAYS | osg::CopyOp::DEEP_COPY_PRIMITIVES );

                            osg::Vec3Array* verts = dynamic_cast<osg::Vec3Array*>( newDrawable->getVertexArray() );
                            if ( verts )
                            {
                                for( osg::Vec3Array::iterator v = verts->begin(); v != verts->end(); ++v )
                                {
                                    (*v).set( (*v) * mat );
                                }
                                
                                // add the new cloned, translated drawable back to the geode.
                                geode.addDrawable( newDrawable.get() );
                            }
                        }

                    }
                }
            }

            geode.dirtyBound();

            MeshConsolidator::run( geode );

            // merge the geometry. Not sure this is necessary
            osgUtil::Optimizer opt;
            opt.optimize( &geode, osgUtil::Optimizer::MERGE_GEOMETRY | osgUtil::Optimizer::SHARE_DUPLICATE_STATE );
            
            osg::NodeVisitor::apply( geode );
        }
    void apply( osg::Geode& geode )
    {
        // save the geode's drawables..
        osg::Geode::DrawableList old_drawables = geode.getDrawableList();

        //OE_DEBUG << "ClusterVisitor geode " << &geode << " featureNode=" << _featureNode << " drawables=" << old_drawables.size() << std::endl;

        // ..and clear out the drawables list.
        geode.removeDrawables( 0, geode.getNumDrawables() );

        // foreach each drawable that was originally in the geode...
        for( osg::Geode::DrawableList::iterator i = old_drawables.begin(); i != old_drawables.end(); i++ )
        {
            osg::Geometry* originalDrawable = dynamic_cast<osg::Geometry*>( i->get() );
            if ( !originalDrawable )
                continue;

            // go through the list of input features...
            for( FeatureList::const_iterator j = _features.begin(); j != _features.end(); j++ )
            {
                Feature* feature = j->get();

                osg::Matrixd scaleMatrix;

                if ( _symbol->scale().isSet() )
                {
                    double scale = feature->eval( _scaleExpr, &_cx );
                    scaleMatrix.makeScale( scale, scale, scale );
                }

                osg::Matrixd rotationMatrix;
                if ( _modelSymbol && _modelSymbol->heading().isSet() )
                {
                    float heading = feature->eval( _headingExpr, &_cx );
                    rotationMatrix.makeRotate( osg::Quat(osg::DegreesToRadians(heading), osg::Vec3(0,0,1)) );
                }

                GeometryIterator gi( feature->getGeometry(), false );
                while( gi.hasMore() )
                {
                    Geometry* geom = gi.next();

                    // if necessary, transform the points to the target SRS:
                    if ( !_makeECEF && !_targetSRS->isEquivalentTo(_srs) )
                    {
                        _srs->transform( geom->asVector(), _targetSRS );
                    }

                    for( Geometry::const_iterator k = geom->begin(); k != geom->end(); ++k )
                    {
                        osg::Vec3d   point = *k;
                        osg::Matrixd mat;

                        if ( _makeECEF )
                        {
                            osg::Matrixd rotation;
                            ECEF::transformAndGetRotationMatrix( point, _srs, point, _targetSRS, rotation );
                            mat = rotationMatrix * rotation * scaleMatrix * osg::Matrixd::translate(point) * _f2n->world2local();
                        }
                        else
                        {
                            mat = rotationMatrix * scaleMatrix * osg::Matrixd::translate(point) * _f2n->world2local();
                        }

                        // clone the source drawable once for each input feature.
                        osg::ref_ptr<osg::Geometry> newDrawable = osg::clone( 
                            originalDrawable, 
                            osg::CopyOp::DEEP_COPY_ARRAYS | osg::CopyOp::DEEP_COPY_PRIMITIVES );

                        osg::Vec3Array* verts = dynamic_cast<osg::Vec3Array*>( newDrawable->getVertexArray() );
                        if ( verts )
                        {
                            for( osg::Vec3Array::iterator v = verts->begin(); v != verts->end(); ++v )
                            {
                                (*v).set( (*v) * mat );
                            }

                            // add the new cloned, translated drawable back to the geode.
                            geode.addDrawable( newDrawable.get() );

                            if ( _cx.featureIndex() )
                                _cx.featureIndex()->tagPrimitiveSets( newDrawable.get(), feature );
                        }
                    }

                }
            }
        }

        geode.dirtyBound();

        MeshConsolidator::run( geode );

        osg::NodeVisitor::apply( geode );
    }