| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| |
|
| | #include <QString>
|
| | #include <Inventor/SoFullPath.h>
|
| | #include <Inventor/SoPickedPoint.h>
|
| | #include <Inventor/actions/SoGLRenderAction.h>
|
| | #include <Inventor/actions/SoHandleEventAction.h>
|
| | #include <Inventor/details/SoFaceDetail.h>
|
| | #include <Inventor/details/SoLineDetail.h>
|
| | #include <Inventor/elements/SoLazyElement.h>
|
| | #include <Inventor/elements/SoMaterialBindingElement.h>
|
| | #include <Inventor/elements/SoOverrideElement.h>
|
| | #include <Inventor/elements/SoWindowElement.h>
|
| | #include <Inventor/events/SoKeyboardEvent.h>
|
| | #include <Inventor/events/SoLocation2Event.h>
|
| | #include <Inventor/events/SoMouseButtonEvent.h>
|
| | #include <Inventor/misc/SoState.h>
|
| |
|
| |
|
| | #include <Base/UnitsApi.h>
|
| |
|
| | #include "SoFCSelection.h"
|
| | #include "MainWindow.h"
|
| | #include "SoFCSelectionAction.h"
|
| | #include "SoFCUnifiedSelection.h"
|
| | #include "ViewParams.h"
|
| |
|
| |
|
| | using namespace Gui;
|
| |
|
| | namespace Gui
|
| | {
|
| | void printPreselectionInfo(
|
| | const char* documentName,
|
| | const char* objectName,
|
| | const char* subElementName,
|
| | float x,
|
| | float y,
|
| | float z,
|
| | double precision
|
| | );
|
| | }
|
| |
|
| | SoFullPath* Gui::SoFCSelection::currenthighlight = nullptr;
|
| |
|
| |
|
| |
|
| |
|
| | SO_NODE_SOURCE(SoFCSelection)
|
| |
|
| | |
| | |
| |
|
| | SoFCSelection::SoFCSelection()
|
| | {
|
| | SO_NODE_CONSTRUCTOR(SoFCSelection);
|
| |
|
| | SO_NODE_ADD_FIELD(colorHighlight, (SbColor(0.8f, 0.1f, 0.1f)));
|
| | SO_NODE_ADD_FIELD(colorSelection, (SbColor(0.1f, 0.8f, 0.1f)));
|
| | SO_NODE_ADD_FIELD(style, (EMISSIVE));
|
| | SO_NODE_ADD_FIELD(preselectionMode, (AUTO));
|
| | SO_NODE_ADD_FIELD(selectionMode, (SEL_ON));
|
| | SO_NODE_ADD_FIELD(selected, (NOTSELECTED));
|
| | SO_NODE_ADD_FIELD(documentName, (""));
|
| | SO_NODE_ADD_FIELD(objectName, (""));
|
| | SO_NODE_ADD_FIELD(subElementName, (""));
|
| | SO_NODE_ADD_FIELD(useNewSelection, (true));
|
| |
|
| | SO_NODE_DEFINE_ENUM_VALUE(Styles, EMISSIVE);
|
| | SO_NODE_DEFINE_ENUM_VALUE(Styles, EMISSIVE_DIFFUSE);
|
| | SO_NODE_DEFINE_ENUM_VALUE(Styles, BOX);
|
| | SO_NODE_SET_SF_ENUM_TYPE(style, Styles);
|
| |
|
| | SO_NODE_DEFINE_ENUM_VALUE(PreselectionModes, AUTO);
|
| | SO_NODE_DEFINE_ENUM_VALUE(PreselectionModes, ON);
|
| | SO_NODE_DEFINE_ENUM_VALUE(PreselectionModes, OFF);
|
| | SO_NODE_SET_SF_ENUM_TYPE(preselectionMode, PreselectionModes);
|
| |
|
| | SO_NODE_DEFINE_ENUM_VALUE(SelectionModes, SEL_ON);
|
| | SO_NODE_DEFINE_ENUM_VALUE(SelectionModes, SEL_OFF);
|
| | SO_NODE_SET_SF_ENUM_TYPE(selectionMode, SelectionModes);
|
| |
|
| | SO_NODE_DEFINE_ENUM_VALUE(Selected, NOTSELECTED);
|
| | SO_NODE_DEFINE_ENUM_VALUE(Selected, SELECTED);
|
| | SO_NODE_SET_SF_ENUM_TYPE(selected, Selected);
|
| |
|
| | highlighted = false;
|
| | bShift = false;
|
| | bCtrl = false;
|
| |
|
| | selected = NOTSELECTED;
|
| |
|
| | useNewSelection = ViewParams::instance()->getUseNewSelection();
|
| | selContext = std::make_shared<SelContext>();
|
| | selContext2 = std::make_shared<SelContext>();
|
| | }
|
| |
|
| | |
| | |
| |
|
| | SoFCSelection::~SoFCSelection()
|
| | {
|
| |
|
| |
|
| | if (currenthighlight
|
| | && (!currenthighlight->getTail()->isOfType(SoFCSelection::getClassTypeId()))) {
|
| | currenthighlight->unref();
|
| | currenthighlight = nullptr;
|
| | }
|
| |
|
| | }
|
| |
|
| |
|
| | void SoFCSelection::initClass()
|
| | {
|
| | SO_NODE_INIT_CLASS(SoFCSelection, SoGroup, "Group");
|
| | }
|
| |
|
| | void SoFCSelection::finish()
|
| | {
|
| | atexit_cleanup();
|
| | }
|
| |
|
| | |
| | |
| |
|
| | void SoFCSelection::turnOffCurrentHighlight(SoGLRenderAction* action)
|
| | {
|
| | SoFCSelection::turnoffcurrent(action);
|
| | }
|
| |
|
| | void SoFCSelection::doAction(SoAction* action)
|
| | {
|
| | if (useNewSelection.getValue() && action->getCurPathCode() != SoAction::OFF_PATH) {
|
| | if (action->getTypeId() == Gui::SoHighlightElementAction::getClassTypeId()) {
|
| | auto hlaction = static_cast<Gui::SoHighlightElementAction*>(action);
|
| | if (!hlaction->isHighlighted()) {
|
| | auto ctx = Gui::SoFCSelectionRoot::getActionContext(action, this, selContext, false);
|
| | if (ctx && ctx->isHighlighted()) {
|
| | ctx->highlightIndex = -1;
|
| | touch();
|
| | }
|
| | }
|
| | else {
|
| | auto ctx = Gui::SoFCSelectionRoot::getActionContext(action, this, selContext);
|
| | if (ctx) {
|
| | ctx->highlightColor = hlaction->getColor();
|
| | if (!ctx->isHighlighted()) {
|
| | ctx->highlightIndex = 0;
|
| | touch();
|
| | }
|
| | }
|
| | }
|
| | return;
|
| | }
|
| | else if (action->getTypeId() == Gui::SoSelectionElementAction::getClassTypeId()) {
|
| | auto selaction = static_cast<Gui::SoSelectionElementAction*>(action);
|
| | if (selaction->getType() == Gui::SoSelectionElementAction::All
|
| | || selaction->getType() == Gui::SoSelectionElementAction::Append) {
|
| | SelContextPtr ctx = Gui::SoFCSelectionRoot::getActionContext(action, this, selContext);
|
| | if (ctx) {
|
| | ctx->selectionColor = selaction->getColor();
|
| | if (!ctx->isSelectAll()) {
|
| | ctx->selectAll();
|
| | this->touch();
|
| | }
|
| | }
|
| | }
|
| | else if (selaction->getType() == Gui::SoSelectionElementAction::None
|
| | || selaction->getType() == Gui::SoSelectionElementAction::Remove) {
|
| | SelContextPtr ctx
|
| | = Gui::SoFCSelectionRoot::getActionContext(action, this, selContext, false);
|
| | if (ctx && ctx->isSelected()) {
|
| | ctx->selectionIndex.clear();
|
| | this->touch();
|
| | }
|
| | }
|
| | return;
|
| | }
|
| | }
|
| |
|
| | if (action->getTypeId() == SoFCDocumentAction::getClassTypeId()) {
|
| | auto docaction = static_cast<SoFCDocumentAction*>(action);
|
| | this->documentName = docaction->documentName;
|
| | }
|
| |
|
| | if (action->getTypeId() == SoFCDocumentObjectAction::getClassTypeId()) {
|
| | auto objaction = static_cast<SoFCDocumentObjectAction*>(action);
|
| | objaction->documentName = this->documentName.getValue();
|
| | objaction->objectName = this->objectName.getValue();
|
| | objaction->componentName = this->subElementName.getValue();
|
| | objaction->setHandled();
|
| | }
|
| |
|
| | if (!useNewSelection.getValue()) {
|
| |
|
| | if (action->getTypeId() == SoFCEnablePreselectionAction::getClassTypeId()) {
|
| | auto preaction = static_cast<SoFCEnablePreselectionAction*>(action);
|
| | if (preaction->enabled) {
|
| | this->preselectionMode = SoFCSelection::AUTO;
|
| | }
|
| | else {
|
| | this->preselectionMode = SoFCSelection::OFF;
|
| | }
|
| | }
|
| |
|
| | if (action->getTypeId() == SoFCEnableSelectionAction::getClassTypeId()) {
|
| | auto selaction = static_cast<SoFCEnableSelectionAction*>(action);
|
| | if (selaction->enabled) {
|
| | this->selectionMode = SoFCSelection::SEL_ON;
|
| | }
|
| | else {
|
| | this->selectionMode = SoFCSelection::SEL_OFF;
|
| | if (selected.getValue() == SELECTED) {
|
| | this->selected = NOTSELECTED;
|
| | }
|
| | }
|
| | }
|
| |
|
| | if (action->getTypeId() == SoFCSelectionColorAction::getClassTypeId()) {
|
| | auto colaction = static_cast<SoFCSelectionColorAction*>(action);
|
| | this->colorSelection = colaction->selectionColor;
|
| | }
|
| |
|
| | if (action->getTypeId() == SoFCHighlightColorAction::getClassTypeId()) {
|
| | auto colaction = static_cast<SoFCHighlightColorAction*>(action);
|
| | this->colorHighlight = colaction->highlightColor;
|
| | }
|
| |
|
| | if (selectionMode.getValue() == SEL_ON
|
| | && action->getTypeId() == SoFCSelectionAction::getClassTypeId()) {
|
| | auto selaction = static_cast<SoFCSelectionAction*>(action);
|
| |
|
| | if (selaction->SelChange.Type == SelectionChanges::AddSelection
|
| | || selaction->SelChange.Type == SelectionChanges::RmvSelection) {
|
| | if (documentName.getValue() == selaction->SelChange.pDocName
|
| | && objectName.getValue() == selaction->SelChange.pObjectName
|
| | && (subElementName.getValue() == selaction->SelChange.pSubName
|
| | || *(selaction->SelChange.pSubName) == '\0')) {
|
| | if (selaction->SelChange.Type == SelectionChanges::AddSelection) {
|
| | if (selected.getValue() == NOTSELECTED) {
|
| | selected = SELECTED;
|
| | }
|
| | }
|
| | else {
|
| | if (selected.getValue() == SELECTED) {
|
| | selected = NOTSELECTED;
|
| | }
|
| | }
|
| | return;
|
| | }
|
| | }
|
| | else if (selaction->SelChange.Type == SelectionChanges::ClrSelection) {
|
| | if (documentName.getValue() == selaction->SelChange.pDocName
|
| | || strcmp(selaction->SelChange.pDocName, "") == 0) {
|
| | if (selected.getValue() == SELECTED) {
|
| | selected = NOTSELECTED;
|
| | }
|
| | }
|
| | }
|
| | else if (selaction->SelChange.Type == SelectionChanges::SetSelection) {
|
| | bool sel = Selection().isSelected(
|
| | documentName.getValue().getString(),
|
| | objectName.getValue().getString() |
| |
|
| | );
|
| | if (sel) {
|
| | if (selected.getValue() == NOTSELECTED) {
|
| | selected = SELECTED;
|
| | }
|
| | }
|
| | else {
|
| | if (selected.getValue() == SELECTED) {
|
| | selected = NOTSELECTED;
|
| | }
|
| | }
|
| | }
|
| | }
|
| | }
|
| |
|
| | inherited::doAction(action);
|
| | }
|
| |
|
| | int SoFCSelection::getPriority(const SoPickedPoint* p)
|
| | {
|
| | const SoDetail* detail = p->getDetail();
|
| | if (!detail) {
|
| | return 0;
|
| | }
|
| | if (detail->isOfType(SoFaceDetail::getClassTypeId())) {
|
| | return 1;
|
| | }
|
| | if (detail->isOfType(SoLineDetail::getClassTypeId())) {
|
| | return 2;
|
| | }
|
| | if (detail->isOfType(SoPointDetail::getClassTypeId())) {
|
| | return 3;
|
| | }
|
| | return 0;
|
| | }
|
| |
|
| | const SoPickedPoint* SoFCSelection::getPickedPoint(SoHandleEventAction* action) const
|
| | {
|
| |
|
| |
|
| |
|
| |
|
| | const SoPickedPointList& points = action->getPickedPointList();
|
| | if (points.getLength() == 0) {
|
| | return nullptr;
|
| | }
|
| | else if (points.getLength() == 1) {
|
| | return points[0];
|
| | }
|
| |
|
| | const SoPickedPoint* picked = points[0];
|
| |
|
| | int picked_prio = getPriority(picked);
|
| | const SbVec3f& picked_pt = picked->getPoint();
|
| |
|
| |
|
| | for (int i = 1; i < points.getLength(); i++) {
|
| | const SoPickedPoint* cur = points[i];
|
| | int cur_prio = getPriority(cur);
|
| | const SbVec3f& cur_pt = cur->getPoint();
|
| |
|
| | if ((cur_prio > picked_prio) && picked_pt.equals(cur_pt, 0.01f)) {
|
| | picked = cur;
|
| | picked_prio = cur_prio;
|
| | }
|
| | }
|
| | return picked;
|
| | }
|
| |
|
| |
|
| | void SoFCSelection::handleEvent(SoHandleEventAction* action)
|
| | {
|
| | if (useNewSelection.getValue()) {
|
| | inherited::handleEvent(action);
|
| | return;
|
| | }
|
| |
|
| | static char buf[513];
|
| | auto mymode = static_cast<PreselectionModes>(this->preselectionMode.getValue());
|
| | const SoEvent* event = action->getEvent();
|
| |
|
| |
|
| | if (event->isOfType(SoLocation2Event::getClassTypeId())) {
|
| |
|
| |
|
| |
|
| | if (mymode == AUTO || mymode == ON) {
|
| | const SoPickedPoint* pp = this->getPickedPoint(action);
|
| | if (pp && pp->getPath()->containsPath(action->getCurPath())) {
|
| | if (!highlighted) {
|
| | if (Gui::Selection().setPreselect(
|
| | documentName.getValue().getString(),
|
| | objectName.getValue().getString(),
|
| | subElementName.getValue().getString(),
|
| | pp->getPoint()[0],
|
| | pp->getPoint()[1],
|
| | pp->getPoint()[2]
|
| | )) {
|
| | SoFCSelection::turnoffcurrent(action);
|
| | SoFCSelection::currenthighlight = static_cast<SoFullPath*>(
|
| | action->getCurPath()->copy()
|
| | );
|
| | SoFCSelection::currenthighlight->ref();
|
| | highlighted = true;
|
| | this->touch();
|
| | this->redrawHighlighted(action, true);
|
| | }
|
| | }
|
| |
|
| | const auto& pt = pp->getPoint();
|
| |
|
| | printPreselectionInfo(
|
| | documentName.getValue().getString(),
|
| | objectName.getValue().getString(),
|
| | subElementName.getValue().getString(),
|
| | pt[0],
|
| | pt[1],
|
| | pt[2],
|
| | 1e-7
|
| | );
|
| | }
|
| | else {
|
| | if (highlighted) {
|
| | if (mymode == AUTO) {
|
| | SoFCSelection::turnoffcurrent(action);
|
| | }
|
| |
|
| |
|
| | highlighted = false;
|
| | Gui::Selection().rmvPreselect();
|
| | }
|
| | }
|
| | }
|
| | }
|
| | else if (event->isOfType(SoKeyboardEvent ::getClassTypeId())) {
|
| | auto const e = static_cast<const SoKeyboardEvent*>(event);
|
| | if (SoKeyboardEvent::isKeyPressEvent(e, SoKeyboardEvent::LEFT_SHIFT)
|
| | || SoKeyboardEvent::isKeyPressEvent(e, SoKeyboardEvent::RIGHT_SHIFT)) {
|
| | bShift = true;
|
| | }
|
| | if (SoKeyboardEvent::isKeyReleaseEvent(e, SoKeyboardEvent::LEFT_SHIFT)
|
| | || SoKeyboardEvent::isKeyReleaseEvent(e, SoKeyboardEvent::RIGHT_SHIFT)) {
|
| | bShift = false;
|
| | }
|
| | if (SoKeyboardEvent::isKeyPressEvent(e, SoKeyboardEvent::LEFT_CONTROL)
|
| | || SoKeyboardEvent::isKeyPressEvent(e, SoKeyboardEvent::RIGHT_CONTROL)) {
|
| | bCtrl = true;
|
| | }
|
| | if (SoKeyboardEvent::isKeyReleaseEvent(e, SoKeyboardEvent::LEFT_CONTROL)
|
| | || SoKeyboardEvent::isKeyReleaseEvent(e, SoKeyboardEvent::RIGHT_CONTROL)) {
|
| | bCtrl = false;
|
| | }
|
| | }
|
| | else if (event->isOfType(SoMouseButtonEvent::getClassTypeId())) {
|
| | auto const e = static_cast<const SoMouseButtonEvent*>(event);
|
| | if (SoMouseButtonEvent::isButtonReleaseEvent(e, SoMouseButtonEvent::BUTTON1)) {
|
| |
|
| |
|
| |
|
| | const SoPickedPoint* pp = this->getPickedPoint(action);
|
| | if (pp && pp->getPath()->containsPath(action->getCurPath())) {
|
| | const auto& pt = pp->getPoint();
|
| | if (bCtrl) {
|
| | if (Gui::Selection().isSelected(
|
| | documentName.getValue().getString(),
|
| | objectName.getValue().getString(),
|
| | subElementName.getValue().getString()
|
| | )) {
|
| | Gui::Selection().rmvSelection(
|
| | documentName.getValue().getString(),
|
| | objectName.getValue().getString(),
|
| | subElementName.getValue().getString()
|
| | );
|
| | }
|
| | else {
|
| | Gui::Selection().addSelection(
|
| | documentName.getValue().getString(),
|
| | objectName.getValue().getString(),
|
| | subElementName.getValue().getString(),
|
| | pt[0],
|
| | pt[1],
|
| | pt[2]
|
| | );
|
| |
|
| | if (mymode == OFF) {
|
| | snprintf(
|
| | buf,
|
| | 512,
|
| | "Selected: %s.%s.%s (%g, %g, %g)",
|
| | documentName.getValue().getString(),
|
| | objectName.getValue().getString(),
|
| | subElementName.getValue().getString(),
|
| | fabs(pt[0]) > 1e-7 ? pt[0] : 0.0,
|
| | fabs(pt[1]) > 1e-7 ? pt[1] : 0.0,
|
| | fabs(pt[2]) > 1e-7 ? pt[2] : 0.0
|
| | );
|
| |
|
| | getMainWindow()->showMessage(QString::fromLatin1(buf));
|
| | }
|
| | }
|
| | }
|
| | else {
|
| | if (!Gui::Selection().isSelected(
|
| | documentName.getValue().getString(),
|
| | objectName.getValue().getString(),
|
| | subElementName.getValue().getString()
|
| | )) {
|
| | Gui::Selection().clearSelection(documentName.getValue().getString());
|
| | Gui::Selection().addSelection(
|
| | documentName.getValue().getString(),
|
| | objectName.getValue().getString(),
|
| | subElementName.getValue().getString(),
|
| | pt[0],
|
| | pt[1],
|
| | pt[2]
|
| | );
|
| | }
|
| | else {
|
| | Gui::Selection().clearSelection(documentName.getValue().getString());
|
| | Gui::Selection().addSelection(
|
| | documentName.getValue().getString(),
|
| | objectName.getValue().getString(),
|
| | nullptr,
|
| | pt[0],
|
| | pt[1],
|
| | pt[2]
|
| | );
|
| | }
|
| |
|
| | if (mymode == OFF) {
|
| | snprintf(
|
| | buf,
|
| | 512,
|
| | "Selected: %s.%s.%s (%g, %g, %g)",
|
| | documentName.getValue().getString(),
|
| | objectName.getValue().getString(),
|
| | subElementName.getValue().getString(),
|
| | fabs(pt[0]) > 1e-7 ? pt[0] : 0.0,
|
| | fabs(pt[1]) > 1e-7 ? pt[1] : 0.0,
|
| | fabs(pt[2]) > 1e-7 ? pt[2] : 0.0
|
| | );
|
| |
|
| | getMainWindow()->showMessage(QString::fromLatin1(buf));
|
| | }
|
| | }
|
| |
|
| | action->setHandled();
|
| | }
|
| | }
|
| | }
|
| |
|
| | inherited::handleEvent(action);
|
| | }
|
| |
|
| |
|
| | void SoFCSelection::GLRenderBelowPath(SoGLRenderAction* action)
|
| | {
|
| | SoState* state = action->getState();
|
| | SelContextPtr ctx = Gui::SoFCSelectionRoot::getRenderContext<SelContext>(this, selContext);
|
| | if (selContext2->checkGlobal(ctx)) {
|
| | ctx = selContext2;
|
| | }
|
| | if (!useNewSelection.getValue() && selContext == ctx) {
|
| | ctx->selectionColor = this->colorSelection.getValue();
|
| | ctx->highlightColor = this->colorHighlight.getValue();
|
| | if (this->selected.getValue() == SELECTED) {
|
| | ctx->selectAll();
|
| | }
|
| | else {
|
| | ctx->selectionIndex.clear();
|
| | }
|
| | ctx->highlightIndex = this->highlighted ? 0 : -1;
|
| | }
|
| |
|
| |
|
| | if (this->setOverride(action, ctx)) {
|
| | inherited::GLRenderBelowPath(action);
|
| | state->pop();
|
| | }
|
| | else {
|
| | inherited::GLRenderBelowPath(action);
|
| | }
|
| | }
|
| |
|
| | void SoFCSelection::GLRender(SoGLRenderAction* action)
|
| | {
|
| | SoState* state = action->getState();
|
| | SelContextPtr ctx = Gui::SoFCSelectionRoot::getRenderContext<SelContext>(this, selContext);
|
| | if (selContext2->checkGlobal(ctx)) {
|
| | ctx = selContext2;
|
| | }
|
| | if (!useNewSelection.getValue() && selContext == ctx) {
|
| | ctx->selectionColor = this->colorSelection.getValue();
|
| | ctx->highlightColor = this->colorHighlight.getValue();
|
| | if (this->selected.getValue() == SELECTED) {
|
| | ctx->selectAll();
|
| | }
|
| | else {
|
| | ctx->selectionIndex.clear();
|
| | }
|
| | ctx->highlightIndex = this->highlighted ? 0 : -1;
|
| | }
|
| |
|
| |
|
| | if (this->setOverride(action, ctx)) {
|
| | inherited::GLRender(action);
|
| | state->pop();
|
| | }
|
| | else {
|
| | inherited::GLRender(action);
|
| | }
|
| | }
|
| |
|
| |
|
| | void SoFCSelection::GLRenderInPath(SoGLRenderAction* action)
|
| | {
|
| | SelContextPtr ctx = Gui::SoFCSelectionRoot::getRenderContext<SelContext>(this, selContext);
|
| | if (selContext2->checkGlobal(ctx)) {
|
| | ctx = selContext2;
|
| | }
|
| | if (!useNewSelection.getValue() && selContext == ctx) {
|
| | ctx->selectionColor = this->colorSelection.getValue();
|
| | ctx->highlightColor = this->colorHighlight.getValue();
|
| | if (this->selected.getValue() == SELECTED) {
|
| | ctx->selectAll();
|
| | }
|
| | else {
|
| | ctx->selectionIndex.clear();
|
| | }
|
| | ctx->highlightIndex = this->highlighted ? 0 : -1;
|
| | }
|
| |
|
| | SoState* state = action->getState();
|
| | if (this->setOverride(action, ctx)) {
|
| | inherited::GLRenderInPath(action);
|
| | state->pop();
|
| | }
|
| | else {
|
| | inherited::GLRenderInPath(action);
|
| | }
|
| | }
|
| |
|
| | SbBool SoFCSelection::preRender(SoGLRenderAction* action, GLint& oldDepthFunc)
|
| |
|
| |
|
| | {
|
| |
|
| | if (preselectionMode.getValue() == OFF) {
|
| | return false;
|
| | }
|
| |
|
| | SoState* state = action->getState();
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | SbBool drawHighlighted
|
| | = (preselectionMode.getValue() == ON || isHighlighted(action)
|
| | || selected.getValue() == SELECTED);
|
| |
|
| | if (drawHighlighted) {
|
| |
|
| | state->push();
|
| | SbColor col;
|
| | if (selected.getValue() == SELECTED) {
|
| | col = colorSelection.getValue();
|
| | }
|
| | else {
|
| | col = colorHighlight.getValue();
|
| | }
|
| |
|
| |
|
| | SoLazyElement::setEmissive(state, &col);
|
| | SoOverrideElement::setEmissiveColorOverride(state, this, true);
|
| |
|
| |
|
| | if (style.getValue() == EMISSIVE_DIFFUSE) {
|
| | SoLazyElement::setDiffuse(state, this, 1, &col, &colorpacker);
|
| | SoOverrideElement::setDiffuseColorOverride(state, this, true);
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | if (drawHighlighted || highlighted) {
|
| | glGetIntegerv(GL_DEPTH_FUNC, &oldDepthFunc);
|
| | if (oldDepthFunc != GL_LEQUAL) {
|
| | glDepthFunc(GL_LEQUAL);
|
| | }
|
| | }
|
| |
|
| | return drawHighlighted;
|
| | }
|
| |
|
| | |
| | |
| | |
| |
|
| | void SoFCSelection::redrawHighlighted(SoAction* action, SbBool doHighlight)
|
| | {
|
| | Q_UNUSED(action);
|
| | Q_UNUSED(doHighlight);
|
| | }
|
| |
|
| | SbBool SoFCSelection::readInstance(SoInput* in, unsigned short flags)
|
| | {
|
| |
|
| |
|
| | SbBool ret = inherited::readInstance(in, flags);
|
| | return ret;
|
| | }
|
| |
|
| |
|
| |
|
| | bool SoFCSelection::setOverride(SoGLRenderAction* action, SelContextPtr ctx)
|
| | {
|
| | auto mymode = static_cast<PreselectionModes>(this->preselectionMode.getValue());
|
| | bool preselected = ctx && ctx->isHighlighted() && (useNewSelection.getValue() || mymode == AUTO);
|
| | if (!preselected && mymode != ON && (!ctx || !ctx->isSelected())) {
|
| | return false;
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | auto oldId = this->uniqueId;
|
| | this->uniqueId ^= std::hash<void*>()(ctx.get()) + 0x9e3779b9 + (oldId << 6) + (oldId >> 2);
|
| |
|
| | auto mystyle = static_cast<Styles>(this->style.getValue());
|
| |
|
| | if (mystyle == SoFCSelection::BOX) {
|
| | if (ctx) {
|
| | SoFCSelectionRoot::renderBBox(
|
| | action,
|
| | this,
|
| | preselected ? ctx->highlightColor : ctx->selectionColor
|
| | );
|
| | }
|
| | this->uniqueId = oldId;
|
| | return false;
|
| | }
|
| |
|
| | SoState* state = action->getState();
|
| | state->push();
|
| |
|
| | SoMaterialBindingElement::set(state, SoMaterialBindingElement::OVERALL);
|
| | SoOverrideElement::setMaterialBindingOverride(state, this, true);
|
| |
|
| | if (!preselected && ctx) {
|
| | SoLazyElement::setEmissive(state, &ctx->selectionColor);
|
| | }
|
| | else if (ctx) {
|
| | SoLazyElement::setEmissive(state, &ctx->highlightColor);
|
| | }
|
| | SoOverrideElement::setEmissiveColorOverride(state, this, true);
|
| |
|
| | if (SoLazyElement::getLightModel(state) == SoLazyElement::BASE_COLOR
|
| | || mystyle == SoFCSelection::EMISSIVE_DIFFUSE) {
|
| | if (!preselected && ctx) {
|
| | SoLazyElement::setDiffuse(state, this, 1, &ctx->selectionColor, &colorpacker);
|
| | }
|
| | else if (ctx) {
|
| | SoLazyElement::setDiffuse(state, this, 1, &ctx->highlightColor, &colorpacker);
|
| | }
|
| | SoOverrideElement::setDiffuseColorOverride(state, this, true);
|
| | }
|
| |
|
| | this->uniqueId = oldId;
|
| | return true;
|
| | }
|
| |
|
| |
|
| | void SoFCSelection::turnoffcurrent(SoAction* action)
|
| | {
|
| | if (SoFCSelection::currenthighlight && SoFCSelection::currenthighlight->getLength()) {
|
| | SoNode* tail = SoFCSelection::currenthighlight->getTail();
|
| | if (tail->isOfType(SoFCSelection::getClassTypeId())) {
|
| | static_cast<SoFCSelection*>(tail)->highlighted = false;
|
| | static_cast<SoFCSelection*>(tail)->touch();
|
| | if (action) {
|
| | static_cast<SoFCSelection*>(tail)->redrawHighlighted(action, false);
|
| | }
|
| | }
|
| | }
|
| | if (SoFCSelection::currenthighlight) {
|
| | SoFCSelection::currenthighlight->unref();
|
| | SoFCSelection::currenthighlight = nullptr;
|
| | }
|
| | }
|
| |
|
| | SbBool SoFCSelection::isHighlighted(SoAction* action)
|
| |
|
| |
|
| | {
|
| | auto actionPath = static_cast<const SoFullPath*>(action->getCurPath());
|
| | return (
|
| | currenthighlight && currenthighlight->getTail() == actionPath->getTail() &&
|
| | *currenthighlight == *actionPath
|
| | );
|
| | }
|
| |
|
| | void SoFCSelection::applySettings()
|
| | {
|
| |
|
| |
|
| | float transparency;
|
| | ParameterGrp::handle hGrp = Gui::WindowParameter::getDefaultParameter()->GetGroup("View");
|
| | bool enablePre = hGrp->GetBool("EnablePreselection", true);
|
| | bool enableSel = hGrp->GetBool("EnableSelection", true);
|
| | if (!enablePre) {
|
| | this->preselectionMode = Gui::SoFCSelection::OFF;
|
| | }
|
| | else {
|
| |
|
| | SbColor highlightColor = this->colorHighlight.getValue();
|
| | auto highlight = (unsigned long)(highlightColor.getPackedValue());
|
| | highlight = hGrp->GetUnsigned("HighlightColor", highlight);
|
| | highlightColor.setPackedValue((uint32_t)highlight, transparency);
|
| | this->colorHighlight.setValue(highlightColor);
|
| | }
|
| | if (!enableSel) {
|
| | this->selectionMode = Gui::SoFCSelection::SEL_OFF;
|
| | }
|
| | else {
|
| |
|
| | SbColor selectionColor = this->colorSelection.getValue();
|
| | auto selection = (unsigned long)(selectionColor.getPackedValue());
|
| | selection = hGrp->GetUnsigned("SelectionColor", selection);
|
| | selectionColor.setPackedValue((uint32_t)selection, transparency);
|
| | this->colorSelection.setValue(selectionColor);
|
| | }
|
| | }
|
| |
|