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/usdRi/splineAPI.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<UsdRiSplineAPI,
38         TfType::Bases< UsdAPISchemaBase > >();
39 
40 }
41 
42 TF_DEFINE_PRIVATE_TOKENS(
43     _schemaTokens,
44     (RiSplineAPI)
45 );
46 
47 /* virtual */
~UsdRiSplineAPI()48 UsdRiSplineAPI::~UsdRiSplineAPI()
49 {
50 }
51 
52 /* static */
53 UsdRiSplineAPI
Get(const UsdStagePtr & stage,const SdfPath & path)54 UsdRiSplineAPI::Get(const UsdStagePtr &stage, const SdfPath &path)
55 {
56     if (!stage) {
57         TF_CODING_ERROR("Invalid stage");
58         return UsdRiSplineAPI();
59     }
60     return UsdRiSplineAPI(stage->GetPrimAtPath(path));
61 }
62 
63 
64 /* virtual */
_GetSchemaKind() const65 UsdSchemaKind UsdRiSplineAPI::_GetSchemaKind() const
66 {
67     return UsdRiSplineAPI::schemaKind;
68 }
69 
70 /* static */
71 bool
CanApply(const UsdPrim & prim,std::string * whyNot)72 UsdRiSplineAPI::CanApply(
73     const UsdPrim &prim, std::string *whyNot)
74 {
75     return prim.CanApplyAPI<UsdRiSplineAPI>(whyNot);
76 }
77 
78 /* static */
79 UsdRiSplineAPI
Apply(const UsdPrim & prim)80 UsdRiSplineAPI::Apply(const UsdPrim &prim)
81 {
82     if (prim.ApplyAPI<UsdRiSplineAPI>()) {
83         return UsdRiSplineAPI(prim);
84     }
85     return UsdRiSplineAPI();
86 }
87 
88 /* static */
89 const TfType &
_GetStaticTfType()90 UsdRiSplineAPI::_GetStaticTfType()
91 {
92     static TfType tfType = TfType::Find<UsdRiSplineAPI>();
93     return tfType;
94 }
95 
96 /* static */
97 bool
_IsTypedSchema()98 UsdRiSplineAPI::_IsTypedSchema()
99 {
100     static bool isTyped = _GetStaticTfType().IsA<UsdTyped>();
101     return isTyped;
102 }
103 
104 /* virtual */
105 const TfType &
_GetTfType() const106 UsdRiSplineAPI::_GetTfType() const
107 {
108     return _GetStaticTfType();
109 }
110 
111 /*static*/
112 const TfTokenVector&
GetSchemaAttributeNames(bool includeInherited)113 UsdRiSplineAPI::GetSchemaAttributeNames(bool includeInherited)
114 {
115     static TfTokenVector localNames;
116     static TfTokenVector allNames =
117         UsdAPISchemaBase::GetSchemaAttributeNames(true);
118 
119     if (includeInherited)
120         return allNames;
121     else
122         return localNames;
123 }
124 
125 PXR_NAMESPACE_CLOSE_SCOPE
126 
127 // ===================================================================== //
128 // Feel free to add custom code below this line. It will be preserved by
129 // the code generator.
130 //
131 // Just remember to wrap code in the appropriate delimiters:
132 // 'PXR_NAMESPACE_OPEN_SCOPE', 'PXR_NAMESPACE_CLOSE_SCOPE'.
133 // ===================================================================== //
134 // --(BEGIN CUSTOM CODE)--
135 
136 #include "pxr/usd/usdRi/tokens.h"
137 #include <algorithm>
138 
139 PXR_NAMESPACE_OPEN_SCOPE
140 
141 TfToken
_GetScopedPropertyName(const TfToken & baseName) const142 UsdRiSplineAPI::_GetScopedPropertyName(const TfToken &baseName) const
143 {
144     return TfToken(
145         SdfPath::JoinIdentifier(
146             SdfPath::JoinIdentifier(
147                 _splineName.GetString(),
148                 UsdRiTokens->spline.GetString()),
149             baseName.GetString()));
150 }
151 
152 UsdAttribute
GetInterpolationAttr() const153 UsdRiSplineAPI::GetInterpolationAttr() const
154 {
155     TfToken name = _GetScopedPropertyName(UsdRiTokens->interpolation);
156     return GetPrim().GetAttribute(name);
157 }
158 
159 UsdAttribute
CreateInterpolationAttr(VtValue const & defaultValue,bool writeSparsely) const160 UsdRiSplineAPI::CreateInterpolationAttr(VtValue const &defaultValue, bool writeSparsely) const
161 {
162     TfToken name = _GetScopedPropertyName(UsdRiTokens->interpolation);
163     return UsdSchemaBase::_CreateAttr(name,
164                        SdfValueTypeNames->Token,
165                        /* custom = */ false,
166                        SdfVariabilityUniform,
167                        defaultValue,
168                        writeSparsely);
169 }
170 
171 UsdAttribute
GetPositionsAttr() const172 UsdRiSplineAPI::GetPositionsAttr() const
173 {
174     TfToken name = _GetScopedPropertyName(UsdRiTokens->positions);
175     return GetPrim().GetAttribute(name);
176 }
177 
178 UsdAttribute
CreatePositionsAttr(VtValue const & defaultValue,bool writeSparsely) const179 UsdRiSplineAPI::CreatePositionsAttr(VtValue const &defaultValue, bool writeSparsely) const
180 {
181     TfToken name = _GetScopedPropertyName(UsdRiTokens->positions);
182     return UsdSchemaBase::_CreateAttr(name,
183                        SdfValueTypeNames->FloatArray,
184                        /* custom = */ false,
185                        SdfVariabilityUniform,
186                        defaultValue,
187                        writeSparsely);
188 }
189 
190 UsdAttribute
GetValuesAttr() const191 UsdRiSplineAPI::GetValuesAttr() const
192 {
193     TfToken name = _GetScopedPropertyName(UsdRiTokens->values);
194     return GetPrim().GetAttribute(name);
195 }
196 
197 UsdAttribute
CreateValuesAttr(VtValue const & defaultValue,bool writeSparsely) const198 UsdRiSplineAPI::CreateValuesAttr(VtValue const &defaultValue, bool writeSparsely) const
199 {
200     TfToken name = _GetScopedPropertyName(UsdRiTokens->values);
201     return UsdSchemaBase::_CreateAttr(name,
202                        _valuesTypeName,
203                        /* custom = */ false,
204                        SdfVariabilityUniform,
205                        defaultValue,
206                        writeSparsely);
207 }
208 
209 bool
Validate(std::string * reason) const210 UsdRiSplineAPI::Validate(std::string *reason) const
211 {
212     if (_splineName.IsEmpty()) {
213         *reason += "SplineAPI is not correctly initialized";
214         return false;
215     }
216 
217     UsdAttribute interpAttr = GetInterpolationAttr();
218     UsdAttribute posAttr = GetPositionsAttr();
219     UsdAttribute valAttr = GetValuesAttr();
220 
221     if (_valuesTypeName != SdfValueTypeNames->FloatArray &&
222         _valuesTypeName != SdfValueTypeNames->Color3fArray) {
223         *reason += "SplineAPI is configured for an unsupported value type '" +
224             _valuesTypeName.GetAsToken().GetString() + "'";
225         return false;
226     }
227     if (!interpAttr) {
228         *reason += "Could not get the interpolation attribute.";
229         return false;
230     }
231     if (!posAttr) {
232         *reason += "Could not get the position attribute.";
233         return false;
234     }
235     TfToken interp;
236     interpAttr.Get(&interp);
237     if (interp != UsdRiTokens->constant &&
238         interp != UsdRiTokens->linear &&
239         interp != UsdRiTokens->catmullRom &&
240         interp != UsdRiTokens->bspline) {
241         *reason += "Interpolation attribute has invalid value '" +
242             interp.GetString() + "'";
243         return false;
244     }
245     if (posAttr.GetTypeName() != SdfValueTypeNames->FloatArray) {
246         *reason += "Values attribute has incorrect type; found '" +
247             valAttr.GetTypeName().GetAsToken().GetString() +
248             "' but expected '" +
249             SdfValueTypeNames->FloatArray.GetAsToken().GetString() +
250             "'";
251         return false;
252     }
253     VtFloatArray positions;
254     posAttr.Get(&positions);
255     if (!std::is_sorted(positions.begin(), positions.end())) {
256         *reason += "Positions attribute must be sorted in increasing order";
257         return false;
258     }
259     if (valAttr.GetTypeName() != _valuesTypeName) {
260         *reason += "Values attribute has incorrect type; found '" +
261             valAttr.GetTypeName().GetAsToken().GetString() +
262             "' but expected '" +
263             _valuesTypeName.GetAsToken().GetString() +
264             "'";
265         return false;
266     }
267     size_t numValues = 0;
268     if (_valuesTypeName == SdfValueTypeNames->FloatArray) {
269         VtFloatArray vals;
270         valAttr.Get(&vals);
271         numValues = vals.size();
272     } else if (_valuesTypeName == SdfValueTypeNames->Color3fArray) {
273         VtVec3fArray vals;
274         valAttr.Get(&vals);
275         numValues = vals.size();
276     }
277     if (positions.size() != numValues) {
278         *reason += "Values attribute and positions attribute must " \
279                     "have the same number of entries";
280         return false;
281     }
282 
283     return true;
284 }
285 
286 PXR_NAMESPACE_CLOSE_SCOPE
287