1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #include "pxr/usd/usdGeom/modelAPI.h"
25 #include "pxr/usd/usd/schemaRegistry.h"
26 #include "pxr/usd/usd/typed.h"
27 #include "pxr/usd/usd/tokens.h"
28
29 #include "pxr/usd/sdf/types.h"
30 #include "pxr/usd/sdf/assetPath.h"
31
32 PXR_NAMESPACE_OPEN_SCOPE
33
34 // Register the schema with the TfType system.
TF_REGISTRY_FUNCTION(TfType)35 TF_REGISTRY_FUNCTION(TfType)
36 {
37 TfType::Define<UsdGeomModelAPI,
38 TfType::Bases< UsdAPISchemaBase > >();
39
40 }
41
42 TF_DEFINE_PRIVATE_TOKENS(
43 _schemaTokens,
44 (GeomModelAPI)
45 );
46
47 /* virtual */
~UsdGeomModelAPI()48 UsdGeomModelAPI::~UsdGeomModelAPI()
49 {
50 }
51
52 /* static */
53 UsdGeomModelAPI
Get(const UsdStagePtr & stage,const SdfPath & path)54 UsdGeomModelAPI::Get(const UsdStagePtr &stage, const SdfPath &path)
55 {
56 if (!stage) {
57 TF_CODING_ERROR("Invalid stage");
58 return UsdGeomModelAPI();
59 }
60 return UsdGeomModelAPI(stage->GetPrimAtPath(path));
61 }
62
63
64 /* virtual */
_GetSchemaKind() const65 UsdSchemaKind UsdGeomModelAPI::_GetSchemaKind() const
66 {
67 return UsdGeomModelAPI::schemaKind;
68 }
69
70 /* static */
71 bool
CanApply(const UsdPrim & prim,std::string * whyNot)72 UsdGeomModelAPI::CanApply(
73 const UsdPrim &prim, std::string *whyNot)
74 {
75 return prim.CanApplyAPI<UsdGeomModelAPI>(whyNot);
76 }
77
78 /* static */
79 UsdGeomModelAPI
Apply(const UsdPrim & prim)80 UsdGeomModelAPI::Apply(const UsdPrim &prim)
81 {
82 if (prim.ApplyAPI<UsdGeomModelAPI>()) {
83 return UsdGeomModelAPI(prim);
84 }
85 return UsdGeomModelAPI();
86 }
87
88 /* static */
89 const TfType &
_GetStaticTfType()90 UsdGeomModelAPI::_GetStaticTfType()
91 {
92 static TfType tfType = TfType::Find<UsdGeomModelAPI>();
93 return tfType;
94 }
95
96 /* static */
97 bool
_IsTypedSchema()98 UsdGeomModelAPI::_IsTypedSchema()
99 {
100 static bool isTyped = _GetStaticTfType().IsA<UsdTyped>();
101 return isTyped;
102 }
103
104 /* virtual */
105 const TfType &
_GetTfType() const106 UsdGeomModelAPI::_GetTfType() const
107 {
108 return _GetStaticTfType();
109 }
110
111 UsdAttribute
GetModelDrawModeAttr() const112 UsdGeomModelAPI::GetModelDrawModeAttr() const
113 {
114 return GetPrim().GetAttribute(UsdGeomTokens->modelDrawMode);
115 }
116
117 UsdAttribute
CreateModelDrawModeAttr(VtValue const & defaultValue,bool writeSparsely) const118 UsdGeomModelAPI::CreateModelDrawModeAttr(VtValue const &defaultValue, bool writeSparsely) const
119 {
120 return UsdSchemaBase::_CreateAttr(UsdGeomTokens->modelDrawMode,
121 SdfValueTypeNames->Token,
122 /* custom = */ false,
123 SdfVariabilityUniform,
124 defaultValue,
125 writeSparsely);
126 }
127
128 UsdAttribute
GetModelApplyDrawModeAttr() const129 UsdGeomModelAPI::GetModelApplyDrawModeAttr() const
130 {
131 return GetPrim().GetAttribute(UsdGeomTokens->modelApplyDrawMode);
132 }
133
134 UsdAttribute
CreateModelApplyDrawModeAttr(VtValue const & defaultValue,bool writeSparsely) const135 UsdGeomModelAPI::CreateModelApplyDrawModeAttr(VtValue const &defaultValue, bool writeSparsely) const
136 {
137 return UsdSchemaBase::_CreateAttr(UsdGeomTokens->modelApplyDrawMode,
138 SdfValueTypeNames->Bool,
139 /* custom = */ false,
140 SdfVariabilityUniform,
141 defaultValue,
142 writeSparsely);
143 }
144
145 UsdAttribute
GetModelDrawModeColorAttr() const146 UsdGeomModelAPI::GetModelDrawModeColorAttr() const
147 {
148 return GetPrim().GetAttribute(UsdGeomTokens->modelDrawModeColor);
149 }
150
151 UsdAttribute
CreateModelDrawModeColorAttr(VtValue const & defaultValue,bool writeSparsely) const152 UsdGeomModelAPI::CreateModelDrawModeColorAttr(VtValue const &defaultValue, bool writeSparsely) const
153 {
154 return UsdSchemaBase::_CreateAttr(UsdGeomTokens->modelDrawModeColor,
155 SdfValueTypeNames->Float3,
156 /* custom = */ false,
157 SdfVariabilityUniform,
158 defaultValue,
159 writeSparsely);
160 }
161
162 UsdAttribute
GetModelCardGeometryAttr() const163 UsdGeomModelAPI::GetModelCardGeometryAttr() const
164 {
165 return GetPrim().GetAttribute(UsdGeomTokens->modelCardGeometry);
166 }
167
168 UsdAttribute
CreateModelCardGeometryAttr(VtValue const & defaultValue,bool writeSparsely) const169 UsdGeomModelAPI::CreateModelCardGeometryAttr(VtValue const &defaultValue, bool writeSparsely) const
170 {
171 return UsdSchemaBase::_CreateAttr(UsdGeomTokens->modelCardGeometry,
172 SdfValueTypeNames->Token,
173 /* custom = */ false,
174 SdfVariabilityUniform,
175 defaultValue,
176 writeSparsely);
177 }
178
179 UsdAttribute
GetModelCardTextureXPosAttr() const180 UsdGeomModelAPI::GetModelCardTextureXPosAttr() const
181 {
182 return GetPrim().GetAttribute(UsdGeomTokens->modelCardTextureXPos);
183 }
184
185 UsdAttribute
CreateModelCardTextureXPosAttr(VtValue const & defaultValue,bool writeSparsely) const186 UsdGeomModelAPI::CreateModelCardTextureXPosAttr(VtValue const &defaultValue, bool writeSparsely) const
187 {
188 return UsdSchemaBase::_CreateAttr(UsdGeomTokens->modelCardTextureXPos,
189 SdfValueTypeNames->Asset,
190 /* custom = */ false,
191 SdfVariabilityVarying,
192 defaultValue,
193 writeSparsely);
194 }
195
196 UsdAttribute
GetModelCardTextureYPosAttr() const197 UsdGeomModelAPI::GetModelCardTextureYPosAttr() const
198 {
199 return GetPrim().GetAttribute(UsdGeomTokens->modelCardTextureYPos);
200 }
201
202 UsdAttribute
CreateModelCardTextureYPosAttr(VtValue const & defaultValue,bool writeSparsely) const203 UsdGeomModelAPI::CreateModelCardTextureYPosAttr(VtValue const &defaultValue, bool writeSparsely) const
204 {
205 return UsdSchemaBase::_CreateAttr(UsdGeomTokens->modelCardTextureYPos,
206 SdfValueTypeNames->Asset,
207 /* custom = */ false,
208 SdfVariabilityVarying,
209 defaultValue,
210 writeSparsely);
211 }
212
213 UsdAttribute
GetModelCardTextureZPosAttr() const214 UsdGeomModelAPI::GetModelCardTextureZPosAttr() const
215 {
216 return GetPrim().GetAttribute(UsdGeomTokens->modelCardTextureZPos);
217 }
218
219 UsdAttribute
CreateModelCardTextureZPosAttr(VtValue const & defaultValue,bool writeSparsely) const220 UsdGeomModelAPI::CreateModelCardTextureZPosAttr(VtValue const &defaultValue, bool writeSparsely) const
221 {
222 return UsdSchemaBase::_CreateAttr(UsdGeomTokens->modelCardTextureZPos,
223 SdfValueTypeNames->Asset,
224 /* custom = */ false,
225 SdfVariabilityVarying,
226 defaultValue,
227 writeSparsely);
228 }
229
230 UsdAttribute
GetModelCardTextureXNegAttr() const231 UsdGeomModelAPI::GetModelCardTextureXNegAttr() const
232 {
233 return GetPrim().GetAttribute(UsdGeomTokens->modelCardTextureXNeg);
234 }
235
236 UsdAttribute
CreateModelCardTextureXNegAttr(VtValue const & defaultValue,bool writeSparsely) const237 UsdGeomModelAPI::CreateModelCardTextureXNegAttr(VtValue const &defaultValue, bool writeSparsely) const
238 {
239 return UsdSchemaBase::_CreateAttr(UsdGeomTokens->modelCardTextureXNeg,
240 SdfValueTypeNames->Asset,
241 /* custom = */ false,
242 SdfVariabilityVarying,
243 defaultValue,
244 writeSparsely);
245 }
246
247 UsdAttribute
GetModelCardTextureYNegAttr() const248 UsdGeomModelAPI::GetModelCardTextureYNegAttr() const
249 {
250 return GetPrim().GetAttribute(UsdGeomTokens->modelCardTextureYNeg);
251 }
252
253 UsdAttribute
CreateModelCardTextureYNegAttr(VtValue const & defaultValue,bool writeSparsely) const254 UsdGeomModelAPI::CreateModelCardTextureYNegAttr(VtValue const &defaultValue, bool writeSparsely) const
255 {
256 return UsdSchemaBase::_CreateAttr(UsdGeomTokens->modelCardTextureYNeg,
257 SdfValueTypeNames->Asset,
258 /* custom = */ false,
259 SdfVariabilityVarying,
260 defaultValue,
261 writeSparsely);
262 }
263
264 UsdAttribute
GetModelCardTextureZNegAttr() const265 UsdGeomModelAPI::GetModelCardTextureZNegAttr() const
266 {
267 return GetPrim().GetAttribute(UsdGeomTokens->modelCardTextureZNeg);
268 }
269
270 UsdAttribute
CreateModelCardTextureZNegAttr(VtValue const & defaultValue,bool writeSparsely) const271 UsdGeomModelAPI::CreateModelCardTextureZNegAttr(VtValue const &defaultValue, bool writeSparsely) const
272 {
273 return UsdSchemaBase::_CreateAttr(UsdGeomTokens->modelCardTextureZNeg,
274 SdfValueTypeNames->Asset,
275 /* custom = */ false,
276 SdfVariabilityVarying,
277 defaultValue,
278 writeSparsely);
279 }
280
281 namespace {
282 static inline TfTokenVector
_ConcatenateAttributeNames(const TfTokenVector & left,const TfTokenVector & right)283 _ConcatenateAttributeNames(const TfTokenVector& left,const TfTokenVector& right)
284 {
285 TfTokenVector result;
286 result.reserve(left.size() + right.size());
287 result.insert(result.end(), left.begin(), left.end());
288 result.insert(result.end(), right.begin(), right.end());
289 return result;
290 }
291 }
292
293 /*static*/
294 const TfTokenVector&
GetSchemaAttributeNames(bool includeInherited)295 UsdGeomModelAPI::GetSchemaAttributeNames(bool includeInherited)
296 {
297 static TfTokenVector localNames = {
298 UsdGeomTokens->modelDrawMode,
299 UsdGeomTokens->modelApplyDrawMode,
300 UsdGeomTokens->modelDrawModeColor,
301 UsdGeomTokens->modelCardGeometry,
302 UsdGeomTokens->modelCardTextureXPos,
303 UsdGeomTokens->modelCardTextureYPos,
304 UsdGeomTokens->modelCardTextureZPos,
305 UsdGeomTokens->modelCardTextureXNeg,
306 UsdGeomTokens->modelCardTextureYNeg,
307 UsdGeomTokens->modelCardTextureZNeg,
308 };
309 static TfTokenVector allNames =
310 _ConcatenateAttributeNames(
311 UsdAPISchemaBase::GetSchemaAttributeNames(true),
312 localNames);
313
314 if (includeInherited)
315 return allNames;
316 else
317 return localNames;
318 }
319
320 PXR_NAMESPACE_CLOSE_SCOPE
321
322 // ===================================================================== //
323 // Feel free to add custom code below this line. It will be preserved by
324 // the code generator.
325 //
326 // Just remember to wrap code in the appropriate delimiters:
327 // 'PXR_NAMESPACE_OPEN_SCOPE', 'PXR_NAMESPACE_CLOSE_SCOPE'.
328 // ===================================================================== //
329 // --(BEGIN CUSTOM CODE)--
330
331 using std::vector;
332 using std::string;
333
334 PXR_NAMESPACE_OPEN_SCOPE
335
336 bool
GetExtentsHint(VtVec3fArray * extents,const UsdTimeCode & time) const337 UsdGeomModelAPI::GetExtentsHint(VtVec3fArray *extents,
338 const UsdTimeCode &time) const
339 {
340 UsdAttribute extentsHintAttr =
341 GetPrim().GetAttribute(UsdGeomTokens->extentsHint);
342
343 if (!extentsHintAttr)
344 return false;
345
346 return extentsHintAttr.Get(extents, time);
347 }
348
349 bool
SetExtentsHint(VtVec3fArray const & extents,const UsdTimeCode & time) const350 UsdGeomModelAPI::SetExtentsHint(VtVec3fArray const &extents,
351 const UsdTimeCode &time) const
352 {
353 if (!TF_VERIFY(extents.size() >= 2 &&
354 extents.size() <= (2 *
355 UsdGeomImageable::GetOrderedPurposeTokens().size())))
356 return false;
357
358 UsdAttribute extentsHintAttr =
359 GetPrim().CreateAttribute(UsdGeomTokens->extentsHint,
360 SdfValueTypeNames->Float3Array,
361 /* custom = */ false);
362
363 if (!extentsHintAttr)
364 return false;
365
366 return extentsHintAttr.Set(extents, time);
367 }
368
369 UsdAttribute
GetExtentsHintAttr() const370 UsdGeomModelAPI::GetExtentsHintAttr() const
371 {
372 return GetPrim().GetAttribute(UsdGeomTokens->extentsHint);
373 }
374
375 VtVec3fArray
ComputeExtentsHint(UsdGeomBBoxCache & bboxCache) const376 UsdGeomModelAPI::ComputeExtentsHint(
377 UsdGeomBBoxCache& bboxCache) const
378 {
379 static const TfTokenVector &purposeTokens =
380 UsdGeomImageable::GetOrderedPurposeTokens();
381
382 VtVec3fArray extents(purposeTokens.size() * 2);
383 size_t lastNonEmptyBbox = std::numeric_limits<size_t>::max();
384
385 // We should be able execute this loop in parallel since the
386 // bounding box computation can be multi-threaded. However, most
387 // conversion processes are run on the farm and are limited to one
388 // CPU, so there may not be a huge benefit from doing this. Also,
389 // we expect purpose 'default' to be the most common purpose value
390 // and in some cases the only purpose value. Computing bounds for
391 // the rest of the purpose values should be very fast.
392 for(size_t bboxType = purposeTokens.size(); bboxType-- != 0; ) {
393
394 // Set the gprim purpose that we are interested in computing the
395 // bbox for. This doesn't cause the cache to be blown.
396 bboxCache.SetIncludedPurposes(
397 std::vector<TfToken>(1, purposeTokens[bboxType]));
398
399 GfBBox3d bbox = bboxCache.
400 ComputeUntransformedBound(GetPrim());
401
402 const GfRange3d range = bbox.ComputeAlignedBox();
403
404 if (!range.IsEmpty() && lastNonEmptyBbox == std::numeric_limits<size_t>::max())
405 lastNonEmptyBbox = bboxType;
406
407 const GfVec3d &min = range.GetMin();
408 const GfVec3d &max = range.GetMax();
409
410 size_t index = bboxType * 2;
411 extents[index] = GfVec3f(min[0], min[1], min[2]);
412 extents[index + 1] = GfVec3f(max[0], max[1], max[2]);
413 }
414
415 // If all the extents are empty. Author a single empty range.
416 if (lastNonEmptyBbox == std::numeric_limits<size_t>::max())
417 lastNonEmptyBbox = 0;
418
419 // Shrink the array to only include non-empty bounds.
420 // If all the bounds are empty, we still need to author one empty
421 // bound.
422 extents.resize(2 * (lastNonEmptyBbox + 1));
423 return extents;
424 }
425
426 UsdGeomConstraintTarget
GetConstraintTarget(const std::string & constraintName) const427 UsdGeomModelAPI::GetConstraintTarget(
428 const std::string &constraintName) const
429 {
430 const TfToken &constraintAttrName =
431 UsdGeomConstraintTarget::GetConstraintAttrName(constraintName);
432
433 return UsdGeomConstraintTarget(GetPrim().GetAttribute(constraintAttrName));
434 }
435
436 UsdGeomConstraintTarget
CreateConstraintTarget(const string & constraintName) const437 UsdGeomModelAPI::CreateConstraintTarget(
438 const string &constraintName) const
439 {
440 const TfToken &constraintAttrName =
441 UsdGeomConstraintTarget::GetConstraintAttrName(constraintName);
442
443 // Check if the constraint target attribute already exists.
444 UsdAttribute constraintAttr = GetPrim().GetAttribute(constraintAttrName);
445 if (!constraintAttr) {
446 // Create the attribute, if it doesn't exist.
447 constraintAttr = GetPrim().CreateAttribute(constraintAttrName,
448 SdfValueTypeNames->Matrix4d,
449 /* custom */ false,
450 SdfVariabilityVarying);
451 }
452
453 return UsdGeomConstraintTarget(constraintAttr);
454 }
455
456 vector<UsdGeomConstraintTarget>
GetConstraintTargets() const457 UsdGeomModelAPI::GetConstraintTargets() const
458 {
459 vector<UsdGeomConstraintTarget> constraintTargets;
460
461 const vector<UsdAttribute> &attributes = GetPrim().GetAttributes();
462 TF_FOR_ALL(attrIt, attributes) {
463 UsdGeomConstraintTarget constraintTarget(*attrIt);
464
465 // Add it to the list, if it is a valid constraint target.
466 if (constraintTarget) {
467 constraintTargets.push_back(constraintTarget);
468 }
469 }
470
471 return constraintTargets;
472 }
473
474 namespace {
475 static
476 bool
_GetAuthoredDrawMode(const UsdPrim & prim,TfToken * drawMode)477 _GetAuthoredDrawMode(const UsdPrim &prim, TfToken *drawMode)
478 {
479 // Only check for the attribute on models; don't check the pseudo-root.
480 if (!prim.IsModel() || !prim.GetParent()) {
481 return false;
482 }
483
484 UsdGeomModelAPI modelAPI(prim);
485 UsdAttribute attr = modelAPI.GetModelDrawModeAttr();
486 return attr && attr.Get(drawMode);
487 }
488 }
489
490 TfToken
ComputeModelDrawMode(const TfToken & parentDrawMode) const491 UsdGeomModelAPI::ComputeModelDrawMode(const TfToken &parentDrawMode) const
492 {
493 TfToken drawMode = UsdGeomTokens->inherited;
494
495 if (_GetAuthoredDrawMode(GetPrim(), &drawMode) &&
496 drawMode != UsdGeomTokens->inherited) {
497 return drawMode;
498 }
499
500 if (!parentDrawMode.IsEmpty()) {
501 return parentDrawMode;
502 }
503
504 // Find the closest applicable model:drawMode among this prim's ancestors.
505 for (UsdPrim curPrim = GetPrim().GetParent();
506 curPrim;
507 curPrim = curPrim.GetParent()) {
508
509 if (_GetAuthoredDrawMode(curPrim, &drawMode) &&
510 drawMode != UsdGeomTokens->inherited) {
511 return drawMode;
512 }
513 }
514
515 // If the attribute isn't set on any ancestors, return "default".
516 return UsdGeomTokens->default_;
517 }
518
519
520 PXR_NAMESPACE_CLOSE_SCOPE
521
522