Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/sculpt_paint/paint_mask.c
| Show First 20 Lines • Show All 657 Lines • ▼ Show 20 Lines | static bool sculpt_gesture_is_effected_lasso(SculptGestureContext *sgcontext, const float co[3]) | ||||
| } | } | ||||
| scr_co_s[0] -= lasso->boundbox.xmin; | scr_co_s[0] -= lasso->boundbox.xmin; | ||||
| scr_co_s[1] -= lasso->boundbox.ymin; | scr_co_s[1] -= lasso->boundbox.ymin; | ||||
| return BLI_BITMAP_TEST_BOOL(lasso->mask_px, scr_co_s[1] * lasso->width + scr_co_s[0]); | return BLI_BITMAP_TEST_BOOL(lasso->mask_px, scr_co_s[1] * lasso->width + scr_co_s[0]); | ||||
| } | } | ||||
| static bool sculpt_gesture_is_vertex_effected(SculptGestureContext *sgcontext, PBVHVertexIter *vd) | static bool sculpt_gesture_is_vertex_effected(SculptGestureContext *sgcontext, PBVHVertRef vertex) | ||||
| { | { | ||||
| float vertex_normal[3]; | float vertex_normal[3]; | ||||
| SCULPT_vertex_normal_get(sgcontext->ss, vd->vertex, vertex_normal); | const float *co = SCULPT_vertex_co_get(sgcontext->ss, vertex); | ||||
| SCULPT_vertex_normal_get(sgcontext->ss, vertex, vertex_normal); | |||||
| float dot = dot_v3v3(sgcontext->view_normal, vertex_normal); | float dot = dot_v3v3(sgcontext->view_normal, vertex_normal); | ||||
| const bool is_effected_front_face = !(sgcontext->front_faces_only && dot < 0.0f); | const bool is_effected_front_face = !(sgcontext->front_faces_only && dot < 0.0f); | ||||
| if (!is_effected_front_face) { | if (!is_effected_front_face) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| switch (sgcontext->shape_type) { | switch (sgcontext->shape_type) { | ||||
| case SCULPT_GESTURE_SHAPE_BOX: | case SCULPT_GESTURE_SHAPE_BOX: | ||||
| return isect_point_planes_v3(sgcontext->clip_planes, 4, vd->co); | return isect_point_planes_v3(sgcontext->clip_planes, 4, co); | ||||
| case SCULPT_GESTURE_SHAPE_LASSO: | case SCULPT_GESTURE_SHAPE_LASSO: | ||||
| return sculpt_gesture_is_effected_lasso(sgcontext, vd->co); | return sculpt_gesture_is_effected_lasso(sgcontext, co); | ||||
| case SCULPT_GESTURE_SHAPE_LINE: | case SCULPT_GESTURE_SHAPE_LINE: | ||||
| if (sgcontext->line.use_side_planes) { | if (sgcontext->line.use_side_planes) { | ||||
| return plane_point_side_v3(sgcontext->line.plane, vd->co) > 0.0f && | return plane_point_side_v3(sgcontext->line.plane, co) > 0.0f && | ||||
| plane_point_side_v3(sgcontext->line.side_plane[0], vd->co) > 0.0f && | plane_point_side_v3(sgcontext->line.side_plane[0], co) > 0.0f && | ||||
| plane_point_side_v3(sgcontext->line.side_plane[1], vd->co) > 0.0f; | plane_point_side_v3(sgcontext->line.side_plane[1], co) > 0.0f; | ||||
| } | } | ||||
| return plane_point_side_v3(sgcontext->line.plane, vd->co) > 0.0f; | return plane_point_side_v3(sgcontext->line.plane, co) > 0.0f; | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| static bool sculpt_gesture_is_face_effected(SculptGestureContext *sgcontext, PBVHFaceIter *fd) | |||||
| { | |||||
| for (int i = 0; i < fd->verts_num; i++) { | |||||
| if (sculpt_gesture_is_vertex_effected(sgcontext, fd->verts[i])) { | |||||
| return true; | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | |||||
| static void sculpt_gesture_apply(bContext *C, SculptGestureContext *sgcontext, wmOperator *op) | static void sculpt_gesture_apply(bContext *C, SculptGestureContext *sgcontext, wmOperator *op) | ||||
| { | { | ||||
| SculptGestureOperation *operation = sgcontext->operation; | SculptGestureOperation *operation = sgcontext->operation; | ||||
| SCULPT_undo_push_begin(CTX_data_active_object(C), op); | SCULPT_undo_push_begin(CTX_data_active_object(C), op); | ||||
| operation->sculpt_gesture_begin(C, sgcontext); | operation->sculpt_gesture_begin(C, sgcontext); | ||||
| for (ePaintSymmetryFlags symmpass = 0; symmpass <= sgcontext->symm; symmpass++) { | for (ePaintSymmetryFlags symmpass = 0; symmpass <= sgcontext->symm; symmpass++) { | ||||
| Show All 22 Lines | typedef struct SculptGestureFaceSetOperation { | ||||
| int new_face_set_id; | int new_face_set_id; | ||||
| } SculptGestureFaceSetOperation; | } SculptGestureFaceSetOperation; | ||||
| static void sculpt_gesture_face_set_begin(bContext *C, SculptGestureContext *sgcontext) | static void sculpt_gesture_face_set_begin(bContext *C, SculptGestureContext *sgcontext) | ||||
| { | { | ||||
| Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); | Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); | ||||
| BKE_sculpt_update_object_for_edit(depsgraph, sgcontext->vc.obact, true, false, false); | BKE_sculpt_update_object_for_edit(depsgraph, sgcontext->vc.obact, true, false, false); | ||||
| /* Face Sets modifications do a single undo push. */ | |||||
| SCULPT_undo_push_node(sgcontext->vc.obact, NULL, SCULPT_UNDO_FACE_SETS); | |||||
| } | } | ||||
| static void face_set_gesture_apply_task_cb(void *__restrict userdata, | static void face_set_gesture_apply_task_cb(void *__restrict userdata, | ||||
| const int i, | const int i, | ||||
| const TaskParallelTLS *__restrict UNUSED(tls)) | const TaskParallelTLS *__restrict UNUSED(tls)) | ||||
| { | { | ||||
| SculptGestureContext *sgcontext = userdata; | SculptGestureContext *sgcontext = userdata; | ||||
| SculptGestureFaceSetOperation *face_set_operation = (SculptGestureFaceSetOperation *) | SculptGestureFaceSetOperation *face_set_operation = (SculptGestureFaceSetOperation *) | ||||
| sgcontext->operation; | sgcontext->operation; | ||||
| PBVHNode *node = sgcontext->nodes[i]; | PBVHNode *node = sgcontext->nodes[i]; | ||||
| PBVHVertexIter vd; | |||||
| bool any_updated = false; | bool any_updated = false; | ||||
| BKE_pbvh_vertex_iter_begin (sgcontext->ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { | SCULPT_undo_push_node(sgcontext->vc.obact, node, SCULPT_UNDO_FACE_SETS); | ||||
| if (sculpt_gesture_is_vertex_effected(sgcontext, &vd)) { | |||||
| SCULPT_vertex_face_set_set(sgcontext->ss, vd.vertex, face_set_operation->new_face_set_id); | PBVHFaceIter fd; | ||||
| BKE_pbvh_face_iter_begin (sgcontext->ss->pbvh, node, fd) { | |||||
| if (sculpt_gesture_is_face_effected(sgcontext, &fd)) { | |||||
| SCULPT_face_set_set(sgcontext->ss, fd.face, face_set_operation->new_face_set_id); | |||||
| any_updated = true; | any_updated = true; | ||||
| } | } | ||||
| } | } | ||||
| BKE_pbvh_vertex_iter_end; | BKE_pbvh_face_iter_end(fd); | ||||
| if (any_updated) { | if (any_updated) { | ||||
| BKE_pbvh_node_mark_update_visibility(node); | BKE_pbvh_node_mark_update_visibility(node); | ||||
| } | } | ||||
| } | } | ||||
| static void sculpt_gesture_face_set_apply_for_symmetry_pass(bContext *UNUSED(C), | static void sculpt_gesture_face_set_apply_for_symmetry_pass(bContext *UNUSED(C), | ||||
| SculptGestureContext *sgcontext) | SculptGestureContext *sgcontext) | ||||
| ▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | static void mask_gesture_apply_task_cb(void *__restrict userdata, | ||||
| const bool is_multires = BKE_pbvh_type(sgcontext->ss->pbvh) == PBVH_GRIDS; | const bool is_multires = BKE_pbvh_type(sgcontext->ss->pbvh) == PBVH_GRIDS; | ||||
| PBVHVertexIter vd; | PBVHVertexIter vd; | ||||
| bool any_masked = false; | bool any_masked = false; | ||||
| bool redraw = false; | bool redraw = false; | ||||
| BKE_pbvh_vertex_iter_begin (sgcontext->ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { | BKE_pbvh_vertex_iter_begin (sgcontext->ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { | ||||
| if (sculpt_gesture_is_vertex_effected(sgcontext, &vd)) { | if (sculpt_gesture_is_vertex_effected(sgcontext, vd.vertex)) { | ||||
| float prevmask = vd.mask ? *vd.mask : 0.0f; | float prevmask = vd.mask ? *vd.mask : 0.0f; | ||||
| if (!any_masked) { | if (!any_masked) { | ||||
| any_masked = true; | any_masked = true; | ||||
| SCULPT_undo_push_node(ob, node, SCULPT_UNDO_MASK); | SCULPT_undo_push_node(ob, node, SCULPT_UNDO_MASK); | ||||
| if (is_multires) { | if (is_multires) { | ||||
| BKE_pbvh_node_mark_normals_update(node); | BKE_pbvh_node_mark_normals_update(node); | ||||
| ▲ Show 20 Lines • Show All 604 Lines • ▼ Show 20 Lines | static void project_line_gesture_apply_task_cb(void *__restrict userdata, | ||||
| PBVHNode *node = sgcontext->nodes[i]; | PBVHNode *node = sgcontext->nodes[i]; | ||||
| PBVHVertexIter vd; | PBVHVertexIter vd; | ||||
| bool any_updated = false; | bool any_updated = false; | ||||
| SCULPT_undo_push_node(sgcontext->vc.obact, node, SCULPT_UNDO_COORDS); | SCULPT_undo_push_node(sgcontext->vc.obact, node, SCULPT_UNDO_COORDS); | ||||
| BKE_pbvh_vertex_iter_begin (sgcontext->ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { | BKE_pbvh_vertex_iter_begin (sgcontext->ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { | ||||
| if (!sculpt_gesture_is_vertex_effected(sgcontext, &vd)) { | if (!sculpt_gesture_is_vertex_effected(sgcontext, vd.vertex)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| float projected_pos[3]; | float projected_pos[3]; | ||||
| closest_to_plane_v3(projected_pos, sgcontext->line.plane, vd.co); | closest_to_plane_v3(projected_pos, sgcontext->line.plane, vd.co); | ||||
| float disp[3]; | float disp[3]; | ||||
| sub_v3_v3v3(disp, projected_pos, vd.co); | sub_v3_v3v3(disp, projected_pos, vd.co); | ||||
| ▲ Show 20 Lines • Show All 379 Lines • Show Last 20 Lines | |||||