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
struct Scene Scene
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a color
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
HdCyclesGeometry(const PXR_NS::SdfPath &rprimId, const PXR_NS::SdfPath &instancerId)
Definition geometry.inl:23
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
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