[Bf-blender-cvs] [da94c057fd2] gsoc-2021-porting-modifiers-to-nodes-solidify: solidify_extrude_generaly working.

Fabian Schempp noreply at git.blender.org
Tue Jun 22 10:49:52 CEST 2021


Commit: da94c057fd2f0fa432abdf2c8e30dd50bceda0f2
Author: Fabian Schempp
Date:   Mon May 24 08:46:30 2021 +0200
Branches: gsoc-2021-porting-modifiers-to-nodes-solidify
https://developer.blender.org/rBda94c057fd2f0fa432abdf2c8e30dd50bceda0f2

solidify_extrude_generaly working.

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

M	source/blender/nodes/CMakeLists.txt
A	source/blender/nodes/geometry/nodes/node_geo_solidify.h
A	source/blender/nodes/geometry/nodes/node_geo_solidify_extrude.c

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

diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index ee395f0e235..ce486d0e8ab 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -197,6 +197,7 @@ set(SRC
   geometry/nodes/node_geo_select_by_material.cc
   geometry/nodes/node_geo_separate_components.cc
   geometry/nodes/node_geo_solidify.cc
+  geometry/nodes/node_geo_solidify_extrude.c
   geometry/nodes/node_geo_subdivide.cc
   geometry/nodes/node_geo_subdivision_surface.cc
   geometry/nodes/node_geo_switch.cc
diff --git a/source/blender/nodes/geometry/nodes/node_geo_solidify.h b/source/blender/nodes/geometry/nodes/node_geo_solidify.h
new file mode 100644
index 00000000000..e1904717ee8
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_solidify.h
@@ -0,0 +1,13 @@
+//
+// Created by fabian on 24.05.21.
+//
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+Mesh *solidify_extrude_modifyMesh(Mesh *mesh);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/nodes/geometry/nodes/node_geo_solidify_extrude.c b/source/blender/nodes/geometry/nodes/node_geo_solidify_extrude.c
new file mode 100644
index 00000000000..992360a7b1d
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_solidify_extrude.c
@@ -0,0 +1,1240 @@
+/*
+ * 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.
+ */
+
+/** \file
+ * \ingroup modifiers
+ */
+
+#include "BLI_utildefines.h"
+#include <BKE_modifier.h>
+#include <DNA_modifier_types.h>
+
+#include "BLI_bitmap.h"
+#include "BLI_math.h"
+#include "BLI_utildefines_stack.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BKE_deform.h"
+#include "BKE_mesh.h"
+#include "BKE_particle.h"
+#include "node_geo_solidify.h"
+
+//#include "node_geometry_util.hh"
+
+#ifdef __GNUC__
+#  pragma GCC diagnostic error "-Wsign-conversion"
+#endif
+
+/* -------------------------------------------------------------------- */
+/** \name Local Utilities
+ * \{ */
+
+/* specific function for solidify - define locally */
+BLI_INLINE void madd_v3v3short_fl(float r[3], const short a[3], const float f)
+{
+  r[0] += (float)a[0] * f;
+  r[1] += (float)a[1] * f;
+  r[2] += (float)a[2] * f;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name High Quality Normal Calculation Function
+ * \{ */
+
+/* skip shell thickness for non-manifold edges, see T35710. */
+#define USE_NONMANIFOLD_WORKAROUND
+
+/* *** derived mesh high quality normal calculation function  *** */
+/* could be exposed for other functions to use */
+
+typedef struct EdgeFaceRef {
+  int p1; /* init as -1 */
+  int p2;
+} EdgeFaceRef;
+
+BLI_INLINE bool edgeref_is_init(const EdgeFaceRef *edge_ref)
+{
+  return !((edge_ref->p1 == 0) && (edge_ref->p2 == 0));
+}
+
+/**
+ * \param mesh: Mesh to calculate normals for.
+ * \param poly_nors: Precalculated face normals.
+ * \param r_vert_nors: Return vert normals.
+ */
+static void mesh_calc_hq_normal(Mesh *mesh, float (*poly_nors)[3], float (*r_vert_nors)[3])
+{
+  int i, numVerts, numEdges, numPolys;
+  MPoly *mpoly, *mp;
+  MLoop *mloop, *ml;
+  MEdge *medge, *ed;
+  MVert *mvert, *mv;
+
+  numVerts = mesh->totvert;
+  numEdges = mesh->totedge;
+  numPolys = mesh->totpoly;
+  mpoly = mesh->mpoly;
+  medge = mesh->medge;
+  mvert = mesh->mvert;
+  mloop = mesh->mloop;
+
+  /* we don't want to overwrite any referenced layers */
+
+  /* Doesn't work here! */
+#if 0
+  mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, numVerts);
+  cddm->mvert = mv;
+#endif
+
+  mv = mvert;
+  mp = mpoly;
+
+  {
+    EdgeFaceRef *edge_ref_array = MEM_calloc_arrayN(
+        (size_t)numEdges, sizeof(EdgeFaceRef), "Edge Connectivity");
+    EdgeFaceRef *edge_ref;
+    float edge_normal[3];
+
+    /* Add an edge reference if it's not there, pointing back to the face index. */
+    for (i = 0; i < numPolys; i++, mp++) {
+      int j;
+
+      ml = mloop + mp->loopstart;
+
+      for (j = 0; j < mp->totloop; j++, ml++) {
+        /* --- add edge ref to face --- */
+        edge_ref = &edge_ref_array[ml->e];
+        if (!edgeref_is_init(edge_ref)) {
+          edge_ref->p1 = i;
+          edge_ref->p2 = -1;
+        }
+        else if ((edge_ref->p1 != -1) && (edge_ref->p2 == -1)) {
+          edge_ref->p2 = i;
+        }
+        else {
+          /* 3+ faces using an edge, we can't handle this usefully */
+          edge_ref->p1 = edge_ref->p2 = -1;
+#ifdef USE_NONMANIFOLD_WORKAROUND
+          medge[ml->e].flag |= ME_EDGE_TMP_TAG;
+#endif
+        }
+        /* --- done --- */
+      }
+    }
+
+    for (i = 0, ed = medge, edge_ref = edge_ref_array; i < numEdges; i++, ed++, edge_ref++) {
+      /* Get the edge vert indices, and edge value (the face indices that use it) */
+
+      if (edgeref_is_init(edge_ref) && (edge_ref->p1 != -1)) {
+        if (edge_ref->p2 != -1) {
+          /* We have 2 faces using this edge, calculate the edges normal
+           * using the angle between the 2 faces as a weighting */
+#if 0
+          add_v3_v3v3(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]);
+          normalize_v3_length(
+              edge_normal,
+              angle_normalized_v3v3(face_nors[edge_ref->f1], face_nors[edge_ref->f2]));
+#else
+          mid_v3_v3v3_angle_weighted(
+              edge_normal, poly_nors[edge_ref->p1], poly_nors[edge_ref->p2]);
+#endif
+        }
+        else {
+          /* only one face attached to that edge */
+          /* an edge without another attached- the weight on this is undefined */
+          copy_v3_v3(edge_normal, poly_nors[edge_ref->p1]);
+        }
+        add_v3_v3(r_vert_nors[ed->v1], edge_normal);
+        add_v3_v3(r_vert_nors[ed->v2], edge_normal);
+      }
+    }
+    MEM_freeN(edge_ref_array);
+  }
+
+  /* normalize vertex normals and assign */
+  for (i = 0; i < numVerts; i++, mv++) {
+    if (normalize_v3(r_vert_nors[i]) == 0.0f) {
+      normal_short_to_float_v3(r_vert_nors[i], mv->no);
+    }
+  }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Main Solidify Function
+ * \{ */
+/* NOLINTNEXTLINE: readability-function-size */
+Mesh *solidify_extrude_modifyMesh( Mesh *mesh)
+{
+  Mesh *result;
+  //const SolidifyModifierData *smd = (SolidifyModifierData *)md;
+
+  MVert *mv, *mvert, *orig_mvert;
+  MEdge *ed, *medge, *orig_medge;
+  MLoop *ml, *mloop, *orig_mloop;
+  MPoly *mp, *mpoly, *orig_mpoly;
+  const uint numVerts = (uint)mesh->totvert;
+  const uint numEdges = (uint)mesh->totedge;
+  const uint numPolys = (uint)mesh->totpoly;
+  const uint numLoops = (uint)mesh->totloop;
+  uint newLoops = 0, newPolys = 0, newEdges = 0, newVerts = 0, rimVerts = 0;
+
+  /* only use material offsets if we have 2 or more materials  */
+  const short mat_nr_max = 0;//ctx->object->totcol > 1 ? ctx->object->totcol - 1 : 0;
+  const short mat_ofs = mat_nr_max ? 0 : 0; //<--------
+  const short mat_ofs_rim = mat_nr_max ? 0 : 0; //<--------
+
+  /* use for edges */
+  /* over-alloc new_vert_arr, old_vert_arr */
+  uint *new_vert_arr = NULL;
+  STACK_DECLARE(new_vert_arr);
+
+  uint *new_edge_arr = NULL;
+  STACK_DECLARE(new_edge_arr);
+
+  uint *old_vert_arr = MEM_calloc_arrayN(
+      numVerts, sizeof(*old_vert_arr), "old_vert_arr in solidify");
+
+  uint *edge_users = NULL;
+  int *edge_order = NULL;
+
+  float(*vert_nors)[3] = NULL;
+  float(*poly_nors)[3] = NULL;
+
+  const bool need_poly_normals = false; /*(smd->flag & MOD_SOLIDIFY_NORMAL_CALC) ||
+                                 (smd->flag & MOD_SOLIDIFY_EVEN) ||
+                                 (smd->flag & MOD_SOLIDIFY_OFFSET_ANGLE_CLAMP) ||
+                                 (smd->bevel_convex != 0);*/
+
+  const float ofs_orig = 20.0f;//-(((-smd->offset_fac + 1.0f) * 0.5f) * smd->offset);
+  const float ofs_new = 20.0f;//smd->offset + ofs_orig;
+  const float offset_fac_vg = 20.0f;//smd->offset_fac_vg;
+  const float offset_fac_vg_inv = -5.0f;//1.0f - smd->offset_fac_vg;
+  const float bevel_convex = 1.0f;//smd->bevel_convex;
+  const bool do_flip = false;//(smd->flag & MOD_SOLIDIFY_FLIP) != 0;
+  const bool do_clamp = false;//(smd->offset_clamp != 0.0f);
+  const bool do_angle_clamp = false;//do_clamp && (smd->flag & MOD_SOLIDIFY_OFFSET_ANGLE_CLAMP) != 0;
+  const bool do_bevel_convex = bevel_convex != 0.0f;
+  const bool do_rim = true;//(smd->flag & MOD_SOLIDIFY_RIM) != 0;
+  const bool do_shell = true;//!(do_rim && (smd->flag & MOD_SOLIDIFY_NOSHELL) != 0);
+
+  /* weights */
+  MDeformVert *dvert = NULL;
+  const bool defgrp_invert = false;//(smd->flag & MOD_SOLIDIFY_VGROUP_INV) != 0;
+  int defgrp_index;
+  const int shell_defgrp_index = 0;//BKE_object_defgroup_name_index(ctx->object, smd->shell_defgrp_name);
+  const int rim_defgrp_index = 0;//BKE_object_defgroup_name_index(ctx->object, smd->rim_defgrp_name);
+
+  /* array size is doubled in case of using a shell */
+  const uint stride = do_shell ? 2 : 1;
+
+  //MOD_get_vgroup(ctx->object, mesh, smd->defgrp_name, &dvert, &defgrp_index);
+
+  orig_mvert = mesh->mvert;
+  orig_medge = mesh->medge;
+  orig_mloop = mesh->mloop;
+  orig_mpoly = mesh->mpoly;
+
+  if (need_poly_normals) {
+    /* calculate only face normals */
+    poly_nors = MEM_malloc_arrayN(numPolys, sizeof(*poly_nors), __func__);
+    BKE_mesh_calc_normals_poly(orig_mvert,
+                               NULL,
+                               (int)numVerts,
+                               orig_mloop,
+ 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list