Merge branch 'master' into blender2.8
Conflicts: source/blender/editors/space_nla/nla_draw.c source/blender/editors/space_view3d/view3d_draw.c
This commit is contained in:
@@ -47,6 +47,8 @@ bool BLI_rcti_is_empty(const struct rcti *rect);
|
||||
bool BLI_rctf_is_empty(const struct rctf *rect);
|
||||
void BLI_rctf_init(struct rctf *rect, float xmin, float xmax, float ymin, float ymax);
|
||||
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax);
|
||||
void BLI_rctf_init_pt_size(struct rctf *rect, const float xy[2], float size);
|
||||
void BLI_rcti_init_pt_size(struct rcti *rect, const int xy[2], int size);
|
||||
void BLI_rcti_init_minmax(struct rcti *rect);
|
||||
void BLI_rctf_init_minmax(struct rctf *rect);
|
||||
void BLI_rcti_do_minmax_v(struct rcti *rect, const int xy[2]);
|
||||
|
||||
@@ -95,8 +95,6 @@ void BLI_task_pool_push_from_thread(TaskPool *pool, TaskRunFunction run,
|
||||
void BLI_task_pool_work_and_wait(TaskPool *pool);
|
||||
/* cancel all tasks, keep worker threads running */
|
||||
void BLI_task_pool_cancel(TaskPool *pool);
|
||||
/* stop all worker threads */
|
||||
void BLI_task_pool_stop(TaskPool *pool);
|
||||
|
||||
/* set number of threads allowed to be used by this pool */
|
||||
void BLI_pool_set_num_threads(TaskPool *pool, int num_threads);
|
||||
|
||||
@@ -351,6 +351,22 @@ void BLI_rcti_init(rcti *rect, int xmin, int xmax, int ymin, int ymax)
|
||||
}
|
||||
}
|
||||
|
||||
void BLI_rctf_init_pt_size(rctf *rect, const float xy[2], float size)
|
||||
{
|
||||
rect->xmin = xy[0] - size;
|
||||
rect->xmax = xy[0] + size;
|
||||
rect->ymin = xy[1] - size;
|
||||
rect->ymax = xy[1] + size;
|
||||
}
|
||||
|
||||
void BLI_rcti_init_pt_size(rcti *rect, const int xy[2], int size)
|
||||
{
|
||||
rect->xmin = xy[0] - size;
|
||||
rect->xmax = xy[0] + size;
|
||||
rect->ymin = xy[1] - size;
|
||||
rect->ymax = xy[1] + size;
|
||||
}
|
||||
|
||||
void BLI_rcti_init_minmax(rcti *rect)
|
||||
{
|
||||
rect->xmin = rect->ymin = INT_MAX;
|
||||
|
||||
@@ -180,9 +180,9 @@ BLI_INLINE TaskMemPool *get_task_mempool(TaskPool *pool, const int thread_id)
|
||||
|
||||
static Task *task_alloc(TaskPool *pool, const int thread_id)
|
||||
{
|
||||
assert(thread_id <= pool->scheduler->num_threads);
|
||||
BLI_assert(thread_id <= pool->scheduler->num_threads);
|
||||
if (thread_id != -1) {
|
||||
assert(thread_id >= 0);
|
||||
BLI_assert(thread_id >= 0);
|
||||
TaskMemPool *mem_pool = get_task_mempool(pool, thread_id);
|
||||
/* Try to re-use task memory from a thread local storage. */
|
||||
if (mem_pool->num_tasks > 0) {
|
||||
@@ -204,8 +204,8 @@ static Task *task_alloc(TaskPool *pool, const int thread_id)
|
||||
static void task_free(TaskPool *pool, Task *task, const int thread_id)
|
||||
{
|
||||
task_data_free(task, thread_id);
|
||||
assert(thread_id >= 0);
|
||||
assert(thread_id <= pool->scheduler->num_threads);
|
||||
BLI_assert(thread_id >= 0);
|
||||
BLI_assert(thread_id <= pool->scheduler->num_threads);
|
||||
TaskMemPool *mem_pool = get_task_mempool(pool, thread_id);
|
||||
if (mem_pool->num_tasks < MEMPOOL_SIZE - 1) {
|
||||
/* Successfully allowed the task to be re-used later. */
|
||||
@@ -357,8 +357,8 @@ TaskScheduler *BLI_task_scheduler_create(int num_threads)
|
||||
|
||||
/* Add background-only thread if needed. */
|
||||
if (num_threads == 0) {
|
||||
scheduler->background_thread_only = true;
|
||||
num_threads = 1;
|
||||
scheduler->background_thread_only = true;
|
||||
num_threads = 1;
|
||||
}
|
||||
|
||||
/* launch threads that will be waiting for work */
|
||||
@@ -565,7 +565,7 @@ TaskPool *BLI_task_pool_create_background(TaskScheduler *scheduler, void *userda
|
||||
|
||||
void BLI_task_pool_free(TaskPool *pool)
|
||||
{
|
||||
BLI_task_pool_stop(pool);
|
||||
BLI_task_pool_cancel(pool);
|
||||
|
||||
BLI_mutex_end(&pool->num_mutex);
|
||||
BLI_condition_end(&pool->num_cond);
|
||||
@@ -708,13 +708,6 @@ void BLI_task_pool_cancel(TaskPool *pool)
|
||||
pool->do_cancel = false;
|
||||
}
|
||||
|
||||
void BLI_task_pool_stop(TaskPool *pool)
|
||||
{
|
||||
task_scheduler_clear(pool->scheduler, pool);
|
||||
|
||||
BLI_assert(pool->num == 0);
|
||||
}
|
||||
|
||||
bool BLI_task_pool_canceled(TaskPool *pool)
|
||||
{
|
||||
return pool->do_cancel;
|
||||
|
||||
@@ -1598,6 +1598,17 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
|
||||
}
|
||||
} FOREACH_NODETREE_END
|
||||
}
|
||||
|
||||
if (!DNA_struct_elem_find(fd->filesdna, "SurfaceDeformModifierData", "float", "mat[4][4]")) {
|
||||
for (Object *ob = main->object.first; ob; ob = ob->id.next) {
|
||||
for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
|
||||
if (md->type == eModifierType_SurfaceDeform) {
|
||||
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
|
||||
unit_m4(smd->mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -980,7 +980,7 @@ bool BM_mesh_intersect(
|
||||
struct BMLoop *(*looptris)[3], const int looptris_tot,
|
||||
int (*test_fn)(BMFace *f, void *user_data), void *user_data,
|
||||
const bool use_self, const bool use_separate, const bool use_dissolve, const bool use_island_connect,
|
||||
const int boolean_mode,
|
||||
const bool use_edge_tag, const int boolean_mode,
|
||||
const float eps)
|
||||
{
|
||||
struct ISectState s;
|
||||
@@ -1516,7 +1516,7 @@ bool BM_mesh_intersect(
|
||||
|
||||
BM_mesh_edgesplit(bm, false, true, false);
|
||||
}
|
||||
else if (boolean_mode != BMESH_ISECT_BOOLEAN_NONE) {
|
||||
else if (boolean_mode != BMESH_ISECT_BOOLEAN_NONE || use_edge_tag) {
|
||||
GSetIterator gs_iter;
|
||||
|
||||
/* no need to clear for boolean */
|
||||
|
||||
@@ -30,7 +30,7 @@ bool BM_mesh_intersect(
|
||||
struct BMLoop *(*looptris)[3], const int looptris_tot,
|
||||
int (*test_fn)(BMFace *f, void *user_data), void *user_data,
|
||||
const bool use_self, const bool use_separate, const bool use_dissolve, const bool use_island_connect,
|
||||
const int boolean_mode,
|
||||
const bool use_edge_tag, const int boolean_mode,
|
||||
const float eps);
|
||||
|
||||
enum {
|
||||
|
||||
@@ -303,17 +303,11 @@ static EditBone *get_nearest_editbonepoint(
|
||||
ebone_next_act = NULL;
|
||||
}
|
||||
|
||||
rect.xmin = mval[0] - 5;
|
||||
rect.xmax = mval[0] + 5;
|
||||
rect.ymin = mval[1] - 5;
|
||||
rect.ymax = mval[1] + 5;
|
||||
BLI_rcti_init_pt_size(&rect, mval, 5);
|
||||
|
||||
hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, true);
|
||||
if (hits == 0) {
|
||||
rect.xmin = mval[0] - 12;
|
||||
rect.xmax = mval[0] + 12;
|
||||
rect.ymin = mval[1] - 12;
|
||||
rect.ymax = mval[1] + 12;
|
||||
BLI_rcti_init_pt_size(&rect, mval, 12);
|
||||
hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, true);
|
||||
}
|
||||
/* See if there are any selected bones in this group */
|
||||
|
||||
@@ -1907,10 +1907,7 @@ static bool sk_selectStroke(bContext *C, SK_Sketch *sketch, const int mval[2], c
|
||||
|
||||
view3d_set_viewcontext(C, &vc);
|
||||
|
||||
rect.xmin = mval[0] - 5;
|
||||
rect.xmax = mval[0] + 5;
|
||||
rect.ymin = mval[1] - 5;
|
||||
rect.ymax = mval[1] + 5;
|
||||
BLI_rcti_init_pt_size(&rect, mval, 5);
|
||||
|
||||
hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect, true);
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ struct Main;
|
||||
struct MetaElem;
|
||||
struct Nurb;
|
||||
struct Object;
|
||||
struct RV3DMatrixStore;
|
||||
struct RegionView3D;
|
||||
struct Scene;
|
||||
struct SceneLayer;
|
||||
@@ -334,8 +335,8 @@ void ED_view3d_check_mats_rv3d(struct RegionView3D *rv3d);
|
||||
#endif
|
||||
int ED_view3d_scene_layer_set(int lay, const int *values, int *active);
|
||||
|
||||
void *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d);
|
||||
void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, void *rv3dmat_pt);
|
||||
struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d);
|
||||
void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixStore *rv3dmat);
|
||||
|
||||
bool ED_view3d_context_activate(struct bContext *C);
|
||||
void ED_view3d_draw_offscreen_init(struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d);
|
||||
|
||||
@@ -7721,7 +7721,8 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
|
||||
if (ui_but_is_cursor_warp(but)) {
|
||||
|
||||
#ifdef USE_CONT_MOUSE_CORRECT
|
||||
if (data->ungrab_mval[0] != FLT_MAX) {
|
||||
/* stereo3d has issues with changing cursor location so rather avoid */
|
||||
if (data->ungrab_mval[0] != FLT_MAX && !WM_stereo3d_enabled(data->window, false)) {
|
||||
int mouse_ungrab_xy[2];
|
||||
ui_block_to_window_fl(data->region, but->block, &data->ungrab_mval[0], &data->ungrab_mval[1]);
|
||||
mouse_ungrab_xy[0] = data->ungrab_mval[0];
|
||||
|
||||
@@ -137,6 +137,12 @@ enum {
|
||||
ISECT_SEL_UNSEL = 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
ISECT_SEPARATE_ALL = 0,
|
||||
ISECT_SEPARATE_CUT = 1,
|
||||
ISECT_SEPARATE_NONE = 2,
|
||||
};
|
||||
|
||||
static int edbm_intersect_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
@@ -144,7 +150,9 @@ static int edbm_intersect_exec(bContext *C, wmOperator *op)
|
||||
BMesh *bm = em->bm;
|
||||
const int mode = RNA_enum_get(op->ptr, "mode");
|
||||
int (*test_fn)(BMFace *, void *);
|
||||
bool use_separate = RNA_boolean_get(op->ptr, "use_separate");
|
||||
bool use_separate_all = false;
|
||||
bool use_separate_cut = false;
|
||||
const int separate_mode = RNA_enum_get(op->ptr, "separate_mode");
|
||||
const float eps = RNA_float_get(op->ptr, "threshold");
|
||||
bool use_self;
|
||||
bool has_isect;
|
||||
@@ -160,15 +168,42 @@ static int edbm_intersect_exec(bContext *C, wmOperator *op)
|
||||
break;
|
||||
}
|
||||
|
||||
switch (separate_mode) {
|
||||
case ISECT_SEPARATE_ALL:
|
||||
use_separate_all = true;
|
||||
break;
|
||||
case ISECT_SEPARATE_CUT:
|
||||
if (use_self == false) {
|
||||
use_separate_cut = true;
|
||||
}
|
||||
else {
|
||||
/* we could support this but would require more advanced logic inside 'BM_mesh_intersect'
|
||||
* for now just separate all */
|
||||
use_separate_all = true;
|
||||
}
|
||||
break;
|
||||
default: /* ISECT_SEPARATE_NONE */
|
||||
break;
|
||||
}
|
||||
|
||||
has_isect = BM_mesh_intersect(
|
||||
bm,
|
||||
em->looptris, em->tottri,
|
||||
test_fn, NULL,
|
||||
use_self, use_separate, true, true,
|
||||
use_self, use_separate_all, true, true, true,
|
||||
-1,
|
||||
eps);
|
||||
|
||||
if (use_separate_cut) {
|
||||
/* detach selected/un-selected faces */
|
||||
BMOperator bmop;
|
||||
EDBM_op_init(em, &bmop, op, "split geom=%hf use_only_faces=%b", BM_ELEM_SELECT, true);
|
||||
BMO_op_exec(em->bm, &bmop);
|
||||
if (!EDBM_op_finish(em, &bmop, op, true)) {
|
||||
/* should never happen! */
|
||||
BKE_report(op->reports, RPT_ERROR, "Error separating");
|
||||
}
|
||||
}
|
||||
|
||||
if (has_isect) {
|
||||
edbm_intersect_select(em);
|
||||
@@ -190,6 +225,16 @@ void MESH_OT_intersect(struct wmOperatorType *ot)
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
static EnumPropertyItem isect_separate_items[] = {
|
||||
{ISECT_SEPARATE_ALL, "ALL", 0, "All",
|
||||
"Separate all geometry from intersections"},
|
||||
{ISECT_SEPARATE_CUT, "CUT", 0, "Cut",
|
||||
"Cut into geometry keeping each side separate (Selected/Unselected only)"},
|
||||
{ISECT_SEPARATE_NONE, "NONE", 0, "Merge",
|
||||
"Merge all geometry from the intersection"},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
/* identifiers */
|
||||
ot->name = "Intersect (Knife)";
|
||||
ot->description = "Cut an intersection into faces";
|
||||
@@ -201,7 +246,7 @@ void MESH_OT_intersect(struct wmOperatorType *ot)
|
||||
|
||||
/* props */
|
||||
RNA_def_enum(ot->srna, "mode", isect_mode_items, ISECT_SEL_UNSEL, "Source", "");
|
||||
RNA_def_boolean(ot->srna, "use_separate", true, "Separate", "");
|
||||
RNA_def_enum(ot->srna, "separate_mode", isect_separate_items, ISECT_SEPARATE_CUT, "Separate Mode", "");
|
||||
RNA_def_float_distance(ot->srna, "threshold", 0.000001f, 0.0, 0.01, "Merge threshold", "", 0.0, 0.001);
|
||||
|
||||
/* flags */
|
||||
@@ -239,7 +284,7 @@ static int edbm_intersect_boolean_exec(bContext *C, wmOperator *op)
|
||||
bm,
|
||||
em->looptris, em->tottri,
|
||||
test_fn, NULL,
|
||||
false, false, true, true,
|
||||
false, false, true, true, true,
|
||||
boolean_operation,
|
||||
eps);
|
||||
|
||||
|
||||
@@ -592,10 +592,7 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese
|
||||
|
||||
view3d_set_viewcontext(C, &vc);
|
||||
|
||||
rect.xmin = mval[0] - 12;
|
||||
rect.xmax = mval[0] + 12;
|
||||
rect.ymin = mval[1] - 12;
|
||||
rect.ymax = mval[1] + 12;
|
||||
BLI_rcti_init_pt_size(&rect, mval, 12);
|
||||
|
||||
hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect, true);
|
||||
|
||||
|
||||
@@ -889,14 +889,15 @@ static void write_result_func(TaskPool * __restrict pool,
|
||||
*/
|
||||
ReportList reports;
|
||||
BKE_reports_init(&reports, oglrender->reports->flag & ~RPT_PRINT);
|
||||
/* Do actual save logic here, depending on the file format. */
|
||||
/* Do actual save logic here, depending on the file format.
|
||||
*
|
||||
* NOTE: We have to construct temporary scene with proper scene->r.cfra.
|
||||
* This is because underlying calls do not use r.cfra but use scene
|
||||
* for that.
|
||||
*/
|
||||
Scene tmp_scene = *scene;
|
||||
tmp_scene.r.cfra = cfra;
|
||||
if (is_movie) {
|
||||
/* We have to construct temporary scene with proper scene->r.cfra.
|
||||
* This is because underlying calls do not use r.cfra but use scene
|
||||
* for that.
|
||||
*/
|
||||
ok = RE_WriteRenderViewsMovie(&reports,
|
||||
rr,
|
||||
&tmp_scene,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
@@ -308,6 +307,7 @@ static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, uns
|
||||
*/
|
||||
for (cfra = strip->start; cfra <= strip->end; cfra += 1.0f) {
|
||||
float y = evaluate_fcurve(fcu, cfra); /* assume this to be in 0-1 range */
|
||||
CLAMP(y, 0.0f, 1.0f);
|
||||
immVertex2f(pos, cfra, ((y * yheight) + yminc));
|
||||
}
|
||||
|
||||
|
||||
@@ -1069,12 +1069,9 @@ int node_find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **so
|
||||
|
||||
/* check if we click in a socket */
|
||||
for (node = snode->edittree->nodes.first; node; node = node->next) {
|
||||
|
||||
rect.xmin = cursor[0] - (NODE_SOCKSIZE + 4);
|
||||
rect.ymin = cursor[1] - (NODE_SOCKSIZE + 4);
|
||||
rect.xmax = cursor[0] + (NODE_SOCKSIZE + 4);
|
||||
rect.ymax = cursor[1] + (NODE_SOCKSIZE + 4);
|
||||
|
||||
|
||||
BLI_rctf_init_pt_size(&rect, cursor, NODE_SOCKSIZE + 4);
|
||||
|
||||
if (!(node->flag & NODE_HIDDEN)) {
|
||||
/* extra padding inside and out - allow dragging on the text areas too */
|
||||
if (in_out == SOCK_IN) {
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
|
||||
#include "ED_keyframing.h"
|
||||
#include "ED_armature.h"
|
||||
#include "ED_keyframing.h"
|
||||
#include "ED_gpencil.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_transform.h"
|
||||
#include "ED_gpencil.h"
|
||||
@@ -1659,8 +1661,6 @@ static void draw_view_axis(RegionView3D *rv3d, rcti *rect)
|
||||
BLF_color4ubv(BLF_default(), axis_col[i]);
|
||||
BLF_draw_default_ascii(axis_pos[i][0] + 2, axis_pos[i][1] + 2, 0.0f, axis_text, 1);
|
||||
}
|
||||
|
||||
/* BLF_draw disabled blending for us */
|
||||
}
|
||||
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
|
||||
@@ -1674,7 +1674,7 @@ struct RV3DMatrixStore {
|
||||
float pixsize;
|
||||
};
|
||||
|
||||
void *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d)
|
||||
struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d)
|
||||
{
|
||||
struct RV3DMatrixStore *rv3dmat = MEM_mallocN(sizeof(*rv3dmat), __func__);
|
||||
copy_m4_m4(rv3dmat->winmat, rv3d->winmat);
|
||||
@@ -1687,7 +1687,7 @@ void *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d)
|
||||
return (void *)rv3dmat;
|
||||
}
|
||||
|
||||
void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, void *rv3dmat_pt)
|
||||
void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixStore *rv3dmat_pt)
|
||||
{
|
||||
struct RV3DMatrixStore *rv3dmat = rv3dmat_pt;
|
||||
copy_m4_m4(rv3d->winmat, rv3dmat->winmat);
|
||||
|
||||
@@ -4872,11 +4872,7 @@ static float view_autodist_depth_margin(ARegion *ar, const int mval[2], int marg
|
||||
rect.ymax = mval[1] + 1;
|
||||
}
|
||||
else {
|
||||
rect.xmax = mval[0] + margin;
|
||||
rect.ymax = mval[1] + margin;
|
||||
|
||||
rect.xmin = mval[0] - margin;
|
||||
rect.ymin = mval[1] - margin;
|
||||
BLI_rcti_init_pt_size(&rect, mval, margin);
|
||||
}
|
||||
|
||||
view3d_update_depths_rect(ar, &depth_temp, &rect);
|
||||
|
||||
@@ -1179,10 +1179,8 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b
|
||||
|
||||
/* case not a border select */
|
||||
if (input->xmin == input->xmax) {
|
||||
rect.xmin = input->xmin - 12; /* seems to be default value for bones only now */
|
||||
rect.xmax = input->xmin + 12;
|
||||
rect.ymin = input->ymin - 12;
|
||||
rect.ymax = input->ymin + 12;
|
||||
/* seems to be default value for bones only now */
|
||||
BLI_rctf_init_pt_size(&rect, (const float[2]){input->xmin, input->ymin}, 12);
|
||||
}
|
||||
else {
|
||||
BLI_rctf_rcti_copy(&rect, input);
|
||||
|
||||
@@ -1594,6 +1594,7 @@ typedef struct SurfaceDeformModifierData {
|
||||
float falloff;
|
||||
unsigned int numverts, numpoly;
|
||||
int flags;
|
||||
float mat[4][4];
|
||||
} SurfaceDeformModifierData;
|
||||
|
||||
/* Surface Deform modifier flags */
|
||||
|
||||
@@ -303,6 +303,7 @@ static DerivedMesh *applyModifier_bmesh(
|
||||
use_separate,
|
||||
use_dissolve,
|
||||
use_island_connect,
|
||||
false,
|
||||
bmd->operation,
|
||||
bmd->double_threshold);
|
||||
|
||||
|
||||
@@ -40,8 +40,9 @@ typedef struct SDefBindCalcData {
|
||||
const MPoly * const mpoly;
|
||||
const MEdge * const medge;
|
||||
const MLoop * const mloop;
|
||||
const MVert * const mvert;
|
||||
float (* const targetCos)[3];
|
||||
float (* const vertexCos)[3];
|
||||
float imat[4][4];
|
||||
const float falloff;
|
||||
int success;
|
||||
} SDefBindCalcData;
|
||||
@@ -81,7 +82,7 @@ typedef struct SDefBindWeightData {
|
||||
|
||||
typedef struct SDefDeformData {
|
||||
const SDefVert * const bind_verts;
|
||||
const MVert * const mvert;
|
||||
float (* const targetCos)[3];
|
||||
float (* const vertexCos)[3];
|
||||
} SDefDeformData;
|
||||
|
||||
@@ -267,23 +268,25 @@ BLI_INLINE void sortPolyVertsTri(unsigned int *indices, const MLoop * const mloo
|
||||
|
||||
BLI_INLINE unsigned int nearestVert(SDefBindCalcData * const data, const float point_co[3])
|
||||
{
|
||||
const MVert * const mvert = data->mvert;
|
||||
BVHTreeNearest nearest = {.dist_sq = FLT_MAX, .index = -1};
|
||||
const MPoly *poly;
|
||||
const MEdge *edge;
|
||||
const MLoop *loop;
|
||||
float t_point[3];
|
||||
float max_dist = FLT_MAX;
|
||||
float dist;
|
||||
unsigned int index = 0;
|
||||
|
||||
BLI_bvhtree_find_nearest(data->treeData->tree, point_co, &nearest, data->treeData->nearest_callback, data->treeData);
|
||||
mul_v3_m4v3(t_point, data->imat, point_co);
|
||||
|
||||
BLI_bvhtree_find_nearest(data->treeData->tree, t_point, &nearest, data->treeData->nearest_callback, data->treeData);
|
||||
|
||||
poly = &data->mpoly[data->looptri[nearest.index].poly];
|
||||
loop = &data->mloop[poly->loopstart];
|
||||
|
||||
for (int i = 0; i < poly->totloop; i++, loop++) {
|
||||
edge = &data->medge[loop->e];
|
||||
dist = dist_squared_to_line_segment_v3(point_co, mvert[edge->v1].co, mvert[edge->v2].co);
|
||||
dist = dist_squared_to_line_segment_v3(point_co, data->targetCos[edge->v1], data->targetCos[edge->v2]);
|
||||
|
||||
if (dist < max_dist) {
|
||||
max_dist = dist;
|
||||
@@ -292,7 +295,7 @@ BLI_INLINE unsigned int nearestVert(SDefBindCalcData * const data, const float p
|
||||
}
|
||||
|
||||
edge = &data->medge[index];
|
||||
if (len_squared_v3v3(point_co, mvert[edge->v1].co) < len_squared_v3v3(point_co, mvert[edge->v2].co)) {
|
||||
if (len_squared_v3v3(point_co, data->targetCos[edge->v1]) < len_squared_v3v3(point_co, data->targetCos[edge->v2])) {
|
||||
return edge->v1;
|
||||
}
|
||||
else {
|
||||
@@ -441,7 +444,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData * const data,
|
||||
}
|
||||
|
||||
for (int j = 0; j < poly->totloop; j++, loop++) {
|
||||
copy_v3_v3(bpoly->coords[j], data->mvert[loop->v].co);
|
||||
copy_v3_v3(bpoly->coords[j], data->targetCos[loop->v]);
|
||||
|
||||
/* Find corner and edge indices within poly loop array */
|
||||
if (loop->v == nearest) {
|
||||
@@ -830,8 +833,8 @@ static void bindVert(void *userdata, void *UNUSED(userdata_chunk), const int ind
|
||||
sortPolyVertsEdge(sdbind->vert_inds, &data->mloop[bpoly->loopstart],
|
||||
bpoly->edge_inds[bpoly->dominant_edge], bpoly->numverts);
|
||||
|
||||
copy_v3_v3(v1, data->mvert[sdbind->vert_inds[0]].co);
|
||||
copy_v3_v3(v2, data->mvert[sdbind->vert_inds[1]].co);
|
||||
copy_v3_v3(v1, data->targetCos[sdbind->vert_inds[0]]);
|
||||
copy_v3_v3(v2, data->targetCos[sdbind->vert_inds[1]]);
|
||||
copy_v3_v3(v3, bpoly->centroid);
|
||||
|
||||
mid_v3_v3v3v3(cent, v1, v2, v3);
|
||||
@@ -872,9 +875,9 @@ static void bindVert(void *userdata, void *UNUSED(userdata_chunk), const int ind
|
||||
|
||||
sortPolyVertsTri(sdbind->vert_inds, &data->mloop[bpoly->loopstart], bpoly->edge_vert_inds[0], bpoly->numverts);
|
||||
|
||||
copy_v3_v3(v1, data->mvert[sdbind->vert_inds[0]].co);
|
||||
copy_v3_v3(v2, data->mvert[sdbind->vert_inds[1]].co);
|
||||
copy_v3_v3(v3, data->mvert[sdbind->vert_inds[2]].co);
|
||||
copy_v3_v3(v1, data->targetCos[sdbind->vert_inds[0]]);
|
||||
copy_v3_v3(v2, data->targetCos[sdbind->vert_inds[1]]);
|
||||
copy_v3_v3(v3, data->targetCos[sdbind->vert_inds[2]]);
|
||||
|
||||
mid_v3_v3v3v3(cent, v1, v2, v3);
|
||||
normal_tri_v3(norm, v1, v2, v3);
|
||||
@@ -902,14 +905,14 @@ static void bindVert(void *userdata, void *UNUSED(userdata_chunk), const int ind
|
||||
}
|
||||
|
||||
static bool surfacedeformBind(SurfaceDeformModifierData *smd, float (*vertexCos)[3],
|
||||
unsigned int numverts, unsigned int tnumpoly, DerivedMesh *tdm)
|
||||
unsigned int numverts, unsigned int tnumpoly, unsigned int tnumverts, DerivedMesh *tdm)
|
||||
{
|
||||
BVHTreeFromMesh treeData = {NULL};
|
||||
const MVert *mvert = tdm->getVertArray(tdm);
|
||||
const MPoly *mpoly = tdm->getPolyArray(tdm);
|
||||
const MEdge *medge = tdm->getEdgeArray(tdm);
|
||||
const MLoop *mloop = tdm->getLoopArray(tdm);
|
||||
unsigned int tnumedges = tdm->getNumEdges(tdm);
|
||||
unsigned int tnumverts = tdm->getNumVerts(tdm);
|
||||
int adj_result;
|
||||
SDefAdjacencyArray *vert_edges;
|
||||
SDefAdjacency *adj_array;
|
||||
@@ -973,15 +976,29 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd, float (*vertexCos)
|
||||
.medge = medge,
|
||||
.mloop = mloop,
|
||||
.looptri = tdm->getLoopTriArray(tdm),
|
||||
.mvert = tdm->getVertArray(tdm),
|
||||
.targetCos = MEM_mallocN(sizeof(float[3]) * tnumverts, "SDefTargetBindVertArray"),
|
||||
.bind_verts = smd->verts,
|
||||
.vertexCos = vertexCos,
|
||||
.falloff = smd->falloff,
|
||||
.success = MOD_SDEF_BIND_RESULT_SUCCESS};
|
||||
|
||||
if (data.targetCos == NULL) {
|
||||
modifier_setError((ModifierData *)smd, "Out of memory");
|
||||
freeData((ModifierData *)smd);
|
||||
return false;
|
||||
}
|
||||
|
||||
invert_m4_m4(data.imat, smd->mat);
|
||||
|
||||
for (int i = 0; i < tnumverts; i++) {
|
||||
mul_v3_m4v3(data.targetCos[i], smd->mat, mvert[i].co);
|
||||
}
|
||||
|
||||
BLI_task_parallel_range_ex(0, numverts, &data, NULL, 0, bindVert,
|
||||
numverts > 10000, false);
|
||||
|
||||
MEM_freeN(data.targetCos);
|
||||
|
||||
if (data.success == MOD_SDEF_BIND_RESULT_MEM_ERR) {
|
||||
modifier_setError((ModifierData *)smd, "Out of memory");
|
||||
freeData((ModifierData *)smd);
|
||||
@@ -1017,7 +1034,6 @@ static void deformVert(void *userdata, void *UNUSED(userdata_chunk), const int i
|
||||
{
|
||||
const SDefDeformData * const data = (SDefDeformData *)userdata;
|
||||
const SDefBind *sdbind = data->bind_verts[index].binds;
|
||||
const MVert * const mvert = data->mvert;
|
||||
float * const vertexCos = data->vertexCos[index];
|
||||
float norm[3], temp[3];
|
||||
|
||||
@@ -1028,7 +1044,7 @@ static void deformVert(void *userdata, void *UNUSED(userdata_chunk), const int i
|
||||
float (*coords)[3] = MEM_mallocN(sizeof(*coords) * sdbind->numverts, "SDefDoPolyCoords");
|
||||
|
||||
for (int k = 0; k < sdbind->numverts; k++) {
|
||||
copy_v3_v3(coords[k], mvert[sdbind->vert_inds[k]].co);
|
||||
copy_v3_v3(coords[k], data->targetCos[sdbind->vert_inds[k]]);
|
||||
}
|
||||
|
||||
normal_poly_v3(norm, coords, sdbind->numverts);
|
||||
@@ -1036,9 +1052,9 @@ static void deformVert(void *userdata, void *UNUSED(userdata_chunk), const int i
|
||||
|
||||
/* ---------- looptri mode ---------- */
|
||||
if (sdbind->mode == MOD_SDEF_MODE_LOOPTRI) {
|
||||
madd_v3_v3fl(temp, mvert[sdbind->vert_inds[0]].co, sdbind->vert_weights[0]);
|
||||
madd_v3_v3fl(temp, mvert[sdbind->vert_inds[1]].co, sdbind->vert_weights[1]);
|
||||
madd_v3_v3fl(temp, mvert[sdbind->vert_inds[2]].co, sdbind->vert_weights[2]);
|
||||
madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[0]], sdbind->vert_weights[0]);
|
||||
madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[1]], sdbind->vert_weights[1]);
|
||||
madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[2]], sdbind->vert_weights[2]);
|
||||
}
|
||||
else {
|
||||
/* ---------- ngon mode ---------- */
|
||||
@@ -1053,8 +1069,8 @@ static void deformVert(void *userdata, void *UNUSED(userdata_chunk), const int i
|
||||
float cent[3];
|
||||
mid_v3_v3_array(cent, coords, sdbind->numverts);
|
||||
|
||||
madd_v3_v3fl(temp, mvert[sdbind->vert_inds[0]].co, sdbind->vert_weights[0]);
|
||||
madd_v3_v3fl(temp, mvert[sdbind->vert_inds[1]].co, sdbind->vert_weights[1]);
|
||||
madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[0]], sdbind->vert_weights[0]);
|
||||
madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[1]], sdbind->vert_weights[1]);
|
||||
madd_v3_v3fl(temp, cent, sdbind->vert_weights[2]);
|
||||
}
|
||||
}
|
||||
@@ -1068,11 +1084,11 @@ static void deformVert(void *userdata, void *UNUSED(userdata_chunk), const int i
|
||||
}
|
||||
}
|
||||
|
||||
static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], unsigned int numverts)
|
||||
static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], unsigned int numverts, Object *ob)
|
||||
{
|
||||
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
|
||||
DerivedMesh *tdm;
|
||||
unsigned int tnumpoly;
|
||||
unsigned int tnumverts, tnumpoly;
|
||||
|
||||
/* Exit function if bind flag is not set (free bind data if any) */
|
||||
if (!(smd->flags & MOD_SDEF_BIND)) {
|
||||
@@ -1089,11 +1105,17 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un
|
||||
tdm = smd->target->derivedFinal;
|
||||
}
|
||||
|
||||
tnumverts = tdm->getNumVerts(tdm);
|
||||
tnumpoly = tdm->getNumPolys(tdm);
|
||||
|
||||
/* If not bound, execute bind */
|
||||
if (!(smd->verts)) {
|
||||
if (!surfacedeformBind(smd, vertexCos, numverts, tnumpoly, tdm)) {
|
||||
float tmp_mat[4][4];
|
||||
|
||||
invert_m4_m4(tmp_mat, ob->obmat);
|
||||
mul_m4_m4m4(smd->mat, tmp_mat, smd->target->obmat);
|
||||
|
||||
if (!surfacedeformBind(smd, vertexCos, numverts, tnumpoly, tnumverts, tdm)) {
|
||||
smd->flags &= ~MOD_SDEF_BIND;
|
||||
return;
|
||||
}
|
||||
@@ -1113,29 +1135,44 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un
|
||||
|
||||
/* Actual vertex location update starts here */
|
||||
SDefDeformData data = {.bind_verts = smd->verts,
|
||||
.mvert = tdm->getVertArray(tdm),
|
||||
.targetCos = MEM_mallocN(sizeof(float[3]) * tnumverts, "SDefTargetVertArray"),
|
||||
.vertexCos = vertexCos};
|
||||
|
||||
BLI_task_parallel_range_ex(0, numverts, &data, NULL, 0, deformVert,
|
||||
numverts > 10000, false);
|
||||
if (data.targetCos != NULL) {
|
||||
bool tdm_vert_alloc;
|
||||
const MVert * const mvert = DM_get_vert_array(tdm, &tdm_vert_alloc);
|
||||
|
||||
for (int i = 0; i < tnumverts; i++) {
|
||||
mul_v3_m4v3(data.targetCos[i], smd->mat, mvert[i].co);
|
||||
}
|
||||
|
||||
BLI_task_parallel_range_ex(0, numverts, &data, NULL, 0, deformVert,
|
||||
numverts > 10000, false);
|
||||
|
||||
if (tdm_vert_alloc) {
|
||||
MEM_freeN((void *)mvert);
|
||||
}
|
||||
|
||||
MEM_freeN(data.targetCos);
|
||||
}
|
||||
|
||||
tdm->release(tdm);
|
||||
}
|
||||
|
||||
static void deformVerts(ModifierData *md, Object *UNUSED(ob),
|
||||
static void deformVerts(ModifierData *md, Object *ob,
|
||||
DerivedMesh *UNUSED(derivedData),
|
||||
float (*vertexCos)[3], int numVerts,
|
||||
ModifierApplyFlag UNUSED(flag))
|
||||
{
|
||||
surfacedeformModifier_do(md, vertexCos, numVerts);
|
||||
surfacedeformModifier_do(md, vertexCos, numVerts, ob);
|
||||
}
|
||||
|
||||
static void deformVertsEM(ModifierData *md, Object *UNUSED(ob),
|
||||
static void deformVertsEM(ModifierData *md, Object *ob,
|
||||
struct BMEditMesh *UNUSED(editData),
|
||||
DerivedMesh *UNUSED(derivedData),
|
||||
float (*vertexCos)[3], int numVerts)
|
||||
{
|
||||
surfacedeformModifier_do(md, vertexCos, numVerts);
|
||||
surfacedeformModifier_do(md, vertexCos, numVerts, ob);
|
||||
}
|
||||
|
||||
static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
|
||||
|
||||
@@ -203,7 +203,7 @@ static PyObject *pygpu_offscreen_draw_view3d(BPy_GPUOffScreen *self, PyObject *a
|
||||
ARegion *ar;
|
||||
GPUFX *fx;
|
||||
GPUFXSettings fx_settings;
|
||||
void *rv3d_mats;
|
||||
struct RV3DMatrixStore *rv3d_mats;
|
||||
|
||||
BPY_GPU_OFFSCREEN_CHECK_OBJ(self);
|
||||
|
||||
|
||||
@@ -3275,6 +3275,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
|
||||
GHOST_TEventCursorData *cd = customdata;
|
||||
|
||||
copy_v2_v2_int(&event.x, &cd->x);
|
||||
wm_stereo3d_mouse_offset_apply(win, &event.x);
|
||||
|
||||
event.type = MOUSEMOVE;
|
||||
wm_event_add_mousemove(win, &event);
|
||||
copy_v2_v2_int(&evt->x, &event.x);
|
||||
|
||||
@@ -394,6 +394,32 @@ bool WM_stereo3d_enabled(wmWindow *win, bool skip_stereo3d_check)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* If needed, this adjusts \a r_mouse_xy so that drawn cursor and handled mouse position are matching visually.
|
||||
*/
|
||||
void wm_stereo3d_mouse_offset_apply(wmWindow *win, int *r_mouse_xy)
|
||||
{
|
||||
if (!WM_stereo3d_enabled(win, false))
|
||||
return;
|
||||
|
||||
if (win->stereo3d_format->display_mode == S3D_DISPLAY_SIDEBYSIDE) {
|
||||
const int half_x = win->sizex / 2;
|
||||
/* right half of the screen */
|
||||
if (r_mouse_xy[0] > half_x) {
|
||||
r_mouse_xy[0] -= half_x;
|
||||
}
|
||||
r_mouse_xy[0] *= 2;
|
||||
}
|
||||
else if (win->stereo3d_format->display_mode == S3D_DISPLAY_TOPBOTTOM) {
|
||||
const int half_y = win->sizey / 2;
|
||||
/* upper half of the screen */
|
||||
if (r_mouse_xy[1] > half_y) {
|
||||
r_mouse_xy[1] -= half_y;
|
||||
}
|
||||
r_mouse_xy[1] *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
/************************** Stereo 3D operator **********************************/
|
||||
typedef struct Stereo3dData {
|
||||
Stereo3dFormat stereo3d_format;
|
||||
|
||||
@@ -80,6 +80,7 @@ void wm_autosave_location(char *filepath);
|
||||
|
||||
/* wm_stereo.c */
|
||||
void wm_method_draw_stereo3d(const bContext *C, wmWindow *win);
|
||||
void wm_stereo3d_mouse_offset_apply(wmWindow *win, int *r_mouse_xy);
|
||||
int wm_stereo3d_set_exec(bContext *C, wmOperator *op);
|
||||
int wm_stereo3d_set_invoke(bContext *C, wmOperator *op, const wmEvent *event);
|
||||
void wm_stereo3d_set_draw(bContext *C, wmOperator *op);
|
||||
|
||||
Reference in New Issue
Block a user