From 1c88753551ff5e87318ff752c15152bbd266f947 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 21 Jan 2009 11:46:03 +0000 Subject: [PATCH] Introduced the ability to switch between different visual properties in osgVolume --- examples/osgvolume/osgvolume.cpp | 45 ++++++++- include/osgVolume/Property | 71 +++++++++++--- src/osgVolume/Property.cpp | 129 ++++++++++++++++++++++--- src/osgWrappers/osgVolume/Property.cpp | 118 +++++++++++++++++++--- 4 files changed, 324 insertions(+), 39 deletions(-) diff --git a/examples/osgvolume/osgvolume.cpp b/examples/osgvolume/osgvolume.cpp index efda6fe1f..d06b4cedd 100644 --- a/examples/osgvolume/osgvolume.cpp +++ b/examples/osgvolume/osgvolume.cpp @@ -1274,7 +1274,8 @@ int main( int argc, char **argv ) tile->setLayer(layer.get()); tile->setEventCallback(new osgVolume::PropertyAdjustmentCallback()); - + +#if 0 if (useShader) { switch(shadingModel) @@ -1306,7 +1307,49 @@ int main( int argc, char **argv ) layer->addProperty(new osgVolume::AlphaFuncProperty(alphaFunc)); tile->setVolumeTechnique(new osgVolume::FixedFunctionTechnique); } +#else + + osgVolume::SwitchProperty* sp = new osgVolume::SwitchProperty; + sp->setActiveProperty(0); + { + // Standard + osgVolume::CompositeProperty* cp = new osgVolume::CompositeProperty; + cp->addProperty(new osgVolume::AlphaFuncProperty(alphaFunc)); + + sp->addProperty(cp); + } + + { + // Light + osgVolume::CompositeProperty* cp = new osgVolume::CompositeProperty; + cp->addProperty(new osgVolume::AlphaFuncProperty(alphaFunc)); + cp->addProperty(new osgVolume::LightingProperty); + + sp->addProperty(cp); + } + + { + // Isosurface + osgVolume::CompositeProperty* cp = new osgVolume::CompositeProperty; + cp->addProperty(new osgVolume::IsoSurfaceProperty(alphaFunc)); + + sp->addProperty(cp); + } + + { + // MaximumIntensityProjection + osgVolume::CompositeProperty* cp = new osgVolume::CompositeProperty; + cp->addProperty(new osgVolume::AlphaFuncProperty(alphaFunc)); + cp->addProperty(new osgVolume::MaximumIntensityProjectionProperty); + + sp->addProperty(cp); + } + + layer->addProperty(sp); + tile->setVolumeTechnique(new osgVolume::ShaderTechnique); + +#endif rootNode = volume.get(); } diff --git a/include/osgVolume/Property b/include/osgVolume/Property index babad9e53..642c04245 100644 --- a/include/osgVolume/Property +++ b/include/osgVolume/Property @@ -27,6 +27,7 @@ namespace osgVolume { // forward decarle class Property; class CompositeProperty; +class SwitchProperty; class TransferFunctionProperty; class ScalarProperty; class IsoSurfaceProperty; @@ -36,15 +37,17 @@ class AlphaFuncProperty; class SampleDensityProperty; class TransparencyProperty; -class PropertyVisitor +class OSGVOLUME_EXPORT PropertyVisitor { public: - PropertyVisitor() {} + PropertyVisitor(bool traverseOnlyActiveChildren=true); + virtual ~PropertyVisitor() {} virtual void apply(Property&) {} - virtual void apply(CompositeProperty&) {} + virtual void apply(CompositeProperty&); + virtual void apply(SwitchProperty&); virtual void apply(TransferFunctionProperty&) {} virtual void apply(ScalarProperty&) {} virtual void apply(IsoSurfaceProperty&) {} @@ -53,6 +56,9 @@ class PropertyVisitor virtual void apply(LightingProperty&) {} virtual void apply(SampleDensityProperty&) {} virtual void apply(TransparencyProperty&) {} + + bool _traverseOnlyActiveChildren; + }; @@ -111,6 +117,34 @@ class OSGVOLUME_EXPORT CompositeProperty : public Property Properties _properties; }; + +class OSGVOLUME_EXPORT SwitchProperty : public CompositeProperty +{ + public: + + SwitchProperty(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + SwitchProperty(const SwitchProperty& switchProperty,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); + + META_Object(osgVolume, SwitchProperty); + + virtual void accept(PropertyVisitor& pv) { pv.apply(*this); } + + /** Set which child property is active. + * -1 disables all children.*/ + void setActiveProperty(int i) { _activeProperty = i; } + + /** Get the active property.*/ + int getActiveProperty() const { return _activeProperty; } + + protected: + + virtual ~SwitchProperty() {} + + int _activeProperty; +}; + class OSGVOLUME_EXPORT TransferFunctionProperty : public Property { public: @@ -294,12 +328,10 @@ class OSGVOLUME_EXPORT CollectPropertiesVisitor : public osgVolume::PropertyVisi { public: - CollectPropertiesVisitor(); + CollectPropertiesVisitor(bool traverseOnlyActiveChildren=true); virtual void apply(Property&); - - virtual void apply(CompositeProperty& cp); - virtual void apply(TransferFunctionProperty& tf); + virtual void apply(TransferFunctionProperty&); virtual void apply(ScalarProperty&); virtual void apply(IsoSurfaceProperty& iso); virtual void apply(AlphaFuncProperty& af); @@ -308,13 +340,13 @@ class OSGVOLUME_EXPORT CollectPropertiesVisitor : public osgVolume::PropertyVisi virtual void apply(SampleDensityProperty& sdp); virtual void apply(TransparencyProperty& tp); - osg::ref_ptr _tfProperty; - osg::ref_ptr _isoProperty; - osg::ref_ptr _afProperty; - osg::ref_ptr _mipProperty; - osg::ref_ptr _lightingProperty; - osg::ref_ptr _sampleDensityProperty; - osg::ref_ptr _transparencyProperty; + osg::ref_ptr _tfProperty; + osg::ref_ptr _isoProperty; + osg::ref_ptr _afProperty; + osg::ref_ptr _mipProperty; + osg::ref_ptr _lightingProperty; + osg::ref_ptr _sampleDensityProperty; + osg::ref_ptr _transparencyProperty; }; @@ -328,6 +360,12 @@ class PropertyAdjustmentCallback : public osgGA::GUIEventHandler, public osg::St META_Object(osgVolume,PropertyAdjustmentCallback); + void setKeyEventCycleForward(int key) { _cyleForwardKey = key; } + int getKeyEventCyclesForward() const { return _cyleForwardKey; } + + void setKeyEventCycleBackward(int key) { _cyleBackwardKey = key; } + int getKeyEventCyclesBackward() const { return _cyleBackwardKey; } + void setKeyEventActivatesTransparenyAdjustment(int key) { _transparencyKey = key; } int getKeyEventActivatesTransparenyAdjustment() const { return _transparencyKey; } @@ -338,7 +376,9 @@ class PropertyAdjustmentCallback : public osgGA::GUIEventHandler, public osg::St int getKeyEventActivatesAlphaFuncAdjustment() const { return _alphaFuncKey; } virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&, osg::Object* object, osg::NodeVisitor*); - + + int _cyleForwardKey; + int _cyleBackwardKey; int _transparencyKey; int _alphaFuncKey; int _sampleDensityKey; @@ -347,6 +387,7 @@ class PropertyAdjustmentCallback : public osgGA::GUIEventHandler, public osg::St bool _updateAlphaCutOff; bool _updateSampleDensity; }; + } #endif diff --git a/src/osgVolume/Property.cpp b/src/osgVolume/Property.cpp index 04e27b077..9ee9ba56f 100644 --- a/src/osgVolume/Property.cpp +++ b/src/osgVolume/Property.cpp @@ -48,6 +48,21 @@ void CompositeProperty::clear() _properties.clear(); } +///////////////////////////////////////////////////////////////////////////// +// +// SwitchProperty +// +SwitchProperty::SwitchProperty() +{ +} + +SwitchProperty::SwitchProperty(const SwitchProperty& switchProperty, const osg::CopyOp& copyop): + CompositeProperty(switchProperty,copyop), + _activeProperty(switchProperty._activeProperty) +{ +} + + ///////////////////////////////////////////////////////////////////////////// // // TransferFunctionProperty @@ -180,13 +195,14 @@ TransparencyProperty::TransparencyProperty(const TransparencyProperty& isp,const ///////////////////////////////////////////////////////////////////////////// // -// CollectPropertiesVisitor +// PropertyVisitor // -CollectPropertiesVisitor::CollectPropertiesVisitor() {} +PropertyVisitor::PropertyVisitor(bool traverseOnlyActiveChildren): + _traverseOnlyActiveChildren(traverseOnlyActiveChildren) +{ +} -void CollectPropertiesVisitor::apply(Property&) {} - -void CollectPropertiesVisitor::apply(CompositeProperty& cp) +void PropertyVisitor::apply(CompositeProperty& cp) { for(unsigned int i=0; i=0 && sp.getActiveProperty()(sp.getNumProperties())) + { + sp.getProperty(sp.getActiveProperty())->accept(*this); + } + } + else + { + for(unsigned int i=0; iaccept(*this); + } + } +} + + +///////////////////////////////////////////////////////////////////////////// +// +// CollectPropertiesVisitor +// +CollectPropertiesVisitor::CollectPropertiesVisitor(bool traverseOnlyActiveChildren): + PropertyVisitor(traverseOnlyActiveChildren) +{ +} + +void CollectPropertiesVisitor::apply(Property&) {} void CollectPropertiesVisitor::apply(TransferFunctionProperty& tf) { _tfProperty = &tf; } void CollectPropertiesVisitor::apply(ScalarProperty&) {} void CollectPropertiesVisitor::apply(IsoSurfaceProperty& iso) { _isoProperty = &iso; } @@ -204,12 +249,64 @@ void CollectPropertiesVisitor::apply(SampleDensityProperty& sdp) { _sampleDensit void CollectPropertiesVisitor::apply(TransparencyProperty& tp) { _transparencyProperty = &tp; } +class CycleSwitchVisitor : public osgVolume::PropertyVisitor +{ + public: + + CycleSwitchVisitor(int delta): + PropertyVisitor(false), + _delta(delta), + _switchModified(true) {} + + virtual void apply(SwitchProperty& sp) + { + if (sp.getNumProperties()>=2) + { + if (_delta>0) + { + int newValue = sp.getActiveProperty()+_delta; + if (newValue(sp.getNumProperties())) + { + sp.setActiveProperty(newValue); + } + else + { + sp.setActiveProperty(0); + } + + _switchModified = true; + } + else // _delta<0 + { + int newValue = sp.getActiveProperty()+_delta; + if (newValue>=0) + { + sp.setActiveProperty(newValue); + } + else + { + sp.setActiveProperty(sp.getNumProperties()-1); + } + + _switchModified = true; + } + } + + PropertyVisitor::apply(sp); + } + + int _delta; + bool _switchModified; +}; + ///////////////////////////////////////////////////////////////////////////// // // PropertyAdjustmentCallback // PropertyAdjustmentCallback::PropertyAdjustmentCallback() { + _cyleForwardKey = 'v'; + _cyleBackwardKey = 'V'; _transparencyKey = 't'; _alphaFuncKey = 'a'; _sampleDensityKey = 'd'; @@ -264,16 +361,26 @@ bool PropertyAdjustmentCallback::handle(const osgGA::GUIEventAdapter& ea,osgGA:: } case(osgGA::GUIEventAdapter::KEYDOWN): { - if (ea.getKey()=='t') _updateTransparency = true; - if (ea.getKey()=='a') _updateAlphaCutOff = true; - if (ea.getKey()=='d') _updateSampleDensity = true; + if (ea.getKey()==_cyleForwardKey || ea.getKey()==_cyleBackwardKey) + { + CycleSwitchVisitor csv( (ea.getKey()==_cyleForwardKey) ? 1 : -1); + property->accept(csv); + if (csv._switchModified) + { + tile->setDirty(true); + tile->init(); + } + } + else if (ea.getKey()==_transparencyKey) _updateTransparency = true; + else if (ea.getKey()==_alphaFuncKey) _updateAlphaCutOff = true; + else if (ea.getKey()==_sampleDensityKey) _updateSampleDensity = true; break; } case(osgGA::GUIEventAdapter::KEYUP): { - if (ea.getKey()=='t') _updateTransparency = false; - if (ea.getKey()=='a') _updateAlphaCutOff = false; - if (ea.getKey()=='d') _updateSampleDensity = false; + if (ea.getKey()==_transparencyKey) _updateTransparency = false; + else if (ea.getKey()==_alphaFuncKey) _updateAlphaCutOff = false; + else if (ea.getKey()==_sampleDensityKey) _updateSampleDensity = false; break; } default: diff --git a/src/osgWrappers/osgVolume/Property.cpp b/src/osgWrappers/osgVolume/Property.cpp index 80a5fde00..51377828e 100644 --- a/src/osgWrappers/osgVolume/Property.cpp +++ b/src/osgWrappers/osgVolume/Property.cpp @@ -96,20 +96,17 @@ END_REFLECTOR BEGIN_OBJECT_REFLECTOR(osgVolume::CollectPropertiesVisitor) I_DeclaringFile("osgVolume/Property"); I_BaseType(osgVolume::PropertyVisitor); - I_Constructor0(____CollectPropertiesVisitor, - "", - ""); + I_ConstructorWithDefaults1(IN, bool, traverseOnlyActiveChildren, true, + Properties::NON_EXPLICIT, + ____CollectPropertiesVisitor__bool, + "", + ""); I_Method1(void, apply, IN, osgVolume::Property &, x, Properties::VIRTUAL, __void__apply__Property_R1, "", ""); - I_Method1(void, apply, IN, osgVolume::CompositeProperty &, cp, - Properties::VIRTUAL, - __void__apply__CompositeProperty_R1, - "", - ""); - I_Method1(void, apply, IN, osgVolume::TransferFunctionProperty &, tf, + I_Method1(void, apply, IN, osgVolume::TransferFunctionProperty &, x, Properties::VIRTUAL, __void__apply__TransferFunctionProperty_R1, "", @@ -447,6 +444,26 @@ BEGIN_OBJECT_REFLECTOR(osgVolume::PropertyAdjustmentCallback) __C5_char_P1__className, "return the name of the object's class type. ", "Must be defined by derived classes. "); + I_Method1(void, setKeyEventCycleForward, IN, int, key, + Properties::NON_VIRTUAL, + __void__setKeyEventCycleForward__int, + "", + ""); + I_Method0(int, getKeyEventCyclesForward, + Properties::NON_VIRTUAL, + __int__getKeyEventCyclesForward, + "", + ""); + I_Method1(void, setKeyEventCycleBackward, IN, int, key, + Properties::NON_VIRTUAL, + __void__setKeyEventCycleBackward__int, + "", + ""); + I_Method0(int, getKeyEventCyclesBackward, + Properties::NON_VIRTUAL, + __int__getKeyEventCyclesBackward, + "", + ""); I_Method1(void, setKeyEventActivatesTransparenyAdjustment, IN, int, key, Properties::NON_VIRTUAL, __void__setKeyEventActivatesTransparenyAdjustment__int, @@ -494,6 +511,20 @@ BEGIN_OBJECT_REFLECTOR(osgVolume::PropertyAdjustmentCallback) I_SimpleProperty(int, KeyEventActivatesTransparenyAdjustment, __int__getKeyEventActivatesTransparenyAdjustment, __void__setKeyEventActivatesTransparenyAdjustment__int); + I_SimpleProperty(int, KeyEventCycleBackward, + 0, + __void__setKeyEventCycleBackward__int); + I_SimpleProperty(int, KeyEventCycleForward, + 0, + __void__setKeyEventCycleForward__int); + I_SimpleProperty(int, KeyEventCyclesBackward, + __int__getKeyEventCyclesBackward, + 0); + I_SimpleProperty(int, KeyEventCyclesForward, + __int__getKeyEventCyclesForward, + 0); + I_PublicMemberProperty(int, _cyleForwardKey); + I_PublicMemberProperty(int, _cyleBackwardKey); I_PublicMemberProperty(int, _transparencyKey); I_PublicMemberProperty(int, _alphaFuncKey); I_PublicMemberProperty(int, _sampleDensityKey); @@ -504,9 +535,11 @@ END_REFLECTOR BEGIN_VALUE_REFLECTOR(osgVolume::PropertyVisitor) I_DeclaringFile("osgVolume/Property"); - I_Constructor0(____PropertyVisitor, - "", - ""); + I_ConstructorWithDefaults1(IN, bool, traverseOnlyActiveChildren, true, + Properties::NON_EXPLICIT, + ____PropertyVisitor__bool, + "", + ""); I_Method1(void, apply, IN, osgVolume::Property &, x, Properties::VIRTUAL, __void__apply__Property_R1, @@ -517,6 +550,11 @@ BEGIN_VALUE_REFLECTOR(osgVolume::PropertyVisitor) __void__apply__CompositeProperty_R1, "", ""); + I_Method1(void, apply, IN, osgVolume::SwitchProperty &, x, + Properties::VIRTUAL, + __void__apply__SwitchProperty_R1, + "", + ""); I_Method1(void, apply, IN, osgVolume::TransferFunctionProperty &, x, Properties::VIRTUAL, __void__apply__TransferFunctionProperty_R1, @@ -557,6 +595,7 @@ BEGIN_VALUE_REFLECTOR(osgVolume::PropertyVisitor) __void__apply__TransparencyProperty_R1, "", ""); + I_PublicMemberProperty(bool, _traverseOnlyActiveChildren); END_REFLECTOR BEGIN_OBJECT_REFLECTOR(osgVolume::SampleDensityProperty) @@ -675,6 +714,61 @@ BEGIN_OBJECT_REFLECTOR(osgVolume::ScalarProperty) __void__setValue__float); END_REFLECTOR +BEGIN_OBJECT_REFLECTOR(osgVolume::SwitchProperty) + I_DeclaringFile("osgVolume/Property"); + I_BaseType(osgVolume::CompositeProperty); + I_Constructor0(____SwitchProperty, + "", + ""); + I_ConstructorWithDefaults2(IN, const osgVolume::SwitchProperty &, switchProperty, , IN, const osg::CopyOp &, copyop, osg::CopyOp::SHALLOW_COPY, + ____SwitchProperty__C5_SwitchProperty_R1__C5_osg_CopyOp_R1, + "Copy constructor using CopyOp to manage deep vs shallow copy. ", + ""); + I_Method0(osg::Object *, cloneType, + Properties::VIRTUAL, + __osg_Object_P1__cloneType, + "Clone the type of an object, with Object* return type. ", + "Must be defined by derived classes. "); + I_Method1(osg::Object *, clone, IN, const osg::CopyOp &, copyop, + Properties::VIRTUAL, + __osg_Object_P1__clone__C5_osg_CopyOp_R1, + "Clone an object, with Object* return type. ", + "Must be defined by derived classes. "); + I_Method1(bool, isSameKindAs, IN, const osg::Object *, obj, + Properties::VIRTUAL, + __bool__isSameKindAs__C5_osg_Object_P1, + "", + ""); + I_Method0(const char *, libraryName, + Properties::VIRTUAL, + __C5_char_P1__libraryName, + "return the name of the object's library. ", + "Must be defined by derived classes. The OpenSceneGraph convention is that the namespace of a library is the same as the library name. "); + I_Method0(const char *, className, + Properties::VIRTUAL, + __C5_char_P1__className, + "return the name of the object's class type. ", + "Must be defined by derived classes. "); + I_Method1(void, accept, IN, osgVolume::PropertyVisitor &, pv, + Properties::VIRTUAL, + __void__accept__PropertyVisitor_R1, + "", + ""); + I_Method1(void, setActiveProperty, IN, int, i, + Properties::NON_VIRTUAL, + __void__setActiveProperty__int, + "Set which child property is active. ", + "-1 disables all children. "); + I_Method0(int, getActiveProperty, + Properties::NON_VIRTUAL, + __int__getActiveProperty, + "Get the active property. ", + ""); + I_SimpleProperty(int, ActiveProperty, + __int__getActiveProperty, + __void__setActiveProperty__int); +END_REFLECTOR + BEGIN_OBJECT_REFLECTOR(osgVolume::TransferFunctionProperty) I_DeclaringFile("osgVolume/Property"); I_BaseType(osgVolume::Property);