osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarthSymbology/GeometrySymbolizer.cpp

Go to the documentation of this file.
00001 /* -*-c++-*- */
00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
00003  * Copyright 2008-2010 Pelican Mapping
00004  * http://osgearth.org
00005  *
00006  * osgEarth is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU Lesser General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018  */
00019 #include <osgEarthSymbology/GeometrySymbolizer>
00020 #include <osgEarthSymbology/PointSymbol>
00021 #include <osgEarthSymbology/LineSymbol>
00022 #include <osgEarthSymbology/PolygonSymbol>
00023 #include <osgUtil/Tessellator>
00024 #include <osg/Geometry>
00025 #include <osg/Point>
00026 #include <osg/LineWidth>
00027 #include <osg/Material>
00028 #include <osg/Geode>
00029 
00030 using namespace osgEarth::Symbology;
00031 
00032 
00033 osg::Node* GeometrySymbolizer::GeometrySymbolizerOperator::operator()(const GeometryList& geometryList,
00034                                                                       const Style* style)
00035 {
00036     osg::ref_ptr<osg::Geode> geode = new osg::Geode;
00037     for (GeometryList::const_iterator it = geometryList.begin(); it != geometryList.end(); ++it)
00038     {
00039         Geometry* geometry = *it;
00040         if (!geometry)
00041             continue;
00042 
00043         GeometryIterator geomIterator( geometry );
00044         geomIterator.traverseMultiGeometry() = true;
00045         geomIterator.traversePolygonHoles() = true;
00046 
00047         while( geomIterator.hasMore() )
00048         {
00049             Geometry* part = geomIterator.next();
00050             if (!part)
00051                 continue;
00052 
00053             osg::ref_ptr<osg::Geometry> osgGeom = new osg::Geometry;
00054             osg::PrimitiveSet::Mode primMode = osg::PrimitiveSet::POINTS;
00055 
00056             osg::Vec4 color = osg::Vec4(1.0, 0.0, 1.0, 1.);
00057 
00058             switch( part->getType())
00059             {
00060             case Geometry::TYPE_POINTSET:
00061             {
00062                 primMode = osg::PrimitiveSet::POINTS;
00063                 const PointSymbol* point = style->getSymbol<PointSymbol>();
00064                 if (point)
00065                 {
00066                     color = point->fill()->color();
00067 
00068                     float size = point->size().value();
00069                     osgGeom->getOrCreateStateSet()->setAttributeAndModes( new osg::Point(size) );
00070                 }
00071             }
00072             break;
00073 
00074             case Geometry::TYPE_LINESTRING:
00075             {
00076                 primMode = osg::PrimitiveSet::LINE_STRIP;
00077                 const LineSymbol* line = style->getSymbol<LineSymbol>();
00078                 if (line) 
00079                 {
00080                     color = line->stroke()->color();
00081                     float size = line->stroke()->width().value();
00082                     osgGeom->getOrCreateStateSet()->setAttributeAndModes( new osg::LineWidth(size));
00083                 }
00084             }
00085             break;
00086 
00087             case Geometry::TYPE_RING:
00088             {
00089                 primMode = osg::PrimitiveSet::LINE_LOOP;
00090                 const LineSymbol* line = style->getSymbol<LineSymbol>();
00091                 if (line) 
00092                 {
00093                     color = line->stroke()->color();
00094                     float size = line->stroke()->width().value();
00095                     osgGeom->getOrCreateStateSet()->setAttributeAndModes( new osg::LineWidth(size));
00096                 }
00097             }
00098             break;
00099 
00100             case Geometry::TYPE_POLYGON:
00101             {
00102                 primMode = osg::PrimitiveSet::LINE_LOOP; // loop will tessellate into polys
00103                 const PolygonSymbol* poly = style->getSymbol<PolygonSymbol>();
00104                 if (poly)
00105                 {
00106                     color = poly->fill()->color();
00107                 }
00108             }
00109             break;
00110             
00111             default:
00112             break;
00113             }
00114 
00115             osg::Material* material = new osg::Material;
00116             material->setDiffuse(osg::Material::FRONT_AND_BACK, color);
00117 
00118             if ( part->getType() == Geometry::TYPE_POLYGON && static_cast<Polygon*>(part)->getHoles().size() > 0 )
00119             {
00120                 Polygon* poly = static_cast<Polygon*>(geometry);
00121                 int totalPoints = poly->getTotalPointCount();
00122                 osg::Vec3Array* allPoints = new osg::Vec3Array( totalPoints );
00123                 int offset = 0;
00124                 for( RingCollection::const_iterator h = poly->getHoles().begin(); h != poly->getHoles().end(); ++h )
00125                 {
00126                     Geometry* hole = h->get();
00127                     std::copy( hole->begin(), hole->end(), allPoints->begin() + offset );
00128                     osgGeom->addPrimitiveSet( new osg::DrawArrays( primMode, offset, hole->size() ) );
00129                     offset += hole->size();
00130                 }
00131                 osgGeom->setVertexArray( allPoints );
00132             }
00133             else
00134             {
00135                 osgGeom->setVertexArray( part->toVec3Array() );
00136                 osgGeom->addPrimitiveSet( new osg::DrawArrays( primMode, 0, part->size() ) );
00137             }
00138 
00139             // tessellate all polygon geometries. Tessellating each geometry separately
00140             // with TESS_TYPE_GEOMETRY is much faster than doing the whole bunch together
00141             // using TESS_TYPE_DRAWABLE.
00142 
00143             if ( part->getType() == Geometry::TYPE_POLYGON)
00144             {
00145                 osgUtil::Tessellator tess;
00146                 tess.setTessellationType( osgUtil::Tessellator::TESS_TYPE_GEOMETRY );
00147                 tess.setWindingType( osgUtil::Tessellator::TESS_WINDING_POSITIVE );
00148                 tess.retessellatePolygons( *osgGeom );
00149             }
00150             osgGeom->getOrCreateStateSet()->setAttributeAndModes(material);
00151             geode->addDrawable(osgGeom);
00152         }
00153     }
00154 
00155     if (geode->getNumDrawables())
00156         return geode.release();
00157     return 0;
00158 }
00159 
00160 
00161 GeometrySymbolizer::GeometrySymbolizer()
00162 {
00163     //nop
00164 }
00165 
00166 bool
00167 GeometrySymbolizer::compile(GeometrySymbolizerState* state,
00168                             osg::Group* attachPoint)
00169 {
00170     if ( !state || !state->getContent() || !attachPoint || !state->getStyle() )
00171         return false;
00172 
00173     //const GeometryContent* geometryInput = dynamic_cast<const GeometryContent*>(dataSet);
00174     //if (!geometryInput)
00175     //    return false;
00176 
00177     const GeometryList& geometryList = state->getContent()->getGeometryList();
00178 
00179     GeometrySymbolizerOperator functor;
00180     osg::Node* node = (functor)(geometryList, state->getStyle());
00181     if (node)
00182     {
00183         attachPoint->removeChildren(0, attachPoint->getNumChildren());
00184         attachPoint->addChild(node);
00185         return true;
00186     }
00187 
00188     return false;
00189 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines