diff --git a/include/osgPresentation/PropertyManager b/include/osgPresentation/PropertyManager index d9c9ebdd8..d345a8c2f 100644 --- a/include/osgPresentation/PropertyManager +++ b/include/osgPresentation/PropertyManager @@ -21,6 +21,8 @@ #include +#include + namespace osgPresentation { @@ -62,6 +64,69 @@ protected: }; +const osg::Object* OSGPRESENTATION_EXPORT getUserObject(const osg::NodePath& nodepath, const std::string& name); + +template +bool getUserValue(const osg::NodePath& nodepath, const std::string& name, T& value) +{ + typedef osg::TemplateValueObject UserValueObject; + const osg::Object* object = getUserObject(nodepath, name); + const UserValueObject* uvo = dynamic_cast(object); + + if (uvo) + { + value = uvo->getValue(); + return true; + } + else + { + return false; + } +} + +bool OSGPRESENTATION_EXPORT containsPropertyReference(const std::string& str); + +struct PropertyReader +{ + PropertyReader(const osg::NodePath& nodePath, const std::string& str): + _nodePath(nodePath), + _sstream(str) {} + + template + bool read(T& value) + { + // skip white space. + while(!_sstream.fail() && _sstream.peek()==' ') _sstream.ignore(); + + // check to see if a &propertyName is used. + if (_sstream.peek()=='$') + { + std::string propertyName; + _sstream.ignore(1); + _sstream >> propertyName; + OSG_NOTICE<<"Reading propertyName="<> value; + OSG_NOTICE<<"Reading value="< + PropertyReader& operator>>( T& value ) { read(value); return *this; } + + bool ok() { return !_sstream.fail(); } + bool fail() { return _sstream.fail(); } + + osg::NodePath _nodePath; + std::istringstream _sstream; +}; + + class OSGPRESENTATION_EXPORT PropertyAnimation : public osg::NodeCallback { public: diff --git a/include/osgPresentation/SlideShowConstructor b/include/osgPresentation/SlideShowConstructor index 93d108309..9ec347148 100644 --- a/include/osgPresentation/SlideShowConstructor +++ b/include/osgPresentation/SlideShowConstructor @@ -28,6 +28,9 @@ #include +#include +#include + #include #include #include @@ -300,10 +303,9 @@ public: useTabbedDragger(false), useTrackballDragger(false), region_in_pixel_coords(false), - alphaValue(1.0), - cutoffValue(0.1), - sampleDensityValue(0.005), - sampleDensityWhenMovingValue(0.0), + alphaValue("1.0"), + cutoffValue("0.1"), + sampleDensityValue("0.005"), colorSpaceOperation(osg::NO_COLOR_SPACE_OPERATION), colorModulate(1.0f,1.0f,1.0f,1.0f) { @@ -316,12 +318,12 @@ public: osg::ref_ptr transferFunction; bool useTabbedDragger; bool useTrackballDragger; - float region[6]; + std::string region; bool region_in_pixel_coords; - float alphaValue; - float cutoffValue; - float sampleDensityValue; - float sampleDensityWhenMovingValue; + std::string alphaValue; + std::string cutoffValue; + std::string sampleDensityValue; + std::string sampleDensityWhenMovingValue; osg::ColorSpaceOperation colorSpaceOperation; osg::Vec4 colorModulate; @@ -461,6 +463,8 @@ public: void addModel(const std::string& filename, const PositionData& positionData, const ModelData& modelData); + void setUpVolumeScalarProperty(osgVolume::VolumeTile* tile, osgVolume::ScalarProperty* property, const std::string& source); + void addVolume(const std::string& filename, const PositionData& positionData, const VolumeData& volumeData); osg::Group* takePresentation() { return _root.release(); } diff --git a/include/osgVolume/Property b/include/osgVolume/Property index d24e990d1..5c2c955e0 100644 --- a/include/osgVolume/Property +++ b/include/osgVolume/Property @@ -216,7 +216,7 @@ class OSGVOLUME_EXPORT IsoSurfaceProperty : public ScalarProperty { public: - IsoSurfaceProperty(float value=1.0); + IsoSurfaceProperty(float value=1.0f); IsoSurfaceProperty(const IsoSurfaceProperty& isp,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); @@ -233,7 +233,7 @@ class OSGVOLUME_EXPORT AlphaFuncProperty : public ScalarProperty { public: - AlphaFuncProperty(float value=1.0); + AlphaFuncProperty(float value=1.0f); AlphaFuncProperty(const AlphaFuncProperty& isp,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); @@ -296,7 +296,7 @@ class OSGVOLUME_EXPORT SampleDensityProperty : public ScalarProperty { public: - SampleDensityProperty(float value=1.0); + SampleDensityProperty(float value=1.0f); SampleDensityProperty(const SampleDensityProperty& isp,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); @@ -314,7 +314,7 @@ class OSGVOLUME_EXPORT SampleDensityWhenMovingProperty : public ScalarProperty { public: - SampleDensityWhenMovingProperty(float value=1.0); + SampleDensityWhenMovingProperty(float value=1.0f); SampleDensityWhenMovingProperty(const SampleDensityWhenMovingProperty& isp,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); @@ -331,7 +331,7 @@ class OSGVOLUME_EXPORT TransparencyProperty : public ScalarProperty { public: - TransparencyProperty(float value=1.0); + TransparencyProperty(float value=1.0f); TransparencyProperty(const TransparencyProperty& isp,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); diff --git a/src/osgPlugins/p3d/ReaderWriterP3D.cpp b/src/osgPlugins/p3d/ReaderWriterP3D.cpp index 623fba4bc..9141b34f3 100644 --- a/src/osgPlugins/p3d/ReaderWriterP3D.cpp +++ b/src/osgPlugins/p3d/ReaderWriterP3D.cpp @@ -1202,7 +1202,7 @@ void ReaderWriterP3DXML::parseVolume(osgPresentation::SlideShowConstructor& cons if (getProperty(cur, "alpha", volumeData.alphaValue)) {} if (getProperty(cur, "cutoff", volumeData.cutoffValue)) {} - if (getProperty(cur, "region", 6, volumeData.region)) {} + if (getProperty(cur, "region", volumeData.region)) {} if (getProperty(cur, "sampleDensity", volumeData.sampleDensityValue)) {} if (getProperty(cur, "sampleDensityWhenMoving", volumeData.sampleDensityWhenMovingValue)) {} diff --git a/src/osgPresentation/PropertyManager.cpp b/src/osgPresentation/PropertyManager.cpp index e06166726..deabebd04 100644 --- a/src/osgPresentation/PropertyManager.cpp +++ b/src/osgPresentation/PropertyManager.cpp @@ -15,6 +15,24 @@ using namespace osgPresentation; +const osg::Object* osgPresentation::getUserObject(const osg::NodePath& nodepath, const std::string& name) +{ + for(osg::NodePath::const_reverse_iterator itr = nodepath.rbegin(); + itr != nodepath.rend(); + ++itr) + { + const osg::UserDataContainer* udc = (*itr)->getUserDataContainer(); + const osg::Object* object = udc ? udc->getUserObject(name) : 0; + if (object) return object; + } + return 0; +} + +bool osgPresentation::containsPropertyReference(const std::string& str) +{ + return (str.find('$')!=std::string::npos); +} + void PropertyAnimation::reset() diff --git a/src/osgPresentation/SlideShowConstructor.cpp b/src/osgPresentation/SlideShowConstructor.cpp index 76741c782..d62f9e7a0 100644 --- a/src/osgPresentation/SlideShowConstructor.cpp +++ b/src/osgPresentation/SlideShowConstructor.cpp @@ -624,6 +624,7 @@ void SlideShowConstructor::layerClickEventOperation(const KeyPosition& keyPos, c } + void SlideShowConstructor::addPropertyAnimation(PresentationContext presentationContext, PropertyAnimation* propertyAnimation) { switch(presentationContext) @@ -641,7 +642,10 @@ void SlideShowConstructor::addPropertyAnimation(PresentationContext presentation case(CURRENT_LAYER): OSG_NOTICE<<"Need to add PropertyAnimation to layer."<addUpdateCallback(propertyAnimation); + if (_currentLayer.valid()) + { + _currentLayer->addUpdateCallback(propertyAnimation); + } break; } } @@ -2077,6 +2081,118 @@ class VolumeTileCallback : public osg::NodeCallback }; + +struct VolumeRegionCallback : public osg::NodeCallback +{ +public: + VolumeRegionCallback(const osg::Matrixd& originalMatrix, const std::string& str): + _matrix(originalMatrix), + _source(str) {} + + virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + { + osgVolume::VolumeTile* tile = dynamic_cast(node); + osgVolume::Locator* locator = tile ? tile->getLocator() : 0; + if (locator) + { + PropertyReader pr(nv->getNodePath(), _source); + + float xMin=0.0; + float yMin=0.0; + float zMin=0.0; + float xMax=1.0; + float yMax=1.0; + float zMax=1.0; + + pr>>xMin>>yMin>>zMin>>xMax>>yMax>>zMax; + + if (pr.ok()) + { + OSG_NOTICE<<"VolumeRegionCallback : xMin="<getNodePath(), _source); + + float value=0.0; + pr>>value; + + if (pr.ok()) + { + OSG_NOTICE<<"ScalarPropertyCallback : value ["<<_source<<"]="<setValue(value); + } + else + { + OSG_NOTICE<<"Problem in reading, ScalarPropertyCallback : value="<addUpdateCallback(new ScalarPropertyCallback( property, source)); + } + else + { + float value; + std::istringstream sstream(source); + sstream>>value; + property->setValue(value); + } + } +} + + void SlideShowConstructor::addVolume(const std::string& filename, const PositionData& in_positionData, const VolumeData& volumeData) { // osg::Object::DataVariance defaultMatrixDataVariance = osg::Object::DYNAMIC; // STATIC @@ -2235,30 +2351,66 @@ void SlideShowConstructor::addVolume(const std::string& filename, const Position } layer->rescaleToZeroToOneRange(); - osg::Matrix tm = osg::Matrix::scale(volumeData.region[3]-volumeData.region[0], volumeData.region[4]-volumeData.region[1], volumeData.region[5]-volumeData.region[2]) * - osg::Matrix::translate(volumeData.region[0],volumeData.region[1],volumeData.region[2]); - if (matrix.valid()) { layer->setLocator(new osgVolume::Locator(*matrix)); - tile->setLocator(new osgVolume::Locator(tm * (*matrix))); + tile->setLocator(new osgVolume::Locator(*matrix)); } else { layer->setLocator(new osgVolume::Locator()); - tile->setLocator(new osgVolume::Locator(tm)); + tile->setLocator(new osgVolume::Locator()); } + + if (!volumeData.region.empty()) + { + if (containsPropertyReference(volumeData.region)) + { + tile->addUpdateCallback(new VolumeRegionCallback((matrix.valid() ? *matrix : osg::Matrixd::identity()), volumeData.region)); + } + else + { + float region[6]; + std::istringstream sstream(volumeData.region); + sstream>>region[0]>>region[1]>>region[2]>>region[3]>>region[4]>>region[5]; + osg::Matrix tm = osg::Matrix::scale(region[3]-region[0], region[4]-region[1], region[5]-region[2]) * + osg::Matrix::translate(region[0],region[1],region[2]); + if (matrix.valid()) + { + tile->setLocator(new osgVolume::Locator(tm * (*matrix))); + } + else + { + tile->setLocator(new osgVolume::Locator(tm)); + } + } + } + tile->setLayer(layer.get()); osgVolume::SwitchProperty* sp = new osgVolume::SwitchProperty; sp->setActiveProperty(0); - osgVolume::AlphaFuncProperty* ap = new osgVolume::AlphaFuncProperty(volumeData.cutoffValue); - osgVolume::TransparencyProperty* tp = new osgVolume::TransparencyProperty(volumeData.alphaValue); - osgVolume::SampleDensityProperty* sd = new osgVolume::SampleDensityProperty(volumeData.sampleDensityValue); - osgVolume::SampleDensityWhenMovingProperty* sdm = (volumeData.sampleDensityWhenMovingValue > 0.0f) ? (new osgVolume::SampleDensityWhenMovingProperty(volumeData.sampleDensityWhenMovingValue)) : 0; + + + osgVolume::AlphaFuncProperty* ap = new osgVolume::AlphaFuncProperty(0.1f); + setUpVolumeScalarProperty(tile, ap, volumeData.cutoffValue); + + osgVolume::TransparencyProperty* tp = new osgVolume::TransparencyProperty(1.0f); + setUpVolumeScalarProperty(tile, tp, volumeData.alphaValue); + + osgVolume::SampleDensityProperty* sd = new osgVolume::SampleDensityProperty(0.005); + setUpVolumeScalarProperty(tile, sd, volumeData.sampleDensityValue); + + osgVolume::SampleDensityWhenMovingProperty* sdm = 0; + if (!volumeData.sampleDensityWhenMovingValue.empty()) + { + sdm = new osgVolume::SampleDensityWhenMovingProperty(0.005); + setUpVolumeScalarProperty(tile, sdm, volumeData.sampleDensityWhenMovingValue); + } + osgVolume::TransferFunctionProperty* tfp = volumeData.transferFunction.valid() ? new osgVolume::TransferFunctionProperty(volumeData.transferFunction.get()) : 0; { @@ -2291,7 +2443,12 @@ void SlideShowConstructor::addVolume(const std::string& filename, const Position osgVolume::CompositeProperty* cp = new osgVolume::CompositeProperty; cp->addProperty(sd); cp->addProperty(tp); - cp->addProperty(new osgVolume::IsoSurfaceProperty(volumeData.cutoffValue)); + + + osgVolume::IsoSurfaceProperty* isp = new osgVolume::IsoSurfaceProperty(0.1); + setUpVolumeScalarProperty(tile, isp, volumeData.alphaValue); + cp->addProperty(isp); + if (sdm) cp->addProperty(sdm); if (tfp) cp->addProperty(tfp); @@ -2321,9 +2478,12 @@ void SlideShowConstructor::addVolume(const std::string& filename, const Position layer->addProperty(sp); tile->setVolumeTechnique(new osgVolume::RayTracedTechnique); - tile->setEventCallback(new osgVolume::PropertyAdjustmentCallback()); + tile->addEventCallback(new osgVolume::PropertyAdjustmentCallback()); } + + + osg::ref_ptr model = volume.get(); if (volumeData.useTabbedDragger || volumeData.useTrackballDragger) @@ -2357,9 +2517,6 @@ void SlideShowConstructor::addVolume(const std::string& filename, const Position model = group.get(); } - tile->setUpdateCallback(new VolumeTileCallback()); - - ModelData modelData; addModel(model.get(), positionData, modelData); }