UI: Asset Shelf (Experimental Feature) #104831
|
@ -360,6 +360,7 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
|
|||
|
||||
info.has_nanovdb = true;
|
||||
info.has_light_tree = true;
|
||||
info.has_mnee = true;
|
||||
info.has_osl = true;
|
||||
info.has_guiding = true;
|
||||
info.has_profiling = true;
|
||||
|
@ -409,6 +410,7 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
|
|||
/* Accumulate device info. */
|
||||
info.has_nanovdb &= device.has_nanovdb;
|
||||
info.has_light_tree &= device.has_light_tree;
|
||||
info.has_mnee &= device.has_mnee;
|
||||
info.has_osl &= device.has_osl;
|
||||
info.has_guiding &= device.has_guiding;
|
||||
info.has_profiling &= device.has_profiling;
|
||||
|
|
|
@ -76,6 +76,7 @@ class DeviceInfo {
|
|||
bool display_device; /* GPU is used as a display device. */
|
||||
bool has_nanovdb; /* Support NanoVDB volumes. */
|
||||
bool has_light_tree; /* Support light tree. */
|
||||
bool has_mnee; /* Support MNEE. */
|
||||
bool has_osl; /* Support Open Shading Language. */
|
||||
bool has_guiding; /* Support path guiding. */
|
||||
bool has_profiling; /* Supports runtime collection of profiling info. */
|
||||
|
@ -98,6 +99,7 @@ class DeviceInfo {
|
|||
display_device = false;
|
||||
has_nanovdb = false;
|
||||
has_light_tree = true;
|
||||
has_mnee = true;
|
||||
has_osl = false;
|
||||
has_guiding = false;
|
||||
has_profiling = false;
|
||||
|
|
|
@ -156,6 +156,7 @@ void device_hip_info(vector<DeviceInfo> &devices)
|
|||
|
||||
info.has_nanovdb = true;
|
||||
info.has_light_tree = true;
|
||||
info.has_mnee = true;
|
||||
info.denoisers = 0;
|
||||
|
||||
info.has_gpu_queue = true;
|
||||
|
|
|
@ -60,6 +60,7 @@ void device_metal_info(vector<DeviceInfo> &devices)
|
|||
|
||||
info.has_nanovdb = vendor == METAL_GPU_APPLE;
|
||||
info.has_light_tree = vendor != METAL_GPU_AMD;
|
||||
info.has_mnee = vendor != METAL_GPU_AMD;
|
||||
|
||||
info.use_hardware_raytracing = vendor != METAL_GPU_INTEL;
|
||||
if (info.use_hardware_raytracing) {
|
||||
|
|
|
@ -85,11 +85,6 @@ CCL_NAMESPACE_BEGIN
|
|||
#define __VISIBILITY_FLAG__
|
||||
#define __VOLUME__
|
||||
|
||||
/* TODO: solve internal compiler perf issue and enable light tree on Metal/AMD. */
|
||||
#if defined(__KERNEL_METAL_AMD__)
|
||||
# undef __LIGHT_TREE__
|
||||
#endif
|
||||
|
||||
/* Device specific features */
|
||||
#ifdef WITH_OSL
|
||||
# define __OSL__
|
||||
|
@ -111,6 +106,13 @@ CCL_NAMESPACE_BEGIN
|
|||
# define __MNEE__
|
||||
#endif
|
||||
|
||||
#if defined(__KERNEL_METAL_AMD__)
|
||||
/* Disabled due to internal compiler perf issue and enable light tree on Metal/AMD. */
|
||||
# undef __LIGHT_TREE__
|
||||
/* Disabled due to compiler crash on Metal/AMD. */
|
||||
# undef __MNEE__
|
||||
#endif
|
||||
|
||||
/* Scene-based selective features compilation. */
|
||||
#ifdef __KERNEL_FEATURES__
|
||||
# if !(__KERNEL_FEATURES & KERNEL_FEATURE_OBJECT_MOTION)
|
||||
|
|
|
@ -819,7 +819,65 @@ static bool fcurve_can_use_simple_bezt_drawing(FCurve *fcu)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* helper func - draw one repeat of an F-Curve (using Bezier curve approximations) */
|
||||
static int calculate_bezt_draw_resolution(BezTriple *bezt,
|
||||
BezTriple *prevbezt,
|
||||
const int max_bez_resolution,
|
||||
const bool is_driver)
|
||||
{
|
||||
if (is_driver) {
|
||||
return max_bez_resolution;
|
||||
}
|
||||
|
||||
const int resolution = (int)(5.0f * len_v2v2(bezt->vec[1], prevbezt->vec[1]));
|
||||
|
||||
/* NOTE: higher values will crash */
|
||||
/* TODO: view scale should factor into this someday too... */
|
||||
return min_ii(resolution, max_bez_resolution);
|
||||
}
|
||||
|
||||
/** Draw a segment from \param prevbezt to \param bezt at the given \param resolution.
|
||||
* immBeginAtMost is expected to be called with enough space for this function to run.
|
||||
*/
|
||||
static void draw_bezt(BezTriple *bezt, BezTriple *prevbezt, int resolution, uint pos)
|
||||
{
|
||||
float prev_key[2], prev_handle[2], bez_handle[2], bez_key[2];
|
||||
float data[120];
|
||||
|
||||
if (resolution < 2) {
|
||||
prev_key[0] = prevbezt->vec[1][0];
|
||||
prev_key[1] = prevbezt->vec[1][1];
|
||||
immVertex2fv(pos, prev_key);
|
||||
return;
|
||||
}
|
||||
|
||||
prev_key[0] = prevbezt->vec[1][0];
|
||||
prev_key[1] = prevbezt->vec[1][1];
|
||||
prev_handle[0] = prevbezt->vec[2][0];
|
||||
prev_handle[1] = prevbezt->vec[2][1];
|
||||
|
||||
bez_handle[0] = bezt->vec[0][0];
|
||||
bez_handle[1] = bezt->vec[0][1];
|
||||
bez_key[0] = bezt->vec[1][0];
|
||||
bez_key[1] = bezt->vec[1][1];
|
||||
|
||||
BKE_fcurve_correct_bezpart(prev_key, prev_handle, bez_handle, bez_key);
|
||||
|
||||
BKE_curve_forward_diff_bezier(
|
||||
prev_key[0], prev_handle[0], bez_handle[0], bez_key[0], data, resolution, sizeof(float[3]));
|
||||
BKE_curve_forward_diff_bezier(prev_key[1],
|
||||
prev_handle[1],
|
||||
bez_handle[1],
|
||||
bez_key[1],
|
||||
data + 1,
|
||||
resolution,
|
||||
sizeof(float[3]));
|
||||
|
||||
for (float *fp = data; resolution; resolution--, fp += 3) {
|
||||
immVertex2fv(pos, fp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper function - draw one repeat of an F-Curve (using Bezier curve approximations). */
|
||||
static void draw_fcurve_curve_bezts(
|
||||
bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, uint pos, const bool draw_extrapolation)
|
||||
{
|
||||
|
@ -827,178 +885,136 @@ static void draw_fcurve_curve_bezts(
|
|||
return;
|
||||
}
|
||||
|
||||
BezTriple *prevbezt = fcu->bezt;
|
||||
BezTriple *bezt = prevbezt + 1;
|
||||
float v1[2], v2[2], v3[2], v4[2];
|
||||
float *fp, data[120];
|
||||
float fac = 0.0f;
|
||||
int b = fcu->totvert - 1;
|
||||
int resol;
|
||||
float unit_scale, offset;
|
||||
short mapping_flag = ANIM_get_normalization_flags(ac);
|
||||
|
||||
/* apply unit mapping */
|
||||
/* Apply unit mapping. */
|
||||
GPU_matrix_push();
|
||||
unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
|
||||
float offset;
|
||||
short mapping_flag = ANIM_get_normalization_flags(ac);
|
||||
const float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
|
||||
GPU_matrix_scale_2f(1.0f, unit_scale);
|
||||
GPU_matrix_translate_2f(0.0f, offset);
|
||||
|
||||
/* For now, this assumes the worst case scenario, where all the keyframes have
|
||||
* bezier interpolation, and are drawn at full res.
|
||||
* This is tricky to optimize, but maybe can be improved at some point... */
|
||||
immBeginAtMost(GPU_PRIM_LINE_STRIP, (b * 32 + 3));
|
||||
int b = fcu->totvert - 1;
|
||||
const int max_bezt_resolution = 32;
|
||||
immBeginAtMost(GPU_PRIM_LINE_STRIP, (b * max_bezt_resolution + 3));
|
||||
|
||||
/* extrapolate to left? */
|
||||
BezTriple *prevbezt = fcu->bezt;
|
||||
BezTriple *bezt = prevbezt + 1;
|
||||
|
||||
float vertex_position[2];
|
||||
float fac = 0.0f;
|
||||
|
||||
/* Extrapolate to the left? */
|
||||
if (draw_extrapolation && prevbezt->vec[1][0] > v2d->cur.xmin) {
|
||||
/* left-side of view comes before first keyframe, so need to extend as not cyclic */
|
||||
v1[0] = v2d->cur.xmin;
|
||||
vertex_position[0] = v2d->cur.xmin;
|
||||
|
||||
/* y-value depends on the interpolation */
|
||||
if ((fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) || (prevbezt->ipo == BEZT_IPO_CONST) ||
|
||||
(prevbezt->ipo == BEZT_IPO_LIN && fcu->totvert == 1))
|
||||
{
|
||||
/* just extend across the first keyframe's value */
|
||||
v1[1] = prevbezt->vec[1][1];
|
||||
vertex_position[1] = prevbezt->vec[1][1];
|
||||
}
|
||||
else if (prevbezt->ipo == BEZT_IPO_LIN) {
|
||||
/* extrapolate linear doesn't use the handle, use the next points center instead */
|
||||
fac = (prevbezt->vec[1][0] - bezt->vec[1][0]) / (prevbezt->vec[1][0] - v1[0]);
|
||||
fac = (prevbezt->vec[1][0] - bezt->vec[1][0]) / (prevbezt->vec[1][0] - vertex_position[0]);
|
||||
if (fac) {
|
||||
fac = 1.0f / fac;
|
||||
}
|
||||
v1[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[1][1] - bezt->vec[1][1]);
|
||||
vertex_position[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[1][1] - bezt->vec[1][1]);
|
||||
}
|
||||
else {
|
||||
/* based on angle of handle 1 (relative to keyframe) */
|
||||
fac = (prevbezt->vec[0][0] - prevbezt->vec[1][0]) / (prevbezt->vec[1][0] - v1[0]);
|
||||
fac = (prevbezt->vec[0][0] - prevbezt->vec[1][0]) /
|
||||
(prevbezt->vec[1][0] - vertex_position[0]);
|
||||
if (fac) {
|
||||
fac = 1.0f / fac;
|
||||
}
|
||||
v1[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[0][1] - prevbezt->vec[1][1]);
|
||||
vertex_position[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[0][1] - prevbezt->vec[1][1]);
|
||||
}
|
||||
|
||||
immVertex2fv(pos, v1);
|
||||
immVertex2fv(pos, vertex_position);
|
||||
}
|
||||
|
||||
/* if only one keyframe, add it now */
|
||||
/* If only one keyframe, add it now. */
|
||||
if (fcu->totvert == 1) {
|
||||
v1[0] = prevbezt->vec[1][0];
|
||||
v1[1] = prevbezt->vec[1][1];
|
||||
immVertex2fv(pos, v1);
|
||||
vertex_position[0] = prevbezt->vec[1][0];
|
||||
vertex_position[1] = prevbezt->vec[1][1];
|
||||
immVertex2fv(pos, vertex_position);
|
||||
}
|
||||
|
||||
/* draw curve between first and last keyframe (if there are enough to do so) */
|
||||
/* Draw curve between first and last keyframe (if there are enough to do so). */
|
||||
/* TODO: optimize this to not have to calc stuff out of view too? */
|
||||
while (b--) {
|
||||
if (prevbezt->ipo == BEZT_IPO_CONST) {
|
||||
/* Constant-Interpolation: draw segment between previous keyframe and next,
|
||||
* but holding same value */
|
||||
v1[0] = prevbezt->vec[1][0];
|
||||
v1[1] = prevbezt->vec[1][1];
|
||||
immVertex2fv(pos, v1);
|
||||
vertex_position[0] = prevbezt->vec[1][0];
|
||||
vertex_position[1] = prevbezt->vec[1][1];
|
||||
immVertex2fv(pos, vertex_position);
|
||||
|
||||
v1[0] = bezt->vec[1][0];
|
||||
v1[1] = prevbezt->vec[1][1];
|
||||
immVertex2fv(pos, v1);
|
||||
vertex_position[0] = bezt->vec[1][0];
|
||||
vertex_position[1] = prevbezt->vec[1][1];
|
||||
immVertex2fv(pos, vertex_position);
|
||||
}
|
||||
else if (prevbezt->ipo == BEZT_IPO_LIN) {
|
||||
/* Linear interpolation: just add one point (which should add a new line segment) */
|
||||
v1[0] = prevbezt->vec[1][0];
|
||||
v1[1] = prevbezt->vec[1][1];
|
||||
immVertex2fv(pos, v1);
|
||||
vertex_position[0] = prevbezt->vec[1][0];
|
||||
vertex_position[1] = prevbezt->vec[1][1];
|
||||
immVertex2fv(pos, vertex_position);
|
||||
}
|
||||
else if (prevbezt->ipo == BEZT_IPO_BEZ) {
|
||||
/* Bezier-Interpolation: draw curve as series of segments between keyframes
|
||||
* - resol determines number of points to sample in between keyframes
|
||||
*/
|
||||
|
||||
/* resol depends on distance between points
|
||||
* (not just horizontal) OR is a fixed high res */
|
||||
/* TODO: view scale should factor into this someday too... */
|
||||
if (fcu->driver) {
|
||||
resol = 32;
|
||||
}
|
||||
else {
|
||||
resol = (int)(5.0f * len_v2v2(bezt->vec[1], prevbezt->vec[1]));
|
||||
}
|
||||
|
||||
if (resol < 2) {
|
||||
/* only draw one */
|
||||
v1[0] = prevbezt->vec[1][0];
|
||||
v1[1] = prevbezt->vec[1][1];
|
||||
immVertex2fv(pos, v1);
|
||||
}
|
||||
else {
|
||||
/* clamp resolution to max of 32 */
|
||||
/* NOTE: higher values will crash */
|
||||
if (resol > 32) {
|
||||
resol = 32;
|
||||
}
|
||||
|
||||
v1[0] = prevbezt->vec[1][0];
|
||||
v1[1] = prevbezt->vec[1][1];
|
||||
v2[0] = prevbezt->vec[2][0];
|
||||
v2[1] = prevbezt->vec[2][1];
|
||||
|
||||
v3[0] = bezt->vec[0][0];
|
||||
v3[1] = bezt->vec[0][1];
|
||||
v4[0] = bezt->vec[1][0];
|
||||
v4[1] = bezt->vec[1][1];
|
||||
|
||||
BKE_fcurve_correct_bezpart(v1, v2, v3, v4);
|
||||
|
||||
BKE_curve_forward_diff_bezier(v1[0], v2[0], v3[0], v4[0], data, resol, sizeof(float[3]));
|
||||
BKE_curve_forward_diff_bezier(
|
||||
v1[1], v2[1], v3[1], v4[1], data + 1, resol, sizeof(float[3]));
|
||||
|
||||
for (fp = data; resol; resol--, fp += 3) {
|
||||
immVertex2fv(pos, fp);
|
||||
}
|
||||
}
|
||||
int resolution = calculate_bezt_draw_resolution(
|
||||
bezt, prevbezt, max_bezt_resolution, fcu->driver != NULL);
|
||||
draw_bezt(bezt, prevbezt, resolution, pos);
|
||||
}
|
||||
|
||||
/* get next pointers */
|
||||
/* Get next pointers. */
|
||||
prevbezt = bezt;
|
||||
bezt++;
|
||||
|
||||
/* last point? */
|
||||
/* Last point? */
|
||||
if (b == 0) {
|
||||
v1[0] = prevbezt->vec[1][0];
|
||||
v1[1] = prevbezt->vec[1][1];
|
||||
immVertex2fv(pos, v1);
|
||||
vertex_position[0] = prevbezt->vec[1][0];
|
||||
vertex_position[1] = prevbezt->vec[1][1];
|
||||
immVertex2fv(pos, vertex_position);
|
||||
}
|
||||
}
|
||||
|
||||
/* extrapolate to right? (see code for left-extrapolation above too) */
|
||||
/* Extrapolate to the right? (see code for left-extrapolation above too) */
|
||||
if (draw_extrapolation && prevbezt->vec[1][0] < v2d->cur.xmax) {
|
||||
v1[0] = v2d->cur.xmax;
|
||||
vertex_position[0] = v2d->cur.xmax;
|
||||
|
||||
/* y-value depends on the interpolation */
|
||||
/* y-value depends on the interpolation. */
|
||||
if ((fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) || (fcu->flag & FCURVE_INT_VALUES) ||
|
||||
(prevbezt->ipo == BEZT_IPO_CONST) || (prevbezt->ipo == BEZT_IPO_LIN && fcu->totvert == 1))
|
||||
{
|
||||
/* based on last keyframe's value */
|
||||
v1[1] = prevbezt->vec[1][1];
|
||||
vertex_position[1] = prevbezt->vec[1][1];
|
||||
}
|
||||
else if (prevbezt->ipo == BEZT_IPO_LIN) {
|
||||
/* extrapolate linear doesn't use the handle, use the previous points center instead */
|
||||
/* Extrapolate linear doesn't use the handle, use the previous points center instead. */
|
||||
bezt = prevbezt - 1;
|
||||
fac = (prevbezt->vec[1][0] - bezt->vec[1][0]) / (prevbezt->vec[1][0] - v1[0]);
|
||||
fac = (prevbezt->vec[1][0] - bezt->vec[1][0]) / (prevbezt->vec[1][0] - vertex_position[0]);
|
||||
if (fac) {
|
||||
fac = 1.0f / fac;
|
||||
}
|
||||
v1[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[1][1] - bezt->vec[1][1]);
|
||||
vertex_position[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[1][1] - bezt->vec[1][1]);
|
||||
}
|
||||
else {
|
||||
/* based on angle of handle 1 (relative to keyframe) */
|
||||
fac = (prevbezt->vec[2][0] - prevbezt->vec[1][0]) / (prevbezt->vec[1][0] - v1[0]);
|
||||
/* Based on angle of handle 1 (relative to keyframe). */
|
||||
fac = (prevbezt->vec[2][0] - prevbezt->vec[1][0]) /
|
||||
(prevbezt->vec[1][0] - vertex_position[0]);
|
||||
if (fac) {
|
||||
fac = 1.0f / fac;
|
||||
}
|
||||
v1[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[2][1] - prevbezt->vec[1][1]);
|
||||
vertex_position[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[2][1] - prevbezt->vec[1][1]);
|
||||
}
|
||||
|
||||
immVertex2fv(pos, v1);
|
||||
immVertex2fv(pos, vertex_position);
|
||||
}
|
||||
|
||||
immEnd();
|
||||
|
|
|
@ -39,6 +39,7 @@ struct SnapSouceCustomData {
|
|||
void *customdata_mode_prev;
|
||||
|
||||
eSnapTargetOP target_operation_prev;
|
||||
eSnapMode snap_mode_confirm;
|
||||
|
||||
struct {
|
||||
void (*apply)(TransInfo *t, MouseInput *mi, const double mval[2], float output[3]);
|
||||
|
@ -76,6 +77,9 @@ static void snapsource_confirm(TransInfo *t)
|
|||
t->tsnap.status |= SNAP_SOURCE_FOUND;
|
||||
t->flag |= T_DRAW_SNAP_SOURCE;
|
||||
|
||||
struct SnapSouceCustomData *customdata = t->custom.mode.data;
|
||||
t->tsnap.mode = customdata->snap_mode_confirm;
|
||||
|
||||
int mval[2];
|
||||
#ifndef RESET_TRANSFORMATION
|
||||
if (true) {
|
||||
|
@ -183,10 +187,17 @@ void transform_mode_snap_source_init(TransInfo *t, wmOperator *UNUSED(op))
|
|||
t->tsnap.target_operation = SCE_SNAP_TARGET_ALL;
|
||||
t->tsnap.status &= ~SNAP_SOURCE_FOUND;
|
||||
|
||||
customdata->snap_mode_confirm = t->tsnap.mode;
|
||||
t->tsnap.mode &= ~(SCE_SNAP_MODE_EDGE_PERPENDICULAR);
|
||||
|
||||
if ((t->tsnap.mode & ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) == 0) {
|
||||
/* Initialize snap modes for geometry. */
|
||||
t->tsnap.mode &= ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID);
|
||||
t->tsnap.mode |= SCE_SNAP_MODE_GEOM;
|
||||
|
||||
if (!(customdata->snap_mode_confirm & SCE_SNAP_MODE_EDGE_PERPENDICULAR)) {
|
||||
customdata->snap_mode_confirm = t->tsnap.mode;
|
||||
}
|
||||
}
|
||||
|
||||
if (t->data_type == &TransConvertType_Mesh) {
|
||||
|
|
|
@ -1390,7 +1390,8 @@ eSnapMode snapObjectsTransform(
|
|||
snap_object_params.use_occlusion_test = true;
|
||||
snap_object_params.use_backface_culling = (t->tsnap.flag & SCE_SNAP_BACKFACE_CULLING) != 0;
|
||||
|
||||
float *prev_co = (t->tsnap.status & SNAP_SOURCE_FOUND) ? t->tsnap.snap_source : nullptr;
|
||||
float *prev_co = (t->tsnap.status & SNAP_SOURCE_FOUND) ? t->tsnap.snap_source : t->center_global;
|
||||
|
||||
return ED_transform_snap_object_project_view3d(t->tsnap.object_context,
|
||||
t->depsgraph,
|
||||
t->region,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,12 +10,6 @@
|
|||
|
||||
#define MAX_CLIPPLANE_LEN 3
|
||||
|
||||
enum eViewProj {
|
||||
VIEW_PROJ_NONE = -1,
|
||||
VIEW_PROJ_ORTHO = 0,
|
||||
VIEW_PROJ_PERSP = -1,
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Internal Data Types
|
||||
* \{ */
|
||||
|
@ -58,8 +52,6 @@ struct SnapData_EditMesh {
|
|||
struct SnapObjectContext {
|
||||
struct Scene *scene;
|
||||
|
||||
int flag;
|
||||
|
||||
blender::Map<const BMEditMesh *, std::unique_ptr<SnapData_EditMesh>> editmesh_caches;
|
||||
|
||||
/* Filter data, returns true to check this value */
|
||||
|
@ -77,14 +69,27 @@ struct SnapObjectContext {
|
|||
const ARegion *region;
|
||||
const View3D *v3d;
|
||||
|
||||
eSnapMode snap_to_flag;
|
||||
SnapObjectParams params;
|
||||
|
||||
float ray_start[3];
|
||||
float ray_dir[3];
|
||||
float mval[2];
|
||||
|
||||
float init_co[3];
|
||||
float curr_co[3];
|
||||
|
||||
float pmat[4][4]; /* perspective matrix */
|
||||
float win_size[2]; /* win x and y */
|
||||
enum eViewProj view_proj;
|
||||
float clip_plane[MAX_CLIPPLANE_LEN][4];
|
||||
short clip_plane_len;
|
||||
eSnapMode snap_to_flag;
|
||||
int clip_plane_len;
|
||||
|
||||
/* read/write */
|
||||
uint object_index;
|
||||
|
||||
bool is_persp;
|
||||
bool has_occlusion_plane; /* Ignore plane of occlusion in curves. */
|
||||
bool use_occlusion_test_edit;
|
||||
} runtime;
|
||||
|
||||
/* Output. */
|
||||
|
@ -104,7 +109,8 @@ struct SnapObjectContext {
|
|||
/* Snapped data. */
|
||||
ID *data;
|
||||
|
||||
float dist_sq;
|
||||
float ray_depth_max;
|
||||
float dist_px_sq;
|
||||
|
||||
bool is_edit;
|
||||
} ret;
|
||||
|
@ -203,7 +209,6 @@ void cb_snap_edge(void *userdata,
|
|||
BVHTreeNearest *nearest);
|
||||
|
||||
bool nearest_world_tree(SnapObjectContext *sctx,
|
||||
const struct SnapObjectParams *params,
|
||||
BVHTree *tree,
|
||||
BVHTree_NearestPointCallback nearest_cb,
|
||||
void *treedata,
|
||||
|
@ -217,57 +222,20 @@ bool nearest_world_tree(SnapObjectContext *sctx,
|
|||
|
||||
/* transform_snap_object_editmesh.cc */
|
||||
|
||||
bool raycastEditMesh(SnapObjectContext *sctx,
|
||||
const struct SnapObjectParams *params,
|
||||
const float ray_start[3],
|
||||
const float ray_dir[3],
|
||||
Object *ob_eval,
|
||||
BMEditMesh *em,
|
||||
const float obmat[4][4],
|
||||
const uint ob_index,
|
||||
/* read/write args */
|
||||
float *ray_depth,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index,
|
||||
ListBase *r_hit_list);
|
||||
eSnapMode snap_object_editmesh(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
ID *id,
|
||||
const float obmat[4][4],
|
||||
eSnapMode snap_to_flag,
|
||||
bool use_hide);
|
||||
|
||||
eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
BMEditMesh *em,
|
||||
Object *ob_eval,
|
||||
ID *id,
|
||||
const float obmat[4][4],
|
||||
float clip_planes_local[MAX_CLIPPLANE_LEN][4],
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index);
|
||||
|
||||
eSnapMode snapEditMesh(struct SnapObjectContext *sctx,
|
||||
const struct SnapObjectParams *params,
|
||||
struct Object *ob_eval,
|
||||
struct BMEditMesh *em,
|
||||
const float obmat[4][4],
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index);
|
||||
|
||||
bool nearest_world_editmesh(struct SnapObjectContext *sctx,
|
||||
const struct SnapObjectParams *params,
|
||||
struct Object *ob_eval,
|
||||
struct BMEditMesh *em,
|
||||
const float (*obmat)[4],
|
||||
const float init_co[3],
|
||||
const float curr_co[3],
|
||||
float *r_dist_sq,
|
||||
float *r_loc,
|
||||
float *r_no,
|
||||
int *r_index);
|
||||
eSnapMode snap_to_flag,
|
||||
int polygon,
|
||||
const float clip_planes_local[MAX_CLIPPLANE_LEN][4]);
|
||||
|
||||
void nearest2d_data_init_editmesh(struct BMEditMesh *em,
|
||||
bool is_persp,
|
||||
|
@ -276,60 +244,22 @@ void nearest2d_data_init_editmesh(struct BMEditMesh *em,
|
|||
|
||||
/* transform_snap_object_mesh.cc */
|
||||
|
||||
bool raycastMesh(const struct SnapObjectParams *params,
|
||||
const float ray_start[3],
|
||||
const float ray_dir[3],
|
||||
struct Object *ob_eval,
|
||||
const struct Mesh *me_eval,
|
||||
const float obmat[4][4],
|
||||
const uint ob_index,
|
||||
bool use_hide,
|
||||
/* read/write args */
|
||||
float *ray_depth,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index,
|
||||
struct ListBase *r_hit_list);
|
||||
eSnapMode snap_object_mesh(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
ID *id,
|
||||
const float obmat[4][4],
|
||||
eSnapMode snap_to_flag,
|
||||
bool use_hide);
|
||||
|
||||
bool nearest_world_mesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
const Mesh *me_eval,
|
||||
const float (*obmat)[4],
|
||||
bool use_hide,
|
||||
const float init_co[3],
|
||||
const float curr_co[3],
|
||||
float *r_dist_sq,
|
||||
float *r_loc,
|
||||
float *r_no,
|
||||
int *r_index);
|
||||
eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
ID *id,
|
||||
const float obmat[4][4],
|
||||
eSnapMode snap_to_flag,
|
||||
int polygon,
|
||||
const float clip_planes_local[MAX_CLIPPLANE_LEN][4]);
|
||||
|
||||
void nearest2d_data_init_mesh(const Mesh *mesh,
|
||||
bool is_persp,
|
||||
bool use_backface_culling,
|
||||
Nearest2dUserData *r_nearest2d);
|
||||
|
||||
eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
const Mesh *mesh,
|
||||
const float obmat[4][4],
|
||||
float clip_planes_local[MAX_CLIPPLANE_LEN][4],
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index);
|
||||
|
||||
eSnapMode snapMesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
Object *ob_eval,
|
||||
const Mesh *me_eval,
|
||||
const float obmat[4][4],
|
||||
bool use_hide,
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index);
|
||||
|
|
|
@ -66,9 +66,10 @@ static blender::bke::MeshRuntime *snap_object_data_editmesh_runtime_get(Object *
|
|||
|
||||
static SnapData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
BMEditMesh *em)
|
||||
BMEditMesh *em,
|
||||
const bool create)
|
||||
{
|
||||
SnapData_EditMesh *sod;
|
||||
SnapData_EditMesh *sod = nullptr;
|
||||
bool init = false;
|
||||
|
||||
if (std::unique_ptr<SnapData_EditMesh> *sod_p = sctx->editmesh_caches.lookup_ptr(em)) {
|
||||
|
@ -114,7 +115,7 @@ static SnapData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx,
|
|||
init = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (create) {
|
||||
std::unique_ptr<SnapData_EditMesh> sod_ptr = std::make_unique<SnapData_EditMesh>();
|
||||
sod = sod_ptr.get();
|
||||
sctx->editmesh_caches.add_new(em, std::move(sod_ptr));
|
||||
|
@ -122,6 +123,9 @@ static SnapData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx,
|
|||
}
|
||||
|
||||
if (init) {
|
||||
/* Operators only update the editmesh looptris of the original mesh. */
|
||||
BLI_assert(em == BKE_editmesh_from_object(DEG_get_original_object(ob_eval)));
|
||||
|
||||
sod->treedata_editmesh.em = em;
|
||||
sod->mesh_runtime = snap_object_data_editmesh_runtime_get(ob_eval);
|
||||
snap_editmesh_minmax(sctx, em->bm, sod->min, sod->max);
|
||||
|
@ -130,18 +134,13 @@ static SnapData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx,
|
|||
return sod;
|
||||
}
|
||||
|
||||
static BVHTreeFromEditMesh *snap_object_data_editmesh_treedata_get(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
static BVHTreeFromEditMesh *snap_object_data_editmesh_treedata_get(SnapData_EditMesh *sod,
|
||||
SnapObjectContext *sctx,
|
||||
BMEditMesh *em)
|
||||
{
|
||||
SnapData_EditMesh *sod = snap_object_data_editmesh_get(sctx, ob_eval, em);
|
||||
|
||||
BVHTreeFromEditMesh *treedata = &sod->treedata_editmesh;
|
||||
|
||||
if (treedata->tree == nullptr) {
|
||||
/* Operators only update the editmesh looptris of the original mesh. */
|
||||
BLI_assert(sod->treedata_editmesh.em ==
|
||||
BKE_editmesh_from_object(DEG_get_original_object(ob_eval)));
|
||||
em = sod->treedata_editmesh.em;
|
||||
|
||||
if (sctx->callbacks.edit_mesh.test_face_fn) {
|
||||
|
@ -178,6 +177,50 @@ static BVHTreeFromEditMesh *snap_object_data_editmesh_treedata_get(SnapObjectCon
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Snap Object Data
|
||||
* \{ */
|
||||
|
||||
static eSnapMode editmesh_snap_mode_supported(BMEditMesh *em)
|
||||
{
|
||||
eSnapMode snap_mode_supported = SCE_SNAP_MODE_NONE;
|
||||
if (em->bm->totface) {
|
||||
snap_mode_supported |= SCE_SNAP_MODE_FACE | SCE_SNAP_MODE_FACE_NEAREST;
|
||||
}
|
||||
if (em->bm->totedge) {
|
||||
snap_mode_supported |= SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT |
|
||||
SCE_SNAP_MODE_EDGE_PERPENDICULAR;
|
||||
}
|
||||
if (em->bm->totvert) {
|
||||
snap_mode_supported |= SCE_SNAP_MODE_VERTEX;
|
||||
}
|
||||
return snap_mode_supported;
|
||||
}
|
||||
|
||||
static SnapData_EditMesh *editmesh_snapdata_init(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
eSnapMode snap_to_flag)
|
||||
{
|
||||
BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
|
||||
if (em == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SnapData_EditMesh *sod = snap_object_data_editmesh_get(sctx, ob_eval, em, false);
|
||||
if (sod != nullptr) {
|
||||
return sod;
|
||||
}
|
||||
|
||||
eSnapMode snap_mode_used = snap_to_flag & editmesh_snap_mode_supported(em);
|
||||
if (snap_mode_used == SCE_SNAP_MODE_NONE) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return snap_object_data_editmesh_get(sctx, ob_eval, em, true);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Ray Cast Functions
|
||||
* \{ */
|
||||
|
@ -212,26 +255,21 @@ static void editmesh_looptri_raycast_backface_culling_cb(void *userdata,
|
|||
}
|
||||
}
|
||||
|
||||
bool raycastEditMesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
const float ray_start[3],
|
||||
const float ray_dir[3],
|
||||
Object *ob_eval,
|
||||
BMEditMesh *em,
|
||||
const float obmat[4][4],
|
||||
const uint ob_index,
|
||||
/* read/write args */
|
||||
float *ray_depth,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index,
|
||||
ListBase *r_hit_list)
|
||||
static bool raycastEditMesh(SnapData_EditMesh *sod,
|
||||
SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
BMEditMesh *em,
|
||||
const float obmat[4][4],
|
||||
const uint ob_index,
|
||||
/* read/write args */
|
||||
float *ray_depth,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index,
|
||||
ListBase *r_hit_list)
|
||||
{
|
||||
bool retval = false;
|
||||
if (em->bm->totface == 0) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
float imat[4][4];
|
||||
float ray_start_local[3], ray_normal_local[3];
|
||||
|
@ -239,8 +277,8 @@ bool raycastEditMesh(SnapObjectContext *sctx,
|
|||
|
||||
invert_m4_m4(imat, obmat);
|
||||
|
||||
copy_v3_v3(ray_start_local, ray_start);
|
||||
copy_v3_v3(ray_normal_local, ray_dir);
|
||||
copy_v3_v3(ray_start_local, sctx->runtime.ray_start);
|
||||
copy_v3_v3(ray_normal_local, sctx->runtime.ray_dir);
|
||||
|
||||
mul_m4_v3(imat, ray_start_local);
|
||||
mul_mat3_m4_v3(imat, ray_normal_local);
|
||||
|
@ -252,8 +290,6 @@ bool raycastEditMesh(SnapObjectContext *sctx,
|
|||
local_depth *= local_scale;
|
||||
}
|
||||
|
||||
SnapData_EditMesh *sod = snap_object_data_editmesh_get(sctx, ob_eval, em);
|
||||
|
||||
/* Test BoundBox */
|
||||
|
||||
/* was BKE_boundbox_ray_hit_check, see: cf6ca226fa58 */
|
||||
|
@ -275,7 +311,7 @@ bool raycastEditMesh(SnapObjectContext *sctx,
|
|||
len_diff = 0.0f;
|
||||
}
|
||||
|
||||
BVHTreeFromEditMesh *treedata = snap_object_data_editmesh_treedata_get(sctx, ob_eval, em);
|
||||
BVHTreeFromEditMesh *treedata = snap_object_data_editmesh_treedata_get(sod, sctx, em);
|
||||
if (treedata == nullptr) {
|
||||
return retval;
|
||||
}
|
||||
|
@ -317,7 +353,7 @@ bool raycastEditMesh(SnapObjectContext *sctx,
|
|||
ray_normal_local,
|
||||
0.0f,
|
||||
&hit,
|
||||
params->use_backface_culling ?
|
||||
sctx->runtime.params.use_backface_culling ?
|
||||
editmesh_looptri_raycast_backface_culling_cb :
|
||||
treedata->raycast_callback,
|
||||
treedata) != -1)
|
||||
|
@ -355,25 +391,23 @@ bool raycastEditMesh(SnapObjectContext *sctx,
|
|||
/** \name Surface Snap Functions
|
||||
* \{ */
|
||||
|
||||
bool nearest_world_editmesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
Object *ob_eval,
|
||||
BMEditMesh *em,
|
||||
const float (*obmat)[4],
|
||||
const float init_co[3],
|
||||
const float curr_co[3],
|
||||
float *r_dist_sq,
|
||||
float *r_loc,
|
||||
float *r_no,
|
||||
int *r_index)
|
||||
static bool nearest_world_editmesh(SnapData_EditMesh *sod,
|
||||
SnapObjectContext *sctx,
|
||||
BMEditMesh *em,
|
||||
const float (*obmat)[4],
|
||||
const float init_co[3],
|
||||
const float curr_co[3],
|
||||
float *r_dist_sq,
|
||||
float *r_loc,
|
||||
float *r_no,
|
||||
int *r_index)
|
||||
{
|
||||
BVHTreeFromEditMesh *treedata = snap_object_data_editmesh_treedata_get(sctx, ob_eval, em);
|
||||
BVHTreeFromEditMesh *treedata = snap_object_data_editmesh_treedata_get(sod, sctx, em);
|
||||
if (treedata == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return nearest_world_tree(sctx,
|
||||
params,
|
||||
treedata->tree,
|
||||
treedata->nearest_callback,
|
||||
treedata,
|
||||
|
@ -437,21 +471,22 @@ void nearest2d_data_init_editmesh(BMEditMesh *em,
|
|||
* \{ */
|
||||
|
||||
eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
BMEditMesh *em,
|
||||
Object *ob_eval,
|
||||
ID * /*id*/,
|
||||
const float obmat[4][4],
|
||||
float clip_planes_local[MAX_CLIPPLANE_LEN][4],
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index)
|
||||
eSnapMode snap_to_flag,
|
||||
int polygon,
|
||||
const float clip_planes_local[MAX_CLIPPLANE_LEN][4])
|
||||
{
|
||||
BLI_assert(sctx->editmesh_caches.lookup(em).get()->treedata_editmesh.em == em);
|
||||
|
||||
eSnapMode elem = SCE_SNAP_MODE_NONE;
|
||||
|
||||
SnapData_EditMesh *sod = editmesh_snapdata_init(sctx, ob_eval, snap_to_flag);
|
||||
if (sod == nullptr) {
|
||||
return elem;
|
||||
}
|
||||
|
||||
BMEditMesh *em = sod->treedata_editmesh.em;
|
||||
|
||||
float lpmat[4][4];
|
||||
mul_m4_m4m4(lpmat, sctx->runtime.pmat, obmat);
|
||||
|
||||
|
@ -461,18 +496,18 @@ eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
|
|||
|
||||
BVHTreeNearest nearest{};
|
||||
nearest.index = -1;
|
||||
nearest.dist_sq = square_f(*dist_px);
|
||||
nearest.dist_sq = sctx->ret.dist_px_sq;
|
||||
|
||||
Nearest2dUserData nearest2d;
|
||||
|
||||
nearest2d_data_init_editmesh(
|
||||
em, sctx->runtime.view_proj == VIEW_PROJ_PERSP, params->use_backface_culling, &nearest2d);
|
||||
em, sctx->runtime.is_persp, sctx->runtime.params.use_backface_culling, &nearest2d);
|
||||
|
||||
BM_mesh_elem_table_ensure(em->bm, BM_FACE);
|
||||
BMFace *f = BM_face_at_index(em->bm, sctx->ret.index);
|
||||
BMFace *f = BM_face_at_index(em->bm, polygon);
|
||||
BMLoop *l_iter, *l_first;
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
|
||||
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE) {
|
||||
if (snap_to_flag & SCE_SNAP_MODE_EDGE) {
|
||||
elem = SCE_SNAP_MODE_EDGE;
|
||||
BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_EDGE);
|
||||
BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE);
|
||||
|
@ -500,10 +535,10 @@ eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
|
|||
}
|
||||
|
||||
if (nearest.index != -1) {
|
||||
*dist_px = sqrtf(nearest.dist_sq);
|
||||
sctx->ret.dist_px_sq = nearest.dist_sq;
|
||||
|
||||
mul_m4_v3(obmat, nearest.co);
|
||||
copy_v3_v3(r_loc, nearest.co);
|
||||
copy_v3_v3(sctx->ret.loc, nearest.co);
|
||||
|
||||
{
|
||||
float imat[4][4];
|
||||
|
@ -511,58 +546,42 @@ eSnapMode snap_polygon_editmesh(SnapObjectContext *sctx,
|
|||
mul_transposed_mat3_m4_v3(imat, nearest.no);
|
||||
normalize_v3(nearest.no);
|
||||
|
||||
copy_v3_v3(r_no, nearest.no);
|
||||
copy_v3_v3(sctx->ret.no, nearest.no);
|
||||
}
|
||||
|
||||
*r_index = nearest.index;
|
||||
sctx->ret.index = nearest.index;
|
||||
return elem;
|
||||
}
|
||||
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
|
||||
eSnapMode snapEditMesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
Object *ob_eval,
|
||||
BMEditMesh *em,
|
||||
const float obmat[4][4],
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index)
|
||||
static eSnapMode snapEditMesh(SnapData_EditMesh *sod,
|
||||
SnapObjectContext *sctx,
|
||||
BMEditMesh *em,
|
||||
const float obmat[4][4],
|
||||
eSnapMode snap_to_flag,
|
||||
/* read/write args */
|
||||
float *dist_px_sq,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index)
|
||||
{
|
||||
BLI_assert(sctx->runtime.snap_to_flag != SCE_SNAP_MODE_FACE);
|
||||
|
||||
if ((sctx->runtime.snap_to_flag & ~SCE_SNAP_MODE_FACE) == SCE_SNAP_MODE_VERTEX) {
|
||||
if (em->bm->totvert == 0) {
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (em->bm->totedge == 0) {
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
BLI_assert(snap_to_flag != SCE_SNAP_MODE_FACE);
|
||||
float lpmat[4][4];
|
||||
mul_m4_m4m4(lpmat, sctx->runtime.pmat, obmat);
|
||||
|
||||
float dist_px_sq = square_f(*dist_px);
|
||||
|
||||
SnapData_EditMesh *sod = snap_object_data_editmesh_get(sctx, ob_eval, em);
|
||||
|
||||
/* Test BoundBox */
|
||||
|
||||
/* Was BKE_boundbox_ray_hit_check, see: cf6ca226fa58. */
|
||||
if (!snap_bound_box_check_dist(
|
||||
sod->min, sod->max, lpmat, sctx->runtime.win_size, sctx->runtime.mval, dist_px_sq))
|
||||
sod->min, sod->max, lpmat, sctx->runtime.win_size, sctx->runtime.mval, *dist_px_sq))
|
||||
{
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
|
||||
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX) {
|
||||
if (snap_to_flag & SCE_SNAP_MODE_VERTEX) {
|
||||
BVHTreeFromEditMesh treedata{};
|
||||
treedata.tree = sod->bvhtree[0];
|
||||
|
||||
|
@ -592,7 +611,7 @@ eSnapMode snapEditMesh(SnapObjectContext *sctx,
|
|||
}
|
||||
}
|
||||
|
||||
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE) {
|
||||
if (snap_to_flag & SCE_SNAP_MODE_EDGE) {
|
||||
BVHTreeFromEditMesh treedata{};
|
||||
treedata.tree = sod->bvhtree[1];
|
||||
|
||||
|
@ -624,13 +643,13 @@ eSnapMode snapEditMesh(SnapObjectContext *sctx,
|
|||
|
||||
Nearest2dUserData nearest2d;
|
||||
nearest2d_data_init_editmesh(sod->treedata_editmesh.em,
|
||||
sctx->runtime.view_proj == VIEW_PROJ_PERSP,
|
||||
params->use_backface_culling,
|
||||
sctx->runtime.is_persp,
|
||||
sctx->runtime.params.use_backface_culling,
|
||||
&nearest2d);
|
||||
|
||||
BVHTreeNearest nearest{};
|
||||
nearest.index = -1;
|
||||
nearest.dist_sq = dist_px_sq;
|
||||
nearest.dist_sq = *dist_px_sq;
|
||||
|
||||
eSnapMode elem = SCE_SNAP_MODE_VERTEX;
|
||||
|
||||
|
@ -641,7 +660,7 @@ eSnapMode snapEditMesh(SnapObjectContext *sctx,
|
|||
mul_v4_m4v4(clip_planes_local[i], tobmat, sctx->runtime.clip_plane[i]);
|
||||
}
|
||||
|
||||
if (sod->bvhtree[0] && (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX)) {
|
||||
if (sod->bvhtree[0] && (snap_to_flag & SCE_SNAP_MODE_VERTEX)) {
|
||||
BM_mesh_elem_table_ensure(em->bm, BM_VERT);
|
||||
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
|
||||
BLI_bvhtree_find_nearest_projected(sod->bvhtree[0],
|
||||
|
@ -655,7 +674,7 @@ eSnapMode snapEditMesh(SnapObjectContext *sctx,
|
|||
&nearest2d);
|
||||
}
|
||||
|
||||
if (sod->bvhtree[1] && (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE)) {
|
||||
if (sod->bvhtree[1] && (snap_to_flag & SCE_SNAP_MODE_EDGE)) {
|
||||
int last_index = nearest.index;
|
||||
nearest.index = -1;
|
||||
BM_mesh_elem_table_ensure(em->bm, BM_EDGE | BM_VERT);
|
||||
|
@ -679,7 +698,7 @@ eSnapMode snapEditMesh(SnapObjectContext *sctx,
|
|||
}
|
||||
|
||||
if (nearest.index != -1) {
|
||||
*dist_px = sqrtf(nearest.dist_sq);
|
||||
*dist_px_sq = nearest.dist_sq;
|
||||
|
||||
copy_v3_v3(r_loc, nearest.co);
|
||||
mul_m4_v3(obmat, r_loc);
|
||||
|
@ -702,3 +721,75 @@ eSnapMode snapEditMesh(SnapObjectContext *sctx,
|
|||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
eSnapMode snap_object_editmesh(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
ID * /*id*/,
|
||||
const float obmat[4][4],
|
||||
eSnapMode snap_to_flag,
|
||||
bool /*use_hide*/)
|
||||
{
|
||||
eSnapMode elem = SCE_SNAP_MODE_NONE;
|
||||
|
||||
SnapData_EditMesh *sod = editmesh_snapdata_init(sctx, ob_eval, snap_to_flag);
|
||||
if (sod == nullptr) {
|
||||
return elem;
|
||||
}
|
||||
|
||||
BMEditMesh *em = sod->treedata_editmesh.em;
|
||||
|
||||
eSnapMode snap_mode_used = snap_to_flag & editmesh_snap_mode_supported(em);
|
||||
if (snap_mode_used & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT |
|
||||
SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_VERTEX))
|
||||
{
|
||||
elem = snapEditMesh(sod,
|
||||
sctx,
|
||||
em,
|
||||
obmat,
|
||||
snap_to_flag,
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index);
|
||||
if (elem) {
|
||||
return elem;
|
||||
}
|
||||
}
|
||||
|
||||
if (snap_mode_used & SCE_SNAP_MODE_FACE) {
|
||||
if (raycastEditMesh(sod,
|
||||
sctx,
|
||||
ob_eval,
|
||||
em,
|
||||
obmat,
|
||||
sctx->runtime.object_index++,
|
||||
/* read/write args */
|
||||
&sctx->ret.ray_depth_max,
|
||||
/* return args */
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index,
|
||||
sctx->ret.hit_list))
|
||||
{
|
||||
return SCE_SNAP_MODE_FACE;
|
||||
}
|
||||
}
|
||||
|
||||
if (snap_mode_used & SCE_SNAP_MODE_FACE_NEAREST) {
|
||||
if (nearest_world_editmesh(sod,
|
||||
sctx,
|
||||
em,
|
||||
obmat,
|
||||
sctx->runtime.init_co,
|
||||
sctx->runtime.curr_co,
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index))
|
||||
{
|
||||
return SCE_SNAP_MODE_FACE_NEAREST;
|
||||
}
|
||||
}
|
||||
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
|
|
|
@ -82,21 +82,19 @@ static void mesh_looptri_raycast_backface_culling_cb(void *userdata,
|
|||
}
|
||||
}
|
||||
|
||||
bool raycastMesh(const SnapObjectParams *params,
|
||||
const float ray_start[3],
|
||||
const float ray_dir[3],
|
||||
Object *ob_eval,
|
||||
const Mesh *me_eval,
|
||||
const float obmat[4][4],
|
||||
const uint ob_index,
|
||||
bool use_hide,
|
||||
/* read/write args */
|
||||
float *ray_depth,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index,
|
||||
ListBase *r_hit_list)
|
||||
static bool raycastMesh(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
const Mesh *me_eval,
|
||||
const float obmat[4][4],
|
||||
const uint ob_index,
|
||||
bool use_hide,
|
||||
/* read/write args */
|
||||
float *ray_depth,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index,
|
||||
ListBase *r_hit_list)
|
||||
{
|
||||
bool retval = false;
|
||||
|
||||
|
@ -110,8 +108,8 @@ bool raycastMesh(const SnapObjectParams *params,
|
|||
|
||||
invert_m4_m4(imat, obmat);
|
||||
|
||||
copy_v3_v3(ray_start_local, ray_start);
|
||||
copy_v3_v3(ray_normal_local, ray_dir);
|
||||
copy_v3_v3(ray_start_local, sctx->runtime.ray_start);
|
||||
copy_v3_v3(ray_normal_local, sctx->runtime.ray_dir);
|
||||
|
||||
mul_m4_v3(imat, ray_start_local);
|
||||
mul_mat3_m4_v3(imat, ray_normal_local);
|
||||
|
@ -191,7 +189,7 @@ bool raycastMesh(const SnapObjectParams *params,
|
|||
ray_normal_local,
|
||||
0.0f,
|
||||
&hit,
|
||||
params->use_backface_culling ?
|
||||
sctx->runtime.params.use_backface_culling ?
|
||||
mesh_looptri_raycast_backface_culling_cb :
|
||||
treedata.raycast_callback,
|
||||
&treedata) != -1)
|
||||
|
@ -229,17 +227,16 @@ bool raycastMesh(const SnapObjectParams *params,
|
|||
/** \name Surface Snap Functions
|
||||
* \{ */
|
||||
|
||||
bool nearest_world_mesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
const Mesh *me_eval,
|
||||
const float (*obmat)[4],
|
||||
bool use_hide,
|
||||
const float init_co[3],
|
||||
const float curr_co[3],
|
||||
float *r_dist_sq,
|
||||
float *r_loc,
|
||||
float *r_no,
|
||||
int *r_index)
|
||||
static bool nearest_world_mesh(SnapObjectContext *sctx,
|
||||
const Mesh *me_eval,
|
||||
const float (*obmat)[4],
|
||||
bool use_hide,
|
||||
const float init_co[3],
|
||||
const float curr_co[3],
|
||||
float *r_dist_sq,
|
||||
float *r_loc,
|
||||
float *r_no,
|
||||
int *r_index)
|
||||
{
|
||||
BVHTreeFromMesh treedata;
|
||||
snap_object_data_mesh_get(me_eval, use_hide, &treedata);
|
||||
|
@ -248,7 +245,6 @@ bool nearest_world_mesh(SnapObjectContext *sctx,
|
|||
}
|
||||
|
||||
return nearest_world_tree(sctx,
|
||||
params,
|
||||
treedata.tree,
|
||||
treedata.nearest_callback,
|
||||
&treedata,
|
||||
|
@ -429,19 +425,17 @@ void nearest2d_data_init_mesh(const Mesh *mesh,
|
|||
* \{ */
|
||||
|
||||
eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
const Mesh *mesh,
|
||||
Object * /*ob_eval*/,
|
||||
ID *id,
|
||||
const float obmat[4][4],
|
||||
float clip_planes_local[MAX_CLIPPLANE_LEN][4],
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index)
|
||||
eSnapMode snap_to_flag,
|
||||
int polygon,
|
||||
const float clip_planes_local[MAX_CLIPPLANE_LEN][4])
|
||||
{
|
||||
eSnapMode elem = SCE_SNAP_MODE_NONE;
|
||||
|
||||
Mesh *mesh_eval = reinterpret_cast<Mesh *>(id);
|
||||
|
||||
float lpmat[4][4];
|
||||
mul_m4_m4m4(lpmat, sctx->runtime.pmat, obmat);
|
||||
|
||||
|
@ -451,15 +445,15 @@ eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
|
|||
|
||||
BVHTreeNearest nearest{};
|
||||
nearest.index = -1;
|
||||
nearest.dist_sq = square_f(*dist_px);
|
||||
nearest.dist_sq = sctx->ret.dist_px_sq;
|
||||
|
||||
Nearest2dUserData nearest2d;
|
||||
nearest2d_data_init_mesh(
|
||||
mesh, sctx->runtime.view_proj == VIEW_PROJ_PERSP, params->use_backface_culling, &nearest2d);
|
||||
mesh_eval, sctx->runtime.is_persp, sctx->runtime.params.use_backface_culling, &nearest2d);
|
||||
|
||||
const blender::IndexRange poly = mesh->polys()[sctx->ret.index];
|
||||
const blender::IndexRange poly = mesh_eval->polys()[polygon];
|
||||
|
||||
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE) {
|
||||
if (snap_to_flag & SCE_SNAP_MODE_EDGE) {
|
||||
elem = SCE_SNAP_MODE_EDGE;
|
||||
BLI_assert(nearest2d.edges != nullptr);
|
||||
const int *poly_edges = &nearest2d.corner_edges[poly.start()];
|
||||
|
@ -486,10 +480,10 @@ eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
|
|||
}
|
||||
|
||||
if (nearest.index != -1) {
|
||||
*dist_px = sqrtf(nearest.dist_sq);
|
||||
sctx->ret.dist_px_sq = sqrtf(nearest.dist_sq);
|
||||
|
||||
mul_m4_v3(obmat, nearest.co);
|
||||
copy_v3_v3(r_loc, nearest.co);
|
||||
copy_v3_v3(sctx->ret.loc, nearest.co);
|
||||
|
||||
{
|
||||
float imat[4][4];
|
||||
|
@ -497,28 +491,27 @@ eSnapMode snap_polygon_mesh(SnapObjectContext *sctx,
|
|||
mul_transposed_mat3_m4_v3(imat, nearest.no);
|
||||
normalize_v3(nearest.no);
|
||||
|
||||
copy_v3_v3(r_no, nearest.no);
|
||||
copy_v3_v3(sctx->ret.no, nearest.no);
|
||||
}
|
||||
|
||||
*r_index = nearest.index;
|
||||
sctx->ret.index = nearest.index;
|
||||
return elem;
|
||||
}
|
||||
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
|
||||
eSnapMode snapMesh(SnapObjectContext *sctx,
|
||||
const SnapObjectParams *params,
|
||||
Object *ob_eval,
|
||||
const Mesh *me_eval,
|
||||
const float obmat[4][4],
|
||||
bool use_hide,
|
||||
/* read/write args */
|
||||
float *dist_px,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index)
|
||||
static eSnapMode snapMesh(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
const Mesh *me_eval,
|
||||
const float obmat[4][4],
|
||||
bool use_hide,
|
||||
/* read/write args */
|
||||
float *dist_px_sq,
|
||||
/* return args */
|
||||
float r_loc[3],
|
||||
float r_no[3],
|
||||
int *r_index)
|
||||
{
|
||||
BLI_assert(sctx->runtime.snap_to_flag != SCE_SNAP_MODE_FACE);
|
||||
if (me_eval->totvert == 0) {
|
||||
|
@ -531,13 +524,15 @@ eSnapMode snapMesh(SnapObjectContext *sctx,
|
|||
float lpmat[4][4];
|
||||
mul_m4_m4m4(lpmat, sctx->runtime.pmat, obmat);
|
||||
|
||||
float dist_px_sq = square_f(*dist_px);
|
||||
|
||||
/* Test BoundBox */
|
||||
if (ob_eval->data == me_eval) {
|
||||
const BoundBox *bb = BKE_object_boundbox_get(ob_eval);
|
||||
if (!snap_bound_box_check_dist(
|
||||
bb->vec[0], bb->vec[6], lpmat, sctx->runtime.win_size, sctx->runtime.mval, dist_px_sq))
|
||||
if (!snap_bound_box_check_dist(bb->vec[0],
|
||||
bb->vec[6],
|
||||
lpmat,
|
||||
sctx->runtime.win_size,
|
||||
sctx->runtime.mval,
|
||||
*dist_px_sq))
|
||||
{
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
|
@ -555,14 +550,12 @@ eSnapMode snapMesh(SnapObjectContext *sctx,
|
|||
}
|
||||
|
||||
Nearest2dUserData nearest2d;
|
||||
nearest2d_data_init_mesh(me_eval,
|
||||
sctx->runtime.view_proj == VIEW_PROJ_PERSP,
|
||||
params->use_backface_culling,
|
||||
&nearest2d);
|
||||
nearest2d_data_init_mesh(
|
||||
me_eval, sctx->runtime.is_persp, sctx->runtime.params.use_backface_culling, &nearest2d);
|
||||
|
||||
BVHTreeNearest nearest{};
|
||||
nearest.index = -1;
|
||||
nearest.dist_sq = dist_px_sq;
|
||||
nearest.dist_sq = *dist_px_sq;
|
||||
|
||||
int last_index = nearest.index;
|
||||
eSnapMode elem = SCE_SNAP_MODE_VERTEX;
|
||||
|
@ -650,7 +643,7 @@ eSnapMode snapMesh(SnapObjectContext *sctx,
|
|||
}
|
||||
|
||||
if (nearest.index != -1) {
|
||||
*dist_px = sqrtf(nearest.dist_sq);
|
||||
*dist_px_sq = nearest.dist_sq;
|
||||
|
||||
copy_v3_v3(r_loc, nearest.co);
|
||||
mul_m4_v3(obmat, r_loc);
|
||||
|
@ -674,3 +667,86 @@ eSnapMode snapMesh(SnapObjectContext *sctx,
|
|||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
static eSnapMode mesh_snap_mode_supported(Mesh *mesh)
|
||||
{
|
||||
eSnapMode snap_mode_supported = SCE_SNAP_MODE_NONE;
|
||||
if (mesh->totpoly) {
|
||||
snap_mode_supported |= SCE_SNAP_MODE_FACE | SCE_SNAP_MODE_FACE_NEAREST;
|
||||
}
|
||||
if (mesh->totedge) {
|
||||
snap_mode_supported |= SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT |
|
||||
SCE_SNAP_MODE_EDGE_PERPENDICULAR;
|
||||
}
|
||||
if (mesh->totvert) {
|
||||
snap_mode_supported |= SCE_SNAP_MODE_VERTEX;
|
||||
}
|
||||
return snap_mode_supported;
|
||||
}
|
||||
|
||||
eSnapMode snap_object_mesh(SnapObjectContext *sctx,
|
||||
Object *ob_eval,
|
||||
ID *id,
|
||||
const float obmat[4][4],
|
||||
eSnapMode snap_to_flag,
|
||||
bool use_hide)
|
||||
{
|
||||
eSnapMode elem = SCE_SNAP_MODE_NONE;
|
||||
|
||||
Mesh *mesh_eval = reinterpret_cast<Mesh *>(id);
|
||||
|
||||
eSnapMode snap_mode_used = snap_to_flag & mesh_snap_mode_supported(mesh_eval);
|
||||
if (snap_mode_used & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_EDGE_MIDPOINT |
|
||||
SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_VERTEX))
|
||||
{
|
||||
elem = snapMesh(sctx,
|
||||
ob_eval,
|
||||
mesh_eval,
|
||||
obmat,
|
||||
use_hide,
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index);
|
||||
if (elem) {
|
||||
return elem;
|
||||
}
|
||||
}
|
||||
|
||||
if (snap_mode_used & SCE_SNAP_MODE_FACE) {
|
||||
if (raycastMesh(sctx,
|
||||
ob_eval,
|
||||
mesh_eval,
|
||||
obmat,
|
||||
sctx->runtime.object_index++,
|
||||
use_hide,
|
||||
/* read/write args */
|
||||
&sctx->ret.ray_depth_max,
|
||||
/* return args */
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index,
|
||||
sctx->ret.hit_list))
|
||||
{
|
||||
return SCE_SNAP_MODE_FACE;
|
||||
}
|
||||
}
|
||||
|
||||
if (snap_mode_used & SCE_SNAP_MODE_FACE_NEAREST) {
|
||||
if (nearest_world_mesh(sctx,
|
||||
mesh_eval,
|
||||
obmat,
|
||||
use_hide,
|
||||
sctx->runtime.init_co,
|
||||
sctx->runtime.curr_co,
|
||||
&sctx->ret.dist_px_sq,
|
||||
sctx->ret.loc,
|
||||
sctx->ret.no,
|
||||
&sctx->ret.index))
|
||||
{
|
||||
return SCE_SNAP_MODE_FACE_NEAREST;
|
||||
}
|
||||
}
|
||||
|
||||
return SCE_SNAP_MODE_NONE;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue