SoGLHighlightRenderAction.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2012-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package MemoryX::gui-plugins::SceneEditor
19  * @date 2015
20  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
21  * GNU General Public License
22  */
23 
24 /*
25  * SoGLHighlightRenderAction.cpp
26  *
27  * Created on: Jan 13, 2015
28  * Author: philipp
29  */
30 
32 
34  const SbViewportRegion& viewportregion, Scene* scene) :
35  SoGLRenderAction(viewportregion), scene(scene), selectedcolor_storage(sizeof(void*), alloc_colorpacker, free_colorpacker)
36 {
37 
38  this->isVisible = true;
39  this->selectedColor = SbColor(1.0f, 0.8f, 0.4f);
40  this->activeColor = SbColor(1.0f, 0.4f, 0.2f);
41  this->linepattern = 0xffff;
42  this->linewidth = 5;
43 
44  // SoBase-derived objects should be dynamically allocated.
45  this->postprocpath = new SoTempPath(32);
46  this->postprocpath->ref();
47 
48 }
49 
51 {
52  postprocpath->unref();
53 }
54 
56 {
57  std::unique_lock lock(scene->execute_mutex);
58 
59  //Render complete scene with standard action
60  SoGLRenderAction::apply(node);
61 
62  if (this->isVisible)
63  {
64  SoSearchAction* searchAction = new SoSearchAction;
65  searchAction->setType(SoSelection::getClassTypeId());
66  searchAction->setInterest(SoSearchAction::ALL);
67  searchAction->apply(node);
68 
69  const SoPathList& pathlist = searchAction->getPaths();
70 
71  if (pathlist.getLength() > 0)
72  {
73  for (int i = 0; i < pathlist.getLength(); i++)
74  {
75  SoPath* path = pathlist[i];
76  SoSelection* selection = (SoSelection*) path->getTail();
77 
78  if (selection->getNumSelected() > 0)
79  //Add highlight border around selected objects
80  {
81  this->drawHighlight(path, selection->getList());
82  }
83  }
84  }
85  }
86 }
87 
88 void scene3D::SoGLHighlightRenderAction::drawHighlight(SoPath* pathtothis,
89  const SoPathList* pathlist)
90 {
91  // Copied from Coin implementation, no idea what it does
92  int oldnumpasses = this->getNumPasses();
93  this->setNumPasses(1);
94 
95  //Insert path to SoSelection node in our postprocesspath
96  int thispos = ((SoFullPath*) pathtothis)->getLength() - 1;
97  this->postprocpath->truncate(0);
98 
99  for (int i = 0; i < thispos; i++)
100  {
101  this->postprocpath->append(pathtothis->getNode(i));
102  }
103 
104  //For 0 to n - 1 selected object of selection list render colored wireframe
105  for (int i = 0; i < pathlist->getLength(); i++)
106  {
107  //Retrieve full path
108  SoFullPath* path = (SoFullPath*)(*pathlist)[i];
109 
110  //Append to postprocesspath
111  for (int j = 0; j < path->getLength(); j++)
112  {
113  this->postprocpath->append(path->getNode(j));
114  }
115 
116  /*
117  We use a little algorithm mostly explained here:
118  http://www.flipcode.com/archives/Object_Outlining.shtml
119  and here:
120  http://www.informit.com/articles/article.aspx?p=328646&seqNum=10
121 
122  We basically fill the opengl stencil buffer with the value 1,
123  tell opengl to never touch the color buffer but modify the stencil buffer only.
124  (Actually writing zero into it at the respective pixel positions).
125  In the next step we render the object again, this time drawing
126  the wireframe version of the object with the selection color
127  and only drawing where we still have the value 1 in stencil buffer.
128  Because line width is 5, we actually get some sort of 'edge glow'
129  effect out of this. :)
130  */
131 
132  // Use 1 for clearing stencil buffer, clear buffer and enable stencil test
133  glEnable(GL_STENCIL_TEST);
134  glClearStencil(1.0f);
135  glClear(GL_STENCIL_BUFFER_BIT);
136 
137  // All drawing commands fail the stencil test and are not
138  // drawn, but set the value in the stencil buffer to zero.
139  glStencilFunc(GL_NEVER, 0x0, 0x0);
140  glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
141  SoGLRenderAction::apply(this->postprocpath);
142 
143  //Render only where stencil is not set to 0, to achieve sort of 'edge glow' effect
144  glStencilFunc(GL_NOTEQUAL, 0, 1);
145  //Do not modify stencil buffer in any way (just to keep it clean, doesn't really matter)
146  glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
147 
148  //Draw wireframe in selection color, masked by stencil
149  drawWireframe(this->postprocpath, i == pathlist->getLength() - 1);
150 
151  //Reset postprocesspath to SoSelection node
152  this->postprocpath->truncate(thispos);
153 
154  glDisable(GL_STENCIL_TEST);
155  }
156 
157  //Restore this mysterious numpass thing
158  this->setNumPasses(oldnumpasses);
159 }
160 
161 void scene3D::SoGLHighlightRenderAction::drawWireframe(SoPath* pathtothis, bool active)
162 {
163  //Save current openGL state
164  SoState* state = this->getState();
165  state->push();
166 
167  //Cause Coin sucks we have to use OpenGL calls directly here
168  //because calling SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR)
169  //ends in SEGFAULT for some selected objects
170  glDisable(GL_LIGHTING);
171 
172  //Do some pretty complex and fun OpenGL adaptions
173  SoColorPacker** selected_cptr =
174  (SoColorPacker**) this->selectedcolor_storage.get();
175 
176  if (!active)
177  {
178  SoGLLazyElement::setDiffuse(state, pathtothis->getHead(), 1,
179  &this->selectedColor, *selected_cptr);
180  }
181  else
182  {
183  //Set new color for last object
184  SoGLLazyElement::setDiffuse(state, pathtothis->getTail(), 1,
185  &this->activeColor, *selected_cptr);
186  }
187 
188  SoLineWidthElement::set(state, this->linewidth);
189  SoLinePatternElement::set(state, this->linepattern);
190  SoTextureQualityElement::set(state, 0.0f);
191  SoDrawStyleElement::set(state, SoDrawStyleElement::LINES);
192  SoPolygonOffsetElement::set(state, NULL, -1.0f, 1.0f,
193  SoPolygonOffsetElement::LINES, TRUE);
194  SoMaterialBindingElement::set(state, NULL,
195  SoMaterialBindingElement::OVERALL);
196  SoNormalElement::set(state, NULL, 0, NULL, FALSE);
197  SoOverrideElement::setNormalVectorOverride(state, NULL, TRUE);
198  SoOverrideElement::setMaterialBindingOverride(state, NULL, TRUE);
199  SoOverrideElement::setLightModelOverride(state, NULL, TRUE);
200  SoOverrideElement::setDiffuseColorOverride(state, NULL, TRUE);
201  SoOverrideElement::setLineWidthOverride(state, NULL, TRUE);
202  SoOverrideElement::setLinePatternOverride(state, NULL, TRUE);
203  SoOverrideElement::setDrawStyleOverride(state, NULL, TRUE);
204  SoOverrideElement::setPolygonOffsetOverride(state, NULL, TRUE);
205  SoTextureOverrideElement::setQualityOverride(state, TRUE);
206 
207  //Render with new OpenGL context
208  SoGLRenderAction::apply(this->postprocpath);
209 
210  //Cause switching light on again might be a good idea
211  glEnable(GL_LIGHTING);
212 
213  //Restore OpenGL context
214  state->pop();
215 }
216 
217 
scene3D::Scene
Definition: Scene.h:61
scene3D::SoGLHighlightRenderAction::~SoGLHighlightRenderAction
~SoGLHighlightRenderAction() override
Destructor.
Definition: SoGLHighlightRenderAction.cpp:50
scene3D::SoGLHighlightRenderAction::apply
void apply(SoNode *node) override
Applies the Highlighting to a given node.
Definition: SoGLHighlightRenderAction.cpp:55
scene3D::SoGLHighlightRenderAction::SoGLHighlightRenderAction
SoGLHighlightRenderAction(const SbViewportRegion &viewportregion, Scene *scene)
Constructor Creates an Instance of the Class.
Definition: SoGLHighlightRenderAction.cpp:33
SoGLHighlightRenderAction.h
scene3D::ALL
@ ALL
Definition: ManipulatorMode.h:35
set
set(LIBS ArmarXCoreInterfaces ${CMAKE_THREAD_LIBS_INIT} ${dl_LIBRARIES} ${rt_LIBRARIES} ${QT_LIBRARIES} ${Boost_LIBRARIES} BoostAssertionHandler ArmarXCPPUtility SimoxUtility) set(LIB_FILES ArmarXManager.cpp ArmarXMultipleObjectsScheduler.cpp ArmarXObjectScheduler.cpp ManagedIceObject.cpp ManagedIceObjectPlugin.cpp Component.cpp ComponentPlugin.cpp IceGridAdmin.cpp ArmarXObjectObserver.cpp IceManager.cpp PackagePath.cpp RemoteReferenceCount.cpp logging/LoggingUtil.cpp logging/Logging.cpp logging/LogSender.cpp logging/ArmarXLogBuf.cpp system/ArmarXDataPath.cpp system/DynamicLibrary.cpp system/ProcessWatcher.cpp system/FactoryCollectionBase.cpp system/cmake/CMakePackageFinder.cpp system/cmake/CMakePackageFinderCache.cpp system/cmake/ArmarXPackageToolInterface.cpp system/RemoteObjectNode.cpp services/sharedmemory/HardwareId.cpp services/tasks/RunningTask.cpp services/tasks/ThreadList.cpp services/tasks/ThreadPool.cpp services/profiler/Profiler.cpp services/profiler/FileLoggingStrategy.cpp services/profiler/IceLoggingStrategy.cpp application/Application.cpp application/ApplicationOptions.cpp application/ApplicationProcessFacet.cpp application/ApplicationNetworkStats.cpp application/properties/PropertyUser.cpp application/properties/Property.cpp application/properties/PropertyDefinition.cpp application/properties/PropertyDefinitionContainer.cpp application/properties/PropertyDefinitionHelpFormatter.cpp application/properties/PropertyDefinitionConfigFormatter.cpp application/properties/PropertyDefinitionBriefHelpFormatter.cpp application/properties/PropertyDefinitionXmlFormatter.cpp application/properties/PropertyDefinitionDoxygenFormatter.cpp application/properties/PropertyDefinitionDoxygenComponentPagesFormatter.cpp application/properties/PropertyDefinitionContainerBriefHelpFormatter.cpp application/properties/IceProperties.cpp exceptions/Exception.cpp exceptions/local/UnexpectedEnumValueException.cpp util/FileSystemPathBuilder.cpp util/StringHelpers.cpp util/IceReportSkipper.cpp util/Throttler.cpp util/distributed/AMDCallbackCollection.cpp util/distributed/RemoteHandle/ClientSideRemoteHandleControlBlock.cpp util/distributed/RemoteHandle/RemoteHandle.cpp util/distributed/RemoteHandle/RemoteHandleControlBlock.cpp time/ice_conversions.cpp time/json_conversions.cpp time/CallbackWaitLock.cpp time/Clock.cpp time/ClockType.cpp time/ClockTypeNames.cpp time/CycleUtil.cpp time/DateTime.cpp time/Duration.cpp time/Frequency.cpp time/LocalTimeServer.cpp time/Metronome.cpp time/ScopedStopWatch.cpp time/StopWatch.cpp time/Timer.cpp time/TimeKeeper.cpp time/TimeUtil.cpp csv/CsvWriter.cpp csv/CsvReader.cpp eigen/conversions.cpp eigen/ice_conversions.cpp) set(LIB_HEADERS ArmarXManager.h ArmarXDummyManager.h ArmarXMultipleObjectsScheduler.h ArmarXObjectObserver.h ArmarXObjectScheduler.h ArmarXFwd.h Component.h ComponentPlugin.h ComponentFactories.h CoreObjectFactories.h IceGridAdmin.h IceManager.h IceManagerImpl.h json_conversions.h ManagedIceObject.h ManagedIceObjectPlugin.h ManagedIceObjectImpl.h ManagedIceObjectDependency.h ManagedIceObjectRegistryInterface.h PackagePath.h RemoteReferenceCount.h system/ImportExport.h system/ImportExportComponent.h system/AbstractFactoryMethod.h system/FactoryCollectionBase.h system/Synchronization.h system/ArmarXDataPath.h system/DynamicLibrary.h system/ProcessWatcher.h system/ConditionSynchronization.h system/cmake/CMakePackageFinder.h system/cmake/CMakePackageFinderCache.h system/cmake/FindPackageX.cmake system/cmake/ArmarXPackageToolInterface.h system/RemoteObjectNode.h logging/LoggingUtil.h logging/LogSender.h logging/Logging.h logging/ArmarXLogBuf.h logging/SpamFilterData.h services/tasks/RunningTask.h services/tasks/PeriodicTask.h services/tasks/ThreadList.h services/tasks/TaskUtil.h services/tasks/ThreadPool.h services/sharedmemory/SharedMemoryProvider.h services/sharedmemory/SharedMemoryConsumer.h services/sharedmemory/IceSharedMemoryProvider.h services/sharedmemory/IceSharedMemoryConsumer.h services/sharedmemory/HardwareIdentifierProvider.h services/sharedmemory/HardwareId.h services/sharedmemory/exceptions/SharedMemoryExceptions.h services/profiler/Profiler.h services/profiler/LoggingStrategy.h services/profiler/FileLoggingStrategy.h services/profiler/IceLoggingStrategy.h application/Application.h application/ApplicationOptions.h application/ApplicationProcessFacet.h application/ApplicationNetworkStats.h application/properties/forward_declarations.h application/properties/Properties.h application/properties/Property.h application/properties/PluginEigen.h application/properties/PluginEnumNames.h application/properties/PluginCfgStruct.h application/properties/PluginAll.h application/properties/PropertyUser.h application/properties/PropertyDefinition.h application/properties/PropertyDefinition.hpp application/properties/PropertyDefinitionInterface.h application/properties/PropertyDefinitionContainer.h application/properties/PropertyDefinitionFormatter.h application/properties/PropertyDefinitionContainerFormatter.h application/properties/PropertyDefinitionConfigFormatter.h application/properties/PropertyDefinitionHelpFormatter.h application/properties/PropertyDefinitionBriefHelpFormatter.h application/properties/PropertyDefinitionXmlFormatter.h application/properties/PropertyDefinitionDoxygenFormatter.h application/properties/PropertyDefinitionDoxygenComponentPagesFormatter.h application/properties/PropertyDefinitionContainerBriefHelpFormatter.h application/properties/ProxyPropertyDefinition.h application/properties/IceProperties.h exceptions/Exception.h exceptions/LocalException.h exceptions/local/DynamicLibraryException.h exceptions/local/ExpressionException.h exceptions/local/FileIOException.h exceptions/local/InvalidPropertyValueException.h exceptions/local/MissingRequiredPropertyException.h exceptions/local/PropertyInheritanceCycleException.h exceptions/local/ProxyNotInitializedException.h exceptions/local/UnexpectedEnumValueException.h exceptions/local/UnmappedValueException.h exceptions/local/ValueRangeExceededException.h exceptions/user/NotImplementedYetException.h rapidxml/rapidxml.hpp rapidxml/rapidxml_print.hpp rapidxml/rapidxml_iterators.hpp rapidxml/rapidxml_utils.hpp rapidxml/wrapper/RapidXmlReader.h rapidxml/wrapper/RapidXmlWriter.h rapidxml/wrapper/DefaultRapidXmlReader.h rapidxml/wrapper/MultiNodeRapidXMLReader.h util/IceBlobToObject.h util/ObjectToIceBlob.h util/FileSystemPathBuilder.h util/FiniteStateMachine.h util/StringHelpers.h util/StringHelperTemplates.h util/algorithm.h util/OnScopeExit.h util/Predicates.h util/Preprocessor.h util/PropagateConst.h util/Registrar.h util/TemplateMetaProgramming.h util/TripleBuffer.h util/IceReportSkipper.h util/Throttler.h util/distributed/AMDCallbackCollection.h util/distributed/RemoteHandle/ClientSideRemoteHandleControlBlock.h util/distributed/RemoteHandle/RemoteHandle.h util/distributed/RemoteHandle/RemoteHandleControlBlock.h util/SimpleStatemachine.h time.h time_minimal.h time/forward_declarations.h time/ice_conversions.h time/json_conversions.h time/CallbackWaitLock.h time/Clock.h time/ClockType.h time/ClockTypeNames.h time/CycleUtil.h time/DateTime.h time/Duration.h time/Frequency.h time/LocalTimeServer.h time/Metronome.h time/ScopedStopWatch.h time/StopWatch.h time/Timer.h time/TimeUtil.h time/TimeKeeper.h csv/CsvWriter.h csv/CsvReader.h eigen/conversions.h eigen/ice_conversions.h ice_conversions.h ice_conversions/ice_conversions_boost_templates.h ice_conversions/ice_conversions_templates.h ice_conversions/ice_conversions_templates.tpp $
Definition: CMakeLists.txt:12