HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_HUSDExtraAOVResource.h
Go to the documentation of this file.
1 /*
2  * Copyright 2019 Side Effects Software Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * NAME: UT_HUSDExtraAOVResource.h (UT Library, C++)
17  *
18  * COMMENTS:
19  * Resource Data for to pass extra AOV buffers affiliated with a primary AOV
20  * in a HdRenderBuffer to husk.
21  */
22 
23 #ifndef __UT_HUSDExtraAOVResource__
24 #define __UT_HUSDExtraAOVResource__
25 
26 #include <functional>
27 #include <map>
28 #include <memory>
29 #include <vector>
30 #include <string>
31 
32 /// @brief HUSD Interface for passing Cryptomatte AOV information through Hydra
33 ///
34 /// Hydra has no facility for managing Cryptomatte AOVs. This class can be
35 /// used to pass information between a render delegate and the HuskEngine.
36 ///
37 /// This class is specifically created to not rely on any Houdini or USD
38 /// classes, so it should be relatively save to include this header in any
39 /// delegate's interface (see below for SYS_Inline.h)
40 ///
41 /// The class is defined in UT so that it does not have to be part of the
42 /// Houdini USD bridge and introduce any unwanted dependencies on the HUSD
43 /// library.
44 ///
45 /// If a render delegate wants to have a single AOV declare multiple child AOVs
46 /// (extra/affiliated AOVs) in offline rendering in husk, the delegate can
47 /// create a subclass for it's AOV buffers from HdRenderBuffer. The sub-class
48 /// should implement the @c GetResource virtual and return VtValue storing a
49 /// UT_HUSDExtraAOVResourcePtr.
50 ///
51 /// This class lets a single AOV have multiple extra AOVs associated with it.
52 ///
53 /// An example of this might be Cryptomatte AOVs where a single AOV is defined
54 /// in the USD file, but then additional AOVs are created in the renderer to
55 /// store additional data for cryptomatte layers. This interface isn't limited
56 /// to cryptomatte, but can be used for any affiliated AOVs.
57 ///
58 /// For example, a delegate might do something like @code
59 /// class AOVBuffer : public HdRenderBuffer
60 /// {
61 /// // Code to map the buffer data for the extra AOV. This is similar to the
62 /// // Map() function, but returns the data buffer for the extra AOV.
63 /// void *mapExtra(int idx) { ... }
64 ///
65 /// // Unmap the extra AOV buffer
66 /// void unmapExtra(int idx) { ... }
67 ///
68 /// VtValue GetResource(bool) const {
69 /// auto resource = std::make_shared<UT_HUSDExtraAOVResource>();
70 /// resource->myMap = [=](int idx) { return this->mapExtra(idx); };
71 /// resource->myUnmap = [=](int idx) { this->unmapExtra(idx); };
72 /// for (int i = 0; i < numExtraPlanes; ++i)
73 /// resource->addPlane(extraName[i], extraFormat[i]);
74 /// for (auto &&meta : extraMetadata)
75 /// resource->addMetadata(meta.first, meta.second);
76 /// return VtValue(resource);
77 /// }
78 /// std::vector<std::string> extraName;
79 /// std::vector<HdFormat> extraFormat;
80 /// std::map<std::string, std::string> extraMetadata;
81 /// };
82 /// @endcode
83 ///
84 /// For example, in Karma, when an AOV sees a render var for cryptomatte: @code
85 /// def RenderVar "MaterialChan" {
86 /// ...
87 /// bool driver:parameters:aov:cryptomatte = 1
88 /// int driver:parameters:aov:cryptomatterank = 6
89 /// string driver:parameters:aov:cryptomattesidecar = "manifest.txt"
90 // token driver:parameters:aov:format = "color3f"
91 /// @endcode
92 /// Karma will internally create additional buffers for "MaterialChan" AOV and
93 /// provide the function to map the AOVs. The resource object would look
94 /// something like:
95 /// @code
96 /// resource->addPlane("MaterialChan00", HdFormatFloat32Vec4);
97 /// resource->addPlane("MaterialChan01", HdFormatFloat32Vec4);
98 /// resource->addPlane("MaterialChan02", HdFormatFloat32Vec4);
99 ///
100 /// // The metadata must begin with "cryptomatte" and each key should be unique.
101 /// resource->addMetadata("cryptomatte/fea6747/conversion", "uint32_to_float32");
102 /// resource->addMetadata("cryptomatte/fea6747/manif_file", "manifest.txt");
103 /// resource->addMetadata("cryptomatte/fea6747/hash", "MurmurHash3_32");
104 /// resource->addMetadata("cryptomatte/fea6747/manifest",
105 /// "{\"boxmat\":\"dce1d1e6\",\"spheremat\":\"710681f7\"}");
106 /// @endcode
107 ///
108 /// While it may be possible to store a UT_HUSDExtraAOVResourcePtr directly
109 /// in the VtValue, the preferred method for passing this resource to
110 /// @c husk is to store to return a VtValue holding a HdAovSettingsMap.
111 /// This is due to symbol visibility and other issues.
112 ///
113 /// The value in the map should be shared pointer stored behind an opaque
114 /// shared void ptr. Houdini/husk will look for a shared_ptr<void> with
115 /// the "extra_aov_resource" key and use a static cast to a
116 /// UT_HUSDExtraAOVResourcePtr. The @c void pointer is only used to pass
117 /// the shared ptr through the libraries. This mechanism allows the
118 /// delegate to construct it's own struct, in its own codebase without
119 /// relying on Houdini's libraries at all. For example: @code
120 /// VtValue
121 /// DelegateAOVBuffer::GetResource(bool) const {
122 /// UT_HUSDExtraAOVResourcePtr extra_aovs = makeExtraAOVResource();
123 ///
124 /// HdAovSettingsMap map;
125 /// map.insert(TfToken("extra_aov_resource"),
126 /// VtValue(std::static_pointer_cast<void>(extra_aovs)));
127 /// return VtValue(map);
128 /// }
129 ///
130 /// The current Karma implementation for Cryptomatte can be found at:
131 /// https://github.com/sideeffects/HoudiniUsdBridge
132 /// in src/houdini/custom/RAY/BRAY_HdKarma/BRAY_HdAOVBuffer.C
133 ///
134 /// The code that reads the resource can be found in:
135 /// src/houdini/lib/H_USD/HUSD/HUSD_RenderBuffer.C
136 /// This is used by husk, and isn't particularly relevant for delegates.
137 ///
138 /// The layout of this class will not change in the future.
139 /// @endcode
140 
141 // The only Houdini dependency is to get the SYS_FORCE_INLINE decorator
142 // This can be replaced if need be (see the source to SYS_Inline.h)
143 #include <SYS/SYS_Inline.h>
144 
146 {
147  using MapFunc = std::function<void *(int)>;
148  using UnmapFunc = std::function<void(int)>;
149 
152  : myMap(map)
153  , myUnmap(unmap)
154  {
155  }
157 
158  /// Convenience function to add an extra plane
159  SYS_FORCE_INLINE void addPlane(const std::string &name, int hd_format)
160  {
161  myNames.push_back(name);
162  myFormats.push_back(hd_format);
163  }
164  /// Convenience method to add metadata
166  const std::string &value)
167  {
168  myMetadata.insert({key, value});
169  }
170  /// Convenience function to set the metadata map
172  std::string> &md)
173  {
174  myMetadata = md;
175  }
176 
177  /// Function to map the AOV buffer (similar to HdRenderBuffer::Map, but for
178  /// an affiliated AOV).
180 
181  /// Function to unmap the AOV buffer (similar to HdRenderBuffer::Unmap, but
182  /// for an affiliated AOV).
184 
185  /// List of names for the affiliated AOV buffers
186  std::vector<std::string> myNames;
187 
188  /// List of the data formats for each of the affiliated AOV buffers. The
189  /// integer stored should match the HdFormat enum. The length of the array
190  /// should match the @c myNames array.
191  /// It's stored as @c int to remove dependencies on the USD library. There
192  /// may be issues if the HdFormats enum changes between versions.
193  std::vector<int> myFormats;
194 
195  /// Dictionary of extra metadata for the AOV
196  std::map<std::string, std::string> myMetadata;
197 };
198 
199 using UT_HUSDExtraAOVResourcePtr = std::shared_ptr<UT_HUSDExtraAOVResource>;
200 
201 #endif
std::vector< std::string > myNames
List of names for the affiliated AOV buffers.
SYS_FORCE_INLINE void addMetadata(const std::string &key, const std::string &value)
Convenience method to add metadata.
std::function< void(int)> UnmapFunc
SYS_FORCE_INLINE void setMetadata(const std::map< std::string, std::string > &md)
Convenience function to set the metadata map.
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
std::map< std::string, std::string > myMetadata
Dictionary of extra metadata for the AOV.
SYS_FORCE_INLINE UT_HUSDExtraAOVResource()=default
SYS_FORCE_INLINE void addPlane(const std::string &name, int hd_format)
Convenience function to add an extra plane.
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
SYS_FORCE_INLINE UT_HUSDExtraAOVResource(MapFunc map, UnmapFunc unmap)
GLuint const GLchar * name
Definition: glcorearb.h:786
std::function< void *(int)> MapFunc
SYS_FORCE_INLINE ~UT_HUSDExtraAOVResource()
std::shared_ptr< UT_HUSDExtraAOVResource > UT_HUSDExtraAOVResourcePtr
Definition: core.h:1131
HUSD Interface for passing Cryptomatte AOV information through Hydra.