Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOve Murberg Henriksen <sorayasilvermoon@hotmail.com>2012-05-18 03:34:54 +0400
committerOve Murberg Henriksen <sorayasilvermoon@hotmail.com>2012-05-18 03:34:54 +0400
commit74a889d8b1a8e9f83214fa885f530b7b167b4a32 (patch)
treeeb85f3c045b69b919b9d2b0b79f1e626ff4f2647 /source/blender/editors
parent8521ca69fac26ebfa14910566f2271562e1ff0b5 (diff)
parent7862b2fa13c0437d9c17eae78e7b79a421dacf05 (diff)
svn merge ^/trunk/blender -r46644:HEAD
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/animation/anim_filter.c8
-rw-r--r--source/blender/editors/armature/editarmature.c2
-rw-r--r--source/blender/editors/armature/editarmature_retarget.c6
-rw-r--r--source/blender/editors/armature/editarmature_sketch.c2
-rw-r--r--source/blender/editors/armature/reeb.c4
-rw-r--r--source/blender/editors/curve/editcurve.c4
-rw-r--r--source/blender/editors/include/ED_mesh.h12
-rw-r--r--source/blender/editors/include/ED_transform.h2
-rw-r--r--source/blender/editors/interface/interface_draw.c38
-rw-r--r--source/blender/editors/interface/interface_handlers.c17
-rw-r--r--source/blender/editors/interface/interface_icons.c3
-rw-r--r--source/blender/editors/interface/interface_intern.h3
-rw-r--r--source/blender/editors/interface/interface_ops.c4
-rw-r--r--source/blender/editors/interface/interface_panel.c5
-rw-r--r--source/blender/editors/interface/interface_regions.c23
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c6
-rw-r--r--source/blender/editors/mesh/editmesh_select.c9
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c600
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c46
-rw-r--r--source/blender/editors/mesh/mesh_ops.c2
-rw-r--r--source/blender/editors/object/object_add.c4
-rw-r--r--source/blender/editors/object/object_constraint.c21
-rw-r--r--source/blender/editors/object/object_select.c4
-rw-r--r--source/blender/editors/object/object_transform.c2
-rw-r--r--source/blender/editors/render/render_update.c2
-rw-r--r--source/blender/editors/screen/screen_ops.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c12
-rw-r--r--source/blender/editors/sculpt_paint/paint_hide.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c18
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c6
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c361
-rw-r--r--source/blender/editors/space_clip/clip_editor.c4
-rw-r--r--source/blender/editors/space_file/file_ops.c6
-rw-r--r--source/blender/editors/space_image/image_ops.c2
-rw-r--r--source/blender/editors/space_node/drawnode.c287
-rw-r--r--source/blender/editors/space_node/node_draw.c7
-rw-r--r--source/blender/editors/space_node/node_edit.c334
-rw-r--r--source/blender/editors/space_node/node_intern.h8
-rw-r--r--source/blender/editors/space_node/node_ops.c2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c2
-rw-r--r--source/blender/editors/space_view3d/drawobject.c30
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c3
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c5
-rw-r--r--source/blender/editors/transform/transform.c162
-rw-r--r--source/blender/editors/transform/transform_conversions.c40
46 files changed, 1590 insertions, 534 deletions
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 2729396cb4a..160e6957513 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -379,7 +379,7 @@ short ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
/* ... standard sub-channel filtering can go on here now ... */
#define END_ANIMFILTER_SUBCHANNELS \
filter_mode = _filter; \
- }
+ } (void)0
/* ............................... */
@@ -447,7 +447,7 @@ short ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
} \
} \
} \
- }
+ } (void)0
/* ............................... */
@@ -467,7 +467,7 @@ short ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
items ++; \
ale_statement \
} \
- }
+ } (void)0
#define ANIMCHANNEL_NEW_CHANNEL(channel_data, channel_type, owner_id) \
ANIMCHANNEL_NEW_CHANNEL_FULL(channel_data, channel_type, owner_id, {})
@@ -2223,7 +2223,7 @@ static size_t animdata_filter_remove_duplis(ListBase *anim_data)
/* build new hashtable to efficiently store and retrieve which entries have been
* encountered already while searching
*/
- gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "animdata_filter_duplis_remove gh");
+ gh = BLI_ghash_ptr_new("animdata_filter_duplis_remove gh");
/* loop through items, removing them from the list if a similar item occurs already */
for (ale = anim_data->first; ale; ale = next) {
diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c
index 8e2dfb72703..7ce2988b067 100644
--- a/source/blender/editors/armature/editarmature.c
+++ b/source/blender/editors/armature/editarmature.c
@@ -5945,7 +5945,7 @@ void generateSkeletonFromReebGraph(Scene *scene, ReebGraph *rg)
ED_armature_to_edit(obedit);
- arcBoneMap = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "SkeletonFromReebGraph gh");
+ arcBoneMap = BLI_ghash_ptr_new("SkeletonFromReebGraph gh");
BLI_markdownSymmetry((BGraph *)rg, rg->nodes.first, scene->toolsettings->skgen_symmetry_limit);
diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c
index 566dbc901b8..80f8c61694c 100644
--- a/source/blender/editors/armature/editarmature_retarget.c
+++ b/source/blender/editors/armature/editarmature_retarget.c
@@ -298,8 +298,8 @@ static RigGraph *newRigGraph(void)
rg->head = NULL;
- rg->bones_map = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "newRigGraph bones gh");
- rg->controls_map = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "newRigGraph cont gh");
+ rg->bones_map = BLI_ghash_str_new("newRigGraph bones gh");
+ rg->controls_map = BLI_ghash_str_new("newRigGraph cont gh");
rg->free_arc = RIG_freeRigArc;
rg->free_node = NULL;
@@ -532,7 +532,7 @@ static RigGraph *cloneRigGraph(RigGraph *src, ListBase *editbones, Object *ob, c
RigControl *ctrl;
RigGraph *rg;
- ptr_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "cloneRigGraph gh");
+ ptr_hash = BLI_ghash_ptr_new("cloneRigGraph gh");
rg = newRigGraph();
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
index 2201bcf7224..06ecf76ba3e 100644
--- a/source/blender/editors/armature/editarmature_sketch.c
+++ b/source/blender/editors/armature/editarmature_sketch.c
@@ -165,7 +165,7 @@ void BIF_makeListTemplates(const bContext *C)
BLI_ghash_free(TEMPLATES_HASH, NULL, NULL);
}
- TEMPLATES_HASH = BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "makeListTemplates gh");
+ TEMPLATES_HASH = BLI_ghash_int_new("makeListTemplates gh");
TEMPLATES_CURRENT = 0;
for (base = FIRSTBASE; base; base = base->next) {
diff --git a/source/blender/editors/armature/reeb.c b/source/blender/editors/armature/reeb.c
index 2564683ddd2..316c4699c0b 100644
--- a/source/blender/editors/armature/reeb.c
+++ b/source/blender/editors/armature/reeb.c
@@ -354,7 +354,7 @@ static ReebArc *copyArc(ReebGraph *rg, ReebArc *arc)
memcpy(cp_arc->buckets, arc->buckets, sizeof(EmbedBucket) * cp_arc->bcount);
/* copy faces map */
- cp_arc->faces = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "copyArc gh");
+ cp_arc->faces = BLI_ghash_ptr_new("copyArc gh");
mergeArcFaces(rg, cp_arc, arc);
/* find corresponding head and tail */
@@ -2295,7 +2295,7 @@ static ReebEdge *createArc(ReebGraph *rg, ReebNode *node1, ReebNode *node2)
arc->flag = 0; // clear flag on init
arc->symmetry_level = 0;
- arc->faces = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "createArc gh");
+ arc->faces = BLI_ghash_ptr_new("createArc gh");
if (node1->weight <= node2->weight) {
v1 = node1;
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index e2824ee35cc..7afba049232 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -311,7 +311,7 @@ static void init_editNurb_keyIndex(EditNurb *editnurb, ListBase *origBase)
if (editnurb->keyindex) return;
- gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "editNurb keyIndex");
+ gh = BLI_ghash_ptr_new("editNurb keyIndex");
while (orignu) {
if (orignu->bezt) {
@@ -667,7 +667,7 @@ static GHash *dupli_keyIndexHash(GHash *keyindex)
GHash *gh;
GHashIterator *hashIter;
- gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "dupli_keyIndex gh");
+ gh = BLI_ghash_ptr_new("dupli_keyIndex gh");
for (hashIter = BLI_ghashIterator_new(keyindex);
!BLI_ghashIterator_isDone(hashIter);
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 71d37d5c6ea..7e84962b154 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -267,6 +267,18 @@ void ED_mesh_mirrtopo_init(struct Mesh *me, const int ob_mode, MirrTopoStore_t *
const short skip_em_vert_array_init);
void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store);
+/* mesh backup */
+typedef struct BMBackup {
+ struct BMesh *bmcopy;
+} BMBackup;
+
+/* save a copy of the bmesh for restoring later */
+struct BMBackup EDBM_redo_state_store(struct BMEditMesh *em);
+/* restore a bmesh from backup */
+void EDBM_redo_state_restore(struct BMBackup, struct BMEditMesh *em, int recalctess);
+/* delete the backup, optionally flushing it to an editmesh */
+void EDBM_redo_state_free(struct BMBackup *, struct BMEditMesh *em, int recalctess);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index 30d49748626..1cc82f19515 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -100,7 +100,7 @@ enum {
* returns 1 if successful, 0 otherwise (usually means there's no selection)
* (if 0 is returns, *vec is unmodified)
* */
-int calculateTransformCenter(struct bContext *C, int centerMode, float *vec);
+int calculateTransformCenter(struct bContext *C, int centerMode, float *cent3d, int *cent2d);
struct TransInfo;
struct ScrArea;
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 8c5913e23fb..2f9e763a7d0 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -252,7 +252,8 @@ void uiDrawBoxShade(int mode, float minx, float miny, float maxx, float maxy, fl
/* linear vertical shade within button or in outline */
/* view2d scrollers use it */
-void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadeLeft, float shadeRight)
+void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float maxy,
+ float rad, float shadeLeft, float shadeRight)
{
float vec[7][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
{0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
@@ -656,7 +657,8 @@ static void draw_scope_end(rctf *rect, GLint *scissor)
uiDrawBox(GL_LINE_LOOP, rect->xmin - 1, rect->ymin, rect->xmax + 1, rect->ymax + 1, 3.0f);
}
-static void histogram_draw_one(float r, float g, float b, float alpha, float x, float y, float w, float h, float *data, int res)
+static void histogram_draw_one(float r, float g, float b, float alpha,
+ float x, float y, float w, float h, float *data, int res)
{
int i;
@@ -716,7 +718,10 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol)
/* need scissor test, histogram can draw outside of boundary */
glGetIntegerv(GL_VIEWPORT, scissor);
- glScissor(ar->winrct.xmin + (rect.xmin - 1), ar->winrct.ymin + (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), (rect.ymax + 1) - (rect.ymin - 1));
+ glScissor(ar->winrct.xmin + (rect.xmin - 1),
+ ar->winrct.ymin + (rect.ymin - 1),
+ (rect.xmax + 1) - (rect.xmin - 1),
+ (rect.ymax + 1) - (rect.ymin - 1));
glColor4f(1.f, 1.f, 1.f, 0.08f);
/* draw grid lines here */
@@ -786,7 +791,10 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol),
/* need scissor test, waveform can draw outside of boundary */
glGetIntegerv(GL_VIEWPORT, scissor);
- glScissor(ar->winrct.xmin + (rect.xmin - 1), ar->winrct.ymin + (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), (rect.ymax + 1) - (rect.ymin - 1));
+ glScissor(ar->winrct.xmin + (rect.xmin - 1),
+ ar->winrct.ymin + (rect.ymin - 1),
+ (rect.xmax + 1) - (rect.xmin - 1),
+ (rect.ymax + 1) - (rect.ymin - 1));
glColor4f(1.f, 1.f, 1.f, 0.08f);
/* draw grid lines here */
@@ -851,7 +859,12 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol),
}
/* RGB / YCC (3 channels) */
- else if (ELEM4(scopes->wavefrm_mode, SCOPES_WAVEFRM_RGB, SCOPES_WAVEFRM_YCC_601, SCOPES_WAVEFRM_YCC_709, SCOPES_WAVEFRM_YCC_JPEG)) {
+ else if (ELEM4(scopes->wavefrm_mode,
+ SCOPES_WAVEFRM_RGB,
+ SCOPES_WAVEFRM_YCC_601,
+ SCOPES_WAVEFRM_YCC_709,
+ SCOPES_WAVEFRM_YCC_JPEG))
+ {
int rgb = (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB);
glBlendFunc(GL_ONE, GL_ONE);
@@ -996,7 +1009,10 @@ void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wco
/* need scissor test, hvectorscope can draw outside of boundary */
glGetIntegerv(GL_VIEWPORT, scissor);
- glScissor(ar->winrct.xmin + (rect.xmin - 1), ar->winrct.ymin + (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), (rect.ymax + 1) - (rect.ymin - 1));
+ glScissor(ar->winrct.xmin + (rect.xmin - 1),
+ ar->winrct.ymin + (rect.ymin - 1),
+ (rect.xmax + 1) - (rect.xmin - 1),
+ (rect.ymax + 1) - (rect.ymin - 1));
glColor4f(1.f, 1.f, 1.f, 0.08f);
/* draw grid elements */
@@ -1507,7 +1523,10 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
/* need scissor test, preview image can draw outside of boundary */
glGetIntegerv(GL_VIEWPORT, scissor);
- glScissor(ar->winrct.xmin + (rect.xmin - 1), ar->winrct.ymin + (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), (rect.ymax + 1) - (rect.ymin - 1));
+ glScissor(ar->winrct.xmin + (rect.xmin - 1),
+ ar->winrct.ymin + (rect.ymin - 1),
+ (rect.xmax + 1) - (rect.xmin - 1),
+ (rect.ymax + 1) - (rect.ymin - 1));
if (scopes->track_disabled) {
glColor4f(0.7f, 0.3f, 0.3f, 0.3f);
@@ -1550,7 +1569,10 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
/* draw cross for pizel position */
glTranslatef(off_x + rect.xmin + track_pos[0] * zoomx, off_y + rect.ymin + track_pos[1] * zoomy, 0.f);
- glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin + rect.ymin, rect.xmax - rect.xmin, rect.ymax - rect.ymin);
+ glScissor(ar->winrct.xmin + rect.xmin,
+ ar->winrct.ymin + rect.ymin,
+ rect.xmax - rect.xmin,
+ rect.ymax - rect.ymin);
for (a = 0; a < 2; a++) {
if (a == 1) {
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 94ebdb7c0b9..8b0c3ecfcf3 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -286,7 +286,9 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
* handling is done, i.e. menus are closed, in order to avoid conflicts
* with these functions removing the buttons we are working with */
- if (but->func || but->funcN || block->handle_func || but->rename_func || (but->type == BUTM && block->butm_func) || but->optype || but->rnaprop) {
+ if (but->func || but->funcN || block->handle_func || but->rename_func ||
+ (but->type == BUTM && block->butm_func) || but->optype || but->rnaprop)
+ {
after = MEM_callocN(sizeof(uiAfterFunc), "uiAfterFunc");
if (but->func && ELEM(but, but->func_arg1, but->func_arg2)) {
@@ -4553,7 +4555,8 @@ static int ui_but_menu(bContext *C, uiBut *but)
PointerRNA ptr_props;
if (but->rnapoin.data && but->rnaprop) {
- BLI_snprintf(buf, sizeof(buf), "%s.%s", RNA_struct_identifier(but->rnapoin.type), RNA_property_identifier(but->rnaprop));
+ BLI_snprintf(buf, sizeof(buf), "%s.%s",
+ RNA_struct_identifier(but->rnapoin.type), RNA_property_identifier(but->rnaprop));
WM_operator_properties_create(&ptr_props, "WM_OT_doc_view");
RNA_string_set(&ptr_props, "doc_id", buf);
@@ -5128,8 +5131,10 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
WM_event_add_ui_handler(C, &data->window->modalhandlers, ui_handler_region_menu, NULL, data);
}
else {
- if (button_modal_state(data->state))
- WM_event_remove_ui_handler(&data->window->modalhandlers, ui_handler_region_menu, NULL, data, 1); /* 1 = postpone free */
+ if (button_modal_state(data->state)) {
+ /* TRUE = postpone free */
+ WM_event_remove_ui_handler(&data->window->modalhandlers, ui_handler_region_menu, NULL, data, TRUE);
+ }
}
}
@@ -6548,7 +6553,7 @@ static void ui_handler_remove_popup(bContext *C, void *userdata)
void UI_add_region_handlers(ListBase *handlers)
{
- WM_event_remove_ui_handler(handlers, ui_handler_region, ui_handler_remove_region, NULL, 0);
+ WM_event_remove_ui_handler(handlers, ui_handler_region, ui_handler_remove_region, NULL, FALSE);
WM_event_add_ui_handler(NULL, handlers, ui_handler_region, ui_handler_remove_region, NULL);
}
@@ -6559,7 +6564,7 @@ void UI_add_popup_handlers(bContext *C, ListBase *handlers, uiPopupBlockHandle *
void UI_remove_popup_handlers(ListBase *handlers, uiPopupBlockHandle *popup)
{
- WM_event_remove_ui_handler(handlers, ui_handler_popup, ui_handler_remove_popup, popup, 0);
+ WM_event_remove_ui_handler(handlers, ui_handler_popup, ui_handler_remove_popup, popup, FALSE);
}
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index e9186aff666..385f74acbd2 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -533,7 +533,8 @@ static void init_internal_icons(void)
}
}
if (bbuf == NULL)
- bbuf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons_png, datatoc_blender_icons_png_size, IB_rect, "<blender icons>");
+ bbuf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons_png,
+ datatoc_blender_icons_png_size, IB_rect, "<blender icons>");
if (bbuf) {
/* free existing texture if any */
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 9e073055fc3..2c4ec9ac482 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -428,7 +428,8 @@ void ui_but_search_test(uiBut *but);
typedef uiBlock * (*uiBlockHandleCreateFunc)(struct bContext *C, struct uiPopupBlockHandle *handle, void *arg1);
uiPopupBlockHandle *ui_popup_block_create(struct bContext *C, struct ARegion *butregion, uiBut *but,
- uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func, void *arg);
+ uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func,
+ void *arg);
uiPopupBlockHandle *ui_popup_menu_create(struct bContext *C, struct ARegion *butregion, uiBut *but,
uiMenuCreateFunc create_func, void *arg, char *str);
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 6d2ac388374..f2a43580fd8 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -589,9 +589,7 @@ static void ui_editsource_active_but_set(uiBut *but)
ui_editsource_info = MEM_callocN(sizeof(uiEditSourceStore), __func__);
memcpy(&ui_editsource_info->but_orig, but, sizeof(uiBut));
- ui_editsource_info->hash = BLI_ghash_new(BLI_ghashutil_ptrhash,
- BLI_ghashutil_ptrcmp,
- __func__);
+ ui_editsource_info->hash = BLI_ghash_ptr_new(__func__);
}
static void ui_editsource_active_but_clear(void)
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 0be1761eaf5..dc2c3b4eea9 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -1253,7 +1253,8 @@ static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelStat
if (data && data->state != PANEL_STATE_ANIMATION) {
/* XXX:
* - the panel tabbing function call below (test_add_new_tabs()) has been commented out
- * "It is too easy to do by accident when reordering panels, is very hard to control and use, and has no real benefit." - BillRey
+ * "It is too easy to do by accident when reordering panels,
+ * is very hard to control and use, and has no real benefit." - BillRey
* Aligorith, 2009Sep
*/
//test_add_new_tabs(ar); // also copies locations of tabs in dragged panel
@@ -1274,7 +1275,7 @@ static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelStat
MEM_freeN(data);
pa->activedata = NULL;
- WM_event_remove_ui_handler(&win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa, 0);
+ WM_event_remove_ui_handler(&win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa, FALSE);
}
else {
if (!data) {
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 9bcda7d86ed..a36b2dd2c45 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -429,7 +429,8 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
/* create tooltip data */
data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
- /* special case, enum rna buttons only have enum item description, use general enum description too before the specific one */
+ /* special case, enum rna buttons only have enum item description,
+ * use general enum description too before the specific one */
if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) {
const char *descr = RNA_property_description(but->rnaprop);
if (descr && descr[0]) {
@@ -448,7 +449,8 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
for (i = 0; i < totitem; i++) {
if (item[i].identifier[0] && item[i].value == value) {
if (item[i].description && item[i].description[0]) {
- BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "%s: %s", item[i].name, item[i].description);
+ BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "%s: %s",
+ item[i].name, item[i].description);
data->color_id[data->totline] = UI_TIP_LC_SUBMENU;
data->totline++;
}
@@ -496,7 +498,9 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
if (unit_type == PROP_UNIT_ROTATION) {
if (RNA_property_type(but->rnaprop) == PROP_FLOAT) {
- float value = RNA_property_array_check(but->rnaprop) ? RNA_property_float_get_index(&but->rnapoin, but->rnaprop, but->rnaindex) : RNA_property_float_get(&but->rnapoin, but->rnaprop);
+ float value = RNA_property_array_check(but->rnaprop) ?
+ RNA_property_float_get_index(&but->rnapoin, but->rnaprop, but->rnaindex) :
+ RNA_property_float_get(&but->rnapoin, but->rnaprop);
BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Radians: %f"), value);
data->color_id[data->totline] = UI_TIP_LC_NORMAL;
data->totline++;
@@ -514,7 +518,8 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
/* rna info */
if ((U.flag & USER_TOOLTIPS_PYTHON) == 0) {
- BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Python: %s.%s"), RNA_struct_identifier(but->rnapoin.type), RNA_property_identifier(but->rnaprop));
+ BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Python: %s.%s"),
+ RNA_struct_identifier(but->rnapoin.type), RNA_property_identifier(but->rnaprop));
data->color_id[data->totline] = UI_TIP_LC_PYTHON;
data->totline++;
}
@@ -1553,7 +1558,9 @@ void ui_popup_block_scrolltest(uiBlock *block)
}
}
-uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut *but, uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func, void *arg)
+uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut *but,
+ uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func,
+ void *arg)
{
wmWindow *window = CTX_wm_window(C);
static ARegionType type;
@@ -1881,7 +1888,8 @@ static void ui_update_block_buts_rgb(uiBlock *block, const float rgb[3])
if (rgb_gamma[1] > 1.0f) rgb_gamma[1] = modf(rgb_gamma[1], &intpart);
if (rgb_gamma[2] > 1.0f) rgb_gamma[2] = modf(rgb_gamma[2], &intpart);
- BLI_snprintf(col, sizeof(col), "%02X%02X%02X", FTOCHAR(rgb_gamma[0]), FTOCHAR(rgb_gamma[1]), FTOCHAR(rgb_gamma[2]));
+ BLI_snprintf(col, sizeof(col), "%02X%02X%02X",
+ FTOCHAR(rgb_gamma[0]), FTOCHAR(rgb_gamma[1]), FTOCHAR(rgb_gamma[2]));
strcpy(bt->poin, col);
}
@@ -2382,7 +2390,8 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
return pup->block;
}
-uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut *but, uiMenuCreateFunc menu_func, void *arg, char *str)
+uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut *but,
+ uiMenuCreateFunc menu_func, void *arg, char *str)
{
wmWindow *window = CTX_wm_window(C);
uiStyle *style = UI_GetStyle();
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index d49b77c7005..a9ec893adb7 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -2829,9 +2829,9 @@ static int knifetool_init(bContext *C, wmOperator *op, int UNUSED(do_cut))
kcd->kverts = BLI_mempool_create(sizeof(KnifeVert), 1, 512, BLI_MEMPOOL_ALLOW_ITER);
kcd->kedges = BLI_mempool_create(sizeof(KnifeEdge), 1, 512, BLI_MEMPOOL_ALLOW_ITER);
- kcd->origedgemap = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "knife origedgemap");
- kcd->origvertmap = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "knife origvertmap");
- kcd->kedgefacemap = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "knife origvertmap");
+ kcd->origedgemap = BLI_ghash_ptr_new("knife origedgemap");
+ kcd->origvertmap = BLI_ghash_ptr_new("knife origvertmap");
+ kcd->kedgefacemap = BLI_ghash_ptr_new("knife origvertmap");
/* cut all the way through the mesh if use_occlude_geometry button not pushed */
kcd->cut_through = !RNA_boolean_get(op->ptr, "use_occlude_geometry");
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index f1393e4def1..2df89a3df6c 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -834,7 +834,12 @@ static int edbm_select_similar_exec(bContext *C, wmOperator *op)
static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop),
int *free)
{
- Object *obedit = CTX_data_edit_object(C);
+ Object *obedit;
+
+ if (!C) /* needed for docs and i18n tools */
+ return prop_similar_types;
+
+ obedit = CTX_data_edit_object(C);
if (obedit && obedit->type == OB_MESH) {
EnumPropertyItem *item = NULL;
@@ -862,7 +867,7 @@ static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *UNUS
return item;
}
-
+
return NULL;
}
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 9be71218da0..57f663aa571 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -1344,7 +1344,8 @@ void MESH_OT_flip_normals(wmOperatorType *ot)
static const EnumPropertyItem direction_items[] = {
{DIRECTION_CW, "CW", 0, "Clockwise", ""},
{DIRECTION_CCW, "CCW", 0, "Counter Clockwise", ""},
- {0, NULL, 0, NULL, NULL}};
+ {0, NULL, 0, NULL, NULL}
+};
/* only accepts 1 selected edge, or 2 selected faces */
static int edbm_edge_rotate_selected_exec(bContext *C, wmOperator *op)
@@ -1957,7 +1958,8 @@ static EnumPropertyItem merge_type_items[] = {
{3, "CENTER", 0, "At Center", ""},
{4, "CURSOR", 0, "At Cursor", ""},
{5, "COLLAPSE", 0, "Collapse", ""},
- {0, NULL, 0, NULL, NULL}};
+ {0, NULL, 0, NULL, NULL}
+};
static EnumPropertyItem *merge_type_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
{
@@ -2377,13 +2379,15 @@ void MESH_OT_select_axis(wmOperatorType *ot)
{0, "POSITIVE", 0, "Positive Axis", ""},
{1, "NEGATIVE", 0, "Negative Axis", ""},
{-1, "ALIGNED", 0, "Aligned Axis", ""},
- {0, NULL, 0, NULL, NULL}};
+ {0, NULL, 0, NULL, NULL}
+ };
static EnumPropertyItem axis_items_xyz[] = {
{0, "X_AXIS", 0, "X Axis", ""},
{1, "Y_AXIS", 0, "Y Axis", ""},
{2, "Z_AXIS", 0, "Z Axis", ""},
- {0, NULL, 0, NULL, NULL}};
+ {0, NULL, 0, NULL, NULL}
+ };
/* identifiers */
ot->name = "Select Axis";
@@ -2685,7 +2689,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
}
/* get the cut curve */
- RNA_BEGIN (op->ptr, itemptr, "path")
+ RNA_BEGIN(op->ptr, itemptr, "path")
{
RNA_float_get_array(&itemptr, "loc", (float *)&curve[len]);
len++;
@@ -2700,7 +2704,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
}
/* the floating point coordinates of verts in screen space will be stored in a hash table according to the vertices pointer */
- gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "knife cut exec");
+ gh = BLI_ghash_ptr_new("knife cut exec");
for (bv = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); bv; bv = BM_iter_step(&iter)) {
scr = MEM_mallocN(sizeof(float) * 2, "Vertex Screen Coordinates");
copy_v3_v3(co, bv->co);
@@ -3566,7 +3570,8 @@ void MESH_OT_select_by_number_vertices(wmOperatorType *ot)
{1, "EQUAL", 0, "Equal To", ""},
{2, "GREATER", 0, "Greater Than", ""},
{3, "NOTEQUAL", 0, "Not Equal To", ""},
- {0, NULL, 0, NULL, NULL}};
+ {0, NULL, 0, NULL, NULL}
+ };
/* identifiers */
ot->name = "Select by Number of Vertices";
@@ -3889,12 +3894,12 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const
mp = map[0] = MEM_callocN(sizeof(int) * totelem[0], "sort_bmelem vert map");
BM_ITER_MESH_INDEX (ve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
- if (BM_elem_flag_test(ve, flag)) {
- mp[affected[0]++] = i;
- }
- else {
- *tb = i;
- tb++;
+ if (BM_elem_flag_test(ve, flag)) {
+ mp[affected[0]++] = i;
+ }
+ else {
+ *tb = i;
+ tb++;
}
}
}
@@ -3904,12 +3909,12 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const
mp = map[1] = MEM_callocN(sizeof(int) * totelem[1], "sort_bmelem edge map");
BM_ITER_MESH_INDEX (ed, &iter, em->bm, BM_EDGES_OF_MESH, i) {
- if (BM_elem_flag_test(ed, flag)) {
- mp[affected[1]++] = i;
- }
- else {
- *tb = i;
- tb++;
+ if (BM_elem_flag_test(ed, flag)) {
+ mp[affected[1]++] = i;
+ }
+ else {
+ *tb = i;
+ tb++;
}
}
}
@@ -3919,17 +3924,17 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const
mp = map[2] = MEM_callocN(sizeof(int) * totelem[2], "sort_bmelem face map");
BM_ITER_MESH_INDEX (fa, &iter, em->bm, BM_FACES_OF_MESH, i) {
- if (BM_elem_flag_test(fa, flag)) {
- mp[affected[2]++] = i;
- }
- else {
- *tb = i;
- tb++;
+ if (BM_elem_flag_test(fa, flag)) {
+ mp[affected[2]++] = i;
+ }
+ else {
+ *tb = i;
+ tb++;
}
}
}
- for (j = 3; j--;) {
+ for (j = 3; j--; ) {
int tot = totelem[j];
int aff = affected[j];
tb = tbuf[j];
@@ -4069,7 +4074,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const
/* printf("%d edges: %d to be affected…\n", totelem[1], affected[1]);*/
/* printf("%d faces: %d to be affected…\n", totelem[2], affected[2]);*/
if (affected[0] == 0 && affected[1] == 0 && affected[2] == 0) {
- for (j = 3; j--;) {
+ for (j = 3; j--; ) {
if (pblock[j])
MEM_freeN(pblock[j]);
if (sblock[j])
@@ -4081,7 +4086,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const
}
/* Sort affected elements, and populate mapping arrays, if needed. */
- for (j = 3; j--;) {
+ for (j = 3; j--; ) {
pb = pblock[j];
sb = sblock[j];
if (pb && sb && !map[j]) {
@@ -4114,7 +4119,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const
BM_mesh_remap(em->bm, map[0], map[1], map[2]);
/* DAG_id_tag_update(ob->data, 0);*/
- for (j = 3; j--;) {
+ for (j = 3; j--; ) {
if (map[j])
MEM_freeN(map[j]);
}
@@ -4303,21 +4308,79 @@ void MESH_OT_noise(wmOperatorType *ot)
RNA_def_float(ot->srna, "factor", 0.1f, -FLT_MAX, FLT_MAX, "Factor", "", 0.0f, 1.0f);
}
-/* bevel! yay!!*/
-static int edbm_bevel_exec(bContext *C, wmOperator *op)
+typedef struct {
+ BMEditMesh *em;
+ BMBackup mesh_backup;
+ float *weights;
+ int li;
+ int mcenter[2];
+ float initial_length;
+ int is_modal;
+} BevelData;
+
+#define HEADER_LENGTH 180
+
+static void edbm_bevel_update_header(wmOperator *op, bContext *C)
+{
+ static char str[] = "Confirm: Enter/LClick, Cancel: (Esc/RClick), factor: %f, , Use Dist (D): %s: Use Even (E): %s";
+
+ char msg[HEADER_LENGTH];
+ ScrArea *sa = CTX_wm_area(C);
+
+ if (sa) {
+ BLI_snprintf(msg, HEADER_LENGTH, str,
+ RNA_float_get(op->ptr, "percent"),
+ RNA_boolean_get(op->ptr, "use_dist") ? "On" : "Off",
+ RNA_boolean_get(op->ptr, "use_even") ? "On" : "Off"
+ );
+
+ ED_area_headerprint(sa, msg);
+ }
+}
+
+static void edbm_bevel_recalc_weights(wmOperator *op)
+{
+ float df, s, ftot;
+ int i;
+ int recursion = 1; /* RNA_int_get(op->ptr, "recursion"); */ /* temp removed, see comment below */
+ BevelData *opdata = op->customdata;
+
+ if (opdata->weights) {
+ /* TODO should change to free only when new recursion is greater than old */
+ MEM_freeN(opdata->weights);
+ }
+ opdata->weights = MEM_mallocN(sizeof(float) * recursion, "bevel weights");
+
+ /* ugh, stupid math depends somewhat on angles!*/
+ /* dfac = 1.0/(float)(recursion + 1); */ /* UNUSED */
+ df = 1.0;
+ for (i = 0, ftot = 0.0f; i < recursion; i++) {
+ s = powf(df, 1.25f);
+
+ opdata->weights[i] = s;
+ ftot += s;
+
+ df *= 2.0f;
+ }
+
+ mul_vn_fl(opdata->weights, recursion, 1.0f / (float)ftot);
+}
+
+static int edbm_bevel_init(bContext *C, wmOperator *op, int is_modal)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BMEdit_FromObject(obedit);
BMIter iter;
BMEdge *eed;
- BMOperator bmop;
- float factor = RNA_float_get(op->ptr, "percent") /*, dfac */ /* UNUSED */, df, s;
- int i, recursion = 1; /* RNA_int_get(op->ptr, "recursion"); */ /* temp removed, see comment below */
- const int use_even = RNA_boolean_get(op->ptr, "use_even");
- const int use_dist = RNA_boolean_get(op->ptr, "use_dist");
- float *w = NULL, ftot;
+ BevelData *opdata;
int li;
+ if (em == NULL) {
+ return 0;
+ }
+
+ op->customdata = opdata = MEM_mallocN(sizeof(BevelData), "beveldata_mesh_operator");
+
BM_data_layer_add(em->bm, &em->bm->edata, CD_PROP_FLT);
li = CustomData_number_of_layers(&em->bm->edata, CD_PROP_FLT) - 1;
@@ -4328,52 +4391,201 @@ static int edbm_bevel_exec(bContext *C, wmOperator *op)
*dv = d;
}
- if (em == NULL) {
- return OPERATOR_CANCELLED;
- }
+ opdata->em = em;
+ opdata->li = li;
+ opdata->weights = NULL;
+ opdata->is_modal = is_modal;
- w = MEM_mallocN(sizeof(float) * recursion, "bevel weights");
+ /* avoid the cost of allocating a bm copy */
+ if (is_modal)
+ opdata->mesh_backup = EDBM_redo_state_store(em);
+ edbm_bevel_recalc_weights(op);
- /* ugh, stupid math depends somewhat on angles!*/
- /* dfac = 1.0/(float)(recursion + 1); */ /* UNUSED */
- df = 1.0;
- for (i = 0, ftot = 0.0f; i < recursion; i++) {
- s = powf(df, 1.25f);
+ return 1;
+}
- w[i] = s;
- ftot += s;
+static int edbm_bevel_calc(bContext *C, wmOperator *op)
+{
+ BevelData *opdata = op->customdata;
+ BMEditMesh *em = opdata->em;
+ BMOperator bmop;
+ int i;
- df *= 2.0f;
- }
+ float factor = RNA_float_get(op->ptr, "percent") /*, dfac */ /* UNUSED */;
+ int recursion = 1; /* RNA_int_get(op->ptr, "recursion"); */ /* temp removed, see comment below */
+ const int use_even = RNA_boolean_get(op->ptr, "use_even");
+ const int use_dist = RNA_boolean_get(op->ptr, "use_dist");
- mul_vn_fl(w, recursion, 1.0f / (float)ftot);
+ /* revert to original mesh */
+ if (opdata->is_modal) {
+ EDBM_redo_state_restore(opdata->mesh_backup, em, FALSE);
+ }
for (i = 0; i < recursion; i++) {
- float fac = w[recursion - i - 1] * factor;
+ float fac = opdata->weights[recursion - i - 1] * factor;
+
if (!EDBM_op_init(em, &bmop, op,
"bevel geom=%hev percent=%f lengthlayer=%i use_lengths=%b use_even=%b use_dist=%b",
- BM_ELEM_SELECT, fac, li, TRUE, use_even, use_dist))
+ BM_ELEM_SELECT, fac, opdata->li, TRUE, use_even, use_dist))
{
- return OPERATOR_CANCELLED;
+ return 0;
}
BMO_op_exec(em->bm, &bmop);
if (!EDBM_op_finish(em, &bmop, op, TRUE))
- return OPERATOR_CANCELLED;
+ return 0;
}
- BM_data_layer_free_n(em->bm, &em->bm->edata, CD_PROP_FLT, li);
+ EDBM_mesh_normals_update(opdata->em);
- MEM_freeN(w);
+ EDBM_update_generic(C, opdata->em, TRUE);
- EDBM_mesh_normals_update(em);
+ return 1;
+}
- EDBM_update_generic(C, em, TRUE);
+static void edbm_bevel_exit(bContext *C, wmOperator *op)
+{
+ BevelData *opdata = op->customdata;
+
+ ScrArea *sa = CTX_wm_area(C);
+
+ if (sa) {
+ ED_area_headerprint(sa, NULL);
+ }
+ BM_data_layer_free_n(opdata->em->bm, &opdata->em->bm->edata, CD_PROP_FLT, opdata->li);
+
+ if (opdata->weights)
+ MEM_freeN(opdata->weights);
+ if (opdata->is_modal) {
+ EDBM_redo_state_free(&opdata->mesh_backup, NULL, FALSE);
+ }
+ MEM_freeN(opdata);
+ op->customdata = NULL;
+}
+
+static int edbm_bevel_cancel(bContext *C, wmOperator *op)
+{
+ BevelData *opdata = op->customdata;
+ if (opdata->is_modal) {
+ EDBM_redo_state_free(&opdata->mesh_backup, opdata->em, TRUE);
+ EDBM_update_generic(C, opdata->em, FALSE);
+ }
+
+ edbm_bevel_exit(C, op);
+
+ /* need to force redisplay or we may still view the modified result */
+ ED_region_tag_redraw(CTX_wm_region(C));
+ return OPERATOR_CANCELLED;
+}
+
+/* bevel! yay!!*/
+static int edbm_bevel_exec(bContext *C, wmOperator *op)
+{
+ if (!edbm_bevel_init(C, op, FALSE)) {
+ edbm_bevel_exit(C, op);
+ return OPERATOR_CANCELLED;
+ }
+
+ if (!edbm_bevel_calc(C, op)) {
+ edbm_bevel_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
+
+ edbm_bevel_exit(C, op);
return OPERATOR_FINISHED;
}
+static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ /* TODO make modal keymap (see fly mode) */
+ BevelData *opdata;
+ float mlen[2];
+
+ if (!edbm_bevel_init(C, op, TRUE))
+ return OPERATOR_CANCELLED;
+
+ /* initialize mouse values */
+ opdata = op->customdata;
+
+ calculateTransformCenter(C, V3D_CENTROID, NULL, opdata->mcenter);
+ mlen[0] = opdata->mcenter[0] - event->mval[0];
+ mlen[1] = opdata->mcenter[1] - event->mval[1];
+ opdata->initial_length = len_v2(mlen);
+
+ edbm_bevel_update_header(op, C);
+
+ if (!edbm_bevel_calc(C, op)) {
+ edbm_bevel_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
+
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ BevelData *opdata = op->customdata;
+// Scene *scene = CTX_data_scene(C);
+
+ switch (event->type) {
+ case ESCKEY:
+ case RIGHTMOUSE:
+ edbm_bevel_cancel(C, op);
+ return OPERATOR_CANCELLED;
+
+ case MOUSEMOVE:
+ {
+ float factor;
+ float mdiff[2];
+
+ mdiff[0] = opdata->mcenter[0] - event->mval[0];
+ mdiff[1] = opdata->mcenter[1] - event->mval[1];
+
+ factor = len_v2(mdiff) / opdata->initial_length;
+ factor = MAX2(1.0 - factor, 0.0);
+
+ RNA_float_set(op->ptr, "percent", factor);
+
+ edbm_bevel_calc(C, op);
+ edbm_bevel_update_header(op, C);
+ return OPERATOR_RUNNING_MODAL;
+ }
+
+ case LEFTMOUSE:
+ case PADENTER:
+ case RETKEY:
+ edbm_bevel_calc(C, op);
+ edbm_bevel_exit(C, op);
+ return OPERATOR_FINISHED;
+
+ case EKEY:
+ if (event->val == KM_PRESS) {
+ int use_even = RNA_boolean_get(op->ptr, "use_even");
+ RNA_boolean_set(op->ptr, "use_even", !use_even);
+
+ edbm_bevel_calc(C, op);
+ edbm_bevel_update_header(op, C);
+ }
+ return OPERATOR_RUNNING_MODAL;
+
+ case DKEY:
+ if (event->val == KM_PRESS) {
+ int use_dist = RNA_boolean_get(op->ptr, "use_dist");
+ RNA_boolean_set(op->ptr, "use_dist", !use_dist);
+
+ edbm_bevel_calc(C, op);
+ edbm_bevel_update_header(op, C);
+ }
+ return OPERATOR_RUNNING_MODAL;
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
void MESH_OT_bevel(wmOperatorType *ot)
{
/* identifiers */
@@ -4383,12 +4595,15 @@ void MESH_OT_bevel(wmOperatorType *ot)
/* api callbacks */
ot->exec = edbm_bevel_exec;
+ ot->invoke = edbm_bevel_invoke;
+ ot->modal = edbm_bevel_modal;
+ ot->cancel = edbm_bevel_cancel;
ot->poll = ED_operator_editmesh;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_float(ot->srna, "percent", 0.5f, -FLT_MAX, FLT_MAX, "Percentage", "", 0.0f, 1.0f);
+ RNA_def_float(ot->srna, "percent", 0.0f, -FLT_MAX, FLT_MAX, "Percentage", "", 0.0f, 1.0f);
// XXX, disabled for 2.63 release, needs to work much better without overlap before we can give to users.
// RNA_def_int(ot->srna, "recursion", 1, 1, 50, "Recursion Level", "Recursion Level", 1, 8);
@@ -4427,20 +4642,112 @@ void MESH_OT_bridge_edge_loops(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "inside", 0, "Inside", "");
}
+typedef struct {
+ float old_thickness;
+ float old_depth;
+ int mcenter[2];
+ int modify_depth;
+ int is_modal;
+ float initial_length;
+ BMBackup backup;
+ BMEditMesh *em;
+} InsetData;
+static void edbm_inset_update_header(wmOperator *op, bContext *C)
+{
+ InsetData *opdata = op->customdata;
-static int edbm_inset_exec(bContext *C, wmOperator *op)
+ static char str[] = "Confirm: Enter/LClick, Cancel: (Esc/RClick), thickness: %f, depth (Ctrl to tweak): %f (%s), Outset (O): (%s)";
+
+ char msg[HEADER_LENGTH];
+ ScrArea *sa = CTX_wm_area(C);
+
+ if (sa) {
+ BLI_snprintf(msg, HEADER_LENGTH, str,
+ RNA_float_get(op->ptr, "thickness"),
+ RNA_float_get(op->ptr, "depth"),
+ opdata->modify_depth ? "On" : "Off",
+ RNA_boolean_get(op->ptr, "use_outset") ? "On" : "Off"
+ );
+
+ ED_area_headerprint(sa, msg);
+ }
+}
+
+
+static int edbm_inset_init(bContext *C, wmOperator *op, int is_modal)
{
+ InsetData *opdata;
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BMEdit_FromObject(obedit);
+
+ op->customdata = opdata = MEM_mallocN(sizeof(InsetData), "inset_operator_data");
+
+ opdata->old_thickness = 0.01;
+ opdata->old_depth = 0.0;
+ opdata->modify_depth = FALSE;
+ opdata->is_modal = is_modal;
+ opdata->em = em;
+
+ if (is_modal)
+ opdata->backup = EDBM_redo_state_store(em);
+
+ return 1;
+}
+
+static void edbm_inset_exit(bContext *C, wmOperator *op)
+{
+ InsetData *opdata;
+ ScrArea *sa = CTX_wm_area(C);
+
+ opdata = op->customdata;
+
+ if (opdata->is_modal)
+ EDBM_redo_state_free(&opdata->backup, NULL, FALSE);
+
+ if (sa) {
+ ED_area_headerprint(sa, NULL);
+ }
+ MEM_freeN(op->customdata);
+}
+
+static int edbm_inset_cancel(bContext *C, wmOperator *op)
+{
+ InsetData *opdata;
+
+ opdata = op->customdata;
+ if (opdata->is_modal) {
+ EDBM_redo_state_free(&opdata->backup, opdata->em, TRUE);
+ EDBM_update_generic(C, opdata->em, FALSE);
+ }
+
+ edbm_inset_exit(C, op);
+
+ /* need to force redisplay or we may still view the modified result */
+ ED_region_tag_redraw(CTX_wm_region(C));
+ return OPERATOR_CANCELLED;
+}
+
+static int edbm_inset_calc(bContext *C, wmOperator *op)
+{
+ InsetData *opdata;
+ BMEditMesh *em;
BMOperator bmop;
- const int use_boundary = RNA_boolean_get(op->ptr, "use_boundary");
- const int use_even_offset = RNA_boolean_get(op->ptr, "use_even_offset");
- const int use_relative_offset = RNA_boolean_get(op->ptr, "use_relative_offset");
- const float thickness = RNA_float_get(op->ptr, "thickness");
- const float depth = RNA_float_get(op->ptr, "depth");
- const int use_outset = RNA_boolean_get(op->ptr, "use_outset");
- const int use_select_inset = RNA_boolean_get(op->ptr, "use_select_inset"); /* not passed onto the BMO */
+
+ int use_boundary = RNA_boolean_get(op->ptr, "use_boundary");
+ int use_even_offset = RNA_boolean_get(op->ptr, "use_even_offset");
+ int use_relative_offset = RNA_boolean_get(op->ptr, "use_relative_offset");
+ float thickness = RNA_float_get(op->ptr, "thickness");
+ float depth = RNA_float_get(op->ptr, "depth");
+ int use_outset = RNA_boolean_get(op->ptr, "use_outset");
+ int use_select_inset = RNA_boolean_get(op->ptr, "use_select_inset"); /* not passed onto the BMO */
+
+ opdata = op->customdata;
+ em = opdata->em;
+
+ if (opdata->is_modal) {
+ EDBM_redo_state_restore(opdata->backup, em, FALSE);
+ }
EDBM_op_init(em, &bmop, op,
"inset faces=%hf use_boundary=%b use_even_offset=%b use_relative_offset=%b "
@@ -4463,14 +4770,142 @@ static int edbm_inset_exec(bContext *C, wmOperator *op)
}
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
- return OPERATOR_CANCELLED;
+ return 0;
}
else {
EDBM_update_generic(C, em, TRUE);
- return OPERATOR_FINISHED;
+ return 1;
+ }
+}
+
+static int edbm_inset_exec(bContext *C, wmOperator *op)
+{
+ edbm_inset_init(C, op, FALSE);
+
+ if (!edbm_inset_calc(C, op)) {
+ edbm_inset_exit(C, op);
+ return OPERATOR_CANCELLED;
}
+
+ edbm_inset_exit(C, op);
+ return OPERATOR_FINISHED;
}
+static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ InsetData *opdata;
+ float mlen[2];
+
+ edbm_inset_init(C, op, TRUE);
+
+ opdata = op->customdata;
+
+ calculateTransformCenter(C, V3D_CENTROID, NULL, opdata->mcenter);
+ /* initialize mouse values */
+ mlen[0] = opdata->mcenter[0] - event->mval[0];
+ mlen[1] = opdata->mcenter[1] - event->mval[1];
+ opdata->initial_length = len_v2(mlen);
+
+ edbm_inset_calc(C, op);
+
+ edbm_inset_update_header(op, C);
+
+ WM_event_add_modal_handler(C, op);
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ InsetData *opdata;
+
+ opdata = op->customdata;
+
+ switch (event->type) {
+ case ESCKEY:
+ case RIGHTMOUSE:
+ edbm_inset_cancel(C, op);
+ return OPERATOR_CANCELLED;
+
+ case MOUSEMOVE:
+ {
+ float mdiff[2];
+ float amount;
+
+ mdiff[0] = opdata->mcenter[0] - event->mval[0];
+ mdiff[1] = opdata->mcenter[1] - event->mval[1];
+
+ if (opdata->modify_depth) {
+ amount = opdata->old_depth + (len_v2(mdiff)
+ - opdata->initial_length) / opdata->initial_length;
+ RNA_float_set(op->ptr, "depth", amount);
+ }
+ else {
+ amount = opdata->old_thickness - (len_v2(mdiff)
+ - opdata->initial_length) / opdata->initial_length;
+ amount = MAX2(amount, 0.0);
+
+ RNA_float_set(op->ptr, "thickness", amount);
+ }
+
+ if (edbm_inset_calc(C, op)) {
+ edbm_inset_update_header(op, C);
+ return OPERATOR_RUNNING_MODAL;
+ }
+ else {
+ edbm_inset_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ }
+
+ case LEFTMOUSE:
+ case PADENTER:
+ case RETKEY:
+ edbm_inset_calc(C, op);
+ edbm_inset_exit(C, op);
+ return OPERATOR_FINISHED;
+
+
+ case LEFTCTRLKEY:
+ case RIGHTCTRLKEY:
+ {
+ float mlen[2];
+
+ mlen[0] = opdata->mcenter[0] - event->mval[0];
+ mlen[1] = opdata->mcenter[1] - event->mval[1];
+
+ if (event->val == KM_PRESS) {
+ opdata->old_thickness = RNA_float_get(op->ptr, "thickness");
+ opdata->modify_depth = TRUE;
+ }
+ else {
+ opdata->old_depth = RNA_float_get(op->ptr, "depth");
+ opdata->modify_depth = FALSE;
+ }
+ opdata->initial_length = len_v2(mlen);
+
+ edbm_inset_update_header(op, C);
+ return OPERATOR_RUNNING_MODAL;
+ }
+
+ case OKEY:
+ if (event->val == KM_PRESS) {
+ int use_outset = RNA_boolean_get(op->ptr, "use_outset");
+ RNA_boolean_set(op->ptr, "use_outset", !use_outset);
+ if (edbm_inset_calc(C, op)) {
+ edbm_inset_update_header(op, C);
+ return OPERATOR_RUNNING_MODAL;
+ }
+ else {
+ edbm_inset_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ }
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+
void MESH_OT_inset(wmOperatorType *ot)
{
PropertyRNA *prop;
@@ -4481,7 +4916,10 @@ void MESH_OT_inset(wmOperatorType *ot)
ot->description = "Inset new faces into selected faces";
/* api callbacks */
+ ot->invoke = edbm_inset_invoke;
+ ot->modal = edbm_inset_modal;
ot->exec = edbm_inset_exec;
+ ot->cancel = edbm_inset_cancel;
ot->poll = ED_operator_editmesh;
/* flags */
@@ -4578,9 +5016,9 @@ static int edbm_convex_hull_exec(bContext *C, wmOperator *op)
BMOperator bmop;
EDBM_op_init(em, &bmop, op, "convex_hull input=%hvef "
- "use_existing_faces=%b",
- BM_ELEM_SELECT,
- RNA_boolean_get(op->ptr, "use_existing_faces"));
+ "use_existing_faces=%b",
+ BM_ELEM_SELECT,
+ RNA_boolean_get(op->ptr, "use_existing_faces"));
BMO_op_exec(em->bm, &bmop);
/* Hull fails if input is coplanar */
@@ -4647,20 +5085,20 @@ void MESH_OT_convex_hull(wmOperatorType *ot)
/* props */
RNA_def_boolean(ot->srna, "delete_unused", TRUE,
- "Delete Unused",
- "Delete selected elements that are not used by the hull");
+ "Delete Unused",
+ "Delete selected elements that are not used by the hull");
RNA_def_boolean(ot->srna, "use_existing_faces", TRUE,
- "Use Existing Faces",
- "Skip hull triangles that are covered by a pre-existing face");
+ "Use Existing Faces",
+ "Skip hull triangles that are covered by a pre-existing face");
RNA_def_boolean(ot->srna, "make_holes", FALSE,
- "Make Holes",
- "Delete selected faces that are used by the hull");
+ "Make Holes",
+ "Delete selected faces that are used by the hull");
RNA_def_boolean(ot->srna, "join_triangles", TRUE,
- "Join Triangles",
- "Merge adjacent triangles into quads");
+ "Join Triangles",
+ "Merge adjacent triangles into quads");
join_triangle_props(ot);
}
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 533ead1ff29..c3fbb2e8c16 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -58,6 +58,52 @@
#include "mesh_intern.h"
+/* mesh backup implementation. This would greatly benefit from some sort of binary diffing
+ * just as the undo stack would. So leaving this as an interface for further work */
+
+BMBackup EDBM_redo_state_store(BMEditMesh *em)
+{
+ BMBackup backup;
+ backup.bmcopy = BM_mesh_copy(em->bm);
+ return backup;
+}
+
+void EDBM_redo_state_restore(BMBackup backup, BMEditMesh *em, int recalctess)
+{
+ BMesh *tmpbm;
+ if (!em || !backup.bmcopy)
+ return;
+
+ BM_mesh_data_free(em->bm);
+ tmpbm = BM_mesh_copy(backup.bmcopy);
+ *em->bm = *tmpbm;
+ MEM_freeN(tmpbm);
+ tmpbm = NULL;
+
+ if (recalctess)
+ BMEdit_RecalcTessellation(em);
+}
+
+void EDBM_redo_state_free(BMBackup *backup, BMEditMesh *em, int recalctess)
+{
+ if (em && backup->bmcopy) {
+ BM_mesh_data_free(em->bm);
+ *em->bm = *backup->bmcopy;
+ }
+ else if (backup->bmcopy) {
+ BM_mesh_data_free(backup->bmcopy);
+ }
+
+ if (backup->bmcopy)
+ MEM_freeN(backup->bmcopy);
+ backup->bmcopy = NULL;
+
+ if (recalctess && em)
+ BMEdit_RecalcTessellation(em);
+}
+
+
+
void EDBM_mesh_normals_update(BMEditMesh *em)
{
BM_mesh_normals_update(em->bm, TRUE);
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 98dce10779f..a77a6f4b430 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -255,6 +255,8 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
keymap->poll = ED_operator_editmesh;
WM_keymap_add_item(keymap, "MESH_OT_loopcut_slide", RKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_bevel", BKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_inset", IKEY, KM_PRESS, 0, 0);
/* selecting */
/* standard mouse selection goes via space_view3d */
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 466338a736f..69aae5c4f06 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1067,8 +1067,8 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
lb = object_duplilist(scene, base->object);
if (use_hierarchy || use_base_parent) {
- dupli_gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "make_object_duplilist_real dupli_gh");
- parent_gh = BLI_ghash_new(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, "make_object_duplilist_real parent_gh");
+ dupli_gh = BLI_ghash_ptr_new("make_object_duplilist_real dupli_gh");
+ parent_gh = BLI_ghash_pair_new("make_object_duplilist_real parent_gh");
}
for (dob = lb->first; dob; dob = dob->next) {
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index d73b53deecc..7cc11fa0209 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -356,8 +356,15 @@ static void test_constraints(Object *owner, bPoseChannel *pchan)
bActionConstraint *data = curcon->data;
/* validate action */
- if (data->act == NULL)
+ if (data->act == NULL) {
+ /* must have action */
curcon->flag |= CONSTRAINT_DISABLE;
+ }
+ else if (data->act->idroot != ID_OB) {
+ /* only object-rooted actions can be used */
+ data->act = NULL;
+ curcon->flag |= CONSTRAINT_DISABLE;
+ }
}
else if (curcon->type == CONSTRAINT_TYPE_FOLLOWPATH) {
bFollowPathConstraint *data = curcon->data;
@@ -409,12 +416,12 @@ static void test_constraints(Object *owner, bPoseChannel *pchan)
if (data->clip != NULL && data->track[0]) {
MovieTracking *tracking = &data->clip->tracking;
MovieTrackingObject *tracking_object;
-
+
if (data->object[0])
tracking_object = BKE_tracking_named_object(tracking, data->object);
else
tracking_object = BKE_tracking_get_camera_object(tracking);
-
+
if (!tracking_object) {
curcon->flag |= CONSTRAINT_DISABLE;
}
@@ -428,14 +435,14 @@ static void test_constraints(Object *owner, bPoseChannel *pchan)
}
else if (curcon->type == CONSTRAINT_TYPE_CAMERASOLVER) {
bCameraSolverConstraint *data = curcon->data;
-
- if ((data->flag & CAMERASOLVER_ACTIVECLIP) == 0 && data->clip == NULL)
+
+ if ((data->flag & CAMERASOLVER_ACTIVECLIP) == 0 && (data->clip == NULL))
curcon->flag |= CONSTRAINT_DISABLE;
}
else if (curcon->type == CONSTRAINT_TYPE_OBJECTSOLVER) {
bObjectSolverConstraint *data = curcon->data;
-
- if ((data->flag & CAMERASOLVER_ACTIVECLIP) == 0 && data->clip == NULL)
+
+ if ((data->flag & CAMERASOLVER_ACTIVECLIP) == 0 && (data->clip == NULL))
curcon->flag |= CONSTRAINT_DISABLE;
}
diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index 86823be09a4..3a932b58fd9 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -79,8 +79,8 @@
/************************ Exported **************************/
/* simple API for object selection, rather than just using the flag
-* this takes into account the 'restrict selection in 3d view' flag.
-* deselect works always, the restriction just prevents selection */
+ * this takes into account the 'restrict selection in 3d view' flag.
+ * deselect works always, the restriction just prevents selection */
/* Note: send a NC_SCENE|ND_OB_SELECT notifier yourself! (or
* or a NC_SCENE|ND_OB_VISIBLE in case of visibility toggling */
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index 16f62f56505..2e21fe9cdfe 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -361,7 +361,7 @@ void OBJECT_OT_origin_clear(wmOperatorType *ot)
/*************************** Apply Transformation ****************************/
/* use this when the loc/size/rot of the parent has changed but the children
-* should stay in the same place, e.g. for apply-size-rot or object center */
+ * should stay in the same place, e.g. for apply-size-rot or object center */
static void ignore_parent_tx(Main *bmain, Scene *scene, Object *ob)
{
Object workob;
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index 48c35873304..08ccf37265b 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -127,7 +127,7 @@ void ED_render_engine_area_exit(ScrArea *sa)
for (ar = sa->regionbase.first; ar; ar = ar->next) {
RegionView3D *rv3d;
- if (ar->regiontype != RGN_TYPE_WINDOW)
+ if (ar->regiontype != RGN_TYPE_WINDOW || !(ar->regiondata))
continue;
rv3d = ar->regiondata;
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 52e1f90606f..0d5aceb9870 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -2301,7 +2301,7 @@ static int area_join_modal(bContext *C, wmOperator *op, wmEvent *event)
}
else {
/* we are back in the area previously selected for keeping
- * we swap the areas if possible to allow user to choose */
+ * we swap the areas if possible to allow user to choose */
if (jd->sa2 != NULL) {
if (jd->sa1) jd->sa1->flag &= ~AREA_FLAG_DRAWJOINFROM;
if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index c681f8ddb75..ebc255f4e43 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -86,7 +86,7 @@ static int same_snap(Snapshot *snap, Brush *brush, ViewContext *vc)
mtex->rot == snap->rot) &&
/* make brush smaller shouldn't cause a resample */
- ((mtex->brush_map_mode == MTEX_MAP_MODE_FIXED &&
+ ((mtex->brush_map_mode == MTEX_MAP_MODE_VIEW &&
(BKE_brush_size_get(vc->scene, brush) <= snap->BKE_brush_size_get)) ||
(BKE_brush_size_get(vc->scene, brush) == snap->BKE_brush_size_get)) &&
@@ -154,7 +154,7 @@ static int load_tex(Sculpt *sd, Brush *br, ViewContext *vc)
make_snap(&snap, br, vc);
- if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) {
+ if (br->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) {
int s = BKE_brush_size_get(vc->scene, br);
int r = 1;
@@ -239,7 +239,7 @@ static int load_tex(Sculpt *sd, Brush *br, ViewContext *vc)
avg += br->texture_sample_bias;
- if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED)
+ if (br->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW)
avg *= BKE_brush_curve_strength(br, len, 1); /* Falloff curve */
buffer[index] = 255 - (GLubyte)(255 * avg);
@@ -278,7 +278,7 @@ static int load_tex(Sculpt *sd, Brush *br, ViewContext *vc)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) {
+ if (br->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
}
@@ -376,7 +376,7 @@ static void paint_draw_alpha_overlay(Sculpt *sd, Brush *brush,
/* check for overlay mode */
if (!(brush->flag & BRUSH_TEXTURE_OVERLAY) ||
- !(ELEM(brush->mtex.brush_map_mode, MTEX_MAP_MODE_FIXED, MTEX_MAP_MODE_TILED)))
+ !(ELEM(brush->mtex.brush_map_mode, MTEX_MAP_MODE_VIEW, MTEX_MAP_MODE_TILED)))
{
return;
}
@@ -405,7 +405,7 @@ static void paint_draw_alpha_overlay(Sculpt *sd, Brush *brush,
glPushMatrix();
glLoadIdentity();
- if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) {
+ if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) {
/* brush rotation */
glTranslatef(0.5, 0.5, 0);
glRotatef((double)RAD2DEGF((brush->flag & BRUSH_RAKE) ?
diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c
index 87bc89f810c..cd8b9164862 100644
--- a/source/blender/editors/sculpt_paint/paint_hide.c
+++ b/source/blender/editors/sculpt_paint/paint_hide.c
@@ -90,7 +90,7 @@ static int is_effected(PartialVisArea area,
if (area == PARTIALVIS_ALL)
return 1;
else if (area == PARTIALVIS_MASKED) {
- return mask > 0.5;
+ return mask > 0.5f;
}
else {
int inside = planes_contain_v3(planes, 4, co);
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index ead85486ec0..9effba5b433 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -114,24 +114,24 @@
(c)[0]= FTOCHAR((f)[0]); \
(c)[1]= FTOCHAR((f)[1]); \
(c)[2]= FTOCHAR((f)[2]); \
-}
+} (void)0
#define IMAPAINT_FLOAT_RGBA_TO_CHAR(c, f) { \
(c)[0]= FTOCHAR((f)[0]); \
(c)[1]= FTOCHAR((f)[1]); \
(c)[2]= FTOCHAR((f)[2]); \
(c)[3]= FTOCHAR((f)[3]); \
-}
+} (void)0
#define IMAPAINT_CHAR_RGB_TO_FLOAT(f, c) { \
(f)[0]= IMAPAINT_CHAR_TO_FLOAT((c)[0]); \
(f)[1]= IMAPAINT_CHAR_TO_FLOAT((c)[1]); \
(f)[2]= IMAPAINT_CHAR_TO_FLOAT((c)[2]); \
-}
+} (void)0
#define IMAPAINT_CHAR_RGBA_TO_FLOAT(f, c) { \
(f)[0]= IMAPAINT_CHAR_TO_FLOAT((c)[0]); \
(f)[1]= IMAPAINT_CHAR_TO_FLOAT((c)[1]); \
(f)[2]= IMAPAINT_CHAR_TO_FLOAT((c)[2]); \
(f)[3]= IMAPAINT_CHAR_TO_FLOAT((c)[3]); \
-}
+} (void)0
#define IMAPAINT_FLOAT_RGB_COPY(a, b) copy_v3_v3(a, b)
@@ -1547,7 +1547,7 @@ static ProjPixel *project_paint_uvpixel_init(
if (ibuf_other->rect_float) { /* float to char */
float rgba[4];
project_face_pixel(tf_other, ibuf_other, w, side, NULL, rgba);
- IMAPAINT_FLOAT_RGBA_TO_CHAR(((ProjPixelClone *)projPixel)->clonepx.ch, rgba)
+ IMAPAINT_FLOAT_RGBA_TO_CHAR(((ProjPixelClone *)projPixel)->clonepx.ch, rgba);
}
else { /* char to char */
project_face_pixel(tf_other, ibuf_other, w, side, ((ProjPixelClone *)projPixel)->clonepx.ch, NULL);
@@ -4206,7 +4206,7 @@ static void imapaint_ibuf_rgb_get(ImBuf *ibuf, int x, int y, const short is_toru
}
else {
char *rrgb = (char *)ibuf->rect + (ibuf->x * y + x) * 4;
- IMAPAINT_CHAR_RGB_TO_FLOAT(r_rgb, rrgb)
+ IMAPAINT_CHAR_RGB_TO_FLOAT(r_rgb, rrgb);
}
}
static void imapaint_ibuf_rgb_set(ImBuf *ibuf, int x, int y, const short is_torus, const float rgb[3])
@@ -4224,7 +4224,7 @@ static void imapaint_ibuf_rgb_set(ImBuf *ibuf, int x, int y, const short is_toru
}
else {
char *rrgb = (char *)ibuf->rect + (ibuf->x * y + x) * 4;
- IMAPAINT_FLOAT_RGB_TO_CHAR(rrgb, rgb)
+ IMAPAINT_FLOAT_RGB_TO_CHAR(rrgb, rgb);
}
}
@@ -4237,7 +4237,9 @@ static int imapaint_ibuf_add_if(ImBuf *ibuf, unsigned int x, unsigned int y, flo
if (torus) imapaint_ibuf_rgb_get(ibuf, x, y, 1, inrgb);
else return 0;
}
- else imapaint_ibuf_rgb_get(ibuf, x, y, 0, inrgb);
+ else {
+ imapaint_ibuf_rgb_get(ibuf, x, y, 0, inrgb);
+ }
outrgb[0] += inrgb[0];
outrgb[1] += inrgb[1];
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index f8ed20430e7..368729723eb 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -238,7 +238,7 @@ static Brush *brush_tool_toggle(Main *bmain, Brush *brush_orig, const int tool,
if (!brush_orig || brush_tool(brush_orig, tool_offset) != tool) {
Brush *br;
/* if the current brush is not using the desired tool, look
- for one that is */
+ * for one that is */
br = brush_tool_cycle(bmain, brush_orig, tool, tool_offset, ob_mode);
/* store the previously-selected brush */
if (br)
@@ -250,8 +250,8 @@ static Brush *brush_tool_toggle(Main *bmain, Brush *brush_orig, const int tool,
BLI_findindex(bmain->brush.first, brush_orig->toggle_brush) != -1)
{
/* if current brush is using the desired tool, try to toggle
- back to the previously selected brush (if it was set, and
- if it still exists) */
+ * back to the previously selected brush (if it was set, and
+ * if it still exists) */
return brush_orig->toggle_brush;
}
else
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 3b74ae54810..d544183ced8 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -2079,7 +2079,7 @@ static char *wpaint_make_validmap(Object *ob)
return NULL;
}
- gh = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "wpaint_make_validmap gh");
+ gh = BLI_ghash_str_new("wpaint_make_validmap gh");
/* add all names to a hash table */
for (dg = ob->defbase.first; dg; dg = dg->next) {
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 02c0acfc367..7e766ea3388 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -247,7 +247,17 @@ typedef struct StrokeCache {
int mirror_symmetry_pass; /* the symmetry pass we are currently on between 0 and 7*/
float true_view_normal[3];
float view_normal[3];
- float last_area_normal[3];
+
+ /* sculpt_normal gets calculated by calc_sculpt_normal(), then the
+ * sculpt_normal_symm gets updated quickly with the usual symmetry
+ * transforms */
+ float sculpt_normal[3];
+ float sculpt_normal_symm[3];
+
+ /* Used for wrap texture mode, local_mat gets calculated by
+ * calc_brush_local_mat() and used in tex_strength(). */
+ float brush_local_mat[4][4];
+
float last_center[3];
int radial_symmetry_pass;
float symm_rot_mat[4][4];
@@ -537,7 +547,7 @@ static float integrate_overlap(Brush *br)
}
/* Uses symm to selectively flip any axis of a coordinate. */
-static void flip_coord(float out[3], float in[3], const char symm)
+static void flip_v3_v3(float out[3], const float in[3], const char symm)
{
if (symm & SCULPT_SYMM_X)
out[0] = -in[0];
@@ -553,13 +563,18 @@ static void flip_coord(float out[3], float in[3], const char symm)
out[2] = in[2];
}
+static void flip_v3(float v[3], const char symm)
+{
+ flip_v3_v3(v, v, symm);
+}
+
static float calc_overlap(StrokeCache *cache, const char symm, const char axis, const float angle)
{
float mirror[3];
float distsq;
- /* flip_coord(mirror, cache->traced_location, symm); */
- flip_coord(mirror, cache->true_location, symm);
+ /* flip_v3_v3(mirror, cache->traced_location, symm); */
+ flip_v3_v3(mirror, cache->true_location, symm);
if (axis != 0) {
float mat[4][4] = MAT4_UNITY;
@@ -745,15 +760,16 @@ static float tex_strength(SculptSession *ss, Brush *br, float point[3],
* position in order to project it. This insures that the
* brush texture will be oriented correctly. */
- flip_coord(symm_point, point, ss->cache->mirror_symmetry_pass);
+ flip_v3_v3(symm_point, point, ss->cache->mirror_symmetry_pass);
if (ss->cache->radial_symmetry_pass)
mul_m4_v3(ss->cache->symm_rot_mat_inv, symm_point);
ED_view3d_project_float_v2(ss->cache->vc->ar, symm_point, point_2d, ss->cache->projection_mat);
- /* if fixed mode, keep coordinates relative to mouse */
- if (mtex->brush_map_mode == MTEX_MAP_MODE_FIXED) {
+ if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
+ /* keep coordinates relative to mouse */
+
rotation += ss->cache->special_rotation;
point_2d[0] -= ss->cache->tex_mouse[0];
@@ -765,8 +781,8 @@ static float tex_strength(SculptSession *ss, Brush *br, float point[3],
x = point_2d[0] + ss->cache->vc->ar->winrct.xmin;
y = point_2d[1] + ss->cache->vc->ar->winrct.ymin;
}
- else { /* else (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) */
- /* leave the coordinates relative to the screen */
+ else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
+ /* leave the coordinates relative to the screen */
/* use unadjusted size for tiled mode */
radius = BKE_brush_size_get(ss->cache->vc->scene, br);
@@ -774,17 +790,31 @@ static float tex_strength(SculptSession *ss, Brush *br, float point[3],
x = point_2d[0];
y = point_2d[1];
}
+ else if (mtex->brush_map_mode == MTEX_MAP_MODE_AREA) {
+ /* Similar to fixed mode, but projects from brush angle
+ * rather than view direction */
+
+ /* Rotation is handled by the brush_local_mat */
+ rotation = 0;
- x /= ss->cache->vc->ar->winx;
- y /= ss->cache->vc->ar->winy;
+ mul_m4_v3(ss->cache->brush_local_mat, symm_point);
- if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
- x -= 0.5f;
- y -= 0.5f;
+ x = symm_point[0];
+ y = symm_point[1];
}
+
+ if (mtex->brush_map_mode != MTEX_MAP_MODE_AREA) {
+ x /= ss->cache->vc->ar->winx;
+ y /= ss->cache->vc->ar->winy;
+
+ if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
+ x -= 0.5f;
+ y -= 0.5f;
+ }
- x *= ss->cache->vc->ar->winx / radius;
- y *= ss->cache->vc->ar->winy / radius;
+ x *= ss->cache->vc->ar->winx / radius;
+ y *= ss->cache->vc->ar->winy / radius;
+ }
/* it is probably worth optimizing for those cases where
* the texture is not rotated by skipping the calls to
@@ -882,9 +912,13 @@ static void add_norm_if(float view_vec[3], float out[3], float out_flip[3], floa
static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nodes, int totnode)
{
SculptSession *ss = ob->sculpt;
- int n;
-
float out_flip[3] = {0.0f, 0.0f, 0.0f};
+ int n, original;
+
+ /* Grab brush requires to test on original data (see r33888 and
+ * bug #25371) */
+ original = (paint_brush(&sd->paint)->sculpt_tool == SCULPT_TOOL_GRAB ?
+ TRUE : ss->cache->original);
(void)sd; /* unused w/o openmp */
@@ -901,7 +935,7 @@ static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nod
unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS);
sculpt_brush_test_init(ss, &test);
- if (ss->cache->original) {
+ if (original) {
BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
{
if (sculpt_brush_test_fast(&test, unode->co[vd.i])) {
@@ -944,56 +978,161 @@ static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nod
normalize_v3(an);
}
-/* This initializes the faces to be moved for this sculpt for draw/layer/flatten; then it
- * finds average normal for all active vertices - note that this is called once for each mirroring direction */
-static void calc_sculpt_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nodes, int totnode)
+/* Calculate primary direction of movement for many brushes */
+static void calc_sculpt_normal(Sculpt *sd, Object *ob,
+ PBVHNode **nodes, int totnode,
+ float an[3])
{
- SculptSession *ss = ob->sculpt;
- Brush *brush = paint_brush(&sd->paint);
-
- if (ss->cache->mirror_symmetry_pass == 0 &&
- ss->cache->radial_symmetry_pass == 0 &&
- (ss->cache->first_time || !(brush->flag & BRUSH_ORIGINAL_NORMAL)))
- {
- switch (brush->sculpt_plane) {
- case SCULPT_DISP_DIR_VIEW:
- ED_view3d_global_to_vector(ss->cache->vc->rv3d, ss->cache->vc->rv3d->twmat[3], an);
- break;
+ const Brush *brush = paint_brush(&sd->paint);
+ const SculptSession *ss = ob->sculpt;
+
+ switch (brush->sculpt_plane) {
+ case SCULPT_DISP_DIR_VIEW:
+ ED_view3d_global_to_vector(ss->cache->vc->rv3d,
+ ss->cache->vc->rv3d->twmat[3],
+ an);
+ break;
- case SCULPT_DISP_DIR_X:
- an[1] = 0.0;
- an[2] = 0.0;
- an[0] = 1.0;
- break;
+ case SCULPT_DISP_DIR_X:
+ an[1] = 0.0;
+ an[2] = 0.0;
+ an[0] = 1.0;
+ break;
- case SCULPT_DISP_DIR_Y:
- an[0] = 0.0;
- an[2] = 0.0;
- an[1] = 1.0;
- break;
+ case SCULPT_DISP_DIR_Y:
+ an[0] = 0.0;
+ an[2] = 0.0;
+ an[1] = 1.0;
+ break;
- case SCULPT_DISP_DIR_Z:
- an[0] = 0.0;
- an[1] = 0.0;
- an[2] = 1.0;
- break;
+ case SCULPT_DISP_DIR_Z:
+ an[0] = 0.0;
+ an[1] = 0.0;
+ an[2] = 1.0;
+ break;
- case SCULPT_DISP_DIR_AREA:
- calc_area_normal(sd, ob, an, nodes, totnode);
+ case SCULPT_DISP_DIR_AREA:
+ calc_area_normal(sd, ob, an, nodes, totnode);
- default:
- break;
- }
+ default:
+ break;
+ }
+}
- copy_v3_v3(ss->cache->last_area_normal, an);
+static void update_sculpt_normal(Sculpt *sd, Object *ob,
+ PBVHNode **nodes, int totnode)
+{
+ const Brush *brush = paint_brush(&sd->paint);
+ StrokeCache *cache = ob->sculpt->cache;
+
+ if (cache->mirror_symmetry_pass == 0 &&
+ cache->radial_symmetry_pass == 0 &&
+ (cache->first_time || !(brush->flag & BRUSH_ORIGINAL_NORMAL)))
+ {
+ calc_sculpt_normal(sd, ob, nodes, totnode, cache->sculpt_normal);
+ copy_v3_v3(cache->sculpt_normal_symm, cache->sculpt_normal);
}
else {
- copy_v3_v3(an, ss->cache->last_area_normal);
- flip_coord(an, an, ss->cache->mirror_symmetry_pass);
- mul_m4_v3(ss->cache->symm_rot_mat, an);
+ copy_v3_v3(cache->sculpt_normal_symm, cache->sculpt_normal);
+ flip_v3(cache->sculpt_normal_symm, cache->mirror_symmetry_pass);
+ mul_m4_v3(cache->symm_rot_mat, cache->sculpt_normal_symm);
+ }
+}
+
+static void calc_local_y(ViewContext *vc, const float center[3], float y[3])
+{
+ Object *ob = vc->obact;
+ float loc[3], mval_f[2] = {0.0f, 1.0f};
+
+ mul_v3_m4v3(loc, ob->imat, center);
+ initgrabz(vc->rv3d, loc[0], loc[1], loc[2]);
+
+ ED_view3d_win_to_delta(vc->ar, mval_f, y);
+ normalize_v3(y);
+
+ add_v3_v3(y, ob->loc);
+ mul_m4_v3(ob->imat, y);
+}
+
+static void calc_brush_local_mat(const Brush *brush, Object *ob,
+ float local_mat[4][4])
+{
+ const StrokeCache *cache = ob->sculpt->cache;
+ float tmat[4][4];
+ float mat[4][4];
+ float scale[4][4];
+ float angle, v[3];
+ float up[3];
+
+ /* Ensure ob->imat is up to date */
+ invert_m4_m4(ob->imat, ob->obmat);
+
+ /* Initialize last column of matrix */
+ mat[0][3] = 0;
+ mat[1][3] = 0;
+ mat[2][3] = 0;
+ mat[3][3] = 1;
+
+ /* Get view's up vector in object-space */
+ calc_local_y(cache->vc, cache->location, up);
+
+ /* Calculate the X axis of the local matrix */
+ cross_v3_v3v3(v, up, cache->sculpt_normal);
+ /* Apply rotation (user angle, rake, etc.) to X axis */
+ angle = brush->mtex.rot - cache->special_rotation;
+ rotate_v3_v3v3fl(mat[0], v, cache->sculpt_normal, angle);
+
+ /* Get other axes */
+ cross_v3_v3v3(mat[1], cache->sculpt_normal, mat[0]);
+ copy_v3_v3(mat[2], cache->sculpt_normal);
+
+ /* Set location */
+ copy_v3_v3(mat[3], cache->location);
+
+ /* Scale by brush radius */
+ normalize_m4(mat);
+ scale_m4_fl(scale, cache->radius);
+ mult_m4_m4m4(tmat, mat, scale);
+
+ /* Return inverse (for converting from modelspace coords to local
+ * area coords) */
+ invert_m4_m4(local_mat, tmat);
+}
+
+static void update_brush_local_mat(Sculpt *sd, Object *ob)
+{
+ StrokeCache *cache = ob->sculpt->cache;
+
+ if (cache->mirror_symmetry_pass == 0 &&
+ cache->radial_symmetry_pass == 0)
+ {
+ calc_brush_local_mat(paint_brush(&sd->paint), ob,
+ cache->brush_local_mat);
}
}
+/* Test whether the StrokeCache.sculpt_normal needs update in
+ * do_brush_action() */
+static int brush_needs_sculpt_normal(const Brush *brush)
+{
+ return ((ELEM(brush->sculpt_tool,
+ SCULPT_TOOL_GRAB,
+ SCULPT_TOOL_SNAKE_HOOK) &&
+ ((brush->normal_weight > 0) ||
+ (brush->flag & BRUSH_FRONTFACE))) ||
+
+ ELEM7(brush->sculpt_tool,
+ SCULPT_TOOL_BLOB,
+ SCULPT_TOOL_CREASE,
+ SCULPT_TOOL_DRAW,
+ SCULPT_TOOL_LAYER,
+ SCULPT_TOOL_NUDGE,
+ SCULPT_TOOL_ROTATE,
+ SCULPT_TOOL_THUMB) ||
+
+ (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA));
+}
+
/* For the smooth brush, uses the neighboring vertices around vert to calculate
* a smoothed location for vert. Skips corner vertices (used by only one
* polygon.) */
@@ -1037,8 +1176,8 @@ static void neighbor_average(SculptSession *ss, float avg[3], unsigned vert)
}
/* Similar to neighbor_average(), but returns an averaged mask value
- instead of coordinate. Also does not restrict based on border or
- corner vertices. */
+ * instead of coordinate. Also does not restrict based on border or
+ * corner vertices. */
static float neighbor_average_mask(SculptSession *ss, unsigned vert)
{
const float *vmask = ss->vmask;
@@ -1356,14 +1495,12 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
- float offset[3], area_normal[3];
+ float offset[3];
float bstrength = ss->cache->bstrength;
int n;
- calc_sculpt_normal(sd, ob, area_normal, nodes, totnode);
-
/* offset with as much as possible factored in already */
- mul_v3_v3fl(offset, area_normal, ss->cache->radius);
+ mul_v3_v3fl(offset, ss->cache->sculpt_normal_symm, ss->cache->radius);
mul_v3_v3(offset, ss->cache->scale);
mul_v3_fl(offset, bstrength);
@@ -1383,7 +1520,8 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
if (sculpt_brush_test(&test, vd.co)) {
/* offset vertex */
float fade = tex_strength(ss, brush, vd.co, test.dist,
- area_normal, vd.no, vd.fno, *vd.mask);
+ ss->cache->sculpt_normal_symm, vd.no,
+ vd.fno, *vd.mask);
mul_v3_v3fl(proxy[vd.i], offset, fade);
@@ -1400,16 +1538,14 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
SculptSession *ss = ob->sculpt;
const Scene *scene = ss->cache->vc->scene;
Brush *brush = paint_brush(&sd->paint);
- float offset[3], area_normal[3];
+ float offset[3];
float bstrength = ss->cache->bstrength;
float flippedbstrength, crease_correction;
float brush_alpha;
int n;
- calc_sculpt_normal(sd, ob, area_normal, nodes, totnode);
-
/* offset with as much as possible factored in already */
- mul_v3_v3fl(offset, area_normal, ss->cache->radius);
+ mul_v3_v3fl(offset, ss->cache->sculpt_normal_symm, ss->cache->radius);
mul_v3_v3(offset, ss->cache->scale);
mul_v3_fl(offset, bstrength);
@@ -1440,7 +1576,8 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
if (sculpt_brush_test(&test, vd.co)) {
/* offset vertex */
const float fade = tex_strength(ss, brush, vd.co, test.dist,
- area_normal, vd.no, vd.fno, *vd.mask);
+ ss->cache->sculpt_normal_symm,
+ vd.no, vd.fno, *vd.mask);
float val1[3];
float val2[3];
@@ -1502,26 +1639,18 @@ static void do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
float bstrength = ss->cache->bstrength;
- float grab_delta[3], an[3];
+ float grab_delta[3];
int n;
float len;
- if (brush->normal_weight > 0 || brush->flag & BRUSH_FRONTFACE) {
- int cache = 1;
- /* grab brush requires to test on original data */
- SWAP(int, ss->cache->original, cache);
- calc_sculpt_normal(sd, ob, an, nodes, totnode);
- SWAP(int, ss->cache->original, cache);
- }
-
copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
len = len_v3(grab_delta);
if (brush->normal_weight > 0) {
- mul_v3_fl(an, len * brush->normal_weight);
+ mul_v3_fl(ss->cache->sculpt_normal_symm, len * brush->normal_weight);
mul_v3_fl(grab_delta, 1.0f - brush->normal_weight);
- add_v3_v3(grab_delta, an);
+ add_v3_v3(grab_delta, ss->cache->sculpt_normal_symm);
}
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
@@ -1545,7 +1674,7 @@ static void do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
if (sculpt_brush_test(&test, origco[vd.i])) {
const float fade = bstrength * tex_strength(ss, brush, origco[vd.i], test.dist,
- an, origno[vd.i], NULL, *vd.mask);
+ ss->cache->sculpt_normal_symm, origno[vd.i], NULL, *vd.mask);
mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
@@ -1563,16 +1692,13 @@ static void do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
Brush *brush = paint_brush(&sd->paint);
float bstrength = ss->cache->bstrength;
float grab_delta[3];
- int n;
- float an[3];
float tmp[3], cono[3];
+ int n;
copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
- calc_sculpt_normal(sd, ob, an, nodes, totnode);
-
- cross_v3_v3v3(tmp, an, grab_delta);
- cross_v3_v3v3(cono, tmp, an);
+ cross_v3_v3v3(tmp, ss->cache->sculpt_normal_symm, grab_delta);
+ cross_v3_v3v3(cono, tmp, ss->cache->sculpt_normal_symm);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
for (n = 0; n < totnode; n++) {
@@ -1588,7 +1714,8 @@ static void do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
{
if (sculpt_brush_test(&test, vd.co)) {
const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
- an, vd.no, vd.fno, *vd.mask);
+ ss->cache->sculpt_normal_symm,
+ vd.no, vd.fno, *vd.mask);
mul_v3_v3fl(proxy[vd.i], cono, fade);
@@ -1605,13 +1732,10 @@ static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
float bstrength = ss->cache->bstrength;
- float grab_delta[3], an[3];
+ float grab_delta[3];
int n;
float len;
- if (brush->normal_weight > 0 || brush->flag & BRUSH_FRONTFACE)
- calc_sculpt_normal(sd, ob, an, nodes, totnode);
-
copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
len = len_v3(grab_delta);
@@ -1620,9 +1744,9 @@ static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
negate_v3(grab_delta);
if (brush->normal_weight > 0) {
- mul_v3_fl(an, len * brush->normal_weight);
+ mul_v3_fl(ss->cache->sculpt_normal_symm, len * brush->normal_weight);
mul_v3_fl(grab_delta, 1.0f - brush->normal_weight);
- add_v3_v3(grab_delta, an);
+ add_v3_v3(grab_delta, ss->cache->sculpt_normal_symm);
}
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
@@ -1639,7 +1763,8 @@ static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
{
if (sculpt_brush_test(&test, vd.co)) {
const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
- an, vd.no, vd.fno, *vd.mask);
+ ss->cache->sculpt_normal_symm,
+ vd.no, vd.fno, *vd.mask);
mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
@@ -1657,16 +1782,13 @@ static void do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
Brush *brush = paint_brush(&sd->paint);
float bstrength = ss->cache->bstrength;
float grab_delta[3];
- int n;
- float an[3];
float tmp[3], cono[3];
+ int n;
copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
- calc_sculpt_normal(sd, ob, an, nodes, totnode);
-
- cross_v3_v3v3(tmp, an, grab_delta);
- cross_v3_v3v3(cono, tmp, an);
+ cross_v3_v3v3(tmp, ss->cache->sculpt_normal_symm, grab_delta);
+ cross_v3_v3v3(cono, tmp, ss->cache->sculpt_normal_symm);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
for (n = 0; n < totnode; n++) {
@@ -1689,7 +1811,8 @@ static void do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
{
if (sculpt_brush_test(&test, origco[vd.i])) {
const float fade = bstrength * tex_strength(ss, brush, origco[vd.i], test.dist,
- an, origno[vd.i], NULL, *vd.mask);
+ ss->cache->sculpt_normal_symm,
+ origno[vd.i], NULL, *vd.mask);
mul_v3_v3fl(proxy[vd.i], cono, fade);
@@ -1706,20 +1829,17 @@ static void do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
float bstrength = ss->cache->bstrength;
- float an[3];
int n;
float m[4][4], rot[4][4], lmat[4][4], ilmat[4][4];
static const int flip[8] = { 1, -1, -1, 1, -1, 1, 1, -1 };
float angle = ss->cache->vertex_rotation * flip[ss->cache->mirror_symmetry_pass];
- calc_sculpt_normal(sd, ob, an, nodes, totnode);
-
unit_m4(m);
unit_m4(lmat);
copy_v3_v3(lmat[3], ss->cache->location);
invert_m4_m4(ilmat, lmat);
- axis_angle_to_mat4(rot, an, angle);
+ axis_angle_to_mat4(rot, ss->cache->sculpt_normal_symm, angle);
mul_serie_m4(m, lmat, rot, ilmat, NULL, NULL, NULL, NULL, NULL);
@@ -1744,7 +1864,8 @@ static void do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
{
if (sculpt_brush_test(&test, origco[vd.i])) {
const float fade = bstrength * tex_strength(ss, brush, origco[vd.i], test.dist,
- an, origno[vd.i], NULL, *vd.mask);
+ ss->cache->sculpt_normal_symm,
+ origno[vd.i], NULL, *vd.mask);
mul_v3_m4v3(proxy[vd.i], m, origco[vd.i]);
sub_v3_v3(proxy[vd.i], origco[vd.i]);
@@ -1770,8 +1891,6 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
if (bstrength < 0)
lim = -lim;
- calc_sculpt_normal(sd, ob, area_normal, nodes, totnode);
-
mul_v3_v3v3(offset, ss->cache->scale, area_normal);
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
@@ -2069,23 +2188,23 @@ static void calc_sculpt_plane(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn
calc_flatten_center(sd, ob, nodes, totnode, fc);
/* for area normal */
- copy_v3_v3(ss->cache->last_area_normal, an);
+ copy_v3_v3(ss->cache->sculpt_normal, an);
/* for flatten center */
copy_v3_v3(ss->cache->last_center, fc);
}
else {
/* for area normal */
- copy_v3_v3(an, ss->cache->last_area_normal);
+ copy_v3_v3(an, ss->cache->sculpt_normal);
/* for flatten center */
copy_v3_v3(fc, ss->cache->last_center);
/* for area normal */
- flip_coord(an, an, ss->cache->mirror_symmetry_pass);
+ flip_v3(an, ss->cache->mirror_symmetry_pass);
/* for flatten center */
- flip_coord(fc, fc, ss->cache->mirror_symmetry_pass);
+ flip_v3(fc, ss->cache->mirror_symmetry_pass);
/* for area normal */
mul_m4_v3(ss->cache->symm_rot_mat, an);
@@ -2591,6 +2710,12 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush)
BLI_pbvh_node_mark_update(nodes[n]);
}
+ if (brush_needs_sculpt_normal(brush))
+ update_sculpt_normal(sd, ob, nodes, totnode);
+
+ if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA)
+ update_brush_local_mat(sd, ob);
+
/* Apply one type of brush action */
switch (brush->sculpt_tool) {
case SCULPT_TOOL_DRAW:
@@ -2816,9 +2941,9 @@ static void calc_brushdata_symm(Sculpt *sd, StrokeCache *cache, const char symm,
{
(void)sd; /* unused */
- flip_coord(cache->location, cache->true_location, symm);
- flip_coord(cache->grab_delta_symmetry, cache->grab_delta, symm);
- flip_coord(cache->view_normal, cache->true_view_normal, symm);
+ flip_v3_v3(cache->location, cache->true_location, symm);
+ flip_v3_v3(cache->grab_delta_symmetry, cache->grab_delta, symm);
+ flip_v3_v3(cache->view_normal, cache->true_view_normal, symm);
/* XXX This reduces the length of the grab delta if it approaches the line of symmetry
* XXX However, a different approach appears to be needed */
@@ -3364,7 +3489,7 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
{
copy_v2_v2(cache->tex_mouse, cache->mouse);
- if ((brush->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) &&
+ if ((brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) &&
(brush->flag & BRUSH_RANDOM_ROTATION) &&
!(brush->flag & BRUSH_RAKE))
{
@@ -3909,7 +4034,7 @@ void ED_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
paint_mask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
/* if multires is active, create a grid paint mask layer if there
- isn't one already */
+ * isn't one already */
if (mmd && !CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK)) {
GridPaintMask *gmask;
int level = MAX2(1, mmd->sculptlvl);
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index ed9265deeb2..a477a7435fd 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -142,7 +142,7 @@ void ED_space_clip_set(bContext *C, bScreen *screen, SpaceClip *sc, MovieClip *c
if (sc->clip && sc->clip->id.us == 0)
sc->clip->id.us = 1;
- if (screen) {
+ if (screen && sc->view == SC_VIEW_CLIP) {
ScrArea *area;
SpaceLink *sl;
@@ -151,7 +151,7 @@ void ED_space_clip_set(bContext *C, bScreen *screen, SpaceClip *sc, MovieClip *c
if (sl->spacetype == SPACE_CLIP) {
SpaceClip *cur_sc = (SpaceClip *) sl;
- if (cur_sc != sc) {
+ if (cur_sc != sc && cur_sc->view != SC_VIEW_CLIP) {
if (cur_sc->clip == old_clip || cur_sc->clip == NULL) {
cur_sc->clip = clip;
}
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index f340c53f528..3ff9c3c0520 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -1099,7 +1099,11 @@ static void file_expand_directory(bContext *C)
SpaceFile *sfile= CTX_wm_space_file(C);
if (sfile->params) {
- if ( sfile->params->dir[0] == '~' ) {
+ /* TODO, what about // when relbase isn't valid? */
+ if (G.relbase_valid && strncmp(sfile->params->dir, "//", 2) == 0) {
+ BLI_path_abs(sfile->params->dir, G.main->name);
+ }
+ else if (sfile->params->dir[0] == '~') {
char tmpstr[sizeof(sfile->params->dir)-1];
BLI_strncpy(tmpstr, sfile->params->dir+1, sizeof(tmpstr));
BLI_join_dirfile(sfile->params->dir, sizeof(sfile->params->dir), BLI_getDefaultDocumentFolder(), tmpstr);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 58fbceb999d..e2ab5ea64e4 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -2210,7 +2210,7 @@ static int image_record_composite_apply(bContext *C, wmOperator *op)
BKE_image_all_free_anim_ibufs(scene->r.cfra);
ntreeCompositTagAnimated(scene->nodetree);
- ntreeCompositExecTree(scene->nodetree, &scene->r, scene->r.cfra != rcd->old_cfra); /* 1 is no previews */
+ ntreeCompositExecTree(scene->nodetree, &scene->r, 0, scene->r.cfra != rcd->old_cfra); /* 1 is no previews */
ED_area_tag_redraw(CTX_wm_area(C));
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 205202a0658..d9fc793adb3 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -1967,6 +1967,256 @@ static void node_composit_buts_moviedistortion(uiLayout *layout, bContext *C, Po
uiItemR(layout, ptr, "distortion_type", 0, "", 0);
}
+static void node_composit_buts_colorcorrection(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiLayout *row;
+
+ row = uiLayoutRow(layout, 0);
+ uiItemR(row, ptr, "red", 0, NULL, ICON_NONE);
+ uiItemR(row, ptr, "green", 0, NULL, ICON_NONE);
+ uiItemR(row, ptr, "blue", 0, NULL, ICON_NONE);
+
+ row = uiLayoutRow(layout, 0);
+ uiItemR(row, ptr, "midtones_start", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "midtones_end", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+
+ row = uiLayoutRow(layout, 0);
+ uiItemR(row, ptr, "master_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "master_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "master_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "master_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "master_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+
+ row = uiLayoutRow(layout, 0);
+ uiItemL(row, "Saturation", 0);
+ uiItemL(row, "Contrast", 0);
+ uiItemL(row, "Gamma", 0);
+ uiItemL(row, "Gain", 0);
+ uiItemL(row, "Lift", 0);
+
+ row = uiLayoutRow(layout, 0);
+ uiItemR(row, ptr, "highlights_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "highlights_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "highlights_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "highlights_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "highlights_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+
+ row = uiLayoutRow(layout, 0);
+ uiItemR(row, ptr, "midtones_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "midtones_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "midtones_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "midtones_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "midtones_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+
+ row = uiLayoutRow(layout, 0);
+ uiItemR(row, ptr, "shadows_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "shadows_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "shadows_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "shadows_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "shadows_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+}
+static void node_composit_buts_colorcorrection_but(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) {
+ uiLayout *row;
+
+ row = uiLayoutRow(layout, 0);
+ uiItemR(row, ptr, "red", 0, NULL, ICON_NONE);
+ uiItemR(row, ptr, "green", 0, NULL, ICON_NONE);
+ uiItemR(row, ptr, "blue", 0, NULL, ICON_NONE);
+ row = layout;
+ uiItemL(row, "Saturation", 0);
+ uiItemR(row, ptr, "master_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "highlights_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "midtones_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "shadows_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+
+ uiItemL(row, "Contrast", 0);
+ uiItemR(row, ptr, "master_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "highlights_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "midtones_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "shadows_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+
+ uiItemL(row, "Gamma", 0);
+ uiItemR(row, ptr, "master_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "highlights_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "midtones_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "shadows_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+
+ uiItemL(row, "Gain", 0);
+ uiItemR(row, ptr, "master_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "highlights_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "midtones_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "shadows_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+
+ uiItemL(row, "Lift", 0);
+ uiItemR(row, ptr, "master_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "highlights_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "midtones_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "shadows_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+
+ row = uiLayoutRow(layout, 0);
+ uiItemR(row, ptr, "midtones_start", 0, NULL, ICON_NONE);
+ uiItemR(row, ptr, "midtones_end", 0, NULL, ICON_NONE);
+}
+
+static void node_composit_buts_switch(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "check", 0, NULL, ICON_NONE);
+}
+
+static void node_composit_buts_boxmask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiLayout *row;
+
+ row= uiLayoutRow(layout, 1);
+ uiItemR(row, ptr, "x", 0, "X", ICON_NONE);
+ uiItemR(row, ptr, "y", 0, "Y", ICON_NONE);
+
+ row= uiLayoutRow(layout, 1);
+ uiItemR(row, ptr, "width", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "height", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+
+ uiItemR(layout, ptr, "rotation", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "mask_type", 0, NULL, ICON_NONE);
+}
+
+static void node_composit_buts_bokehimage(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "flaps", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "angle", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "rounding", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "catadioptric", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "shift", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+}
+
+void node_composit_backdrop_viewer(SpaceNode* snode, ImBuf* backdrop, bNode* node, int x, int y)
+{
+// node_composit_backdrop_canvas(snode, backdrop, node, x, y);
+ if (node->custom1 == 0) { /// @todo: why did we need this one?
+ const float backdropWidth = backdrop->x;
+ const float backdropHeight = backdrop->y;
+ const float cx = x+snode->zoom*backdropWidth*node->custom3;
+ const float cy = y+snode->zoom*backdropHeight*node->custom4;
+
+ glColor3f(1.0, 1.0, 1.0);
+
+ glBegin(GL_LINES);
+ glVertex2f(cx-25, cy-25);
+ glVertex2f(cx+25, cy+25);
+ glVertex2f(cx+25, cy-25);
+ glVertex2f(cx-25, cy+25);
+ glEnd();
+ }
+}
+
+void node_composit_backdrop_boxmask(SpaceNode* snode, ImBuf* backdrop, bNode* node, int x, int y)
+{
+ NodeBoxMask * boxmask = node->storage;
+ const float backdropWidth = backdrop->x;
+ const float backdropHeight = backdrop->y;
+ const float aspect = backdropWidth/backdropHeight;
+ const float rad = DEG2RAD(-boxmask->rotation);
+ const float cosine = cos(rad);
+ const float sine = sin(rad);
+ const float halveBoxWidth = backdropWidth*(boxmask->width/2.0f);
+ const float halveBoxHeight = backdropHeight*(boxmask->height/2.0f)*aspect;
+
+ float cx, cy, x1, x2, x3, x4;
+ float y1, y2, y3, y4;
+
+
+ /* keep this, saves us from a version patch */
+ if(snode->zoom==0.0f) snode->zoom= 1.0f;
+
+ glColor3f(1.0, 1.0, 1.0);
+
+ cx = x+snode->zoom*backdropWidth*boxmask->x;
+ cy = y+snode->zoom*backdropHeight*boxmask->y;
+
+ x1 = cx - (cosine*halveBoxWidth+sine*halveBoxHeight)*snode->zoom;
+ x2 = cx - (cosine*-halveBoxWidth+sine*halveBoxHeight)*snode->zoom;
+ x3 = cx - (cosine*-halveBoxWidth+sine*-halveBoxHeight)*snode->zoom;
+ x4 = cx - (cosine*halveBoxWidth+sine*-halveBoxHeight)*snode->zoom;
+ y1 = cy - (-sine*halveBoxWidth + cosine*halveBoxHeight)*snode->zoom;
+ y2 = cy - (-sine*-halveBoxWidth + cosine*halveBoxHeight)*snode->zoom;
+ y3 = cy - (-sine*-halveBoxWidth + cosine*-halveBoxHeight)*snode->zoom;
+ y4 = cy - (-sine*halveBoxWidth + cosine*-halveBoxHeight)*snode->zoom;
+
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(x1, y1);
+ glVertex2f(x2, y2);
+ glVertex2f(x3, y3);
+ glVertex2f(x4, y4);
+ glEnd();
+}
+
+void node_composit_backdrop_ellipsemask(SpaceNode* snode, ImBuf* backdrop, bNode* node, int x, int y)
+{
+ NodeEllipseMask * ellipsemask = node->storage;
+ const float backdropWidth = backdrop->x;
+ const float backdropHeight = backdrop->y;
+ const float aspect = backdropWidth/backdropHeight;
+ const float rad = DEG2RAD(-ellipsemask->rotation);
+ const float cosine = cos(rad);
+ const float sine = sin(rad);
+ const float halveBoxWidth = backdropWidth*(ellipsemask->width/2.0f);
+ const float halveBoxHeight = backdropHeight*(ellipsemask->height/2.0f)*aspect;
+
+ float cx, cy, x1, x2, x3, x4;
+ float y1, y2, y3, y4;
+
+
+ /* keep this, saves us from a version patch */
+ if(snode->zoom==0.0f) snode->zoom= 1.0f;
+
+ glColor3f(1.0, 1.0, 1.0);
+
+ cx = x+snode->zoom*backdropWidth*ellipsemask->x;
+ cy = y+snode->zoom*backdropHeight*ellipsemask->y;
+
+ x1 = cx - (cosine*halveBoxWidth+sine*halveBoxHeight)*snode->zoom;
+ x2 = cx - (cosine*-halveBoxWidth+sine*halveBoxHeight)*snode->zoom;
+ x3 = cx - (cosine*-halveBoxWidth+sine*-halveBoxHeight)*snode->zoom;
+ x4 = cx - (cosine*halveBoxWidth+sine*-halveBoxHeight)*snode->zoom;
+ y1 = cy - (-sine*halveBoxWidth + cosine*halveBoxHeight)*snode->zoom;
+ y2 = cy - (-sine*-halveBoxWidth + cosine*halveBoxHeight)*snode->zoom;
+ y3 = cy - (-sine*-halveBoxWidth + cosine*-halveBoxHeight)*snode->zoom;
+ y4 = cy - (-sine*halveBoxWidth + cosine*-halveBoxHeight)*snode->zoom;
+
+ glBegin(GL_LINE_LOOP);
+
+ glVertex2f(x1, y1);
+ glVertex2f(x2, y2);
+ glVertex2f(x3, y3);
+ glVertex2f(x4, y4);
+ glEnd();
+}
+
+static void node_composit_buts_ellipsemask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiLayout *row;
+ row= uiLayoutRow(layout, 1);
+ uiItemR(row, ptr, "x", 0, "X", ICON_NONE);
+ uiItemR(row, ptr, "y", 0, "Y", ICON_NONE);
+ row= uiLayoutRow(layout, 1);
+ uiItemR(row, ptr, "width", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+ uiItemR(row, ptr, "height", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
+
+ uiItemR(layout, ptr, "rotation", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "mask_type", 0, NULL, ICON_NONE);
+}
+
+static void node_composit_buts_viewer_but(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiLayout *col;
+
+ uiItemR(layout, ptr, "tile_order", 0, NULL, ICON_NONE);
+ if (RNA_enum_get(ptr, "tile_order")==0) {
+ col= uiLayoutColumn(layout, 1);
+ uiItemR(col, ptr, "center_x", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "center_y", 0, NULL, ICON_NONE);
+ }
+}
+
/* only once called */
static void node_composit_set_butfunc(bNodeType *ntype)
{
@@ -2134,6 +2384,30 @@ static void node_composit_set_butfunc(bNodeType *ntype)
case CMP_NODE_MOVIEDISTORTION:
ntype->uifunc= node_composit_buts_moviedistortion;
break;
+ case CMP_NODE_COLORCORRECTION:
+ ntype->uifunc=node_composit_buts_colorcorrection;
+ ntype->uifuncbut=node_composit_buts_colorcorrection_but;
+ break;
+ case CMP_NODE_SWITCH:
+ ntype->uifunc= node_composit_buts_switch;
+ break;
+ case CMP_NODE_MASK_BOX:
+ ntype->uifunc= node_composit_buts_boxmask;
+ ntype->uibackdropfunc = node_composit_backdrop_boxmask;
+ break;
+ case CMP_NODE_MASK_ELLIPSE:
+ ntype->uifunc= node_composit_buts_ellipsemask;
+ ntype->uibackdropfunc = node_composit_backdrop_ellipsemask;
+ break;
+ case CMP_NODE_BOKEHIMAGE:
+ ntype->uifunc= node_composit_buts_bokehimage;
+ break;
+ case CMP_NODE_VIEWER:
+ ntype->uifunc = NULL;
+ ntype->uifuncbut= node_composit_buts_viewer_but;
+ ntype->uibackdropfunc = node_composit_backdrop_viewer;
+ break;
+
default:
ntype->uifunc= NULL;
}
@@ -2432,6 +2706,19 @@ void draw_nodespace_back_pix(ARegion *ar, SpaceNode *snode, int color_manage)
glPixelZoom(1.0f, 1.0f);
}
}
+
+ /// @note draw selected info on backdrop
+ if (snode->edittree) {
+ bNode *node = snode->edittree->nodes.first;
+ while (node) {
+ if (node->flag & NODE_SELECT) {
+ if (node->typeinfo->uibackdropfunc) {
+ node->typeinfo->uibackdropfunc(snode, ibuf, node, x, y);
+ }
+ }
+ node = node->next;
+ }
+ }
glMatrixMode(GL_PROJECTION);
glPopMatrix();
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 3a920e16f8a..d93b1b1fcc8 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -914,6 +914,7 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d)
Scene *scene= CTX_data_scene(C);
int color_manage = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
bNodeLinkDrag *nldrag;
+ LinkData *linkdata;
UI_ThemeClearColor(TH_BACK);
glClear(GL_COLOR_BUFFER_BIT);
@@ -965,8 +966,10 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d)
/* temporary links */
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
- for (nldrag= snode->linkdrag.first; nldrag; nldrag= nldrag->next)
- node_draw_link(&ar->v2d, snode, nldrag->link);
+ for (nldrag= snode->linkdrag.first; nldrag; nldrag= nldrag->next) {
+ for (linkdata=nldrag->links.first; linkdata; linkdata=linkdata->next)
+ node_draw_link(&ar->v2d, snode, (bNodeLink *)linkdata->data);
+ }
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index ae6c09b0339..f71ce3f960c 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -185,8 +185,8 @@ static void compo_startjob(void *cjv, short *stop, short *do_update, float *prog
// XXX BIF_store_spare();
- ntreeCompositExecTree(ntree, &cj->scene->r, 1); /* 1 is do_previews */
-
+ ntreeCompositExecTree(ntree, &cj->scene->r, 0, 1); /* 1 is do_previews */
+
ntree->test_break= NULL;
ntree->stats_draw= NULL;
ntree->progress= NULL;
@@ -405,6 +405,10 @@ void ED_node_composit_default(Scene *sce)
}
sce->nodetree= ntreeAddTree("Compositing Nodetree", NTREE_COMPOSIT, 0);
+
+ sce->nodetree->chunksize = 256;
+ sce->nodetree->edit_quality = NTREE_QUALITY_HIGH;
+ sce->nodetree->render_quality = NTREE_QUALITY_HIGH;
ntemp.type = CMP_NODE_COMPOSITE;
out= nodeAddNode(sce->nodetree, &ntemp);
@@ -2324,15 +2328,13 @@ static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event)
SpaceNode *snode= CTX_wm_space_node(C);
ARegion *ar= CTX_wm_region(C);
bNodeLinkDrag *nldrag= op->customdata;
- bNode *tnode, *node;
- bNodeSocket *tsock= NULL, *sock;
+ bNode *tnode;
+ bNodeSocket *tsock= NULL;
bNodeLink *link;
+ LinkData *linkdata;
int in_out;
- in_out= nldrag->in_out;
- node= nldrag->node;
- sock= nldrag->sock;
- link= nldrag->link;
+ in_out = nldrag->in_out;
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
&snode->mx, &snode->my);
@@ -2342,57 +2344,86 @@ static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event)
if (in_out==SOCK_OUT) {
if (node_find_indicated_socket(snode, &tnode, &tsock, SOCK_IN)) {
- if (nodeFindLink(snode->edittree, sock, tsock)==NULL) {
- if ( link->tosock!= tsock && (!tnode || (tnode!=node && link->tonode!=tnode)) ) {
- link->tonode= tnode;
- link->tosock= tsock;
- if (link->prev==NULL && link->next==NULL) {
- BLI_addtail(&snode->edittree->links, link);
- }
-
- snode->edittree->update |= NTREE_UPDATE_LINKS;
- ntreeUpdateTree(snode->edittree);
- }
+ for (linkdata=nldrag->links.first; linkdata; linkdata=linkdata->next) {
+ link = linkdata->data;
+
+ /* skip if this is already the target socket */
+ if (link->tosock == tsock)
+ continue;
+ /* skip if socket is on the same node as the fromsock */
+ if (tnode && link->fromnode == tnode)
+ continue;
+
+ /* attach links to the socket */
+ link->tonode = tnode;
+ link->tosock = tsock;
+ /* add it to the node tree temporarily */
+ if (link->prev==NULL && link->next==NULL)
+ BLI_addtail(&snode->edittree->links, link);
+
+ snode->edittree->update |= NTREE_UPDATE_LINKS;
}
+ ntreeUpdateTree(snode->edittree);
}
else {
- if (link->tonode || link->tosock) {
- BLI_remlink(&snode->edittree->links, link);
- link->prev = link->next = NULL;
- link->tonode= NULL;
- link->tosock= NULL;
+ int do_update = 0;
+ for (linkdata=nldrag->links.first; linkdata; linkdata=linkdata->next) {
+ link = linkdata->data;
- snode->edittree->update |= NTREE_UPDATE_LINKS;
- ntreeUpdateTree(snode->edittree);
+ if (link->tonode || link->tosock) {
+ BLI_remlink(&snode->edittree->links, link);
+ link->prev = link->next = NULL;
+ link->tonode= NULL;
+ link->tosock= NULL;
+
+ snode->edittree->update |= NTREE_UPDATE_LINKS;
+ do_update = 1;
+ }
}
+ if (do_update)
+ ntreeUpdateTree(snode->edittree);
}
}
else {
if (node_find_indicated_socket(snode, &tnode, &tsock, SOCK_OUT)) {
- if (nodeFindLink(snode->edittree, sock, tsock)==NULL) {
- if (nodeCountSocketLinks(snode->edittree, tsock) < tsock->limit) {
- if ( link->fromsock!= tsock && (!tnode || (tnode!=node && link->fromnode!=tnode)) ) {
- link->fromnode= tnode;
- link->fromsock= tsock;
- if (link->prev==NULL && link->next==NULL) {
- BLI_addtail(&snode->edittree->links, link);
- }
-
- snode->edittree->update |= NTREE_UPDATE_LINKS;
- ntreeUpdateTree(snode->edittree);
- }
- }
+ for (linkdata=nldrag->links.first; linkdata; linkdata=linkdata->next) {
+ link = linkdata->data;
+
+ /* skip if this is already the target socket */
+ if (link->fromsock == tsock)
+ continue;
+ /* skip if socket is on the same node as the fromsock */
+ if (tnode && link->tonode == tnode)
+ continue;
+
+ /* attach links to the socket */
+ link->fromnode = tnode;
+ link->fromsock = tsock;
+ /* add it to the node tree temporarily */
+ if (link->prev==NULL && link->next==NULL)
+ BLI_addtail(&snode->edittree->links, link);
+
+ snode->edittree->update |= NTREE_UPDATE_LINKS;
}
+ ntreeUpdateTree(snode->edittree);
}
else {
- if (link->tonode || link->tosock) {
- BLI_remlink(&snode->edittree->links, link);
- link->prev = link->next = NULL;
- link->fromnode= NULL;
- link->fromsock= NULL;
- snode->edittree->update |= NTREE_UPDATE_LINKS;
- ntreeUpdateTree(snode->edittree);
+ int do_update = 0;
+ for (linkdata=nldrag->links.first; linkdata; linkdata=linkdata->next) {
+ link = linkdata->data;
+
+ if (link->fromnode || link->fromsock) {
+ BLI_remlink(&snode->edittree->links, link);
+ link->prev = link->next = NULL;
+ link->fromnode= NULL;
+ link->fromsock= NULL;
+
+ snode->edittree->update |= NTREE_UPDATE_LINKS;
+ do_update = 1;
+ }
}
+ if (do_update)
+ ntreeUpdateTree(snode->edittree);
}
}
@@ -2401,139 +2432,161 @@ static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event)
case LEFTMOUSE:
case RIGHTMOUSE:
- case MIDDLEMOUSE:
- if (link->tosock && link->fromsock) {
- /* send changed events for original tonode and new */
- snode_update(snode, link->tonode);
+ case MIDDLEMOUSE: {
+ for (linkdata=nldrag->links.first; linkdata; linkdata=linkdata->next) {
+ link = linkdata->data;
- /* we might need to remove a link */
- if (in_out==SOCK_OUT)
- node_remove_extra_links(snode, link->tosock, link);
-
- /* when linking to group outputs, update the socket type */
- /* XXX this should all be part of a generic update system */
- if (!link->tonode) {
- if(link->tosock->type != link->fromsock->type)
- nodeSocketSetType(link->tosock, link->fromsock->type);
- }
- }
- else if (outside_group_rect(snode) && (link->tonode || link->fromnode)) {
- /* automatically add new group socket */
- if (link->tonode && link->tosock) {
- link->fromsock = node_group_expose_socket(snode->edittree, link->tosock, SOCK_IN);
- link->fromnode = NULL;
- if (link->prev==NULL && link->next==NULL) {
- BLI_addtail(&snode->edittree->links, link);
+ if (link->tosock && link->fromsock) {
+ /* send changed events for original tonode and new */
+ if (link->tonode)
+ snode_update(snode, link->tonode);
+
+ /* we might need to remove a link */
+ if (in_out==SOCK_OUT)
+ node_remove_extra_links(snode, link->tosock, link);
+
+ /* when linking to group outputs, update the socket type */
+ /* XXX this should all be part of a generic update system */
+ if (!link->tonode) {
+ if(link->tosock->type != link->fromsock->type)
+ nodeSocketSetType(link->tosock, link->fromsock->type);
}
- snode->edittree->update |= NTREE_UPDATE_GROUP_IN | NTREE_UPDATE_LINKS;
}
- else if (link->fromnode && link->fromsock) {
- link->tosock = node_group_expose_socket(snode->edittree, link->fromsock, SOCK_OUT);
- link->tonode = NULL;
- if (link->prev==NULL && link->next==NULL) {
- BLI_addtail(&snode->edittree->links, link);
+ else if (outside_group_rect(snode) && (link->tonode || link->fromnode)) {
+ /* automatically add new group socket */
+ if (link->tonode && link->tosock) {
+ link->fromsock = node_group_expose_socket(snode->edittree, link->tosock, SOCK_IN);
+ link->fromnode = NULL;
+ if (link->prev==NULL && link->next==NULL)
+ BLI_addtail(&snode->edittree->links, link);
+
+ snode->edittree->update |= NTREE_UPDATE_GROUP_IN | NTREE_UPDATE_LINKS;
+ }
+ else if (link->fromnode && link->fromsock) {
+ link->tosock = node_group_expose_socket(snode->edittree, link->fromsock, SOCK_OUT);
+ link->tonode = NULL;
+ if (link->prev==NULL && link->next==NULL)
+ BLI_addtail(&snode->edittree->links, link);
+
+ snode->edittree->update |= NTREE_UPDATE_GROUP_OUT | NTREE_UPDATE_LINKS;
}
- snode->edittree->update |= NTREE_UPDATE_GROUP_OUT | NTREE_UPDATE_LINKS;
}
+ else
+ nodeRemLink(snode->edittree, link);
}
- else
- nodeRemLink(snode->edittree, link);
ntreeUpdateTree(snode->edittree);
snode_notify(C, snode);
snode_dag_update(C, snode);
BLI_remlink(&snode->linkdrag, nldrag);
+ /* links->data pointers are either held by the tree or freed already */
+ BLI_freelistN(&nldrag->links);
MEM_freeN(nldrag);
return OPERATOR_FINISHED;
+ }
}
return OPERATOR_RUNNING_MODAL;
}
/* return 1 when socket clicked */
-static int node_link_init(SpaceNode *snode, bNodeLinkDrag *nldrag)
+static bNodeLinkDrag *node_link_init(SpaceNode *snode, int detach)
{
- bNodeLink *link;
- int in_out = 0;
-
+ bNode *node;
+ bNodeSocket *sock;
+ bNodeLink *link, *link_next, *oplink;
+ bNodeLinkDrag *nldrag = NULL;
+ LinkData *linkdata;
+ int num_links;
+
/* output indicated? */
- if (node_find_indicated_socket(snode, &nldrag->node, &nldrag->sock, SOCK_OUT)) {
- if (nodeCountSocketLinks(snode->edittree, nldrag->sock) < nldrag->sock->limit)
- in_out = SOCK_OUT;
- else {
- /* find if we break a link */
- for (link= snode->edittree->links.first; link; link= link->next) {
- if (link->fromsock==nldrag->sock)
- break;
- }
- if (link) {
- nldrag->node= link->tonode;
- nldrag->sock= link->tosock;
- nodeRemLink(snode->edittree, link);
- in_out = SOCK_IN;
+ if (node_find_indicated_socket(snode, &node, &sock, SOCK_OUT)) {
+ nldrag= MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata");
+
+ num_links = nodeCountSocketLinks(snode->edittree, sock);
+ if (num_links > 0 && (num_links >= sock->limit || detach)) {
+ /* dragged links are fixed on input side */
+ nldrag->in_out = SOCK_IN;
+ /* detach current links and store them in the operator data */
+ for (link= snode->edittree->links.first; link; link= link_next) {
+ link_next = link->next;
+ if (link->fromsock==sock) {
+ linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
+ linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
+ *oplink = *link;
+ BLI_addtail(&nldrag->links, linkdata);
+ nodeRemLink(snode->edittree, link);
+ }
}
}
+ else {
+ /* dragged links are fixed on output side */
+ nldrag->in_out = SOCK_OUT;
+ /* create a new link */
+ linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
+ linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
+ oplink->fromnode = node;
+ oplink->fromsock = sock;
+ BLI_addtail(&nldrag->links, linkdata);
+ }
}
/* or an input? */
- else if (node_find_indicated_socket(snode, &nldrag->node, &nldrag->sock, SOCK_IN)) {
- if (nodeCountSocketLinks(snode->edittree, nldrag->sock) < nldrag->sock->limit)
- in_out = SOCK_IN;
- else {
- /* find if we break a link */
- for (link= snode->edittree->links.first; link; link= link->next) {
- if (link->tosock==nldrag->sock)
- break;
- }
- if (link) {
- /* send changed event to original tonode */
- if (link->tonode)
- snode_update(snode, link->tonode);
-
- nldrag->node= link->fromnode;
- nldrag->sock= link->fromsock;
- nodeRemLink(snode->edittree, link);
- in_out = SOCK_OUT;
+ else if (node_find_indicated_socket(snode, &node, &sock, SOCK_IN)) {
+ nldrag= MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata");
+
+ num_links = nodeCountSocketLinks(snode->edittree, sock);
+ if (num_links > 0 && (num_links >= sock->limit || detach)) {
+ /* dragged links are fixed on output side */
+ nldrag->in_out = SOCK_OUT;
+ /* detach current links and store them in the operator data */
+ for (link= snode->edittree->links.first; link; link= link_next) {
+ link_next = link->next;
+ if (link->tosock==sock) {
+ linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
+ linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
+ *oplink = *link;
+ BLI_addtail(&nldrag->links, linkdata);
+ nodeRemLink(snode->edittree, link);
+
+ /* send changed event to original link->tonode */
+ if (node)
+ snode_update(snode, node);
+ }
}
}
+ else {
+ /* dragged links are fixed on input side */
+ nldrag->in_out = SOCK_IN;
+ /* create a new link */
+ linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data");
+ linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link");
+ oplink->tonode = node;
+ oplink->tosock = sock;
+ BLI_addtail(&nldrag->links, linkdata);
+ }
}
- return in_out;
+ return nldrag;
}
static int node_link_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
SpaceNode *snode= CTX_wm_space_node(C);
ARegion *ar= CTX_wm_region(C);
- bNodeLinkDrag *nldrag= MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata");
-
+ bNodeLinkDrag *nldrag;
+ int detach = RNA_boolean_get(op->ptr, "detach");
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
&snode->mx, &snode->my);
ED_preview_kill_jobs(C);
- nldrag->in_out= node_link_init(snode, nldrag);
+ nldrag = node_link_init(snode, detach);
- if (nldrag->in_out) {
+ if (nldrag) {
op->customdata= nldrag;
-
- /* we make a temporal link */
- if (nldrag->in_out==SOCK_OUT) {
- nldrag->link= MEM_callocN(sizeof(bNodeLink), "link");
- nldrag->link->fromnode= nldrag->node;
- nldrag->link->fromsock= nldrag->sock;
- nldrag->link->tonode= NULL;
- nldrag->link->tosock= NULL;
- }
- else {
- nldrag->link= MEM_callocN(sizeof(bNodeLink), "link");
- nldrag->link->fromnode= NULL;
- nldrag->link->fromsock= NULL;
- nldrag->link->tonode= nldrag->node;
- nldrag->link->tosock= nldrag->sock;
- }
BLI_addtail(&snode->linkdrag, nldrag);
/* add modal handler */
@@ -2541,21 +2594,20 @@ static int node_link_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
- else {
- MEM_freeN(nldrag);
+ else
return OPERATOR_CANCELLED|OPERATOR_PASS_THROUGH;
- }
}
static int node_link_cancel(bContext *C, wmOperator *op)
{
SpaceNode *snode= CTX_wm_space_node(C);
bNodeLinkDrag *nldrag= op->customdata;
-
- nodeRemLink(snode->edittree, nldrag->link);
+
BLI_remlink(&snode->linkdrag, nldrag);
+
+ BLI_freelistN(&nldrag->links);
MEM_freeN(nldrag);
-
+
return OPERATOR_CANCELLED;
}
@@ -2575,6 +2627,8 @@ void NODE_OT_link(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
+
+ RNA_def_boolean(ot->srna, "detach", FALSE, "Detach", "Detach and redirect existing links");
}
/* ********************** Make Link operator ***************** */
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index 17078443987..802c471c7aa 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -52,9 +52,11 @@ typedef struct bNodeLinkDrag
{
struct bNodeLinkDrag *next, *prev;
- struct bNode *node;
- struct bNodeSocket *sock;
- struct bNodeLink *link;
+ /* List of links dragged by the operator.
+ * Note: This is a list of LinkData structs on top of the actual bNodeLinks.
+ * This way the links can be added to the node tree while being stored in this list.
+ */
+ ListBase links;
int in_out;
} bNodeLinkDrag;
diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c
index 7d9d7d736f6..5d586f08eb0 100644
--- a/source/blender/editors/space_node/node_ops.c
+++ b/source/blender/editors/space_node/node_ops.c
@@ -171,6 +171,8 @@ void node_keymap(struct wmKeyConfig *keyconf)
/* each of these falls through if not handled... */
WM_keymap_add_item(keymap, "NODE_OT_link", LEFTMOUSE, KM_PRESS, 0, 0);
+ kmi = WM_keymap_add_item(keymap, "NODE_OT_link", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
+ RNA_boolean_set(kmi->ptr, "detach", TRUE);
WM_keymap_add_item(keymap, "NODE_OT_resize", LEFTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NODE_OT_links_cut", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 3d6fbb53e37..1590d08b4a1 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -1323,7 +1323,7 @@ void SEQUENCER_OT_reload(struct wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER; /* no undo, the data changed is stored outside 'main' */
prop = RNA_def_boolean(ot->srna, "adjust_length", 0, "Adjust Length",
- "Adjust lenght of strips to their data lenght");
+ "Adjust length of strips to their data length");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 5413aa88ab6..00622f368f0 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -2987,7 +2987,7 @@ static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitS
interp_v3_v3v3(fvec, vmid, v2, 0.8f);
}
else {
- angle = angle_v3v3v3(loop->prev->v->co, loop->v->co, loop->v->co);
+ angle = angle_v3v3v3(loop->prev->v->co, loop->v->co, loop->next->v->co);
interp_v3_v3v3(fvec, vmid, loop->v->co, 0.8f);
}
@@ -3586,7 +3586,7 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
}
else {
/* ob->bb was set by derived mesh system, do NULL check just to be sure */
- if (me->totpoly <= 4 || (ob->bb && ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb))) {
+ if (me->totpoly <= 4 || (!ob->bb || ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb))) {
glsl = draw_glsl_material(scene, ob, v3d, dt);
check_alpha = check_alpha_pass(base);
@@ -3603,19 +3603,21 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
}
}
- /* GPU_begin_object_materials checked if this is needed */
- if (do_alpha_after) {
- if (ob->dtx & OB_DRAWXRAY) {
- add_view3d_after(&v3d->afterdraw_xraytransp, base, flag);
- }
- else {
- add_view3d_after(&v3d->afterdraw_transp, base, flag);
+ if ((flag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0) {
+ /* GPU_begin_object_materials checked if this is needed */
+ if (do_alpha_after) {
+ if (ob->dtx & OB_DRAWXRAY) {
+ add_view3d_after(&v3d->afterdraw_xraytransp, base, flag);
+ }
+ else {
+ add_view3d_after(&v3d->afterdraw_transp, base, flag);
+ }
}
- }
- else if (ob->dtx & OB_DRAWXRAY && ob->dtx & OB_DRAWTRANSP) {
- /* special case xray+transp when alpha is 1.0, without this the object vanishes */
- if (v3d->xray == 0 && v3d->transp == 0) {
- add_view3d_after(&v3d->afterdraw_xray, base, flag);
+ else if (ob->dtx & OB_DRAWXRAY && ob->dtx & OB_DRAWTRANSP) {
+ /* special case xray+transp when alpha is 1.0, without this the object vanishes */
+ if (v3d->xray == 0 && v3d->transp == 0) {
+ add_view3d_after(&v3d->afterdraw_xray, base, flag);
+ }
}
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 682d8950440..fe142ced7fa 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -1715,6 +1715,7 @@ typedef struct View3DAfter {
void add_view3d_after(ListBase *lb, Base *base, int flag)
{
View3DAfter *v3da = MEM_callocN(sizeof(View3DAfter), "View 3d after");
+ BLI_assert((base->flag & OB_FROMDUPLI) == 0);
BLI_addtail(lb, v3da);
v3da->base = base;
v3da->flag = flag;
@@ -1815,7 +1816,7 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas
RegionView3D *rv3d = ar->regiondata;
ListBase *lb;
DupliObject *dob_prev = NULL, *dob, *dob_next = NULL;
- Base tbase;
+ Base tbase = {NULL};
BoundBox bb, *bb_tmp; /* use a copy because draw_object, calls clear_mesh_caches */
GLuint displist = 0;
short transflag, use_displist = -1; /* -1 is initialize */
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index e35c0e1c654..4bfb6dd9fd6 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -431,7 +431,7 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event)
if (vod->use_dyn_ofs) {
/* If there's no selection, lastofs is unmodified and last value since static */
- calculateTransformCenter(C, V3D_CENTROID, lastofs);
+ calculateTransformCenter(C, V3D_CENTROID, lastofs, NULL);
negate_v3_v3(vod->dyn_ofs, lastofs);
}
else if (U.uiflag & USER_ORBIT_ZBUF) {
@@ -1423,7 +1423,8 @@ void viewzoom_modal_keymap(wmKeyConfig *keyconf)
{VIEWROT_MODAL_SWITCH_ROTATE, "SWITCH_TO_ROTATE", 0, "Switch to Rotate"},
{VIEWROT_MODAL_SWITCH_MOVE, "SWITCH_TO_MOVE", 0, "Switch to Move"},
- {0, NULL, 0, NULL, NULL}};
+ {0, NULL, 0, NULL, NULL}
+ };
wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Zoom Modal");
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 5c605e02fd1..d07ae468f35 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -606,6 +606,72 @@ wmKeyMap* transform_modal_keymap(wmKeyConfig *keyconf)
return keymap;
}
+static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cmode)
+{
+ if (!(t->flag & T_NO_CONSTRAINT)) {
+ int constraint_axis, constraint_plane;
+ int edit_2d = (t->flag & T_2D_EDIT);
+ char msg1[] = "along _";
+ char msg2[] = "along %s _";
+ char msg3[] = "locking %s _";
+ char axis;
+
+ /* Initialize */
+ switch(key_type) {
+ case XKEY:
+ axis = 'X';
+ constraint_axis = CON_AXIS0;
+ break;
+ case YKEY:
+ axis = 'Y';
+ constraint_axis = CON_AXIS1;
+ break;
+ case ZKEY:
+ axis = 'Z';
+ constraint_axis = CON_AXIS2;
+ break;
+ default:
+ /* Invalid key */
+ return;
+ }
+ msg1[sizeof(msg1) - 2] = axis;
+ msg2[sizeof(msg2) - 2] = axis;
+ msg3[sizeof(msg3) - 2] = axis;
+ constraint_plane = ((CON_AXIS0 | CON_AXIS1 | CON_AXIS2) &
+ (~constraint_axis));
+
+ if (edit_2d && (key_type != ZKEY)) {
+ if (cmode == axis) {
+ stopConstraint(t);
+ }
+ else {
+ setUserConstraint(t, V3D_MANIP_GLOBAL, constraint_axis, msg1);
+ }
+ }
+ else if (!edit_2d) {
+ if (cmode == axis) {
+ if (t->con.orientation != V3D_MANIP_GLOBAL) {
+ stopConstraint(t);
+ }
+ else {
+ short orientation = (t->current_orientation != V3D_MANIP_GLOBAL ?
+ t->current_orientation : V3D_MANIP_LOCAL);
+ if (!(t->modifiers & MOD_CONSTRAINT_PLANE))
+ setUserConstraint(t, orientation, constraint_axis, msg2);
+ else if (t->modifiers & MOD_CONSTRAINT_PLANE)
+ setUserConstraint(t, orientation, constraint_plane, msg3);
+ }
+ }
+ else {
+ if (!(t->modifiers & MOD_CONSTRAINT_PLANE))
+ setUserConstraint(t, V3D_MANIP_GLOBAL, constraint_axis, msg2);
+ else if (t->modifiers & MOD_CONSTRAINT_PLANE)
+ setUserConstraint(t, V3D_MANIP_GLOBAL, constraint_plane, msg3);
+ }
+ }
+ t->redraw |= TREDRAW_HARD;
+ }
+}
int transformEvent(TransInfo *t, wmEvent *event)
{
@@ -950,93 +1016,9 @@ int transformEvent(TransInfo *t, wmEvent *event)
}
break;
case XKEY:
- if ((t->flag & T_NO_CONSTRAINT)==0) {
- if (t->flag & T_2D_EDIT) {
- if (cmode == 'X') {
- stopConstraint(t);
- }
- else {
- setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS0), "along X");
- }
- }
- else {
- if (cmode == 'X') {
- if (t->con.orientation != V3D_MANIP_GLOBAL) {
- stopConstraint(t);
- }
- else {
- short orientation = t->current_orientation != V3D_MANIP_GLOBAL ? t->current_orientation : V3D_MANIP_LOCAL;
- if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0)
- setUserConstraint(t, orientation, (CON_AXIS0), "along %s X");
- else if (t->modifiers & MOD_CONSTRAINT_PLANE)
- setUserConstraint(t, orientation, (CON_AXIS1|CON_AXIS2), "locking %s X");
- }
- }
- else {
- if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0)
- setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS0), "along %s X");
- else if (t->modifiers & MOD_CONSTRAINT_PLANE)
- setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS1|CON_AXIS2), "locking %s X");
- }
- }
- t->redraw |= TREDRAW_HARD;
- }
- break;
case YKEY:
- if ((t->flag & T_NO_CONSTRAINT)==0) {
- if (t->flag & T_2D_EDIT) {
- if (cmode == 'Y') {
- stopConstraint(t);
- }
- else {
- setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS1), "along Y");
- }
- }
- else {
- if (cmode == 'Y') {
- if (t->con.orientation != V3D_MANIP_GLOBAL) {
- stopConstraint(t);
- }
- else {
- short orientation = t->current_orientation != V3D_MANIP_GLOBAL ? t->current_orientation : V3D_MANIP_LOCAL;
- if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0)
- setUserConstraint(t, orientation, (CON_AXIS1), "along %s Y");
- else if (t->modifiers & MOD_CONSTRAINT_PLANE)
- setUserConstraint(t, orientation, (CON_AXIS0|CON_AXIS2), "locking %s Y");
- }
- }
- else {
- if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0)
- setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS1), "along %s Y");
- else if (t->modifiers & MOD_CONSTRAINT_PLANE)
- setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS0|CON_AXIS2), "locking %s Y");
- }
- }
- t->redraw |= TREDRAW_HARD;
- }
- break;
case ZKEY:
- if ((t->flag & (T_NO_CONSTRAINT|T_2D_EDIT))==0) {
- if (cmode == 'Z') {
- if (t->con.orientation != V3D_MANIP_GLOBAL) {
- stopConstraint(t);
- }
- else {
- short orientation = t->current_orientation != V3D_MANIP_GLOBAL ? t->current_orientation : V3D_MANIP_LOCAL;
- if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0)
- setUserConstraint(t, orientation, (CON_AXIS2), "along %s Z");
- else if (t->modifiers & MOD_CONSTRAINT_PLANE)
- setUserConstraint(t, orientation, (CON_AXIS0|CON_AXIS1), "locking %s Z");
- }
- }
- else {
- if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0)
- setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS2), "along %s Z");
- else if (t->modifiers & MOD_CONSTRAINT_PLANE)
- setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS0|CON_AXIS1), "locking %s Z");
- }
- t->redraw |= TREDRAW_HARD;
- }
+ transform_event_xyz_constraint(t, event->type, cmode);
break;
case OKEY:
if (t->flag & T_PROP_EDIT && event->shift) {
@@ -1134,7 +1116,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
return OPERATOR_PASS_THROUGH;
}
-int calculateTransformCenter(bContext *C, int centerMode, float *vec)
+int calculateTransformCenter(bContext *C, int centerMode, float *cent3d, int *cent2d)
{
TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data");
int success = 1;
@@ -1159,8 +1141,12 @@ int calculateTransformCenter(bContext *C, int centerMode, float *vec)
calculateCenter(t);
- // Copy center from constraint center. Transform center can be local
- copy_v3_v3(vec, t->con.center);
+ if(cent2d)
+ copy_v2_v2_int(cent2d, t->center2d);
+ if(cent3d) {
+ // Copy center from constraint center. Transform center can be local
+ copy_v3_v3(cent3d, t->con.center);
+ }
}
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index c4db85420ca..c9eb975cb77 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -4054,7 +4054,47 @@ static void freeSeqData(TransInfo *t)
}
}
+#if 1 /* (mango hack! - for Ian) this is truely bad - should _never_ be in a release :| */
+ if (CTX_wm_window(t->context)->eventstate->alt) {
+ int minframe = MAXFRAME;
+ td= t->data;
+ seq_prev= NULL;
+ for (a=0; a<t->total; a++, td++) {
+ seq= ((TransDataSeq *)td->extra)->seq;
+ if ((seq != seq_prev)) {
+ minframe = MIN2(minframe, seq->startdisp);
+ }
+ }
+
+
+ for (seq= seqbasep->first; seq; seq= seq->next) {
+ if (!(seq->flag & SELECT)) {
+ if (seq->startdisp >= minframe) {
+ seq->machine += MAXSEQ * 2;
+ }
+ }
+ }
+
+ shuffle_seq_time(seqbasep, t->scene);
+
+ for (seq= seqbasep->first; seq; seq= seq->next) {
+ if (seq->machine >= MAXSEQ * 2) {
+ seq->machine -= MAXSEQ * 2;
+ seq->tmp= (void*)1;
+ }
+ else {
+ seq->tmp= NULL;
+ }
+ }
+
+ shuffle_seq_time(seqbasep, t->scene);
+ }
+ else {
+ shuffle_seq_time(seqbasep, t->scene);
+ }
+#else
shuffle_seq_time(seqbasep, t->scene);
+#endif
if (has_effect) {
/* update effects strips based on strips just moved in time */