Blender V4.3
hydra/curves.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/curves.h"
7#include "hydra/geometry.inl"
8#include "scene/hair.h"
9
10#include <pxr/imaging/hd/extComputationUtils.h>
11
13
14HdCyclesCurves::HdCyclesCurves(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 | HdChangeTracker::DirtyTopology;
36 return bits;
37}
38
39HdDirtyBits HdCyclesCurves::_PropagateDirtyBits(HdDirtyBits bits) const
40{
41 if (bits & (HdChangeTracker::DirtyTopology)) {
42 // Changing topology clears the geometry, so need to populate everything again
43 bits |= HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyWidths |
44 HdChangeTracker::DirtyPrimvar;
45 }
46
47 return bits;
48}
49
50void HdCyclesCurves::Populate(HdSceneDelegate *sceneDelegate, HdDirtyBits dirtyBits, bool &rebuild)
51{
52 if (HdChangeTracker::IsTopologyDirty(dirtyBits, GetId())) {
53 PopulateTopology(sceneDelegate);
54 }
55
56 if (dirtyBits & HdChangeTracker::DirtyPoints) {
57 PopulatePoints(sceneDelegate);
58 }
59
60 if (dirtyBits & HdChangeTracker::DirtyWidths) {
61 PopulateWidths(sceneDelegate);
62 }
63
64 if (dirtyBits & HdChangeTracker::DirtyPrimvar) {
65 PopulatePrimvars(sceneDelegate);
66 }
67
68 rebuild = (_geom->curve_keys_is_modified()) || (_geom->curve_radius_is_modified());
69}
70
71void HdCyclesCurves::PopulatePoints(HdSceneDelegate *sceneDelegate)
72{
73 VtValue value;
74
75 for (const HdExtComputationPrimvarDescriptor &desc :
76 sceneDelegate->GetExtComputationPrimvarDescriptors(GetId(), HdInterpolationVertex))
77 {
78 if (desc.name == HdTokens->points) {
79 auto valueStore = HdExtComputationUtils::GetComputedPrimvarValues({desc}, sceneDelegate);
80 const auto valueStoreIt = valueStore.find(desc.name);
81 if (valueStoreIt != valueStore.end()) {
82 value = std::move(valueStoreIt->second);
83 }
84 break;
85 }
86 }
87
88 if (value.IsEmpty()) {
89 value = GetPrimvar(sceneDelegate, HdTokens->points);
90 }
91
92 if (!value.IsHolding<VtVec3fArray>()) {
93 TF_WARN("Invalid points data for %s", GetId().GetText());
94 return;
95 }
96
97 const auto &points = value.UncheckedGet<VtVec3fArray>();
98
99 array<float3> pointsDataCycles;
100 pointsDataCycles.reserve(points.size());
101
102 for (const GfVec3f &point : points) {
103 pointsDataCycles.push_back_reserved(make_float3(point[0], point[1], point[2]));
104 }
105
106 _geom->set_curve_keys(pointsDataCycles);
107}
108
109void HdCyclesCurves::PopulateWidths(HdSceneDelegate *sceneDelegate)
110{
111 VtValue value = GetPrimvar(sceneDelegate, HdTokens->widths);
112 const HdInterpolation interpolation = GetPrimvarInterpolation(sceneDelegate, HdTokens->widths);
113
114 if (!value.IsHolding<VtFloatArray>()) {
115 TF_WARN("Invalid widths data for %s", GetId().GetText());
116 return;
117 }
118
119 const auto &widths = value.UncheckedGet<VtFloatArray>();
120
121 array<float> radiusDataCycles;
122 radiusDataCycles.reserve(widths.size());
123
124 if (interpolation == HdInterpolationConstant) {
125 TF_VERIFY(widths.size() == 1);
126
127 const float constantRadius = widths[0] * 0.5f;
128
129 for (size_t i = 0; i < _geom->num_keys(); ++i) {
130 radiusDataCycles.push_back_reserved(constantRadius);
131 }
132 }
133 else if (interpolation == HdInterpolationVertex) {
134 TF_VERIFY(widths.size() == _geom->num_keys());
135
136 for (size_t i = 0; i < _geom->num_keys(); ++i) {
137 radiusDataCycles.push_back_reserved(widths[i] * 0.5f);
138 }
139 }
140
141 _geom->set_curve_radius(radiusDataCycles);
142}
143
144void HdCyclesCurves::PopulatePrimvars(HdSceneDelegate *sceneDelegate)
145{
146 Scene *const scene = (Scene *)_geom->get_owner();
147
148 const std::pair<HdInterpolation, AttributeElement> interpolations[] = {
149 std::make_pair(HdInterpolationVertex, ATTR_ELEMENT_CURVE_KEY),
150 std::make_pair(HdInterpolationVarying, ATTR_ELEMENT_CURVE_KEY),
151 std::make_pair(HdInterpolationUniform, ATTR_ELEMENT_CURVE),
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 (desc.name == HdTokens->displayColor &&
176 interpolation.first == HdInterpolationConstant)
177 {
178 if (value.IsHolding<VtVec3fArray>() && value.GetArraySize() == 1) {
179 const GfVec3f color = value.UncheckedGet<VtVec3fArray>()[0];
180 _instances[0]->set_color(make_float3(color[0], color[1], color[2]));
181 }
182 }
183
184 // Skip attributes that are not needed
185 if ((std != ATTR_STD_NONE && _geom->need_attribute(scene, std)) ||
186 _geom->need_attribute(scene, name))
187 {
188 ApplyPrimvars(_geom->attributes, name, value, interpolation.second, std);
189 }
190 }
191 }
192}
193
194void HdCyclesCurves::PopulateTopology(HdSceneDelegate *sceneDelegate)
195{
196 // Clear geometry before populating it again with updated topology
197 _geom->clear(true);
198
199 HdBasisCurvesTopology topology = GetBasisCurvesTopology(sceneDelegate);
200
201 _geom->reserve_curves(topology.GetNumCurves(), topology.CalculateNeededNumberOfControlPoints());
202
203 const VtIntArray vertCounts = topology.GetCurveVertexCounts();
204
205 for (int curve = 0, key = 0; curve < topology.GetNumCurves(); ++curve) {
206 // Always reference shader at index zero, which is the primitive material
207 _geom->add_curve(key, 0);
208
209 key += vertCounts[curve];
210 }
211}
212
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
HdCyclesCurves(const PXR_NS::SdfPath &rprimId, const PXR_NS::SdfPath &instancerId={})
PXR_NS::HdDirtyBits GetInitialDirtyBitsMask() const override
~HdCyclesCurves() override
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
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_NONE
@ ATTR_ELEMENT_CURVE_KEY
@ ATTR_ELEMENT_OBJECT
@ ATTR_ELEMENT_CURVE