00001
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
00028
00029
00030
00031
00032
00033
00034
00035
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
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
00119 cfgFile.ignore (1024,'\n');
00120 }
00121 cfgFile.close ();
00122 }else
00123 {
00124 LOG (0, trace, LFcommon2d, "Cannot read configuration file");
00125 }
00126
00127
00128 m_objectTransform = new SoTransform;
00129 m_objectTransform->rotation.setValue (SbVec3f (0, 1, 0), M_PI/2);
00130 m_objectTransform->ref ();
00131
00132
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
00141
00142
00143
00144
00145
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
00157
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
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
00216
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
00234
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
00266
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
00279 Ig3DBaseRep *child = (from ? from : attachPoint ())->child (encode (name));
00280
00281
00282
00283
00284
00285 return static_cast<Ig2DRep *> (child);
00286 }
00287
00288 std::string
00289 Ig2DModel::closestMatchName (const std::string &name)
00290 {
00291
00292 if (name == "")
00293 {
00294 return "";
00295 }
00296
00297
00298
00299 Ig3DBaseRep *child = attachPoint ()->child (encode (name));
00300 if (child)
00301 {
00302
00303 return name;
00304 }
00305 else
00306 {
00307
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
00327 currentPath = removeFirst (currentPath);
00328 currentRep = rep;
00329 }
00330 else
00331 {
00332
00333
00334
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
00355
00356
00357 Ig2DRep *fullMatchRep = fullMatch (attachPoint (), encodedName);
00358 if (fullMatchRep != 0)
00359 {
00360 result = fullMatchRep;
00361 }
00362 else
00363 {
00364
00365 std::string closestMatchName = this->closestMatchName (encodedName);
00366
00367 if (closestMatchName != "")
00368 {
00369
00370
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
00381
00382
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 }