- simplify rip code not to expand/contract selection.
- disable BVH edge visibility test (ifdef'd out. dont think its really needed)
This commit is contained in:
@@ -220,39 +220,39 @@ float BM_face_area_calc(BMesh *bm, BMFace *f)
|
||||
/**
|
||||
* computes center of face in 3d. uses center of bounding box.
|
||||
*/
|
||||
void BM_face_center_bounds_calc(BMesh *bm, BMFace *f, float r_cent[3])
|
||||
void BM_face_center_bounds_calc(BMesh *UNUSED(bm), BMFace *f, float r_cent[3])
|
||||
{
|
||||
BMIter iter;
|
||||
BMLoop *l;
|
||||
BMLoop *l_iter;
|
||||
BMLoop *l_first;
|
||||
float min[3], max[3];
|
||||
int i;
|
||||
|
||||
INIT_MINMAX(min, max);
|
||||
l = BM_iter_new(&iter, bm, BM_LOOPS_OF_FACE, f);
|
||||
for (i = 0; l; l = BM_iter_step(&iter), i++) {
|
||||
DO_MINMAX(l->v->co, min, max);
|
||||
}
|
||||
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
do {
|
||||
DO_MINMAX(l_iter->v->co, min, max);
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
|
||||
mid_v3_v3v3(r_cent, min, max);
|
||||
}
|
||||
|
||||
/**
|
||||
* computes the centroid of a face, using the mean average
|
||||
* computes the center of a face, using the mean average
|
||||
*/
|
||||
void BM_face_center_mean_calc(BMesh *bm, BMFace *f, float r_cent[3])
|
||||
void BM_face_center_mean_calc(BMesh *UNUSED(bm), BMFace *f, float r_cent[3])
|
||||
{
|
||||
BMIter iter;
|
||||
BMLoop *l;
|
||||
int i;
|
||||
BMLoop *l_iter;
|
||||
BMLoop *l_first;
|
||||
|
||||
zero_v3(r_cent);
|
||||
|
||||
l = BM_iter_new(&iter, bm, BM_LOOPS_OF_FACE, f);
|
||||
for (i = 0; l; l = BM_iter_step(&iter), i++) {
|
||||
add_v3_v3(r_cent, l->v->co);
|
||||
}
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
do {
|
||||
add_v3_v3(r_cent, l_iter->v->co);
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
|
||||
if (f->len) mul_v3_fl(r_cent, 1.0f / (float)f->len);
|
||||
if (f->len)
|
||||
mul_v3_fl(r_cent, 1.0f / (float) f->len);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -291,11 +291,6 @@ void compute_poly_plane(float (*verts)[3], int nverts)
|
||||
avgn[2] = 1.0f;
|
||||
}
|
||||
else {
|
||||
/* XXX, why is this being divided and _then_ normalized
|
||||
* division could be removed? - campbell */
|
||||
avgn[0] /= nverts;
|
||||
avgn[1] /= nverts;
|
||||
avgn[2] /= nverts;
|
||||
normalize_v3(avgn);
|
||||
}
|
||||
|
||||
|
||||
@@ -2327,26 +2327,40 @@ static float mesh_rip_edgedist(ARegion *ar, float mat[][4], float *co1, float *c
|
||||
return dist_to_line_segment_v2(mvalf, vec1, vec2);
|
||||
}
|
||||
|
||||
/* #define USE_BVH_VISIBILITY */
|
||||
|
||||
/* based on mouse cursor position, it defines how is being ripped */
|
||||
static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
#ifdef USE_BVH_VISIBILITY
|
||||
BMBVHTree *bvhtree;
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
#endif
|
||||
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
||||
BMEditMesh *em = BMEdit_FromObject(obedit);
|
||||
BMesh *bm = em->bm;
|
||||
BMOperator bmop;
|
||||
BMBVHTree *bvhtree;
|
||||
BMOIter siter;
|
||||
BMIter iter, eiter, liter;
|
||||
BMIter iter, eiter;
|
||||
BMLoop *l;
|
||||
BMEdge *e, *e2, *closest = NULL;
|
||||
BMVert *v, *ripvert = NULL;
|
||||
int side = 0, i, singlesel = 0;
|
||||
int side = 0, i, singlesel = FALSE;
|
||||
float projectMat[4][4], fmval[3] = {event->mval[0], event->mval[1]};
|
||||
float dist = FLT_MAX, d;
|
||||
|
||||
/* note on selection:
|
||||
* When calling edge split we operate on tagged edges rather then selected
|
||||
* this is important because the edges to operate on are extended by one,
|
||||
* but the selection is left alone.
|
||||
*
|
||||
* After calling edge split - the duplicated edges have the same selection state as the
|
||||
* original, so all we do is de-select the far side from the mouse and we have a
|
||||
* useful selection for grabbing.
|
||||
*/
|
||||
|
||||
ED_view3d_ob_project_mat_get(rv3d, obedit, projectMat);
|
||||
|
||||
/* BM_ELEM_SELECT --> BM_ELEM_TAG */
|
||||
@@ -2358,12 +2372,18 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
* closest edge around that vert to mouse cursor,
|
||||
* then rip two adjacent edges in the vert fan. */
|
||||
if (bm->totvertsel == 1 && bm->totedgesel == 0 && bm->totfacesel == 0) {
|
||||
singlesel = 1;
|
||||
BMEditSelection ese;
|
||||
singlesel = TRUE;
|
||||
|
||||
/* find selected vert */
|
||||
BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {
|
||||
if (BM_elem_flag_test(v, BM_ELEM_SELECT))
|
||||
break;
|
||||
/* find selected vert - same some time and check history first */
|
||||
if (EDBM_get_actSelection(em, &ese) && ese.htype == BM_VERT) {
|
||||
v = (BMVert *)ese.ele;
|
||||
}
|
||||
else {
|
||||
BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {
|
||||
if (BM_elem_flag_test(v, BM_ELEM_SELECT))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* this should be impossible, but sanity checks are a good thing */
|
||||
@@ -2402,12 +2422,10 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
l = e2->l;
|
||||
e = BM_face_other_edge_loop(l->f, e2, v)->e;
|
||||
BM_elem_flag_enable(e, BM_ELEM_TAG);
|
||||
BM_elem_select_set(bm, e, TRUE);
|
||||
|
||||
l = e2->l->radial_next;
|
||||
e = BM_face_other_edge_loop(l->f, e2, v)->e;
|
||||
BM_elem_flag_enable(e, BM_ELEM_TAG);
|
||||
BM_elem_select_set(bm, e, TRUE);
|
||||
}
|
||||
|
||||
dist = FLT_MAX;
|
||||
@@ -2418,7 +2436,9 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
e2 = NULL;
|
||||
i = 0;
|
||||
BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, v) {
|
||||
if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
|
||||
/* important to check selection rather then tag here
|
||||
* else we get feedback loop */
|
||||
if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
|
||||
e2 = e;
|
||||
i++;
|
||||
}
|
||||
@@ -2430,37 +2450,38 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
l = BM_face_other_edge_loop(l->f, l->e, v);
|
||||
|
||||
if (l) {
|
||||
BM_elem_select_set(bm, l->e, TRUE);
|
||||
BM_elem_flag_enable(l->e, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!EDBM_InitOpf(em, &bmop, op, "edgesplit edges=%he", BM_ELEM_SELECT)) {
|
||||
if (!EDBM_InitOpf(em, &bmop, op, "edgesplit edges=%he", BM_ELEM_TAG)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
BMO_op_exec(bm, &bmop);
|
||||
|
||||
#ifdef USE_BVH_VISIBILITY
|
||||
/* build bvh tree for edge visibility tests */
|
||||
bvhtree = BMBVH_NewBVH(em, 0, NULL, NULL);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
BMO_ITER(e, &siter, bm, &bmop, i ? "edgeout2":"edgeout1", BM_EDGE) {
|
||||
float cent[3] = {0, 0, 0}, mid[3], vec[3];
|
||||
|
||||
#ifdef USE_BVH_VISIBILITY
|
||||
if (!BMBVH_EdgeVisible(bvhtree, e, ar, v3d, obedit) || !e->l)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
/* method for calculating distance:
|
||||
*
|
||||
* for each edge: calculate face center, then made a vector
|
||||
* from edge midpoint to face center. offset edge midpoint
|
||||
* by a small amount along this vector. */
|
||||
BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, e->l->f) {
|
||||
add_v3_v3(cent, l->v->co);
|
||||
}
|
||||
mul_v3_fl(cent, 1.0f/(float)e->l->f->len);
|
||||
BM_face_center_mean_calc(bm, e->l->f, cent);
|
||||
|
||||
mid_v3_v3v3(mid, e->v1->co, e->v2->co);
|
||||
sub_v3_v3v3(vec, cent, mid);
|
||||
@@ -2468,7 +2489,7 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
mul_v3_fl(vec, 0.01f);
|
||||
add_v3_v3v3(mid, mid, vec);
|
||||
|
||||
/* yay we have our comparison point, now project it */
|
||||
/* We have our comparison point, now project it */
|
||||
ED_view3d_project_float(ar, mid, mid, projectMat);
|
||||
|
||||
d = len_squared_v2v2(fmval, mid);
|
||||
@@ -2480,34 +2501,13 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_BVH_VISIBILITY
|
||||
BMBVH_FreeBVH(bvhtree);
|
||||
#endif
|
||||
|
||||
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
|
||||
BMO_slot_buffer_hflag_enable(bm, &bmop, side?"edgeout2":"edgeout1", BM_ELEM_SELECT, BM_EDGE, TRUE);
|
||||
|
||||
BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) {
|
||||
BM_elem_flag_set(e, BM_ELEM_TAG, BM_elem_flag_test(e, BM_ELEM_SELECT));
|
||||
}
|
||||
|
||||
/* constrict edge selection again */
|
||||
BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {
|
||||
e2 = NULL;
|
||||
i = 0;
|
||||
BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, v) {
|
||||
if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
|
||||
e2 = e;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 1) {
|
||||
if (singlesel)
|
||||
BM_elem_select_set(bm, v, FALSE);
|
||||
else
|
||||
BM_elem_select_set(bm, e2, FALSE);
|
||||
}
|
||||
}
|
||||
/* de-select one of the sides */
|
||||
BMO_slot_buffer_hflag_disable(bm, &bmop, side ? "edgeout1" : "edgeout2", BM_ELEM_SELECT, BM_EDGE, TRUE);
|
||||
|
||||
if (ripvert) {
|
||||
BM_elem_select_set(bm, ripvert, TRUE);
|
||||
@@ -2962,7 +2962,7 @@ static float bm_edge_seg_isect(BMEdge *e, CutCurve *c, int len, char mode,
|
||||
}
|
||||
}
|
||||
|
||||
/* now check for edge interesect (may produce vertex intersection as well)*/
|
||||
/* now check for edge intersect (may produce vertex intersection as well) */
|
||||
for (i = 0; i < len; i++) {
|
||||
if (i > 0) {
|
||||
x11 = x12;
|
||||
|
||||
@@ -43,11 +43,10 @@ struct RayHint;
|
||||
struct VlakRen;
|
||||
|
||||
/* RayObject
|
||||
|
||||
Can be a face/triangle, bvh tree, object instance, etc. This is the
|
||||
public API used by the renderer, see rayobject_internal.h for the
|
||||
internal implementation details. */
|
||||
|
||||
* Can be a face/triangle, bvh tree, object instance, etc. This is the
|
||||
* public API used by the renderer, see rayobject_internal.h for the
|
||||
* internal implementation details.
|
||||
* */
|
||||
typedef struct RayObject RayObject;
|
||||
|
||||
/* Intersection, see rayintersection.h */
|
||||
@@ -74,8 +73,8 @@ void RE_rayobject_free(RayObject *r);
|
||||
void RE_rayobject_set_control(RayObject *r, void *data, int (*test_break)(void *data));
|
||||
|
||||
/* RayObject representing faces, all data is locally available instead
|
||||
of referring to some external data structure, for possibly faster
|
||||
intersection tests. */
|
||||
* of referring to some external data structure, for possibly faster
|
||||
* intersection tests. */
|
||||
|
||||
typedef struct RayFace {
|
||||
float v1[4], v2[4], v3[4], v4[3];
|
||||
@@ -89,8 +88,8 @@ typedef struct RayFace {
|
||||
RayObject* RE_rayface_from_vlak(RayFace *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr);
|
||||
|
||||
/* RayObject representing faces directly from a given VlakRen structure. Thus
|
||||
allowing to save memory, but making code triangle intersection dependent on
|
||||
render structures. */
|
||||
* allowing to save memory, but making code triangle intersection dependent on
|
||||
* render structures. */
|
||||
|
||||
typedef struct VlakPrimitive {
|
||||
struct ObjectInstanceRen *ob;
|
||||
@@ -104,10 +103,10 @@ RayObject* RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstance
|
||||
/* extend min/max coords so that the rayobject is inside them */
|
||||
void RE_rayobject_merge_bb(RayObject *ob, float *min, float *max);
|
||||
|
||||
/* initializes an hint for optiming raycast where it is know that a ray will pass by the given BB often the origin point */
|
||||
/* initializes an hint for optimizing raycast where it is know that a ray will pass by the given BB often the origin point */
|
||||
void RE_rayobject_hint_bb(RayObject *r, struct RayHint *hint, float *min, float *max);
|
||||
|
||||
/* initializes an hint for optiming raycast where it is know that a ray will be contained inside the given cone*/
|
||||
/* initializes an hint for optimizing raycast where it is know that a ray will be contained inside the given cone*/
|
||||
/* void RE_rayobject_hint_cone(RayObject *r, struct RayHint *hint, float *); */
|
||||
|
||||
/* Internals */
|
||||
|
||||
Reference in New Issue
Block a user