CMS 3D CMS Logo

IgSoGridPlane.cc

Go to the documentation of this file.
00001 //<<<<<< INCLUDES                                                       >>>>>>
00002 
00003 #include "Iguana/Inventor/interface/IgSoGridPlane.h"
00004 #include "Iguana/Inventor/interface/IgSoGridPlaneMap.h"
00005 #include "Iguana/GLModels/interface/Ig3DBaseModel.h"
00006 #include <Inventor/sensors/SoFieldSensor.h>
00007 #include <Inventor/nodes/SoMaterial.h>
00008 #include <Inventor/nodes/SoTranslation.h>
00009 #include <Inventor/nodes/SoText2.h>
00010 #include <Inventor/nodes/SoResetTransform.h>
00011 #include <Inventor/SbString.h>
00012 #include <assert.h>
00013 
00014 #ifdef __APPLE__
00015 # include <OpenGL/gl.h>
00016 #else
00017 # include <GL/gl.h>
00018 #endif
00019 //<<<<<< PRIVATE DEFINES                                                >>>>>>
00020 //<<<<<< PRIVATE CONSTANTS                                              >>>>>>
00021 //<<<<<< PRIVATE TYPES                                                  >>>>>>
00022 //<<<<<< PRIVATE VARIABLE DEFINITIONS                                   >>>>>>
00023 //<<<<<< PUBLIC VARIABLE DEFINITIONS                                    >>>>>>
00024 //<<<<<< CLASS STRUCTURE INITIALIZATION                                 >>>>>>
00025 
00026 SO_NODE_SOURCE (IgSoGridPlane);
00027 
00028 //<<<<<< PRIVATE FUNCTION DEFINITIONS                                   >>>>>>
00029 //<<<<<< PUBLIC FUNCTION DEFINITIONS                                    >>>>>>
00030 //<<<<<< MEMBER FUNCTION DEFINITIONS                                    >>>>>>
00031 
00032 void
00033 IgSoGridPlane::initClass (void)
00034 {
00035     SO_NODE_INIT_CLASS (IgSoGridPlane, SoGroup, "Group");
00036 }
00037 
00038 IgSoGridPlane::IgSoGridPlane (void)
00039     : m_plane            (new IgSoGridPlaneMap),
00040       m_shapeHints       (new SoShapeHints),      
00041       m_planeSensor      (0),
00042       m_xOriginSensor    (0),
00043       m_zOriginSensor    (0),
00044       m_xLenSensor       (0),
00045       m_zLenSensor       (0),
00046       m_spacingSensor    (0),
00047       m_onSensor         (0),
00048       m_colorSensor      (0),
00049       m_labelColorSensor (0),
00050       m_manip            (0),
00051       m_manipSensor      (0),
00052       m_mplaneSensor     (0),
00053           m_scaleSensor      (0),
00054           m_scale            (0),
00055           m_gridPlane        (0)
00056 {
00057         SO_NODE_CONSTRUCTOR (IgSoGridPlane);    
00058         SO_NODE_ADD_FIELD (plane, (SbPlane (SbVec3f (0.0, 1.0, 0.0), 0.0)));
00059         SO_NODE_ADD_FIELD (xOrigin, (0.0f));
00060         SO_NODE_ADD_FIELD (zOrigin, (0.0f));
00061         SO_NODE_ADD_FIELD (xLen, (7.0f));
00062         SO_NODE_ADD_FIELD (zLen, (16.0f));
00063         SO_NODE_ADD_FIELD (spacing, (1000.0f));
00064         SO_NODE_ADD_FIELD (on, (FALSE));
00065         SO_NODE_ADD_FIELD (color, (SbVec3f (1,1,1)));
00066         SO_NODE_ADD_FIELD (labelColor, (SbVec3f (1,1,1)));
00067         SO_NODE_ADD_FIELD (manip, (FALSE));
00068         
00069         // the reason we are setting the caller is that we need a way to get the
00070         // most recent values for the scale without disturbing the order of the
00071         // rendered elements, as soon as a value changes which is important to 
00072         // the scale, we set a flag on the GridPlaneMap which then calls the 
00073         // updateScale method in this class
00074         m_plane->setCaller (this);
00075         // reset previous transformations
00076         addChild (new SoResetTransform);
00077 
00078         m_gridPlane = new SoGroup;
00079         m_gridPlane->setName ("Grid_Plane_Composite");
00080         addChild (m_gridPlane);
00081 
00082         m_shapeHints->ref();
00083         m_shapeHints->setName ("Shape_Hints");
00084         m_gridPlane->addChild (m_shapeHints);
00085         
00086         m_plane->setName ("GridPlaneMap");
00087         m_gridPlane->addChild (m_plane);
00088         addScale ();
00089         
00090         attachSensors ();
00091 }
00092 
00093 void
00094 IgSoGridPlane::addScale ()
00095 {
00096         const bool hasChildren = m_gridPlane->getNumChildren () == 2;
00097         assert (hasChildren && "check the scene graph elements!");
00098                 
00099         if (hasChildren)
00100         {
00101                 // using 'ref ()' because we dont want the scale to be deleted,
00102                 // when the grid is turned off
00103                 m_scale = new SoLevelOfDetail;
00104                 m_scale->screenArea.set1Value (0, 5000);
00105                 m_scale->setName ("Grid_Scale");
00106                 m_scale->ref ();
00107                 
00108                 // add different levels of complexity: until now only 2
00109                 SoSeparator* complexLabels = new SoSeparator;
00110                 SoSeparator* noLabels = new SoSeparator;
00111                 m_scale->addChild (complexLabels);
00112                 m_scale->addChild (noLabels);
00113                 
00114                 if (on.getValue ())
00115                 {
00116                         m_gridPlane->addChild (m_scale);
00117                 }
00118         }
00119 }
00120 
00121 void
00122 IgSoGridPlane::updateScale ()
00123 {
00124         // is called by gridplanemap
00125         if (on.getValue ())
00126         {
00127                 assert (m_scale);
00128                 const float stepLength = spacing.getValue () / 1000.0f;
00129                 const float xLength = ceil (xLen.getValue () / stepLength) * stepLength;
00130                 const float zLength = ceil (zLen.getValue () / stepLength) * stepLength;
00131                 
00132                 SoSeparator* labelGroup = static_cast<SoSeparator*> (m_scale->getChild (0));
00133                 labelGroup->removeAllChildren ();
00134                 
00135                 SbVec3f xDir = m_plane->labelSpot[1] - m_plane->labelSpot[0];
00136                 xDir.normalize ();
00137                 SbVec3f zDir = m_plane->labelSpot[2] - m_plane->labelSpot[0];
00138                 zDir.normalize ();
00139                 
00140                 // if the color is any other than white, change it
00141                 const SbColor c = labelColor.getValue ();
00142                 if (c[0] * c[1] * c[2] < 1.0f) 
00143                 {
00144                         SoMaterial* labelColor = new SoMaterial;
00145                         labelColor->diffuseColor.setValue (c[0], c[1], c[2]);
00146                         labelGroup->addChild (labelColor);
00147                 }
00148                 // set 0
00149                 setLabelMove (labelGroup, m_plane->labelSpot[0]);
00150                 setLabelText (labelGroup, 0, true);
00151                 // set lower right
00152                 setLabelMove (labelGroup, m_plane->labelSpot[1] - m_plane->labelSpot[0]);
00153                 setLabelText (labelGroup, xLength, true);
00154                 // set upper left
00155                 setLabelMove (labelGroup, m_plane->labelSpot[2] - m_plane->labelSpot[1]);
00156                 setLabelText (labelGroup, zLength);
00157                 // back to center
00158                 setLabelMove (labelGroup, m_plane->labelSpot[0] - m_plane->labelSpot[2]);
00159                 
00160                 const float tenStepLengths = stepLength * 10;
00161                 SbVec3f step = xDir * tenStepLengths;
00162                 
00163                 float length = xLength;
00164                 float stepSum = tenStepLengths;
00165                 SbVec3f movedSteps (0.f, 0.f, 0.f);
00166                 bool changed = false;
00167                 
00168                 // steps inbetween
00169                 for (unsigned i = 0; i < 2; i++)
00170                 {
00171                         while (stepSum < length)
00172                         {
00173                                 setLabelMove (labelGroup, step);
00174                                 movedSteps += step;
00175 
00176                                 setLabelText (labelGroup, stepSum, (i == 0));
00177                                 stepSum += tenStepLengths;
00178                         }
00179                         
00180                         // change direction
00181                         if (!changed)
00182                         {
00183                                 if (movedSteps.length () > 0) 
00184                                 {
00185                                         setLabelMove (labelGroup, -movedSteps);
00186                                 }
00187                                 step = zDir * tenStepLengths;
00188                                 stepSum = tenStepLengths;
00189                                 length = zLength;
00190                                 changed = true;
00191                         }
00192                 }
00193         }
00194 }
00195 
00196 void
00197 IgSoGridPlane::setLabelMove (SoSeparator* labelGroup, SbVec3f step)
00198 {
00199         SoTranslation* move = new SoTranslation;
00200         move->translation = step;
00201         labelGroup->addChild (move);
00202 }
00203 
00204 void
00205 IgSoGridPlane::setLabelText (SoSeparator* labelGroup, float position, bool right)
00206 {
00207         char textLabel[20];
00208         SoText2* text = new SoText2;
00209         unsigned nbr = sprintf (textLabel, "%.2f", position);
00210         textLabel[nbr+1] = textLabel[nbr];
00211         textLabel[nbr] = 'm';
00212         text->string = textLabel;
00213         
00214         if (right)
00215         {
00216                 text->justification = SoText2::RIGHT;
00217         }
00218         labelGroup->addChild (text);
00219 }
00220 
00221 void
00222 IgSoGridPlane::attachSensors ()
00223 {
00224         m_planeSensor = new SoFieldSensor (&planeSensorCB, this);
00225         m_xOriginSensor = new SoFieldSensor (&xOriginSensorCB, this);
00226         m_zOriginSensor = new SoFieldSensor (&zOriginSensorCB, this);
00227         m_xLenSensor = new SoFieldSensor (&xLenSensorCB, this);
00228         m_zLenSensor = new SoFieldSensor (&zLenSensorCB, this);
00229         m_spacingSensor = new SoFieldSensor (&spacingSensorCB, this);
00230         m_onSensor = new SoFieldSensor (&onSensorCB, this);
00231         m_colorSensor = new SoFieldSensor (&colorSensorCB, this);
00232         m_labelColorSensor = new SoFieldSensor (&labelColorSensorCB, this);
00233         m_manipSensor = new SoFieldSensor (&manipSensorCB, this);
00234         m_mplaneSensor = new SoFieldSensor (&planeSensorCB, this);
00235         
00236         m_planeSensor->attach (&plane);
00237         m_xOriginSensor->attach (&xOrigin);
00238         m_zOriginSensor->attach (&zOrigin);
00239         m_xLenSensor->attach (&xLen);
00240         m_zLenSensor->attach (&zLen); 
00241         m_spacingSensor->attach (&spacing);
00242         m_onSensor->attach (&on);
00243         m_colorSensor->attach (&color);
00244         m_labelColorSensor->attach (&labelColor);
00245         m_manipSensor->attach (&manip);
00246 }
00247 
00248 IgSoGridPlane::~IgSoGridPlane (void)
00249 {
00250         m_shapeHints->unref ();
00251         m_scale->unref ();
00252         m_gridPlane->removeAllChildren ();
00253         removeChild (m_gridPlane);
00254         
00255         delete m_onSensor;
00256         delete m_planeSensor;
00257         delete m_xOriginSensor;
00258         delete m_zOriginSensor;
00259         delete m_xLenSensor;
00260     delete m_zLenSensor;
00261     delete m_spacingSensor;
00262         delete m_colorSensor;
00263         delete m_labelColorSensor;
00264         delete m_manipSensor;
00265 }
00266 
00267 void
00268 IgSoGridPlane::xOriginSensorCB (void *me, SoSensor *)
00269 {
00270         IgSoGridPlane* self = static_cast<IgSoGridPlane *> (me);
00271         
00272         self->m_plane->xOrigin = self->xOrigin;
00273         self->m_plane->refreshScale = true;
00274 }
00275 
00276 void
00277 IgSoGridPlane::zOriginSensorCB (void *me, SoSensor *)
00278 {
00279         IgSoGridPlane* self = static_cast<IgSoGridPlane *> (me);
00280         
00281         self->m_plane->zOrigin = self->zOrigin;
00282         self->m_plane->refreshScale = true;
00283 }
00284 
00285 void
00286 IgSoGridPlane::xLenSensorCB (void *me, SoSensor *)
00287 {
00288         IgSoGridPlane* self = static_cast<IgSoGridPlane *> (me);
00289         
00290         self->m_plane->xLen = self->xLen;
00291         self->m_plane->refreshScale = true;
00292 }
00293 
00294 void
00295 IgSoGridPlane::zLenSensorCB (void *me, SoSensor *)
00296 {
00297         IgSoGridPlane* self = static_cast<IgSoGridPlane *> (me);
00298         
00299         self->m_plane->zLen = self->zLen;
00300         self->m_plane->refreshScale = true;
00301 }
00302 
00303 void
00304 IgSoGridPlane::spacingSensorCB (void *me, SoSensor *)
00305 {
00306         IgSoGridPlane* self = static_cast<IgSoGridPlane *> (me);
00307         
00308         self->m_plane->spacing = self->spacing;
00309         self->m_plane->refreshScale = true;
00310 }
00311 
00312 void
00313 IgSoGridPlane::colorSensorCB (void *me, SoSensor *)
00314 {
00315         IgSoGridPlane* self = static_cast<IgSoGridPlane *> (me);
00316         
00317         self->m_plane->color = self->color;
00318 }
00319 
00320 void
00321 IgSoGridPlane::labelColorSensorCB (void *me, SoSensor *)
00322 {
00323         IgSoGridPlane* self = static_cast<IgSoGridPlane *> (me);
00324         
00325         self->updateScale ();
00326 }
00327 
00330 void
00331 IgSoGridPlane::onSensorCB (void *me, SoSensor *)
00332 {
00333         // activate or deactivate the grid plane
00334         IgSoGridPlane *self = static_cast<IgSoGridPlane *> (me);
00335         
00336         const bool foundHints = (self->m_gridPlane->findChild (self->m_shapeHints) != -1);
00337         const bool foundScale = (self->m_gridPlane->findChild (self->m_scale) != -1);
00338         
00339         if (self->on.getValue ())
00340         {
00341                 if (!foundHints)
00342                 {
00343                         // 'm_scale' is added in 'updateScale ()'
00344                         self->m_gridPlane->addChild (self->m_shapeHints);
00345                 }
00346                 
00347                 if (!foundScale)
00348                 {
00349                         self->m_gridPlane->addChild (self->m_scale);
00350                 }
00351         }
00352         else
00353         {
00354                 if (foundHints && foundScale)
00355                 {
00356                         self->m_gridPlane->removeChild (self->m_shapeHints);
00357                         self->m_gridPlane->removeChild (self->m_scale);
00358                 }
00359         }
00360         self->m_plane->on = self->on;
00361         self->m_plane->refreshScale = true;
00362 }
00363 
00367 void
00368 IgSoGridPlane::manipSensorCB (void *me, SoSensor *)
00369 {       // Hide or show the grid plane manipulators
00370         
00371         IgSoGridPlane *self = static_cast<IgSoGridPlane *> (me);
00372         const bool isOn = self->manip.getValue ();
00373         
00374         // check if the manipulator is activated
00375         if (isOn)
00376         {
00377                 // if the manipulator doesnt exist yet, create it, activate its plane
00378                 // adjust its plane to the current plane orientation, attach it to a 
00379                 // sensor and add it to the scene graph
00380                 if (!self->m_manip)
00381                 {
00382                         self->m_manip = new IgSoPlaneManip;
00383                         self->m_manip->manip = isOn;
00384                         self->m_manip->plane = self->plane;
00385                         self->m_mplaneSensor->attach (&self->m_manip->plane);
00386                         self->m_gridPlane->addChild (self->m_manip);
00387                 }
00388         }
00389         else
00390         {
00391                 // since the manipulator is turned off, we remove it from the 
00392                 // scene graph and set it to zero
00393                 if (self->m_manip)
00394                 {
00395                         self->m_gridPlane->removeChild (self->m_manip);
00396                         self->m_manip = 0;
00397                 }
00398         }
00399         self->m_plane->refreshScale = true;
00400 }
00401 
00405 void
00406 IgSoGridPlane::planeSensorCB (void *me, SoSensor *)
00407 {
00408         IgSoGridPlane *self = static_cast<IgSoGridPlane *> (me);
00409         
00410         // disable the sensors for both planes in order to avoid an infinite 
00411         // chain of callbacks
00412         self->m_mplaneSensor->detach ();
00413         self->m_planeSensor->detach();
00414         
00415         // if the manipulator is turned on, we use the manipulators plane 
00416         // otherwise the standard plane
00417         if (self->manip.getValue ())
00418         {
00419                 self->m_plane->plane = self->m_manip->plane;
00420                 self->plane = self->m_manip->plane;
00421         }
00422         else
00423         {
00424                 // no need to update the manipulator's plane because it 
00425                 // doesn't exist
00426                 self->m_plane->plane = self->plane;
00427         }
00428         
00429         // enable the sensors again
00430         self->m_planeSensor->attach (&self->plane);
00431         self->m_mplaneSensor->attach (&self->m_plane->plane);
00432         
00433         // only attach the manipulator if it is active (i.e. not null)
00434         if (self->m_manip)
00435         {
00436                 self->m_mplaneSensor->attach (&self->m_manip->plane);
00437         }
00438         self->m_plane->refreshScale = true;
00439 }

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