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