1
1

Compare commits

...

83 Commits

Author SHA1 Message Date
06dadc78a7 updated to fields workflow 2022-02-04 23:39:06 +01:00
c1ae3b850c Merge branch 'master' into soc-2021-porting-modifiers-to-nodes-solidify
# Conflicts:
#	release/scripts/startup/nodeitems_builtins.py
#	source/blender/blenkernel/BKE_node.h
#	source/blender/blenkernel/intern/node.cc
#	source/blender/geometry/CMakeLists.txt
#	source/blender/geometry/intern/solidify_nonmanifold.c
#	source/blender/makesdna/DNA_node_types.h
#	source/blender/makesrna/RNA_enum_types.h
#	source/blender/nodes/CMakeLists.txt
#	source/blender/nodes/NOD_geometry.h
#	source/blender/nodes/NOD_static_types.h
2022-02-03 22:53:51 +01:00
bcb7f4c172 Merge branch 'master' into soc-2021-porting-modifiers-to-nodes-solidify 2021-08-14 00:08:23 +02:00
745ff852f5 Merge branch 'master' into soc-2021-porting-modifiers-to-nodes-solidify
# Conflicts:
#	source/blender/blenkernel/BKE_node.h
#	source/blender/geometry/intern/solidify_nonmanifold.c
#	source/blender/nodes/NOD_static_types.h
2021-08-06 07:58:14 +02:00
c21f9930bc removed makesrna from includes in CMakeLists.txt 2021-07-16 21:17:19 +02:00
906347042d - added geometry module
- moved solidify to geometry module
2021-07-15 22:33:26 +02:00
0d8bb5f898 more cleanup 2021-07-15 11:28:08 +02:00
bcd1a5af89 Cleanup 2021-07-15 11:19:56 +02:00
de9dda76ab Merge branch 'master' into soc-2021-porting-modifiers-to-nodes-solidify
# Conflicts:
#	release/scripts/startup/nodeitems_builtins.py
#	source/blender/blenkernel/BKE_node.h
#	source/blender/blenkernel/intern/node.cc
#	source/blender/blenkernel/intern/solidify_nonmanifold.c
#	source/blender/nodes/CMakeLists.txt
#	source/blender/nodes/NOD_geometry.h
#	source/blender/nodes/NOD_static_types.h
2021-07-15 00:07:52 +02:00
f0f26b3fcb - cleanup 2021-06-25 09:15:21 +02:00
28ee6ef31a - changes previously lost due to merge conflict.
- some more cleanup.
2021-06-25 09:06:18 +02:00
6afd66c2eb Merge branch 'master' into soc-2021-porting-modifiers-to-nodes-solidify 2021-06-25 08:04:02 +02:00
5379633e59 - corrected two comments in corresponding test 2021-06-24 23:11:39 +02:00
051ce30390 Merge branch 'master' into gsoc-2021-porting-modifiers-to-nodes-solidify 2021-06-24 21:16:25 +02:00
1f70e8b748 - changes based on review by Hans Goudey. 2021-06-24 01:37:45 +02:00
ecc67c10e1 - changes based on review by Hans Goudey. 2021-06-24 00:40:57 +02:00
75df5d34d3 - some more cleanup 2021-06-22 11:31:34 +02:00
aedf0f3efa Merge remote-tracking branch 'origin/gsoc-2021-porting-modifiers-to-nodes-solidify' into gsoc-2021-porting-modifiers-to-nodes-solidify
# Conflicts:
#	source/blender/nodes/CMakeLists.txt
#	source/blender/nodes/geometry/nodes/node_geo_solidifiy.cc
2021-06-22 10:49:28 +02:00
97aab4245e - re-added the one important file that I deleted by accident. 2021-06-22 10:43:29 +02:00
897838a2cc - deleted unneeded files 2021-06-22 09:45:28 +02:00
0766941f8f rebaseing and cleanup 2021-06-22 09:41:49 +02:00
bfbeabeb39 - selection for simple 2021-06-22 09:40:18 +02:00
efcab1bc1b makeing node and modifier working with solidify kernel version. 2021-06-22 09:37:36 +02:00
4a4445124e moved solidify to Blender Kernel 2021-06-22 09:28:13 +02:00
a58a4cfc14 - working with data from node 2021-06-22 09:26:06 +02:00
c71b4ee3f6 solidify_extrude_generaly working. 2021-06-22 09:25:49 +02:00
496e3b2b1a - rebased to master
- removed solidify extrude mode from node and reverted solidify extrude
back to internal version in modifier
- fixed vertex-groups for
2021-06-22 09:22:19 +02:00
fa06eb9b97 - added output groups for rim and fill 2021-06-22 09:20:46 +02:00
7d2b039942 Initial setup for solidify node
solidify_extrude_generaly working.

- working with data from node

- added basic support for input data

moved solidify to Blender Kernel

makeing node and modifier working with solidify kernel version.

- added offset and boundary data enums for nonmanifold mode.

- selection for simple

make selection work for complex mode

rebaseing and cleanup

Differential Revision: https://developer.blender.org/D11575
2021-06-22 09:18:10 +02:00
a13e9edfbb - selection for simple 2021-06-22 09:16:06 +02:00
00a3241095 makeing node and modifier working with solidify kernel version. 2021-06-22 09:12:54 +02:00
171a1feeb3 moved solidify to Blender Kernel 2021-06-22 09:04:35 +02:00
c17b1601b7 - added basic support for input data 2021-06-22 09:00:02 +02:00
931b1ed7c7 - working with data from node 2021-06-22 09:00:02 +02:00
b51602996e solidify_extrude_generaly working. 2021-06-22 09:00:02 +02:00
1cc5ab539b Initial setup for solidify node 2021-06-22 09:00:02 +02:00
f12f0f0cd9 generalized material offset for solidify_modifier 2021-06-22 08:59:34 +02:00
2869ee328c added back vertex-group reverse option. 2021-06-22 08:59:34 +02:00
84ecc6c3e1 rebaseing and cleanup 2021-06-22 08:59:34 +02:00
0176d404f1 - selection for simple 2021-06-22 08:59:34 +02:00
821b17be25 makeing node and modifier working with solidify kernel version. 2021-06-22 08:59:34 +02:00
751679edc2 moved solidify to Blender Kernel 2021-06-22 08:59:34 +02:00
fd9932d380 - working with data from node 2021-06-22 08:59:34 +02:00
da94c057fd solidify_extrude_generaly working. 2021-06-22 08:59:34 +02:00
a44785c4dc - formatting 2021-06-22 08:59:34 +02:00
ef51c65775 - rebased to master
- removed solidify extrude mode from node and reverted solidify extrude
back to internal version in modifier
- fixed vertex-groups for
2021-06-22 08:59:34 +02:00
b4ff2ce85d - added output groups for rim and fill 2021-06-22 08:59:34 +02:00
1640c3536f Initial setup for solidify node
solidify_extrude_generaly working.

- working with data from node

- added basic support for input data

moved solidify to Blender Kernel

makeing node and modifier working with solidify kernel version.

- added offset and boundary data enums for nonmanifold mode.

- selection for simple

make selection work for complex mode

rebaseing and cleanup

Differential Revision: https://developer.blender.org/D11575
2021-06-22 08:59:34 +02:00
08fc5f1d8e make selection work for complex mode 2021-06-22 08:59:34 +02:00
339b7a7b03 - selection for simple 2021-06-22 08:59:34 +02:00
5af6c35dd1 - added offset and boundary data enums for nonmanifold mode. 2021-06-22 08:59:34 +02:00
a33076f769 makeing node and modifier working with solidify kernel version. 2021-06-22 08:59:33 +02:00
7026eca6e3 moved solidify to Blender Kernel 2021-06-22 08:59:33 +02:00
0291553d70 - added basic support for input data 2021-06-22 08:59:33 +02:00
48fc1bde95 - working with data from node 2021-06-22 08:59:33 +02:00
48dc0c6fd6 solidify_extrude_generaly working. 2021-06-22 08:59:33 +02:00
95bd8e494c Initial setup for solidify node 2021-06-22 08:59:33 +02:00
328406cf60 generalized material offset for solidify_modifier 2021-06-18 21:14:59 +02:00
3ecf0753e8 added back vertex-group reverse option. 2021-06-18 17:22:24 +02:00
dbeb2a7724 Merge remote-tracking branch 'origin/gsoc-2021-porting-modifiers-to-nodes-solidify' into gsoc-2021-porting-modifiers-to-nodes-solidify
# Conflicts:
#	source/blender/blenkernel/BKE_node.h
#	source/blender/blenkernel/BKE_solidifiy.h
#	source/blender/blenkernel/CMakeLists.txt
#	source/blender/blenkernel/intern/node.cc
#	source/blender/blenkernel/intern/solidify_nonmanifold.c
#	source/blender/makesrna/intern/rna_nodetree.c
#	source/blender/modifiers/intern/MOD_solidify.c
#	source/blender/nodes/CMakeLists.txt
#	source/blender/nodes/NOD_geometry.h
#	source/blender/nodes/NOD_static_types.h
2021-06-18 16:24:12 +02:00
f07aa393bf - formatting 2021-06-18 16:07:51 +02:00
68a28e1982 - rebased to master
- removed solidify extrude mode from node and reverted solidify extrude
back to internal version in modifier
- fixed vertex-groups for
2021-06-18 16:07:51 +02:00
f23bb03cbb - added output groups for rim and fill 2021-06-18 16:07:51 +02:00
1fcbade10c Initial setup for solidify node
solidify_extrude_generaly working.

- working with data from node

- added basic support for input data

moved solidify to Blender Kernel

makeing node and modifier working with solidify kernel version.

- added offset and boundary data enums for nonmanifold mode.

- selection for simple

make selection work for complex mode

rebaseing and cleanup

Differential Revision: https://developer.blender.org/D11575
2021-06-18 16:07:51 +02:00
cbe359bbf2 make selection work for complex mode 2021-06-18 16:07:51 +02:00
3493fefb74 - selection for simple 2021-06-18 16:07:51 +02:00
8f600e8256 - added offset and boundary data enums for nonmanifold mode. 2021-06-18 16:07:51 +02:00
607eef0ae7 makeing node and modifier working with solidify kernel version. 2021-06-18 16:07:51 +02:00
035ee22a50 moved solidify to Blender Kernel 2021-06-18 16:07:51 +02:00
e39543a64d - added basic support for input data 2021-06-18 16:07:51 +02:00
a97bfc4e31 - working with data from node 2021-06-18 16:07:51 +02:00
30ea058694 solidify_extrude_generaly working. 2021-06-18 16:07:51 +02:00
6fad4ce981 Initial setup for solidify node 2021-06-18 16:07:51 +02:00
c718d169a9 rebaseing and cleanup 2021-06-10 21:01:34 +02:00
0a96b035cf make selection work for complex mode 2021-06-10 20:11:24 +02:00
39f1908ba9 - selection for simple 2021-06-10 20:11:24 +02:00
1f38c1f3b2 - added offset and boundary data enums for nonmanifold mode. 2021-06-10 20:11:24 +02:00
5444335e44 makeing node and modifier working with solidify kernel version. 2021-06-10 20:11:24 +02:00
531c65fd93 moved solidify to Blender Kernel 2021-06-10 20:11:09 +02:00
1e07e070fc - added basic support for input data 2021-06-10 20:10:23 +02:00
29c0528eb6 - working with data from node 2021-06-10 20:10:23 +02:00
174052e1de solidify_extrude_generaly working. 2021-06-10 20:10:23 +02:00
caac062b55 Initial setup for solidify node 2021-06-10 20:10:23 +02:00
18 changed files with 637 additions and 242 deletions

View File

@@ -147,6 +147,7 @@ def mesh_node_items(context):
yield NodeItem("GeometryNodeMeshBoolean")
yield NodeItem("GeometryNodeMeshToCurve")
yield NodeItem("GeometryNodeMeshToPoints")
yield NodeItem("GeometryNodeSolidify")
yield NodeItem("GeometryNodeSplitEdges")
yield NodeItem("GeometryNodeSubdivideMesh")
yield NodeItem("GeometryNodeSubdivisionSurface")

View File

@@ -1526,6 +1526,7 @@ struct TexResult;
#define GEO_NODE_SCALE_ELEMENTS 1151
#define GEO_NODE_EXTRUDE_MESH 1152
#define GEO_NODE_MERGE_BY_DISTANCE 1153
#define GEO_NODE_SOLIDIFY 1154
/** \} */

View File

@@ -4845,6 +4845,7 @@ static void registerGeometryNodes()
register_node_type_geo_set_shade_smooth();
register_node_type_geo_set_spline_cyclic();
register_node_type_geo_set_spline_resolution();
register_node_type_geo_solidify();
register_node_type_geo_string_join();
register_node_type_geo_string_to_curves();
register_node_type_geo_subdivision_surface();

View File

@@ -34,11 +34,13 @@ set(SRC
intern/mesh_to_curve_convert.cc
intern/point_merge_by_distance.cc
intern/realize_instances.cc
intern/solidify_nonmanifold.c
GEO_mesh_merge_by_distance.hh
GEO_mesh_to_curve.hh
GEO_point_merge_by_distance.hh
GEO_realize_instances.hh
GEO_solidifiy.h
)
set(LIB

View File

@@ -0,0 +1,43 @@
#include "DNA_object_types.h"
#ifdef __cplusplus
extern "C" {
#endif
struct Mesh;
typedef struct SolidifyData {
const Object *object;
/** New surface offset level. (Thickness) */
float offset;
/** Midpoint of the offset. */
float offset_fac;
/**
* Factor for the minimum weight to use when vertex-groups are used,
* avoids 0.0 weights giving duplicate geometry.
*/
float offset_fac_vg;
/** Clamp offset based on surrounding geometry. */
float offset_clamp;
/** Variables for #MOD_SOLIDIFY_MODE_NONMANIFOLD. */
char nonmanifold_offset_mode;
char nonmanifold_boundary_mode;
int flag;
float merge_tolerance;
float bevel_convex;
const float *distance;
} SolidifyData;
struct Mesh *solidify_nonmanifold(const SolidifyData *solidify_data,
struct Mesh *mesh,
bool **r_shell_verts,
bool **r_rim_verts,
bool **r_shell_faces,
bool **r_rim_faces);
#ifdef __cplusplus
}
#endif

View File

@@ -18,24 +18,20 @@
* \ingroup modifiers
*/
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_modifier_types.h"
#include "GEO_solidifiy.h"
#include "MEM_guardedalloc.h"
#include "BKE_deform.h"
#include "BKE_mesh.h"
#include "BKE_particle.h"
#include "MOD_modifiertypes.h"
#include "MOD_solidify_util.h" /* Own include. */
#include "MOD_util.h"
#ifdef __GNUC__
# pragma GCC diagnostic error "-Wsign-conversion"
#endif
@@ -144,12 +140,14 @@ static int comp_float_int_pair(const void *a, const void *b)
}
/* NOLINTNEXTLINE: readability-function-size */
Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh)
Mesh *solidify_nonmanifold(const SolidifyData *solidify_data,
Mesh *mesh,
bool **r_shell_verts,
bool **r_rim_verts,
bool **r_shell_faces,
bool **r_rim_faces)
{
Mesh *result;
const SolidifyModifierData *smd = (SolidifyModifierData *)md;
MVert *mv, *mvert, *orig_mvert;
MEdge *ed, *medge, *orig_medge;
@@ -158,49 +156,32 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
const uint numVerts = (uint)mesh->totvert;
const uint numEdges = (uint)mesh->totedge;
const uint numPolys = (uint)mesh->totpoly;
const uint numLoops = (uint)mesh->totloop;
if (numPolys == 0 && numVerts != 0) {
return mesh;
}
/* Only use material offsets if we have 2 or more materials. */
const short mat_nrs = ctx->object->totcol > 1 ? ctx->object->totcol : 1;
const short mat_nr_max = mat_nrs - 1;
const short mat_ofs = mat_nrs > 1 ? smd->mat_ofs : 0;
const short mat_ofs_rim = mat_nrs > 1 ? smd->mat_ofs_rim : 0;
float(*poly_nors)[3] = NULL;
/* #ofs_front and #ofs_back are the offset from the original
* surface along the normal, where #oft_front is along the positive
* and #oft_back is along the negative normal. */
const float ofs_front = (smd->offset_fac + 1.0f) * 0.5f * smd->offset;
const float ofs_back = ofs_front - smd->offset * smd->offset_fac;
/* #ofs_front_clamped and #ofs_back_clamped are the same as
* #ofs_front and #ofs_back, but never zero. */
const float ofs_front_clamped = clamp_nonzero(ofs_front, 1e-5f);
const float ofs_back_clamped = clamp_nonzero(ofs_back, 1e-5f);
const float offset_fac_vg = smd->offset_fac_vg;
const float offset_fac_vg_inv = 1.0f - smd->offset_fac_vg;
const float offset = fabsf(smd->offset) * smd->offset_clamp;
const bool do_angle_clamp = smd->flag & MOD_SOLIDIFY_OFFSET_ANGLE_CLAMP;
/* #do_flip, flips the normals of the result. This is inverted if negative thickness
* is used, since simple solidify with negative thickness keeps the faces facing outside. */
const bool do_flip = ((smd->flag & MOD_SOLIDIFY_FLIP) != 0) == (smd->offset > 0);
const bool do_rim = smd->flag & MOD_SOLIDIFY_RIM;
const bool do_shell = ((smd->flag & MOD_SOLIDIFY_RIM) && (smd->flag & MOD_SOLIDIFY_NOSHELL)) ==
0;
const bool do_clamp = (smd->offset_clamp != 0.0f);
const float ofs_front = (solidify_data->offset_fac + 1.0f) * 0.5f * solidify_data->offset;
const float ofs_back = ofs_front - solidify_data->offset * solidify_data->offset_fac;
const float ofs_front_clamped = max_ff(1e-5f,
fabsf(solidify_data->offset > 0 ? ofs_front : ofs_back));
const float ofs_back_clamped = max_ff(1e-5f,
fabsf(solidify_data->offset > 0 ? ofs_back : ofs_front));
const float offset_fac_vg = solidify_data->offset_fac_vg;
const float offset_fac_vg_inv = 1.0f - solidify_data->offset_fac_vg;
const float offset = fabsf(solidify_data->offset) * solidify_data->offset_clamp;
const bool do_angle_clamp = solidify_data->flag & MOD_SOLIDIFY_OFFSET_ANGLE_CLAMP;
const bool do_flip = (solidify_data->flag & MOD_SOLIDIFY_FLIP) != 0;
const bool do_rim = solidify_data->flag & MOD_SOLIDIFY_RIM;
const bool do_shell = solidify_data->flag & MOD_SOLIDIFY_SHELL;
const bool do_clamp = (solidify_data->offset_clamp != 0.0f);
const float bevel_convex = smd->bevel_convex;
const float bevel_convex = solidify_data->bevel_convex;
MDeformVert *dvert;
const bool defgrp_invert = (smd->flag & MOD_SOLIDIFY_VGROUP_INV) != 0;
int defgrp_index;
const int shell_defgrp_index = BKE_id_defgroup_name_index(&mesh->id, smd->shell_defgrp_name);
const int rim_defgrp_index = BKE_id_defgroup_name_index(&mesh->id, smd->rim_defgrp_name);
MOD_get_vgroup(ctx->object, mesh, smd->defgrp_name, &dvert, &defgrp_index);
const bool do_flat_faces = dvert && (smd->flag & MOD_SOLIDIFY_NONMANIFOLD_FLAT_FACES);
const bool do_flat_faces = solidify_data->flag & MOD_SOLIDIFY_NONMANIFOLD_FLAT_FACES;
orig_mvert = mesh->mvert;
orig_medge = mesh->medge;
@@ -214,16 +195,18 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
#define MOD_SOLIDIFY_EMPTY_TAG ((uint)-1)
/* Calculate only face normals. Copied because they are modified directly below. */
float(*poly_nors)[3] = MEM_malloc_arrayN(numPolys, sizeof(float[3]), __func__);
memcpy(poly_nors, BKE_mesh_poly_normals_ensure(mesh), sizeof(float[3]) * numPolys);
/* Calculate only face normals. */
poly_nors = MEM_malloc_arrayN(numPolys, sizeof(*poly_nors), __func__);
BKE_mesh_calc_normals_poly(
orig_mvert, (int)numVerts, orig_mloop, (int)numLoops, orig_mpoly, (int)numPolys, poly_nors);
NewFaceRef *face_sides_arr = MEM_malloc_arrayN(
numPolys * 2, sizeof(*face_sides_arr), "face_sides_arr in solidify");
bool *null_faces =
(smd->nonmanifold_offset_mode == MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_CONSTRAINTS) ?
MEM_calloc_arrayN(numPolys, sizeof(*null_faces), "null_faces in solidify") :
NULL;
bool *null_faces = (solidify_data->nonmanifold_offset_mode ==
MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_CONSTRAINTS) ?
MEM_calloc_arrayN(
numPolys, sizeof(*null_faces), "null_faces in solidify") :
NULL;
uint largest_ngon = 3;
/* Calculate face to #NewFaceRef map. */
{
@@ -363,7 +346,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
bool *face_singularity = MEM_calloc_arrayN(
numPolys, sizeof(*face_singularity), "face_sides_arr in solidify");
const float merge_tolerance_sqr = smd->merge_tolerance * smd->merge_tolerance;
const float merge_tolerance_sqr = solidify_data->merge_tolerance *
solidify_data->merge_tolerance;
uint *combined_verts = MEM_calloc_arrayN(
numVerts, sizeof(*combined_verts), "combined_verts in solidify");
@@ -1397,14 +1381,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
int loopend = mp->loopstart + mp->totloop;
ml = orig_mloop + mp->loopstart;
for (int j = mp->loopstart; j < loopend; j++, ml++) {
MDeformVert *dv = &dvert[ml->v];
if (defgrp_invert) {
scalar_vgroup = min_ff(1.0f - BKE_defvert_find_weight(dv, defgrp_index),
scalar_vgroup);
}
else {
scalar_vgroup = min_ff(BKE_defvert_find_weight(dv, defgrp_index), scalar_vgroup);
}
scalar_vgroup = min_ff(solidify_data->distance[i], scalar_vgroup);
}
scalar_vgroup = offset_fac_vg + (scalar_vgroup * offset_fac_vg_inv);
face_weight[i] = scalar_vgroup;
@@ -1420,11 +1397,12 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
if (!g->is_singularity) {
float *nor = g->no;
float move_nor[3] = {0, 0, 0};
bool disable_boundary_fix = (smd->nonmanifold_boundary_mode ==
bool disable_boundary_fix = (solidify_data->nonmanifold_boundary_mode ==
MOD_SOLIDIFY_NONMANIFOLD_BOUNDARY_MODE_NONE ||
(g->is_orig_closed || g->split));
/* Constraints Method. */
if (smd->nonmanifold_offset_mode == MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_CONSTRAINTS) {
if (solidify_data->nonmanifold_offset_mode ==
MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_CONSTRAINTS) {
NewEdgeRef *first_edge = NULL;
NewEdgeRef **edge_ptr = g->edges;
/* Contains normal and offset [nx, ny, nz, ofs]. */
@@ -1470,7 +1448,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
}
uint face_nors_len = 0;
const float stop_explosion = 0.999f - fabsf(smd->offset_fac) * 0.05f;
const float stop_explosion = 0.999f - fabsf(solidify_data->offset_fac) * 0.05f;
while (queue_index > 0) {
if (face_nors_len == 0) {
if (queue_index <= 2) {
@@ -1620,7 +1598,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
ofs *= face_weight[face->index];
}
if (smd->nonmanifold_offset_mode ==
if (solidify_data->nonmanifold_offset_mode ==
MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_EVEN) {
MLoop *ml_next = orig_mloop + face->face->loopstart;
ml = ml_next + (face->face->totloop - 1);
@@ -1666,7 +1644,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
/* Set normal length with selected method. */
if (smd->nonmanifold_offset_mode == MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_EVEN) {
if (solidify_data->nonmanifold_offset_mode ==
MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_EVEN) {
if (has_front) {
float length_sq = len_squared_v3(nor);
if (LIKELY(length_sq > FLT_EPSILON)) {
@@ -1755,7 +1734,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
sub_v3_v3v3(e1,
orig_mvert_co[vm[e1_edge->v1] == i ? e1_edge->v2 : e1_edge->v1],
orig_mvert_co[i]);
if (smd->nonmanifold_boundary_mode == MOD_SOLIDIFY_NONMANIFOLD_BOUNDARY_MODE_FLAT) {
if (solidify_data->nonmanifold_boundary_mode ==
MOD_SOLIDIFY_NONMANIFOLD_BOUNDARY_MODE_FLAT) {
cross_v3_v3v3(constr_nor, e0, e1);
}
else {
@@ -1789,14 +1769,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
float scalar_vgroup = 1;
/* Use vertex group. */
if (dvert && !do_flat_faces) {
MDeformVert *dv = &dvert[i];
if (defgrp_invert) {
scalar_vgroup = 1.0f - BKE_defvert_find_weight(dv, defgrp_index);
}
else {
scalar_vgroup = BKE_defvert_find_weight(dv, defgrp_index);
}
if (!do_flat_faces) {
scalar_vgroup = solidify_data->distance[i];
scalar_vgroup = offset_fac_vg + (scalar_vgroup * offset_fac_vg_inv);
}
/* Do clamping. */
@@ -1929,16 +1903,32 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
result->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
}
/* Checks that result has dvert data. */
if (shell_defgrp_index != -1 || rim_defgrp_index != -1) {
dvert = CustomData_duplicate_referenced_layer(&result->vdata, CD_MDEFORMVERT, result->totvert);
/* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
if (dvert == NULL) {
/* Add a valid data layer! */
dvert = CustomData_add_layer(
&result->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, result->totvert);
}
result->dvert = dvert;
*r_shell_verts = MEM_malloc_arrayN(
(size_t)result->totvert, sizeof(bool), "shell verts selection in solidify");
for (int i = 0; i < result->totvert; i++) {
(*r_shell_verts)[i] = false;
}
*r_rim_verts = MEM_malloc_arrayN(
(size_t)result->totvert, sizeof(bool), "rim verts selection in solidify");
for (int i = 0; i < result->totvert; i++) {
(*r_rim_verts)[i] = false;
}
*r_shell_faces = MEM_malloc_arrayN(
(size_t)result->totpoly, sizeof(bool), "shell faces selection in solidify");
for (int i = 0; i < result->totpoly; i++) {
(*r_shell_faces)[i] = false;
}
*r_rim_faces = MEM_malloc_arrayN(
(size_t)result->totpoly, sizeof(bool), "rim faces selection in solidify");
for (int i = 0; i < result->totpoly; i++) {
(*r_rim_faces)[i] = false;
}
/* Make_new_verts. */
@@ -2167,50 +2157,17 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
/* Loop data. */
int *loops = MEM_malloc_arrayN(j, sizeof(*loops), "loops in solidify");
/* The #mat_nr is from consensus. */
short most_mat_nr = 0;
uint most_mat_nr_face = 0;
uint most_mat_nr_count = 0;
for (short l = 0; l < mat_nrs; l++) {
uint count = 0;
uint face = 0;
uint k = 0;
for (EdgeGroup *g3 = g2; g3->valid && k < j; g3++) {
if ((do_rim && !g3->is_orig_closed) || (do_shell && g3->split)) {
/* Check both far ends in terms of faces of an edge group. */
if (g3->edges[0]->faces[0]->face->mat_nr == l) {
face = g3->edges[0]->faces[0]->index;
count++;
}
NewEdgeRef *le = g3->edges[g3->edges_len - 1];
if (le->faces[1] && le->faces[1]->face->mat_nr == l) {
face = le->faces[1]->index;
count++;
}
else if (!le->faces[1] && le->faces[0]->face->mat_nr == l) {
face = le->faces[0]->index;
count++;
}
k++;
}
}
if (count > most_mat_nr_count) {
most_mat_nr = l;
most_mat_nr_face = face;
most_mat_nr_count = count;
}
}
CustomData_copy_data(
&mesh->pdata, &result->pdata, (int)most_mat_nr_face, (int)poly_index, 1);
if (origindex_poly) {
origindex_poly[poly_index] = ORIGINDEX_NONE;
}
mpoly[poly_index].loopstart = (int)loop_index;
mpoly[poly_index].totloop = (int)j;
mpoly[poly_index].mat_nr = most_mat_nr +
(g->is_orig_closed || !do_rim ? 0 : mat_ofs_rim);
CLAMP(mpoly[poly_index].mat_nr, 0, mat_nr_max);
mpoly[poly_index].flag = orig_mpoly[most_mat_nr_face].flag;
if (g->is_orig_closed || !do_rim) {
(*r_rim_faces)[poly_index] = true;
}
poly_index++;
for (uint k = 0; g2->valid && k < j; g2++) {
@@ -2282,8 +2239,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
&mesh->pdata, &result->pdata, (int)(*new_edges)->faces[0]->index, (int)poly_index, 1);
mpoly[poly_index].loopstart = (int)loop_index;
mpoly[poly_index].totloop = 4 - (int)(v1_singularity || v2_singularity);
mpoly[poly_index].mat_nr = face->mat_nr + mat_ofs_rim;
CLAMP(mpoly[poly_index].mat_nr, 0, mat_nr_max);
(*r_rim_faces)[poly_index] = true;
mpoly[poly_index].flag = face->flag;
poly_index++;
@@ -2304,20 +2261,17 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
MEdge *open_face_edge;
uint open_face_edge_index;
if (!do_flip) {
if (rim_defgrp_index != -1) {
BKE_defvert_ensure_index(&result->dvert[medge[edge1->new_edge].v1], rim_defgrp_index)
->weight = 1.0f;
}
(*r_rim_verts)[medge[edge1->new_edge].v1] = true;
CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1);
mloop[loop_index].v = medge[edge1->new_edge].v1;
mloop[loop_index++].e = edge1->new_edge;
if (!v2_singularity) {
open_face_edge_index = edge1->link_edge_groups[1]->open_face_edge;
if (rim_defgrp_index != -1) {
BKE_defvert_ensure_index(&result->dvert[medge[edge1->new_edge].v2], rim_defgrp_index)
->weight = 1.0f;
}
(*r_rim_verts)[medge[edge1->new_edge].v2] = true;
CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1);
mloop[loop_index].v = medge[edge1->new_edge].v2;
open_face_edge = medge + open_face_edge_index;
@@ -2328,21 +2282,17 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
mloop[loop_index++].e = edge2->link_edge_groups[1]->open_face_edge;
}
}
(*r_rim_verts)[medge[edge2->new_edge].v2] = true;
if (rim_defgrp_index != -1) {
BKE_defvert_ensure_index(&result->dvert[medge[edge2->new_edge].v2], rim_defgrp_index)
->weight = 1.0f;
}
CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1);
mloop[loop_index].v = medge[edge2->new_edge].v2;
mloop[loop_index++].e = edge2->new_edge;
if (!v1_singularity) {
open_face_edge_index = edge2->link_edge_groups[0]->open_face_edge;
if (rim_defgrp_index != -1) {
BKE_defvert_ensure_index(&result->dvert[medge[edge2->new_edge].v1], rim_defgrp_index)
->weight = 1.0f;
}
(*r_rim_verts)[medge[edge2->new_edge].v1] = true;
CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1);
mloop[loop_index].v = medge[edge2->new_edge].v1;
open_face_edge = medge + open_face_edge_index;
@@ -2357,10 +2307,9 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
else {
if (!v1_singularity) {
open_face_edge_index = edge1->link_edge_groups[0]->open_face_edge;
if (rim_defgrp_index != -1) {
BKE_defvert_ensure_index(&result->dvert[medge[edge1->new_edge].v1], rim_defgrp_index)
->weight = 1.0f;
}
(*r_rim_verts)[medge[edge1->new_edge].v1] = true;
CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1);
mloop[loop_index].v = medge[edge1->new_edge].v1;
open_face_edge = medge + open_face_edge_index;
@@ -2372,20 +2321,17 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
}
if (rim_defgrp_index != -1) {
BKE_defvert_ensure_index(&result->dvert[medge[edge2->new_edge].v1], rim_defgrp_index)
->weight = 1.0f;
}
(*r_rim_verts)[medge[edge2->new_edge].v1] = true;
CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1);
mloop[loop_index].v = medge[edge2->new_edge].v1;
mloop[loop_index++].e = edge2->new_edge;
if (!v2_singularity) {
open_face_edge_index = edge2->link_edge_groups[1]->open_face_edge;
if (rim_defgrp_index != -1) {
BKE_defvert_ensure_index(&result->dvert[medge[edge2->new_edge].v2], rim_defgrp_index)
->weight = 1.0f;
}
(*r_rim_verts)[medge[edge2->new_edge].v2] = true;
CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1);
mloop[loop_index].v = medge[edge2->new_edge].v2;
open_face_edge = medge + open_face_edge_index;
@@ -2397,10 +2343,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
}
if (rim_defgrp_index != -1) {
BKE_defvert_ensure_index(&result->dvert[medge[edge1->new_edge].v2], rim_defgrp_index)
->weight = 1.0f;
}
(*r_rim_verts)[medge[edge1->new_edge].v2] = true;
CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1);
mloop[loop_index].v = medge[edge1->new_edge].v2;
mloop[loop_index++].e = edge1->new_edge;
@@ -2414,10 +2358,13 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
NewFaceRef *fr = face_sides_arr;
uint *face_loops = MEM_malloc_arrayN(
largest_ngon * 2, sizeof(*face_loops), "face_loops in solidify");
uint *face_verts = MEM_malloc_arrayN(
largest_ngon * 2, sizeof(*face_verts), "face_verts in solidify");
uint *face_edges = MEM_malloc_arrayN(
largest_ngon * 2, sizeof(*face_edges), "face_edges in solidify");
for (uint i = 0; i < numPolys * 2; i++, fr++) {
const uint loopstart = (uint)fr->face->loopstart;
uint totloop = (uint)fr->face->totloop;
@@ -2473,15 +2420,15 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
CustomData_copy_data(&mesh->pdata, &result->pdata, (int)(i / 2), (int)poly_index, 1);
mpoly[poly_index].loopstart = (int)loop_index;
mpoly[poly_index].totloop = (int)k;
mpoly[poly_index].mat_nr = fr->face->mat_nr + (fr->reversed != do_flip ? mat_ofs : 0);
CLAMP(mpoly[poly_index].mat_nr, 0, mat_nr_max);
if (fr->reversed != do_flip) {
(*r_shell_faces)[poly_index] = true;
}
mpoly[poly_index].flag = fr->face->flag;
if (fr->reversed != do_flip) {
for (int l = (int)k - 1; l >= 0; l--) {
if (shell_defgrp_index != -1) {
BKE_defvert_ensure_index(&result->dvert[face_verts[l]], shell_defgrp_index)
->weight = 1.0f;
}
(*r_shell_verts)[face_verts[l]] = true;
CustomData_copy_data(
&mesh->ldata, &result->ldata, (int)face_loops[l], (int)loop_index, 1);
mloop[loop_index].v = face_verts[l];
@@ -2506,27 +2453,28 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
MEM_freeN(face_verts);
MEM_freeN(face_edges);
}
if (edge_index != numNewEdges) {
BKE_modifier_set_error(ctx->object,
md,
"Internal Error: edges array wrong size: %u instead of %u",
numNewEdges,
edge_index);
}
if (poly_index != numNewPolys) {
BKE_modifier_set_error(ctx->object,
md,
"Internal Error: polys array wrong size: %u instead of %u",
numNewPolys,
poly_index);
}
if (loop_index != numNewLoops) {
BKE_modifier_set_error(ctx->object,
md,
"Internal Error: loops array wrong size: %u instead of %u",
numNewLoops,
loop_index);
}
/* Haven't found a good way to generalize this. */
// if (edge_index != numNewEdges) {
/*BKE_modifier_set_error(ctx->object,
md,A
"Internal Error: edges array wrong size: %u instead of %u",
numNewEdges,
edge_index);*/
//}
// if (poly_index != numNewPolys) {
/*BKE_modifier_set_error(ctx->object,
md,
"Internal Error: polys array wrong size: %u instead of %u",
numNewPolys,f
poly_index);*/
//}
// if (loop_index != numNewLoops) {
/*BKE_modifier_set_error(ctx->object,
md,
"Internal Error: loops array wrong size: %u instead of %u",
numNewLoops,
loop_index);*/
//}
BLI_assert(edge_index == numNewEdges);
BLI_assert(poly_index == numNewPolys);
BLI_assert(loop_index == numNewLoops);

View File

@@ -399,9 +399,9 @@ enum {
/* We can't have both flags enabled at once,
* flags defined in DNA_scene_types.h */
#define ME_EDIT_PAINT_SEL_MODE(_me) \
(((_me)->editflag & ME_EDIT_PAINT_FACE_SEL) ? SCE_SELECT_FACE : \
((_me)->editflag & ME_EDIT_PAINT_VERT_SEL) ? SCE_SELECT_VERTEX : \
0)
(((_me)->editflag & ME_EDIT_PAINT_FACE_SEL) ? \
SCE_SELECT_FACE : \
((_me)->editflag & ME_EDIT_PAINT_VERT_SEL) ? SCE_SELECT_VERTEX : 0)
/** #Mesh.flag */
enum {

View File

@@ -1314,9 +1314,11 @@ enum {
MOD_SOLIDIFY_RIM_MATERIAL = (1 << 4), /* deprecated, used in do_versions */
#endif
MOD_SOLIDIFY_FLIP = (1 << 5),
MOD_SOLIDIFY_NOSHELL = (1 << 6),
MOD_SOLIDIFY_OFFSET_ANGLE_CLAMP = (1 << 7),
MOD_SOLIDIFY_NONMANIFOLD_FLAT_FACES = (1 << 8),
MOD_SOLIDIFY_SHELL = (1 << 6),
MOD_SOLIDIFY_NOSHELL = (1 << 7), /* MOD_SOLIDIFY_SHELL should be used. instead This is kept as
long as the Modifier uses it. */
MOD_SOLIDIFY_OFFSET_ANGLE_CLAMP = (1 << 8),
MOD_SOLIDIFY_NONMANIFOLD_FLAT_FACES = (1 << 9),
};
/** #SolidifyModifierData.mode */

View File

@@ -1347,6 +1347,14 @@ typedef struct NodeInputColor {
float color[4];
} NodeInputColor;
typedef struct NodeGeometrySolidify {
/* GeometryNodeAttributeInputMode */
uint8_t thickness_mode;
uint8_t nonmanifold_offset_mode;
uint8_t nonmanifold_boundary_mode;
char _pad[5];
} NodeGeometrySolidify;
typedef struct NodeInputString {
char *string;
} NodeInputString;

View File

@@ -4522,6 +4522,36 @@ static void rna_def_modifier_surface(BlenderRNA *brna)
RNA_def_struct_ui_icon(srna, ICON_MOD_PHYSICS);
}
const EnumPropertyItem nonmanifold_thickness_mode_items[] = {
{MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_FIXED,
"FIXED",
0,
"Fixed",
"Most basic thickness calculation"},
{MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_EVEN,
"EVEN",
0,
"Even",
"Even thickness calculation which takes the angle between faces into account"},
{MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_CONSTRAINTS,
"CONSTRAINTS",
0,
"Constraints",
"Thickness calculation using constraints, most advanced"},
{0, NULL, 0, NULL, NULL},
};
const EnumPropertyItem nonmanifold_boundary_mode_items[] = {
{MOD_SOLIDIFY_NONMANIFOLD_BOUNDARY_MODE_NONE, "NONE", 0, "None", "No shape correction"},
{MOD_SOLIDIFY_NONMANIFOLD_BOUNDARY_MODE_ROUND,
"ROUND",
0,
"Round",
"Round open perimeter shape"},
{MOD_SOLIDIFY_NONMANIFOLD_BOUNDARY_MODE_FLAT, "FLAT", 0, "Flat", "Flat open perimeter shape"},
{0, NULL, 0, NULL, NULL},
};
static void rna_def_modifier_solidify(BlenderRNA *brna)
{
static const EnumPropertyItem mode_items[] = {
@@ -4540,40 +4570,6 @@ static void rna_def_modifier_solidify(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem nonmanifold_thickness_mode_items[] = {
{MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_FIXED,
"FIXED",
0,
"Fixed",
"Most basic thickness calculation"},
{MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_EVEN,
"EVEN",
0,
"Even",
"Even thickness calculation which takes the angle between faces into account"},
{MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_CONSTRAINTS,
"CONSTRAINTS",
0,
"Constraints",
"Thickness calculation using constraints, most advanced"},
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem nonmanifold_boundary_mode_items[] = {
{MOD_SOLIDIFY_NONMANIFOLD_BOUNDARY_MODE_NONE, "NONE", 0, "None", "No shape correction"},
{MOD_SOLIDIFY_NONMANIFOLD_BOUNDARY_MODE_ROUND,
"ROUND",
0,
"Round",
"Round open perimeter shape"},
{MOD_SOLIDIFY_NONMANIFOLD_BOUNDARY_MODE_FLAT,
"FLAT",
0,
"Flat",
"Flat open perimeter shape"},
{0, NULL, 0, NULL, NULL},
};
StructRNA *srna;
PropertyRNA *prop;

View File

@@ -10485,6 +10485,59 @@ static void def_geo_point_scale(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
static const EnumPropertyItem nonmanifold_thickness_mode_items[] = {
{MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_FIXED,
"FIXED",
0,
"Fixed",
"Most basic thickness calculation"},
{MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_EVEN,
"EVEN",
0,
"Even",
"Even thickness calculation which takes the angle between faces into account"},
{MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_CONSTRAINTS,
"CONSTRAINTS",
0,
"Constraints",
"Thickness calculation using constraints, most advanced"},
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem nonmanifold_boundary_mode_items[] = {
{MOD_SOLIDIFY_NONMANIFOLD_BOUNDARY_MODE_NONE, "NONE", 0, "None", "No shape correction"},
{MOD_SOLIDIFY_NONMANIFOLD_BOUNDARY_MODE_ROUND,
"ROUND",
0,
"Round",
"Round open perimeter shape"},
{MOD_SOLIDIFY_NONMANIFOLD_BOUNDARY_MODE_FLAT, "FLAT", 0, "Flat", "Flat open perimeter shape"},
{0, NULL, 0, NULL, NULL},
};
static void def_geo_solidify(StructRNA *srna)
{
PropertyRNA *prop;
RNA_def_struct_sdna_from(srna, "NodeGeometrySolidify", "storage");
prop = RNA_def_property(srna, "thickness_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
RNA_def_property_ui_text(
prop, "Thickness", "Changes the Thickness input between Float and Attribute");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
prop = RNA_def_property(srna, "nonmanifold_offset_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, nonmanifold_thickness_mode_items);
RNA_def_property_ui_text(prop, "Mode", "Selects the used thickness algorithm");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
prop = RNA_def_property(srna, "nonmanifold_boundary_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, nonmanifold_boundary_mode_items);
RNA_def_property_ui_text(prop, "Boundary", "Selects the boundary adjustment algorithm");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
static void def_geo_point_translate(StructRNA *srna)
{
PropertyRNA *prop;

View File

@@ -96,8 +96,7 @@ set(SRC
intern/MOD_softbody.c
intern/MOD_solidify.c
intern/MOD_solidify_extrude.c
intern/MOD_solidify_nonmanifold.c
intern/MOD_subsurf.c
intern/MOD_subsurf.c
intern/MOD_surface.c
intern/MOD_surfacedeform.c
intern/MOD_triangulate.c
@@ -130,7 +129,8 @@ set(SRC
set(LIB
bf_blenkernel
bf_blenlib
)
bf_geometry
)
if(WITH_ALEMBIC)
add_definitions(-DWITH_ALEMBIC)

View File

@@ -29,22 +29,26 @@
#include "DNA_defaults.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "BKE_context.h"
#include "BKE_particle.h"
#include "BKE_deform.h"
#include "BKE_screen.h"
#include "GEO_solidifiy.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "RNA_access.h"
#include "MOD_modifiertypes.h"
#include "MOD_ui_common.h"
#include "MEM_guardedalloc.h"
#include "MOD_modifiertypes.h"
#include "MOD_solidify_util.h"
#include "MOD_ui_common.h"
static bool dependsOnNormals(ModifierData *md)
{
@@ -81,14 +85,154 @@ static void requiredDataMask(Object *UNUSED(ob),
}
}
static void get_distance_factor(
Mesh *mesh, Object *ob, const char *name, bool invert, float *r_selection)
{
int defgrp_index = BKE_object_defgroup_name_index(ob, name);
if (mesh && defgrp_index != -1) {
MDeformVert *dvert = mesh->dvert;
for (int i = 0; i < mesh->totvert; i++) {
MDeformVert *dv = &dvert[i];
r_selection[i] = BKE_defvert_find_weight(dv, defgrp_index);
}
}
else {
for (int i = 0; i < mesh->totvert; i++) {
r_selection[i] = 1.0f;
}
}
if (invert) {
for (int i = 0; i < mesh->totvert; i++) {
r_selection[i] = 1.0f - r_selection[i];
}
}
}
static SolidifyData solidify_data_from_modifier_data(ModifierData *md,
const ModifierEvalContext *ctx)
{
const SolidifyModifierData *smd = (SolidifyModifierData *)md;
SolidifyData solidify_data = {
ctx->object,
smd->offset,
smd->offset_fac,
smd->offset_fac_vg,
smd->offset_clamp,
smd->nonmanifold_offset_mode,
smd->nonmanifold_boundary_mode,
smd->flag,
smd->merge_tolerance,
smd->bevel_convex,
NULL,
};
if (!(smd->flag & MOD_SOLIDIFY_NOSHELL)) {
solidify_data.flag |= MOD_SOLIDIFY_SHELL;
}
return solidify_data;
}
static Mesh *solidify_nonmanifold_modify_mesh(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh,
const SolidifyModifierData *smd)
{
SolidifyData solidify_data = solidify_data_from_modifier_data(md, ctx);
const bool defgrp_invert = (solidify_data.flag & MOD_SOLIDIFY_VGROUP_INV) != 0;
float *selection = MEM_callocN(sizeof(float) * (uint64_t)mesh->totvert, __func__);
get_distance_factor(mesh, ctx->object, smd->defgrp_name, defgrp_invert, selection);
solidify_data.distance = selection;
bool *shell_verts = NULL;
bool *rim_verts = NULL;
bool *shell_faces = NULL;
bool *rim_faces = NULL;
Mesh *output_mesh = solidify_nonmanifold(
&solidify_data, mesh, &shell_verts, &rim_verts, &shell_faces, &rim_faces);
const int shell_defgrp_index = BKE_object_defgroup_name_index(ctx->object,
smd->shell_defgrp_name);
const int rim_defgrp_index = BKE_object_defgroup_name_index(ctx->object, smd->rim_defgrp_name);
MDeformVert *dvert;
if (shell_defgrp_index != -1 || rim_defgrp_index != -1) {
dvert = CustomData_duplicate_referenced_layer(
&output_mesh->vdata, CD_MDEFORMVERT, output_mesh->totvert);
/* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
if (dvert == NULL) {
/* Add a valid data layer! */
dvert = CustomData_add_layer(
&output_mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, output_mesh->totvert);
}
output_mesh->dvert = dvert;
if ((solidify_data.flag & MOD_SOLIDIFY_SHELL) && shell_defgrp_index != -1) {
for (int i = 0; i < output_mesh->totvert; i++) {
BKE_defvert_ensure_index(&output_mesh->dvert[i], shell_defgrp_index)->weight =
shell_verts[i];
}
}
if ((solidify_data.flag & MOD_SOLIDIFY_RIM) && rim_defgrp_index != -1) {
for (int i = 0; i < output_mesh->totvert; i++) {
BKE_defvert_ensure_index(&output_mesh->dvert[i], rim_defgrp_index)->weight = rim_verts[i];
}
}
}
/* Only use material offsets if we have 2 or more materials. */
const short mat_nrs = ctx->object->totcol > 1 ? ctx->object->totcol : 1;
const short mat_nr_max = mat_nrs - 1;
const short mat_ofs = mat_nrs > 1 ? smd->mat_ofs : 0;
const short mat_ofs_rim = mat_nrs > 1 ? smd->mat_ofs_rim : 0;
short most_mat_nr = 0;
uint most_mat_nr_count = 0;
for (int mat_nr = 0; mat_nr < mat_nrs; mat_nr++) {
uint count = 0;
for (int i = 0; i < mesh->totpoly; i++) {
if (mesh->mpoly[i].mat_nr == mat_nr) {
count++;
}
}
if (count > most_mat_nr_count) {
most_mat_nr = mat_nr;
}
}
for (int i = 0; i < output_mesh->totpoly; i++) {
output_mesh->mpoly[i].mat_nr = most_mat_nr;
if (mat_ofs > 0 && shell_faces && shell_faces[i]) {
output_mesh->mpoly[i].mat_nr += mat_ofs;
CLAMP(output_mesh->mpoly[i].mat_nr, 0, mat_nr_max);
}
else if (mat_ofs_rim > 0 && rim_faces && rim_faces[i]) {
output_mesh->mpoly[i].mat_nr += mat_ofs_rim;
CLAMP(output_mesh->mpoly[i].mat_nr, 0, mat_nr_max);
}
}
MEM_freeN(selection);
MEM_freeN(shell_verts);
MEM_freeN(rim_verts);
MEM_freeN(shell_faces);
MEM_freeN(rim_faces);
return output_mesh;
}
static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
const SolidifyModifierData *smd = (SolidifyModifierData *)md;
switch (smd->mode) {
case MOD_SOLIDIFY_MODE_EXTRUDE:
return MOD_solidify_extrude_modifyMesh(md, ctx, mesh);
case MOD_SOLIDIFY_MODE_NONMANIFOLD:
return MOD_solidify_nonmanifold_modifyMesh(md, ctx, mesh);
case MOD_SOLIDIFY_MODE_NONMANIFOLD: {
return solidify_nonmanifold_modify_mesh(md, ctx, mesh, smd);
}
default:
BLI_assert(0);
}

View File

@@ -24,8 +24,3 @@
Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh);
/* MOD_solidify_nonmanifold.c */
Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh);

View File

@@ -174,6 +174,7 @@ void register_node_type_geo_set_position(void);
void register_node_type_geo_set_shade_smooth(void);
void register_node_type_geo_set_spline_cyclic(void);
void register_node_type_geo_set_spline_resolution(void);
void register_node_type_geo_solidify(void);
void register_node_type_geo_string_join(void);
void register_node_type_geo_string_to_curves(void);
void register_node_type_geo_subdivision_surface(void);

View File

@@ -427,6 +427,7 @@ DefNode(GeometryNode, GEO_NODE_SET_POSITION, 0, "SET_POSITION", SetPosition, "Se
DefNode(GeometryNode, GEO_NODE_SET_SHADE_SMOOTH, 0, "SET_SHADE_SMOOTH", SetShadeSmooth, "Set Shade Smooth", "")
DefNode(GeometryNode, GEO_NODE_SET_SPLINE_CYCLIC, 0, "SET_SPLINE_CYCLIC", SetSplineCyclic, "Set Spline Cyclic", "")
DefNode(GeometryNode, GEO_NODE_SET_SPLINE_RESOLUTION, 0, "SET_SPLINE_RESOLUTION", SetSplineResolution, "Set Spline Resolution", "")
DefNode(GeometryNode, GEO_NODE_SOLIDIFY, def_geo_solidify, "SOLIDIFY", Solidify, "Solidify", "")
DefNode(GeometryNode, GEO_NODE_SPLIT_EDGES, 0, "SPLIT_EDGES", SplitEdges, "Split Edges", "")
DefNode(GeometryNode, GEO_NODE_STRING_JOIN, 0, "STRING_JOIN", StringJoin, "Join Strings", "")
DefNode(GeometryNode, GEO_NODE_STRING_TO_CURVES, def_geo_string_to_curves, "STRING_TO_CURVES", StringToCurves, "String to Curves", "")

View File

@@ -184,6 +184,7 @@ set(SRC
nodes/node_geo_set_shade_smooth.cc
nodes/node_geo_set_spline_cyclic.cc
nodes/node_geo_set_spline_resolution.cc
nodes/node_geo_solidify.cc
nodes/node_geo_string_join.cc
nodes/node_geo_string_to_curves.cc
nodes/node_geo_subdivision_surface.cc

View File

@@ -0,0 +1,198 @@
/*
* 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 "BKE_node.h"
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_node_types.h"
#include "GEO_solidifiy.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_solidify {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH);
b.add_input<decl::Float>(N_("Thickness"))
.default_value(0.0f)
.subtype(PROP_DISTANCE)
.supports_field();
b.add_input<decl::Float>(N_("Clamp"))
.default_value(0.0f)
.min(0.0f)
.max(2.0f)
.subtype(PROP_FACTOR);
b.add_input<decl::Float>(N_("Offset"))
.default_value(0.0f)
.min(-1.0f)
.max(1.0f)
.subtype(PROP_FACTOR);
b.add_input<decl::Bool>(N_("Fill")).default_value(true);
b.add_input<decl::Bool>(N_("Rim")).default_value(true);
b.add_output<decl::Geometry>(N_("Mesh"));
b.add_output<decl::Bool>(N_("Fill Faces")).field_source();
b.add_output<decl::Bool>(N_("Rim Faces")).field_source();
}
static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
uiItemR(layout, ptr, "nonmanifold_offset_mode", 0, nullptr, ICON_NONE);
uiItemR(layout, ptr, "nonmanifold_boundary_mode", 0, nullptr, ICON_NONE);
}
static void geo_node_solidify_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometrySolidify *node_storage = (NodeGeometrySolidify *)MEM_callocN(
sizeof(NodeGeometrySolidify), __func__);
node->storage = node_storage;
}
static void node_geo_exec(GeoNodeExecParams params)
{
const bNode &node = params.node();
NodeGeometrySolidify &node_storage = *(NodeGeometrySolidify *)node.storage;
const Object *self_object = params.self_object();
bool add_fill = params.extract_input<bool>("Fill");
bool add_rim = params.extract_input<bool>("Rim");
GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh");
float offset = params.extract_input<float>("Offset");
float offset_clamp = params.extract_input<float>("Clamp");
bke::StrongAnonymousAttributeID fill_id;
bke::StrongAnonymousAttributeID rim_id;
if (geometry_set.has<MeshComponent>()) {
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
MeshComponent &component = geometry_set.get_component_for_write<MeshComponent>();
Mesh *input_mesh = component.get_for_write();
const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
GeometryComponentFieldContext context{component, ATTR_DOMAIN_POINT};
Field<float> thickness_field = params.extract_input<Field<float>>("Thickness");
FieldEvaluator thickness_evaluator{context, domain_size};
thickness_evaluator.add(thickness_field);
thickness_evaluator.evaluate();
Array<float> thickness(domain_size);
thickness_evaluator.get_evaluated<float>(0).materialize(thickness);
char flag = 0;
if (add_fill) {
flag |= MOD_SOLIDIFY_SHELL;
}
if (add_rim) {
flag |= MOD_SOLIDIFY_RIM;
}
SolidifyData solidify_node_data = {
self_object,
1,
offset,
0.0f,
offset_clamp,
node_storage.nonmanifold_offset_mode,
node_storage.nonmanifold_boundary_mode,
flag,
0.01f,
0.0f,
thickness.begin(),
};
bool *shell_verts = nullptr;
bool *rim_verts = nullptr;
bool *shell_faces = nullptr;
bool *rim_faces = nullptr;
Mesh *output_mesh = solidify_nonmanifold(
&solidify_node_data, input_mesh, &shell_verts, &rim_verts, &shell_faces, &rim_faces);
if (output_mesh != input_mesh) {
component.replace(output_mesh, GeometryOwnershipType::Editable);
if (params.output_is_required("Fill Faces")) {
fill_id = StrongAnonymousAttributeID("fill_faces");
if (add_fill) {
OutputAttribute_Typed<bool> shell_faces_attribute =
component.attribute_try_get_for_output_only<bool>(fill_id.get(), ATTR_DOMAIN_FACE);
Span<bool> shell_faces_span(shell_faces, shell_faces_attribute->size());
shell_faces_attribute->set_all(shell_faces_span);
shell_faces_attribute.save();
}
}
if (params.output_is_required("Rim Faces")) {
rim_id = StrongAnonymousAttributeID("rim_faces");
if (add_rim) {
OutputAttribute_Typed<bool> rim_faces_attribute =
component.attribute_try_get_for_output_only<bool>(rim_id.get(), ATTR_DOMAIN_FACE);
Span<bool> rim_faces_span(rim_faces, rim_faces_attribute->size());
rim_faces_attribute->set_all(rim_faces_span);
rim_faces_attribute.save();
}
}
}
MEM_freeN(shell_verts);
MEM_freeN(rim_verts);
MEM_freeN(shell_faces);
MEM_freeN(rim_faces);
});
}
if (fill_id) {
params.set_output("Fill Faces",
AnonymousAttributeFieldInput::Create<bool>(
std::move(fill_id), params.attribute_producer_name()));
}
if (rim_id) {
params.set_output("Rim Faces",
AnonymousAttributeFieldInput::Create<bool>(
std::move(rim_id), params.attribute_producer_name()));
}
params.set_output("Mesh", geometry_set);
}
} // namespace blender::nodes::node_geo_solidify
void register_node_type_geo_solidify()
{
namespace file_ns = blender::nodes::node_geo_solidify;
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_SOLIDIFY, "Solidify", NODE_CLASS_GEOMETRY);
ntype.declare = file_ns::node_declare;
node_type_storage(
&ntype, "NodeGeometrySolidify", node_free_standard_storage, node_copy_standard_storage);
node_type_init(&ntype, file_ns::geo_node_solidify_init);
node_type_size(&ntype, 172, 100, 600);
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
}