Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/hydra/pointcloud.cpp')
-rw-r--r--intern/cycles/hydra/pointcloud.cpp199
1 files changed, 199 insertions, 0 deletions
diff --git a/intern/cycles/hydra/pointcloud.cpp b/intern/cycles/hydra/pointcloud.cpp
new file mode 100644
index 00000000000..8d43fd8bfcd
--- /dev/null
+++ b/intern/cycles/hydra/pointcloud.cpp
@@ -0,0 +1,199 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2022 NVIDIA Corporation
+ * Copyright 2022 Blender Foundation */
+
+#include "hydra/pointcloud.h"
+#include "hydra/geometry.inl"
+#include "scene/pointcloud.h"
+
+#include <pxr/imaging/hd/extComputationUtils.h>
+
+HDCYCLES_NAMESPACE_OPEN_SCOPE
+
+HdCyclesPoints::HdCyclesPoints(const SdfPath &rprimId
+#if PXR_VERSION < 2102
+ ,
+ const SdfPath &instancerId
+#endif
+ )
+ : HdCyclesGeometry(rprimId
+#if PXR_VERSION < 2102
+ ,
+ instancerId
+#endif
+ )
+{
+}
+
+HdCyclesPoints::~HdCyclesPoints()
+{
+}
+
+HdDirtyBits HdCyclesPoints::GetInitialDirtyBitsMask() const
+{
+ HdDirtyBits bits = HdCyclesGeometry::GetInitialDirtyBitsMask();
+ bits |= HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyWidths |
+ HdChangeTracker::DirtyPrimvar;
+ return bits;
+}
+
+HdDirtyBits HdCyclesPoints::_PropagateDirtyBits(HdDirtyBits bits) const
+{
+ // Points and widths always have to be updated together
+ if (bits & (HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyWidths)) {
+ bits |= HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyWidths;
+ }
+
+ return bits;
+}
+
+void HdCyclesPoints::Populate(HdSceneDelegate *sceneDelegate, HdDirtyBits dirtyBits, bool &rebuild)
+{
+ if (dirtyBits & (HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyWidths)) {
+ const size_t numPoints = _geom->num_points();
+
+ PopulatePoints(sceneDelegate);
+ PopulateWidths(sceneDelegate);
+
+ rebuild = _geom->num_points() != numPoints;
+
+ array<int> shaders;
+ shaders.reserve(_geom->num_points());
+ for (size_t i = 0; i < _geom->num_points(); ++i) {
+ shaders.push_back_reserved(0);
+ }
+
+ _geom->set_shader(shaders);
+ }
+
+ if (dirtyBits & HdChangeTracker::DirtyPrimvar) {
+ PopulatePrimvars(sceneDelegate);
+ }
+}
+
+void HdCyclesPoints::PopulatePoints(HdSceneDelegate *sceneDelegate)
+{
+ VtValue value;
+
+ for (const HdExtComputationPrimvarDescriptor &desc :
+ sceneDelegate->GetExtComputationPrimvarDescriptors(GetId(), HdInterpolationVertex)) {
+ if (desc.name == HdTokens->points) {
+ auto valueStore = HdExtComputationUtils::GetComputedPrimvarValues({desc}, sceneDelegate);
+ const auto valueStoreIt = valueStore.find(desc.name);
+ if (valueStoreIt != valueStore.end()) {
+ value = std::move(valueStoreIt->second);
+ }
+ break;
+ }
+ }
+
+ if (value.IsEmpty()) {
+ value = GetPrimvar(sceneDelegate, HdTokens->points);
+ }
+
+ if (!value.IsHolding<VtVec3fArray>()) {
+ TF_WARN("Invalid points data for %s", GetId().GetText());
+ return;
+ }
+
+ const auto &points = value.UncheckedGet<VtVec3fArray>();
+
+ array<float3> pointsDataCycles;
+ pointsDataCycles.reserve(points.size());
+
+ for (const GfVec3f &point : points) {
+ pointsDataCycles.push_back_reserved(make_float3(point[0], point[1], point[2]));
+ }
+
+ _geom->set_points(pointsDataCycles);
+}
+
+void HdCyclesPoints::PopulateWidths(HdSceneDelegate *sceneDelegate)
+{
+ VtValue value = GetPrimvar(sceneDelegate, HdTokens->widths);
+ const HdInterpolation interpolation = GetPrimvarInterpolation(sceneDelegate, HdTokens->widths);
+
+ if (!value.IsHolding<VtFloatArray>()) {
+ TF_WARN("Invalid widths data for %s", GetId().GetText());
+ return;
+ }
+
+ const auto &widths = value.UncheckedGet<VtFloatArray>();
+
+ array<float> radiusDataCycles;
+ radiusDataCycles.reserve(_geom->num_points());
+
+ if (interpolation == HdInterpolationConstant) {
+ TF_VERIFY(widths.size() == 1);
+
+ const float constantRadius = widths[0] * 0.5f;
+
+ for (size_t i = 0; i < _geom->num_points(); ++i) {
+ radiusDataCycles.push_back_reserved(constantRadius);
+ }
+ }
+ else if (interpolation == HdInterpolationVertex) {
+ TF_VERIFY(widths.size() == _geom->num_points());
+
+ for (size_t i = 0; i < _geom->num_points(); ++i) {
+ radiusDataCycles.push_back_reserved(widths[i] * 0.5f);
+ }
+ }
+
+ _geom->set_radius(radiusDataCycles);
+}
+
+void HdCyclesPoints::PopulatePrimvars(HdSceneDelegate *sceneDelegate)
+{
+ Scene *const scene = (Scene *)_geom->get_owner();
+
+ const std::pair<HdInterpolation, AttributeElement> interpolations[] = {
+ std::make_pair(HdInterpolationVertex, ATTR_ELEMENT_VERTEX),
+ std::make_pair(HdInterpolationConstant, ATTR_ELEMENT_OBJECT),
+ };
+
+ for (const auto &interpolation : interpolations) {
+ for (const HdPrimvarDescriptor &desc :
+ GetPrimvarDescriptors(sceneDelegate, interpolation.first)) {
+ // Skip special primvars that are handled separately
+ if (desc.name == HdTokens->points || desc.name == HdTokens->widths) {
+ continue;
+ }
+
+ VtValue value = GetPrimvar(sceneDelegate, desc.name);
+ if (value.IsEmpty()) {
+ continue;
+ }
+
+ const ustring name(desc.name.GetString());
+
+ AttributeStandard std = ATTR_STD_NONE;
+ if (desc.role == HdPrimvarRoleTokens->textureCoordinate) {
+ std = ATTR_STD_UV;
+ }
+ else if (interpolation.first == HdInterpolationVertex) {
+ if (desc.name == HdTokens->displayColor || desc.role == HdPrimvarRoleTokens->color) {
+ std = ATTR_STD_VERTEX_COLOR;
+ }
+ else if (desc.name == HdTokens->normals) {
+ std = ATTR_STD_VERTEX_NORMAL;
+ }
+ }
+ else if (desc.name == HdTokens->displayColor &&
+ interpolation.first == HdInterpolationConstant) {
+ if (value.IsHolding<VtVec3fArray>() && value.GetArraySize() == 1) {
+ const GfVec3f color = value.UncheckedGet<VtVec3fArray>()[0];
+ _instances[0]->set_color(make_float3(color[0], color[1], color[2]));
+ }
+ }
+
+ // Skip attributes that are not needed
+ if ((std != ATTR_STD_NONE && _geom->need_attribute(scene, std)) ||
+ _geom->need_attribute(scene, name)) {
+ ApplyPrimvars(_geom->attributes, name, value, interpolation.second, std);
+ }
+ }
+ }
+}
+
+HDCYCLES_NAMESPACE_CLOSE_SCOPE