[Bf-blender-cvs] [fa9d1cb2a99] temp-geometry-nodes-fields-prototype: properly adapt selection domain
Jacques Lucke
noreply at git.blender.org
Mon Aug 9 19:31:44 CEST 2021
Commit: fa9d1cb2a9977980c697c0595cd6dd87007f000d
Author: Jacques Lucke
Date: Mon Aug 9 19:31:32 2021 +0200
Branches: temp-geometry-nodes-fields-prototype
https://developer.blender.org/rBfa9d1cb2a9977980c697c0595cd6dd87007f000d
properly adapt selection domain
===================================================================
M source/blender/blenkernel/BKE_geometry_set.hh
M source/blender/blenkernel/intern/geometry_component_mesh.cc
M source/blender/functions/FN_generic_virtual_array.hh
M source/blender/nodes/geometry/node_geometry_util.cc
M source/blender/nodes/geometry/nodes/node_geo_extrude.cc
===================================================================
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 4118a1013d4..55a239f6a5c 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -396,6 +396,10 @@ class MeshComponent : public GeometryComponent {
const AttributeDomain from_domain,
const AttributeDomain to_domain) const final;
+ blender::VArrayPtr<bool> adapt_selection(blender::VArrayPtr<bool> selection,
+ AttributeDomain from_domain,
+ AttributeDomain to_domain) const;
+
bool is_empty() const final;
bool owns_direct_data() const override;
diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc
index ef93a3f9b3f..d694cdc634d 100644
--- a/source/blender/blenkernel/intern/geometry_component_mesh.cc
+++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc
@@ -651,6 +651,207 @@ blender::fn::GVArrayPtr MeshComponent::attribute_try_adapt_domain(
return {};
}
+namespace blender::bke::adapt_selection_domain {
+static VArrayPtr<bool> varray_from_array(Array<bool> array)
+{
+ return std::make_unique<VArray_For_ArrayContainer<Array<bool>>>(std::move(array));
+}
+
+static VArrayPtr<bool> adapt_selection_point_to_face(const Mesh &mesh, VArrayPtr<bool> selection)
+{
+ Array<bool> new_selection(mesh.totpoly);
+ for (const int poly_index : IndexRange(mesh.totpoly)) {
+ const MPoly &poly = mesh.mpoly[poly_index];
+ bool poly_is_selected = true;
+ for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
+ const MLoop &loop = mesh.mloop[loop_index];
+ if (!selection->get(loop.v)) {
+ poly_is_selected = false;
+ break;
+ }
+ }
+ new_selection[poly_index] = poly_is_selected;
+ }
+ return varray_from_array(std::move(new_selection));
+}
+
+static VArrayPtr<bool> adapt_selection_point_to_corner(const Mesh &mesh, VArrayPtr<bool> selection)
+{
+ Array<bool> new_selection(mesh.totloop);
+ for (const int loop_index : IndexRange(mesh.totloop)) {
+ const MLoop &loop = mesh.mloop[loop_index];
+ new_selection[loop_index] = selection->get(loop.v);
+ }
+ return varray_from_array(std::move(new_selection));
+}
+
+static VArrayPtr<bool> adapt_selection_point_to_edge(const Mesh &mesh, VArrayPtr<bool> selection)
+{
+ Array<bool> new_selection(mesh.totedge);
+ for (const int edge_index : IndexRange(mesh.totedge)) {
+ const MEdge &edge = mesh.medge[edge_index];
+ const bool edge_is_selected = selection->get(edge.v1) && selection->get(edge.v2);
+ new_selection[edge_index] = edge_is_selected;
+ }
+ return varray_from_array(std::move(new_selection));
+}
+
+static VArrayPtr<bool> adapt_selection_edge_to_point(const Mesh &mesh, VArrayPtr<bool> selection)
+{
+ Array<bool> new_selection(mesh.totvert, false);
+ for (const int edge_index : IndexRange(mesh.totedge)) {
+ if (selection->get(edge_index)) {
+ const MEdge &edge = mesh.medge[edge_index];
+ new_selection[edge.v1] = true;
+ new_selection[edge.v2] = true;
+ }
+ }
+ return varray_from_array(std::move(new_selection));
+}
+
+static VArrayPtr<bool> adapt_selection_edge_to_face(const Mesh &mesh, VArrayPtr<bool> selection)
+{
+ Array<bool> new_selection(mesh.totpoly);
+ for (const int poly_index : IndexRange(mesh.totpoly)) {
+ const MPoly &poly = mesh.mpoly[poly_index];
+ bool poly_is_selected = true;
+ for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
+ const MLoop &loop = mesh.mloop[loop_index];
+ if (!selection->get(loop.e)) {
+ poly_is_selected = false;
+ break;
+ }
+ }
+ new_selection[poly_index] = poly_is_selected;
+ }
+ return varray_from_array(std::move(new_selection));
+}
+
+static VArrayPtr<bool> adapt_selection_face_to_point(const Mesh &mesh, VArrayPtr<bool> selection)
+{
+ Array<bool> new_selection(mesh.totvert, false);
+ for (const int poly_index : IndexRange(mesh.totpoly)) {
+ const MPoly &poly = mesh.mpoly[poly_index];
+ if (selection->get(poly_index)) {
+ for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
+ const MLoop &loop = mesh.mloop[loop_index];
+ BLI_assert(loop.v < mesh.totvert);
+ new_selection[loop.v] = true;
+ }
+ }
+ }
+ return varray_from_array(std::move(new_selection));
+}
+
+static VArrayPtr<bool> adapt_selection_face_to_edge(const Mesh &mesh, VArrayPtr<bool> selection)
+{
+ Array<bool> new_selection(mesh.totedge, false);
+ for (const int poly_index : IndexRange(mesh.totpoly)) {
+ const MPoly &poly = mesh.mpoly[poly_index];
+ if (selection->get(poly_index)) {
+ for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
+ const MLoop &loop = mesh.mloop[loop_index];
+ new_selection[loop.e] = true;
+ }
+ }
+ }
+ return varray_from_array(std::move(new_selection));
+}
+
+static VArrayPtr<bool> adapt_selection_face_to_corner(const Mesh &mesh, VArrayPtr<bool> selection)
+{
+ Array<bool> new_selection(mesh.totloop);
+ for (const int poly_index : IndexRange(mesh.totpoly)) {
+ const MPoly &poly = mesh.mpoly[poly_index];
+ const bool is_selected = selection->get(poly_index);
+ for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
+ new_selection[loop_index] = is_selected;
+ }
+ }
+ return varray_from_array(std::move(new_selection));
+}
+
+} // namespace blender::bke::adapt_selection_domain
+
+blender::VArrayPtr<bool> MeshComponent::adapt_selection(blender::VArrayPtr<bool> selection,
+ const AttributeDomain from_domain,
+ const AttributeDomain to_domain) const
+{
+ using namespace blender::bke::adapt_selection_domain;
+
+ const int from_domain_size = this->attribute_domain_size(from_domain);
+ BLI_assert(selection->size() == from_domain_size);
+
+ if (from_domain == to_domain) {
+ return selection;
+ }
+ if (from_domain_size == 0) {
+ return selection;
+ }
+ if (selection->is_single()) {
+ return selection;
+ }
+
+ switch (from_domain) {
+ case ATTR_DOMAIN_CORNER: {
+ switch (to_domain) {
+ case ATTR_DOMAIN_POINT:
+ break;
+ case ATTR_DOMAIN_FACE:
+ break;
+ case ATTR_DOMAIN_EDGE:
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case ATTR_DOMAIN_POINT: {
+ switch (to_domain) {
+ case ATTR_DOMAIN_CORNER:
+ return adapt_selection_point_to_corner(*mesh_, std::move(selection));
+ case ATTR_DOMAIN_FACE:
+ return adapt_selection_point_to_face(*mesh_, std::move(selection));
+ case ATTR_DOMAIN_EDGE:
+ return adapt_selection_point_to_edge(*mesh_, std::move(selection));
+ default:
+ break;
+ }
+ break;
+ }
+ case ATTR_DOMAIN_FACE: {
+ switch (to_domain) {
+ case ATTR_DOMAIN_POINT:
+ return adapt_selection_face_to_point(*mesh_, std::move(selection));
+ case ATTR_DOMAIN_CORNER:
+ return adapt_selection_face_to_corner(*mesh_, std::move(selection));
+ case ATTR_DOMAIN_EDGE:
+ return adapt_selection_face_to_edge(*mesh_, std::move(selection));
+ default:
+ break;
+ }
+ break;
+ }
+ case ATTR_DOMAIN_EDGE: {
+ switch (to_domain) {
+ case ATTR_DOMAIN_CORNER:
+ break;
+ case ATTR_DOMAIN_POINT:
+ return adapt_selection_edge_to_point(*mesh_, std::move(selection));
+ case ATTR_DOMAIN_FACE:
+ return adapt_selection_edge_to_face(*mesh_, std::move(selection));
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return {};
+}
+
static Mesh *get_mesh_from_component_for_write(GeometryComponent &component)
{
BLI_assert(component.type() == GEO_COMPONENT_TYPE_MESH);
diff --git a/source/blender/functions/FN_generic_virtual_array.hh b/source/blender/functions/FN_generic_virtual_array.hh
index be810c89a16..e2ba603415b 100644
--- a/source/blender/functions/FN_generic_virtual_array.hh
+++ b/source/blender/functions/FN_generic_virtual_array.hh
@@ -365,7 +365,7 @@ template<typename T> class GVArray_For_VArray : public GVArray {
{
}
- GVArray_For_VArray(std::unique_ptr<VArray<T>> varray)
+ GVArray_For_VArray(std::unique_ptr<const VArray<T>> varray)
: GVArray_For_VArray(optional_ptr<const VArray<T>>(std::move(varray)))
{
}
@@ -437,7 +437,13 @@ template<typename T> class VArray_For_GVArray : public VArray<T> {
BLI_assert(varray_->type().template is<T>());
}
- VArray_For_GVArray(optional_ptr<const GVArray> varray) : varray_(std::move(varray))
+ VArray_For_GVArray(optional_ptr<const GVArray> varray)
+ : VArray<T>(varray->size()), varray_(std::move(varray))
+ {
+ }
+
+ VArray_For_GVArray(GVArrayPtr varray)
+ : VArray_For_GVArray(optional_ptr<const GVArray>(std::move(varray)))
{
}
diff --git a/source/blender/nodes/geometry/node_geometry_util.cc b/source/blender/nodes/geometry/node_geometry_util.cc
index 4ea12190ae8..1fd24061300 100644
--- a/source/blender/nodes/geometry/node_geometry_util.cc
+++ b/source/blender/nodes/geometry/node_geometry_util.cc
@@ -124,13 +124,34 @@ void prepare_field_inputs(bke::FieldInputs &field_inputs,
}
GVArrayPtr varray = std::move(attribute.varray);
if (attribute.domain != domain) {
- varray = component.attribute_try_adapt_domain(std::move(varray), attribute.domain, domain);
+ /* TODO: Not all boolean attributes are selections. */
+ if (varray->type().is<bool>() && component.type() == GEO_COMPONENT_TYPE_MESH) {
+ const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
+ VArrayPtr<bool> varray_bool = std::make_unique<fn::VArray_For_GVArray<bool>>(
+ std::move(varray));
+ varray_bool = mesh_component.adapt_selection(
+ std::move(varray_bool), attribute.domain, domain);
+ if
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list