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 /// \file VariantSetSpec.cpp
25
26 #include "pxr/pxr.h"
27 #include "pxr/usd/sdf/variantSetSpec.h"
28 #include "pxr/usd/sdf/childrenUtils.h"
29 #include "pxr/usd/sdf/layer.h"
30 #include "pxr/usd/sdf/primSpec.h"
31 #include "pxr/usd/sdf/types.h"
32 #include "pxr/usd/sdf/variantSpec.h"
33 #include "pxr/base/tf/diagnostic.h"
34 #include "pxr/base/tf/type.h"
35 #include "pxr/base/trace/trace.h"
36 #include <ostream>
37
38 PXR_NAMESPACE_OPEN_SCOPE
39
40 SDF_DEFINE_SPEC(SdfSchema, SdfSpecTypeVariantSet, SdfVariantSetSpec, SdfSpec);
41
42 SdfVariantSetSpecHandle
New(const SdfPrimSpecHandle & owner,const std::string & name)43 SdfVariantSetSpec::New(const SdfPrimSpecHandle& owner, const std::string& name)
44 {
45 TRACE_FUNCTION();
46
47 if (!owner) {
48 TF_CODING_ERROR("NULL owner prim");
49 return TfNullPtr;
50 }
51
52 if (!Sdf_ChildrenUtils<Sdf_VariantSetChildPolicy>::IsValidName(name)) {
53 TF_CODING_ERROR("Cannot create variant set spec with invalid "
54 "identifier: '%s'", name.c_str());
55 return TfNullPtr;
56 }
57
58 SdfChangeBlock block;
59
60 SdfLayerHandle layer = owner->GetLayer();
61 SdfPath path = owner->GetPath().AppendVariantSelection(name, "");
62
63 if (!path.IsPrimVariantSelectionPath()) {
64 TF_CODING_ERROR("Cannot create variant set spec at invalid "
65 "path <%s{%s=}>", owner->GetPath().GetText(), name.c_str());
66 return TfNullPtr;
67 }
68
69 if (!Sdf_ChildrenUtils<Sdf_VariantSetChildPolicy>::CreateSpec(
70 layer, path, SdfSpecTypeVariantSet))
71 return TfNullPtr;
72
73 return TfStatic_cast<SdfVariantSetSpecHandle>(layer->GetObjectAtPath(path));
74 }
75
76 SdfVariantSetSpecHandle
New(const SdfVariantSpecHandle & owner,const std::string & name)77 SdfVariantSetSpec::New(const SdfVariantSpecHandle& owner,
78 const std::string& name)
79 {
80 TRACE_FUNCTION();
81
82 if (!owner) {
83 TF_CODING_ERROR("NULL owner variant");
84 return TfNullPtr;
85 }
86
87 if (!Sdf_ChildrenUtils<Sdf_VariantSetChildPolicy>::IsValidName(name)) {
88 TF_CODING_ERROR("Cannot create variant set spec with invalid "
89 "identifier: '%s'", name.c_str());
90 return TfNullPtr;
91 }
92
93 SdfChangeBlock block;
94
95 SdfLayerHandle layer = owner->GetLayer();
96 SdfPath path = owner->GetPath().AppendVariantSelection(name, "");
97
98 if (!path.IsPrimVariantSelectionPath()) {
99 TF_CODING_ERROR("Cannot create variant set spec at invalid "
100 "path <%s{%s=}>", owner->GetPath().GetText(), name.c_str());
101 return TfNullPtr;
102 }
103
104 if (!Sdf_ChildrenUtils<Sdf_VariantSetChildPolicy>::CreateSpec(
105 layer, path, SdfSpecTypeVariantSet))
106 return TfNullPtr;
107
108 return TfStatic_cast<SdfVariantSetSpecHandle>(layer->GetObjectAtPath(path));
109 }
110
111 //
112 // Name
113 //
114
115 std::string
GetName() const116 SdfVariantSetSpec::GetName() const
117 {
118 return GetPath().GetName();
119 }
120
121 TfToken
GetNameToken() const122 SdfVariantSetSpec::GetNameToken() const
123 {
124 return GetPath().GetNameToken();
125 }
126
127 //
128 // Namespace hierarchy
129 //
130
131 SdfSpecHandle
GetOwner() const132 SdfVariantSetSpec::GetOwner() const
133 {
134 return GetLayer()->GetObjectAtPath(GetPath().GetParentPath());
135 }
136
137 //
138 // Variants
139 //
140
141 SdfVariantView
GetVariants() const142 SdfVariantSetSpec::GetVariants() const
143 {
144 return SdfVariantView(
145 GetLayer(), GetPath(),
146 SdfChildrenKeys->VariantChildren);
147 }
148
149 SdfVariantSpecHandleVector
GetVariantList() const150 SdfVariantSetSpec::GetVariantList() const
151 {
152 return GetVariants().values();
153 }
154
155 void
RemoveVariant(const SdfVariantSpecHandle & variant)156 SdfVariantSetSpec::RemoveVariant(const SdfVariantSpecHandle& variant)
157 {
158 const SdfLayerHandle& layer = GetLayer();
159 const SdfPath& path = GetPath();
160
161 SdfPath parentPath =
162 Sdf_VariantChildPolicy::GetParentPath(variant->GetPath());
163 if (variant->GetLayer() != layer || parentPath != path) {
164 TF_CODING_ERROR("Cannot remove a variant that does not belong to "
165 "this variant set.");
166 return;
167 }
168
169 if (!Sdf_ChildrenUtils<Sdf_VariantChildPolicy>::RemoveChild(
170 layer, path, variant->GetNameToken())) {
171 TF_CODING_ERROR("Unable to remove child: %s",
172 variant->GetName().c_str());
173 }
174 }
175
176 PXR_NAMESPACE_CLOSE_SCOPE
177