[Bf-blender-cvs] [8b74236b43e] temp-geometry-nodes-extrude-mesh: Merge branch 'master' into temp-geometry-nodes-extrude-mesh

Hans Goudey noreply at git.blender.org
Tue Jan 4 17:30:06 CET 2022


Commit: 8b74236b43e6da1a893c47f794c083304b72b718
Author: Hans Goudey
Date:   Tue Jan 4 10:22:35 2022 -0600
Branches: temp-geometry-nodes-extrude-mesh
https://developer.blender.org/rB8b74236b43e6da1a893c47f794c083304b72b718

Merge branch 'master' into temp-geometry-nodes-extrude-mesh

===================================================================



===================================================================

diff --cc source/blender/blenkernel/BKE_node.h
index 3e191a78ac7,56b44994985..68c156c2cec
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@@ -1707,7 -1709,7 +1709,8 @@@ int ntreeTexExecTree(struct bNodeTree *
  #define GEO_NODE_INPUT_MESH_ISLAND 1144
  #define GEO_NODE_INPUT_SCENE_TIME 1145
  #define GEO_NODE_ACCUMULATE_FIELD 1146
- #define GEO_NODE_EXTRUDE_MESH 1147
+ #define GEO_NODE_INPUT_MESH_EDGE_ANGLE 1147
++#define GEO_NODE_EXTRUDE_MESH 1148
  
  /** \} */
  
diff --cc source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
index c819cc26e69,00000000000..21bb1bd0b7f
mode 100644,000000..100644
--- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
@@@ -1,1036 -1,0 +1,1036 @@@
 +/*
 + * This program is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU General Public License
 + * as published by the Free Software Foundation; either version 2
 + * of the License, or (at your option) any later version.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + * GNU General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program; if not, write to the Free Software Foundation,
 + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 + */
 +
 +#include "BLI_task.hh"
 +
 +#include "DNA_mesh_types.h"
 +#include "DNA_meshdata_types.h"
 +
 +#include "BKE_attribute_math.hh"
 +#include "BKE_mesh.h"
 +#include "BKE_mesh_runtime.h"
 +
 +#include "UI_interface.h"
 +#include "UI_resources.h"
 +
 +#include "node_geometry_util.hh"
 +
 +namespace blender::nodes::node_geo_extrude_mesh_cc {
 +
 +NODE_STORAGE_FUNCS(NodeGeometryExtrudeMesh)
 +
 +static void node_declare(NodeDeclarationBuilder &b)
 +{
 +  b.add_input<decl::Geometry>("Mesh").supported_type(GEO_COMPONENT_TYPE_MESH);
 +  b.add_input<decl::Bool>(N_("Selection")).default_value(true).supports_field().hide_value();
 +  b.add_input<decl::Vector>(N_("Offset")).supports_field().subtype(PROP_TRANSLATION);
 +  b.add_input<decl::Bool>(N_("Individual"));
 +  b.add_output<decl::Geometry>("Mesh");
 +  b.add_output<decl::Bool>(N_("Top")).field_source();
 +  b.add_output<decl::Bool>(N_("Side")).field_source();
 +}
 +
 +static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
 +{
 +  uiLayoutSetPropSep(layout, true);
 +  uiLayoutSetPropDecorate(layout, false);
 +  uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
 +}
 +
 +static void node_init(bNodeTree *UNUSED(tree), bNode *node)
 +{
 +  NodeGeometryExtrudeMesh *data = MEM_cnew<NodeGeometryExtrudeMesh>(__func__);
 +  data->mode = GEO_NODE_EXTRUDE_MESH_FACES;
 +  node->storage = data;
 +}
 +
 +static void node_update(bNodeTree *ntree, bNode *node)
 +{
 +  const NodeGeometryExtrudeMesh &storage = node_storage(*node);
 +  const GeometryNodeExtrudeMeshMode mode = static_cast<GeometryNodeExtrudeMeshMode>(storage.mode);
 +
 +  bNodeSocket *individual_socket = (bNodeSocket *)node->inputs.last;
 +
 +  nodeSetSocketAvailability(ntree, individual_socket, mode == GEO_NODE_EXTRUDE_MESH_FACES);
 +}
 +
 +struct AttributeOutputs {
 +  StrongAnonymousAttributeID top_id;
 +  StrongAnonymousAttributeID side_id;
 +};
 +
 +static void save_selection_as_attribute(MeshComponent &component,
 +                                        const AnonymousAttributeID *id,
 +                                        const AttributeDomain domain,
 +                                        const IndexMask selection)
 +{
 +  BLI_assert(!component.attribute_exists(id));
 +
 +  OutputAttribute_Typed<bool> attribute = component.attribute_try_get_for_output_only<bool>(
 +      id, domain);
 +  if (selection.is_range()) {
 +    attribute.as_span().slice(selection.as_range()).fill(true);
 +  }
 +  else {
 +    attribute.as_span().fill_indices(selection, true);
 +  }
 +
 +  attribute.save();
 +}
 +
 +static void expand_mesh_size(Mesh &mesh,
 +                             const int vert_expand,
 +                             const int edge_expand,
 +                             const int poly_expand,
 +                             const int loop_expand)
 +{
 +  if (vert_expand != 0) {
 +    mesh.totvert += vert_expand;
 +    CustomData_duplicate_referenced_layers(&mesh.vdata, mesh.totvert);
 +    CustomData_realloc(&mesh.vdata, mesh.totvert);
 +  }
 +  else {
 +    /* Even when the number of vertices is not changed, the mesh can still be deformed. */
 +    CustomData_duplicate_referenced_layer(&mesh.vdata, CD_MVERT, mesh.totvert);
 +  }
 +  if (edge_expand != 0) {
 +    mesh.totedge += edge_expand;
 +    CustomData_duplicate_referenced_layers(&mesh.edata, mesh.totedge);
 +    CustomData_realloc(&mesh.edata, mesh.totedge);
 +  }
 +  if (poly_expand != 0) {
 +    mesh.totpoly += poly_expand;
 +    CustomData_duplicate_referenced_layers(&mesh.pdata, mesh.totpoly);
 +    CustomData_realloc(&mesh.pdata, mesh.totpoly);
 +  }
 +  if (loop_expand != 0) {
 +    mesh.totloop += loop_expand;
 +    CustomData_duplicate_referenced_layers(&mesh.ldata, mesh.totloop);
 +    CustomData_realloc(&mesh.ldata, mesh.totloop);
 +  }
 +  BKE_mesh_update_customdata_pointers(&mesh, false);
 +
 +  for (MVert &vert : bke::mesh_verts(mesh).take_back(vert_expand)) {
 +    vert.flag = 0;
 +  }
 +}
 +
 +static void extrude_mesh_vertices(MeshComponent &component,
 +                                  const Field<bool> &selection_field,
 +                                  const Field<float3> &offset_field,
 +                                  const AttributeOutputs &attribute_outputs)
 +{
 +  Mesh &mesh = *component.get_for_write();
 +  const int orig_vert_size = mesh.totvert;
 +  const int orig_edge_size = mesh.totedge;
 +
 +  GeometryComponentFieldContext context{component, ATTR_DOMAIN_POINT};
 +  FieldEvaluator evaluator{context, mesh.totvert};
 +  evaluator.add(offset_field);
 +  evaluator.set_selection(selection_field);
 +  evaluator.evaluate();
 +  const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
 +  const VArray<float3> offsets = evaluator.get_evaluated<float3>(0);
 +
 +  expand_mesh_size(mesh, selection.size(), selection.size(), 0, 0);
 +
 +  const IndexRange new_vert_range{orig_vert_size, selection.size()};
 +  const IndexRange new_edge_range{orig_edge_size, selection.size()};
 +
 +  MutableSpan<MVert> new_verts = bke::mesh_verts(mesh).slice(new_vert_range);
 +  MutableSpan<MEdge> new_edges = bke::mesh_edges(mesh).slice(new_edge_range);
 +
 +  for (const int i_selection : selection.index_range()) {
 +    MEdge &edge = new_edges[i_selection];
 +    edge.v1 = selection[i_selection];
 +    edge.v2 = orig_vert_size + i_selection;
 +    edge.flag = ME_LOOSEEDGE;
 +  }
 +
 +  component.attribute_foreach([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
 +    if (!ELEM(meta_data.domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE)) {
 +      return true;
 +    }
 +    OutputAttribute attribute = component.attribute_try_get_for_output(
 +        id, meta_data.domain, meta_data.data_type);
 +    attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
 +      using T = decltype(dummy);
 +      MutableSpan<T> data = attribute.as_span().typed<T>();
 +      switch (attribute.domain()) {
 +        case ATTR_DOMAIN_POINT: {
 +          MutableSpan<T> new_data = data.slice(new_vert_range);
 +          for (const int i : selection.index_range()) {
 +            new_data[i] = data[selection[i]];
 +          }
 +          break;
 +        }
 +        case ATTR_DOMAIN_EDGE: {
 +          MutableSpan<T> new_edges = data.slice(new_edge_range);
 +          new_edges.fill(T());
 +          break;
 +        }
 +        default:
 +          BLI_assert_unreachable();
 +      }
 +    });
 +
 +    attribute.save();
 +    return true;
 +  });
 +
 +  devirtualize_varray(offsets, [&](const auto offsets) {
 +    threading::parallel_for(selection.index_range(), 1024, [&](const IndexRange range) {
 +      for (const int i : range) {
 +        const float3 offset = offsets[selection[i]];
 +        add_v3_v3(new_verts[i].co, offset);
 +      }
 +    });
 +  });
 +
 +  if (attribute_outputs.top_id) {
 +    save_selection_as_attribute(
 +        component, attribute_outputs.top_id.get(), ATTR_DOMAIN_POINT, new_vert_range);
 +  }
 +  if (attribute_outputs.side_id) {
 +    save_selection_as_attribute(
 +        component, attribute_outputs.side_id.get(), ATTR_DOMAIN_EDGE, new_edge_range);
 +  }
 +
 +  BKE_mesh_runtime_clear_cache(&mesh);
 +  BKE_mesh_normals_tag_dirty(&mesh);
 +
 +  BKE_mesh_calc_normals(component.get_for_write());
 +  BLI_assert(BKE_mesh_is_valid(component.get_for_write()));
 +}
 +
 +/**
 + * The resulting vector maps from the index in the added vertices to the original vertex they were
 + * extruded from.
 + */
 +static Vector<int> extrude_vert_orig_indices_from_edges(const IndexMask edge_selection,
 +                                                        const Mesh &mesh,
 +                                                        MutableSpan<int> new_vert_indices)
 +{
 +  Vector<int> new_vert_orig_indices;
 +  new_vert_orig_indices.reserve(edge_selection.size());
 +  for (const int i_edge : edge_selection) {
 +    const MEdge &edge = bke::mesh_edges(mesh)[i_edge];
 +
 +    if (new_vert_indices[edge.v1] == -1) {
 +      new_vert_indices[edge.v1] = mesh.totvert + new_vert_orig_indices.size();
 +      new_vert_orig_indices.append(edge.v1);
 +    }
 +
 +    if (new_vert_indices[edge.v2] == -1) {
 +      new_vert_indices[edge.v2] = mesh.totvert + new_vert_orig_indices.size();
 +      new_vert_orig_indices.append(edge.v2);
 +    }
 +  }
 +  return new_vert_orig_indices;
 +}
 +
 +static void extrude_mesh_edges(MeshComponent &component,
 +                               const Field<bool> &selection_field,
 +                               const Field<float3> &offset_field,
 +                               const AttributeOutputs &attribute_outputs)
 +{
 +  Mesh &mesh = *component.get_for_w

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list