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