00001
00002
00003 #include "Iguana/Inventor/interface/IgSoFieldPlane.h"
00004 #include "Iguana/Inventor/interface/IgSoFieldPlaneMap.h"
00005 #include "Iguana/Inventor/interface/IgSbColorMap.h"
00006 #include "Iguana/Inventor/interface/IgSbField.h"
00007 #include "Iguana/Inventor/interface/IgSoPlaneManip.h"
00008 #include <Inventor/nodes/SoText2.h>
00009 #include <Inventor/nodes/SoTranslation.h>
00010 #include <Inventor/nodes/SoResetTransform.h>
00011 #include <Inventor/nodes/SoIndexedLineSet.h>
00012 #include <Inventor/nodes/SoVertexProperty.h>
00013 #include <Inventor/sensors/SoFieldSensor.h>
00014 #include <Inventor/SbLinear.h>
00015
00016 #include <math.h>
00017 #include <assert.h>
00018
00019 #ifdef WIN32
00020 # include <windows.h>
00021 #endif
00022 #ifdef __APPLE__
00023 # include <OpenGL/gl.h>
00024 #else
00025 # include <GL/gl.h>
00026 #endif
00027
00028
00029
00030 #define MINIMUM(a,b) ((a)<(b)?a:b)
00031 #define MAXIMUM(a,b) ((a)>(b)?a:b)
00032
00033
00034
00035
00036
00037
00038
00039 SO_NODE_SOURCE (IgSoFieldPlane);
00040
00041
00042
00043
00044
00045 void
00046 IgSoFieldPlane::initClass (void)
00047 {
00048 SO_NODE_INIT_CLASS (IgSoFieldPlane, SoSwitch, "Switch");
00049 }
00050
00051 IgSoFieldPlane::IgSoFieldPlane (void)
00052 : m_cmap (IgSbColorMap::getColorMap (IgSbColorMap::Jet)),
00053 m_field (0),
00054 m_manip (0),
00055 m_fieldPlane (0),
00056 m_segments (0),
00057 m_gradientScale (0),
00058 m_showSensor (0),
00059 m_planeSensor (0),
00060 m_mapDensityXSensor (0),
00061 m_mapDensityZSensor (0),
00062 m_segRatioXSensor (0),
00063 m_segRatioZSensor (0),
00064 m_winSizeXSensor (0),
00065 m_winSizeZSensor (0),
00066 m_winDensityXSensor (0),
00067 m_winDensityZSensor (0),
00068 m_winOriginXSensor (0),
00069 m_winOriginZSensor (0),
00070 m_componentSensor (0),
00071 m_maxvalueSensor (0),
00072 m_invisibleSensor (0),
00073 m_alphaSensor (0),
00074 m_mplaneSensor (0),
00075 m_gradientScaleSensor (0)
00076 {
00077 SO_NODE_CONSTRUCTOR (IgSoFieldPlane);
00078 SO_NODE_ADD_FIELD (plane, (SbPlane (SbVec3f (0.0f, 1.0f, 0.0f), 00.f)));
00079 SO_NODE_ADD_FIELD (mapDensityX, (50));
00080 SO_NODE_ADD_FIELD (mapDensityZ, (50));
00081 SO_NODE_ADD_FIELD (segRatioX, (2));
00082 SO_NODE_ADD_FIELD (segRatioZ, (2));
00083
00084 SO_NODE_ADD_FIELD (winSizeX, (10.0f));
00085 SO_NODE_ADD_FIELD (winSizeZ, (10.0f));
00086 SO_NODE_ADD_FIELD (winDensityX, (2));
00087 SO_NODE_ADD_FIELD (winDensityZ, (2));
00088 SO_NODE_ADD_FIELD (winOriginX, (0.0f));
00089 SO_NODE_ADD_FIELD (winOriginZ, (0.0f));
00090
00091 SO_NODE_ADD_FIELD (component, (XYZ_ALL));
00092 SO_NODE_DEFINE_ENUM_VALUE (Component, XYZ_ALL);
00093 SO_NODE_DEFINE_ENUM_VALUE (Component, XYZ_X);
00094 SO_NODE_DEFINE_ENUM_VALUE (Component, XYZ_Y);
00095 SO_NODE_DEFINE_ENUM_VALUE (Component, XYZ_Z);
00096 SO_NODE_DEFINE_ENUM_VALUE (Component, XYZ_R);
00097 SO_NODE_DEFINE_ENUM_VALUE (Component, XYZ_PHI);
00098 SO_NODE_SET_SF_ENUM_TYPE (component, Component);
00099 SO_NODE_ADD_FIELD (maxvalue, (4.75f));
00100 SO_NODE_ADD_FIELD (invisible, (0));
00101 SO_NODE_ADD_FIELD (alpha, (255));
00102 SO_NODE_ADD_FIELD (show, (FALSE));
00103 SO_NODE_ADD_FIELD (manip, (FALSE));
00104 SO_NODE_ADD_FIELD (showMap, (TRUE));
00105 SO_NODE_ADD_FIELD (showSegments, (TRUE));
00106 SO_NODE_ADD_FIELD (gradientScale, (TRUE));
00107
00108
00109
00110
00111
00112 m_showSensor = new SoFieldSensor (&showChanged, this);
00113 m_showMapSensor = new SoFieldSensor (&showMapChanged, this);
00114 m_showSegmentsSensor = new SoFieldSensor (&showSegmentsChanged, this);
00115 m_gradientScaleSensor = new SoFieldSensor (&gradientScaleChanged, this);
00116
00117 m_showSensor->attach (&show);
00118 m_showMapSensor->attach (&showMap);
00119 m_showSegmentsSensor->attach (&showSegments);
00120 m_gradientScaleSensor->attach (&gradientScale);
00121 }
00122
00123 IgSoFieldPlane::~IgSoFieldPlane (void)
00124 {
00125 show = FALSE;
00126 showMap = FALSE;
00127 showSegments = FALSE;
00128 gradientScale = FALSE;
00129
00130 if (m_fieldPlane)
00131 {
00132 m_fieldPlane->unref ();
00133 m_segments->unref ();
00134 m_gradientScale->unref ();
00135 }
00136
00137 if (m_planeSensor)
00138 {
00139 delete m_planeSensor;
00140 delete m_mplaneSensor;
00141 delete m_mapDensityXSensor;
00142 delete m_mapDensityZSensor;
00143 delete m_segRatioXSensor;
00144 delete m_segRatioZSensor;
00145
00146 delete m_winSizeXSensor;
00147 delete m_winSizeZSensor;
00148 delete m_winDensityXSensor;
00149 delete m_winDensityZSensor;
00150 delete m_winOriginXSensor;
00151 delete m_winOriginZSensor;
00152
00153 delete m_componentSensor;
00154 delete m_maxvalueSensor;
00155 delete m_invisibleSensor;
00156 delete m_alphaSensor;
00157 }
00158
00159 delete m_showSensor;
00160 delete m_showMapSensor;
00161 delete m_showSegmentsSensor;
00162 delete m_gradientScaleSensor;
00163 }
00164
00165 void
00166 IgSoFieldPlane::colorMap (const IgSbColorMap *cmap)
00167 {
00168 assert (cmap);
00169 m_cmap = cmap;
00170 if (show.getValue () && m_field)
00171 {
00172 refreshColors ();
00173 }
00174 }
00175
00176 void
00177 IgSoFieldPlane::attachSensors (void)
00178 {
00179 m_planeSensor->attach (&plane);
00180 m_mapDensityXSensor->attach (&mapDensityX);
00181 m_mapDensityZSensor->attach (&mapDensityZ);
00182 m_segRatioXSensor->attach (&segRatioX);
00183 m_segRatioZSensor->attach (&segRatioZ);
00184
00185 m_winSizeXSensor->attach (&winSizeX);
00186 m_winSizeZSensor->attach (&winSizeZ);
00187 m_winDensityXSensor->attach (&winDensityX);
00188 m_winDensityZSensor->attach (&winDensityZ);
00189 m_winOriginXSensor->attach (&winOriginX);
00190 m_winOriginZSensor->attach (&winOriginZ);
00191
00192 m_componentSensor->attach (&component);
00193 m_maxvalueSensor->attach (&maxvalue);
00194 m_invisibleSensor->attach (&invisible);
00195 m_alphaSensor->attach (&alpha);
00196 m_mplaneSensor->attach (&m_manip->plane);
00197 }
00198
00199 void
00200 IgSoFieldPlane::detachSensors (void)
00201 {
00202 m_planeSensor->detach ();
00203 m_mapDensityXSensor->detach ();
00204 m_mapDensityZSensor->detach ();
00205 m_segRatioXSensor->detach ();
00206 m_segRatioZSensor->detach ();
00207
00208 m_winSizeXSensor->detach ();
00209 m_winSizeZSensor->detach ();
00210 m_winDensityXSensor->detach ();
00211 m_winDensityZSensor->detach ();
00212 m_winOriginXSensor->detach ();
00213 m_winOriginZSensor->detach ();
00214
00215 m_componentSensor->detach ();
00216 m_maxvalueSensor->detach ();
00217 m_invisibleSensor->detach ();
00218 m_alphaSensor->detach ();
00219 m_mplaneSensor->detach ();
00220 }
00221
00222
00223 void
00224 IgSoFieldPlane::field (const IgSbField *field, SbBox3f world)
00225 {
00226
00227 m_world = world;
00228
00229 if (field)
00230 {
00231 buildStructure ();
00232
00233 if (!m_planeSensor)
00234 {
00235
00236 m_planeSensor = new SoFieldSensor (&planeChanged, this);
00237 m_mplaneSensor = new SoFieldSensor (&mplaneChanged, this);
00238
00239
00240 m_mapDensityXSensor =
00241 new SoFieldSensor (&resampleSegmentsCB, this);
00242 m_mapDensityZSensor =
00243 new SoFieldSensor (&resampleSegmentsCB, this);
00244 m_componentSensor =
00245 new SoFieldSensor (&resampleSegmentsCB, this);
00246 m_maxvalueSensor =
00247 new SoFieldSensor (&resampleSegmentsCB, this);
00248 m_invisibleSensor =
00249 new SoFieldSensor (&resampleSegmentsCB, this);
00250 m_alphaSensor =
00251 new SoFieldSensor (&resampleSegmentsCB, this);
00252 m_segRatioXSensor =
00253 new SoFieldSensor (&resampleSegmentsCB, this);
00254 m_segRatioZSensor =
00255 new SoFieldSensor (&resampleSegmentsCB, this);
00256 m_winSizeXSensor =
00257 new SoFieldSensor (&resampleSegmentsCB, this);
00258 m_winSizeZSensor =
00259 new SoFieldSensor (&resampleSegmentsCB, this);
00260 m_winDensityXSensor =
00261 new SoFieldSensor (&resampleSegmentsCB, this);
00262 m_winDensityZSensor =
00263 new SoFieldSensor (&resampleSegmentsCB, this);
00264 m_winOriginXSensor =
00265 new SoFieldSensor (&resampleSegmentsCB, this);
00266 m_winOriginZSensor =
00267 new SoFieldSensor (&resampleSegmentsCB, this);
00268 }
00269 else if (m_field)
00270 {
00271 detachSensors ();
00272 }
00273
00274 if (!m_field)
00275 {
00276 m_manip->manip.connectFrom (&manip);
00277
00278
00279 }
00280 m_field = field;
00281 update ();
00282 attachSensors ();
00283 m_showSensor->attach (&show);
00284 m_showMapSensor->attach (&showMap);
00285 m_showSegmentsSensor->attach (&showSegments);
00286 m_gradientScaleSensor->attach (&gradientScale);
00287 show = TRUE;
00288 }
00289 else if (m_field)
00290 {
00291 m_field = field;
00292 manip = FALSE;
00293 show = FALSE;
00294 showMap = FALSE;
00295 showSegments = FALSE;
00296 gradientScale = FALSE;
00297 m_manip->manip.disconnect ();
00298
00299
00300 m_showSensor->detach ();
00301 m_showMapSensor->detach ();
00302 m_showSegmentsSensor->detach ();
00303 m_gradientScaleSensor->detach ();
00304 detachSensors ();
00305 }
00306 }
00307
00308 void
00309 IgSoFieldPlane::buildStructure (void)
00310 {
00311 if (m_manip) {return;}
00312
00313 assert ((getNumChildren () == 0) || (getNumChildren () >= 2));
00314
00315 if (getNumChildren () == 0)
00316 {
00317 whichChild = SO_SWITCH_NONE;
00318
00319
00320 addChild (new SoResetTransform);
00321
00322
00323 m_manip = new IgSoPlaneManip;
00324 addChild (m_manip);
00325 }
00326 else
00327 {
00328 m_manip = dynamic_cast<IgSoPlaneManip*>(getChild(1));
00329
00330 assert (dynamic_cast<SoResetTransform*>(getChild(0)));
00331 assert (m_manip);
00332
00333 if (m_manip->manip.isConnectedFromField ())
00334 {
00335 m_manip->manip.disconnect ();
00336 }
00337 m_manip->manip = FALSE;
00338
00339 for(int i = 2; i < getNumChildren (); i++)
00340 {
00341 SoNode *child = getChild(i);
00342 if (!m_fieldPlane && dynamic_cast<IgSoFieldPlaneMap*>(child)
00343 && child->getName() == SbName ("FieldMap"))
00344 {
00345 m_fieldPlane = dynamic_cast<IgSoFieldPlaneMap*>(child);
00346 }
00347 else if (!m_segments && dynamic_cast<SoIndexedLineSet*>(child))
00348 {
00349 m_segments = dynamic_cast<SoIndexedLineSet*>(child);
00350 }
00351 else if (!m_gradientScale && dynamic_cast<SoGroup*>(child)
00352 && child->getName() == SbName ("GradientScale"))
00353 {
00354 m_gradientScale = dynamic_cast<SoGroup*>(child);
00355 assert (m_gradientScale->getNumChildren () == 12);
00356 }
00357 if (m_fieldPlane && m_segments && m_gradientScale)
00358 {
00359 break;
00360 }
00361 }
00362 }
00363
00364 if (!m_segments)
00365 {
00366 m_segments = new SoIndexedLineSet;
00367 SoVertexProperty *vtx = new SoVertexProperty;
00368 vtx->orderedRGBA = 0xff0000ff;
00369 vtx->materialBinding = SoVertexProperty::OVERALL;
00370 m_segments->vertexProperty = vtx;
00371
00372 if (showSegments.getValue ())
00373 {
00374 addChild (m_segments);
00375 }
00376 }
00377
00378 if (!m_fieldPlane)
00379 {
00380 m_fieldPlane = new IgSoFieldPlaneMap;
00381 m_fieldPlane->setName ("FieldMap");
00382 if (showMap.getValue ())
00383 {
00384 addChild (m_fieldPlane);
00385 }
00386 }
00387 else
00388 {
00389
00390
00391 }
00392
00393 if (!m_gradientScale)
00394 {
00395 m_gradientScale = new SoGroup;
00396 m_gradientScale->setName ("GradientScale");
00397 IgSoFieldPlaneMap *gs = new IgSoFieldPlaneMap;
00398
00399
00400 m_gradientScale->addChild (gs);
00401
00402 SoIndexedLineSet *grid = new SoIndexedLineSet;
00403 SoVertexProperty *vtx = new SoVertexProperty;
00404 vtx->orderedRGBA = 0xffffffff;
00405 vtx->materialBinding = SoVertexProperty::OVERALL;
00406 grid->vertexProperty = vtx;
00407 m_gradientScale->addChild (grid);
00408
00409 m_gradientScale->addChild (new SoTranslation);
00410 m_gradientScale->addChild (new SoText2);
00411 m_gradientScale->addChild (new SoTranslation);
00412 m_gradientScale->addChild (new SoText2);
00413 m_gradientScale->addChild (new SoTranslation);
00414 m_gradientScale->addChild (new SoText2);
00415 m_gradientScale->addChild (new SoTranslation);
00416 m_gradientScale->addChild (new SoText2);
00417 m_gradientScale->addChild (new SoTranslation);
00418 m_gradientScale->addChild (new SoText2);
00419 if (gradientScale.getValue ())
00420 {
00421 addChild (m_gradientScale);
00422 }
00423 }
00424
00425 m_segments->ref ();
00426 m_fieldPlane->ref ();
00427 m_gradientScale->ref ();
00428 }
00429
00430 void
00431 IgSoFieldPlane::update (void)
00432 {
00433
00434 updateCorners ();
00435
00436
00437 resampleSegments ();
00438 }
00439
00440 void
00441 IgSoFieldPlane::updateCorners (void)
00442 {
00443
00444
00445
00446
00447
00448
00449 SbMatrix matrix;
00450 m_manip->getMotionMatrix (matrix);
00451
00452 SbVec3f xdir (matrix[0][0],matrix[0][1],matrix[0][2]);
00453 SbVec3f zdir (matrix[2][0],matrix[2][1],matrix[2][2]);
00454 SbVec3f origin (matrix[3][0],matrix[3][1],matrix[3][2]);
00455 SbPlane slicePlane (plane.getValue ());
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467 int nedges = 0;
00468 float xmin = 0.f;
00469 float xmax = 0.f;
00470 float zmin = 0.f;
00471 float zmax = 0.f;
00472 SbVec3f wcorners [8] = {
00473 SbVec3f (m_world.getMin()[0], m_world.getMin()[1], m_world.getMin()[2]),
00474 SbVec3f (m_world.getMin()[0], m_world.getMin()[1], m_world.getMax()[2]),
00475 SbVec3f (m_world.getMin()[0], m_world.getMax()[1], m_world.getMin()[2]),
00476 SbVec3f (m_world.getMin()[0], m_world.getMax()[1], m_world.getMax()[2]),
00477 SbVec3f (m_world.getMax()[0], m_world.getMin()[1], m_world.getMin()[2]),
00478 SbVec3f (m_world.getMax()[0], m_world.getMin()[1], m_world.getMax()[2]),
00479 SbVec3f (m_world.getMax()[0], m_world.getMax()[1], m_world.getMin()[2]),
00480 SbVec3f (m_world.getMax()[0], m_world.getMax()[1], m_world.getMax()[2])
00481 };
00482 static const int edgeidx [] = {
00483 0, 1,
00484 0, 2,
00485 2, 3,
00486 1, 3,
00487 0, 4,
00488 1, 5,
00489 3, 7,
00490 2, 6,
00491 4, 5,
00492 4, 6,
00493 6, 7,
00494 5, 7,
00495 -1, -1,
00496 };
00497
00498 for (int i = 0; edgeidx [i] != -1; i += 2)
00499 {
00500
00501 SbVec3f pt0 (wcorners [edgeidx [i]]);
00502 SbVec3f pt1 (wcorners [edgeidx [i+1]]);
00503 SbLine edge (pt0, pt1);
00504 SbVec3f point;
00505 float product = 0.f;
00506
00507
00508
00509
00510 if (slicePlane.intersect (edge, point)
00511 && (product = (point - pt0).dot (edge.getDirection ())) >= 0.f
00512 && product <= (pt1 - pt0).length ())
00513 {
00514 float x = xdir.dot (point - origin);
00515 float z = zdir.dot (point - origin);
00516 if (++nedges == 1)
00517 {
00518 xmin = xmax = x;
00519 zmin = zmax = z;
00520 }
00521 else
00522 {
00523 xmin = MINIMUM (xmin, x);
00524 xmax = MAXIMUM (xmax, x);
00525 zmin = MINIMUM (zmin, z);
00526 zmax = MAXIMUM (zmax, z);
00527 }
00528
00529 }
00530 }
00531
00532 if (xmax - xmin < 1.f)
00533 {
00534 float xcenter = (xmax + xmin) / 2;
00535 xmin = xcenter - .5f;
00536 xmax = xcenter + .5f;
00537 }
00538
00539 if (zmax - zmin < 1.f)
00540 {
00541 float zcenter = (zmax + zmin) / 2;
00542 zmin = zcenter - .5f;
00543 zmax = zcenter + .5f;
00544 }
00545
00546
00547
00548
00549
00550
00551
00552
00553 SbVec3f corners [4];
00554 corners [0] = origin + xmin * xdir + zmin * zdir;
00555 corners [1] = origin + xmax * xdir + zmin * zdir;
00556 corners [2] = origin + xmin * xdir + zmax * zdir;
00557 corners [3] = origin + xmax * xdir + zmax * zdir;
00558
00559 m_fieldPlane->corners.setValues (0, 4, corners);
00560
00561
00562 zmax += 0.5f;
00563 corners [0] = corners [2];
00564 corners [1] = corners [3];
00565 corners [2] = origin + xmin * xdir + zmax * zdir;
00566 corners [3] = origin + xmax * xdir + zmax * zdir;
00567
00568 assert (dynamic_cast<IgSoFieldPlaneMap*>(m_gradientScale->getChild(0)));
00569 assert (dynamic_cast<SoIndexedLineSet*>(m_gradientScale->getChild(1)));
00570
00571 static_cast<IgSoFieldPlaneMap*>(m_gradientScale->getChild(0))->
00572 corners.setValues (0, 4, corners);
00573
00574
00575
00576 float lineOffset = 0.01;
00577 corners[0][0] -= lineOffset;
00578 corners[0][2] -= lineOffset;
00579 corners[1][0] += lineOffset;
00580 corners[1][2] -= lineOffset;
00581 corners[2][0] -= lineOffset;
00582 corners[2][2] += lineOffset;
00583 corners[3][0] += lineOffset;
00584 corners[3][2] += lineOffset;
00585
00586 std::vector<int> coords;
00587 std::vector<SbVec3f> vtxs;
00588 vtxs.push_back (corners [0]);
00589 vtxs.push_back (corners [1]);
00590 vtxs.push_back (corners [3]);
00591 vtxs.push_back (corners [2]);
00592 for(int i = 0; i <= 4; i++)
00593 coords.push_back (i%4);
00594 coords.push_back (SO_END_LINE_INDEX);
00595
00596
00597
00598 assert (dynamic_cast<SoTranslation*>(m_gradientScale->getChild(2)));
00599
00600 SoTranslation *t = static_cast<SoTranslation*>(m_gradientScale->
00601 getChild(2));
00602 t->translation = corners [2];
00603 SbVec3f step = (corners [3]-corners [2])/4;
00604 SbVec3f pcorner = corners [2];
00605 SbVec3f tmpcorner = corners [2];
00606
00607 tmpcorner[2] += 0.5f;
00608 vtxs.push_back (tmpcorner);
00609 unsigned vsize = vtxs.size ();
00610 coords.push_back (vsize - 2);
00611 coords.push_back (vsize - 1);
00612 coords.push_back (SO_END_LINE_INDEX);
00613
00614
00615 for (int i = 1; i <= 4; i++)
00616 {
00617 assert (dynamic_cast<SoTranslation*> (m_gradientScale->getChild ((i * 2) + 2)));
00618 t = static_cast<SoTranslation*> (m_gradientScale->getChild ((i * 2) + 2));
00619 t->translation = step;
00620 pcorner = pcorner + step;
00621 vtxs.push_back (pcorner);
00622 tmpcorner = pcorner;
00623 tmpcorner[2] += 0.5f;
00624 vtxs.push_back (tmpcorner);
00625 vsize = vtxs.size ();
00626 coords.push_back (vsize - 2);
00627 coords.push_back (vsize - 1);
00628 coords.push_back (SO_END_LINE_INDEX);
00629 }
00630
00631 SoIndexedLineSet *grid = static_cast<SoIndexedLineSet*>(m_gradientScale->getChild(1));
00632 SoVertexProperty *vtx = (SoVertexProperty *)grid->vertexProperty.getValue ();
00633 vtx->vertex.setValues (0, vtxs.size (), &vtxs [0]);
00634 vtx->vertex.deleteValues (vtxs.size ());
00635 grid->coordIndex.setValues (0, coords.size (), &coords [0]);
00636 grid->coordIndex.deleteValues (coords.size ());
00637 }
00638
00639 void
00640 IgSoFieldPlane::convertMagFieldColors (double &minMag, double &maxMag)
00641 {
00642 float rgb [3];
00643 double mag;
00644 unsigned r,g,b,a;
00645 unsigned invisibleAlpha = invisible.getValue ();
00646 unsigned defaultAlpha = alpha.getValue ();
00647
00648 unsigned startColors = 0;
00649
00650 for (unsigned regionIndex = 0; regionIndex < 5; regionIndex++)
00651 {
00652 unsigned size = m_colorsMags[regionIndex].size ();
00653
00654 if (size > 0)
00655 {
00656 std::vector<unsigned> colors (size, 0u);
00657
00658
00659 for (unsigned i = 0; i < size; i++)
00660 {
00661 mag = m_colorsMags[regionIndex] [i];
00662
00663
00664 if ((mag > 0.f) && (mag < minMag))
00665 {
00666 minMag = mag;
00667 }
00668
00669
00670 if (mag > maxMag)
00671 {
00672 maxMag = mag;
00673 }
00674
00675
00676 m_cmap->color (mag, rgb);
00677
00678 r = int (rgb [0] * 255 + .5);
00679 g = int (rgb [1] * 255 + .5);
00680 b = int (rgb [2] * 255 + .5);
00681 a = mag < 1./256 ? invisibleAlpha : defaultAlpha;
00682
00683
00684 colors [i] = r << 24 | g << 16 | b << 8 | a;
00685 }
00686
00687
00688 m_fieldPlane->orderedRGBA.setValues (startColors, size, &colors [0]);
00689 startColors += size;
00690
00691 m_fieldPlane->orderedRGBA.deleteValues (startColors);
00692 }
00693 }
00694 }
00695
00696 void
00697 IgSoFieldPlane::convertGradientScaleColors (double &minMag, double &maxMag)
00698 {
00699 float rgb [3];
00700 double mag;
00701 unsigned r,g,b,a;
00702 unsigned size = 0;
00703
00704 for (unsigned i = 0; i < 5; i++)
00705 {
00706 size += m_colorsMags[i].size ();
00707 }
00708 std::vector<unsigned> colors (size, 0u);
00709
00710 assert (dynamic_cast<IgSoFieldPlaneMap*> (m_gradientScale->getChild (0)));
00711 IgSoFieldPlaneMap *gs =
00712 static_cast<IgSoFieldPlaneMap*> (m_gradientScale->getChild (0));
00713
00714
00715 size = 10;
00716 colors.resize ((size + 1) * 2);
00717
00718
00719 if (minMag < 0.f) { minMag = 0.f; }
00720 if (maxMag > 1.f) { maxMag = 1.f; }
00721
00722 double delta = (maxMag - minMag)/(size);
00723 mag = minMag;
00724
00725
00726
00727 for (unsigned i = 0; i <= size; i++)
00728 {
00729 m_cmap->color (mag, rgb);
00730
00731 r = int (rgb [0] * 255 + .5);
00732 g = int (rgb [1] * 255 + .5);
00733 b = int (rgb [2] * 255 + .5);
00734 a = 255;
00735
00736
00737 colors [i] = r << 24 | g << 16 | b << 8 | a;
00738
00739 colors [i+size+1] = colors [i];
00740 mag += delta;
00741 }
00742
00743 size = colors.size ();
00744
00745 gs->orderedRGBA.setValues (0, size, &colors [0]);
00746 gs->orderedRGBA.deleteValues (size);
00747
00748
00749 gs->xdivs.set1Value (0, 10);
00750 gs->zdivs.set1Value (0, 1);
00751
00752
00753 for (unsigned i = 1; i < 5; i++)
00754 {
00755 gs->xdivs.set1Value (i, 0);
00756 gs->zdivs.set1Value (i, 0);
00757 }
00758
00759 gs->lowerLeftCorners.set1Value (0, gs->corners[0]);
00760 gs->upperRightCorners.set1Value (0, gs->corners[3]);
00761 gs->lowerRightCorners.set1Value (0, gs->corners[1]);
00762 }
00763
00764 void
00765 IgSoFieldPlane::refreshColors (void)
00766 {
00767 double minMag = 1.f;
00768 double maxMag = 0.f;
00769
00770 convertMagFieldColors (minMag, maxMag);
00771
00772 convertGradientScaleColors (minMag, maxMag);
00773
00774
00775 char textLabel [20];
00776 double clamp = maxvalue.getValue ();
00777 SoText2 *text;
00778 double step = (maxMag - minMag)/4;
00779 double mag = minMag;
00780
00781 for (int i = 0; i < 5; i++)
00782 {
00783 assert (dynamic_cast<SoText2*> (m_gradientScale->getChild (3 + (i * 2))));
00784 text = static_cast<SoText2*> (m_gradientScale->getChild (3 + (i * 2)));
00785 sprintf (textLabel, "%.4f", mag * clamp);
00786 text->string = textLabel;
00787 mag += step;
00788 }
00789 }
00790
00791 void
00792 IgSoFieldPlane::resampleSegments (void)
00793 {
00794
00795
00796 m_xBaseDir = (m_fieldPlane->corners[1] - m_fieldPlane->corners[0]) / mapDensityX.getValue ();
00797 m_zBaseDir = (m_fieldPlane->corners[2] - m_fieldPlane->corners[0]) / mapDensityZ.getValue ();
00798
00799
00800 m_colorsMags.clear ();
00801
00802 unsigned borderBitmask;
00803 borderBitmask = initializeParameters ();
00804
00805 determineCorners (borderBitmask);
00806
00807 transferValuesToMap ();
00808
00809 calcColorMags ();
00810
00811
00812 std::vector<SbVec3f> segments;
00813 std::vector<int> segidx;
00814 std::vector<unsigned> colors;
00815 unsigned invisibleAlpha = invisible.getValue ();
00816 unsigned defaultAlpha = alpha.getValue ();
00817 Component comp = (Component) component.getValue ();
00818 unsigned division [2] = { mapDensityX.getValue (), mapDensityZ.getValue () };
00819 unsigned subdiv [2] = { segRatioX.getValue (), segRatioZ.getValue () };
00820 float clamp = maxvalue.getValue ();
00821
00822 SbVec3f xdir = m_xBaseDir;
00823 SbVec3f zdir = m_zBaseDir;
00824
00825 float segscale = MINIMUM (xdir.length()*subdiv[0],zdir.length()*subdiv[1])
00826 / clamp;
00827
00828 for (unsigned i = 0; i <= division [1]; ++i)
00829 {
00830 for (unsigned j = 0; j <= division [0]; ++j)
00831 {
00832
00833 SbVec3f from (m_fieldPlane->corners[0] + zdir * i + xdir * j);
00834 double pt [3] = { from [0], from [1], from [2] };
00835 double val [3];
00836
00837 m_field->evaluate (pt, val);
00838
00839
00840
00841
00842 SbVec3f dir (val [0], val [1], val [2]);
00843 double mag;
00844
00845 switch (comp)
00846 {
00847 case XYZ_ALL:
00848 mag = MINIMUM (dir.length (), clamp) / clamp;
00849 break;
00850
00851 case XYZ_X:
00852 mag = MINIMUM (fabs (dir [0]), clamp) / clamp;
00853 break;
00854
00855 case XYZ_Y:
00856 mag = MINIMUM (fabs (dir [1]), clamp) / clamp;
00857 break;
00858
00859 case XYZ_Z:
00860 mag = MINIMUM (fabs (dir [2]), clamp) / clamp;
00861 break;
00862
00863 case XYZ_PHI:
00864 {
00865 SbVec3f radius (from [0], from [1], 0);
00866 radius.normalize ();
00867 SbVec3f angular (SbVec3f (0, 0, 1).cross (radius));
00868 mag = MINIMUM (fabs (angular.dot (dir)), clamp) / clamp;
00869 }
00870 break;
00871
00872 case XYZ_R:
00873 {
00874 SbVec3f radius (from [0], from [1], 0);
00875 radius.normalize ();
00876 mag = MINIMUM (fabs (radius.dot (dir)), clamp) / clamp;
00877 }
00878 break;
00879
00880 default:
00881 assert (false);
00882 mag = 0.;
00883 break;
00884 }
00885
00886 unsigned a = mag < 1./256 ? invisibleAlpha : defaultAlpha;
00887
00888
00889 if (i % subdiv [1] == 0 && j % subdiv [0] == 0 && a)
00890 {
00891 unsigned index = segments.size ();
00892 segments.push_back (from);
00893 segments.push_back (from + dir * segscale);
00894 segidx.push_back (index);
00895 segidx.push_back (index + 1);
00896 segidx.push_back (SO_END_LINE_INDEX);
00897 }
00898 }
00899 }
00900
00901 refreshColors ();
00902
00903 SoVertexProperty *vtx;
00904 vtx = (SoVertexProperty *) m_segments->vertexProperty.getValue ();
00905 vtx->vertex.setValues (0, segments.size (), &segments [0]);
00906 vtx->vertex.deleteValues (segments.size ());
00907 m_segments->coordIndex.setValues (0, segidx.size (), &segidx [0]);
00908 m_segments->coordIndex.deleteValues (segidx.size ());
00909 }
00910
00911 void
00912 IgSoFieldPlane::determineCorners (unsigned bitmask)
00913 {
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937 if ( m_sizeIsZero || (m_densityXTooLow && m_densityZTooLow) )
00938 {
00939 m_regions[0].density[X_AXIS] = mapDensityX.getValue ();
00940 m_regions[0].density[Z_AXIS] = mapDensityZ.getValue ();
00941 m_regions[0].lowerLeft = m_fieldPlane->corners[0];
00942 m_regions[0].upperRight = m_fieldPlane->corners[2] - m_fieldPlane->corners[0] + m_fieldPlane->corners[1];
00943 m_regions[0].lowerRight = m_fieldPlane->corners[1];
00944
00945 for (int i = 1; i < 5; i++)
00946 {
00947
00948 m_regions[i].density[X_AXIS] = 0;
00949 m_regions[i].density[Z_AXIS] = 0;
00950 }
00951 }
00952 else
00953 {
00954 m_regions[0].lowerLeft = m_fieldPlane->corners[0];
00955 m_regions[0].lowerRight = m_fieldPlane->corners[1];
00956
00957 SbVec3f xdir = m_fieldPlane->corners[1] - m_fieldPlane->corners[0];
00958 SbVec3f zdir = m_fieldPlane->corners[2] - m_fieldPlane->corners[0];
00959
00960 m_regions[4].upperRight = m_fieldPlane->corners[2] - m_fieldPlane->corners[0] + m_fieldPlane->corners[1];
00961
00962 SbLine leftEdge (m_fieldPlane->corners[0], m_fieldPlane->corners[2]);
00963 SbLine rightEdge (m_fieldPlane->corners[1], m_regions[4].upperRight);
00964
00965
00966
00967 m_regions[2].lowerLeft = m_fieldPlane->corners[0] + (xdir * (m_window.origin[X_AXIS] + 1.0f - m_window.size[X_AXIS])
00968 + zdir * (m_window.origin[Z_AXIS] + 1.0f - m_window.size[Z_AXIS])) / 2.0f;
00969 m_regions[1].lowerRight = m_regions[2].lowerLeft;
00970 m_regions[1].upperRight = m_regions[2].lowerLeft + m_zBaseDir * m_window.baseDiv[Z_AXIS];
00971 m_regions[3].lowerLeft = m_regions[2].lowerLeft + m_xBaseDir * m_window.baseDiv[X_AXIS];
00972 m_regions[2].lowerRight = m_regions[3].lowerLeft;
00973 m_regions[2].upperRight = m_regions[3].lowerLeft + m_zBaseDir * m_window.baseDiv[Z_AXIS];
00974
00975
00976
00977 m_regions[1].lowerLeft = leftEdge.getClosestPoint (m_regions[2].lowerLeft);
00978 m_regions[0].upperRight = rightEdge.getClosestPoint (m_regions[2].lowerLeft);
00979 m_regions[3].lowerRight = m_regions[0].upperRight;
00980 m_regions[4].lowerLeft = leftEdge.getClosestPoint (m_regions[1].upperRight);
00981 m_regions[3].upperRight = rightEdge.getClosestPoint (m_regions[1].upperRight);
00982 m_regions[4].lowerRight = m_regions[3].upperRight;
00983
00984 unsigned mapDensX = mapDensityX.getValue ();
00985 unsigned mapDensZ = mapDensityZ.getValue ();
00986
00987
00988 if ((bitmask & 2u) == 2u)
00989 {
00990 m_regions[0].density[X_AXIS] = 0;
00991 m_regions[0].density[Z_AXIS] = 0;
00992 }
00993 else
00994 {
00995 m_regions[0].density[X_AXIS] = mapDensX;
00996 m_regions[0].density[Z_AXIS] = (unsigned) round ((m_regions[1].lowerLeft - m_regions[0].lowerLeft).length () / m_zBaseDir.length ());
00997 }
00998
00999 if ((bitmask & 8u) == 8u)
01000 {
01001 m_regions[4].density[X_AXIS] = 0;
01002 m_regions[4].density[Z_AXIS] = 0;
01003 }
01004 else
01005 {
01006 m_regions[4].density[X_AXIS] = mapDensX;
01007 m_regions[4].density[Z_AXIS] = mapDensZ - m_regions[0].density[Z_AXIS] - m_window.baseDiv[Z_AXIS];
01008 }
01009
01010 if ((bitmask & 1u) == 1u)
01011 {
01012 m_regions[1].density[X_AXIS] = 0;
01013 m_regions[1].density[Z_AXIS] = 0;
01014 }
01015 else
01016 {
01017 m_regions[1].density[X_AXIS] = (unsigned) round ((m_regions[2].lowerLeft - m_regions[1].lowerLeft).length () / m_xBaseDir.length ());
01018 m_regions[1].density[Z_AXIS] = m_window.baseDiv[Z_AXIS];
01019 }
01020
01021 if ((bitmask & 4u) == 4u)
01022 {
01023 m_regions[3].density[X_AXIS] = 0;
01024 m_regions[3].density[Z_AXIS] = 0;
01025 }
01026 else
01027 {
01028 m_regions[3].density[X_AXIS] = mapDensX - m_regions[1].density[X_AXIS] - m_window.baseDiv[X_AXIS];
01029 m_regions[3].density[Z_AXIS] = m_window.baseDiv[Z_AXIS];
01030 }
01031
01032
01033 if ((bitmask & 15u) == 15u)
01034 {
01035 m_regions[2].density[X_AXIS] = m_window.density[X_AXIS] * mapDensX;
01036 m_regions[2].density[Z_AXIS] = m_window.density[Z_AXIS] * mapDensZ;
01037 }
01038 else
01039 {
01040 m_regions[2].density[X_AXIS] = (unsigned) round ((float) mapDensX * (float) m_window.density[X_AXIS] * m_window.size[X_AXIS]);
01041 m_regions[2].density[Z_AXIS] = (unsigned) round ((float) mapDensZ * (float) m_window.density[Z_AXIS] * m_window.size[Z_AXIS]);
01042 }
01043 }
01044 }
01045
01046 void
01047 IgSoFieldPlane::correctDetailedSize ()
01048 {
01049
01050
01051
01052 unsigned mapDens[2];
01053 mapDens[X_AXIS] = mapDensityX.getValue ();
01054 mapDens[Z_AXIS] = mapDensityZ.getValue ();
01055
01056 float smallest[2];
01057
01058 for (unsigned axis = X_AXIS; axis <= Z_AXIS; axis++)
01059 {
01060
01061 smallest[axis] = 1.0f / (float) mapDens[axis];
01062
01063
01064 m_window.baseDiv[axis] = (unsigned) round (m_window.size[axis] * mapDens[axis]);
01065
01066
01067 m_window.size[axis] = ((float) m_window.baseDiv[axis] / (float) mapDens[axis]);
01068
01069
01070 if (m_window.size[axis] <= 0.0f)
01071 {
01072 m_window.size[axis] = smallest[axis];
01073 m_window.baseDiv[axis] = 1;
01074 }
01075 }
01076 }
01077
01078 void
01079 IgSoFieldPlane::transferValuesToMap ()
01080 {
01081
01082 m_fieldPlane->xdivs.set1Value (0, m_regions[0].density[X_AXIS]);
01083 m_fieldPlane->zdivs.set1Value (0, m_regions[0].density[Z_AXIS]);
01084
01085 m_fieldPlane->lowerLeftCorners.set1Value (0, m_regions[0].lowerLeft);
01086 m_fieldPlane->upperRightCorners.set1Value (0, m_regions[0].upperRight);
01087 m_fieldPlane->lowerRightCorners.set1Value (0, m_regions[0].lowerRight);
01088
01089
01090 if (! (m_sizeIsZero || (m_densityXTooLow && m_densityZTooLow) ))
01091 {
01092 for (unsigned i = 1; i < 5; i++)
01093 {
01094 m_fieldPlane->xdivs.set1Value (i, m_regions[i].density[X_AXIS]);
01095 m_fieldPlane->zdivs.set1Value (i, m_regions[i].density[Z_AXIS]);
01096
01097 m_fieldPlane->lowerLeftCorners.set1Value (i, m_regions[i].lowerLeft);
01098 m_fieldPlane->upperRightCorners.set1Value (i, m_regions[i].upperRight);
01099 m_fieldPlane->lowerRightCorners.set1Value (i, m_regions[i].lowerRight);
01100 }
01101 }
01102 else
01103 {
01104
01105 for (unsigned i = 1; i < 5; i++)
01106 {
01107 m_fieldPlane->xdivs.set1Value (i, 0);
01108 m_fieldPlane->zdivs.set1Value (i, 0);
01109 }
01110 }
01111 }
01112
01113 unsigned
01114 IgSoFieldPlane::initializeParameters ()
01115 {
01116
01117
01118
01119
01120
01121
01122 const unsigned nbrOfRegions = 5u;
01123 unsigned borderBitmap = 0u;
01124
01125 m_window.size[X_AXIS] = winSizeX.getValue () / 100.0f;
01126 m_window.size[Z_AXIS] = winSizeZ.getValue () / 100.0f;
01127 m_window.density[X_AXIS] = winDensityX.getValue ();
01128 m_window.density[Z_AXIS] = winDensityZ.getValue ();
01129 m_window.origin[X_AXIS] = winOriginX.getValue ();
01130 m_window.origin[Z_AXIS] = winOriginZ.getValue ();
01131
01132 m_sizeIsZero = (m_window.size[X_AXIS] <= 0.0f || m_window.size[Z_AXIS] <= 0.0f);
01133
01134
01135
01136 m_densityXTooLow = m_window.density[X_AXIS] < 2;
01137 m_densityZTooLow = m_window.density[Z_AXIS] < 2;
01138
01139
01140
01141 if ( !(m_sizeIsZero || (m_densityXTooLow && m_densityZTooLow)) )
01142 {
01143 correctDetailedSize ();
01144
01145
01146 borderBitmap = correctOriginAndGetMask ();
01147 }
01148
01149
01150 for (unsigned i = 0; i < nbrOfRegions; i++)
01151 {
01152 m_colorsMags.push_back (std::vector<double> ());
01153 }
01154 return borderBitmap;
01155 }
01156
01157 unsigned
01158 IgSoFieldPlane::correctOriginAndGetMask ()
01159 {
01160
01161
01162
01163
01164 unsigned crossingBorder = 0u;
01165
01166 unsigned mapDens[2];
01167 mapDens[X_AXIS] = mapDensityX.getValue ();
01168 mapDens[Z_AXIS] = mapDensityX.getValue ();
01169
01170
01171
01172 for (unsigned axis = X_AXIS; axis <= Z_AXIS; axis++)
01173 {
01174 float position = mapDens[axis] * (m_window.origin[axis] + 1.0f) / 2.0f;
01175 float roundedPos = round (position);
01176
01177 if ((m_window.baseDiv[axis] % 2) == 1)
01178 {
01179 position = ((position > roundedPos) ? (roundedPos + 0.5) : (roundedPos - 0.5));
01180 }
01181 else
01182 {
01183 position = roundedPos;
01184 }
01185
01186 m_window.origin[axis] = (position * 2.0f / (float) mapDens[axis]) - 1.0f;
01187 }
01188
01189
01190
01191
01192
01193 for (unsigned axis = X_AXIS; axis <= Z_AXIS; axis++)
01194 {
01195
01196 if ( m_window.origin[axis] <= (-1.0f + m_window.size[axis]) )
01197 {
01198 m_window.origin[axis] = -1.0f + m_window.size[axis];
01199 crossingBorder = crossingBorder | (1u << axis);
01200 }
01201
01202
01203 if ( (1.0f - m_window.size[axis]) <= m_window.origin[axis] )
01204 {
01205 m_window.origin[axis] = 1.0f - m_window.size[axis];
01206 crossingBorder = crossingBorder | (4u << axis);
01207 }
01208 }
01209 return crossingBorder;
01210 }
01211
01212 void
01213 IgSoFieldPlane::calcColorMags ()
01214 {
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225 Component comp = (Component) component.getValue ();
01226 float clamp = maxvalue.getValue ();
01227 SbVec3f xdir;
01228 SbVec3f zdir;
01229
01230
01231
01232 for (unsigned index = 0; index < 5; index++)
01233 {
01234
01235 if (m_regions[index].density[X_AXIS] == 0
01236 || m_regions[index].density[Z_AXIS] == 0)
01237 {
01238 continue;
01239 }
01240
01241
01242
01243 xdir = (m_regions[index].lowerRight - m_regions[index].lowerLeft) / (float) m_regions[index].density[X_AXIS];
01244 zdir = (m_regions[index].upperRight - m_regions[index].lowerRight) / (float) m_regions[index].density[Z_AXIS];
01245
01246 for (unsigned i = 0; i <= m_regions[index].density [Z_AXIS]; ++i)
01247 {
01248 for (unsigned j = 0; j <= m_regions[index].density [X_AXIS]; ++j)
01249 {
01250
01251 SbVec3f from (m_regions[index].lowerLeft + zdir * i + xdir * j);
01252 double pt [3] = { from [0], from [1], from [2] };
01253 double val [3];
01254
01255 m_field->evaluate (pt, val);
01256
01257
01258
01259
01260 SbVec3f dir (val [0], val [1], val [2]);
01261 double mag;
01262
01263 switch (comp)
01264 {
01265 case XYZ_ALL:
01266 mag = MINIMUM (dir.length (), clamp) / clamp;
01267 break;
01268
01269 case XYZ_X:
01270 mag = MINIMUM (fabs (dir [0]), clamp) / clamp;
01271 break;
01272
01273 case XYZ_Y:
01274 mag = MINIMUM (fabs (dir [1]), clamp) / clamp;
01275 break;
01276
01277 case XYZ_Z:
01278 mag = MINIMUM (fabs (dir [2]), clamp) / clamp;
01279 break;
01280
01281 case XYZ_PHI:
01282 {
01283 SbVec3f radius (from [0], from [1], 0);
01284 radius.normalize ();
01285 SbVec3f angular (SbVec3f (0, 0, 1).cross (radius));
01286 mag = MINIMUM (fabs (angular.dot (dir)), clamp) / clamp;
01287 }
01288 break;
01289
01290 case XYZ_R:
01291 {
01292 SbVec3f radius (from [0], from [1], 0);
01293 radius.normalize ();
01294 mag = MINIMUM (fabs (radius.dot (dir)), clamp) / clamp;
01295 }
01296 break;
01297
01298 default:
01299 assert (false);
01300 mag = 0.;
01301 break;
01302 }
01303
01304 m_colorsMags[index].push_back (mag);
01305 }
01306 }
01307 }
01308 }
01309
01310 void
01311 IgSoFieldPlane::planeChanged (void *me, SoSensor *)
01312 {
01313 IgSoFieldPlane *self = static_cast<IgSoFieldPlane *> (me);
01314 self->m_mplaneSensor->detach ();
01315 self->m_manip->plane = self->plane;
01316 self->update ();
01317 self->m_mplaneSensor->attach (&self->m_manip->plane);
01318 }
01319
01320 void
01321 IgSoFieldPlane::mplaneChanged (void *me, SoSensor *)
01322 {
01323 IgSoFieldPlane *self = static_cast<IgSoFieldPlane *> (me);
01324 self->m_planeSensor->detach ();
01325 self->plane = self->m_manip->plane;
01326 self->update ();
01327 self->m_planeSensor->attach (&self->plane);
01328 }
01329
01330 void
01331 IgSoFieldPlane::showChanged (void *me, SoSensor *)
01332 {
01333 IgSoFieldPlane *self = static_cast<IgSoFieldPlane *> (me);
01334 self->buildStructure ();
01335 if (! self->show.getValue ())
01336 self->whichChild = SO_SWITCH_NONE;
01337 else
01338 self->whichChild = SO_SWITCH_ALL;
01339 }
01340
01341 void
01342 IgSoFieldPlane::resampleSegmentsCB (void *me, SoSensor *)
01343 {
01344 IgSoFieldPlane *self = static_cast<IgSoFieldPlane *> (me);
01345 self->resampleSegments ();
01346 }
01347
01348 void
01349 IgSoFieldPlane::showMapChanged (void *me, SoSensor *)
01350 {
01351
01352 IgSoFieldPlane *self = static_cast<IgSoFieldPlane *> (me);
01353 self->buildStructure ();
01354 if (self->showMap.getValue ())
01355 {
01356 if (self->m_fieldPlane->getRefCount () == 1)
01357 {
01358 if (self->m_gradientScale->getRefCount () == 1)
01359 self->addChild (self->m_fieldPlane);
01360 else
01361 self->insertChild (self->m_fieldPlane,
01362 self->getNumChildren()-1);
01363 }
01364 }
01365 else if (self->m_fieldPlane->getRefCount () > 1)
01366 self->removeChild (self->m_fieldPlane);
01367 }
01368
01369 void
01370 IgSoFieldPlane::gradientScaleChanged (void *me, SoSensor *)
01371 {
01372
01373 IgSoFieldPlane *self = static_cast<IgSoFieldPlane *> (me);
01374 self->buildStructure ();
01375 if (self->gradientScale.getValue ())
01376 {
01377 if (self->m_gradientScale->getRefCount () == 1)
01378 self->addChild (self->m_gradientScale);
01379 }
01380 else if (self->m_gradientScale->getRefCount () > 1)
01381 self->removeChild (self->m_gradientScale);
01382 }
01383
01384 void
01385 IgSoFieldPlane::showSegmentsChanged (void *me, SoSensor *)
01386 {
01387
01388 IgSoFieldPlane *self = static_cast<IgSoFieldPlane *> (me);
01389 self->buildStructure ();
01390 if (self->showSegments.getValue ())
01391 {
01392 if (self->m_segments->getRefCount () == 1)
01393 self->insertChild (self->m_segments, 2);
01394 }
01395 else if (self->m_segments->getRefCount () > 1)
01396 self->removeChild (self->m_segments);
01397 }