Blender V4.3
hydra/pointcloud.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2022 NVIDIA Corporation
2 * SPDX-FileCopyrightText: 2022 Blender Foundation
3 *
4 * SPDX-License-Identifier: Apache-2.0 */
5
6#include "hydra/pointcloud.h"
7#include "hydra/geometry.inl"
8#include "scene/pointcloud.h"
9
10#include <pxr/imaging/hd/extComputationUtils.h>
11
13
14HdCyclesPoints::HdCyclesPoints(const SdfPath &rprimId
15#if PXR_VERSION < 2102
16 ,
17 const SdfPath &instancerId
18#endif
19 )
20 : HdCyclesGeometry(rprimId
21#if PXR_VERSION < 2102
22 ,
23 instancerId
24#endif
25 )
26{
27}
28
30
32{
34 bits |= HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyWidths |
35 HdChangeTracker::DirtyPrimvar;
36 return bits;
37}
38
39HdDirtyBits HdCyclesPoints::_PropagateDirtyBits(HdDirtyBits bits) const
40{
41 // Points and widths always have to be updated together
42 if (bits & (HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyWidths)) {
43 bits |= HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyWidths;
44 }
45
46 return bits;
47}
48
49void HdCyclesPoints::Populate(HdSceneDelegate *sceneDelegate, HdDirtyBits dirtyBits, bool &rebuild)
50{
51 if (dirtyBits & (HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyWidths)) {
52 const size_t numPoints = _geom->num_points();
53
54 PopulatePoints(sceneDelegate);
55 PopulateWidths(sceneDelegate);
56
57 rebuild = _geom->num_points() != numPoints;
58
59 array<int> shaders;
60 shaders.reserve(_geom->num_points());
61 for (size_t i = 0; i < _geom->num_points(); ++i) {
62 shaders.push_back_reserved(0);
63 }
64
65 _geom->set_shader(shaders);
66 }
67
68 if (dirtyBits & HdChangeTracker::DirtyPrimvar) {
69 PopulatePrimvars(sceneDelegate);
70 }
71}
72
73void HdCyclesPoints::PopulatePoints(HdSceneDelegate *sceneDelegate)
74{
75 VtValue value;
76
77 for (const HdExtComputationPrimvarDescriptor &desc :
78 sceneDelegate->GetExtComputationPrimvarDescriptors(GetId(), HdInterpolationVertex))
79 {
80 if (desc.name == HdTokens->points) {
81 auto valueStore = HdExtComputationUtils::GetComputedPrimvarValues({desc}, sceneDelegate);
82 const auto valueStoreIt = valueStore.find(desc.name);
83 if (valueStoreIt != valueStore.end()) {
84 value = std::move(valueStoreIt->second);
85 }
86 break;
87 }
88 }
89
90 if (value.IsEmpty()) {
91 value = GetPrimvar(sceneDelegate, HdTokens->points);
92 }
93
94 if (!value.IsHolding<VtVec3fArray>()) {
95 TF_WARN("Invalid points data for %s", GetId().GetText());
96 return;
97 }
98
99 const auto &points = value.UncheckedGet<VtVec3fArray>();
100
101 array<float3> pointsDataCycles;
102 pointsDataCycles.reserve(points.size());
103
104 for (const GfVec3f &point : points) {
105 pointsDataCycles.push_back_reserved(make_float3(point[0], point[1], point[2]));
106 }
107
108 _geom->set_points(pointsDataCycles);
109}
110
111void HdCyclesPoints::PopulateWidths(HdSceneDelegate *sceneDelegate)
112{
113 VtValue value = GetPrimvar(sceneDelegate, HdTokens->widths);
114 const HdInterpolation interpolation = GetPrimvarInterpolation(sceneDelegate, HdTokens->widths);
115
116 if (!value.IsHolding<VtFloatArray>()) {
117 TF_WARN("Invalid widths data for %s", GetId().GetText());
118 return;
119 }
120
121 const auto &widths = value.UncheckedGet<VtFloatArray>();
122
123 array<float> radiusDataCycles;
124 radiusDataCycles.reserve(_geom->num_points());
125
126 if (interpolation == HdInterpolationConstant) {
127 TF_VERIFY(widths.size() == 1);
128
129 const float constantRadius = widths[0] * 0.5f;
130
131 for (size_t i = 0; i < _geom->num_points(); ++i) {
132 radiusDataCycles.push_back_reserved(constantRadius);
133 }
134 }
135 else if (interpolation == HdInterpolationVertex) {
136 TF_VERIFY(widths.size() == _geom->num_points());
137
138 for (size_t i = 0; i < _geom->num_points(); ++i) {
139 radiusDataCycles.push_back_reserved(widths[i] * 0.5f);
140 }
141 }
142
143 _geom->set_radius(radiusDataCycles);
144}
145
146void HdCyclesPoints::PopulatePrimvars(HdSceneDelegate *sceneDelegate)
147{
148 Scene *const scene = (Scene *)_geom->get_owner();
149
150 const std::pair<HdInterpolation, AttributeElement> interpolations[] = {
151 std::make_pair(HdInterpolationVertex, ATTR_ELEMENT_VERTEX),
152 std::make_pair(HdInterpolationConstant, ATTR_ELEMENT_OBJECT),
153 };
154
155 for (const auto &interpolation : interpolations) {
156 for (const HdPrimvarDescriptor &desc :
157 GetPrimvarDescriptors(sceneDelegate, interpolation.first))
158 {
159 // Skip special primvars that are handled separately
160 if (desc.name == HdTokens->points || desc.name == HdTokens->widths) {
161 continue;
162 }
163
164 VtValue value = GetPrimvar(sceneDelegate, desc.name);
165 if (value.IsEmpty()) {
166 continue;
167 }
168
169 const ustring name(desc.name.GetString());
170
172 if (desc.role == HdPrimvarRoleTokens->textureCoordinate) {
173 std = ATTR_STD_UV;
174 }
175 else if (interpolation.first == HdInterpolationVertex) {
176 if (desc.name == HdTokens->displayColor || desc.role == HdPrimvarRoleTokens->color) {
178 }
179 else if (desc.name == HdTokens->normals) {
181 }
182 }
183 else if (desc.name == HdTokens->displayColor &&
184 interpolation.first == HdInterpolationConstant)
185 {
186 if (value.IsHolding<VtVec3fArray>() && value.GetArraySize() == 1) {
187 const GfVec3f color = value.UncheckedGet<VtVec3fArray>()[0];
188 _instances[0]->set_color(make_float3(color[0], color[1], color[2]));
189 }
190 }
191
192 // Skip attributes that are not needed
193 if ((std != ATTR_STD_NONE && _geom->need_attribute(scene, std)) ||
194 _geom->need_attribute(scene, name))
195 {
196 ApplyPrimvars(_geom->attributes, name, value, interpolation.second, std);
197 }
198 }
199 }
200}
201
PXR_NS::HdInterpolation GetPrimvarInterpolation(PXR_NS::HdSceneDelegate *sceneDelegate, const PXR_NS::TfToken &name) const
Definition geometry.inl:242
PXR_NS::HdDirtyBits GetInitialDirtyBitsMask() const override
Definition geometry.inl:49
HdCyclesPoints(const PXR_NS::SdfPath &rprimId, const PXR_NS::SdfPath &instancerId={})
~HdCyclesPoints() override
PXR_NS::HdDirtyBits GetInitialDirtyBitsMask() const override
void reserve(size_t newcapacity)
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
HDCYCLES_NAMESPACE_OPEN_SCOPE void ApplyPrimvars(AttributeSet &attributes, const ustring &name, VtValue value, AttributeElement elem, AttributeStandard std)
#define HDCYCLES_NAMESPACE_CLOSE_SCOPE
AttributeStandard
@ ATTR_STD_UV
@ ATTR_STD_VERTEX_NORMAL
@ ATTR_STD_NONE
@ ATTR_STD_VERTEX_COLOR
@ ATTR_ELEMENT_OBJECT
@ ATTR_ELEMENT_VERTEX