// SPDX-License-Identifier: LGPL-2.1-or-later /*************************************************************************** * Copyright (c) 2005 Jürgen Riegel * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "SoFCSelectionAction.h" #include "SoFCSelection.h" using namespace Gui; SO_ACTION_SOURCE(SoFCPreselectionAction) /** * The order of the defined SO_ACTION_ADD_METHOD statements is very important. First the base * classes and afterwards subclasses of them must be listed, otherwise the registered methods * of subclasses will be overridden. For more details see the thread in the Coin3d forum * https://www.coin3d.org/pipermail/coin-discuss/2004-May/004346.html. * This means that \c SoSwitch must be listed after \c SoGroup and \c SoFCSelection after * \c SoSeparator because both classes inherits the others. */ void SoFCPreselectionAction::initClass() { SO_ACTION_INIT_CLASS(SoFCPreselectionAction, SoAction); SO_ENABLE(SoFCPreselectionAction, SoSwitchElement); SO_ACTION_ADD_METHOD(SoNode, nullAction); SO_ENABLE(SoFCPreselectionAction, SoModelMatrixElement); SO_ENABLE(SoFCPreselectionAction, SoShapeStyleElement); SO_ENABLE(SoFCPreselectionAction, SoComplexityElement); SO_ENABLE(SoFCPreselectionAction, SoComplexityTypeElement); SO_ENABLE(SoFCPreselectionAction, SoCoordinateElement); SO_ENABLE(SoFCPreselectionAction, SoFontNameElement); SO_ENABLE(SoFCPreselectionAction, SoFontSizeElement); SO_ENABLE(SoFCPreselectionAction, SoProfileCoordinateElement); SO_ENABLE(SoFCPreselectionAction, SoProfileElement); SO_ENABLE(SoFCPreselectionAction, SoSwitchElement); SO_ENABLE(SoFCPreselectionAction, SoUnitsElement); SO_ENABLE(SoFCPreselectionAction, SoViewVolumeElement); SO_ENABLE(SoFCPreselectionAction, SoViewingMatrixElement); SO_ENABLE(SoFCPreselectionAction, SoViewportRegionElement); SO_ACTION_ADD_METHOD(SoCallback, callDoAction); SO_ACTION_ADD_METHOD(SoComplexity, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate3, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate4, callDoAction); SO_ACTION_ADD_METHOD(SoFont, callDoAction); SO_ACTION_ADD_METHOD(SoGroup, callDoAction); SO_ACTION_ADD_METHOD(SoProfile, callDoAction); SO_ACTION_ADD_METHOD(SoProfileCoordinate2, callDoAction); SO_ACTION_ADD_METHOD(SoProfileCoordinate3, callDoAction); SO_ACTION_ADD_METHOD(SoTransformation, callDoAction); SO_ACTION_ADD_METHOD(SoSwitch, callDoAction); SO_ACTION_ADD_METHOD(SoSeparator, callDoAction); SO_ACTION_ADD_METHOD(SoFCSelection, callDoAction); SO_ACTION_ADD_METHOD(SoIndexedLineSet, callDoAction); SO_ACTION_ADD_METHOD(SoIndexedFaceSet, callDoAction); SO_ACTION_ADD_METHOD(SoPointSet, callDoAction); } void SoFCPreselectionAction::finish() { atexit_cleanup(); } SoFCPreselectionAction::SoFCPreselectionAction(const SelectionChanges& SelCh) : SelChange(SelCh) { SO_ACTION_CONSTRUCTOR(SoFCPreselectionAction); } SoFCPreselectionAction::~SoFCPreselectionAction() = default; void SoFCPreselectionAction::beginTraversal(SoNode* node) { traverse(node); } void SoFCPreselectionAction::callDoAction(SoAction* action, SoNode* node) { node->doAction(action); } // --------------------------------------------------------------- SO_ACTION_SOURCE(SoFCSelectionAction) /** * The order of the defined SO_ACTION_ADD_METHOD statements is very important. First the base * classes and afterwards subclasses of them must be listed, otherwise the registered methods * of subclasses will be overridden. For more details see the thread in the Coin3d forum * https://www.coin3d.org/pipermail/coin-discuss/2004-May/004346.html. * This means that \c SoSwitch must be listed after \c SoGroup and \c SoFCSelection after * \c SoSeparator because both classes inherits the others. */ void SoFCSelectionAction::initClass() { SO_ACTION_INIT_CLASS(SoFCSelectionAction, SoAction); SO_ENABLE(SoFCSelectionAction, SoSwitchElement); SO_ACTION_ADD_METHOD(SoNode, nullAction); SO_ENABLE(SoFCSelectionAction, SoModelMatrixElement); SO_ENABLE(SoFCSelectionAction, SoShapeStyleElement); SO_ENABLE(SoFCSelectionAction, SoComplexityElement); SO_ENABLE(SoFCSelectionAction, SoComplexityTypeElement); SO_ENABLE(SoFCSelectionAction, SoCoordinateElement); SO_ENABLE(SoFCSelectionAction, SoFontNameElement); SO_ENABLE(SoFCSelectionAction, SoFontSizeElement); SO_ENABLE(SoFCSelectionAction, SoProfileCoordinateElement); SO_ENABLE(SoFCSelectionAction, SoProfileElement); SO_ENABLE(SoFCSelectionAction, SoSwitchElement); SO_ENABLE(SoFCSelectionAction, SoUnitsElement); SO_ENABLE(SoFCSelectionAction, SoViewVolumeElement); SO_ENABLE(SoFCSelectionAction, SoViewingMatrixElement); SO_ENABLE(SoFCSelectionAction, SoViewportRegionElement); SO_ACTION_ADD_METHOD(SoCallback, callDoAction); SO_ACTION_ADD_METHOD(SoComplexity, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate3, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate4, callDoAction); SO_ACTION_ADD_METHOD(SoFont, callDoAction); SO_ACTION_ADD_METHOD(SoGroup, callDoAction); SO_ACTION_ADD_METHOD(SoProfile, callDoAction); SO_ACTION_ADD_METHOD(SoProfileCoordinate2, callDoAction); SO_ACTION_ADD_METHOD(SoProfileCoordinate3, callDoAction); SO_ACTION_ADD_METHOD(SoTransformation, callDoAction); SO_ACTION_ADD_METHOD(SoSwitch, callDoAction); SO_ACTION_ADD_METHOD(SoSeparator, callDoAction); SO_ACTION_ADD_METHOD(SoFCSelection, callDoAction); SO_ACTION_ADD_METHOD(SoIndexedLineSet, callDoAction); SO_ACTION_ADD_METHOD(SoIndexedFaceSet, callDoAction); SO_ACTION_ADD_METHOD(SoPointSet, callDoAction); } void SoFCSelectionAction::finish() { atexit_cleanup(); } SoFCSelectionAction::SoFCSelectionAction(const SelectionChanges& SelCh) : SelChange(SelCh) { SO_ACTION_CONSTRUCTOR(SoFCSelectionAction); } SoFCSelectionAction::~SoFCSelectionAction() = default; void SoFCSelectionAction::beginTraversal(SoNode* node) { traverse(node); } void SoFCSelectionAction::callDoAction(SoAction* action, SoNode* node) { node->doAction(action); } // --------------------------------------------------------------- SO_ACTION_SOURCE(SoFCEnableSelectionAction) /** * The order of the defined SO_ACTION_ADD_METHOD statements is very important. First the base * classes and afterwards subclasses of them must be listed, otherwise the registered methods * of subclasses will be overridden. For more details see the thread in the Coin3d forum * https://www.coin3d.org/pipermail/coin-discuss/2004-May/004346.html. * This means that \c SoSwitch must be listed after \c SoGroup and \c SoFCSelection after * \c SoSeparator because both classes inherits the others. */ void SoFCEnableSelectionAction::initClass() { SO_ACTION_INIT_CLASS(SoFCEnableSelectionAction, SoAction); SO_ENABLE(SoFCEnableSelectionAction, SoSwitchElement); SO_ACTION_ADD_METHOD(SoNode, nullAction); SO_ENABLE(SoFCEnableSelectionAction, SoModelMatrixElement); SO_ENABLE(SoFCEnableSelectionAction, SoShapeStyleElement); SO_ENABLE(SoFCEnableSelectionAction, SoComplexityElement); SO_ENABLE(SoFCEnableSelectionAction, SoComplexityTypeElement); SO_ENABLE(SoFCEnableSelectionAction, SoCoordinateElement); SO_ENABLE(SoFCEnableSelectionAction, SoFontNameElement); SO_ENABLE(SoFCEnableSelectionAction, SoFontSizeElement); SO_ENABLE(SoFCEnableSelectionAction, SoProfileCoordinateElement); SO_ENABLE(SoFCEnableSelectionAction, SoProfileElement); SO_ENABLE(SoFCEnableSelectionAction, SoSwitchElement); SO_ENABLE(SoFCEnableSelectionAction, SoUnitsElement); SO_ENABLE(SoFCEnableSelectionAction, SoViewVolumeElement); SO_ENABLE(SoFCEnableSelectionAction, SoViewingMatrixElement); SO_ENABLE(SoFCEnableSelectionAction, SoViewportRegionElement); SO_ACTION_ADD_METHOD(SoCallback, callDoAction); SO_ACTION_ADD_METHOD(SoComplexity, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate3, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate4, callDoAction); SO_ACTION_ADD_METHOD(SoFont, callDoAction); SO_ACTION_ADD_METHOD(SoGroup, callDoAction); SO_ACTION_ADD_METHOD(SoProfile, callDoAction); SO_ACTION_ADD_METHOD(SoProfileCoordinate2, callDoAction); SO_ACTION_ADD_METHOD(SoProfileCoordinate3, callDoAction); SO_ACTION_ADD_METHOD(SoTransformation, callDoAction); SO_ACTION_ADD_METHOD(SoSwitch, callDoAction); SO_ACTION_ADD_METHOD(SoSeparator, callDoAction); SO_ACTION_ADD_METHOD(SoFCSelection, callDoAction); } void SoFCEnableSelectionAction::finish() { atexit_cleanup(); } SoFCEnableSelectionAction::SoFCEnableSelectionAction(const SbBool& sel) : enabled(sel) { SO_ACTION_CONSTRUCTOR(SoFCEnableSelectionAction); } SoFCEnableSelectionAction::~SoFCEnableSelectionAction() = default; void SoFCEnableSelectionAction::beginTraversal(SoNode* node) { traverse(node); } void SoFCEnableSelectionAction::callDoAction(SoAction* action, SoNode* node) { node->doAction(action); } // --------------------------------------------------------------- SO_ACTION_SOURCE(SoFCEnablePreselectionAction) /** * The order of the defined SO_ACTION_ADD_METHOD statements is very important. First the base * classes and afterwards subclasses of them must be listed, otherwise the registered methods * of subclasses will be overridden. For more details see the thread in the Coin3d forum * https://www.coin3d.org/pipermail/coin-discuss/2004-May/004346.html. * This means that \c SoSwitch must be listed after \c SoGroup and \c SoFCSelection after * \c SoSeparator because both classes inherits the others. */ void SoFCEnablePreselectionAction::initClass() { SO_ACTION_INIT_CLASS(SoFCEnablePreselectionAction, SoAction); SO_ENABLE(SoFCEnablePreselectionAction, SoSwitchElement); SO_ACTION_ADD_METHOD(SoNode, nullAction); SO_ENABLE(SoFCEnablePreselectionAction, SoModelMatrixElement); SO_ENABLE(SoFCEnablePreselectionAction, SoShapeStyleElement); SO_ENABLE(SoFCEnablePreselectionAction, SoComplexityElement); SO_ENABLE(SoFCEnablePreselectionAction, SoComplexityTypeElement); SO_ENABLE(SoFCEnablePreselectionAction, SoCoordinateElement); SO_ENABLE(SoFCEnablePreselectionAction, SoFontNameElement); SO_ENABLE(SoFCEnablePreselectionAction, SoFontSizeElement); SO_ENABLE(SoFCEnablePreselectionAction, SoProfileCoordinateElement); SO_ENABLE(SoFCEnablePreselectionAction, SoProfileElement); SO_ENABLE(SoFCEnablePreselectionAction, SoSwitchElement); SO_ENABLE(SoFCEnablePreselectionAction, SoUnitsElement); SO_ENABLE(SoFCEnablePreselectionAction, SoViewVolumeElement); SO_ENABLE(SoFCEnablePreselectionAction, SoViewingMatrixElement); SO_ENABLE(SoFCEnablePreselectionAction, SoViewportRegionElement); SO_ACTION_ADD_METHOD(SoCallback, callDoAction); SO_ACTION_ADD_METHOD(SoComplexity, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate3, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate4, callDoAction); SO_ACTION_ADD_METHOD(SoFont, callDoAction); SO_ACTION_ADD_METHOD(SoGroup, callDoAction); SO_ACTION_ADD_METHOD(SoProfile, callDoAction); SO_ACTION_ADD_METHOD(SoProfileCoordinate2, callDoAction); SO_ACTION_ADD_METHOD(SoProfileCoordinate3, callDoAction); SO_ACTION_ADD_METHOD(SoTransformation, callDoAction); SO_ACTION_ADD_METHOD(SoSwitch, callDoAction); SO_ACTION_ADD_METHOD(SoSeparator, callDoAction); SO_ACTION_ADD_METHOD(SoFCSelection, callDoAction); } void SoFCEnablePreselectionAction::finish() { atexit_cleanup(); } SoFCEnablePreselectionAction::SoFCEnablePreselectionAction(const SbBool& sel) : enabled(sel) { SO_ACTION_CONSTRUCTOR(SoFCEnablePreselectionAction); } SoFCEnablePreselectionAction::~SoFCEnablePreselectionAction() = default; void SoFCEnablePreselectionAction::beginTraversal(SoNode* node) { traverse(node); } void SoFCEnablePreselectionAction::callDoAction(SoAction* action, SoNode* node) { node->doAction(action); } // --------------------------------------------------------------- SO_ACTION_SOURCE(SoFCSelectionColorAction) /** * The order of the defined SO_ACTION_ADD_METHOD statements is very important. First the base * classes and afterwards subclasses of them must be listed, otherwise the registered methods * of subclasses will be overridden. For more details see the thread in the Coin3d forum * https://www.coin3d.org/pipermail/coin-discuss/2004-May/004346.html. * This means that \c SoSwitch must be listed after \c SoGroup and \c SoFCSelection after * \c SoSeparator because both classes inherits the others. */ void SoFCSelectionColorAction::initClass() { SO_ACTION_INIT_CLASS(SoFCSelectionColorAction, SoAction); SO_ENABLE(SoFCSelectionColorAction, SoSwitchElement); SO_ACTION_ADD_METHOD(SoNode, nullAction); SO_ENABLE(SoFCSelectionColorAction, SoModelMatrixElement); SO_ENABLE(SoFCSelectionColorAction, SoShapeStyleElement); SO_ENABLE(SoFCSelectionColorAction, SoComplexityElement); SO_ENABLE(SoFCSelectionColorAction, SoComplexityTypeElement); SO_ENABLE(SoFCSelectionColorAction, SoCoordinateElement); SO_ENABLE(SoFCSelectionColorAction, SoFontNameElement); SO_ENABLE(SoFCSelectionColorAction, SoFontSizeElement); SO_ENABLE(SoFCSelectionColorAction, SoProfileCoordinateElement); SO_ENABLE(SoFCSelectionColorAction, SoProfileElement); SO_ENABLE(SoFCSelectionColorAction, SoSwitchElement); SO_ENABLE(SoFCSelectionColorAction, SoUnitsElement); SO_ENABLE(SoFCSelectionColorAction, SoViewVolumeElement); SO_ENABLE(SoFCSelectionColorAction, SoViewingMatrixElement); SO_ENABLE(SoFCSelectionColorAction, SoViewportRegionElement); SO_ACTION_ADD_METHOD(SoCallback, callDoAction); SO_ACTION_ADD_METHOD(SoComplexity, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate3, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate4, callDoAction); SO_ACTION_ADD_METHOD(SoFont, callDoAction); SO_ACTION_ADD_METHOD(SoGroup, callDoAction); SO_ACTION_ADD_METHOD(SoProfile, callDoAction); SO_ACTION_ADD_METHOD(SoProfileCoordinate2, callDoAction); SO_ACTION_ADD_METHOD(SoProfileCoordinate3, callDoAction); SO_ACTION_ADD_METHOD(SoTransformation, callDoAction); SO_ACTION_ADD_METHOD(SoSwitch, callDoAction); SO_ACTION_ADD_METHOD(SoSeparator, callDoAction); SO_ACTION_ADD_METHOD(SoFCSelection, callDoAction); } void SoFCSelectionColorAction::finish() { atexit_cleanup(); } SoFCSelectionColorAction::SoFCSelectionColorAction(const SoSFColor& col) : selectionColor(col) { SO_ACTION_CONSTRUCTOR(SoFCSelectionColorAction); } SoFCSelectionColorAction::~SoFCSelectionColorAction() = default; void SoFCSelectionColorAction::beginTraversal(SoNode* node) { traverse(node); } void SoFCSelectionColorAction::callDoAction(SoAction* action, SoNode* node) { node->doAction(action); } // --------------------------------------------------------------- SO_ACTION_SOURCE(SoFCHighlightColorAction) /** * The order of the defined SO_ACTION_ADD_METHOD statements is very important. First the base * classes and afterwards subclasses of them must be listed, otherwise the registered methods * of subclasses will be overridden. For more details see the thread in the Coin3d forum * https://www.coin3d.org/pipermail/coin-discuss/2004-May/004346.html. * This means that \c SoSwitch must be listed after \c SoGroup and \c SoFCSelection after * \c SoSeparator because both classes inherits the others. */ void SoFCHighlightColorAction::initClass() { SO_ACTION_INIT_CLASS(SoFCHighlightColorAction, SoAction); SO_ENABLE(SoFCHighlightColorAction, SoSwitchElement); SO_ACTION_ADD_METHOD(SoNode, nullAction); SO_ENABLE(SoFCHighlightColorAction, SoModelMatrixElement); SO_ENABLE(SoFCHighlightColorAction, SoShapeStyleElement); SO_ENABLE(SoFCHighlightColorAction, SoComplexityElement); SO_ENABLE(SoFCHighlightColorAction, SoComplexityTypeElement); SO_ENABLE(SoFCHighlightColorAction, SoCoordinateElement); SO_ENABLE(SoFCHighlightColorAction, SoFontNameElement); SO_ENABLE(SoFCHighlightColorAction, SoFontSizeElement); SO_ENABLE(SoFCHighlightColorAction, SoProfileCoordinateElement); SO_ENABLE(SoFCHighlightColorAction, SoProfileElement); SO_ENABLE(SoFCHighlightColorAction, SoSwitchElement); SO_ENABLE(SoFCHighlightColorAction, SoUnitsElement); SO_ENABLE(SoFCHighlightColorAction, SoViewVolumeElement); SO_ENABLE(SoFCHighlightColorAction, SoViewingMatrixElement); SO_ENABLE(SoFCHighlightColorAction, SoViewportRegionElement); SO_ACTION_ADD_METHOD(SoCallback, callDoAction); SO_ACTION_ADD_METHOD(SoComplexity, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate3, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate4, callDoAction); SO_ACTION_ADD_METHOD(SoFont, callDoAction); SO_ACTION_ADD_METHOD(SoGroup, callDoAction); SO_ACTION_ADD_METHOD(SoProfile, callDoAction); SO_ACTION_ADD_METHOD(SoProfileCoordinate2, callDoAction); SO_ACTION_ADD_METHOD(SoProfileCoordinate3, callDoAction); SO_ACTION_ADD_METHOD(SoTransformation, callDoAction); SO_ACTION_ADD_METHOD(SoSwitch, callDoAction); SO_ACTION_ADD_METHOD(SoSeparator, callDoAction); SO_ACTION_ADD_METHOD(SoFCSelection, callDoAction); } void SoFCHighlightColorAction::finish() { atexit_cleanup(); } SoFCHighlightColorAction::SoFCHighlightColorAction(const SoSFColor& col) : highlightColor(col) { SO_ACTION_CONSTRUCTOR(SoFCHighlightColorAction); } SoFCHighlightColorAction::~SoFCHighlightColorAction() = default; void SoFCHighlightColorAction::beginTraversal(SoNode* node) { traverse(node); } void SoFCHighlightColorAction::callDoAction(SoAction* action, SoNode* node) { node->doAction(action); } // --------------------------------------------------------------- SO_ACTION_SOURCE(SoFCDocumentAction) /** * The order of the defined SO_ACTION_ADD_METHOD statements is very important. First the base * classes and afterwards subclasses of them must be listed, otherwise the registered methods * of subclasses will be overridden. For more details see the thread in the Coin3d forum * https://www.coin3d.org/pipermail/coin-discuss/2004-May/004346.html. * This means that \c SoSwitch must be listed after \c SoGroup and \c SoFCSelection after * \c SoSeparator because both classes inherits the others. */ void SoFCDocumentAction::initClass() { SO_ACTION_INIT_CLASS(SoFCDocumentAction, SoAction); SO_ENABLE(SoFCDocumentAction, SoSwitchElement); SO_ACTION_ADD_METHOD(SoNode, nullAction); SO_ENABLE(SoFCDocumentAction, SoModelMatrixElement); SO_ENABLE(SoFCDocumentAction, SoShapeStyleElement); SO_ENABLE(SoFCDocumentAction, SoComplexityElement); SO_ENABLE(SoFCDocumentAction, SoComplexityTypeElement); SO_ENABLE(SoFCDocumentAction, SoCoordinateElement); SO_ENABLE(SoFCDocumentAction, SoFontNameElement); SO_ENABLE(SoFCDocumentAction, SoFontSizeElement); SO_ENABLE(SoFCDocumentAction, SoProfileCoordinateElement); SO_ENABLE(SoFCDocumentAction, SoProfileElement); SO_ENABLE(SoFCDocumentAction, SoSwitchElement); SO_ENABLE(SoFCDocumentAction, SoUnitsElement); SO_ENABLE(SoFCDocumentAction, SoViewVolumeElement); SO_ENABLE(SoFCDocumentAction, SoViewingMatrixElement); SO_ENABLE(SoFCDocumentAction, SoViewportRegionElement); SO_ACTION_ADD_METHOD(SoCallback, callDoAction); SO_ACTION_ADD_METHOD(SoComplexity, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate3, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate4, callDoAction); SO_ACTION_ADD_METHOD(SoFont, callDoAction); SO_ACTION_ADD_METHOD(SoGroup, callDoAction); SO_ACTION_ADD_METHOD(SoProfile, callDoAction); SO_ACTION_ADD_METHOD(SoProfileCoordinate2, callDoAction); SO_ACTION_ADD_METHOD(SoProfileCoordinate3, callDoAction); SO_ACTION_ADD_METHOD(SoTransformation, callDoAction); SO_ACTION_ADD_METHOD(SoSwitch, callDoAction); SO_ACTION_ADD_METHOD(SoSeparator, callDoAction); SO_ACTION_ADD_METHOD(SoFCSelection, callDoAction); } void SoFCDocumentAction::finish() { atexit_cleanup(); } SoFCDocumentAction::SoFCDocumentAction(const SoSFString& docName) : documentName(docName) { SO_ACTION_CONSTRUCTOR(SoFCDocumentAction); } SoFCDocumentAction::~SoFCDocumentAction() = default; void SoFCDocumentAction::beginTraversal(SoNode* node) { traverse(node); } void SoFCDocumentAction::callDoAction(SoAction* action, SoNode* node) { node->doAction(action); } // --------------------------------------------------------------- SO_ACTION_SOURCE(SoFCDocumentObjectAction) /** * The order of the defined SO_ACTION_ADD_METHOD statements is very important. First the base * classes and afterwards subclasses of them must be listed, otherwise the registered methods * of subclasses will be overridden. For more details see the thread in the Coin3d forum * https://www.coin3d.org/pipermail/coin-discuss/2004-May/004346.html. * This means that \c SoSwitch must be listed after \c SoGroup and \c SoFCSelection after * \c SoSeparator because both classes inherits the others. */ void SoFCDocumentObjectAction::initClass() { SO_ACTION_INIT_CLASS(SoFCDocumentObjectAction, SoAction); SO_ENABLE(SoFCDocumentObjectAction, SoSwitchElement); SO_ACTION_ADD_METHOD(SoNode, nullAction); SO_ENABLE(SoFCDocumentObjectAction, SoModelMatrixElement); SO_ENABLE(SoFCDocumentObjectAction, SoShapeStyleElement); SO_ENABLE(SoFCDocumentObjectAction, SoComplexityElement); SO_ENABLE(SoFCDocumentObjectAction, SoComplexityTypeElement); SO_ENABLE(SoFCDocumentObjectAction, SoCoordinateElement); SO_ENABLE(SoFCDocumentObjectAction, SoFontNameElement); SO_ENABLE(SoFCDocumentObjectAction, SoFontSizeElement); SO_ENABLE(SoFCDocumentObjectAction, SoProfileCoordinateElement); SO_ENABLE(SoFCDocumentObjectAction, SoProfileElement); SO_ENABLE(SoFCDocumentObjectAction, SoSwitchElement); SO_ENABLE(SoFCDocumentObjectAction, SoUnitsElement); SO_ENABLE(SoFCDocumentObjectAction, SoViewVolumeElement); SO_ENABLE(SoFCDocumentObjectAction, SoViewingMatrixElement); SO_ENABLE(SoFCDocumentObjectAction, SoViewportRegionElement); SO_ACTION_ADD_METHOD(SoCallback, callDoAction); SO_ACTION_ADD_METHOD(SoComplexity, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate3, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate4, callDoAction); SO_ACTION_ADD_METHOD(SoFont, callDoAction); SO_ACTION_ADD_METHOD(SoGroup, callDoAction); SO_ACTION_ADD_METHOD(SoProfile, callDoAction); SO_ACTION_ADD_METHOD(SoProfileCoordinate2, callDoAction); SO_ACTION_ADD_METHOD(SoProfileCoordinate3, callDoAction); SO_ACTION_ADD_METHOD(SoTransformation, callDoAction); SO_ACTION_ADD_METHOD(SoSwitch, callDoAction); SO_ACTION_ADD_METHOD(SoSeparator, callDoAction); SO_ACTION_ADD_METHOD(SoFCSelection, callDoAction); } void SoFCDocumentObjectAction::finish() { atexit_cleanup(); } SoFCDocumentObjectAction::SoFCDocumentObjectAction() { SO_ACTION_CONSTRUCTOR(SoFCDocumentObjectAction); } SoFCDocumentObjectAction::~SoFCDocumentObjectAction() = default; void SoFCDocumentObjectAction::beginTraversal(SoNode* node) { traverse(node); } void SoFCDocumentObjectAction::callDoAction(SoAction* action, SoNode* node) { node->doAction(action); } void SoFCDocumentObjectAction::setHandled() { this->_handled = true; } SbBool SoFCDocumentObjectAction::isHandled() const { return this->_handled; } // --------------------------------------------------------------- SO_ACTION_SOURCE(SoGLSelectAction) /** * The order of the defined SO_ACTION_ADD_METHOD statements is very important. First the base * classes and afterwards subclasses of them must be listed, otherwise the registered methods * of subclasses will be overridden. For more details see the thread in the Coin3d forum * https://www.coin3d.org/pipermail/coin-discuss/2004-May/004346.html. * This means that \c SoSwitch must be listed after \c SoGroup and \c SoFCSelection after * \c SoSeparator because both classes inherits the others. */ void SoGLSelectAction::initClass() { SO_ACTION_INIT_CLASS(SoGLSelectAction, SoAction); SO_ENABLE(SoGLSelectAction, SoSwitchElement); SO_ACTION_ADD_METHOD(SoNode, nullAction); SO_ENABLE(SoGLSelectAction, SoModelMatrixElement); SO_ENABLE(SoGLSelectAction, SoProjectionMatrixElement); SO_ENABLE(SoGLSelectAction, SoCoordinateElement); SO_ENABLE(SoGLSelectAction, SoViewVolumeElement); SO_ENABLE(SoGLSelectAction, SoViewingMatrixElement); SO_ENABLE(SoGLSelectAction, SoViewportRegionElement); SO_ACTION_ADD_METHOD(SoCamera, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate3, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate4, callDoAction); SO_ACTION_ADD_METHOD(SoGroup, callDoAction); SO_ACTION_ADD_METHOD(SoSwitch, callDoAction); SO_ACTION_ADD_METHOD(SoShape, callDoAction); SO_ACTION_ADD_METHOD(SoIndexedFaceSet, callDoAction); SO_ACTION_ADD_METHOD(SoSeparator, callDoAction); SO_ACTION_ADD_METHOD(SoFCSelection, callDoAction); } SoGLSelectAction::SoGLSelectAction(const SbViewportRegion& region, const SbViewportRegion& select) : vpregion(region) , vpselect(select) { SO_ACTION_CONSTRUCTOR(SoGLSelectAction); } SoGLSelectAction::~SoGLSelectAction() = default; const SbViewportRegion& SoGLSelectAction::getViewportRegion() const { return this->vpselect; } void SoGLSelectAction::beginTraversal(SoNode* node) { SoViewportRegionElement::set(this->getState(), this->vpregion); traverse(node); } void SoGLSelectAction::callDoAction(SoAction* action, SoNode* node) { node->doAction(action); } void SoGLSelectAction::setHandled() { this->_handled = true; } SbBool SoGLSelectAction::isHandled() const { return this->_handled; } // --------------------------------------------------------------- SO_ACTION_SOURCE(SoVisibleFaceAction) /** * The order of the defined SO_ACTION_ADD_METHOD statements is very important. First the base * classes and afterwards subclasses of them must be listed, otherwise the registered methods * of subclasses will be overridden. For more details see the thread in the Coin3d forum * https://www.coin3d.org/pipermail/coin-discuss/2004-May/004346.html. * This means that \c SoSwitch must be listed after \c SoGroup and \c SoFCSelection after * \c SoSeparator because both classes inherits the others. */ void SoVisibleFaceAction::initClass() { SO_ACTION_INIT_CLASS(SoVisibleFaceAction, SoAction); SO_ENABLE(SoVisibleFaceAction, SoSwitchElement); SO_ACTION_ADD_METHOD(SoNode, nullAction); SO_ENABLE(SoVisibleFaceAction, SoModelMatrixElement); SO_ENABLE(SoVisibleFaceAction, SoProjectionMatrixElement); SO_ENABLE(SoVisibleFaceAction, SoCoordinateElement); SO_ENABLE(SoVisibleFaceAction, SoViewVolumeElement); SO_ENABLE(SoVisibleFaceAction, SoViewingMatrixElement); SO_ENABLE(SoVisibleFaceAction, SoViewportRegionElement); SO_ACTION_ADD_METHOD(SoCamera, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate3, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate4, callDoAction); SO_ACTION_ADD_METHOD(SoGroup, callDoAction); SO_ACTION_ADD_METHOD(SoSwitch, callDoAction); SO_ACTION_ADD_METHOD(SoShape, callDoAction); SO_ACTION_ADD_METHOD(SoIndexedFaceSet, callDoAction); SO_ACTION_ADD_METHOD(SoSeparator, callDoAction); SO_ACTION_ADD_METHOD(SoFCSelection, callDoAction); } SoVisibleFaceAction::SoVisibleFaceAction() { SO_ACTION_CONSTRUCTOR(SoVisibleFaceAction); } SoVisibleFaceAction::~SoVisibleFaceAction() = default; void SoVisibleFaceAction::beginTraversal(SoNode* node) { traverse(node); } void SoVisibleFaceAction::callDoAction(SoAction* action, SoNode* node) { node->doAction(action); } void SoVisibleFaceAction::setHandled() { this->_handled = true; } SbBool SoVisibleFaceAction::isHandled() const { return this->_handled; } // --------------------------------------------------------------- SO_ACTION_SOURCE(SoUpdateVBOAction) /** * The order of the defined SO_ACTION_ADD_METHOD statements is very important. First the base * classes and afterwards subclasses of them must be listed, otherwise the registered methods * of subclasses will be overridden. For more details see the thread in the Coin3d forum * https://www.coin3d.org/pipermail/coin-discuss/2004-May/004346.html. * This means that \c SoSwitch must be listed after \c SoGroup and \c SoFCSelection after * \c SoSeparator because both classes inherits the others. */ void SoUpdateVBOAction::initClass() { SO_ACTION_INIT_CLASS(SoUpdateVBOAction, SoAction); SO_ENABLE(SoUpdateVBOAction, SoSwitchElement); SO_ACTION_ADD_METHOD(SoNode, nullAction); SO_ENABLE(SoUpdateVBOAction, SoModelMatrixElement); SO_ENABLE(SoUpdateVBOAction, SoProjectionMatrixElement); SO_ENABLE(SoUpdateVBOAction, SoCoordinateElement); SO_ENABLE(SoUpdateVBOAction, SoViewVolumeElement); SO_ENABLE(SoUpdateVBOAction, SoViewingMatrixElement); SO_ENABLE(SoUpdateVBOAction, SoViewportRegionElement); SO_ACTION_ADD_METHOD(SoCamera, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate3, callDoAction); SO_ACTION_ADD_METHOD(SoCoordinate4, callDoAction); SO_ACTION_ADD_METHOD(SoGroup, callDoAction); SO_ACTION_ADD_METHOD(SoSwitch, callDoAction); SO_ACTION_ADD_METHOD(SoShape, callDoAction); SO_ACTION_ADD_METHOD(SoIndexedFaceSet, callDoAction); SO_ACTION_ADD_METHOD(SoSeparator, callDoAction); SO_ACTION_ADD_METHOD(SoFCSelection, callDoAction); } SoUpdateVBOAction::SoUpdateVBOAction() { SO_ACTION_CONSTRUCTOR(SoUpdateVBOAction); } SoUpdateVBOAction::~SoUpdateVBOAction() = default; void SoUpdateVBOAction::finish() { atexit_cleanup(); } void SoUpdateVBOAction::beginTraversal(SoNode* node) { traverse(node); } void SoUpdateVBOAction::callDoAction(SoAction* action, SoNode* node) { node->doAction(action); } // --------------------------------------------------------------- namespace Gui { class SoBoxSelectionRenderActionP { public: SoBoxSelectionRenderActionP(SoBoxSelectionRenderAction* master) : master(master) {} SoBoxSelectionRenderAction* master; SoSearchAction* searchaction {nullptr}; SoSearchAction* selectsearch {nullptr}; SoSearchAction* camerasearch {nullptr}; SoGetBoundingBoxAction* bboxaction {nullptr}; SoBaseColor* basecolor {nullptr}; SoTempPath* postprocpath {nullptr}; SoPath* highlightPath {nullptr}; SoSeparator* localRoot {nullptr}; SoMatrixTransform* xform {nullptr}; SoCube* cube {nullptr}; SoDrawStyle* drawstyle {nullptr}; SoColorPacker colorpacker; void initBoxGraph(); void updateBbox(const SoPath* path); }; } // namespace Gui #undef PRIVATE #define PRIVATE(p) ((p)->pimpl) #undef PUBLIC #define PUBLIC(p) ((p)->master) // used to initialize the internal storage class with variables void SoBoxSelectionRenderActionP::initBoxGraph() { this->localRoot = new SoSeparator; this->localRoot->ref(); this->localRoot->renderCaching = SoSeparator::OFF; this->localRoot->boundingBoxCaching = SoSeparator::OFF; this->xform = new SoMatrixTransform; this->cube = new SoCube; this->drawstyle = new SoDrawStyle; this->drawstyle->style = SoDrawStyleElement::LINES; this->basecolor = new SoBaseColor; auto lightmodel = new SoLightModel; lightmodel->model = SoLightModel::BASE_COLOR; auto complexity = new SoComplexity; complexity->textureQuality = 0.0f; complexity->type = SoComplexityTypeElement::BOUNDING_BOX; this->localRoot->addChild(this->drawstyle); this->localRoot->addChild(this->basecolor); this->localRoot->addChild(lightmodel); this->localRoot->addChild(complexity); this->localRoot->addChild(this->xform); this->localRoot->addChild(this->cube); } // used to render shape and non-shape nodes (usually SoGroup or SoSeparator). void SoBoxSelectionRenderActionP::updateBbox(const SoPath* path) { if (!this->camerasearch) { this->camerasearch = new SoSearchAction; } // find camera used to render node this->camerasearch->setFind(SoSearchAction::TYPE); this->camerasearch->setInterest(SoSearchAction::LAST); this->camerasearch->setType(SoCamera::getClassTypeId()); this->camerasearch->apply(const_cast(path)); if (!this->camerasearch->getPath()) { // if there is no camera there is no point rendering the bbox return; } this->localRoot->insertChild(this->camerasearch->getPath()->getTail(), 0); this->camerasearch->reset(); if (!this->bboxaction) { this->bboxaction = new SoGetBoundingBoxAction(SbViewportRegion(100, 100)); } this->bboxaction->setViewportRegion(PUBLIC(this)->getViewportRegion()); this->bboxaction->apply(const_cast(path)); SbXfBox3f& box = this->bboxaction->getXfBoundingBox(); if (!box.isEmpty()) { // set cube size float x, y, z; box.getSize(x, y, z); this->cube->width = x; this->cube->height = y; this->cube->depth = z; SbMatrix transform = box.getTransform(); // clazy:exclude=rule-of-two-soft // get center (in the local bbox coordinate system) SbVec3f center = box.SbBox3f::getCenter(); // if center != (0,0,0), move the cube if (center != SbVec3f(0.0f, 0.0f, 0.0f)) { SbMatrix t; t.setTranslate(center); transform.multLeft(t); } this->xform->matrix = transform; PUBLIC(this)->SoGLRenderAction::apply(this->localRoot); } // remove camera this->localRoot->removeChild(0); } SO_ACTION_SOURCE(SoBoxSelectionRenderAction) // Overridden from parent class. void SoBoxSelectionRenderAction::initClass() { SO_ACTION_INIT_CLASS(SoBoxSelectionRenderAction, SoGLRenderAction); } SoBoxSelectionRenderAction::SoBoxSelectionRenderAction() : inherited(SbViewportRegion()) { this->constructorCommon(); } SoBoxSelectionRenderAction::SoBoxSelectionRenderAction(const SbViewportRegion& viewportregion) : inherited(viewportregion) { this->constructorCommon(); } // // private. called by both constructors // void SoBoxSelectionRenderAction::constructorCommon() { SO_ACTION_CONSTRUCTOR(SoBoxSelectionRenderAction); PRIVATE(this) = new SoBoxSelectionRenderActionP(this); // Initialize local variables PRIVATE(this)->initBoxGraph(); this->hlVisible = false; PRIVATE(this)->basecolor->rgb.setValue(1.0f, 0.0f, 0.0f); PRIVATE(this)->drawstyle->linePattern = 0xffff; PRIVATE(this)->drawstyle->lineWidth = 1.0f; PRIVATE(this)->searchaction = nullptr; PRIVATE(this)->selectsearch = nullptr; PRIVATE(this)->camerasearch = nullptr; PRIVATE(this)->bboxaction = nullptr; // SoBase-derived objects should be dynamically allocated. PRIVATE(this)->postprocpath = new SoTempPath(32); PRIVATE(this)->postprocpath->ref(); PRIVATE(this)->highlightPath = nullptr; } SoBoxSelectionRenderAction::~SoBoxSelectionRenderAction() { // clear highlighting node if (PRIVATE(this)->highlightPath) { PRIVATE(this)->highlightPath->unref(); } PRIVATE(this)->postprocpath->unref(); PRIVATE(this)->localRoot->unref(); delete PRIVATE(this)->searchaction; delete PRIVATE(this)->selectsearch; delete PRIVATE(this)->camerasearch; delete PRIVATE(this)->bboxaction; delete PRIVATE(this); } void SoBoxSelectionRenderAction::apply(SoNode* node) { SoGLRenderAction::apply(node); if (this->hlVisible) { if (!PRIVATE(this)->searchaction) { PRIVATE(this)->searchaction = new SoSearchAction; } PRIVATE(this)->searchaction->setType(SoFCSelection::getClassTypeId()); PRIVATE(this)->searchaction->setInterest(SoSearchAction::ALL); PRIVATE(this)->searchaction->apply(node); const SoPathList& pathlist = PRIVATE(this)->searchaction->getPaths(); if (pathlist.getLength() > 0) { for (int i = 0; i < pathlist.getLength(); i++) { SoPath* path = pathlist[i]; assert(path); auto selection = static_cast(path->getTail()); assert(selection->getTypeId().isDerivedFrom(SoFCSelection::getClassTypeId())); if (selection->selected.getValue() && selection->style.getValue() == SoFCSelection::BOX) { PRIVATE(this)->basecolor->rgb.setValue(selection->colorSelection.getValue()); if (!PRIVATE(this)->selectsearch) { PRIVATE(this)->selectsearch = new SoSearchAction; } PRIVATE(this)->selectsearch->setType(SoShape::getClassTypeId()); PRIVATE(this)->selectsearch->setInterest(SoSearchAction::FIRST); PRIVATE(this)->selectsearch->apply(selection); SoPath* shapepath = PRIVATE(this)->selectsearch->getPath(); if (shapepath) { SoPathList list; list.append(shapepath); this->drawBoxes(path, &list); } PRIVATE(this)->selectsearch->reset(); } else if (selection->isHighlighted() && selection->selected.getValue() == SoFCSelection::NOTSELECTED && selection->style.getValue() == SoFCSelection::BOX) { PRIVATE(this)->basecolor->rgb.setValue(selection->colorHighlight.getValue()); if (!PRIVATE(this)->selectsearch) { PRIVATE(this)->selectsearch = new SoSearchAction; } PRIVATE(this)->selectsearch->setType(SoShape::getClassTypeId()); PRIVATE(this)->selectsearch->setInterest(SoSearchAction::FIRST); PRIVATE(this)->selectsearch->apply(selection); SoPath* shapepath = PRIVATE(this)->selectsearch->getPath(); if (shapepath) { SoPathList list; list.append(shapepath); // clear old highlighting node if still active if (PRIVATE(this)->highlightPath) { PRIVATE(this)->highlightPath->unref(); } PRIVATE(this)->highlightPath = path; PRIVATE(this)->highlightPath->ref(); this->drawBoxes(path, &list); } PRIVATE(this)->selectsearch->reset(); } } } PRIVATE(this)->searchaction->reset(); } } void SoBoxSelectionRenderAction::apply(SoPath* path) { SoGLRenderAction::apply(path); SoNode* node = path->getTail(); if (node && node->getTypeId() == SoFCSelection::getClassTypeId()) { auto selection = static_cast(node); // This happens when dehighlighting the current shape if (PRIVATE(this)->highlightPath == path) { PRIVATE(this)->highlightPath->unref(); PRIVATE(this)->highlightPath = nullptr; // FIXME: Doing a redraw to remove the shown bounding box causes // some problems when moving the mouse from one shape to another // because this will destroy the box immediately selection->touch(); // force a redraw when dehighlighting } else if (selection->isHighlighted() && selection->selected.getValue() == SoFCSelection::NOTSELECTED && selection->style.getValue() == SoFCSelection::BOX) { PRIVATE(this)->basecolor->rgb.setValue(selection->colorHighlight.getValue()); if (!PRIVATE(this)->selectsearch) { PRIVATE(this)->selectsearch = new SoSearchAction; } PRIVATE(this)->selectsearch->setType(SoShape::getClassTypeId()); PRIVATE(this)->selectsearch->setInterest(SoSearchAction::FIRST); PRIVATE(this)->selectsearch->apply(selection); SoPath* shapepath = PRIVATE(this)->selectsearch->getPath(); if (shapepath) { SoPathList list; list.append(shapepath); // clear old highlighting node if still active if (PRIVATE(this)->highlightPath) { PRIVATE(this)->highlightPath->unref(); } PRIVATE(this)->highlightPath = path; PRIVATE(this)->highlightPath->ref(); this->drawBoxes(path, &list); } PRIVATE(this)->selectsearch->reset(); } } } void SoBoxSelectionRenderAction::apply(const SoPathList& pathlist, SbBool obeysrules) { SoGLRenderAction::apply(pathlist, obeysrules); } void SoBoxSelectionRenderAction::setColor(const SbColor& color) { PRIVATE(this)->basecolor->rgb = color; } const SbColor& SoBoxSelectionRenderAction::getColor() { return PRIVATE(this)->basecolor->rgb[0]; } void SoBoxSelectionRenderAction::setLinePattern(unsigned short pattern) { PRIVATE(this)->drawstyle->linePattern = pattern; } unsigned short SoBoxSelectionRenderAction::getLinePattern() const { return PRIVATE(this)->drawstyle->linePattern.getValue(); } void SoBoxSelectionRenderAction::setLineWidth(const float width) { PRIVATE(this)->drawstyle->lineWidth = width; } float SoBoxSelectionRenderAction::getLineWidth() const { return PRIVATE(this)->drawstyle->lineWidth.getValue(); } void SoBoxSelectionRenderAction::drawBoxes(SoPath* pathtothis, const SoPathList* pathlist) { int i; int thispos = static_cast(pathtothis)->getLength() - 1; assert(thispos >= 0); PRIVATE(this)->postprocpath->truncate(0); // reset for (i = 0; i < thispos; i++) { PRIVATE(this)->postprocpath->append(pathtothis->getNode(i)); } // we need to disable accumulation buffer antialiasing while // rendering selected objects int oldnumpasses = this->getNumPasses(); this->setNumPasses(1); SoState* thestate = this->getState(); thestate->push(); for (i = 0; i < pathlist->getLength(); i++) { auto path = static_cast((*pathlist)[i]); for (int j = 0; j < path->getLength(); j++) { PRIVATE(this)->postprocpath->append(path->getNode(j)); } // Previously SoGLRenderAction was used to draw the bounding boxes // of shapes in selection paths, by overriding renderstyle state // elements to lines drawstyle and simply doing: // // SoGLRenderAction::apply(PRIVATE(this)->postprocpath); // Bug // // This could have the unwanted side effect of rendering // non-selected shapes, as they could be part of the path (due to // being placed below SoGroup nodes (instead of SoSeparator // nodes)) up to the selected shape. // // // A better approach turned out to be to soup up and draw only the // bounding boxes of the selected shapes: PRIVATE(this)->updateBbox(PRIVATE(this)->postprocpath); // Remove temporary path from path buffer PRIVATE(this)->postprocpath->truncate(thispos); } this->setNumPasses(oldnumpasses); thestate->pop(); } #undef PRIVATE #undef PUBLIC