Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/sculpt_paint/paint_mask.c')
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c63
1 files changed, 34 insertions, 29 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index 622ea82bf25..826dd80175d 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -283,6 +283,14 @@ typedef struct SculptGestureContext {
float true_clip_planes[4][4];
float clip_planes[4][4];
+ /* These store the view origin and normal in world space, which is used in some gestures to
+ * generate geometry aligned from the view directly in world space. */
+ /* World space view origin and normal are not affected by object symmetry when doing symmetry
+ * passes, so there is no separate variables with the true_ prefix to store their original values
+ * without symmetry modifications. */
+ float world_space_view_origin[3];
+ float world_space_view_normal[3];
+
/* Lasso Gesture. */
LassoGestureData lasso;
@@ -337,11 +345,13 @@ static void sculpt_gesture_context_init_common(bContext *C,
float view_dir[3] = {0.0f, 0.0f, 1.0f};
copy_m3_m4(mat, sgcontext->vc.rv3d->viewinv);
mul_m3_v3(mat, view_dir);
+ normalize_v3_v3(sgcontext->world_space_view_normal, view_dir);
copy_m3_m4(mat, ob->imat);
mul_m3_v3(mat, view_dir);
normalize_v3_v3(sgcontext->true_view_normal, view_dir);
/* View Origin. */
+ copy_v3_v3(sgcontext->world_space_view_origin, sgcontext->vc.rv3d->viewinv[3]);
copy_v3_v3(sgcontext->true_view_origin, sgcontext->vc.rv3d->viewinv[3]);
}
@@ -893,17 +903,27 @@ static void sculpt_gesture_trim_calculate_depth(SculptGestureContext *sgcontext)
SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation;
SculptSession *ss = sgcontext->ss;
+ ViewContext *vc = &sgcontext->vc;
+
const int totvert = SCULPT_vertex_count_get(ss);
float view_plane[4];
- plane_from_point_normal_v3(view_plane, sgcontext->true_view_origin, sgcontext->true_view_normal);
+ const float *view_origin = sgcontext->world_space_view_origin;
+ const float *view_normal = sgcontext->world_space_view_normal;
+
+ plane_from_point_normal_v3(view_plane, view_origin, view_normal);
trim_operation->depth_front = FLT_MAX;
trim_operation->depth_back = -FLT_MAX;
for (int i = 0; i < totvert; i++) {
const float *vco = SCULPT_vertex_co_get(ss, i);
- const float dist = dist_signed_to_plane_v3(vco, view_plane);
+ /* Convert the coordinates to world space to calculate the depth. When generating the trimming
+ * mesh, coordinates are first calculated in world space, then converted to object space to
+ * store them. */
+ float world_space_vco[3];
+ mul_v3_m4v3(world_space_vco, vc->obact->obmat, vco);
+ const float dist = dist_signed_to_plane_v3(world_space_vco, view_plane);
trim_operation->depth_front = min_ff(dist, trim_operation->depth_front);
trim_operation->depth_back = max_ff(dist, trim_operation->depth_back);
}
@@ -927,18 +947,23 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex
const float depth_front = trim_operation->depth_front - 0.1f;
const float depth_back = trim_operation->depth_back + 0.1f;
- float *view_origin = sgcontext->true_view_origin;
- float *view_normal = sgcontext->true_view_normal;
+ /* Use the view origin and normal in world space. The trimming mesh coordinates are calculated in
+ * world space, aligned to the view, and then converted to object space to store them in the
+ * final trimming mesh which is going to be used in the boolean operation.
+ */
+ const float *view_origin = sgcontext->world_space_view_origin;
+ const float *view_normal = sgcontext->world_space_view_normal;
- /* Write vertices coordinates for the front face. */
+ const float(*ob_imat)[4] = vc->obact->imat;
+ /* Write vertices coordinates for the front face. */
float depth_point[3];
madd_v3_v3v3fl(depth_point, view_origin, view_normal, depth_front);
for (int i = 0; i < tot_screen_points; i++) {
float new_point[3];
ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point);
- copy_v3_v3(trim_operation->mesh->mvert[i].co, new_point);
- copy_v3_v3(trim_operation->true_mesh_co[i], new_point);
+ mul_v3_m4v3(trim_operation->mesh->mvert[i].co, ob_imat, new_point);
+ mul_v3_m4v3(trim_operation->true_mesh_co[i], ob_imat, new_point);
}
/* Write vertices coordinates for the back face. */
@@ -946,8 +971,8 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex
for (int i = 0; i < tot_screen_points; i++) {
float new_point[3];
ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point);
- copy_v3_v3(trim_operation->mesh->mvert[i + tot_screen_points].co, new_point);
- copy_v3_v3(trim_operation->true_mesh_co[i + tot_screen_points], new_point);
+ mul_v3_m4v3(trim_operation->mesh->mvert[i + tot_screen_points].co, ob_imat, new_point);
+ mul_v3_m4v3(trim_operation->true_mesh_co[i + tot_screen_points], ob_imat, new_point);
}
/* Get the triangulation for the front/back poly. */
@@ -1055,29 +1080,10 @@ static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext)
BMIter iter;
int i;
- const int i_verts_end = trim_mesh->totvert;
const int i_faces_end = trim_mesh->totpoly;
- float imat[4][4];
- float omat[4][4];
-
- invert_m4_m4(imat, object->obmat);
- mul_m4_m4m4(omat, imat, object->obmat);
-
- BMVert *eve;
- i = 0;
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
- mul_m4_v3(omat, eve->co);
- if (++i == i_verts_end) {
- break;
- }
- }
-
/* We need face normals because of 'BM_face_split_edgenet'
* we could calculate on the fly too (before calling split). */
- float nmat[3][3];
- copy_m3_m4(nmat, omat);
- invert_m3(nmat);
const short ob_src_totcol = trim_mesh->totcol;
short *material_remap = BLI_array_alloca(material_remap, ob_src_totcol ? ob_src_totcol : 1);
@@ -1085,7 +1091,6 @@ static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext)
BMFace *efa;
i = 0;
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- mul_transposed_m3_v3(nmat, efa->no);
normalize_v3(efa->no);
/* Temp tag to test which side split faces are from. */