OSGGeoTypeGraphOp.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038
00039 #include "OSGBaseTypes.h"
00040 #include "OSGGeoTypeGraphOp.h"
00041 #include "OSGLog.h"
00042 #include "OSGTypedGeoIntegralProperty.h"
00043 #include "OSGTypedGeoVectorProperty.h"
00044 #include "OSGGraphOpFactory.h"
00045
00046 OSG_USING_NAMESPACE
00047
00048 namespace
00049 {
00050
00052 static bool registerOp(void)
00053 {
00054     GraphOpRefPtr newOp = GeoTypeGraphOp::create();
00055
00056     GraphOpFactory::the()->registerOp(newOp);
00057     return true;
00058 }
00059
00060 static OSG::StaticInitFuncWrapper registerOpWrapper(registerOp);
00061
00062 } // namespace
00063
00064
00065 GeoTypeGraphOpTransitPtr GeoTypeGraphOp::create(void)
00066 {
00067     return GeoTypeGraphOpTransitPtr(new GeoTypeGraphOp);
00068 }
00069
00070 GraphOpTransitPtr GeoTypeGraphOp::clone(void)
00071 {
00072     return GraphOpTransitPtr(new GeoTypeGraphOp);
00073 }
00074
00075 GeoTypeGraphOp::GeoTypeGraphOp(const char* name)
00076     : Inherited(name),
00077       _filter  (TypeTraits<OSG::BitVector>::getMax())
00078 {
00079 }
00080
00081 GeoTypeGraphOp::~GeoTypeGraphOp(void)
00082 {
00083 }
00084
00085 bool GeoTypeGraphOp::travNodeEnter(Node *node)
00086 {
00087     return true;
00088 }
00089
00090 bool GeoTypeGraphOp::travNodeLeave(Node *node)
00091 {
00092     Geometry *geo = dynamic_cast<Geometry *>(node->getCore());
00093
00094     if(geo == NULL)
00095         return true;
00096
00097     if(_filter & FilterNormals)
00098         processNormals(geo);
00099
00100     if(_filter & FilterIndices)
00101         processIndices(geo);
00102
00103     if(_filter & FilterLengths)
00104         processLengths(geo);
00105
00106     return true;
00107 }
00108
00109 void GeoTypeGraphOp::processNormals(Geometry *geo)
00110 {
00111     GeoVectorProperty *norm   = geo->getProperty(Geometry::NormalsIndex);
00112     GeoVec3fProperty  *norm3f = dynamic_cast<GeoVec3fProperty *>(norm);
00113
00114     if(norm3f != NULL)
00115     {
00116         GeoVec3NbPropertyUnrecPtr norm3b = GeoVec3NbProperty::create();
00117
00118         const GeoVec3fProperty::StoredFieldType *srcF = norm3f->getFieldPtr();
00119
00120         norm3b->resize(srcF->size());
00121
00122         for(UInt32 i = 0; i < srcF->size(); ++i)
00123         {
00124             Vec3f n = (*srcF)[i];
00125             n.normalize();
00126
00127             norm3b->setValue(n, i);
00128         }
00129
00130         geo->setProperty(norm3b, Geometry::NormalsIndex);
00131     }
00132 }
00133
00134 void GeoTypeGraphOp::processIndices(Geometry *geo)
00135 {
00136     Geometry::IndexBag ibag = geo->getUniqueIndexBag();
00137
00138     for(UInt32 i = 0; i < ibag.size(); ++i)
00139     {
00140         GeoIntegralProperty *ind   = ibag[i].first;
00141         GeoUInt32Property   *ind32 = dynamic_cast<GeoUInt32Property *>(ind);
00142
00143         if(ind32 != NULL)
00144         {
00145             const GeoUInt32Property::StoredFieldType *srcF = ind32->getFieldPtr();
00146
00147             UInt32 maxIndex     = TypeTraits<UInt16>::getMax();
00148             bool   allowConvert = true;
00149
00150             for(UInt32 j = 0; j < srcF->size(); ++j)
00151             {
00152                 if((*srcF)[j] > maxIndex)
00153                 {
00154                     allowConvert = false;
00155                     break;
00156                 }
00157             }
00158
00159             if(allowConvert)
00160             {
00161                 GeoUInt16PropertyUnrecPtr           ind16 =
00162                         GeoUInt16Property::create();
00163                 GeoUInt16Property::StoredFieldType *dstF  =
00164                         ind16->editFieldPtr();
00165
00166                 dstF->reserve(srcF->size());
00167
00168                 for(UInt32 j = 0; j < srcF->size(); ++j)
00169                 {
00170                     UInt32 i = (*srcF)[j];
00171                     dstF->push_back(i);
00172                 }
00173
00174                 // set index for all properties that use it
00175                 for(UInt32 j = 0; j < ibag[i].second.size(); ++j)
00176                     geo->setIndex(ind16, ibag[i].second[j]);
00177             }
00178         }
00179     }
00180 }
00181
00182 void GeoTypeGraphOp::processLengths(Geometry *geo)
00183 {
00184     GeoIntegralProperty *len   = geo->getLengths();
00185     GeoUInt32Property   *len32 = dynamic_cast<GeoUInt32Property *>(len);
00186
00187     if(len32 != NULL)
00188     {
00189         const GeoUInt32Property::StoredFieldType *srcF = len32->getFieldPtr();
00190
00191         UInt32 maxLength    = TypeTraits<UInt16>::getMax();
00192         bool   allowConvert = true;
00193
00194         for(UInt32 i = 0; i < srcF->size(); ++i)
00195         {
00196             if((*srcF)[i] > maxLength)
00197             {
00198                 allowConvert = false;
00199                 break;
00200             }
00201         }
00202
00203         if(allowConvert)
00204         {
00205             GeoUInt16PropertyUnrecPtr           len16 =
00206                     GeoUInt16Property::create();
00207             GeoUInt16Property::StoredFieldType *dstF  =
00208                     len16->editFieldPtr();
00209
00210             dstF->reserve(srcF->size());
00211
00212             for(UInt32 j = 0; j < srcF->size(); ++j)
00213             {
00214                 UInt32 i = (*srcF)[j];
00215                 dstF->push_back(i);
00216             }
00217
00218             geo->setLengths(len16);
00219         }
00220     }
00221 }
00222
00223 void GeoTypeGraphOp::setParams(const std::string params)
00224 {
00225     ParamSet ps(params);
00226     std::string filter;
00227
00228     if(ps("filter", filter))
00229     {
00230         _filter = TypeTraits<BitVector>::BitsClear;
00231
00232         if(filter.find("Nor") != std::string::npos ||
00233            filter.find("nor") != std::string::npos   )
00234         {
00235             _filter |= FilterNormals;
00236         }
00237
00238         if(filter.find("Ind") != std::string::npos ||
00239            filter.find("ind") != std::string::npos   )
00240         {
00241             _filter |= FilterIndices;
00242         }
00243
00244         if(filter.find("Len") != std::string::npos ||
00245            filter.find("len") != std::string::npos   )
00246         {
00247             _filter |= FilterLengths;
00248         }
00249     }
00250
00251     std::string out = ps.getUnusedParams();
00252
00253     if(out.length())
00254     {
00255         FWARNING(("GeoTypeGraphOp doesn't have parameters '%s'.\n",
00256                 out.c_str()));
00257     }
00258 }
00259
00260 std::string GeoTypeGraphOp::usage(void)
00261 {
00262     return
00263     "GeoType: convert the types of a Geometry's attributes\n"
00264     "  Tries to convert the attributes of a Geometry to smaller/faster\n"
00265     "  types. By default only the lengths are changed to 16 bit.\n"
00266     "Params: name (type, default)\n"
00267     "  filter  (string, \"\"): fields to convert, can be a combination of\n"
00268     "                        Normals, Indices and Lengths, connected by +.\n"
00269     ;
00270 }
00271
00272 void GeoTypeGraphOp::setFilter(const OSG::BitVector &filter)
00273 {
00274     _filter = filter;
00275 }