CMS 3D CMS Logo

Ig2DModel.cc

Go to the documentation of this file.
00001 //<<<<<< INCLUDES                                                       >>>>>>
00002 
00003 #include "Iguana/GLModels/interface/Ig2DModel.h"
00004 #include "Iguana/GLModels/interface/Ig2DRep.h"
00005 #include "Iguana/Framework/interface/IgRepSet.h"
00006 #include "Iguana/Framework/interface/IgRepContext.h"
00007 #include <Inventor/actions/SoSearchAction.h>
00008 #include <Inventor/nodes/SoVertexProperty.h>
00009 #include <Inventor/nodes/SoIndexedFaceSet.h>
00010 #include <Inventor/nodes/SoShapeHints.h>
00011 #include <Inventor/nodes/SoGroup.h>
00012 #include <Inventor/nodes/SoSeparator.h>
00013 #include <Inventor/nodes/SoTransform.h>
00014 #include <Inventor/nodes/SoSwitch.h>
00015 #include <Inventor/nodes/SoScale.h>
00016 #include <Inventor/nodes/SoSphere.h>
00017 #include <Inventor/nodes/SoQuadMesh.h>
00018 #include <classlib/utils/StringOps.h>
00019 #include <classlib/utils/DebugAids.h>
00020 #include <classlib/utils/Log.h>
00021 
00022 #include <cassert>
00023 #include <fstream>
00024 #include <sstream>
00025 #include <iostream>
00026 
00027 //<<<<<< PRIVATE DEFINES                                                >>>>>>
00028 //<<<<<< PRIVATE CONSTANTS                                              >>>>>>
00029 //<<<<<< PRIVATE TYPES                                                  >>>>>>
00030 //<<<<<< PRIVATE VARIABLE DEFINITIONS                                   >>>>>>
00031 //<<<<<< PUBLIC VARIABLE DEFINITIONS                                    >>>>>>
00032 //<<<<<< CLASS STRUCTURE INITIALIZATION                                 >>>>>>
00033 //<<<<<< PRIVATE FUNCTION DEFINITIONS                                   >>>>>>
00034 //<<<<<< PUBLIC FUNCTION DEFINITIONS                                    >>>>>>
00035 //<<<<<< MEMBER FUNCTION DEFINITIONS                                    >>>>>>
00036 
00037 #define GRID_SIZE 20
00038 
00050 lat::logflag LFcommon2d = { 0, "common2d", true, -1 };
00051 
00052 Ig2DModel::Ig2DModel (IgState *state, Ig3DBaseModel *sourceModel)
00053     : Ig3DBaseModel (state),
00054       m_sourceModel (sourceModel),
00055       m_objectTransform (0),
00056       m_cutGroup (0)
00057 {
00058     LOG (0, trace, LFcommon2d, "Ig2DModel created\n");  
00059 
00060     std::ifstream cfgFile ("layers.dat");
00061 
00062     SoScale *scale = new SoScale;
00063     scale->scaleFactor = SbVec3f (1, 1, 100);
00064     scale->setName ("SUBLAYER_SCALING");
00065     attachPoint ()->magic ()->addChild (scale);
00066     
00067     if (cfgFile.is_open ())
00068     {
00069         /*reading of the input file*/
00070         while (cfgFile.good ())
00071         {
00072             std::stringstream fullName;
00073             std::stringbuf buffer;
00074             std::stringbuf element;
00075             
00076             cfgFile.get (buffer, '\n');    
00077             std::string line = 
00078                 lat::StringOps::split (buffer.str(), "#").front ();
00079             
00080             if (line != "")
00081             {
00082                 lat::StringList stringList = 
00083                     lat::StringOps::split (line, "=");          
00084                 
00085                 if (stringList.size () > 1)
00086                 {
00087                     if (find (stringList.begin (), 
00088                               stringList.end (), 
00089                               std::string ("nocut")) != stringList.end ())
00090                     {
00091                         std::string layerName = stringList.front ();
00092                         m_cutConf.insert (layerName);
00093                         LOG (0, trace, LFcommon2d, 
00094                              "Not cutting layer:" << layerName << "\n");                        
00095                     }
00096                     else
00097                     {
00098                         LOG (0, trace, LFcommon2d,
00099                              "nocut not found in " << line << "\n");                    
00100                     }               
00101                 }
00102                 else
00103                 {
00104                     LOG (0, trace, LFcommon2d, "Layer:" << line << "\n");
00105                     
00106                     SoSwitch    *node = new SoSwitch;
00107                     node->whichChild = SO_SWITCH_ALL;
00108                     node->setName (encode (line));                                      
00109                     LOG (0, trace, lat::LFgeneral, line << "\n");
00110                     LOG (0, trace, lat::LFgeneral, 
00111                          node->getName ().getString () << "\n");
00112                     
00113                     Ig2DRep *rep = new Ig2DRep (this, 0, 0, node);
00114                     
00115                     ASSERT (rep);
00116                 }               
00117             }
00118             //FIXME: max 1024 trash characters after layer position.
00119             cfgFile.ignore (1024,'\n');
00120         }
00121         cfgFile.close ();
00122     }else
00123     {
00124         LOG (0, trace, LFcommon2d, "Cannot read configuration file");   
00125     }
00126     
00127     // Rotate the object to face the correct direction
00128     m_objectTransform = new SoTransform;
00129     m_objectTransform->rotation.setValue (SbVec3f (0, 1, 0), M_PI/2);
00130     m_objectTransform->ref ();    
00131 
00132     // Create a plane made of quads.
00133     SbVec3f vertices[2*2];
00134 
00135     vertices[0] = SbVec3f (-1, 1, 0);
00136     vertices[1] = SbVec3f (1, 1, 0);
00137     vertices[2] = SbVec3f (-1, -1, 0);
00138     vertices[3] = SbVec3f (1, -1, 0);
00139     
00140     //for (int y = 0; y < 2; y++)
00141     //  for (int x = 0; x < 2; x++)
00142     //  {
00143     //      vertices [x+y*2] = SbVec3f (((float) (x - 1)) * 0.5,
00144     //                                   ((float) (y - 1)) * 0.5,
00145     //                                   0);
00146     //  }
00147 
00148     SoVertexProperty *properties = new SoVertexProperty;
00149     properties->vertex.setValues (0, 2*2, vertices);
00150 
00151     SoQuadMesh *mesh = new SoQuadMesh;
00152     mesh->verticesPerRow = 2;
00153     mesh->verticesPerColumn = 2;
00154     mesh->vertexProperty = properties;
00155     
00156     // Project the semi-sphere and translate it a bit from 0 to avoid
00157     // numerical problems.
00158     m_cutScale = new SoTransform;
00159     m_cutScale->scaleFactor = SbVec3f (1, 1, 1);
00160     m_cutPosition = new SoTransform;
00161     m_cutPosition->translation = SbVec3f (0, 0, 0);
00162     
00163     m_cutGroup = new SoSeparator;
00164     m_cutGroup->ref ();
00165     m_cutGroup->addChild (m_cutPosition);
00166     m_cutGroup->addChild (m_cutScale);
00167     m_cutGroup->addChild (mesh);
00168 }
00169 
00170 Ig3DBaseModel *
00171 Ig2DModel::sourceModel (void) const
00172 { return m_sourceModel; }
00173 
00174 SoNode *
00175 Ig2DModel::cutTransform (void) const
00176 { return m_objectTransform; }
00177 
00178 void
00179 Ig2DModel::setCutTransform (SbVec3f axis, float angle)
00180 {
00181     m_objectTransform->rotation.setValue (axis, angle);
00182 
00183     Ig3DBaseRep *start = attachPoint ();
00184     for (int i = 0; i < start->children (); i++)
00185     {
00186         ASSERT (dynamic_cast<Ig2DRep *> (start->child (i)));
00187         if (IgRepContext *context = start->child (i)->context ())
00188         {
00189             ASSERT (context->object ());
00190             // FIXME: Cheat with bits.  Move to invalidation
00191             IgRepSet::invalidate (context->object (), this, ~0u);
00192         }
00193         else
00194             LOG (0, trace, lat::LFgeneral,
00195                  "2d model not updated, child does not"
00196                  << " have a context: " << i << " = "
00197                  << start->child (i)->getChild (1)->getName ().getString ()
00198                  << "\n");
00199     }   
00200 }
00201 
00202 SoNode *
00203 Ig2DModel::cutPlane (void) const
00204 { return m_cutGroup; }
00205 
00206 std::string
00207 Ig2DModel::removeLast (const std::string &str)
00208 {
00209     std::string result = str;    
00210 
00211     int position = result.rfind ("/");
00212 
00213     if (position == 1)
00214     {
00215     // If the slash is found in at position 1, than it its the root
00216     // one, skip!
00217         return "";      
00218     }
00219         
00220     result.erase (position, result.size ()-position);
00221     
00222     return result;
00223 }
00224 
00225 std::string
00226 Ig2DModel::removeFirst (const std::string &str)
00227 {
00228     std::string result = str;    
00229     
00230     unsigned int position = result.find ("/", 2);
00231     if (position == std::string::npos)
00232     {
00233         // If the slash is not found, than we are at a toplevel name.
00234         // Remove everthing!
00235         return "";      
00236     }
00237     
00238     result.erase (0, position);
00239     result = "_" + result;
00240     
00241     return result;
00242 }
00243 
00244 std::string
00245 Ig2DModel::getFirst (const std::string &str)
00246 {
00247     std::string result = str;
00248     unsigned int position = result.find ("/", 2);
00249     if (position != std::string::npos)
00250     {           
00251         result.erase (position, str.size() - position);
00252     }    
00253 
00254     return result;    
00255 }
00256 
00257 std::string
00258 Ig2DModel::getLast (const std::string &str)
00259 {
00260     std::string result = str;
00261     int position = result.rfind ("/");    
00262     
00263     if (position != 1)
00264     {
00265         // If position != 1, then it means we have to remove one
00266         // entry. Remember to add _ in front of it!
00267         result.erase (0, position);
00268         result = "_" + result;  
00269     }
00270         
00271     return result;
00272 }
00273 
00274 
00275 Ig2DRep *
00276 Ig2DModel::fullMatch (Ig3DBaseRep *from, const std::string &name)
00277 {
00278     //    std::cerr << "Looking for: " << name << "...";
00279     Ig3DBaseRep *child = (from ? from : attachPoint ())->child (encode (name));
00280     //    if (child)
00281     //  std::cerr << "Found @" << std::hex << child << std::dec << "\n";
00282     //    else
00283     //  std::cerr << "Not found\n";
00284 
00285     return static_cast<Ig2DRep *> (child);
00286 }
00287 
00288 std::string
00289 Ig2DModel::closestMatchName (const std::string &name)
00290 {
00291     // if we are looking for an empty string, just return.
00292     if (name == "")
00293     {
00294         return "";
00295     }
00296     //    std::cerr << "Looking for partial match: " << name << "...";
00297 
00298     // Search for the separator with the wanted name
00299     Ig3DBaseRep *child = attachPoint ()->child (encode (name));
00300     if (child)
00301     {
00302         //std::cerr << "Found @" << std::hex << child << std::dec << "\n";
00303         return name;
00304     }
00305     else
00306     {
00307         //      std::cerr << "Not found\n";
00308         return closestMatchName (removeLast (name));    
00309     }
00310 }
00311 
00312 Ig2DRep *
00313 Ig2DModel::createFull (Ig2DRep *startingRep, const std::string &name)
00314 {
00315     getFirst (name);
00316     
00317     std::string currentPath = name;
00318     Ig2DRep *currentRep = startingRep;
00319 
00320     while (getFirst (currentPath) != "")
00321     {
00322         Ig2DRep *rep;
00323         
00324         if ((rep = fullMatch (currentRep, getFirst (currentPath))))
00325         {
00326             //  std::cerr << "Found " << getFirst (currentPath) << "...descending..." << std::endl;         
00327             currentPath = removeFirst (currentPath);
00328             currentRep = rep;       
00329         }
00330         else
00331         {
00332             //std::cerr << "Creating: " << getFirst (currentPath) << std::endl;
00333             
00334             // Create a new separator with a scaling operation in front
00335             SoSwitch    *node = new SoSwitch;
00336             node->setName (encode (getFirst (currentPath)));
00337             node->whichChild = SO_SWITCH_ALL;
00338 
00339             rep = new Ig2DRep (this, currentRep, 0, node);
00340 
00341             currentPath = removeFirst (currentPath);    
00342             currentRep = rep;   
00343         }
00344     }
00345     return currentRep;
00346 }
00347 
00348 Ig2DRep *
00349 Ig2DModel::getLayer (const std::string &name)
00350 {       
00351     Ig2DRep *result = 0;
00352     
00353     std::string encodedName = "_" + name;
00354     //    std::cerr << "Getting layer: " << encodedName << std::endl;
00355         
00356     // Search for a full match
00357     Ig2DRep *fullMatchRep = fullMatch (attachPoint (), encodedName);
00358     if (fullMatchRep != 0) 
00359     {
00360         result = fullMatchRep;
00361     }
00362     else
00363     {
00364         // Search for a partial match
00365         std::string closestMatchName = this->closestMatchName (encodedName);
00366     
00367         if (closestMatchName != "")
00368         {
00369             // If a partial match is found, look for the rep associate to
00370             // it and add the remaining part.
00371             Ig2DRep *closestMatchRep
00372                 = static_cast<Ig2DRep *> (attachPoint ()->child
00373                                           (encode (closestMatchName)));
00374             std::string relativeName = encodedName;
00375             relativeName.erase (0, closestMatchName.size ());   
00376             result = createFull (closestMatchRep, "_"+relativeName);    
00377         }
00378         else
00379         {
00380             //    std::cerr << "Creating path: " << encodedName << std::endl;
00381         
00382             // Create a new top-level entry for the name specified.
00383             result = createFull (0, encodedName);
00384         }
00385     }
00386     return result;    
00387 }
00388 
00389 void
00390 Ig2DModel::setCutPlaneSize (float w, float h)
00391 {
00392     m_cutScale->scaleFactor = SbVec3f (w, h, 0);    
00393 }
00394 
00395 void
00396 Ig2DModel::setCutPlanePosition (float x, float y)
00397 {
00398     m_cutPosition->translation = SbVec3f (x, y, 0);
00399 }
00400 
00401 bool
00402 Ig2DModel::isToBeCut (std::string twigName)
00403 {
00404     for(NotCutTwigSet::iterator i = m_cutConf.begin ();
00405         i != m_cutConf.end ();
00406         i++)
00407     {
00408         std::string matchString = *i;
00409         if (twigName.find (matchString) != std::string::npos)
00410         {
00411             LOG (0, trace, LFcommon2d,
00412                  "Not cutting " << twigName
00413                  << " because matches " << matchString << "\n");
00414             return false;           
00415         }
00416     } 
00417     return true;    
00418 }

Generated on Tue Jun 9 17:38:42 2009 for CMSSW by  doxygen 1.5.4