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:
Julian Eisel
2017-03-06 13:00:46 +01:00
31 changed files with 235 additions and 112 deletions

View File

@@ -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]);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}
}
}
}
}
{

View File

@@ -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 */

View File

@@ -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 {

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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);

View File

@@ -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];

View File

@@ -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);

View File

@@ -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);

View File

@@ -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,

View File

@@ -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));
}

View File

@@ -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) {

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -1594,6 +1594,7 @@ typedef struct SurfaceDeformModifierData {
float falloff;
unsigned int numverts, numpoly;
int flags;
float mat[4][4];
} SurfaceDeformModifierData;
/* Surface Deform modifier flags */

View File

@@ -303,6 +303,7 @@ static DerivedMesh *applyModifier_bmesh(
use_separate,
use_dissolve,
use_island_connect,
false,
bmd->operation,
bmd->double_threshold);

View File

@@ -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))

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);