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/imaging/hd/instancer.h"
25 #include "pxr/imaging/hd/renderDelegate.h"
26 #include "pxr/imaging/hd/renderIndex.h"
27 #include "pxr/imaging/hd/rprim.h"
28 #include "pxr/imaging/hd/tokens.h"
29
30 PXR_NAMESPACE_OPEN_SCOPE
31
HdInstancer(HdSceneDelegate * delegate,SdfPath const & id)32 HdInstancer::HdInstancer(HdSceneDelegate* delegate,
33 SdfPath const& id)
34 : _delegate(delegate)
35 , _id(id)
36 , _parentId()
37 {
38 }
39
40 HdInstancer::~HdInstancer() = default;
41
42 /* static */
43 int
GetInstancerNumLevels(HdRenderIndex & index,HdRprim const & rprim)44 HdInstancer::GetInstancerNumLevels(HdRenderIndex& index,
45 HdRprim const& rprim)
46 {
47 // Walk up the instancing hierarchy to figure out how many levels of
48 // instancing the passed-in rprim has.
49
50 int instancerLevels = 0;
51 SdfPath parent = rprim.GetInstancerId();
52 HdInstancer *instancer = nullptr;
53 while (!parent.IsEmpty()) {
54 instancerLevels++;
55 instancer = index.GetInstancer(parent);
56 TF_VERIFY(instancer);
57 parent = instancer ? instancer->GetParentId()
58 : SdfPath::EmptyPath();
59 }
60 return instancerLevels;
61 }
62
63 /* static */
64 TfTokenVector const &
GetBuiltinPrimvarNames()65 HdInstancer::GetBuiltinPrimvarNames()
66 {
67 static const TfTokenVector primvarNames = {
68 HdInstancerTokens->instanceTransform,
69 HdInstancerTokens->rotate,
70 HdInstancerTokens->scale,
71 HdInstancerTokens->translate
72 };
73 return primvarNames;
74 }
75
76 void
Sync(HdSceneDelegate * sceneDelegate,HdRenderParam * renderParam,HdDirtyBits * dirtyBits)77 HdInstancer::Sync(HdSceneDelegate *sceneDelegate,
78 HdRenderParam *renderParam,
79 HdDirtyBits *dirtyBits)
80 {
81 }
82
83 void
Finalize(HdRenderParam * renderParam)84 HdInstancer::Finalize(HdRenderParam *renderParam)
85 {
86 }
87
88 void
_SyncInstancerAndParents(HdRenderIndex & renderIndex,SdfPath const & instancerId)89 HdInstancer::_SyncInstancerAndParents(HdRenderIndex &renderIndex,
90 SdfPath const& instancerId)
91 {
92 HdRenderParam *renderParam =
93 renderIndex.GetRenderDelegate()->GetRenderParam();
94 SdfPath id = instancerId;
95 while (!id.IsEmpty()) {
96 HdInstancer *instancer = renderIndex.GetInstancer(id);
97 if (!TF_VERIFY(instancer)) {
98 return;
99 }
100
101 HdDirtyBits dirtyBits =
102 renderIndex.GetChangeTracker().GetInstancerDirtyBits(id);
103
104 if (dirtyBits != HdChangeTracker::Clean) {
105 std::lock_guard<std::mutex> lock(instancer->_instanceLock);
106 dirtyBits =
107 renderIndex.GetChangeTracker().GetInstancerDirtyBits(id);
108 instancer->Sync(instancer->GetDelegate(), renderParam, &dirtyBits);
109 renderIndex.GetChangeTracker().MarkInstancerClean(id);
110 }
111
112 id = instancer->GetParentId();
113 }
114 }
115
116 void
_UpdateInstancer(HdSceneDelegate * delegate,HdDirtyBits * dirtyBits)117 HdInstancer::_UpdateInstancer(HdSceneDelegate *delegate,
118 HdDirtyBits *dirtyBits)
119 {
120 if (HdChangeTracker::IsInstancerDirty(*dirtyBits, GetId())) {
121 SdfPath const& parentId = delegate->GetInstancerId(GetId());
122 if (parentId == _parentId) {
123 return;
124 }
125
126 // If we have a new instancer ID, we need to update the dependency
127 // map and also update the stored instancer ID.
128 HdChangeTracker &tracker =
129 delegate->GetRenderIndex().GetChangeTracker();
130 if (!_parentId.IsEmpty()) {
131 tracker.RemoveInstancerInstancerDependency(_parentId, GetId());
132 }
133 if (!parentId.IsEmpty()) {
134 tracker.AddInstancerInstancerDependency(parentId, GetId());
135 }
136 _parentId = parentId;
137 }
138 }
139
140 HdDirtyBits
GetInitialDirtyBitsMask() const141 HdInstancer::GetInitialDirtyBitsMask() const
142 {
143 return HdChangeTracker::DirtyTransform |
144 HdChangeTracker::DirtyPrimvar |
145 HdChangeTracker::DirtyInstanceIndex |
146 HdChangeTracker::DirtyInstancer;
147 }
148
149 PXR_NAMESPACE_CLOSE_SCOPE
150
151