Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/sculpt_paint/paint_mask.c
| Show First 20 Lines • Show All 271 Lines • ▼ Show 20 Lines | typedef struct SculptGestureContext { | ||||||||
| float view_normal[3]; | float view_normal[3]; | ||||||||
| float true_view_origin[3]; | float true_view_origin[3]; | ||||||||
| float view_origin[3]; | float view_origin[3]; | ||||||||
| float true_clip_planes[4][4]; | float true_clip_planes[4][4]; | ||||||||
| float 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. */ | |||||||||
sergey: I don't know what that mens or how this helps understanding what `world_space_view_origin` and… | |||||||||
| /* World space view origin and normal are not affected by object symmetry when doing symmetry | |||||||||
| * passes, so there is not a true version of them. */ | |||||||||
sergeyUnsubmitted Not Done Inline Actions
so these (variables?) are not a true version of them ? What is the true version anyway? sergey: > so there is not a true version of them
`so these (variables?) are not a true version of… | |||||||||
pablodp606AuthorUnsubmitted Done Inline ActionsThis is how variables are named all over the sculpt code. When a variable needs to be modified for symmetry, the original version has the true prefix and never changes and there is another variable with the same name without the prefix that changes per symmetry pass. pablodp606: This is how variables are named all over the sculpt code. When a variable needs to be modified… | |||||||||
sergeyUnsubmitted Done Inline ActionsOk, this is fine. sergey: Ok, this is fine.
But the sentence still needs to be adjusted to be more proper English I think. | |||||||||
Done Inline Actions
sergey: | |||||||||
| float world_space_view_origin[3]; | |||||||||
| float world_space_view_normal[3]; | |||||||||
| /* Lasso Gesture. */ | /* Lasso Gesture. */ | ||||||||
| LassoGestureData lasso; | LassoGestureData lasso; | ||||||||
| /* Task Callback Data. */ | /* Task Callback Data. */ | ||||||||
| PBVHNode **nodes; | PBVHNode **nodes; | ||||||||
| int totnode; | int totnode; | ||||||||
| } SculptGestureContext; | } SculptGestureContext; | ||||||||
| Show All 37 Lines | static void sculpt_gesture_context_init_common(bContext *C, | ||||||||
| /* Symmetry. */ | /* Symmetry. */ | ||||||||
| sgcontext->symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; | sgcontext->symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; | ||||||||
| /* View Normal. */ | /* View Normal. */ | ||||||||
| float mat[3][3]; | float mat[3][3]; | ||||||||
| float view_dir[3] = {0.0f, 0.0f, 1.0f}; | float view_dir[3] = {0.0f, 0.0f, 1.0f}; | ||||||||
| copy_m3_m4(mat, sgcontext->vc.rv3d->viewinv); | copy_m3_m4(mat, sgcontext->vc.rv3d->viewinv); | ||||||||
| mul_m3_v3(mat, view_dir); | mul_m3_v3(mat, view_dir); | ||||||||
| normalize_v3_v3(sgcontext->world_space_view_normal, view_dir); | |||||||||
| copy_m3_m4(mat, ob->imat); | copy_m3_m4(mat, ob->imat); | ||||||||
| mul_m3_v3(mat, view_dir); | mul_m3_v3(mat, view_dir); | ||||||||
| normalize_v3_v3(sgcontext->true_view_normal, view_dir); | normalize_v3_v3(sgcontext->true_view_normal, view_dir); | ||||||||
| /* View Origin. */ | /* 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]); | copy_v3_v3(sgcontext->true_view_origin, sgcontext->vc.rv3d->viewinv[3]); | ||||||||
| } | } | ||||||||
| static void sculpt_gesture_lasso_px_cb(int x, int x_end, int y, void *user_data) | static void sculpt_gesture_lasso_px_cb(int x, int x_end, int y, void *user_data) | ||||||||
| { | { | ||||||||
| SculptGestureContext *mcontext = user_data; | SculptGestureContext *mcontext = user_data; | ||||||||
| LassoGestureData *lasso = &mcontext->lasso; | LassoGestureData *lasso = &mcontext->lasso; | ||||||||
| int index = (y * lasso->width) + x; | int index = (y * lasso->width) + x; | ||||||||
| ▲ Show 20 Lines • Show All 453 Lines • ▼ Show 20 Lines | static void sculpt_gesture_trim_normals_update(SculptGestureContext *sgcontext) | ||||||||
| trim_operation->mesh = result; | trim_operation->mesh = result; | ||||||||
| } | } | ||||||||
| static void sculpt_gesture_trim_calculate_depth(SculptGestureContext *sgcontext) | static void sculpt_gesture_trim_calculate_depth(SculptGestureContext *sgcontext) | ||||||||
| { | { | ||||||||
| SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation; | SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation; | ||||||||
| SculptSession *ss = sgcontext->ss; | SculptSession *ss = sgcontext->ss; | ||||||||
| ViewContext *vc = &sgcontext->vc; | |||||||||
| const int totvert = SCULPT_vertex_count_get(ss); | const int totvert = SCULPT_vertex_count_get(ss); | ||||||||
| float view_plane[4]; | 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_front = FLT_MAX; | ||||||||
| trim_operation->depth_back = -FLT_MAX; | trim_operation->depth_back = -FLT_MAX; | ||||||||
| for (int i = 0; i < totvert; i++) { | for (int i = 0; i < totvert; i++) { | ||||||||
| const float *vco = SCULPT_vertex_co_get(ss, 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_front = min_ff(dist, trim_operation->depth_front); | ||||||||
| trim_operation->depth_back = max_ff(dist, trim_operation->depth_back); | trim_operation->depth_back = max_ff(dist, trim_operation->depth_back); | ||||||||
| } | } | ||||||||
| } | } | ||||||||
| static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontext) | static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontext) | ||||||||
| { | { | ||||||||
| SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation; | SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation; | ||||||||
| ViewContext *vc = &sgcontext->vc; | ViewContext *vc = &sgcontext->vc; | ||||||||
| ARegion *region = vc->region; | ARegion *region = vc->region; | ||||||||
| const int tot_screen_points = sgcontext->tot_gesture_points; | const int tot_screen_points = sgcontext->tot_gesture_points; | ||||||||
| float(*screen_points)[2] = sgcontext->gesture_points; | float(*screen_points)[2] = sgcontext->gesture_points; | ||||||||
| const int trim_totverts = tot_screen_points * 2; | const int trim_totverts = tot_screen_points * 2; | ||||||||
| const int trim_totpolys = (2 * (tot_screen_points - 2)) + (2 * tot_screen_points); | const int trim_totpolys = (2 * (tot_screen_points - 2)) + (2 * tot_screen_points); | ||||||||
| trim_operation->mesh = BKE_mesh_new_nomain( | trim_operation->mesh = BKE_mesh_new_nomain( | ||||||||
| trim_totverts, 0, 0, trim_totpolys * 3, trim_totpolys); | trim_totverts, 0, 0, trim_totpolys * 3, trim_totpolys); | ||||||||
| trim_operation->true_mesh_co = MEM_malloc_arrayN(trim_totverts, 3 * sizeof(float), "mesh orco"); | trim_operation->true_mesh_co = MEM_malloc_arrayN(trim_totverts, 3 * sizeof(float), "mesh orco"); | ||||||||
| const float depth_front = trim_operation->depth_front - 0.1f; | const float depth_front = trim_operation->depth_front - 0.1f; | ||||||||
| const float depth_back = trim_operation->depth_back + 0.1f; | const float depth_back = trim_operation->depth_back + 0.1f; | ||||||||
| float *view_origin = sgcontext->true_view_origin; | /* Use the view origin and normal in world space. The trimming mesh coordinates are calculated in | ||||||||
| float *view_normal = sgcontext->true_view_normal; | * 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; | |||||||||
Done Inline Actionsand then converted? Otherwise I don't really follow. sergey: `and then converted`? Otherwise I don't really follow. | |||||||||
| /* 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]; | float depth_point[3]; | ||||||||
| madd_v3_v3v3fl(depth_point, view_origin, view_normal, depth_front); | madd_v3_v3v3fl(depth_point, view_origin, view_normal, depth_front); | ||||||||
| for (int i = 0; i < tot_screen_points; i++) { | for (int i = 0; i < tot_screen_points; i++) { | ||||||||
| float new_point[3]; | float new_point[3]; | ||||||||
| ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point); | 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); | mul_v3_m4v3(trim_operation->mesh->mvert[i].co, ob_imat, new_point); | ||||||||
| copy_v3_v3(trim_operation->true_mesh_co[i], new_point); | mul_v3_m4v3(trim_operation->true_mesh_co[i], ob_imat, new_point); | ||||||||
| } | } | ||||||||
| /* Write vertices coordinates for the back face. */ | /* Write vertices coordinates for the back face. */ | ||||||||
| madd_v3_v3v3fl(depth_point, view_origin, view_normal, depth_back); | madd_v3_v3v3fl(depth_point, view_origin, view_normal, depth_back); | ||||||||
| for (int i = 0; i < tot_screen_points; i++) { | for (int i = 0; i < tot_screen_points; i++) { | ||||||||
| float new_point[3]; | float new_point[3]; | ||||||||
| ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point); | 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); | mul_v3_m4v3(trim_operation->mesh->mvert[i + tot_screen_points].co, ob_imat, new_point); | ||||||||
| copy_v3_v3(trim_operation->true_mesh_co[i + tot_screen_points], 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. */ | /* Get the triangulation for the front/back poly. */ | ||||||||
| const int tot_tris_face = tot_screen_points - 2; | const int tot_tris_face = tot_screen_points - 2; | ||||||||
| uint(*r_tris)[3] = MEM_malloc_arrayN(tot_tris_face, 3 * sizeof(uint), "tris"); | uint(*r_tris)[3] = MEM_malloc_arrayN(tot_tris_face, 3 * sizeof(uint), "tris"); | ||||||||
| BLI_polyfill_calc(screen_points, tot_screen_points, 0, r_tris); | BLI_polyfill_calc(screen_points, tot_screen_points, 0, r_tris); | ||||||||
| /* Write the front face triangle indices. */ | /* Write the front face triangle indices. */ | ||||||||
| ▲ Show 20 Lines • Show All 91 Lines • ▼ Show 20 Lines | static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext) | ||||||||
| const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop); | const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop); | ||||||||
| int tottri; | int tottri; | ||||||||
| BMLoop *(*looptris)[3]; | BMLoop *(*looptris)[3]; | ||||||||
| looptris = MEM_malloc_arrayN(looptris_tot, sizeof(*looptris), __func__); | looptris = MEM_malloc_arrayN(looptris_tot, sizeof(*looptris), __func__); | ||||||||
| BM_mesh_calc_tessellation_beauty(bm, looptris, &tottri); | BM_mesh_calc_tessellation_beauty(bm, looptris, &tottri); | ||||||||
| BMIter iter; | BMIter iter; | ||||||||
| int i; | int i; | ||||||||
| const int i_verts_end = trim_mesh->totvert; | |||||||||
| const int i_faces_end = trim_mesh->totpoly; | 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 need face normals because of 'BM_face_split_edgenet' | ||||||||
| * we could calculate on the fly too (before calling split). */ | * 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; | const short ob_src_totcol = trim_mesh->totcol; | ||||||||
| short *material_remap = BLI_array_alloca(material_remap, ob_src_totcol ? ob_src_totcol : 1); | short *material_remap = BLI_array_alloca(material_remap, ob_src_totcol ? ob_src_totcol : 1); | ||||||||
| BMFace *efa; | BMFace *efa; | ||||||||
| i = 0; | i = 0; | ||||||||
| BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { | BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { | ||||||||
| mul_transposed_m3_v3(nmat, efa->no); | |||||||||
| normalize_v3(efa->no); | normalize_v3(efa->no); | ||||||||
| /* Temp tag to test which side split faces are from. */ | /* Temp tag to test which side split faces are from. */ | ||||||||
| BM_elem_flag_enable(efa, BM_ELEM_DRAW); | BM_elem_flag_enable(efa, BM_ELEM_DRAW); | ||||||||
| /* Remap material. */ | /* Remap material. */ | ||||||||
| if (efa->mat_nr < ob_src_totcol) { | if (efa->mat_nr < ob_src_totcol) { | ||||||||
| efa->mat_nr = material_remap[efa->mat_nr]; | efa->mat_nr = material_remap[efa->mat_nr]; | ||||||||
| ▲ Show 20 Lines • Show All 298 Lines • Show Last 20 Lines | |||||||||
I don't know what that mens or how this helps understanding what world_space_view_origin and world_space_view_normal are for.