HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
XUSD_HydraInstancer.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: XUSD_HydraInstancer.h (HUSD Library, C++)
17  *
18  * COMMENTS: Basic instancer for creating instance transforms.
19  *
20  */
21 
22 #ifndef XUSD_HydraInstancer_h
23 #define XUSD_HydraInstancer_h
24 
25 #include "HUSD_API.h"
26 #include <UT/UT_Lock.h>
27 #include <UT/UT_Map.h>
28 #include <UT/UT_StringMap.h>
29 #include <UT/UT_SmallArray.h>
30 #include <UT/UT_UniquePtr.h>
31 #include <GT/GT_Transform.h>
32 #include <GT/GT_TransformArray.h>
33 
34 #include <pxr/pxr.h>
37 #include <pxr/base/tf/hashmap.h>
38 #include <pxr/base/tf/token.h>
39 
40 class HUSD_Scene;
41 
43 
45 {
46 public:
48  SdfPath const& id,
49  SdfPath const &parentInstancerId);
50  ~XUSD_HydraInstancer() override;
51 
52  // Checks the change tracker to determine whether instance primvars are
53  // dirty, and if so pulls them. Since primvars can only be pulled once,
54  // and are cached, this function is not re-entrant. However, this function
55  // is called by ComputeInstanceTransforms, which is called (potentially)
56  // by HdMantraMesh::Sync(), which is dispatched in parallel, so it needs
57  // to be guarded by _instanceLock.
58  //
59  // The @c nsegs variable indicates the number of segments/samples required
60  // for motion blur. The function returns the actual number of segments on
61  // the instancer.
62  //
63  // Pulled primvars are cached in _primvarMap.
64  int syncPrimvars(bool recurse, int nsegs=1);
65 
66  // Return the number of evaluated motion segments
67  int motionSegments() const
68  {
69  return SYSmax(xsegments(), psegments());
70  }
71 
72  // Grab the transforms for this instancer, and flatten it with any parent
73  // instancers if 'recurse' is true. syncPrimvars() must be called first.
74  VtMatrix4dArray computeTransforms(const SdfPath &protoId,
75  bool recurse,
76  const GfMatrix4d *protoXform,
77  float shutter_time=0);
78 
79  // Grab the transforms and scene ids for each instance. If 'recurse' is
80  // true, flatten both the transforms and ids for nested instancers.
81  // syncPrimvars() must be called first.
82  VtMatrix4dArray computeTransformsAndIDs(const SdfPath &protoId,
83  bool recurse,
84  const GfMatrix4d *protoXform,
85  int level,
87  HUSD_Scene *scene,
88  float shutter=0,
89  int hou_proto_id=-1);
90 
91  bool isResolved() const { return myIsResolved; }
92  void resolved() { myIsResolved = true; }
93 
94  // Add all instance prims to the scene tree. This does nothing for point
95  // instancers.
96  void resolveInstancePrims();
97 
98  UT_StringArray resolveInstance(int proto_id,
99  const UT_IntArray &indices,
100  int instance_level = 0);
101  UT_StringArray resolveInstanceID(HUSD_Scene &scene,
102  const UT_StringRef &houdini_inst_path,
103  int instance_idx,
105  UT_StringArray *proto_id = nullptr)
106  const;
107  void addInstanceRef(int id);
108  void removeInstanceRef(int id);
109  bool invalidateInstanceRefs();
110  const UT_Map<int,int> &instanceRefs() const;
111  void clearInstanceRefs();
112 
113  const UT_StringRef &getCachedResolvedInstance(const UT_StringRef &id_key);
114  void cacheResolvedInstance(const UT_StringRef &id_key,
115  const UT_StringRef &resolved);
116 
117  int id() const { return myID; }
118 
119  void removePrototype(const UT_StringRef &proto_path,
120  int proto_id);
122  { return myPrototypes; }
124  { return myPrototypeID; }
125 
126  const VtValue &primvarValue(const TfToken &name) const;
127 
128  void setIsPointInstancer(bool is_pi)
129  { myIsPointInstancer = is_pi; }
130  bool isPointInstancer() const
131  { return myIsPointInstancer; }
132 
133 protected:
135  : public UT_NonCopyable
136  {
137  using BufferPtr = UT_UniquePtr<HdVtBufferSource>;
138  public:
140  : myBuffers()
141  , myValues()
142  , mySize(0)
143  {
144  }
146  : myBuffers(UTmakeUnique<BufferPtr[]>(size))
147  , myValues(UTmakeUnique<VtValue[]>(size))
148  , mySize(size)
149  {
150  }
152  : myBuffers(std::move(src.myBuffers))
153  , myValues(std::move(src.myValues))
154  , mySize(src.mySize)
155  {
156  src.mySize = 0;
157  }
159  {
160  myBuffers = std::move(src.myBuffers);
161  myValues = std::move(src.myValues);
162  mySize = src.mySize;
163  src.mySize = 0;
164  return *this;
165  }
167  {
168  }
169  exint size() const
170  {
171  return mySize;
172  }
173  const HdVtBufferSource *buffer(exint i) const
174  {
175  UT_ASSERT_P(i >= 0 && i < mySize);
176  return myBuffers[i].get();
177  }
178  const VtValue &value(exint i) const
179  {
180  UT_ASSERT_P(i >= 0 && i < mySize);
181  return myValues[i];
182  }
184  {
185  return buffer(i);
186  }
187  void setValueAndBuffer(exint idx, const VtValue &value, BufferPtr b)
188  {
189  myValues[idx] = value;
190  myBuffers[idx] = std::move(b);
191  }
192 
193  private:
194  UT_UniquePtr<BufferPtr[]> myBuffers;
195  UT_UniquePtr<VtValue[]> myValues;
196  exint mySize;
197  };
198 
199  /// Given a shutter time and a number of motion segments, return the motion
200  /// segment and interpolant. If seg0 != seg1, then values should be
201  /// interpolated using: @code
202  /// val = SYSlerp(primvar[seg0], primvar[seg1], lerp);
203  /// @endcode
204  void getSegment(float time, int &seg0, int &seg1, float &lerp,
205  bool for_transform) const;
206 
207  const float *xtimes() const { return myXTimes.data(); }
208  int xsegments() const { return myXTimes.size(); }
209  const float *ptimes() const { return myPTimes.data(); }
210  int psegments() const { return myPTimes.size(); }
211 
212  // Map of the latest primvar data for this instancer, keyed by
213  // primvar name. Primvar values are VtValue, an any-type; they are
214  // interpreted at consumption time (here, in ComputeInstanceTransforms).
216  UT_SmallArray<float> myXTimes; // USD time samples for xforms
217  UT_SmallArray<float> myPTimes; // USD time samples for primvars
218  UT_SmallArray<GfMatrix4d> myXforms; // Transform matrices
219 
220  mutable UT_Lock myLock;
221 
222 private:
223  UT_StringHolder findParentInstancer() const;
224 
225  VtMatrix4dArray privComputeTransforms(const SdfPath &prototypeId,
226  bool recurse,
227  const GfMatrix4d *protoXform,
228  int level,
229  UT_StringArray *instances,
230  UT_IntArray *ids,
231  HUSD_Scene *scene,
232  float shutter_time,
233  int hou_proto_id = -1);
234 
235  UT_StringMap<UT_StringHolder> myResolvedInstances;
236  UT_Map<int,int> myInstanceRefs;
237  UT_StringMap<UT_Map<int,int> > myPrototypes;
238  UT_Map<int, UT_StringHolder> myPrototypeID;
239 
240  int myID;
241  bool myIsResolved;
242  bool myIsPointInstancer;
243 };
244 
246 {
247 public:
248  XUSD_HydraTransforms() : myDataId(-1) {}
249  ~XUSD_HydraTransforms() override {}
250 
251  void setDataId(int64 id) { myDataId = id; }
252  int64 getDataId() const override { return myDataId; }
253 private:
254  int64 myDataId;
255 };
256 
258 
259 #endif
#define SYSmax(a, b)
Definition: SYS_Math.h:1521
GLuint id
Definition: glew.h:1679
GLsizeiptr size
Definition: glew.h:1681
GLenum src
Definition: glew.h:2410
GLuint const GLchar * name
Definition: glew.h:1814
const float * xtimes() const
const float * ptimes() const
UT_SmallArray< float > myPTimes
GT_API const UT_StringHolder time
Scene information for the native viewport renderer.
Definition: HUSD_Scene.h:65
virtual bool lerp(GA_AttributeOperand &d, GA_AttributeOperand &a, GA_AttributeOperand &b, GA_AttributeOperand &t) const
d = SYSlerp(a, b, t);
UT_SmallArray< GfMatrix4d > myXforms
int64 exint
Definition: SYS_Types.h:125
#define HUSD_API
Definition: HUSD_API.h:32
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:33
const UT_Map< int, UT_StringHolder > & prototypeIDs() const
UT_SmallArray< float > myXTimes
const VtValue & value(exint i) const
Definition: token.h:87
UT_Map< TfToken, PrimvarMapItem, TfToken::HashFunctor > myPrimvarMap
GLuint buffer
Definition: glew.h:1680
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:134
GLuint GLuint GLsizei GLenum const void * indices
Definition: glew.h:1253
long long int64
Definition: SYS_Types.h:116
const UT_StringMap< UT_Map< int, int > > & prototypes() const
std::enable_if< !std::is_array< T >::value, UT_UniquePtr< T >>::type UTmakeUnique(REST &&...args)
Definition: UT_UniquePtr.h:46
bool isPointInstancer() const
Definition: path.h:288
GLdouble GLdouble GLdouble b
Definition: glew.h:9122
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1346
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:83
PrimvarMapItem & operator=(PrimvarMapItem &&src)
const HdVtBufferSource * buffer(exint i) const
const GLuint * ids
Definition: glew.h:1684
int64 getDataId() const override
Data id support for derived classes (-1 means always re-update).
const HdVtBufferSource * operator[](exint i) const
GLsizei const GLfloat * value
Definition: glew.h:1849
GLint level
Definition: glew.h:1252
Definition: value.h:174
void setIsPointInstancer(bool is_pi)
void setValueAndBuffer(exint idx, const VtValue &value, BufferPtr b)