Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSGVerifyGraphOp.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 
00040 /***************************************************************************\
00041 *                             Includes                                    *
00042 \***************************************************************************/
00043 
00044 #include <OSGVerifyGraphOp.h>
00045 #include <OSGGroup.h>
00046 #include <OSGSimpleAttachments.h>
00047 #include <OSGPrimitiveIterator.h>
00048 
00049 OSG_USING_NAMESPACE
00050 
00051 /***************************************************************************\
00052  *                            Description                                  *
00053 \***************************************************************************/
00054 
00062 /***************************************************************************\
00063  *                           Instance methods                              *
00064 \***************************************************************************/
00065 
00066 /*-------------------------------------------------------------------------*\
00067  -  public                                                                 -
00068 \*-------------------------------------------------------------------------*/
00069 
00070 
00071 /*------------- constructors & destructors --------------------------------*/
00072 
00073 VerifyGraphOp::VerifyGraphOp(const char* name, bool repair, bool verbose): 
00074     GraphOp(name), _repair(repair), _verbose(verbose)
00075 {
00076 }
00077 
00078 VerifyGraphOp::~VerifyGraphOp(void)
00079 {
00080 }
00081 
00082 GraphOp *VerifyGraphOp::create()
00083 {
00084     VerifyGraphOp *inst = new VerifyGraphOp();
00085     return inst;
00086 }
00087 
00088 void VerifyGraphOp::setParams(const std::string params)
00089 {
00090     ParamSet ps(params);   
00091     
00092     ps("repair",  _repair);
00093     ps("verbose",  _verbose);
00094     
00095     std::string out = ps.getUnusedParams();
00096     if(out.length())
00097     {
00098         FWARNING(("VerifyGraphOp doesn't have parameters '%s'.\n",
00099                 out.c_str()));
00100     }
00101 }
00102 
00103 std::string VerifyGraphOp::usage(void)
00104 {
00105     return 
00106     "Verify: Test validity of Geometries\n"
00107     "  Run some validity tests on Geometries, makes sure indices are\n"
00108     "  in the valid range etc.\n"
00109     "Params: name (type, default)\n"
00110     "  repair  (bool, true): try to repair consistency errors\n"
00111     "  verbose (bool, false): print information during traversal\n";
00112 }
00113 
00114 void VerifyGraphOp::setRepair(bool repair)
00115 {
00116     _repair = repair;
00117 }
00118 
00119 void VerifyGraphOp::setVerbose(bool verbose)
00120 {
00121     _verbose = verbose;
00122 }
00123 
00124 bool VerifyGraphOp::traverse(NodePtr& node)
00125 {
00126     // Clean up
00127     
00128     _numErrors = 0;
00129     _corruptedGeos.clear();
00130     _corruptedNodes.clear();
00131     
00132     // Find the bad nodes.
00133     if (!GraphOp::traverse(node)) {
00134         return false;
00135     }
00136 
00137 
00138     if(_repair)
00139     {
00140         repairGeometry();      // Repair any corrupted geometry nodes
00141     }
00142 
00143     if(_verbose)
00144     {
00145         SINFO << "Verifier completed. Errors found:" << _numErrors << endLog;
00146     }
00147 
00148      
00149 
00150     return true;
00151 }
00152 
00153 Action::ResultE VerifyGraphOp::traverseEnter(NodePtr &node)
00154 {
00155     if(NullFC == node)
00156     {
00157         FWARNING(("VerifyGraphOp::travNodeEnter: called with NULL node, "
00158                   "skipping."));
00159         return Action::Continue;
00160     }
00161 
00162     // Verify basic node structure
00163     std::string node_name;
00164     if(OSG::getName(node) != NULL)
00165     { 
00166         node_name = std::string(OSG::getName(node)); 
00167     }
00168 
00169     NodeCorePtr node_core = node->getCore();
00170     if(NullFC == node_core)
00171     {
00172         _corruptedNodes.push_back(node);
00173         _numErrors += 1;
00174         if(_verbose)
00175         { 
00176             SINFO << "Node: [" << node_name << "] has NULL core." 
00177                   << endLog; 
00178         }
00179         if(_repair)
00180         {
00181             if(_verbose) 
00182                 SINFO << "  Repairing node.  Adding group core." << endLog;
00183             beginEditCP(node);
00184             node->setCore(Group::create());
00185             endEditCP(node);
00186             std::string new_name = node_name + "_FIXED";
00187             OSG::setName(node, new_name);
00188         }
00189     }
00190 
00191     // Check based on core types
00192     if(NullFC != node_core)
00193     {
00194         if(GeometryPtr::dcast(node_core) != NullFC)
00195         {
00196             return verifyGeometry(node);
00197         }
00198     }
00199 
00200     return Action::Continue;
00201 }
00202 
00203 Action::ResultE VerifyGraphOp::traverseLeave(NodePtr&, Action::ResultE res)
00204 {
00205     return Action::Continue;
00206 }
00207 
00208 
00210 Action::ResultE VerifyGraphOp::verifyGeometry(NodePtr &node)
00211 {
00212     GeometryPtr geo = GeometryPtr::dcast(node->getCore());
00213 
00214     if(geo == NullFC)
00215         return Action::Continue;
00216 
00217     if(geo->getPositions() == NullFC)
00218         return Action::Continue;
00219 
00220     UInt32 start_errors = _numErrors;
00221 
00222     Int32 positions_size = geo->getPositions()->getSize();
00223 
00224     Int32 normals_size = 0;
00225     if(geo->getNormals() != NullFC)
00226         normals_size = geo->getNormals()->getSize();
00227 
00228     Int32 colors_size = 0;
00229     if(geo->getColors() != NullFC)
00230         colors_size = geo->getColors()->getSize();
00231 
00232     Int32 secondary_colors_size = 0;
00233     if(geo->getSecondaryColors() != NullFC)
00234         secondary_colors_size = geo->getSecondaryColors()->getSize();
00235 
00236     Int32 texccords_size = 0;
00237     if(geo->getTexCoords() != NullFC)
00238         texccords_size = geo->getTexCoords()->getSize();
00239 
00240     Int32 texccords1_size = 0;
00241     if(geo->getTexCoords1() != NullFC)
00242         texccords1_size = geo->getTexCoords1()->getSize();
00243 
00244     Int32 texccords2_size = 0;
00245     if(geo->getTexCoords2() != NullFC)
00246         texccords2_size = geo->getTexCoords2()->getSize();
00247 
00248     Int32 texccords3_size = 0;
00249     if(geo->getTexCoords3() != NullFC)
00250         texccords3_size = geo->getTexCoords3()->getSize();
00251 
00252     UInt32 pos_errors = 0;
00253     UInt32 norm_errors = 0;
00254     UInt32 col_errors = 0;
00255     UInt32 col2_errors = 0;
00256     UInt32 tex0_errors = 0;
00257     UInt32 tex1_errors = 0;
00258     UInt32 tex2_errors = 0;
00259     UInt32 tex3_errors = 0;
00260 
00261     PrimitiveIterator it;
00262     for(it = geo->beginPrimitives(); it != geo->endPrimitives(); ++it)
00263     {
00264         for(UInt32 v=0; v < it.getLength(); ++v)
00265         {
00266             if(it.getPositionIndex(v) >= positions_size)
00267                 ++pos_errors;
00268             if(it.getNormalIndex(v) >= normals_size)
00269                 ++norm_errors;
00270             if(it.getColorIndex(v) >= colors_size)
00271                 ++col_errors;
00272             if(it.getSecondaryColorIndex(v) >= secondary_colors_size)
00273                 ++col2_errors;
00274             if(it.getTexCoordsIndex(v) >= texccords_size)
00275                 ++tex0_errors;
00276             if(it.getTexCoordsIndex1(v) >= texccords1_size)
00277                 ++tex1_errors;
00278             if(it.getTexCoordsIndex2(v) >= texccords2_size)
00279                 ++tex2_errors;
00280             if(it.getTexCoordsIndex3(v) >= texccords3_size)
00281                 ++tex3_errors;
00282         }
00283     }
00284 
00285     if(norm_errors > 0)
00286     {
00287         norm_errors = 0;
00288         if(_verbose) SINFO << "removed corrupted normals!\n";
00289         beginEditCP(geo);
00290         geo->setNormals(NullFC);
00291         endEditCP(geo);
00292     }
00293 
00294     if(col_errors > 0)
00295     {
00296         col_errors = 0;
00297         if(_verbose) SINFO << "removed corrupted colors!\n";
00298         beginEditCP(geo);
00299         geo->setColors(NullFC);
00300         endEditCP(geo);
00301     }
00302 
00303     if(tex0_errors > 0)
00304     {
00305         tex0_errors = 0;
00306         if(_verbose) SINFO << "removed corrupted tex coords0!\n";
00307         beginEditCP(geo);
00308         geo->setTexCoords(NullFC);
00309         endEditCP(geo);
00310     }
00311 
00312     _numErrors += (pos_errors + norm_errors + col_errors +
00313                    col2_errors + tex0_errors + tex1_errors +
00314                    tex2_errors + tex3_errors);
00315 
00316     // found some errors.
00317     if(_numErrors > start_errors)
00318     {
00319         _corruptedGeos.push_back(geo); 
00320     }
00321 
00322     // ok we found no errors now check for missing index map.
00323     bool need_repair(false);
00324     if(!verifyIndexMap(geo, need_repair))
00325     {
00326         if(need_repair)
00327         { 
00328             SINFO << "verifyGeometry : added missing index map!" << endLog; 
00329         }
00330         else
00331         { 
00332             SINFO << "verifyGeometry : couldn't add missing index map!\n" 
00333                   << endLog; 
00334         }
00335     }
00336 
00337     return Action::Continue;
00338 }
00339 
00340 
00341 bool VerifyGraphOp::verifyIndexMap(GeometryPtr &geo, bool &repair)
00342 {
00343     repair = false;
00344 
00345     if(geo == NullFC)
00346         return true;
00347 
00348     if(geo->getIndices() == NullFC)
00349         return true;
00350 
00351     if(!geo->getIndexMapping().empty())
00352         return true;
00353 
00354     if(geo->getPositions() == NullFC)
00355         return true;
00356 
00357     UInt32 positions_size = geo->getPositions()->getSize();
00358 
00359     UInt32 normals_size = 0;
00360     if(geo->getNormals() != NullFC)
00361         normals_size = geo->getNormals()->getSize();
00362 
00363     UInt32 colors_size = 0;
00364     if(geo->getColors() != NullFC)
00365         colors_size = geo->getColors()->getSize();
00366 
00367     UInt32 secondary_colors_size = 0;
00368     if(geo->getSecondaryColors() != NullFC)
00369         secondary_colors_size = geo->getSecondaryColors()->getSize();
00370 
00371     UInt32 texccords_size = 0;
00372     if(geo->getTexCoords() != NullFC)
00373         texccords_size = geo->getTexCoords()->getSize();
00374 
00375     UInt32 texccords1_size = 0;
00376     if(geo->getTexCoords1() != NullFC)
00377         texccords1_size = geo->getTexCoords1()->getSize();
00378 
00379     UInt32 texccords2_size = 0;
00380     if(geo->getTexCoords2() != NullFC)
00381         texccords2_size = geo->getTexCoords2()->getSize();
00382 
00383     UInt32 texccords3_size = 0;
00384     if(geo->getTexCoords3() != NullFC)
00385         texccords3_size = geo->getTexCoords3()->getSize();
00386 
00387     /*
00388     printf("sizes: %u %u %u %u %u %u %u %u\n", positions_size, normals_size,
00389     colors_size, secondary_colors_size,
00390     texccords_size, texccords1_size,
00391     texccords2_size, texccords3_size);
00392     */
00393     if((positions_size == normals_size || normals_size == 0) &&
00394        (positions_size == colors_size || colors_size == 0) &&
00395        (positions_size == secondary_colors_size || secondary_colors_size == 0) &&
00396        (positions_size == texccords_size || texccords_size == 0) &&
00397        (positions_size == texccords1_size || texccords1_size == 0) &&
00398        (positions_size == texccords2_size || texccords2_size == 0) &&
00399        (positions_size == texccords3_size || texccords3_size == 0)
00400       )
00401     {
00402         UInt16 indexmap = 0;
00403         if(positions_size > 0)
00404             indexmap |= Geometry::MapPosition;
00405         if(normals_size > 0)
00406             indexmap |= Geometry::MapNormal;
00407         if(colors_size > 0)
00408             indexmap |= Geometry::MapColor;
00409         if(secondary_colors_size > 0)
00410             indexmap |= Geometry::MapSecondaryColor;
00411         if(texccords_size > 0)
00412             indexmap |= Geometry::MapTexCoords;
00413         if(texccords1_size > 0)
00414             indexmap |= Geometry::MapTexCoords1;
00415         if(texccords2_size > 0)
00416             indexmap |= Geometry::MapTexCoords2;
00417         if(texccords3_size > 0)
00418             indexmap |= Geometry::MapTexCoords3;
00419 
00420         beginEditCP(geo, Geometry::IndexMappingFieldMask);
00421         geo->getIndexMapping().push_back(indexmap);
00422         endEditCP(geo, Geometry::IndexMappingFieldMask);
00423         repair = true;
00424         return false;
00425     }
00426     else
00427     {
00428         return false;
00429     }
00430 }
00431 
00432 
00437 bool VerifyGraphOp::repairGeometry(void)
00438 {
00439     if (!_corruptedGeos.empty())
00440     {
00441         if (_verbose)
00442         { 
00443             SINFO << "Repairing corrupted geos:" << endLog; 
00444         }
00445 
00446         for (UInt32 i=0;i<_corruptedGeos.size();++i)
00447         {
00448         // now replace corrupted geometry core with a group core.
00449         for (UInt32 j=0;j<_corruptedGeos[i]->getParents().size();++j)
00450         {
00451             NodePtr parent = _corruptedGeos[i]->getParents()[j];
00452             if (parent != NullFC)
00453             {
00454                 std::string nname;
00455                 if(OSG::getName(parent) != NULL)
00456                 { 
00457                     nname = OSG::getName(parent); 
00458                 }
00459                 if (_verbose)
00460                 { 
00461                     SINFO << "Removing corrupted geom from node: " 
00462                               << nname << endLog; 
00463                 }
00464                 nname += "_CORRUPTED";
00465                 OSG::setName(parent, nname.c_str());
00466                 beginEditCP(parent, Node::CoreFieldMask);
00467                 parent->setCore(Group::create());
00468                 endEditCP(parent, Node::CoreFieldMask);
00469                 }
00470             }
00471         }
00472         return true;
00473     }
00474 
00475     return false;
00476 }

Generated on Thu Aug 25 04:11:57 2005 for OpenSG by  doxygen 1.4.3