[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