Layer 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2009 Robert Osfield
  2. *
  3. * This library is open source and may be redistributed and/or modified under
  4. * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  5. * (at your option) any later version. The full license is in LICENSE file
  6. * included with this distribution, and on the openscenegraph.org website.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * OpenSceneGraph Public License for more details.
  12. */
  13. #ifndef OSGVOLUME_LAYER
  14. #define OSGVOLUME_LAYER 1
  15. #include <osg/Image>
  16. #include <osg/TransferFunction>
  17. #include <osgVolume/Locator>
  18. #include <osgVolume/Property>
  19. namespace osgVolume {
  20. /** Data strucutre for passing details about the loading imagery on to osgVolume for use when setting up dimensions etc.*/
  21. class OSGVOLUME_EXPORT ImageDetails : public osg::Object
  22. {
  23. public:
  24. ImageDetails();
  25. /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
  26. ImageDetails(const ImageDetails&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
  27. META_Object(osgVolume, ImageDetails);
  28. void setTexelOffset(const osg::Vec4& offset) { _texelOffset = offset; }
  29. const osg::Vec4& getTexelOffset() const { return _texelOffset; }
  30. void setTexelScale(const osg::Vec4& scale) { _texelScale = scale; }
  31. const osg::Vec4& getTexelScale() const { return _texelScale; }
  32. void setMatrix(osg::RefMatrix* matrix) { _matrix = matrix; }
  33. osg::RefMatrix* getMatrix() { return _matrix.get(); }
  34. const osg::RefMatrix* getMatrix() const { return _matrix.get(); }
  35. protected:
  36. osg::Vec4 _texelOffset;
  37. osg::Vec4 _texelScale;
  38. osg::ref_ptr<osg::RefMatrix> _matrix;
  39. };
  40. /** Base class for representing a single layer of volume data.*/
  41. class OSGVOLUME_EXPORT Layer : public osg::Object
  42. {
  43. public:
  44. Layer();
  45. /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
  46. Layer(const Layer&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
  47. META_Object(osgVolume, Layer);
  48. /** Set the file name of the data associated with this layer. */
  49. virtual void setFileName(const std::string& filename) { _filename = filename; }
  50. /** Get the file name of the layer. */
  51. virtual const std::string& getFileName() const { return _filename; }
  52. void setLocator(Locator* locator) { _locator = locator; }
  53. template<class T> void setLocator(const osg::ref_ptr<T>& locator) { setLocator(locator.get()); }
  54. Locator* getLocator() { return _locator.get(); }
  55. const Locator* getLocator() const { return _locator.get(); }
  56. void setDefaultValue(const osg::Vec4& value) { _defaultValue = value; }
  57. const osg::Vec4& getDefaultValue() const { return _defaultValue; }
  58. /** Set the minification texture filter to use when do texture associated with this layer.*/
  59. void setMinFilter(osg::Texture::FilterMode filter) { _minFilter = filter; }
  60. /** Get the minification texture filter to use when do texture associated with this layer.*/
  61. osg::Texture::FilterMode getMinFilter() const { return _minFilter; }
  62. /** Set the magniification texture filter to use when do texture associated with this layer.*/
  63. void setMagFilter(osg::Texture::FilterMode filter) { _magFilter = filter; }
  64. /** Get the magnification texture filter to use when do texture associated with this layer.*/
  65. osg::Texture::FilterMode getMagFilter() const { return _magFilter; }
  66. /** Return image associated with layer if supported. */
  67. virtual osg::Image* getImage() { return 0; }
  68. /** Return const image associated with layer if supported. */
  69. virtual const osg::Image* getImage() const { return 0; }
  70. /** Set the Property (or Properties via the CompositeProperty) that informs the VolumeTechnique how this layer should be rendered.*/
  71. void setProperty(Property* property) { _property = property; }
  72. template<class T> void setProperty(const osg::ref_ptr<T>& p) { setProperty(p.get()); }
  73. /** Get the Property that informs the VolumeTechnique how this layer should be rendered.*/
  74. Property* getProperty() { return _property.get(); }
  75. /** Get the const Property that informs the VolumeTechnique how this layer should be rendered.*/
  76. const Property* getProperty() const { return _property.get(); }
  77. /** Add a property, automatically creating a CompositePorperty if one isn't already assigned.*/
  78. void addProperty(Property* property);
  79. template<class T> void addProperty(const osg::ref_ptr<T>& p) { addProperty(p.get()); }
  80. /** Specify whether ImageLayer requires update traversal. */
  81. virtual bool requiresUpdateTraversal() const { return false; }
  82. /** Call update on the Layer.*/
  83. virtual void update(osg::NodeVisitor& /*nv*/) {}
  84. /** increment the modified count."*/
  85. virtual void dirty() {};
  86. /** Set the modified count value. */
  87. virtual void setModifiedCount(unsigned int /*value*/) {};
  88. /** Get modified count value. */
  89. virtual unsigned int getModifiedCount() const { return 0; }
  90. virtual osg::BoundingSphere computeBound() const;
  91. protected:
  92. virtual ~Layer();
  93. std::string _filename;
  94. osg::ref_ptr<Locator> _locator;
  95. osg::Vec4 _defaultValue;
  96. osg::Texture::FilterMode _minFilter;
  97. osg::Texture::FilterMode _magFilter;
  98. osg::ref_ptr<Property> _property;
  99. };
  100. class OSGVOLUME_EXPORT ImageLayer : public Layer
  101. {
  102. public:
  103. ImageLayer(osg::Image* image=0);
  104. /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
  105. ImageLayer(const ImageLayer& imageLayer,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
  106. META_Object(osgVolume, ImageLayer);
  107. void setFileName(const std::string& filename) { _filename = filename; if (_image.valid()) _image->setFileName(filename); }
  108. virtual const std::string& getFileName() const { return _image.get() ? _image->getFileName() : _filename; }
  109. void setImage(osg::Image* image);
  110. template<class T> void setImage(const osg::ref_ptr<T>& image) { setImage(image.get()); }
  111. /** Return image associated with layer. */
  112. virtual osg::Image* getImage() { return _image.get(); }
  113. /** Return const image associated with layer. */
  114. virtual const osg::Image* getImage() const { return _image.get(); }
  115. void setTexelOffset(const osg::Vec4& offset) { _texelOffset = offset; }
  116. const osg::Vec4& getTexelOffset() const { return _texelOffset; }
  117. void setTexelScale(const osg::Vec4& scale) { _texelScale = scale; }
  118. const osg::Vec4& getTexelScale() const { return _texelScale; }
  119. /** Compute the min and max pixel colors.*/
  120. bool computeMinMax(osg::Vec4& min, osg::Vec4& max);
  121. /** Apply color transformation to pixels using c' = offset + c * scale .*/
  122. void offsetAndScaleImage(const osg::Vec4& offset, const osg::Vec4& scale);
  123. /** Compute the min max range of the image, and then remap this to a 0 to 1 range.*/
  124. void rescaleToZeroToOneRange();
  125. /** Compute the min color component of the image and then translate and pixels by this offset to make the new min component 0.*/
  126. void translateMinToZero();
  127. virtual bool requiresUpdateTraversal() const;
  128. virtual void update(osg::NodeVisitor& /*nv*/);
  129. virtual void dirty();
  130. virtual void setModifiedCount(unsigned int value);
  131. virtual unsigned int getModifiedCount() const;
  132. protected:
  133. virtual ~ImageLayer() {}
  134. osg::Vec4 _texelOffset;
  135. osg::Vec4 _texelScale;
  136. osg::ref_ptr<osg::Image> _image;
  137. };
  138. class OSGVOLUME_EXPORT CompositeLayer : public Layer
  139. {
  140. public:
  141. CompositeLayer();
  142. /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
  143. CompositeLayer(const CompositeLayer& compositeLayer,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
  144. META_Object(osgVolume, CompositeLayer);
  145. void clear();
  146. void setFileName(unsigned int i, const std::string& filename) { if (i>=_layers.size()) _layers.resize(i+1); _layers[i].filename = filename; if (_layers[i].layer.valid()) _layers[i].layer->setFileName(filename); }
  147. const std::string& getFileName(unsigned int i) const { return _layers[i].layer.valid() ? _layers[i].layer->getFileName() : _layers[i].filename; }
  148. void setLayer(unsigned int i, Layer* layer) { if (i>=_layers.size()) _layers.resize(i+1); _layers[i].layer = layer; }
  149. template<class T> void setLayer(unsigned int i, const osg::ref_ptr<T>& layer) { setLayer(i, layer.get()); }
  150. Layer* getLayer(unsigned int i) { return i<_layers.size() ? _layers[i].layer.get() : 0; }
  151. const Layer* getLayer(unsigned int i) const { return i<_layers.size() ? _layers[i].layer.get() : 0; }
  152. void addLayer(Layer* layer) { _layers.push_back(NameLayer(layer->getFileName(),layer)); }
  153. template<class T> void addLayer(const osg::ref_ptr<T>& layer) { addLayer(layer.get()); }
  154. void removeLayer(unsigned int i) { _layers.erase(_layers.begin()+i); }
  155. unsigned int getNumLayers() const { return _layers.size(); }
  156. bool requiresUpdateTraversal() const;
  157. virtual void update(osg::NodeVisitor& /*nv*/);
  158. protected:
  159. virtual ~CompositeLayer() {}
  160. struct NameLayer
  161. {
  162. NameLayer() {}
  163. NameLayer(const NameLayer& cnl):
  164. filename(cnl.filename),
  165. layer(cnl.layer) {}
  166. NameLayer(const std::string& fn, Layer* l):
  167. filename(fn),
  168. layer(l) {}
  169. NameLayer& operator = (const NameLayer& cnl)
  170. {
  171. if (&cnl==this) return *this;
  172. filename = cnl.filename;
  173. layer = cnl.layer;
  174. return *this;
  175. }
  176. std::string filename;
  177. osg::ref_ptr<Layer> layer;
  178. };
  179. typedef std::vector< NameLayer > Layers;
  180. Layers _layers;
  181. };
  182. /** Compute a 3d image that represent the normal map of the specified 3d image.*/
  183. extern OSGVOLUME_EXPORT osg::Image* createNormalMapTexture(osg::Image* image_3d);
  184. /** Create an image that has a transfer function applied specified Image.*/
  185. extern OSGVOLUME_EXPORT osg::Image* applyTransferFunction(osg::Image* image, osg::TransferFunction1D* transferFunction);
  186. }
  187. #endif