* Enable mask/fset extract for dyntopo]
* Fix nasty memory corruption bug
This commit is contained in:
parent
d66d5b431e
commit
dcb00bf529
|
@ -3765,8 +3765,11 @@ CLANG_OPT_BUG static bool cleanup_valence_3_4(PBVH *pbvh,
|
|||
vs[2] = ls[3]->v;
|
||||
|
||||
BMFace *f2 = pbvh_bmesh_face_create(pbvh, n, vs, NULL, v->e->l->f, false, false);
|
||||
|
||||
printf("%p %p %p\n", f2->l_first->prev->head.data, ls[3]->head.data);
|
||||
|
||||
CustomData_bmesh_swap_data_simple(
|
||||
&pbvh->bm->pdata, &f2->l_first->prev->head.data, &ls[3]->head.data);
|
||||
&pbvh->bm->ldata, &f2->l_first->prev->head.data, &ls[3]->head.data);
|
||||
|
||||
CustomData_bmesh_copy_data(
|
||||
&pbvh->bm->ldata, &pbvh->bm->ldata, ls[0]->head.data, &f2->l_first->head.data);
|
||||
|
|
|
@ -61,14 +61,16 @@
|
|||
|
||||
#include "mesh_intern.h" /* own include */
|
||||
|
||||
#include "../sculpt_paint/sculpt_intern.h"
|
||||
|
||||
static bool geometry_extract_poll(bContext *C)
|
||||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
if (ob != NULL && ob->mode == OB_MODE_SCULPT) {
|
||||
if (ob->sculpt->bm) {
|
||||
CTX_wm_operator_poll_msg_set(C, "The geometry can not be extracted with dyntopo activated");
|
||||
return false;
|
||||
}
|
||||
// if (ob->sculpt->bm) {
|
||||
// CTX_wm_operator_poll_msg_set(C, "The geometry can not be extracted with dyntopo activated");
|
||||
// return false;
|
||||
//}
|
||||
return ED_operator_object_active_editable_mesh(C);
|
||||
}
|
||||
return false;
|
||||
|
@ -120,7 +122,8 @@ static int geometry_extract_apply(bContext *C,
|
|||
.use_toolflags = true,
|
||||
}));
|
||||
|
||||
BM_mesh_bm_from_me(NULL, bm,
|
||||
BM_mesh_bm_from_me(NULL,
|
||||
bm,
|
||||
new_mesh,
|
||||
(&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
@ -373,6 +376,7 @@ static int face_set_extract_invoke(bContext *C, wmOperator *op, const wmEvent *U
|
|||
ED_workspace_status_text(C, TIP_("Click on the mesh to select a Face Set"));
|
||||
WM_cursor_modal_set(CTX_wm_window(C), WM_CURSOR_EYEDROPPER);
|
||||
WM_event_add_modal_handler(C, op);
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
|
@ -513,7 +517,8 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op)
|
|||
.use_toolflags = true,
|
||||
}));
|
||||
|
||||
BM_mesh_bm_from_me(NULL, bm,
|
||||
BM_mesh_bm_from_me(NULL,
|
||||
bm,
|
||||
new_mesh,
|
||||
(&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
@ -544,7 +549,8 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op)
|
|||
.use_toolflags = true,
|
||||
}));
|
||||
|
||||
BM_mesh_bm_from_me(NULL, bm,
|
||||
BM_mesh_bm_from_me(NULL,
|
||||
bm,
|
||||
new_ob_mesh,
|
||||
(&(struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
|
@ -580,15 +586,42 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op)
|
|||
|
||||
if (ob->mode == OB_MODE_SCULPT) {
|
||||
SculptSession *ss = ob->sculpt;
|
||||
ss->face_sets = CustomData_get_layer(&((Mesh *)ob->data)->pdata, CD_SCULPT_FACE_SETS);
|
||||
if (ss->face_sets) {
|
||||
/* Assign a new Face Set ID to the new faces created by the slice operation. */
|
||||
const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(ob->data);
|
||||
ED_sculpt_face_sets_initialize_none_to_id(ob->data, next_face_set_id);
|
||||
|
||||
/* Assign a new Face Set ID to the new faces created by the slice operation. */
|
||||
|
||||
switch (BKE_pbvh_type(ss->pbvh)) {
|
||||
case PBVH_GRIDS:
|
||||
case PBVH_FACES:
|
||||
ss->face_sets = CustomData_get_layer(&((Mesh *)ob->data)->pdata, CD_SCULPT_FACE_SETS);
|
||||
|
||||
if (ss->face_sets) {
|
||||
const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(ob->data);
|
||||
ED_sculpt_face_sets_initialize_none_to_id(ob->data, next_face_set_id);
|
||||
}
|
||||
break;
|
||||
case PBVH_BMESH: {
|
||||
if (ss->bm && CustomData_has_layer(&ss->bm->pdata, CD_SCULPT_FACE_SETS)) {
|
||||
const int cd_fset = CustomData_get_offset(&ss->bm->pdata, CD_SCULPT_FACE_SETS);
|
||||
BMFace *f;
|
||||
BMIter iter;
|
||||
|
||||
const int next_face_set_id = SCULPT_face_set_next_available_get(ss);
|
||||
|
||||
BM_ITER_MESH (f, &iter, ss->bm, BM_FACES_OF_MESH) {
|
||||
int fset = BM_ELEM_CD_GET_INT(f, cd_fset);
|
||||
|
||||
if (fset == SCULPT_FACE_SET_NONE) {
|
||||
BM_ELEM_CD_SET_INT(f, cd_fset, next_face_set_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
ED_sculpt_undo_geometry_end(ob);
|
||||
}
|
||||
|
||||
ED_sculpt_undo_geometry_end(ob);
|
||||
|
||||
BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
|
||||
|
|
|
@ -76,204 +76,6 @@
|
|||
#include <stdlib.h>
|
||||
#define SCULPT_GEODESIC_VERTEX_NONE -1
|
||||
|
||||
/*
|
||||
|
||||
on factor;
|
||||
off period;
|
||||
|
||||
load_package "avector";
|
||||
|
||||
comment: if (dist1 != 0.0f && dist2 != 0.0f);
|
||||
|
||||
forall x let abs(abs(x)*abs(x)) = x**2;
|
||||
forall x let abs(x*x) = x**2;
|
||||
forall x let abs(abs(x)) = abs(x);
|
||||
forall x let abs(x)**2 = x**2;
|
||||
|
||||
let v2len**2 = v2lensqr;
|
||||
let abs(v2len) = v2len;
|
||||
let sqrt(the_hh) = the_hh_sqrt;
|
||||
|
||||
v0 := avec(v0x, v0y, v0z);
|
||||
v1 := avec(0, 0, 0); comment: avec(v1x, v1y, v1z);
|
||||
v2 := avec(v2x, v2y, v2z);
|
||||
|
||||
let v2x**2 + v2y**2 + v2z**2 = v2lensqr;
|
||||
let sqrt(v2lensqr) = v2len;
|
||||
|
||||
v10 := v0; comment: v0 - v1;
|
||||
v12 := v2; comment: v2 - v1;
|
||||
|
||||
d12 := v2len;
|
||||
|
||||
comment: if d12*d12 > 0.0;
|
||||
|
||||
u := v12 / d12;
|
||||
|
||||
n := v12 cross v10;
|
||||
n = n / VMOD n;
|
||||
v := n cross u;
|
||||
|
||||
v0_0 := v10 dot u;
|
||||
v0_1 := abs(v10 dot v);
|
||||
|
||||
a := 0.5 * (1.0 + (dist1 * dist1 - dist2 * dist2) / (d12 * d12));
|
||||
|
||||
hh := dist1 * dist1 - a * a * d12 * d12;
|
||||
|
||||
commment: if (hh > 0.0f);
|
||||
|
||||
h := the_hh**0.5;
|
||||
|
||||
S_0 := a*d12;
|
||||
S_1 := -h;
|
||||
|
||||
x_intercept := S_0 + h * (v0_0 - S_0) / (v0_1 + h);
|
||||
|
||||
comment: if (x_intercept >= 0.0f && x_intercept <= d12);
|
||||
|
||||
on rounded;
|
||||
on double;
|
||||
on period;
|
||||
|
||||
result := ((S_0-v0_0)**2 + (S_1 - v0_1)**2)**0.5;
|
||||
|
||||
load_package "gentran";
|
||||
|
||||
gentranlang!* := 'c$
|
||||
|
||||
on factor;
|
||||
|
||||
gentran begin outhh := eval(hh); outxintercept := eval(x_intercept); outresult := eval(result) end;
|
||||
|
||||
*/
|
||||
static float fast_geodesic_distance_propagate_across_triangle(
|
||||
const float v0[3], const float v1[3], const float v2[3], const float dist1, const float dist2)
|
||||
{
|
||||
float the_hh, the_hh_sqrt;
|
||||
float v0x = v0[0] - v1[0];
|
||||
float v0y = v0[1] - v1[1];
|
||||
float v0z = v0[2] - v1[2];
|
||||
|
||||
float v2x = v2[0] - v1[0];
|
||||
float v2y = v2[1] - v1[1];
|
||||
float v2z = v2[2] - v1[2];
|
||||
|
||||
if (dist1 != 0.0f && dist2 != 0.0f) {
|
||||
float v2lensqr = (v2x * v2x + v2y * v2y + v2z * v2z);
|
||||
float xintercept;
|
||||
|
||||
if (v2lensqr > 1.0e-35f) {
|
||||
float v2len = sqrtf(v2lensqr);
|
||||
|
||||
the_hh = -(0.25 * (dist2 + v2len + dist1) * (dist2 + v2len - dist1) *
|
||||
(dist2 - v2len + dist1) * (dist2 - v2len - dist1)) /
|
||||
v2lensqr;
|
||||
|
||||
if (the_hh > 0.0f) {
|
||||
the_hh_sqrt = sqrtf(the_hh);
|
||||
|
||||
xintercept =
|
||||
-(0.5 * (dist2 * dist2 - v2lensqr - (dist1 * dist1)) *
|
||||
fabsf((float)(((v2lensqr - (v2z * v2z)) * v0z - (2 * v0y * v2y * v2z)) * v0z +
|
||||
(v2lensqr - (v2y * v2y)) * (v0y * v0y) -
|
||||
((2 * (v0y * v2y + v0z * v2z) * v2x -
|
||||
((v2y * v2y + v2z * v2z) * v0x)) *
|
||||
v0x))) -
|
||||
((v0y * v2y + v0z * v2z + v0x * v2x) * the_hh_sqrt * v2len)) /
|
||||
((fabsf(
|
||||
(float)(((v2lensqr - (v2z * v2z)) * v0z - (2 * v0y * v2y * v2z)) * v0z +
|
||||
(v2lensqr - (v2y * v2y)) * (v0y * v0y) -
|
||||
((2 * (v0y * v2y + v0z * v2z) * v2x - ((v2y * v2y + v2z * v2z) * v0x)) *
|
||||
v0x))) +
|
||||
the_hh_sqrt * v2len) *
|
||||
v2len);
|
||||
|
||||
if (xintercept >= 0.0 && xintercept <= v2len) {
|
||||
float result =
|
||||
(0.5 * sqrt((float)((2.0 * (v0y * v2y + v0z * v2z + v0x * v2x) - (dist1 * dist1) +
|
||||
(dist2 + v2len) * (dist2 - v2len)) *
|
||||
(2.0 * (v0y * v2y + v0z * v2z + v0x * v2x) -
|
||||
(dist1 * dist1) + (dist2 + v2len) * (dist2 - v2len)) +
|
||||
4.0 * ((fabsf((float)(((v2lensqr - (v2z * v2z)) * v0z -
|
||||
(2 * v0y * v2y * v2z)) *
|
||||
v0z +
|
||||
(v2lensqr - (v2y * v2y)) * (v0y * v0y) -
|
||||
((2 * (v0y * v2y + v0z * v2z) * v2x -
|
||||
((v2y * v2y + v2z * v2z) * v0x)) *
|
||||
v0x))) +
|
||||
the_hh_sqrt * v2len) *
|
||||
(fabsf((float)(((v2lensqr - (v2z * v2z)) * v0z -
|
||||
(2 * v0y * v2y * v2z)) *
|
||||
v0z +
|
||||
(v2lensqr - (v2y * v2y)) * (v0y * v0y) -
|
||||
((2 * (v0y * v2y + v0z * v2z) * v2x -
|
||||
((v2y * v2y + v2z * v2z) * v0x)) *
|
||||
v0x))) +
|
||||
the_hh_sqrt * v2len))))) /
|
||||
v2len;
|
||||
/*
|
||||
printf("%.7f : %.7f\n",
|
||||
result*2.0,
|
||||
geodesic_distance_propagate_across_triangle(v0, v1, v2, dist1, dist2));*/
|
||||
return result * 4.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Fall back to Dijsktra approximation in trivial case, or if no valid source
|
||||
* point found that connects to v0 across the triangle. */
|
||||
return min_ff(dist1 + sqrtf(v0x * v0x + v0y * v0y + v0z * v0z), dist2 + len_v3v3(v0, v2));
|
||||
}
|
||||
|
||||
#if 0
|
||||
float geodesic_distance_propagate_across_triangle(
|
||||
const float v0[3], const float v1[3], const float v2[3], const float dist1, const float dist2)
|
||||
{
|
||||
/* Vectors along triangle edges. */
|
||||
float v10[3], v12[3];
|
||||
sub_v3_v3v3(v10, v0, v1);
|
||||
sub_v3_v3v3(v12, v2, v1);
|
||||
|
||||
if (dist1 != 0.0f && dist2 != 0.0f) {
|
||||
/* Local coordinate system in the triangle plane. */
|
||||
float u[3], v[3], n[3];
|
||||
const float d12 = normalize_v3_v3(u, v12);
|
||||
|
||||
if (d12 * d12 > 0.0f) {
|
||||
cross_v3_v3v3(n, v12, v10);
|
||||
normalize_v3(n);
|
||||
cross_v3_v3v3(v, n, u);
|
||||
|
||||
/* v0 in local coordinates */
|
||||
const float v0_[2] = {dot_v3v3(v10, u), fabsf(dot_v3v3(v10, v))};
|
||||
|
||||
/* Compute virtual source point in local coordinates, that we estimate the geodesic
|
||||
* distance is being computed from. See figure 9 in the paper for the derivation. */
|
||||
const float a = 0.5f * (1.0f + (dist1 * dist1 - dist2 * dist2) / (d12 * d12));
|
||||
const float hh = dist1 * dist1 - a * a * d12 * d12;
|
||||
|
||||
if (hh > 0.0f) {
|
||||
const float h = sqrtf(hh);
|
||||
const float S_[2] = {a * d12, -h};
|
||||
|
||||
/* Only valid if the line between the source point and v0 crosses
|
||||
* the edge between v1 and v2. */
|
||||
const float x_intercept = S_[0] + h * (v0_[0] - S_[0]) / (v0_[1] + h);
|
||||
if (x_intercept >= 0.0f && x_intercept <= d12) {
|
||||
return len_v2v2(S_, v0_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Fall back to Dijsktra approximation in trivial case, or if no valid source
|
||||
* point found that connects to v0 across the triangle. */
|
||||
return min_ff(dist1 + len_v3(v10), dist2 + len_v3v3(v0, v2));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Propagate distance from v1 and v2 to v0. */
|
||||
static bool sculpt_geodesic_mesh_test_dist_add(
|
||||
MVert *mvert, const int v0, const int v1, const int v2, float *dists, GSet *initial_vertices)
|
||||
|
|
Loading…
Reference in New Issue