Blender  V3.3
hydra/curves.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2022 NVIDIA Corporation
3  * Copyright 2022 Blender Foundation */
4 
5 #include "hydra/curves.h"
6 #include "hydra/geometry.inl"
7 #include "scene/hair.h"
8 
9 #include <pxr/imaging/hd/extComputationUtils.h>
10 
12 
13 HdCyclesCurves::HdCyclesCurves(const SdfPath &rprimId
14 #if PXR_VERSION < 2102
15  ,
16  const SdfPath &instancerId
17 #endif
18  )
19  : HdCyclesGeometry(rprimId
20 #if PXR_VERSION < 2102
21  ,
22  instancerId
23 #endif
24  )
25 {
26 }
27 
29 {
30 }
31 
33 {
34  HdDirtyBits bits = HdCyclesGeometry::GetInitialDirtyBitsMask();
35  bits |= HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyWidths |
36  HdChangeTracker::DirtyPrimvar | HdChangeTracker::DirtyTopology;
37  return bits;
38 }
39 
40 HdDirtyBits HdCyclesCurves::_PropagateDirtyBits(HdDirtyBits bits) const
41 {
42  if (bits & (HdChangeTracker::DirtyTopology)) {
43  // Changing topology clears the geometry, so need to populate everything again
44  bits |= HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyWidths |
45  HdChangeTracker::DirtyPrimvar;
46  }
47 
48  return bits;
49 }
50 
51 void HdCyclesCurves::Populate(HdSceneDelegate *sceneDelegate, HdDirtyBits dirtyBits, bool &rebuild)
52 {
53  if (HdChangeTracker::IsTopologyDirty(dirtyBits, GetId())) {
54  PopulateTopology(sceneDelegate);
55  }
56 
57  if (dirtyBits & HdChangeTracker::DirtyPoints) {
58  PopulatePoints(sceneDelegate);
59  }
60 
61  if (dirtyBits & HdChangeTracker::DirtyWidths) {
62  PopulateWidths(sceneDelegate);
63  }
64 
65  if (dirtyBits & HdChangeTracker::DirtyPrimvar) {
66  PopulatePrimvars(sceneDelegate);
67  }
68 
69  rebuild = (_geom->curve_keys_is_modified()) || (_geom->curve_radius_is_modified());
70 }
71 
72 void HdCyclesCurves::PopulatePoints(HdSceneDelegate *sceneDelegate)
73 {
74  VtValue value;
75 
76  for (const HdExtComputationPrimvarDescriptor &desc :
77  sceneDelegate->GetExtComputationPrimvarDescriptors(GetId(), HdInterpolationVertex)) {
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 
109 void 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 
144 void 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  // Skip special primvars that are handled separately
159  if (desc.name == HdTokens->points || desc.name == HdTokens->widths) {
160  continue;
161  }
162 
163  VtValue value = GetPrimvar(sceneDelegate, desc.name);
164  if (value.IsEmpty()) {
165  continue;
166  }
167 
168  const ustring name(desc.name.GetString());
169 
171  if (desc.role == HdPrimvarRoleTokens->textureCoordinate) {
172  std = ATTR_STD_UV;
173  }
174  else if (desc.name == HdTokens->displayColor &&
175  interpolation.first == HdInterpolationConstant) {
176  if (value.IsHolding<VtVec3fArray>() && value.GetArraySize() == 1) {
177  const GfVec3f color = value.UncheckedGet<VtVec3fArray>()[0];
178  _instances[0]->set_color(make_float3(color[0], color[1], color[2]));
179  }
180  }
181 
182  // Skip attributes that are not needed
183  if ((std != ATTR_STD_NONE && _geom->need_attribute(scene, std)) ||
184  _geom->need_attribute(scene, name)) {
185  ApplyPrimvars(_geom->attributes, name, value, interpolation.second, std);
186  }
187  }
188  }
189 }
190 
191 void HdCyclesCurves::PopulateTopology(HdSceneDelegate *sceneDelegate)
192 {
193  // Clear geometry before populating it again with updated topology
194  _geom->clear(true);
195 
196  HdBasisCurvesTopology topology = GetBasisCurvesTopology(sceneDelegate);
197 
198  _geom->reserve_curves(topology.GetNumCurves(), topology.CalculateNeededNumberOfControlPoints());
199 
200  const VtIntArray vertCounts = topology.GetCurveVertexCounts();
201 
202  for (int curve = 0, key = 0; curve < topology.GetNumCurves(); ++curve) {
203  // Always reference shader at index zero, which is the primitive material
204  _geom->add_curve(key, 0);
205 
206  key += vertCounts[curve];
207  }
208 }
209 
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 Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise 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
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 Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input 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 a color
HdCyclesCurves(const PXR_NS::SdfPath &rprimId, const PXR_NS::SdfPath &instancerId={})
PXR_NS::HdDirtyBits GetInitialDirtyBitsMask() const override
~HdCyclesCurves() override
PXR_NS::HdInterpolation GetPrimvarInterpolation(PXR_NS::HdSceneDelegate *sceneDelegate, const PXR_NS::TfToken &name) const
Definition: geometry.inl:241
PXR_NS::HdDirtyBits GetInitialDirtyBitsMask() const override
Definition: geometry.inl:48
void reserve(size_t newcapacity)
Scene scene
Curve curve
HDCYCLES_NAMESPACE_OPEN_SCOPE void ApplyPrimvars(AttributeSet &attributes, const ustring &name, VtValue value, AttributeElement elem, AttributeStandard std)
#define HDCYCLES_NAMESPACE_CLOSE_SCOPE
Definition: hydra/config.h:17
AttributeStandard
Definition: kernel/types.h:612
@ ATTR_STD_UV
Definition: kernel/types.h:616
@ ATTR_STD_NONE
Definition: kernel/types.h:613
@ ATTR_ELEMENT_CURVE_KEY
Definition: kernel/types.h:607
@ ATTR_ELEMENT_OBJECT
Definition: kernel/types.h:599
@ ATTR_ELEMENT_CURVE
Definition: kernel/types.h:606
#define make_float3(x, y, z)
Definition: metal/compat.h:204