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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs