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