Fix multires sculpt not setting the active vertex correctly
Also cleanup code to remove duplicated min_depth tracking, ray intersection already does it.
This commit is contained in:
parent
899b7ff1de
commit
52c02dc311
@ -1905,14 +1905,11 @@ static bool pbvh_faces_node_raycast(PBVH *bvh,
|
|||||||
const MVert *vert = bvh->verts;
|
const MVert *vert = bvh->verts;
|
||||||
const MLoop *mloop = bvh->mloop;
|
const MLoop *mloop = bvh->mloop;
|
||||||
const int *faces = node->prim_indices;
|
const int *faces = node->prim_indices;
|
||||||
int i, totface = node->totprim;
|
int totface = node->totprim;
|
||||||
bool hit = false;
|
bool hit = false;
|
||||||
float min_depth = FLT_MAX;
|
float nearest_vertex_co[3] = {0.0f};
|
||||||
float location[3] = {0.0f};
|
|
||||||
float nearest_vertex_co[3];
|
|
||||||
copy_v3_fl(nearest_vertex_co, 0.0f);
|
|
||||||
|
|
||||||
for (i = 0; i < totface; i++) {
|
for (int i = 0; i < totface; i++) {
|
||||||
const MLoopTri *lt = &bvh->looptri[faces[i]];
|
const MLoopTri *lt = &bvh->looptri[faces[i]];
|
||||||
const int *face_verts = node->face_vert_indices[i];
|
const int *face_verts = node->face_vert_indices[i];
|
||||||
|
|
||||||
@ -1920,35 +1917,33 @@ static bool pbvh_faces_node_raycast(PBVH *bvh,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float *co[3];
|
||||||
if (origco) {
|
if (origco) {
|
||||||
/* intersect with backuped original coordinates */
|
/* intersect with backuped original coordinates */
|
||||||
hit |= ray_face_intersection_tri(ray_start,
|
co[0] = origco[face_verts[0]];
|
||||||
isect_precalc,
|
co[1] = origco[face_verts[1]];
|
||||||
origco[face_verts[0]],
|
co[2] = origco[face_verts[2]];
|
||||||
origco[face_verts[1]],
|
|
||||||
origco[face_verts[2]],
|
|
||||||
depth);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* intersect with current coordinates */
|
/* intersect with current coordinates */
|
||||||
hit |= ray_face_intersection_tri(ray_start,
|
co[0] = vert[mloop[lt->tri[0]].v].co;
|
||||||
isect_precalc,
|
co[1] = vert[mloop[lt->tri[1]].v].co;
|
||||||
vert[mloop[lt->tri[0]].v].co,
|
co[2] = vert[mloop[lt->tri[2]].v].co;
|
||||||
vert[mloop[lt->tri[1]].v].co,
|
}
|
||||||
vert[mloop[lt->tri[2]].v].co,
|
|
||||||
depth);
|
|
||||||
|
|
||||||
if (hit && *depth < min_depth) {
|
if (ray_face_intersection_tri(ray_start, isect_precalc, co[0], co[1], co[2], depth)) {
|
||||||
min_depth = *depth;
|
hit = true;
|
||||||
normal_tri_v3(r_face_normal,
|
|
||||||
vert[mloop[lt->tri[0]].v].co,
|
if (r_face_normal) {
|
||||||
vert[mloop[lt->tri[1]].v].co,
|
normal_tri_v3(r_face_normal, co[0], co[1], co[2]);
|
||||||
vert[mloop[lt->tri[2]].v].co);
|
}
|
||||||
|
|
||||||
|
if (r_active_vertex_index) {
|
||||||
|
float location[3] = {0.0f};
|
||||||
madd_v3_v3v3fl(location, ray_start, ray_normal, *depth);
|
madd_v3_v3v3fl(location, ray_start, ray_normal, *depth);
|
||||||
for (int j = 0; j < 3; j++) {
|
for (int j = 0; j < 3; j++) {
|
||||||
if (len_squared_v3v3(location, vert[mloop[lt->tri[j]].v].co) <
|
if (len_squared_v3v3(location, co[j]) < len_squared_v3v3(location, nearest_vertex_co)) {
|
||||||
len_squared_v3v3(location, nearest_vertex_co)) {
|
copy_v3_v3(nearest_vertex_co, co[j]);
|
||||||
copy_v3_v3(nearest_vertex_co, vert[mloop[lt->tri[j]].v].co);
|
|
||||||
*r_active_vertex_index = mloop[lt->tri[j]].v;
|
*r_active_vertex_index = mloop[lt->tri[j]].v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1963,22 +1958,28 @@ static bool pbvh_grids_node_raycast(PBVH *bvh,
|
|||||||
PBVHNode *node,
|
PBVHNode *node,
|
||||||
float (*origco)[3],
|
float (*origco)[3],
|
||||||
const float ray_start[3],
|
const float ray_start[3],
|
||||||
|
const float ray_normal[3],
|
||||||
struct IsectRayPrecalc *isect_precalc,
|
struct IsectRayPrecalc *isect_precalc,
|
||||||
float *depth)
|
float *depth,
|
||||||
|
int *r_active_vertex_index,
|
||||||
|
float *r_face_normal)
|
||||||
{
|
{
|
||||||
const int totgrid = node->totprim;
|
const int totgrid = node->totprim;
|
||||||
const int gridsize = bvh->gridkey.grid_size;
|
const int gridsize = bvh->gridkey.grid_size;
|
||||||
bool hit = false;
|
bool hit = false;
|
||||||
|
float nearest_vertex_co[3] = {0.0};
|
||||||
|
const CCGKey *gridkey = &bvh->gridkey;
|
||||||
|
|
||||||
for (int i = 0; i < totgrid; i++) {
|
for (int i = 0; i < totgrid; i++) {
|
||||||
CCGElem *grid = bvh->grids[node->prim_indices[i]];
|
const int grid_index = node->prim_indices[i];
|
||||||
|
CCGElem *grid = bvh->grids[grid_index];
|
||||||
BLI_bitmap *gh;
|
BLI_bitmap *gh;
|
||||||
|
|
||||||
if (!grid) {
|
if (!grid) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
gh = bvh->grid_hidden[node->prim_indices[i]];
|
gh = bvh->grid_hidden[grid_index];
|
||||||
|
|
||||||
for (int y = 0; y < gridsize - 1; y++) {
|
for (int y = 0; y < gridsize - 1; y++) {
|
||||||
for (int x = 0; x < gridsize - 1; x++) {
|
for (int x = 0; x < gridsize - 1; x++) {
|
||||||
@ -1989,23 +1990,40 @@ static bool pbvh_grids_node_raycast(PBVH *bvh,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float *co[4];
|
||||||
if (origco) {
|
if (origco) {
|
||||||
hit |= ray_face_intersection_quad(ray_start,
|
co[0] = origco[y * gridsize + x];
|
||||||
isect_precalc,
|
co[1] = origco[y * gridsize + x + 1];
|
||||||
origco[y * gridsize + x],
|
co[2] = origco[(y + 1) * gridsize + x + 1];
|
||||||
origco[y * gridsize + x + 1],
|
co[3] = origco[(y + 1) * gridsize + x];
|
||||||
origco[(y + 1) * gridsize + x + 1],
|
|
||||||
origco[(y + 1) * gridsize + x],
|
|
||||||
depth);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
hit |= ray_face_intersection_quad(ray_start,
|
co[0] = CCG_grid_elem_co(gridkey, grid, x, y);
|
||||||
isect_precalc,
|
co[1] = CCG_grid_elem_co(gridkey, grid, x + 1, y);
|
||||||
CCG_grid_elem_co(&bvh->gridkey, grid, x, y),
|
co[2] = CCG_grid_elem_co(gridkey, grid, x + 1, y + 1);
|
||||||
CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y),
|
co[3] = CCG_grid_elem_co(gridkey, grid, x, y + 1);
|
||||||
CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y + 1),
|
}
|
||||||
CCG_grid_elem_co(&bvh->gridkey, grid, x, y + 1),
|
|
||||||
depth);
|
if (ray_face_intersection_quad(
|
||||||
|
ray_start, isect_precalc, co[0], co[1], co[2], co[3], depth)) {
|
||||||
|
hit = true;
|
||||||
|
|
||||||
|
if (r_face_normal) {
|
||||||
|
normal_quad_v3(r_face_normal, co[0], co[1], co[2], co[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r_active_vertex_index) {
|
||||||
|
float location[3] = {0.0};
|
||||||
|
madd_v3_v3v3fl(location, ray_start, ray_normal, *depth);
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
if (len_squared_v3v3(location, co[j]) <
|
||||||
|
len_squared_v3v3(location, nearest_vertex_co)) {
|
||||||
|
copy_v3_v3(nearest_vertex_co, co[j]);
|
||||||
|
*r_active_vertex_index = gridkey->grid_area * grid_index + y * gridkey->grid_size +
|
||||||
|
x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2048,7 +2066,15 @@ bool BKE_pbvh_node_raycast(PBVH *bvh,
|
|||||||
face_normal);
|
face_normal);
|
||||||
break;
|
break;
|
||||||
case PBVH_GRIDS:
|
case PBVH_GRIDS:
|
||||||
hit |= pbvh_grids_node_raycast(bvh, node, origco, ray_start, isect_precalc, depth);
|
hit |= pbvh_grids_node_raycast(bvh,
|
||||||
|
node,
|
||||||
|
origco,
|
||||||
|
ray_start,
|
||||||
|
ray_normal,
|
||||||
|
isect_precalc,
|
||||||
|
depth,
|
||||||
|
active_vertex_index,
|
||||||
|
face_normal);
|
||||||
break;
|
break;
|
||||||
case PBVH_BMESH:
|
case PBVH_BMESH:
|
||||||
BM_mesh_elem_index_ensure(bvh->bm, BM_VERT);
|
BM_mesh_elem_index_ensure(bvh->bm, BM_VERT);
|
||||||
|
@ -1516,10 +1516,8 @@ bool pbvh_bmesh_node_raycast(PBVHNode *node,
|
|||||||
float *r_face_normal)
|
float *r_face_normal)
|
||||||
{
|
{
|
||||||
bool hit = false;
|
bool hit = false;
|
||||||
|
|
||||||
float min_depth = FLT_MAX;
|
|
||||||
float nearest_vertex_co[3] = {0.0f};
|
float nearest_vertex_co[3] = {0.0f};
|
||||||
float location[3] = {0.0f};
|
|
||||||
if (use_original && node->bm_tot_ortri) {
|
if (use_original && node->bm_tot_ortri) {
|
||||||
for (int i = 0; i < node->bm_tot_ortri; i++) {
|
for (int i = 0; i < node->bm_tot_ortri; i++) {
|
||||||
const int *t = node->bm_ortri[i];
|
const int *t = node->bm_ortri[i];
|
||||||
@ -1542,12 +1540,17 @@ bool pbvh_bmesh_node_raycast(PBVHNode *node,
|
|||||||
BMVert *v_tri[3];
|
BMVert *v_tri[3];
|
||||||
|
|
||||||
BM_face_as_array_vert_tri(f, v_tri);
|
BM_face_as_array_vert_tri(f, v_tri);
|
||||||
hit |= ray_face_intersection_tri(
|
|
||||||
ray_start, isect_precalc, v_tri[0]->co, v_tri[1]->co, v_tri[2]->co, depth);
|
|
||||||
|
|
||||||
if (hit && *depth < min_depth) {
|
if (ray_face_intersection_tri(
|
||||||
min_depth = *depth;
|
ray_start, isect_precalc, v_tri[0]->co, v_tri[1]->co, v_tri[2]->co, depth)) {
|
||||||
|
hit = true;
|
||||||
|
|
||||||
|
if (r_face_normal) {
|
||||||
normal_tri_v3(r_face_normal, v_tri[0]->co, v_tri[1]->co, v_tri[2]->co);
|
normal_tri_v3(r_face_normal, v_tri[0]->co, v_tri[1]->co, v_tri[2]->co);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r_active_vertex_index) {
|
||||||
|
float location[3] = {0.0f};
|
||||||
madd_v3_v3v3fl(location, ray_start, ray_normal, *depth);
|
madd_v3_v3v3fl(location, ray_start, ray_normal, *depth);
|
||||||
for (int j = 0; j < 3; j++) {
|
for (int j = 0; j < 3; j++) {
|
||||||
if (len_squared_v3v3(location, v_tri[j]->co) <
|
if (len_squared_v3v3(location, v_tri[j]->co) <
|
||||||
@ -1560,6 +1563,7 @@ bool pbvh_bmesh_node_raycast(PBVHNode *node,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user