Transform Volume rewrite/refactor
Take advantage of the efficiency provided by the snap_context. Also fixes errors: - volume snap fails based on view angle (T48394). - multiple instances of dupli-objects break volume calculation.
This commit is contained in:

committed by
Campbell Barton

parent
4a135ad2b7
commit
67d2de8828
@@ -82,7 +82,6 @@ typedef struct SK_Intersection {
|
||||
|
||||
typedef struct SK_Sketch {
|
||||
ListBase strokes;
|
||||
ListBase depth_peels;
|
||||
SK_Stroke *active_stroke;
|
||||
SK_Stroke *gesture;
|
||||
SK_Point next_point;
|
||||
|
@@ -50,8 +50,6 @@ void freeSketch(SK_Sketch *sketch)
|
||||
sk_freeStroke(stk);
|
||||
}
|
||||
|
||||
BLI_freelistN(&sketch->depth_peels);
|
||||
|
||||
MEM_freeN(sketch);
|
||||
}
|
||||
|
||||
|
@@ -970,100 +970,30 @@ static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, S
|
||||
ToolSettings *ts = CTX_data_tool_settings(C);
|
||||
int point_added = 0;
|
||||
|
||||
struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
|
||||
CTX_data_main(C), CTX_data_scene(C), 0,
|
||||
CTX_wm_region(C), CTX_wm_view3d(C));
|
||||
|
||||
float mvalf[2] = {UNPACK2(dd->mval)};
|
||||
float r_loc[3], dummy_no[3];
|
||||
|
||||
if (ts->snap_mode == SCE_SNAP_MODE_VOLUME) {
|
||||
DepthPeel *p1, *p2;
|
||||
float *last_p = NULL;
|
||||
float dist = FLT_MAX;
|
||||
float p[3] = {0};
|
||||
float size = 0;
|
||||
float mvalf[2];
|
||||
|
||||
BLI_freelistN(&sketch->depth_peels);
|
||||
BLI_listbase_clear(&sketch->depth_peels);
|
||||
|
||||
mvalf[0] = dd->mval[0];
|
||||
mvalf[1] = dd->mval[1];
|
||||
peelObjectsContext(C, mvalf, SNAP_ALL, &sketch->depth_peels);
|
||||
|
||||
if (stk->nb_points > 0 && stk->points[stk->nb_points - 1].type == PT_CONTINUOUS) {
|
||||
last_p = stk->points[stk->nb_points - 1].p;
|
||||
}
|
||||
else if (LAST_SNAP_POINT_VALID) {
|
||||
last_p = LAST_SNAP_POINT;
|
||||
}
|
||||
|
||||
|
||||
for (p1 = sketch->depth_peels.first; p1; p1 = p1->next) {
|
||||
if (p1->flag == 0) {
|
||||
float vec[3];
|
||||
float new_dist;
|
||||
float new_size = 0;
|
||||
|
||||
p2 = NULL;
|
||||
p1->flag = 1;
|
||||
|
||||
/* if peeling objects, take the first and last from each object */
|
||||
if (ts->snap_flag & SCE_SNAP_PEEL_OBJECT) {
|
||||
DepthPeel *peel;
|
||||
for (peel = p1->next; peel; peel = peel->next) {
|
||||
if (peel->ob == p1->ob) {
|
||||
peel->flag = 1;
|
||||
p2 = peel;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* otherwise, pair first with second and so on */
|
||||
else {
|
||||
for (p2 = p1->next; p2 && p2->ob != p1->ob; p2 = p2->next) {
|
||||
/* nothing to do here */
|
||||
}
|
||||
}
|
||||
|
||||
if (p2) {
|
||||
p2->flag = 1;
|
||||
|
||||
add_v3_v3v3(vec, p1->p, p2->p);
|
||||
mul_v3_fl(vec, 0.5f);
|
||||
new_size = len_v3v3(p1->p, p2->p);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(vec, p1->p);
|
||||
}
|
||||
|
||||
if (last_p == NULL) {
|
||||
copy_v3_v3(p, vec);
|
||||
size = new_size;
|
||||
dist = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
new_dist = len_v3v3(last_p, vec);
|
||||
|
||||
if (new_dist < dist) {
|
||||
copy_v3_v3(p, vec);
|
||||
dist = new_dist;
|
||||
size = new_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dist != FLT_MAX) {
|
||||
float size;
|
||||
if (peelObjectsSnapContext(
|
||||
snap_context, mvalf, SNAP_ALL,
|
||||
(ts->snap_flag & SCE_SNAP_PEEL_OBJECT) != 0,
|
||||
r_loc, dummy_no, &size))
|
||||
{
|
||||
pt->type = dd->type;
|
||||
pt->mode = PT_SNAP;
|
||||
pt->size = size / 2;
|
||||
copy_v3_v3(pt->p, p);
|
||||
copy_v3_v3(pt->p, r_loc);
|
||||
|
||||
point_added = 1;
|
||||
}
|
||||
|
||||
//BLI_freelistN(&depth_peels);
|
||||
}
|
||||
else {
|
||||
SK_Stroke *snap_stk;
|
||||
float vec[3];
|
||||
float no[3];
|
||||
float mval[2];
|
||||
int found = 0;
|
||||
float dist_px = SNAP_MIN_DISTANCE; // Use a user defined value here
|
||||
|
||||
/* snap to strokes */
|
||||
@@ -1083,36 +1013,27 @@ static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, S
|
||||
}
|
||||
}
|
||||
|
||||
mval[0] = dd->mval[0];
|
||||
mval[1] = dd->mval[1];
|
||||
|
||||
/* try to snap to closer object */
|
||||
{
|
||||
struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
|
||||
CTX_data_main(C), CTX_data_scene(C), 0,
|
||||
CTX_wm_region(C), CTX_wm_view3d(C));
|
||||
|
||||
found = ED_transform_snap_object_project_view3d(
|
||||
if (ED_transform_snap_object_project_view3d(
|
||||
snap_context,
|
||||
&(const struct SnapObjectParams){
|
||||
.snap_select = SNAP_NOT_SELECTED,
|
||||
.snap_to = ts->snap_mode,
|
||||
},
|
||||
mval, &dist_px, NULL,
|
||||
vec, no);
|
||||
|
||||
ED_transform_snap_object_context_destroy(snap_context);
|
||||
}
|
||||
|
||||
if (found == 1) {
|
||||
mvalf, &dist_px, NULL,
|
||||
r_loc, dummy_no))
|
||||
{
|
||||
pt->type = dd->type;
|
||||
pt->mode = PT_SNAP;
|
||||
copy_v3_v3(pt->p, vec);
|
||||
copy_v3_v3(pt->p, r_loc);
|
||||
|
||||
point_added = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ED_transform_snap_object_context_destroy(snap_context);
|
||||
return point_added;
|
||||
}
|
||||
|
||||
|
@@ -158,19 +158,6 @@ void BIF_draw_manipulator(const struct bContext *C);
|
||||
|
||||
/* Snapping */
|
||||
|
||||
|
||||
typedef struct DepthPeel {
|
||||
struct DepthPeel *next, *prev;
|
||||
|
||||
float depth;
|
||||
float p[3];
|
||||
float no[3];
|
||||
struct Object *ob;
|
||||
int flag;
|
||||
} DepthPeel;
|
||||
|
||||
struct ListBase;
|
||||
|
||||
typedef enum SnapSelect {
|
||||
SNAP_ALL = 0,
|
||||
SNAP_NOT_SELECTED = 1,
|
||||
@@ -179,14 +166,18 @@ typedef enum SnapSelect {
|
||||
|
||||
#define SNAP_MIN_DISTANCE 30
|
||||
|
||||
bool peelObjectsTransForm(
|
||||
struct TransInfo *t, const float mval[2], SnapSelect snap_select,
|
||||
bool peelObjectsTransform(
|
||||
struct TransInfo *t, const float mval[2],
|
||||
SnapSelect snap_select, bool use_peel_object,
|
||||
/* return args */
|
||||
struct ListBase *r_depth_peels);
|
||||
bool peelObjectsContext(
|
||||
struct bContext *C, const float mval[2], SnapSelect snap_select,
|
||||
float r_loc[3], float r_no[3], float *r_thickness);
|
||||
bool peelObjectsSnapContext(
|
||||
struct SnapObjectContext *sctx,
|
||||
const float mval[2],
|
||||
SnapSelect snap_select, bool use_peel_object,
|
||||
/* return args */
|
||||
struct ListBase *r_depth_peels);
|
||||
float r_loc[3], float r_no[3], float *r_thickness);
|
||||
|
||||
bool snapObjectsTransform(
|
||||
struct TransInfo *t, const float mval[2], SnapSelect snap_select,
|
||||
float *dist_px,
|
||||
|
@@ -29,6 +29,7 @@ struct BMVert;
|
||||
struct BMEdge;
|
||||
struct BMFace;
|
||||
|
||||
struct ListBase;
|
||||
struct Scene;
|
||||
struct Main;
|
||||
struct Object;
|
||||
@@ -38,6 +39,24 @@ struct View3D;
|
||||
/* transform_snap_object.c */
|
||||
|
||||
/* ED_transform_snap_object_*** API */
|
||||
|
||||
/** used for storing multiple hits */
|
||||
struct SnapObjectHitDepth {
|
||||
struct SnapObjectHitDepth *next, *prev;
|
||||
|
||||
float depth;
|
||||
float co[3];
|
||||
float no[3];
|
||||
int index;
|
||||
|
||||
struct Object *ob;
|
||||
float obmat[4][4];
|
||||
|
||||
/* needed to tell which ray-cast this was part of,
|
||||
* the same object may be part of many ray-casts when dupli's are used. */
|
||||
unsigned int ob_uuid;
|
||||
};
|
||||
|
||||
struct SnapObjectParams {
|
||||
int snap_select; /* SnapSelect */
|
||||
union {
|
||||
@@ -81,9 +100,16 @@ bool ED_transform_snap_object_project_ray_ex(
|
||||
struct Object **r_ob, float r_obmat[4][4]);
|
||||
bool ED_transform_snap_object_project_ray(
|
||||
SnapObjectContext *sctx,
|
||||
const float ray_origin[3], const float ray_direction[3], float *ray_dist,
|
||||
const float ray_origin[3], const float ray_direction[3], float *ray_depth,
|
||||
float r_co[3], float r_no[3]);
|
||||
|
||||
bool ED_transform_snap_object_project_ray_all(
|
||||
SnapObjectContext *sctx,
|
||||
const struct SnapObjectParams *params,
|
||||
const float ray_start[3], const float ray_normal[3],
|
||||
float ray_depth, bool sort,
|
||||
struct ListBase *r_hit_list);
|
||||
|
||||
bool ED_transform_snap_object_project_view3d_ex(
|
||||
struct SnapObjectContext *sctx,
|
||||
const struct SnapObjectParams *params,
|
||||
@@ -104,4 +130,11 @@ bool ED_transform_snap_object_project_view3d_mixed(
|
||||
bool use_depth,
|
||||
float r_co[3], float r_no[3]);
|
||||
|
||||
bool ED_transform_snap_object_project_all_view3d_ex(
|
||||
SnapObjectContext *sctx,
|
||||
const struct SnapObjectParams *params,
|
||||
const float mval[2],
|
||||
float ray_depth, bool sort,
|
||||
ListBase *r_hit_list);
|
||||
|
||||
#endif /* __ED_TRANSFORM_SNAP_OBJECT_CONTEXT_H__ */
|
||||
|
@@ -963,86 +963,10 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec))
|
||||
mval[1] = t->mval[1];
|
||||
|
||||
if (t->tsnap.mode == SCE_SNAP_MODE_VOLUME) {
|
||||
ListBase depth_peels;
|
||||
DepthPeel *p1, *p2;
|
||||
const float *last_p = NULL;
|
||||
float max_dist = FLT_MAX;
|
||||
float p[3] = {0.0f, 0.0f, 0.0f};
|
||||
|
||||
BLI_listbase_clear(&depth_peels);
|
||||
|
||||
peelObjectsTransForm(t, mval, t->tsnap.modeSelect, &depth_peels);
|
||||
|
||||
// if (LAST_SNAP_POINT_VALID)
|
||||
// {
|
||||
// last_p = LAST_SNAP_POINT;
|
||||
// }
|
||||
// else
|
||||
{
|
||||
last_p = t->tsnap.snapPoint;
|
||||
}
|
||||
|
||||
|
||||
for (p1 = depth_peels.first; p1; p1 = p1->next) {
|
||||
if (p1->flag == 0) {
|
||||
float vec[3];
|
||||
float new_dist;
|
||||
|
||||
p2 = NULL;
|
||||
p1->flag = 1;
|
||||
|
||||
/* if peeling objects, take the first and last from each object */
|
||||
if (t->settings->snap_flag & SCE_SNAP_PEEL_OBJECT) {
|
||||
DepthPeel *peel;
|
||||
for (peel = p1->next; peel; peel = peel->next) {
|
||||
if (peel->ob == p1->ob) {
|
||||
peel->flag = 1;
|
||||
p2 = peel;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* otherwise, pair first with second and so on */
|
||||
else {
|
||||
for (p2 = p1->next; p2 && p2->ob != p1->ob; p2 = p2->next) {
|
||||
/* nothing to do here */
|
||||
}
|
||||
}
|
||||
|
||||
if (p2) {
|
||||
p2->flag = 1;
|
||||
|
||||
add_v3_v3v3(vec, p1->p, p2->p);
|
||||
mul_v3_fl(vec, 0.5f);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(vec, p1->p);
|
||||
}
|
||||
|
||||
if (last_p == NULL) {
|
||||
copy_v3_v3(p, vec);
|
||||
max_dist = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
new_dist = len_squared_v3v3(last_p, vec);
|
||||
|
||||
if (new_dist < max_dist) {
|
||||
copy_v3_v3(p, vec);
|
||||
max_dist = new_dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (max_dist != FLT_MAX) {
|
||||
copy_v3_v3(loc, p);
|
||||
/* XXX, is there a correct normal in this case ???, for now just z up */
|
||||
no[0] = 0.0;
|
||||
no[1] = 0.0;
|
||||
no[2] = 1.0;
|
||||
found = true;
|
||||
}
|
||||
|
||||
BLI_freelistN(&depth_peels);
|
||||
found = peelObjectsTransform(
|
||||
t, mval, t->tsnap.modeSelect,
|
||||
(t->settings->snap_flag & SCE_SNAP_PEEL_OBJECT) != 0,
|
||||
loc, no, NULL);
|
||||
}
|
||||
else {
|
||||
zero_v3(no); /* objects won't set this */
|
||||
@@ -1302,347 +1226,87 @@ bool snapObjectsTransform(
|
||||
|
||||
/******************** PEELING *********************************/
|
||||
|
||||
|
||||
static int cmpPeel(const void *arg1, const void *arg2)
|
||||
bool peelObjectsSnapContext(
|
||||
SnapObjectContext *sctx,
|
||||
const float mval[2], SnapSelect snap_select, bool use_peel_object,
|
||||
/* return args */
|
||||
float r_loc[3], float r_no[3], float *r_thickness)
|
||||
{
|
||||
const DepthPeel *p1 = arg1;
|
||||
const DepthPeel *p2 = arg2;
|
||||
int val = 0;
|
||||
ListBase depths_peel = {0};
|
||||
ED_transform_snap_object_project_all_view3d_ex(
|
||||
sctx,
|
||||
&(const struct SnapObjectParams){
|
||||
.snap_to = SCE_SNAP_MODE_FACE,
|
||||
.snap_select = snap_select,
|
||||
.use_object_edit = true,
|
||||
},
|
||||
mval, -1.0f, false,
|
||||
&depths_peel);
|
||||
|
||||
if (p1->depth < p2->depth) {
|
||||
val = -1;
|
||||
if (!BLI_listbase_is_empty(&depths_peel)) {
|
||||
/* At the moment we only use the hits of the first object */
|
||||
struct SnapObjectHitDepth *hit_min = depths_peel.first;
|
||||
for (struct SnapObjectHitDepth *iter = hit_min->next; iter; iter = iter->next) {
|
||||
if (iter->depth < hit_min->depth) {
|
||||
hit_min = iter;
|
||||
}
|
||||
else if (p1->depth > p2->depth) {
|
||||
val = 1;
|
||||
}
|
||||
struct SnapObjectHitDepth *hit_max = NULL;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void removeDoublesPeel(ListBase *depth_peels)
|
||||
{
|
||||
DepthPeel *peel;
|
||||
|
||||
for (peel = depth_peels->first; peel; peel = peel->next) {
|
||||
DepthPeel *next_peel = peel->next;
|
||||
|
||||
if (next_peel && fabsf(peel->depth - next_peel->depth) < 0.0015f) {
|
||||
peel->next = next_peel->next;
|
||||
|
||||
if (next_peel->next) {
|
||||
next_peel->next->prev = peel;
|
||||
}
|
||||
|
||||
MEM_freeN(next_peel);
|
||||
if (use_peel_object) {
|
||||
/* if peeling objects, take the first and last from each object */
|
||||
hit_max = hit_min;
|
||||
for (struct SnapObjectHitDepth *iter = depths_peel.first; iter; iter = iter->next) {
|
||||
if ((iter->depth > hit_max->depth) && (iter->ob_uuid == hit_min->ob_uuid)) {
|
||||
hit_max = iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void addDepthPeel(ListBase *depth_peels, float depth, float p[3], float no[3], Object *ob)
|
||||
{
|
||||
DepthPeel *peel = MEM_callocN(sizeof(DepthPeel), "DepthPeel");
|
||||
|
||||
peel->depth = depth;
|
||||
peel->ob = ob;
|
||||
copy_v3_v3(peel->p, p);
|
||||
copy_v3_v3(peel->no, no);
|
||||
|
||||
BLI_addtail(depth_peels, peel);
|
||||
|
||||
peel->flag = 0;
|
||||
else {
|
||||
/* otherwise, pair first with second and so on */
|
||||
for (struct SnapObjectHitDepth *iter = depths_peel.first; iter; iter = iter->next) {
|
||||
if ((iter != hit_min) && (iter->ob_uuid == hit_min->ob_uuid)) {
|
||||
if (hit_max == NULL) {
|
||||
hit_max = iter;
|
||||
}
|
||||
|
||||
struct PeelRayCast_Data {
|
||||
BVHTreeFromMesh bvhdata;
|
||||
|
||||
/* internal vars for adding peel */
|
||||
Object *ob;
|
||||
const float (*obmat)[4];
|
||||
const float (*timat)[3];
|
||||
|
||||
const float *ray_start; /* globalspace */
|
||||
|
||||
const MLoopTri *looptri;
|
||||
const float (*polynors)[3]; /* optional, can be NULL */
|
||||
|
||||
/* output list */
|
||||
ListBase *depth_peels;
|
||||
};
|
||||
|
||||
struct PeelEditMeshRayCast_Data {
|
||||
BVHTreeFromEditMesh bvhdata;
|
||||
|
||||
/* internal vars for adding peel */
|
||||
Object *ob;
|
||||
const float(*obmat)[4];
|
||||
const float(*timat)[3];
|
||||
|
||||
const float *ray_start; /* globalspace */
|
||||
|
||||
/* output list */
|
||||
ListBase *depth_peels;
|
||||
};
|
||||
|
||||
static void peelRayCast_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
|
||||
{
|
||||
struct PeelRayCast_Data *data = userdata;
|
||||
|
||||
data->bvhdata.raycast_callback(&data->bvhdata, index, ray, hit);
|
||||
|
||||
if (hit->index != -1) {
|
||||
/* get all values in worldspace */
|
||||
float location[3], normal[3];
|
||||
float depth;
|
||||
|
||||
/* worldspace location */
|
||||
mul_v3_m4v3(location, (float (*)[4])data->obmat, hit->co);
|
||||
depth = len_v3v3(location, data->ray_start);
|
||||
|
||||
/* worldspace normal */
|
||||
copy_v3_v3(normal, data->polynors ? data->polynors[data->looptri[hit->index].poly] : hit->no);
|
||||
mul_m3_v3((float (*)[3])data->timat, normal);
|
||||
normalize_v3(normal);
|
||||
|
||||
addDepthPeel(data->depth_peels, depth, location, normal, data->ob);
|
||||
else if (iter->depth < hit_max->depth) {
|
||||
hit_max = iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* in this case has only one hit. treat as raycast */
|
||||
if (hit_max == NULL) {
|
||||
hit_max = hit_min;
|
||||
}
|
||||
}
|
||||
|
||||
static void peelEditMeshRayCast_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
|
||||
{
|
||||
struct PeelEditMeshRayCast_Data *data = userdata;
|
||||
mid_v3_v3v3(r_loc, hit_min->co, hit_max->co);
|
||||
|
||||
data->bvhdata.raycast_callback(&data->bvhdata, index, ray, hit);
|
||||
|
||||
if (hit->index != -1) {
|
||||
/* get all values in worldspace */
|
||||
float location[3], normal[3];
|
||||
float depth;
|
||||
|
||||
/* worldspace location */
|
||||
mul_v3_m4v3(location, (float(*)[4])data->obmat, hit->co);
|
||||
depth = len_v3v3(location, data->ray_start);
|
||||
|
||||
/* worldspace normal */
|
||||
copy_v3_v3(normal, hit->no);
|
||||
mul_m3_v3((float(*)[3])data->timat, normal);
|
||||
normalize_v3(normal);
|
||||
|
||||
addDepthPeel(data->depth_peels, depth, location, normal, data->ob);
|
||||
}
|
||||
if (r_thickness) {
|
||||
*r_thickness = hit_max->depth - hit_min->depth;
|
||||
}
|
||||
|
||||
static bool peelDerivedMesh(
|
||||
Object *ob, DerivedMesh *dm, float obmat[4][4],
|
||||
const float ray_start[3], const float ray_normal[3], const float UNUSED(mval[2]),
|
||||
ListBase *depth_peels)
|
||||
{
|
||||
bool retval = false;
|
||||
int totvert = dm->getNumVerts(dm);
|
||||
/* XXX, is there a correct normal in this case ???, for now just z up */
|
||||
r_no[0] = 0.0;
|
||||
r_no[1] = 0.0;
|
||||
r_no[2] = 1.0;
|
||||
|
||||
if (totvert > 0) {
|
||||
const MLoopTri *looptri = dm->getLoopTriArray(dm);
|
||||
const int looptri_num = dm->getNumLoopTri(dm);
|
||||
float imat[4][4];
|
||||
float timat[3][3]; /* transpose inverse matrix for normals */
|
||||
float ray_start_local[3], ray_normal_local[3];
|
||||
bool test = true;
|
||||
|
||||
invert_m4_m4(imat, obmat);
|
||||
|
||||
transpose_m3_m4(timat, imat);
|
||||
|
||||
mul_v3_m4v3(ray_start_local, imat, ray_start);
|
||||
mul_v3_mat3_m4v3(ray_normal_local, imat, ray_normal);
|
||||
|
||||
/* If number of vert is more than an arbitrary limit,
|
||||
* test against boundbox first
|
||||
* */
|
||||
if (looptri_num > 16) {
|
||||
BoundBox *bb = BKE_object_boundbox_get(ob);
|
||||
|
||||
if (bb) {
|
||||
BoundBox bb_temp;
|
||||
|
||||
/* We cannot aford a bbox with some null dimension, which may happen in some cases...
|
||||
* Threshold is rather high, but seems to be needed to get good behavior, see T46099. */
|
||||
bb = BKE_boundbox_ensure_minimum_dimensions(bb, &bb_temp, 1e-1f);
|
||||
|
||||
test = BKE_boundbox_ray_hit_check(bb, ray_start_local, ray_normal_local, NULL);
|
||||
BLI_freelistN(&depths_peel);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (test == true) {
|
||||
struct PeelRayCast_Data data;
|
||||
|
||||
bvhtree_from_mesh_looptri(&data.bvhdata, dm, 0.0f, 4, 6);
|
||||
|
||||
if (data.bvhdata.tree != NULL) {
|
||||
data.ob = ob;
|
||||
data.obmat = (const float (*)[4])obmat;
|
||||
data.timat = (const float (*)[3])timat;
|
||||
data.ray_start = ray_start;
|
||||
data.looptri = looptri;
|
||||
data.polynors = dm->getPolyDataArray(dm, CD_NORMAL); /* can be NULL */
|
||||
data.depth_peels = depth_peels;
|
||||
|
||||
BLI_bvhtree_ray_cast_all(
|
||||
data.bvhdata.tree, ray_start_local, ray_normal_local, 0.0f, BVH_RAYCAST_DIST_MAX,
|
||||
peelRayCast_cb, &data);
|
||||
}
|
||||
|
||||
free_bvhtree_from_mesh(&data.bvhdata);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static bool peelEditMesh(
|
||||
Object *ob, BMEditMesh *em, float obmat[4][4],
|
||||
const float ray_start[3], const float ray_normal[3],
|
||||
ListBase *depth_peels)
|
||||
{
|
||||
bool retval = false;
|
||||
int totvert = em->bm->totvert;
|
||||
|
||||
if (totvert > 0) {
|
||||
float imat[4][4];
|
||||
float timat[3][3]; /* transpose inverse matrix for normals */
|
||||
float ray_start_local[3], ray_normal_local[3];
|
||||
bool test = true;
|
||||
|
||||
invert_m4_m4(imat, obmat);
|
||||
|
||||
transpose_m3_m4(timat, imat);
|
||||
|
||||
mul_v3_m4v3(ray_start_local, imat, ray_start);
|
||||
mul_v3_mat3_m4v3(ray_normal_local, imat, ray_normal);
|
||||
|
||||
if (test == true) {
|
||||
struct PeelEditMeshRayCast_Data data;
|
||||
|
||||
BLI_bitmap *looptri_mask = BLI_BITMAP_NEW(em->tottri, __func__);
|
||||
int looptri_num_active = BM_iter_mesh_bitmap_from_filter_tessface(
|
||||
em->bm, looptri_mask,
|
||||
BM_elem_cb_check_hflag_enabled_simple(BMFace *, (BM_ELEM_SELECT | BM_ELEM_HIDDEN)));
|
||||
|
||||
bvhtree_from_editmesh_looptri_ex(&data.bvhdata, em, looptri_mask, looptri_num_active, 0.0f, 4, 6);
|
||||
|
||||
MEM_freeN(looptri_mask);
|
||||
|
||||
if (data.bvhdata.tree != NULL) {
|
||||
data.ob = ob;
|
||||
data.obmat = (const float(*)[4])obmat;
|
||||
data.timat = (const float(*)[3])timat;
|
||||
data.ray_start = ray_start;
|
||||
data.depth_peels = depth_peels;
|
||||
|
||||
BLI_bvhtree_ray_cast_all(
|
||||
data.bvhdata.tree, ray_start_local, ray_normal_local, 0.0f, BVH_RAYCAST_DIST_MAX,
|
||||
peelEditMeshRayCast_cb, &data);
|
||||
}
|
||||
|
||||
free_bvhtree_from_editmesh(&data.bvhdata);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static bool peelObjects(
|
||||
Scene *scene, View3D *v3d, ARegion *ar, Object *obedit,
|
||||
const float mval[2], SnapSelect snap_select,
|
||||
ListBase *r_depth_peels)
|
||||
{
|
||||
Base *base;
|
||||
bool retval = false;
|
||||
float ray_start[3], ray_normal[3];
|
||||
|
||||
if (ED_view3d_win_to_ray(ar, v3d, mval, ray_start, ray_normal, true) == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (base = scene->base.first; base != NULL; base = base->next) {
|
||||
if (BASE_SELECTABLE(v3d, base)) {
|
||||
Object *ob = base->object;
|
||||
|
||||
if (ob->transflag & OB_DUPLI) {
|
||||
DupliObject *dupli_ob;
|
||||
ListBase *lb = object_duplilist(G.main->eval_ctx, scene, ob);
|
||||
|
||||
for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) {
|
||||
Object *dob = dupli_ob->ob;
|
||||
|
||||
if (dob->type == OB_MESH) {
|
||||
BMEditMesh *em;
|
||||
bool val;
|
||||
|
||||
if (dob != obedit) {
|
||||
DerivedMesh *dm;
|
||||
dm = mesh_get_derived_final(scene, dob, CD_MASK_BAREMESH);
|
||||
val = peelDerivedMesh(dob, dm, dob->obmat, ray_start, ray_normal, mval, r_depth_peels);
|
||||
|
||||
dm->release(dm);
|
||||
}
|
||||
else {
|
||||
em = BKE_editmesh_from_object(dob);
|
||||
val = peelEditMesh(dob, em, dob->obmat, ray_start, ray_normal, r_depth_peels);
|
||||
}
|
||||
|
||||
retval = retval || val;
|
||||
}
|
||||
}
|
||||
|
||||
free_object_duplilist(lb);
|
||||
}
|
||||
|
||||
if (ob->type == OB_MESH) {
|
||||
bool val = false;
|
||||
|
||||
if (ob != obedit && ((snap_select == SNAP_NOT_SELECTED && (base->flag & (SELECT | BA_WAS_SEL)) == 0) || ELEM(snap_select, SNAP_ALL, SNAP_NOT_OBEDIT))) {
|
||||
DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
|
||||
|
||||
val = peelDerivedMesh(ob, dm, ob->obmat, ray_start, ray_normal, mval, r_depth_peels);
|
||||
dm->release(dm);
|
||||
}
|
||||
else if (ob == obedit && snap_select != SNAP_NOT_OBEDIT) {
|
||||
BMEditMesh *em = BKE_editmesh_from_object(ob);
|
||||
DerivedMesh *dm = editbmesh_get_derived_cage(scene, obedit, em, CD_MASK_BAREMESH);
|
||||
|
||||
val = peelDerivedMesh(ob, dm, ob->obmat, ray_start, ray_normal, mval, r_depth_peels);
|
||||
dm->release(dm);
|
||||
}
|
||||
|
||||
retval = retval || val;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BLI_listbase_sort(r_depth_peels, cmpPeel);
|
||||
removeDoublesPeel(r_depth_peels);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool peelObjectsTransForm(
|
||||
TransInfo *t, const float mval[2], SnapSelect snap_select,
|
||||
ListBase *r_depth_peels)
|
||||
bool peelObjectsTransform(
|
||||
TransInfo *t,
|
||||
const float mval[2], SnapSelect snap_select, bool use_peel_object,
|
||||
/* return args */
|
||||
float r_loc[3], float r_no[3], float *r_thickness)
|
||||
{
|
||||
return peelObjects(t->scene, t->view, t->ar, t->obedit, mval, snap_select, r_depth_peels);
|
||||
}
|
||||
|
||||
bool peelObjectsContext(
|
||||
bContext *C, const float mval[2], SnapSelect snap_select,
|
||||
ListBase *r_depth_peels)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
View3D *v3d = sa->spacedata.first;
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
|
||||
return peelObjects(scene, v3d, ar, obedit, mval, snap_select, r_depth_peels);
|
||||
return peelObjectsSnapContext(
|
||||
t->tsnap.object_context,
|
||||
mval, snap_select, use_peel_object,
|
||||
r_loc, r_no, r_thickness);
|
||||
}
|
||||
|
||||
/******************** NODES ***********************************/
|
||||
|
@@ -34,6 +34,7 @@
|
||||
#include "BLI_memarena.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "DNA_armature_types.h"
|
||||
@@ -109,6 +110,111 @@ struct SnapObjectContext {
|
||||
|
||||
};
|
||||
|
||||
static int dm_looptri_to_poly_index(DerivedMesh *dm, const MLoopTri *lt);
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
/** \name Support for storing all depths, not just the first (raycast 'all')
|
||||
*
|
||||
* This uses a list of #SnapObjectHitDepth structs.
|
||||
*
|
||||
* \{ */
|
||||
|
||||
/* Store all ray-hits */
|
||||
struct RayCastAll_Data {
|
||||
void *bvhdata;
|
||||
|
||||
/* internal vars for adding depths */
|
||||
BVHTree_RayCastCallback raycast_callback;
|
||||
|
||||
const float(*obmat)[4];
|
||||
const float(*timat)[3];
|
||||
|
||||
float len_diff;
|
||||
float local_scale;
|
||||
|
||||
Object *ob;
|
||||
unsigned int ob_uuid;
|
||||
|
||||
/* DerivedMesh only */
|
||||
DerivedMesh *dm;
|
||||
const struct MLoopTri *dm_looptri;
|
||||
|
||||
/* output data */
|
||||
ListBase *hit_list;
|
||||
bool retval;
|
||||
};
|
||||
|
||||
static struct SnapObjectHitDepth *hit_depth_create(
|
||||
const float depth, const float co[3], const float no[3], int index,
|
||||
Object *ob, const float obmat[4][4], unsigned int ob_uuid)
|
||||
{
|
||||
struct SnapObjectHitDepth *hit = MEM_mallocN(sizeof(*hit), __func__);
|
||||
|
||||
hit->depth = depth;
|
||||
copy_v3_v3(hit->co, co);
|
||||
copy_v3_v3(hit->no, no);
|
||||
hit->index = index;
|
||||
|
||||
hit->ob = ob;
|
||||
copy_m4_m4(hit->obmat, (float(*)[4])obmat);
|
||||
hit->ob_uuid = ob_uuid;
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
||||
static int hit_depth_cmp(const void *arg1, const void *arg2)
|
||||
{
|
||||
const struct SnapObjectHitDepth *h1 = arg1;
|
||||
const struct SnapObjectHitDepth *h2 = arg2;
|
||||
int val = 0;
|
||||
|
||||
if (h1->depth < h2->depth) {
|
||||
val = -1;
|
||||
}
|
||||
else if (h1->depth > h2->depth) {
|
||||
val = 1;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void raycast_all_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
|
||||
{
|
||||
struct RayCastAll_Data *data = userdata;
|
||||
data->raycast_callback(data->bvhdata, index, ray, hit);
|
||||
if (hit->index != -1) {
|
||||
/* get all values in worldspace */
|
||||
float location[3], normal[3];
|
||||
float depth;
|
||||
|
||||
/* worldspace location */
|
||||
mul_v3_m4v3(location, (float(*)[4])data->obmat, hit->co);
|
||||
depth = (hit->dist + data->len_diff) / data->local_scale;
|
||||
|
||||
/* worldspace normal */
|
||||
copy_v3_v3(normal, hit->no);
|
||||
mul_m3_v3((float(*)[3])data->timat, normal);
|
||||
normalize_v3(normal);
|
||||
|
||||
/* currently unused, and causes issues when looptri's havn't been calculated.
|
||||
* since theres some overhead in ensuring this data is valid, it may need to be optional. */
|
||||
#if 0
|
||||
if (data->dm) {
|
||||
hit->index = dm_looptri_to_poly_index(data->dm, &data->dm_looptri[hit->index]);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct SnapObjectHitDepth *hit_item = hit_depth_create(
|
||||
depth, location, normal, hit->index,
|
||||
data->ob, data->obmat, data->ob_uuid);
|
||||
BLI_addtail(data->hit_list, hit_item);
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
@@ -572,8 +678,10 @@ static bool snapDerivedMesh(
|
||||
SnapObjectContext *sctx,
|
||||
Object *ob, DerivedMesh *dm, float obmat[4][4],
|
||||
const float mval[2], float *dist_px, const short snap_to, bool do_bb,
|
||||
const float ray_start[3], const float ray_normal[3], const float ray_origin[3], float *ray_depth,
|
||||
float r_loc[3], float r_no[3], int *r_index)
|
||||
const float ray_start[3], const float ray_normal[3], const float ray_origin[3],
|
||||
float *ray_depth, unsigned int ob_index,
|
||||
float r_loc[3], float r_no[3], int *r_index,
|
||||
ListBase *r_hit_list)
|
||||
{
|
||||
ARegion *ar = sctx->v3d_data.ar;
|
||||
bool retval = false;
|
||||
@@ -729,13 +837,36 @@ static bool snapDerivedMesh(
|
||||
switch (snap_to) {
|
||||
case SCE_SNAP_MODE_FACE:
|
||||
{
|
||||
if (r_hit_list) {
|
||||
struct RayCastAll_Data data;
|
||||
|
||||
data.bvhdata = treedata;
|
||||
data.raycast_callback = treedata->raycast_callback;
|
||||
data.obmat = obmat;
|
||||
data.timat = timat;
|
||||
data.len_diff = len_diff;
|
||||
data.local_scale = local_scale;
|
||||
data.ob = ob;
|
||||
data.ob_uuid = ob_index,
|
||||
data.dm = dm;
|
||||
data.hit_list = r_hit_list;
|
||||
data.retval = retval;
|
||||
|
||||
BLI_bvhtree_ray_cast_all(
|
||||
treedata->tree, ray_start_local, ray_normal_local, 0.0f,
|
||||
*ray_depth, raycast_all_cb, &data);
|
||||
|
||||
retval = data.retval;
|
||||
}
|
||||
else {
|
||||
BVHTreeRayHit hit;
|
||||
|
||||
hit.index = -1;
|
||||
hit.dist = local_depth;
|
||||
|
||||
if (treedata->tree &&
|
||||
BLI_bvhtree_ray_cast(treedata->tree, ray_start_local, ray_normal_local, 0.0f,
|
||||
BLI_bvhtree_ray_cast(
|
||||
treedata->tree, ray_start_local, ray_normal_local, 0.0f,
|
||||
&hit, treedata->raycast_callback, treedata) != -1)
|
||||
{
|
||||
hit.dist += len_diff;
|
||||
@@ -757,6 +888,7 @@ static bool snapDerivedMesh(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SCE_SNAP_MODE_VERTEX:
|
||||
@@ -814,8 +946,10 @@ static bool snapEditMesh(
|
||||
SnapObjectContext *sctx,
|
||||
Object *ob, BMEditMesh *em, float obmat[4][4],
|
||||
const float mval[2], float *dist_px, const short snap_to,
|
||||
const float ray_start[3], const float ray_normal[3], const float ray_origin[3], float *ray_depth,
|
||||
float r_loc[3], float r_no[3], int *r_index)
|
||||
const float ray_start[3], const float ray_normal[3], const float ray_origin[3],
|
||||
float *ray_depth, const unsigned int ob_index,
|
||||
float r_loc[3], float r_no[3], int *r_index,
|
||||
ListBase *r_hit_list)
|
||||
{
|
||||
ARegion *ar = sctx->v3d_data.ar;
|
||||
bool retval = false;
|
||||
@@ -961,6 +1095,28 @@ static bool snapEditMesh(
|
||||
switch (snap_to) {
|
||||
case SCE_SNAP_MODE_FACE:
|
||||
{
|
||||
if (r_hit_list) {
|
||||
struct RayCastAll_Data data;
|
||||
|
||||
data.bvhdata = treedata;
|
||||
data.raycast_callback = treedata->raycast_callback;
|
||||
data.obmat = obmat;
|
||||
data.timat = timat;
|
||||
data.len_diff = len_diff;
|
||||
data.local_scale = local_scale;
|
||||
data.ob = ob;
|
||||
data.ob_uuid = ob_index;
|
||||
data.dm = NULL;
|
||||
data.hit_list = r_hit_list;
|
||||
data.retval = retval;
|
||||
|
||||
BLI_bvhtree_ray_cast_all(
|
||||
treedata->tree, ray_start_local, ray_normal_local, 0.0f,
|
||||
*ray_depth, raycast_all_cb, &data);
|
||||
|
||||
retval = data.retval;
|
||||
}
|
||||
else {
|
||||
BVHTreeRayHit hit;
|
||||
|
||||
hit.index = -1;
|
||||
@@ -990,6 +1146,7 @@ static bool snapEditMesh(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SCE_SNAP_MODE_VERTEX:
|
||||
@@ -1050,11 +1207,13 @@ static bool snapEditMesh(
|
||||
static bool snapObject(
|
||||
SnapObjectContext *sctx,
|
||||
Object *ob, float obmat[4][4], bool use_obedit, const short snap_to,
|
||||
const float mval[2], float *dist_px,
|
||||
const float ray_start[3], const float ray_normal[3], const float ray_origin[3], float *ray_depth,
|
||||
const float mval[2], float *dist_px, const unsigned int ob_index,
|
||||
const float ray_start[3], const float ray_normal[3], const float ray_origin[3],
|
||||
float *ray_depth,
|
||||
/* return args */
|
||||
float r_loc[3], float r_no[3], int *r_index,
|
||||
Object **r_ob, float r_obmat[4][4])
|
||||
Object **r_ob, float r_obmat[4][4],
|
||||
ListBase *r_hit_list)
|
||||
{
|
||||
ARegion *ar = sctx->v3d_data.ar;
|
||||
bool retval = false;
|
||||
@@ -1066,8 +1225,10 @@ static bool snapObject(
|
||||
em = BKE_editmesh_from_object(ob);
|
||||
retval = snapEditMesh(
|
||||
sctx, ob, em, obmat, mval, dist_px, snap_to,
|
||||
ray_start, ray_normal, ray_origin, ray_depth,
|
||||
r_loc, r_no, r_index);
|
||||
ray_start, ray_normal, ray_origin,
|
||||
ray_depth, ob_index,
|
||||
r_loc, r_no, r_index,
|
||||
r_hit_list);
|
||||
}
|
||||
else {
|
||||
/* in this case we want the mesh from the editmesh, avoids stale data. see: T45978.
|
||||
@@ -1082,8 +1243,9 @@ static bool snapObject(
|
||||
}
|
||||
retval = snapDerivedMesh(
|
||||
sctx, ob, dm, obmat, mval, dist_px, snap_to, true,
|
||||
ray_start, ray_normal, ray_origin, ray_depth,
|
||||
r_loc, r_no, r_index);
|
||||
ray_start, ray_normal, ray_origin,
|
||||
ray_depth, ob_index,
|
||||
r_loc, r_no, r_index, r_hit_list);
|
||||
|
||||
dm->release(dm);
|
||||
}
|
||||
@@ -1132,19 +1294,22 @@ static bool snapObjectsRay(
|
||||
const float ray_start[3], const float ray_normal[3], const float ray_origin[3], float *ray_depth,
|
||||
/* return args */
|
||||
float r_loc[3], float r_no[3], int *r_index,
|
||||
Object **r_ob, float r_obmat[4][4])
|
||||
Object **r_ob, float r_obmat[4][4],
|
||||
ListBase *r_hit_list)
|
||||
{
|
||||
Base *base;
|
||||
bool retval = false;
|
||||
bool snap_obedit_first = snap_select == SNAP_ALL && obedit;
|
||||
unsigned int ob_index = 0;
|
||||
|
||||
if (snap_select == SNAP_ALL && obedit) {
|
||||
if (snap_obedit_first) {
|
||||
Object *ob = obedit;
|
||||
|
||||
retval |= snapObject(
|
||||
sctx, ob, ob->obmat, true, snap_to,
|
||||
mval, dist_px,
|
||||
mval, dist_px, ob_index++,
|
||||
ray_start, ray_normal, ray_origin, ray_depth,
|
||||
r_loc, r_no, r_index, r_ob, r_obmat);
|
||||
r_loc, r_no, r_index, r_ob, r_obmat, r_hit_list);
|
||||
}
|
||||
|
||||
/* Need an exception for particle edit because the base is flagged with BA_HAS_RECALC_DATA
|
||||
@@ -1157,9 +1322,9 @@ static bool snapObjectsRay(
|
||||
Object *ob = base->object;
|
||||
retval |= snapObject(
|
||||
sctx, ob, ob->obmat, false, snap_to,
|
||||
mval, dist_px,
|
||||
mval, dist_px, ob_index++,
|
||||
ray_start, ray_normal, ray_origin, ray_depth,
|
||||
r_loc, r_no, r_index, r_ob, r_obmat);
|
||||
r_loc, r_no, r_index, r_ob, r_obmat, r_hit_list);
|
||||
}
|
||||
|
||||
for (base = sctx->scene->base.first; base != NULL; base = base->next) {
|
||||
@@ -1173,12 +1338,6 @@ static bool snapObjectsRay(
|
||||
Object *ob_snap = ob;
|
||||
bool use_obedit = false;
|
||||
|
||||
/* for linked objects, use the same object but a different matrix */
|
||||
if (obedit && ob->data == obedit->data) {
|
||||
use_obedit = true;
|
||||
ob_snap = obedit;
|
||||
}
|
||||
|
||||
if (ob->transflag & OB_DUPLI) {
|
||||
DupliObject *dupli_ob;
|
||||
ListBase *lb = object_duplilist(sctx->bmain->eval_ctx, sctx->scene, ob);
|
||||
@@ -1189,19 +1348,33 @@ static bool snapObjectsRay(
|
||||
|
||||
retval |= snapObject(
|
||||
sctx, dupli_snap, dupli_ob->mat, use_obedit_dupli, snap_to,
|
||||
mval, dist_px,
|
||||
mval, dist_px, ob_index++,
|
||||
ray_start, ray_normal, ray_origin, ray_depth,
|
||||
r_loc, r_no, r_index, r_ob, r_obmat);
|
||||
r_loc, r_no, r_index, r_ob, r_obmat, r_hit_list);
|
||||
}
|
||||
|
||||
free_object_duplilist(lb);
|
||||
}
|
||||
|
||||
if (obedit) {
|
||||
if ((ob == obedit) &&
|
||||
(snap_obedit_first || (snap_select == SNAP_NOT_OBEDIT)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ob->data == obedit->data) {
|
||||
/* for linked objects, use the same object but a different matrix */
|
||||
use_obedit = true;
|
||||
ob_snap = obedit;
|
||||
}
|
||||
}
|
||||
|
||||
retval |= snapObject(
|
||||
sctx, ob_snap, ob->obmat, use_obedit, snap_to,
|
||||
mval, dist_px,
|
||||
mval, dist_px, ob_index++,
|
||||
ray_start, ray_normal, ray_origin, ray_depth,
|
||||
r_loc, r_no, r_index, r_ob, r_obmat);
|
||||
r_loc, r_no, r_index, r_ob, r_obmat, r_hit_list);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1315,7 +1488,53 @@ bool ED_transform_snap_object_project_ray_ex(
|
||||
base_act, obedit,
|
||||
ray_start, ray_normal, ray_start, ray_depth,
|
||||
r_loc, r_no, r_index,
|
||||
r_ob, r_obmat);
|
||||
r_ob, r_obmat, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill in a list of all hits.
|
||||
*
|
||||
* \param ray_depth: Only depths in this range are considered, -1.0 for maximum.
|
||||
* \param sort: Optionally sort the hits by depth.
|
||||
* \param r_hit_list: List of #SnapObjectHitDepth (caller must free).
|
||||
*/
|
||||
bool ED_transform_snap_object_project_ray_all(
|
||||
SnapObjectContext *sctx,
|
||||
const struct SnapObjectParams *params,
|
||||
const float ray_start[3], const float ray_normal[3],
|
||||
float ray_depth, bool sort,
|
||||
ListBase *r_hit_list)
|
||||
{
|
||||
Base *base_act = params->use_object_active ? sctx->scene->basact : NULL;
|
||||
Object *obedit = params->use_object_edit ? sctx->scene->obedit : NULL;
|
||||
|
||||
if (ray_depth == -1.0f) {
|
||||
ray_depth = BVH_RAYCAST_DIST_MAX;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
float ray_depth_prev = ray_depth;
|
||||
#endif
|
||||
|
||||
bool retval = snapObjectsRay(
|
||||
sctx,
|
||||
params->snap_select, params->snap_to,
|
||||
NULL, NULL,
|
||||
base_act, obedit,
|
||||
ray_start, ray_normal, ray_start, &ray_depth,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
r_hit_list);
|
||||
|
||||
/* meant to be readonly for 'all' hits, ensure it is */
|
||||
#ifdef DEBUG
|
||||
BLI_assert(ray_depth_prev == ray_depth);
|
||||
#endif
|
||||
|
||||
if (sort) {
|
||||
BLI_listbase_sort(r_hit_list, hit_depth_cmp);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1327,7 +1546,7 @@ bool ED_transform_snap_object_project_ray_ex(
|
||||
*/
|
||||
static bool transform_snap_context_project_ray_impl(
|
||||
SnapObjectContext *sctx,
|
||||
const float ray_start[3], const float ray_normal[3], float *ray_dist,
|
||||
const float ray_start[3], const float ray_normal[3], float *ray_depth,
|
||||
float r_co[3], float r_no[3])
|
||||
{
|
||||
bool ret;
|
||||
@@ -1340,7 +1559,7 @@ static bool transform_snap_context_project_ray_impl(
|
||||
.snap_to = SCE_SNAP_MODE_FACE,
|
||||
.use_object_edit = (sctx->scene->obedit != NULL),
|
||||
},
|
||||
ray_start, ray_normal, ray_dist,
|
||||
ray_start, ray_normal, ray_depth,
|
||||
r_co, r_no, NULL,
|
||||
NULL, NULL);
|
||||
|
||||
@@ -1349,13 +1568,13 @@ static bool transform_snap_context_project_ray_impl(
|
||||
|
||||
bool ED_transform_snap_object_project_ray(
|
||||
SnapObjectContext *sctx,
|
||||
const float ray_origin[3], const float ray_direction[3], float *ray_dist,
|
||||
const float ray_origin[3], const float ray_direction[3], float *ray_depth,
|
||||
float r_co[3], float r_no[3])
|
||||
{
|
||||
float ray_dist_fallback;
|
||||
if (ray_dist == NULL) {
|
||||
ray_dist_fallback = BVH_RAYCAST_DIST_MAX;
|
||||
ray_dist = &ray_dist_fallback;
|
||||
float ray_depth_fallback;
|
||||
if (ray_depth == NULL) {
|
||||
ray_depth_fallback = BVH_RAYCAST_DIST_MAX;
|
||||
ray_depth = &ray_depth_fallback;
|
||||
}
|
||||
|
||||
float no_fallback[3];
|
||||
@@ -1365,7 +1584,7 @@ bool ED_transform_snap_object_project_ray(
|
||||
|
||||
return transform_snap_context_project_ray_impl(
|
||||
sctx,
|
||||
ray_origin, ray_direction, ray_dist,
|
||||
ray_origin, ray_direction, ray_depth,
|
||||
r_co, r_no);
|
||||
}
|
||||
|
||||
@@ -1376,7 +1595,7 @@ static bool transform_snap_context_project_view3d_mixed_impl(
|
||||
bool use_depth,
|
||||
float r_co[3], float r_no[3])
|
||||
{
|
||||
float ray_dist = BVH_RAYCAST_DIST_MAX;
|
||||
float ray_depth = BVH_RAYCAST_DIST_MAX;
|
||||
bool is_hit = false;
|
||||
|
||||
float r_no_dummy[3];
|
||||
@@ -1394,7 +1613,7 @@ static bool transform_snap_context_project_view3d_mixed_impl(
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if ((params->snap_to_flag & (1 << i)) && (is_hit == false || use_depth)) {
|
||||
if (use_depth == false) {
|
||||
ray_dist = BVH_RAYCAST_DIST_MAX;
|
||||
ray_depth = BVH_RAYCAST_DIST_MAX;
|
||||
}
|
||||
|
||||
params_temp.snap_to = elem_type[i];
|
||||
@@ -1402,7 +1621,7 @@ static bool transform_snap_context_project_view3d_mixed_impl(
|
||||
if (ED_transform_snap_object_project_view3d(
|
||||
sctx,
|
||||
¶ms_temp,
|
||||
mval, dist_px, &ray_dist,
|
||||
mval, dist_px, &ray_depth,
|
||||
r_co, r_no))
|
||||
{
|
||||
is_hit = true;
|
||||
@@ -1470,7 +1689,7 @@ bool ED_transform_snap_object_project_view3d_ex(
|
||||
mval, dist_px,
|
||||
base_act, obedit,
|
||||
ray_start, ray_normal, ray_orgigin, ray_depth,
|
||||
r_loc, r_no, r_index, NULL, NULL);
|
||||
r_loc, r_no, r_index, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
bool ED_transform_snap_object_project_view3d(
|
||||
@@ -1488,4 +1707,32 @@ bool ED_transform_snap_object_project_view3d(
|
||||
r_loc, r_no, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* see: #ED_transform_snap_object_project_ray_all
|
||||
*/
|
||||
bool ED_transform_snap_object_project_all_view3d_ex(
|
||||
SnapObjectContext *sctx,
|
||||
const struct SnapObjectParams *params,
|
||||
const float mval[2],
|
||||
float ray_depth, bool sort,
|
||||
ListBase *r_hit_list)
|
||||
{
|
||||
float ray_start[3], ray_normal[3];
|
||||
|
||||
BLI_assert(params->snap_to == SCE_SNAP_MODE_FACE);
|
||||
|
||||
if (!ED_view3d_win_to_ray_ex(
|
||||
sctx->v3d_data.ar, sctx->v3d_data.v3d,
|
||||
mval, NULL, ray_normal, ray_start, true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ED_transform_snap_object_project_ray_all(
|
||||
sctx,
|
||||
params,
|
||||
ray_start, ray_normal, ray_depth, sort,
|
||||
r_hit_list);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
Reference in New Issue
Block a user