Previously, box style selection is rendered using customized SoBoxSelectionRenderAction, which does not support selection context, i.e. it does not work with Link. This patch implements context aware bound box rendering inside SoFCSelectionRoot, SoFCSelection and SoFCPathAnnotation (for always on top rendering). The box rendering in SoBoxSelectionRenderAction is disabled on construction. Box style selection can be enabled for individual object through property SelectionStyle (moved from ViewProviderGeometryObject to ViewProviderDocumentObject), or globally through Parameter BaseApp/Preferences/View/ShowSelectionBoundingBox. In addition, the parameter BaseApp/Preferences/View/UseNewSelection is used to override selection model reported from ViewProvider::useNewSelectionModel(). The reason being that, the same parameter is already used to toggle selection model inside SoFCSelection. This avoids inconsistency of selection model choice between view provider and the SoFCSelection node inside. Note that if the parameter 'UseNewSelection' is set to false, those view providers that choose old selection model will not work with Link.
1384 lines
47 KiB
C++
1384 lines
47 KiB
C++
/***************************************************************************
|
|
*
|
|
* Copyright (c) 2005 Jürgen Riegel <juergen.riegel@web.de> *
|
|
* *
|
|
* 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 "PreCompiled.h"
|
|
|
|
#ifndef _PreComp_
|
|
# include <cassert>
|
|
# include <float.h>
|
|
# include <Inventor/actions/SoSearchAction.h>
|
|
# include <Inventor/actions/SoGetBoundingBoxAction.h>
|
|
# include <Inventor/nodes/SoCallback.h>
|
|
# include <Inventor/nodes/SoComplexity.h>
|
|
# include <Inventor/nodes/SoCube.h>
|
|
# include <Inventor/nodes/SoCamera.h>
|
|
# include <Inventor/nodes/SoCoordinate3.h>
|
|
# include <Inventor/nodes/SoCoordinate4.h>
|
|
# include <Inventor/nodes/SoFont.h>
|
|
# include <Inventor/nodes/SoMatrixTransform.h>
|
|
# include <Inventor/nodes/SoProfile.h>
|
|
# include <Inventor/nodes/SoProfileCoordinate2.h>
|
|
# include <Inventor/nodes/SoProfileCoordinate3.h>
|
|
# include <Inventor/nodes/SoSwitch.h>
|
|
# include <Inventor/nodes/SoTransformation.h>
|
|
# include <Inventor/nodes/SoIndexedLineSet.h>
|
|
# include <Inventor/nodes/SoIndexedFaceSet.h>
|
|
# include <Inventor/nodes/SoPointSet.h>
|
|
# include <Inventor/nodes/SoDrawStyle.h>
|
|
# include <Inventor/nodes/SoComplexity.h>
|
|
# include <Inventor/nodes/SoLightModel.h>
|
|
# include <Inventor/nodes/SoBaseColor.h>
|
|
#endif
|
|
|
|
#include <Base/Console.h>
|
|
|
|
#include "SoFCSelectionAction.h"
|
|
#include "SoFCSelection.h"
|
|
#include "SoFCUnifiedSelection.h"
|
|
#include <Inventor/bundles/SoMaterialBundle.h>
|
|
#include <Inventor/elements/SoSwitchElement.h>
|
|
#include "Selection.h"
|
|
|
|
#include <Inventor/elements/SoComplexityElement.h>
|
|
#include <Inventor/elements/SoComplexityTypeElement.h>
|
|
#include <Inventor/elements/SoCoordinateElement.h>
|
|
#include <Inventor/elements/SoElements.h>
|
|
#include <Inventor/elements/SoFontNameElement.h>
|
|
#include <Inventor/elements/SoFontSizeElement.h>
|
|
#include <Inventor/elements/SoModelMatrixElement.h>
|
|
#include <Inventor/elements/SoShapeStyleElement.h>
|
|
#include <Inventor/elements/SoProfileCoordinateElement.h>
|
|
#include <Inventor/elements/SoProfileElement.h>
|
|
#include <Inventor/elements/SoSwitchElement.h>
|
|
#include <Inventor/elements/SoUnitsElement.h>
|
|
#include <Inventor/elements/SoViewVolumeElement.h>
|
|
#include <Inventor/elements/SoViewingMatrixElement.h>
|
|
#include <Inventor/elements/SoViewportRegionElement.h>
|
|
#include <Inventor/nodes/SoCamera.h>
|
|
#include <Inventor/nodes/SoComplexity.h>
|
|
#include <Inventor/nodes/SoCoordinate3.h>
|
|
#include <Inventor/nodes/SoCoordinate4.h>
|
|
#include <Inventor/nodes/SoCube.h>
|
|
#include <Inventor/nodes/SoFont.h>
|
|
#include <Inventor/nodes/SoGroup.h>
|
|
#include <Inventor/nodes/SoSeparator.h>
|
|
#include <Inventor/nodes/SoProfile.h>
|
|
#include <Inventor/nodes/SoProfileCoordinate2.h>
|
|
#include <Inventor/nodes/SoProfileCoordinate3.h>
|
|
#include <Inventor/nodes/SoSphere.h>
|
|
#include <Inventor/nodes/SoTransformation.h>
|
|
|
|
|
|
|
|
|
|
|
|
using namespace Gui;
|
|
|
|
|
|
SO_ACTION_SOURCE(SoFCHighlightAction)
|
|
|
|
/**
|
|
* 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 SoFCHighlightAction::initClass()
|
|
{
|
|
SO_ACTION_INIT_CLASS(SoFCHighlightAction,SoAction);
|
|
|
|
SO_ENABLE(SoFCHighlightAction, SoSwitchElement);
|
|
|
|
SO_ACTION_ADD_METHOD(SoNode,nullAction);
|
|
|
|
SO_ENABLE(SoFCHighlightAction, SoModelMatrixElement);
|
|
SO_ENABLE(SoFCHighlightAction, SoShapeStyleElement);
|
|
SO_ENABLE(SoFCHighlightAction, SoComplexityElement);
|
|
SO_ENABLE(SoFCHighlightAction, SoComplexityTypeElement);
|
|
SO_ENABLE(SoFCHighlightAction, SoCoordinateElement);
|
|
SO_ENABLE(SoFCHighlightAction, SoFontNameElement);
|
|
SO_ENABLE(SoFCHighlightAction, SoFontSizeElement);
|
|
SO_ENABLE(SoFCHighlightAction, SoProfileCoordinateElement);
|
|
SO_ENABLE(SoFCHighlightAction, SoProfileElement);
|
|
SO_ENABLE(SoFCHighlightAction, SoSwitchElement);
|
|
SO_ENABLE(SoFCHighlightAction, SoUnitsElement);
|
|
SO_ENABLE(SoFCHighlightAction, SoViewVolumeElement);
|
|
SO_ENABLE(SoFCHighlightAction, SoViewingMatrixElement);
|
|
SO_ENABLE(SoFCHighlightAction, 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 SoFCHighlightAction::finish()
|
|
{
|
|
atexit_cleanup();
|
|
}
|
|
|
|
|
|
SoFCHighlightAction::SoFCHighlightAction (const SelectionChanges &SelCh)
|
|
:SelChange(SelCh)
|
|
{
|
|
SO_ACTION_CONSTRUCTOR(SoFCHighlightAction);
|
|
}
|
|
|
|
|
|
SoFCHighlightAction::~SoFCHighlightAction()
|
|
{
|
|
}
|
|
|
|
|
|
void SoFCHighlightAction::beginTraversal(SoNode *node)
|
|
{
|
|
traverse(node);
|
|
}
|
|
|
|
void SoFCHighlightAction::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()
|
|
{
|
|
}
|
|
|
|
|
|
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)
|
|
: selection(sel)
|
|
{
|
|
SO_ACTION_CONSTRUCTOR(SoFCEnableSelectionAction);
|
|
}
|
|
|
|
|
|
SoFCEnableSelectionAction::~SoFCEnableSelectionAction()
|
|
{
|
|
}
|
|
|
|
|
|
void SoFCEnableSelectionAction::beginTraversal(SoNode *node)
|
|
{
|
|
traverse(node);
|
|
}
|
|
|
|
void SoFCEnableSelectionAction::callDoAction(SoAction *action,SoNode *node)
|
|
{
|
|
node->doAction(action);
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
|
|
SO_ACTION_SOURCE(SoFCEnableHighlightAction)
|
|
|
|
/**
|
|
* 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 SoFCEnableHighlightAction::initClass()
|
|
{
|
|
SO_ACTION_INIT_CLASS(SoFCEnableHighlightAction,SoAction);
|
|
|
|
SO_ENABLE(SoFCEnableHighlightAction, SoSwitchElement);
|
|
|
|
SO_ACTION_ADD_METHOD(SoNode,nullAction);
|
|
|
|
SO_ENABLE(SoFCEnableHighlightAction, SoModelMatrixElement);
|
|
SO_ENABLE(SoFCEnableHighlightAction, SoShapeStyleElement);
|
|
SO_ENABLE(SoFCEnableHighlightAction, SoComplexityElement);
|
|
SO_ENABLE(SoFCEnableHighlightAction, SoComplexityTypeElement);
|
|
SO_ENABLE(SoFCEnableHighlightAction, SoCoordinateElement);
|
|
SO_ENABLE(SoFCEnableHighlightAction, SoFontNameElement);
|
|
SO_ENABLE(SoFCEnableHighlightAction, SoFontSizeElement);
|
|
SO_ENABLE(SoFCEnableHighlightAction, SoProfileCoordinateElement);
|
|
SO_ENABLE(SoFCEnableHighlightAction, SoProfileElement);
|
|
SO_ENABLE(SoFCEnableHighlightAction, SoSwitchElement);
|
|
SO_ENABLE(SoFCEnableHighlightAction, SoUnitsElement);
|
|
SO_ENABLE(SoFCEnableHighlightAction, SoViewVolumeElement);
|
|
SO_ENABLE(SoFCEnableHighlightAction, SoViewingMatrixElement);
|
|
SO_ENABLE(SoFCEnableHighlightAction, 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 SoFCEnableHighlightAction::finish()
|
|
{
|
|
atexit_cleanup();
|
|
}
|
|
|
|
|
|
SoFCEnableHighlightAction::SoFCEnableHighlightAction (const SbBool& sel)
|
|
: highlight(sel)
|
|
{
|
|
SO_ACTION_CONSTRUCTOR(SoFCEnableHighlightAction);
|
|
}
|
|
|
|
|
|
SoFCEnableHighlightAction::~SoFCEnableHighlightAction()
|
|
{
|
|
}
|
|
|
|
|
|
void SoFCEnableHighlightAction::beginTraversal(SoNode *node)
|
|
{
|
|
traverse(node);
|
|
}
|
|
|
|
void SoFCEnableHighlightAction::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()
|
|
{
|
|
}
|
|
|
|
|
|
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()
|
|
{
|
|
}
|
|
|
|
|
|
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()
|
|
{
|
|
}
|
|
|
|
|
|
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 () : _handled(false)
|
|
{
|
|
SO_ACTION_CONSTRUCTOR(SoFCDocumentObjectAction);
|
|
}
|
|
|
|
SoFCDocumentObjectAction::~SoFCDocumentObjectAction()
|
|
{
|
|
}
|
|
|
|
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), _handled(false)
|
|
{
|
|
SO_ACTION_CONSTRUCTOR(SoGLSelectAction);
|
|
}
|
|
|
|
SoGLSelectAction::~SoGLSelectAction()
|
|
{
|
|
}
|
|
|
|
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 () : _handled(false)
|
|
{
|
|
SO_ACTION_CONSTRUCTOR(SoVisibleFaceAction);
|
|
}
|
|
|
|
SoVisibleFaceAction::~SoVisibleFaceAction()
|
|
{
|
|
}
|
|
|
|
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()
|
|
{
|
|
}
|
|
|
|
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)
|
|
, searchaction(0)
|
|
, selectsearch(0)
|
|
, camerasearch(0)
|
|
, bboxaction(0)
|
|
, basecolor(0)
|
|
, postprocpath(0)
|
|
, highlightPath(0)
|
|
, localRoot(0)
|
|
, xform(0)
|
|
, cube(0)
|
|
, drawstyle(0)
|
|
{
|
|
|
|
}
|
|
|
|
SoBoxSelectionRenderAction * master;
|
|
SoSearchAction * searchaction;
|
|
SoSearchAction * selectsearch;
|
|
SoSearchAction * camerasearch;
|
|
SoGetBoundingBoxAction * bboxaction;
|
|
SoBaseColor * basecolor;
|
|
SoTempPath * postprocpath;
|
|
SoPath * highlightPath;
|
|
SoSeparator * localRoot;
|
|
SoMatrixTransform * xform;
|
|
SoCube * cube;
|
|
SoDrawStyle * drawstyle;
|
|
SoColorPacker colorpacker;
|
|
|
|
void initBoxGraph();
|
|
void updateBbox(const SoPath * path);
|
|
};
|
|
|
|
}
|
|
|
|
#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;
|
|
|
|
SoLightModel * lightmodel = new SoLightModel;
|
|
lightmodel->model = SoLightModel::BASE_COLOR;
|
|
|
|
SoComplexity * 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 == NULL) {
|
|
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((SoPath*) 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 == NULL) {
|
|
this->bboxaction = new SoGetBoundingBoxAction(SbViewportRegion(100, 100));
|
|
}
|
|
this->bboxaction->setViewportRegion(PUBLIC(this)->getViewportRegion());
|
|
this->bboxaction->apply((SoPath*) 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();
|
|
|
|
// 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(void)
|
|
{
|
|
SO_ACTION_INIT_CLASS(SoBoxSelectionRenderAction, SoGLRenderAction);
|
|
}
|
|
|
|
SoBoxSelectionRenderAction::SoBoxSelectionRenderAction(void)
|
|
: inherited(SbViewportRegion())
|
|
{
|
|
this->constructorCommon();
|
|
}
|
|
|
|
SoBoxSelectionRenderAction::SoBoxSelectionRenderAction(const SbViewportRegion & viewportregion)
|
|
: inherited(viewportregion)
|
|
{
|
|
this->constructorCommon();
|
|
}
|
|
|
|
//
|
|
// private. called by both constructors
|
|
//
|
|
void
|
|
SoBoxSelectionRenderAction::constructorCommon(void)
|
|
{
|
|
SO_ACTION_CONSTRUCTOR(SoBoxSelectionRenderAction);
|
|
|
|
PRIVATE(this) = new SoBoxSelectionRenderActionP(this);
|
|
|
|
// Initialize local variables
|
|
PRIVATE(this)->initBoxGraph();
|
|
|
|
// this->hlVisible = true;
|
|
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 = NULL;
|
|
PRIVATE(this)->selectsearch = NULL;
|
|
PRIVATE(this)->camerasearch = NULL;
|
|
PRIVATE(this)->bboxaction = NULL;
|
|
|
|
// SoBase-derived objects should be dynamically allocated.
|
|
PRIVATE(this)->postprocpath = new SoTempPath(32);
|
|
PRIVATE(this)->postprocpath->ref();
|
|
PRIVATE(this)->highlightPath = 0;
|
|
}
|
|
|
|
SoBoxSelectionRenderAction::~SoBoxSelectionRenderAction(void)
|
|
{
|
|
// 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 == NULL) {
|
|
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);
|
|
SoFCSelection * selection = (SoFCSelection *) 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 == NULL) {
|
|
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 == NULL) {
|
|
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()) {
|
|
SoFCSelection * selection = (SoFCSelection *) node;
|
|
|
|
// This happens when dehighlighting the current shape
|
|
if (PRIVATE(this)->highlightPath == path) {
|
|
PRIVATE(this)->highlightPath->unref();
|
|
PRIVATE(this)->highlightPath = 0;
|
|
// 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 == NULL) {
|
|
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(void)
|
|
{
|
|
return PRIVATE(this)->basecolor->rgb[0];
|
|
}
|
|
|
|
void
|
|
SoBoxSelectionRenderAction::setLinePattern(unsigned short pattern)
|
|
{
|
|
PRIVATE(this)->drawstyle->linePattern = pattern;
|
|
}
|
|
|
|
unsigned short
|
|
SoBoxSelectionRenderAction::getLinePattern(void) const
|
|
{
|
|
return PRIVATE(this)->drawstyle->linePattern.getValue();
|
|
}
|
|
|
|
void
|
|
SoBoxSelectionRenderAction::setLineWidth(const float width)
|
|
{
|
|
PRIVATE(this)->drawstyle->lineWidth = width;
|
|
}
|
|
|
|
float
|
|
SoBoxSelectionRenderAction::getLineWidth(void) const
|
|
{
|
|
return PRIVATE(this)->drawstyle->lineWidth.getValue();
|
|
}
|
|
|
|
void
|
|
SoBoxSelectionRenderAction::drawBoxes(SoPath * pathtothis, const SoPathList * pathlist)
|
|
{
|
|
int i;
|
|
int thispos = ((SoFullPath *)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++) {
|
|
SoFullPath * path = (SoFullPath *)(*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
|