[Bf-blender-cvs] [df9a5825e16] sculpt-dev: Initial commit for new generic sculpt expand operator
Pablo Dobarro
noreply at git.blender.org
Wed Jan 13 23:00:31 CET 2021
Commit: df9a5825e16df9f3a6e375e592d6c8d3a2f677ee
Author: Pablo Dobarro
Date: Wed Jan 13 22:59:59 2021 +0100
Branches: sculpt-dev
https://developer.blender.org/rBdf9a5825e16df9f3a6e375e592d6c8d3a2f677ee
Initial commit for new generic sculpt expand operator
===================================================================
M source/blender/blenkernel/BKE_paint.h
M source/blender/editors/sculpt_paint/CMakeLists.txt
A source/blender/editors/sculpt_paint/sculpt_expand.c
M source/blender/editors/sculpt_paint/sculpt_intern.h
===================================================================
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index bf478e44f97..ecabda9e207 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -515,6 +515,7 @@ typedef struct SculptSession {
struct StrokeCache *cache;
struct FilterCache *filter_cache;
+ struct ExpandCache *expand_cache;
/* Cursor data and active vertex for tools */
int active_vertex_index;
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index e6b0b6431fc..025fa6b0697 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -61,6 +61,7 @@ set(SRC
sculpt_cloth.c
sculpt_detail.c
sculpt_dyntopo.c
+ sculpt_expand.c
sculpt_face_set.c
sculpt_filter_color.c
sculpt_filter_mask.c
diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.c b/source/blender/editors/sculpt_paint/sculpt_expand.c
new file mode 100644
index 00000000000..2c53e320522
--- /dev/null
+++ b/source/blender/editors/sculpt_paint/sculpt_expand.c
@@ -0,0 +1,689 @@
+/*
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup edsculpt
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_task.h"
+
+#include "BLT_translation.h"
+
+#include "DNA_brush_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+
+#include "BKE_brush.h"
+#include "BKE_ccg.h"
+#include "BKE_colortools.h"
+#include "BKE_context.h"
+#include "BKE_mesh.h"
+#include "BKE_multires.h"
+#include "BKE_node.h"
+#include "BKE_object.h"
+#include "BKE_paint.h"
+#include "BKE_pbvh.h"
+#include "BKE_scene.h"
+
+#include "DEG_depsgraph.h"
+
+#include "WM_api.h"
+#include "WM_message.h"
+#include "WM_toolsystem.h"
+#include "WM_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "ED_object.h"
+#include "ED_screen.h"
+#include "ED_sculpt.h"
+#include "ED_view3d.h"
+#include "paint_intern.h"
+#include "sculpt_intern.h"
+
+#include "bmesh.h"
+
+#include <math.h>
+#include <stdlib.h>
+
+
+static EnumPropertyItem prop_sculpt_expand_faloff_type_items[] = {
+ {SCULPT_EXPAND_FALLOFF_GEODESICS, "GEODESICS", 0, "Surface", ""},
+ {SCULPT_EXPAND_FALLOFF_TOPOLOGY, "TOPOLOGY", 0, "Topology", ""},
+ {SCULPT_EXPAND_FALLOFF_NORMALS, "NORMALS", 0, "Normals", ""},
+ {SCULPT_EXPAND_FALLOFF_SPHERICAL, "SPHERICAL", 0, "Spherical", ""},
+ {0, NULL, 0, NULL, NULL},
+};
+
+
+
+static float *sculpt_expand_geodesic_falloff_create(Sculpt *sd, Object *ob, const int vertex) {
+ return SCULPT_geodesic_from_vertex_and_symm(sd, ob, vertex, FLT_MAX);
+}
+
+static float *sculpt_expand_topology_falloff_create() {
+ return NULL;
+}
+
+static float *sculpt_expand_spherical_falloff_create() {
+ return NULL;
+}
+
+static float *sculpt_expand_normal_falloff_create() {
+ return NULL;
+}
+
+static void sculpt_expand_update_max_falloff_factor(SculptSession *ss, ExpandCache *expand_cache) {
+ const int totvert = SCULPT_vertex_count_get(ss);
+ expand_cache->max_falloff_factor = -FLT_MAX;
+ for (int i = 0; i < totvert; i++) {
+ expand_cache->max_falloff_factor = max_ff(expand_cache->max_falloff_factor, expand_cache->falloff_factor[i]);
+ }
+}
+
+
+static void sculpt_expand_falloff_factors_from_vertex_and_symm_create(ExpandCache *expand_cache, Sculpt *sd, Object *ob, const int vertex, eSculptExpandFalloffType falloff_type) {
+ if (expand_cache->falloff_factor && expand_cache->falloff_factor_type == falloff_type) {
+ /* Falloffs are already initialize with the current falloff type, nothing to do. */
+ return;
+ }
+
+
+ switch (falloff_type) {
+ case SCULPT_EXPAND_FALLOFF_GEODESICS:
+ expand_cache->falloff_factor = sculpt_expand_geodesic_falloff_create(sd, ob, vertex);
+ break;
+ case SCULPT_EXPAND_FALLOFF_TOPOLOGY:
+
+ break;
+ case SCULPT_EXPAND_FALLOFF_NORMALS:
+
+ break;
+ case SCULPT_EXPAND_FALLOFF_SPHERICAL:
+
+ break;
+ case SCULPT_EXPAND_FALLOFF_BOUNDARY_TOPOLOGY:
+
+ break;
+ }
+
+ expand_cache->falloff_factor_type = falloff_type;
+
+ SculptSession *ss = ob->sculpt;
+ sculpt_expand_update_max_falloff_factor(ss, expand_cache);
+}
+
+
+float *sculpt_expand_falloff_factors_update() {
+ return NULL;
+}
+
+
+void sculpt_expand_cache_free(ExpandCache *expand_cache) {
+
+
+ MEM_SAFE_FREE(expand_cache);
+}
+
+
+
+static void sculpt_mask_expand_cancel(bContext *C, wmOperator *op)
+{
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+ const bool create_face_set = RNA_boolean_get(op->ptr, "create_face_set");
+
+ MEM_freeN(op->customdata);
+
+ for (int n = 0; n < ss->filter_cache->totnode; n++) {
+ PBVHNode *node = ss->filter_cache->nodes[n];
+ if (create_face_set) {
+ for (int i = 0; i < ss->totfaces; i++) {
+ ss->face_sets[i] = ss->filter_cache->prev_face_set[i];
+ }
+ }
+ else {
+ PBVHVertexIter vd;
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE)
+ {
+ *vd.mask = ss->filter_cache->prev_mask[vd.index];
+ }
+ BKE_pbvh_vertex_iter_end;
+ }
+
+ BKE_pbvh_node_mark_redraw(node);
+ }
+
+ if (!create_face_set) {
+ SCULPT_flush_update_step(C, SCULPT_UPDATE_MASK);
+ }
+ SCULPT_filter_cache_free(ss);
+ SCULPT_undo_push_end();
+ SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
+ ED_workspace_status_text(C, NULL);
+}
+
+
+static void sculpt_expand_cancel(bContext *C, wmOperator *op) {
+
+ ED_workspace_status_text(C, NULL);
+}
+
+
+static void sculpt_expand_task_cb(void *__restrict userdata,
+ const int i,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+ PBVHNode *node = data->nodes[i];
+ PBVHVertexIter vd;
+ int update_it = data->mask_expand_update_it;
+
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL)
+ {
+ int vi = vd.index;
+ float final_mask = *vd.mask;
+ if (data->mask_expand_use_normals) {
+ if (ss->filter_cache->normal_factor[SCULPT_active_vertex_get(ss)] <
+ ss->filter_cache->normal_factor[vd.index]) {
+ final_mask = 1.0f;
+ }
+ else {
+ final_mask = 0.0f;
+ }
+ }
+ else {
+ if (ss->filter_cache->mask_update_it[vi] <= update_it &&
+ ss->filter_cache->mask_update_it[vi] != 0) {
+ final_mask = 1.0f;
+ }
+ else {
+ final_mask = 0.0f;
+ }
+ }
+
+ if (data->mask_expand_create_face_set) {
+ if (final_mask == 1.0f) {
+ SCULPT_vertex_face_set_set(ss, vd.index, ss->filter_cache->new_face_set);
+ }
+ BKE_pbvh_node_mark_redraw(node);
+ }
+ else {
+
+ if (data->mask_expand_keep_prev_mask) {
+ final_mask = MAX2(ss->filter_cache->prev_mask[vd.index], final_mask);
+ }
+
+ if (data->mask_expand_invert_mask) {
+ final_mask = 1.0f - final_mask;
+ }
+
+ if (*vd.mask != final_mask) {
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ }
+ *vd.mask = final_mask;
+ BKE_pbvh_node_mark_update_mask(node);
+ }
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+}
+
+static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+ Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ ARegion *region = CTX_wm_region(C);
+ float prevclick_f[2];
+ copy_v2_v2(prevclick_f, op->customdata);
+ const int prevclick[2] = {(int)prevclick_f[0], (int)prevclick_f[1]};
+ int len = (int)len_v2v2_int(prevclick, event->mval);
+ len = abs(len);
+ int mask_speed = RNA_int_get(op->ptr, "mask_speed");
+ int mask_expand_update_it = len / mask_speed;
+ mask_expand_update_it = mask_expand_update_it + 1;
+
+ const bool create_face_set = RNA_boolean_get(op->ptr, "create_face_set");
+
+ if (RNA_boolean_get(op->ptr, "use_cursor")) {
+ SculptCursorGeometryInfo sgi;
+ float mouse[2];
+ mouse[0] = event->mval[0];
+ mouse[1] = event->mval[1];
+ if (SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false)) {
+ /* The cursor is over the mesh, get the update iteration from the updated active vertex. */
+ mask_expand_update_it = ss->filter_cache->mask_update_it[(int)SCULPT_active_vertex_get(ss)];
+ }
+ else {
+ /* When the cursor is outside the mesh, affect the entire connected component. */
+ mask_expand_update_it = ss->filter_cache->mask_update_last_it - 1;
+ }
+ }
+
+ if ((event->type == EVT_ESCKEY && event->val == KM_PRESS) ||
+ (event->type == RIGHTMOUSE && event->val == KM_PRESS)) {
+ /* Returning OPERATOR_CANCELLED will leak memory due to not finishing
+ * undo. Better solution could be to make paint_mesh_restore_co work
+ * for this case. */
+ sculpt_mask_expand_cancel(C, op);
+ return OPERATOR_FINISHED;
+ }
+
+ if ((event->type == LEFTMOUSE && event->val == KM_RELEASE) ||
+ (event->type == EVT_RETKEY && event->val == KM_PRESS) ||
+ (event->type == EVT_PADENTER && event->val == KM_PRESS)) {
+
+ /* Smooth iterations. */
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list