00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "PreCompiled.h"
00024
00025 #ifndef _PreComp_
00026 # include <qstatusbar.h>
00027 # include <qstring.h>
00028 # include <Inventor/details/SoFaceDetail.h>
00029 # include <Inventor/details/SoLineDetail.h>
00030 #endif
00031
00032 #include <Inventor/elements/SoOverrideElement.h>
00033 #include <Inventor/elements/SoLazyElement.h>
00034 #include <Inventor/elements/SoCacheElement.h>
00035 #include <Inventor/elements/SoOverrideElement.h>
00036 #include <Inventor/elements/SoWindowElement.h>
00037
00038 #include <Inventor/SoFullPath.h>
00039 #include <Inventor/actions/SoGLRenderAction.h>
00040 #include <Inventor/actions/SoHandleEventAction.h>
00041 #include <Inventor/events/SoKeyboardEvent.h>
00042 #include <Inventor/events/SoMouseButtonEvent.h>
00043 #include <Inventor/misc/SoState.h>
00044 #include <Inventor/misc/SoChildList.h>
00045 #include <Inventor/events/SoLocation2Event.h>
00046 #include <Inventor/SoPickedPoint.h>
00047
00048 #include "View3DInventor.h"
00049 #include "View3DInventorViewer.h"
00050
00051 #include <Base/Console.h>
00052 #include "SoFCSelection.h"
00053 #include "MainWindow.h"
00054 #include "Selection.h"
00055 #include "SoFCSelectionAction.h"
00056 #include "SoFCInteractiveElement.h"
00057
00058
00059
00060
00061 #if defined(_OCC64) // is set by configure or cmake
00062 # define NO_FRONTBUFFER
00063 #endif
00064
00065 using namespace Gui;
00066
00067 SoFullPath * Gui::SoFCSelection::currenthighlight = NULL;
00068
00069
00070
00071
00072 SO_NODE_SOURCE(SoFCSelection);
00073
00077 SoFCSelection::SoFCSelection()
00078 {
00079 SO_NODE_CONSTRUCTOR(SoFCSelection);
00080
00081 SO_NODE_ADD_FIELD(colorHighlight, (SbColor(0.8f, 0.1f, 0.1f)));
00082 SO_NODE_ADD_FIELD(colorSelection, (SbColor(0.1f, 0.8f, 0.1f)));
00083 SO_NODE_ADD_FIELD(style, (EMISSIVE));
00084 SO_NODE_ADD_FIELD(highlightMode, (AUTO));
00085 SO_NODE_ADD_FIELD(selectionMode, (SEL_ON));
00086 SO_NODE_ADD_FIELD(selected, (NOTSELECTED));
00087 SO_NODE_ADD_FIELD(documentName, (""));
00088 SO_NODE_ADD_FIELD(objectName, (""));
00089 SO_NODE_ADD_FIELD(subElementName, (""));
00090
00091 SO_NODE_DEFINE_ENUM_VALUE(Styles, EMISSIVE);
00092 SO_NODE_DEFINE_ENUM_VALUE(Styles, EMISSIVE_DIFFUSE);
00093 SO_NODE_DEFINE_ENUM_VALUE(Styles, BOX);
00094 SO_NODE_SET_SF_ENUM_TYPE(style, Styles);
00095
00096 SO_NODE_DEFINE_ENUM_VALUE(HighlightModes, AUTO);
00097 SO_NODE_DEFINE_ENUM_VALUE(HighlightModes, ON);
00098 SO_NODE_DEFINE_ENUM_VALUE(HighlightModes, OFF);
00099 SO_NODE_SET_SF_ENUM_TYPE (highlightMode, HighlightModes);
00100
00101 SO_NODE_DEFINE_ENUM_VALUE(SelectionModes, SEL_ON);
00102 SO_NODE_DEFINE_ENUM_VALUE(SelectionModes, SEL_OFF);
00103 SO_NODE_SET_SF_ENUM_TYPE (selectionMode, SelectionModes);
00104
00105 SO_NODE_DEFINE_ENUM_VALUE(Selected, NOTSELECTED);
00106 SO_NODE_DEFINE_ENUM_VALUE(Selected, SELECTED);
00107 SO_NODE_SET_SF_ENUM_TYPE(selected, Selected);
00108
00109 highlighted = FALSE;
00110 bShift = FALSE;
00111 bCtrl = FALSE;
00112
00113 selected = NOTSELECTED;
00114 }
00115
00119 SoFCSelection::~SoFCSelection()
00120 {
00121
00122
00123 if (currenthighlight != NULL &&
00124 (!currenthighlight->getTail()->isOfType(SoFCSelection::getClassTypeId()))) {
00125 currenthighlight->unref();
00126 currenthighlight = NULL;
00127 }
00128
00129 }
00130
00131
00132 void
00133 SoFCSelection::initClass(void)
00134 {
00135 SO_NODE_INIT_CLASS(SoFCSelection,SoGroup,"Group");
00136 }
00137
00138 void SoFCSelection::finish()
00139 {
00140 atexit_cleanup();
00141 }
00142
00146 void
00147 SoFCSelection::turnOffCurrentHighlight(SoGLRenderAction * action)
00148 {
00149 SoFCSelection::turnoffcurrent(action);
00150 }
00151
00152 void SoFCSelection::doAction(SoAction *action)
00153 {
00154 if (action->getTypeId() == SoFCDocumentAction::getClassTypeId()) {
00155 SoFCDocumentAction *docaction = (SoFCDocumentAction*)action;
00156 this->documentName = docaction->documentName;
00157 }
00158
00159 if (action->getTypeId() == SoFCDocumentObjectAction::getClassTypeId()) {
00160 SoFCDocumentObjectAction* objaction = static_cast<SoFCDocumentObjectAction*>(action);
00161 objaction->documentName = this->documentName.getValue();
00162 objaction->objectName = this->objectName.getValue();
00163 objaction->componentName = this->subElementName.getValue();
00164 objaction->setHandled();
00165 }
00166
00167 if (action->getTypeId() == SoFCEnableHighlightAction::getClassTypeId()) {
00168 SoFCEnableHighlightAction *preaction = (SoFCEnableHighlightAction*)action;
00169 if (preaction->highlight) {
00170 this->highlightMode = SoFCSelection::AUTO;
00171 }
00172 else {
00173 this->highlightMode = SoFCSelection::OFF;
00174 }
00175 }
00176
00177 if (action->getTypeId() == SoFCEnableSelectionAction::getClassTypeId()) {
00178 SoFCEnableSelectionAction *selaction = (SoFCEnableSelectionAction*)action;
00179 if (selaction->selection) {
00180 this->selectionMode = SoFCSelection::SEL_ON;
00181 }
00182 else {
00183 this->selectionMode = SoFCSelection::SEL_OFF;
00184 if (selected.getValue() == SELECTED) {
00185 this->selected = NOTSELECTED;
00186 }
00187 }
00188 }
00189
00190 if (action->getTypeId() == SoFCSelectionColorAction::getClassTypeId()) {
00191 SoFCSelectionColorAction *colaction = (SoFCSelectionColorAction*)action;
00192 this->colorSelection = colaction->selectionColor;
00193 }
00194
00195 if (action->getTypeId() == SoFCHighlightColorAction::getClassTypeId()) {
00196 SoFCHighlightColorAction *colaction = (SoFCHighlightColorAction*)action;
00197 this->colorHighlight = colaction->highlightColor;
00198 }
00199
00200 if (selectionMode.getValue() == SEL_ON && action->getTypeId() == SoFCSelectionAction::getClassTypeId()) {
00201 SoFCSelectionAction *selaction = static_cast<SoFCSelectionAction*>(action);
00202
00203 if (selaction->SelChange.Type == SelectionChanges::AddSelection ||
00204 selaction->SelChange.Type == SelectionChanges::RmvSelection) {
00205 if (documentName.getValue() == selaction->SelChange.pDocName &&
00206 objectName.getValue() == selaction->SelChange.pObjectName &&
00207 (subElementName.getValue() == selaction->SelChange.pSubName ||
00208 *(selaction->SelChange.pSubName) == '\0') ) {
00209 if (selaction->SelChange.Type == SelectionChanges::AddSelection) {
00210 if(selected.getValue() == NOTSELECTED){
00211 selected = SELECTED;
00212 }
00213 }
00214 else {
00215 if(selected.getValue() == SELECTED){
00216 selected = NOTSELECTED;
00217 }
00218 }
00219 return;
00220 }
00221 }
00222 else if (selaction->SelChange.Type == SelectionChanges::ClrSelection) {
00223 if (documentName.getValue() == selaction->SelChange.pDocName ||
00224 strcmp(selaction->SelChange.pDocName,"") == 0){
00225 if(selected.getValue() == SELECTED){
00226 selected = NOTSELECTED;
00227 }
00228
00229 }
00230 }
00231 else if (selaction->SelChange.Type == SelectionChanges::SetSelection) {
00232 bool sel = Selection().isSelected(
00233 documentName.getValue().getString(),
00234 objectName.getValue().getString()
00235 );
00236 if (sel) {
00237 if (selected.getValue() == NOTSELECTED) {
00238 selected = SELECTED;
00239 }
00240 }
00241 else {
00242 if (selected.getValue() == SELECTED) {
00243 selected = NOTSELECTED;
00244 }
00245 }
00246 }
00247 }
00248
00249 inherited::doAction( action );
00250 }
00251
00252 int SoFCSelection::getPriority(const SoPickedPoint* p)
00253 {
00254 const SoDetail* detail = p->getDetail();
00255 if(!detail) return 0;
00256 if(detail->isOfType(SoFaceDetail::getClassTypeId())) return 1;
00257 if(detail->isOfType(SoLineDetail::getClassTypeId())) return 2;
00258 if(detail->isOfType(SoPointDetail::getClassTypeId())) return 3;
00259 return 0;
00260 }
00261
00262 const SoPickedPoint*
00263 SoFCSelection::getPickedPoint(SoHandleEventAction* action) const
00264 {
00265
00266
00267
00268
00269 const SoPickedPointList & points = action->getPickedPointList();
00270 if (points.getLength() == 0)
00271 return 0;
00272 else if (points.getLength() == 1)
00273 return points[0];
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288 const SoPickedPoint* picked = points[0];
00289
00290 int picked_prio = getPriority(picked);
00291 const SbVec3f& picked_pt = picked->getPoint();
00292
00293
00294 for(int i=1; i<points.getLength();i++) {
00295 const SoPickedPoint* cur = points[i];
00296 int cur_prio = getPriority(cur);
00297 const SbVec3f& cur_pt = cur->getPoint();
00298
00299 if ((cur_prio > picked_prio) && picked_pt.equals(cur_pt, 0.01f)) {
00300 picked = cur;
00301 picked_prio = cur_prio;
00302 }
00303 }
00304 return picked;
00305
00306 }
00307
00308
00309 void
00310 SoFCSelection::handleEvent(SoHandleEventAction * action)
00311 {
00312 static char buf[513];
00313 HighlightModes mymode = (HighlightModes) this->highlightMode.getValue();
00314 const SoEvent * event = action->getEvent();
00315 #ifdef NO_FRONTBUFFER
00316
00317 if (event->isOfType(SoLocation2Event::getClassTypeId())) {
00318
00319
00320
00321 if (mymode == AUTO || mymode == ON) {
00322 const SoPickedPoint * pp = this->getPickedPoint(action);
00323 if (pp && pp->getPath()->containsPath(action->getCurPath())) {
00324 if (!highlighted) {
00325 if (Gui::Selection().setPreselect(documentName.getValue().getString()
00326 ,objectName.getValue().getString()
00327 ,subElementName.getValue().getString()
00328 ,pp->getPoint()[0]
00329 ,pp->getPoint()[1]
00330 ,pp->getPoint()[2])){
00331 SoFCSelection::turnoffcurrent(action);
00332 SoFCSelection::currenthighlight = (SoFullPath*)action->getCurPath()->copy();
00333 SoFCSelection::currenthighlight->ref();
00334 highlighted = TRUE;
00335 this->touch();
00336 this->redrawHighlighted(action, TRUE);
00337 }
00338 }
00339
00340 snprintf(buf,512,"Preselected: %s.%s.%s (%f,%f,%f)",documentName.getValue().getString()
00341 ,objectName.getValue().getString()
00342 ,subElementName.getValue().getString()
00343 ,pp->getPoint()[0]
00344 ,pp->getPoint()[1]
00345 ,pp->getPoint()[2]);
00346
00347 getMainWindow()->showMessage(QString::fromAscii(buf),3000);
00348 }
00349 else {
00350 if (highlighted) {
00351 if (mymode == AUTO)
00352 SoFCSelection::turnoffcurrent(action);
00353
00354
00355 highlighted = FALSE;
00356 Gui::Selection().rmvPreselect();
00357 }
00358 }
00359 }
00360 }
00361 else if (event->isOfType(SoKeyboardEvent ::getClassTypeId())) {
00362 SoKeyboardEvent * const e = (SoKeyboardEvent *) event;
00363 if (SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::LEFT_SHIFT) ||
00364 SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::RIGHT_SHIFT) )
00365 bShift = true;
00366 if (SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::LEFT_SHIFT) ||
00367 SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::RIGHT_SHIFT) )
00368 bShift = false;
00369 if (SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::LEFT_CONTROL) ||
00370 SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::RIGHT_CONTROL) )
00371 bCtrl = true;
00372 if (SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::LEFT_CONTROL) ||
00373 SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::RIGHT_CONTROL) )
00374 bCtrl = false;
00375 }
00376 else if (event->isOfType(SoMouseButtonEvent::getClassTypeId())) {
00377 SoMouseButtonEvent * const e = (SoMouseButtonEvent *) event;
00378 if (SoMouseButtonEvent::isButtonReleaseEvent(e,SoMouseButtonEvent::BUTTON1)) {
00379
00380
00381 const SoPickedPoint * pp = this->getPickedPoint(action);
00382 if (pp && pp->getPath()->containsPath(action->getCurPath())) {
00383 if (bCtrl) {
00384 if (Gui::Selection().isSelected(documentName.getValue().getString()
00385 ,objectName.getValue().getString()
00386 ,subElementName.getValue().getString())) {
00387 Gui::Selection().rmvSelection(documentName.getValue().getString()
00388 ,objectName.getValue().getString()
00389 ,subElementName.getValue().getString());
00390 } else {
00391 Gui::Selection().addSelection(documentName.getValue().getString()
00392 ,objectName.getValue().getString()
00393 ,subElementName.getValue().getString()
00394 ,pp->getPoint()[0]
00395 ,pp->getPoint()[1]
00396 ,pp->getPoint()[2]);
00397
00398 if (mymode == OFF) {
00399 snprintf(buf,512,"Selected: %s.%s.%s (%f,%f,%f)",documentName.getValue().getString()
00400 ,objectName.getValue().getString()
00401 ,subElementName.getValue().getString()
00402 ,pp->getPoint()[0]
00403 ,pp->getPoint()[1]
00404 ,pp->getPoint()[2]);
00405
00406 getMainWindow()->showMessage(QString::fromAscii(buf),3000);
00407 }
00408 }
00409 }
00410 else {
00411 if (!Gui::Selection().isSelected(documentName.getValue().getString()
00412 ,objectName.getValue().getString()
00413 ,subElementName.getValue().getString())) {
00414 Gui::Selection().clearSelection(documentName.getValue().getString());
00415 Gui::Selection().addSelection(documentName.getValue().getString()
00416 ,objectName.getValue().getString()
00417 ,subElementName.getValue().getString()
00418 ,pp->getPoint()[0]
00419 ,pp->getPoint()[1]
00420 ,pp->getPoint()[2]);
00421 }
00422 else {
00423 Gui::Selection().clearSelection(documentName.getValue().getString());
00424 Gui::Selection().addSelection(documentName.getValue().getString()
00425 ,objectName.getValue().getString()
00426 ,0
00427 ,pp->getPoint()[0]
00428 ,pp->getPoint()[1]
00429 ,pp->getPoint()[2]);
00430 }
00431
00432 if (mymode == OFF) {
00433 snprintf(buf,512,"Selected: %s.%s.%s (%f,%f,%f)",documentName.getValue().getString()
00434 ,objectName.getValue().getString()
00435 ,subElementName.getValue().getString()
00436 ,pp->getPoint()[0]
00437 ,pp->getPoint()[1]
00438 ,pp->getPoint()[2]);
00439
00440 getMainWindow()->showMessage(QString::fromAscii(buf),3000);
00441 }
00442 }
00443
00444 action->setHandled();
00445 }
00446 }
00447 }
00448
00449 inherited::handleEvent(action);
00450 #else
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 if (event->isOfType(SoLocation2Event::getClassTypeId())) {
00466
00467 SbBool underTheMouse = FALSE;
00468 const SoPickedPoint * pp = this->getPickedPoint(action);
00469 SoFullPath *pPath = (pp != NULL) ? (SoFullPath *) pp->getPath() : NULL;
00470 if (pPath && pPath->containsPath(action->getCurPath())) {
00471
00472 underTheMouse = TRUE;
00473 for (int i = 0; i < pPath->getLength(); i++) {
00474 SoNode *node = pPath->getNodeFromTail(i);
00475 if (node->isOfType(SoFCSelection::getClassTypeId())) {
00476 if (node != this)
00477 underTheMouse = FALSE;
00478 break;
00479 }
00480 }
00481 }
00482
00483 if (isHighlighted(action)) {
00484 if (! underTheMouse) {
00485
00486
00487 redrawHighlighted(action, FALSE);
00488 Gui::Selection().rmvPreselect();
00489 }
00490 else {
00491 action->setHandled();
00492
00493 Gui::Selection().setPreselectCoord(pp->getPoint()[0]
00494 ,pp->getPoint()[1]
00495 ,pp->getPoint()[2]);
00496 }
00497 }
00498
00499 else {
00500
00501 if (underTheMouse) {
00502
00503 if (mymode != OFF)
00504 redrawHighlighted(action, TRUE);
00505
00506 Gui::Selection().setPreselect(documentName.getValue().getString()
00507 ,objectName.getValue().getString()
00508 ,subElementName.getValue().getString()
00509 ,pp->getPoint()[0]
00510 ,pp->getPoint()[1]
00511 ,pp->getPoint()[2]);
00512 }
00513 }
00514
00515
00516
00517
00518
00519
00520
00521 }
00522
00523 else if (event->isOfType(SoKeyboardEvent ::getClassTypeId())) {
00524 SoKeyboardEvent * const e = (SoKeyboardEvent *) event;
00525 if (SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::LEFT_SHIFT) ||
00526 SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::RIGHT_SHIFT) )
00527 bShift = true;
00528 if (SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::LEFT_SHIFT) ||
00529 SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::RIGHT_SHIFT) )
00530 bShift = false;
00531 if (SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::LEFT_CONTROL) ||
00532 SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::RIGHT_CONTROL) )
00533 bCtrl = true;
00534 if (SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::LEFT_CONTROL) ||
00535 SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::RIGHT_CONTROL) )
00536 bCtrl = false;
00537 }
00538
00539 else if (event->isOfType(SoMouseButtonEvent::getClassTypeId()) &&
00540 selectionMode.getValue() == SoFCSelection::SEL_ON) {
00541 SoMouseButtonEvent * const e = (SoMouseButtonEvent *) event;
00542 if (SoMouseButtonEvent::isButtonReleaseEvent(e,SoMouseButtonEvent::BUTTON1)) {
00543
00544
00545 const SoPickedPoint * pp = this->getPickedPoint(action);
00546 if (pp && pp->getPath()->containsPath(action->getCurPath())) {
00547 if (bCtrl) {
00548 if (Gui::Selection().isSelected(documentName.getValue().getString()
00549 ,objectName.getValue().getString()
00550 ,subElementName.getValue().getString())) {
00551 Gui::Selection().rmvSelection(documentName.getValue().getString()
00552 ,objectName.getValue().getString()
00553 ,subElementName.getValue().getString());
00554 }
00555 else {
00556 Gui::Selection().addSelection(documentName.getValue().getString()
00557 ,objectName.getValue().getString()
00558 ,subElementName.getValue().getString()
00559 ,pp->getPoint()[0]
00560 ,pp->getPoint()[1]
00561 ,pp->getPoint()[2]);
00562
00563 if (mymode == OFF) {
00564 snprintf(buf,512,"Selected: %s.%s.%s (%f,%f,%f)",documentName.getValue().getString()
00565 ,objectName.getValue().getString()
00566 ,subElementName.getValue().getString()
00567 ,pp->getPoint()[0]
00568 ,pp->getPoint()[1]
00569 ,pp->getPoint()[2]);
00570
00571 getMainWindow()->statusBar()->showMessage(QString::fromAscii(buf),3000);
00572 }
00573 }
00574 }
00575 else {
00576 if (!Gui::Selection().isSelected(documentName.getValue().getString()
00577 ,objectName.getValue().getString()
00578 ,subElementName.getValue().getString())) {
00579 Gui::Selection().clearSelection(documentName.getValue().getString());
00580 Gui::Selection().addSelection(documentName.getValue().getString()
00581 ,objectName.getValue().getString()
00582 ,subElementName.getValue().getString()
00583 ,pp->getPoint()[0]
00584 ,pp->getPoint()[1]
00585 ,pp->getPoint()[2]);
00586 }
00587 else {
00588 Gui::Selection().clearSelection(documentName.getValue().getString());
00589 Gui::Selection().addSelection(documentName.getValue().getString()
00590 ,objectName.getValue().getString()
00591 ,0
00592 ,pp->getPoint()[0]
00593 ,pp->getPoint()[1]
00594 ,pp->getPoint()[2]);
00595 }
00596
00597 if (mymode == OFF) {
00598 snprintf(buf,512,"Selected: %s.%s.%s (%f,%f,%f)",documentName.getValue().getString()
00599 ,objectName.getValue().getString()
00600 ,subElementName.getValue().getString()
00601 ,pp->getPoint()[0]
00602 ,pp->getPoint()[1]
00603 ,pp->getPoint()[2]);
00604
00605 getMainWindow()->statusBar()->showMessage(QString::fromAscii(buf),3000);
00606 }
00607 }
00608
00609 action->setHandled();
00610 }
00611 }
00612 }
00613
00614
00615 if (action->getGrabber() != this)
00616 inherited::handleEvent(action);
00617 #endif
00618 }
00619
00620
00621 void
00622 SoFCSelection::GLRenderBelowPath(SoGLRenderAction * action)
00623 {
00624 #ifdef NO_FRONTBUFFER
00625
00626 HighlightModes mymode = (HighlightModes) this->highlightMode.getValue();
00627 bool preselected = highlighted && mymode == AUTO;
00628 SoState * state = action->getState();
00629 state->push();
00630 if (preselected || this->highlightMode.getValue() == ON || this->selected.getValue() == SELECTED) {
00631 this->setOverride(action);
00632 }
00633 inherited::GLRenderBelowPath(action);
00634 state->pop();
00635 #else
00636
00637 GLint oldDepthFunc;
00638 SbBool drawHighlighted = preRender(action, oldDepthFunc);
00639
00640
00641 inherited::GLRenderBelowPath(action);
00642
00643
00644 if (drawHighlighted || highlighted)
00645 glDepthFunc((GLenum)oldDepthFunc);
00646
00647
00648 if (drawHighlighted)
00649 action->getState()->pop();
00650 #endif
00651 }
00652
00653 void SoFCSelection::GLRender(SoGLRenderAction * action)
00654 {
00655 inherited::GLRender(action);
00656 }
00657
00658
00659 void
00660 SoFCSelection::GLRenderInPath(SoGLRenderAction * action)
00661 {
00662 #ifdef NO_FRONTBUFFER
00663
00664 HighlightModes mymode = (HighlightModes) this->highlightMode.getValue();
00665 bool preselected = highlighted && mymode == AUTO;
00666 SoState * state = action->getState();
00667 state->push();
00668 if (preselected || this->highlightMode.getValue() == ON || this->selected.getValue() == SELECTED) {
00669 this->setOverride(action);
00670 }
00671 inherited::GLRenderInPath(action);
00672 state->pop();
00673 #else
00674
00675 GLint oldDepthFunc;
00676 SbBool drawHighlighted = preRender(action, oldDepthFunc);
00677
00678
00679 inherited::GLRenderInPath(action);
00680
00681
00682 if (drawHighlighted || highlighted)
00683 glDepthFunc((GLenum)oldDepthFunc);
00684
00685
00686 if (drawHighlighted)
00687 action->getState()->pop();
00688 #endif
00689 }
00690
00691 SbBool
00692 SoFCSelection::preRender(SoGLRenderAction *action, GLint &oldDepthFunc)
00693
00695 {
00696
00697 if (highlightMode.getValue() == OFF)
00698 return FALSE;
00699
00700 SoState *state = action->getState();
00701
00702
00703
00704
00705
00706
00707 SbBool drawHighlighted = (highlightMode.getValue() == ON || isHighlighted(action) || selected.getValue() == SELECTED);
00708
00709 if (drawHighlighted) {
00710
00711 state->push();
00712 SbColor col;
00713 if (selected.getValue() == SELECTED)
00714 col = colorSelection.getValue();
00715 else
00716 col = colorHighlight.getValue();
00717
00718
00719 SoLazyElement::setEmissive(state, &col);
00720 SoOverrideElement::setEmissiveColorOverride(state, this, TRUE);
00721
00722
00723 if (style.getValue() == EMISSIVE_DIFFUSE) {
00724 SoLazyElement::setDiffuse(state, this, 1, &col, &colorpacker);
00725 SoOverrideElement::setDiffuseColorOverride(state, this, TRUE);
00726 }
00727 }
00728
00729
00730
00731
00732
00733
00734 if (drawHighlighted || highlighted) {
00735 glGetIntegerv(GL_DEPTH_FUNC, &oldDepthFunc);
00736 if (oldDepthFunc != GL_LEQUAL)
00737 glDepthFunc(GL_LEQUAL);
00738 }
00739
00740 return drawHighlighted;
00741 }
00742
00747 void
00748 SoFCSelection::redrawHighlighted(SoAction * action , SbBool doHighlight )
00749 {
00750
00751
00752 #ifdef NO_FRONTBUFFER
00753 #else
00754
00755
00756 if (doHighlight && currenthighlight != NULL &&
00757 !(*((SoFullPath *)action->getCurPath()) == *currenthighlight)) {
00758
00759 SoNode *tail = currenthighlight->getTail();
00760 if (tail->isOfType( SoFCSelection::getClassTypeId()))
00761 ((SoFCSelection *)tail)->redrawHighlighted(action, FALSE);
00762 else {
00763
00764 currenthighlight->unref();
00765 currenthighlight = NULL;
00766 }
00767 }
00768
00769 SoPath *pathToRender;
00770
00771 if (doHighlight) {
00772 if (currenthighlight != NULL)
00773 currenthighlight->unref();
00774 currenthighlight = (SoFullPath *) action->getCurPath()->copy();
00775 currenthighlight->ref();
00776
00777
00778 pathToRender = currenthighlight;
00779 pathToRender->ref();
00780 }
00781
00782 else {
00783 if (currenthighlight) {
00784
00785 pathToRender = currenthighlight;
00786 pathToRender->ref();
00787
00788 currenthighlight->unref();
00789 currenthighlight = NULL;
00790 }
00791 }
00792
00793
00794 if (highlightMode.getValue() != AUTO) {
00795 pathToRender->unref();
00796 return;
00797 }
00798
00799 SoState *state = action->getState();
00800
00801
00802
00803
00804 QGLWidget* window;
00805 SoGLRenderAction *glAction;
00806
00807 SoGLWidgetElement::get(state, window);
00808 SoGLRenderActionElement::get(state, glAction);
00809
00810
00811 if (window == 0 || glAction == NULL)
00812 return;
00813
00814 window->makeCurrent();
00815 #ifndef WIN32
00816
00817
00818 #endif
00819
00820 GLint whichBuffer;
00821 glGetIntegerv(GL_DRAW_BUFFER, &whichBuffer);
00822 if (whichBuffer != GL_FRONT)
00823 glDrawBuffer(GL_FRONT);
00824
00825 highlighted = TRUE;
00826 glAction->apply(pathToRender);
00827 highlighted = FALSE;
00828
00829
00830 if (whichBuffer != GL_FRONT)
00831 glDrawBuffer((GLenum)whichBuffer);
00832 glFlush();
00833
00834 pathToRender->unref();
00835 #endif
00836 }
00837
00838 SbBool
00839 SoFCSelection::readInstance ( SoInput * in, unsigned short flags )
00840 {
00841
00842 SbBool ret = inherited::readInstance(in, flags);
00843 return ret;
00844 }
00845
00846
00847
00848 void
00849 SoFCSelection::setOverride(SoGLRenderAction * action)
00850 {
00851
00852 SoState * state = action->getState();
00853 if(this->selected.getValue() == SELECTED)
00854 SoLazyElement::setEmissive(state, &this->colorSelection.getValue());
00855 else
00856 SoLazyElement::setEmissive(state, &this->colorHighlight.getValue());
00857 SoOverrideElement::setEmissiveColorOverride(state, this, TRUE);
00858
00859 Styles mystyle = (Styles) this->style.getValue();
00860 if (mystyle == SoFCSelection::EMISSIVE_DIFFUSE) {
00861 if(this->selected.getValue() == SELECTED)
00862 SoLazyElement::setDiffuse(state, this,1, &this->colorSelection.getValue(),&colorpacker);
00863 else
00864 SoLazyElement::setDiffuse(state, this,1, &this->colorHighlight.getValue(),&colorpacker);
00865 SoOverrideElement::setDiffuseColorOverride(state, this, TRUE);
00866 }
00867 }
00868
00869
00870 void
00871 SoFCSelection::turnoffcurrent(SoAction * action)
00872 {
00873 #ifdef NO_FRONTBUFFER
00874 if (SoFCSelection::currenthighlight &&
00875 SoFCSelection::currenthighlight->getLength()) {
00876 SoNode * tail = SoFCSelection::currenthighlight->getTail();
00877 if (tail->isOfType(SoFCSelection::getClassTypeId())) {
00878 ((SoFCSelection*)tail)->highlighted = FALSE;
00879 ((SoFCSelection*)tail)->touch();
00880 if (action) ((SoFCSelection*)tail)->redrawHighlighted(action, FALSE);
00881 }
00882 }
00883 if (SoFCSelection::currenthighlight) {
00884 SoFCSelection::currenthighlight->unref();
00885 SoFCSelection::currenthighlight = NULL;
00886 }
00887 #else
00888 if (currenthighlight == NULL)
00889 return;
00890
00891 SoNode *tail = currenthighlight->getTail();
00892 if (tail->isOfType(SoFCSelection::getClassTypeId())) {
00893
00894
00895
00896 SoState *state = action->getState();
00897 if (state && state->getDepth() == 1)
00898 ((SoFCSelection *)tail)->redrawHighlighted(action, FALSE);
00899 }
00900 else {
00901
00902 currenthighlight->unref();
00903 currenthighlight = NULL;
00904 }
00905 #endif
00906 }
00907
00908 SbBool
00909 SoFCSelection::isHighlighted(SoAction *action)
00910
00912 {
00913 SoFullPath *actionPath = (SoFullPath *) action->getCurPath();
00914 return (currenthighlight != NULL &&
00915 currenthighlight->getTail() == actionPath->getTail() &&
00916 *currenthighlight == *actionPath);
00917 }
00918
00919