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:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2012-10-20 20:48:48 +0400
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2012-10-20 20:48:48 +0400
commit55015daa43f0ab45341e316abcf11f23c87b5ebe (patch)
tree3156892b6d807d9ba513d444adb870b0ae358e7a /source/blender/editors
parent1fe70c07a008185c4e5925aff2c214c93ff396b7 (diff)
parenta9e2e2279780ec2fb58e6820b9cad95ba03f4cad (diff)
Merged changes in the trunk up to revision 51448.
Conflicts resolved: source/blender/blenkernel/CMakeLists.txt source/blender/blenloader/intern/readfile.c source/blender/editors/mesh/editmesh_tools.c source/blender/makesrna/intern/rna_main_api.c
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/animation/anim_filter.c28
-rw-r--r--source/blender/editors/animation/anim_intern.h2
-rw-r--r--source/blender/editors/animation/anim_ops.c2
-rw-r--r--source/blender/editors/animation/drivers.c8
-rw-r--r--source/blender/editors/animation/fmodifier_ui.c43
-rw-r--r--source/blender/editors/animation/keyframing.c53
-rw-r--r--source/blender/editors/animation/keyingsets.c18
-rw-r--r--source/blender/editors/armature/editarmature.c50
-rw-r--r--source/blender/editors/armature/editarmature_retarget.c6
-rw-r--r--source/blender/editors/armature/editarmature_sketch.c12
-rw-r--r--source/blender/editors/armature/meshlaplacian.c8
-rw-r--r--source/blender/editors/armature/poseSlide.c1
-rw-r--r--source/blender/editors/armature/poselib.c22
-rw-r--r--source/blender/editors/armature/poseobject.c8
-rw-r--r--source/blender/editors/curve/editcurve.c138
-rw-r--r--source/blender/editors/curve/editfont.c5
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c21
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c154
-rw-r--r--source/blender/editors/include/ED_anim_api.h36
-rw-r--r--source/blender/editors/include/ED_armature.h13
-rw-r--r--source/blender/editors/include/ED_keyframes_draw.h1
-rw-r--r--source/blender/editors/include/ED_mball.h2
-rw-r--r--source/blender/editors/include/ED_mesh.h6
-rw-r--r--source/blender/editors/include/ED_object.h22
-rw-r--r--source/blender/editors/include/ED_view3d.h125
-rw-r--r--source/blender/editors/include/UI_icons.h2
-rw-r--r--source/blender/editors/interface/interface.c67
-rw-r--r--source/blender/editors/interface/interface_handlers.c32
-rw-r--r--source/blender/editors/interface/interface_layout.c11
-rw-r--r--source/blender/editors/interface/interface_ops.c24
-rw-r--r--source/blender/editors/interface/interface_regions.c14
-rw-r--r--source/blender/editors/interface/interface_widgets.c16
-rw-r--r--source/blender/editors/interface/view2d_ops.c32
-rw-r--r--source/blender/editors/io/io_collada.c4
-rw-r--r--source/blender/editors/mask/mask_add.c24
-rw-r--r--source/blender/editors/mask/mask_draw.c79
-rw-r--r--source/blender/editors/mask/mask_intern.h3
-rw-r--r--source/blender/editors/mask/mask_ops.c22
-rw-r--r--source/blender/editors/mask/mask_select.c2
-rw-r--r--source/blender/editors/mesh/CMakeLists.txt5
-rw-r--r--source/blender/editors/mesh/SConscript5
-rw-r--r--source/blender/editors/mesh/editface.c8
-rw-r--r--source/blender/editors/mesh/editmesh_add.c22
-rw-r--r--source/blender/editors/mesh/editmesh_bvh.c6
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c2
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c4
-rw-r--r--source/blender/editors/mesh/editmesh_rip.c359
-rw-r--r--source/blender/editors/mesh/editmesh_select.c152
-rw-r--r--source/blender/editors/mesh/editmesh_slide.c25
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c224
-rw-r--r--source/blender/editors/mesh/mesh_data.c30
-rw-r--r--source/blender/editors/mesh/mesh_intern.h6
-rw-r--r--source/blender/editors/mesh/mesh_ops.c17
-rw-r--r--source/blender/editors/mesh/meshtools.c12
-rw-r--r--source/blender/editors/metaball/mball_edit.c3
-rw-r--r--source/blender/editors/object/object_add.c26
-rw-r--r--source/blender/editors/object/object_bake.c27
-rw-r--r--source/blender/editors/object/object_constraint.c4
-rw-r--r--source/blender/editors/object/object_hook.c2
-rw-r--r--source/blender/editors/object/object_intern.h3
-rw-r--r--source/blender/editors/object/object_lattice.c276
-rw-r--r--source/blender/editors/object/object_modifier.c2
-rw-r--r--source/blender/editors/object/object_ops.c5
-rw-r--r--source/blender/editors/object/object_relations.c118
-rw-r--r--source/blender/editors/object/object_shapekey.c6
-rw-r--r--source/blender/editors/object/object_transform.c38
-rw-r--r--source/blender/editors/object/object_vgroup.c591
-rw-r--r--source/blender/editors/physics/dynamicpaint_ops.c58
-rw-r--r--source/blender/editors/physics/particle_edit.c24
-rw-r--r--source/blender/editors/physics/physics_pointcache.c6
-rw-r--r--source/blender/editors/render/render_internal.c4
-rw-r--r--source/blender/editors/render/render_opengl.c2
-rw-r--r--source/blender/editors/render/render_preview.c15
-rw-r--r--source/blender/editors/render/render_shading.c6
-rw-r--r--source/blender/editors/render/render_update.c53
-rw-r--r--source/blender/editors/screen/area.c31
-rw-r--r--source/blender/editors/screen/screen_ops.c12
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c6
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c22
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h2
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c19
-rw-r--r--source/blender/editors/sculpt_paint/paint_undo.c12
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c18
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c16
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h2
-rw-r--r--source/blender/editors/space_action/action_edit.c35
-rw-r--r--source/blender/editors/space_action/action_ops.c5
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c2
-rw-r--r--source/blender/editors/space_buttons/buttons_ops.c2
-rw-r--r--source/blender/editors/space_clip/clip_draw.c5
-rw-r--r--source/blender/editors/space_clip/clip_editor.c3
-rw-r--r--source/blender/editors/space_clip/clip_ops.c30
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c15
-rw-r--r--source/blender/editors/space_clip/tracking_select.c3
-rw-r--r--source/blender/editors/space_console/console_draw.c13
-rw-r--r--source/blender/editors/space_console/console_ops.c2
-rw-r--r--source/blender/editors/space_file/file_ops.c39
-rw-r--r--source/blender/editors/space_file/filelist.c21
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c39
-rw-r--r--source/blender/editors/space_graph/graph_edit.c41
-rw-r--r--source/blender/editors/space_graph/graph_ops.c5
-rw-r--r--source/blender/editors/space_image/image_ops.c27
-rw-r--r--source/blender/editors/space_image/space_image.c5
-rw-r--r--source/blender/editors/space_info/info_ops.c4
-rw-r--r--source/blender/editors/space_info/textview.c2
-rw-r--r--source/blender/editors/space_nla/nla_draw.c2
-rw-r--r--source/blender/editors/space_nla/nla_edit.c10
-rw-r--r--source/blender/editors/space_node/drawnode.c1
-rw-r--r--source/blender/editors/space_node/node_edit.c3
-rw-r--r--source/blender/editors/space_node/node_group.c16
-rw-r--r--source/blender/editors/space_node/node_select.c2
-rw-r--r--source/blender/editors/space_node/node_templates.c6
-rw-r--r--source/blender/editors/space_node/space_node.c9
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c16
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c6
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c73
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c24
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c20
-rw-r--r--source/blender/editors/space_text/text_draw.c13
-rw-r--r--source/blender/editors/space_text/text_ops.c2
-rw-r--r--source/blender/editors/space_view3d/CMakeLists.txt2
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c13
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c3
-rw-r--r--source/blender/editors/space_view3d/drawobject.c559
-rw-r--r--source/blender/editors/space_view3d/drawvolume.c298
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c363
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c57
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c362
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h19
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.c415
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c18
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c493
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c323
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c486
-rw-r--r--source/blender/editors/transform/transform.c99
-rw-r--r--source/blender/editors/transform/transform.h2
-rw-r--r--source/blender/editors/transform/transform_conversions.c8
-rw-r--r--source/blender/editors/transform/transform_ops.c20
-rw-r--r--source/blender/editors/transform/transform_orientations.c9
-rw-r--r--source/blender/editors/transform/transform_snap.c8
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c47
-rw-r--r--source/blender/editors/uvedit/uvedit_intern.h24
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c42
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c80
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c24
146 files changed, 5037 insertions, 2645 deletions
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index eb7bc68ff8f..9b88c307cb6 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -994,6 +994,27 @@ static short skip_fcurve_with_name(bDopeSheet *ads, FCurve *fcu, ID *owner_id)
return 1;
}
+/* Check if F-Curve has errors and/or is disabled
+ * > returns: (bool) True if F-Curve has errors/is disabled
+ */
+static short fcurve_has_errors(FCurve *fcu)
+{
+ /* F-Curve disabled - path eval error */
+ if (fcu->flag & FCURVE_DISABLED) {
+ return 1;
+ }
+
+ /* driver? */
+ if (fcu->driver) {
+ /* for now, just check if the entire thing got disabled... */
+ if (fcu->driver->flag & DRIVER_FLAG_INVALID)
+ return 1;
+ }
+
+ /* no errors found */
+ return 0;
+}
+
/* find the next F-Curve that is usable for inclusion */
static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, bActionGroup *grp, int filter_mode, ID *owner_id)
{
@@ -1032,6 +1053,13 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, bActionGro
continue;
}
+ /* error-based filtering... */
+ if ((ads) && (ads->filterflag & ADS_FILTER_ONLY_ERRORS)) {
+ /* skip if no errors... */
+ if (fcurve_has_errors(fcu) == 0)
+ continue;
+ }
+
/* this F-Curve can be used, so return it */
return fcu;
}
diff --git a/source/blender/editors/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h
index bc07bf091de..54c7f7ea30f 100644
--- a/source/blender/editors/animation/anim_intern.h
+++ b/source/blender/editors/animation/anim_intern.h
@@ -82,4 +82,4 @@ void ANIM_OT_driver_button_remove(struct wmOperatorType *ot);
void ANIM_OT_copy_driver_button(struct wmOperatorType *ot);
void ANIM_OT_paste_driver_button(struct wmOperatorType *ot);
-#endif // __ANIM_INTERN_H__
+#endif /* __ANIM_INTERN_H__ */
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index f2711ec3bb5..ca036a8540e 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -172,7 +172,7 @@ static void ANIM_OT_change_frame(wmOperatorType *ot)
ot->poll = change_frame_poll;
/* flags */
- ot->flag = OPTYPE_BLOCKING | OPTYPE_UNDO;
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_UNDO | OPTYPE_GRAB_POINTER;
/* rna */
RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME);
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index 672e11ac613..38f9119104b 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -147,7 +147,7 @@ short ANIM_add_driver(ReportList *reports, ID *id, const char rna_path[], int ar
RNA_id_pointer_create(id, &id_ptr);
if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) {
BKE_reportf(reports, RPT_ERROR,
- "Could not add Driver, as RNA Path is invalid for the given ID (ID = %s, Path = %s)",
+ "Could not add driver, as RNA path is invalid for the given ID (ID = %s, path = %s)",
id->name, rna_path);
return 0;
}
@@ -310,7 +310,7 @@ short ANIM_copy_driver(ReportList *reports, ID *id, const char rna_path[], int a
RNA_id_pointer_create(id, &id_ptr);
if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) {
BKE_reportf(reports, RPT_ERROR,
- "Could not find Driver to copy, as RNA Path is invalid for the given ID (ID = %s, Path = %s)",
+ "Could not find driver to copy, as RNA path is invalid for the given ID (ID = %s, path = %s)",
id->name, rna_path);
return 0;
}
@@ -357,14 +357,14 @@ short ANIM_paste_driver(ReportList *reports, ID *id, const char rna_path[], int
RNA_id_pointer_create(id, &id_ptr);
if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) {
BKE_reportf(reports, RPT_ERROR,
- "Could not paste Driver, as RNA Path is invalid for the given ID (ID = %s, Path = %s)",
+ "Could not paste driver, as RNA path is invalid for the given ID (ID = %s, path = %s)",
id->name, rna_path);
return 0;
}
/* if the buffer is empty, cannot paste... */
if (channeldriver_copypaste_buf == NULL) {
- BKE_report(reports, RPT_ERROR, "Paste Driver: No Driver to paste");
+ BKE_report(reports, RPT_ERROR, "Paste driver: no driver to paste");
return 0;
}
diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c
index 30e4d8570cb..a591b51b0b3 100644
--- a/source/blender/editors/animation/fmodifier_ui.c
+++ b/source/blender/editors/animation/fmodifier_ui.c
@@ -111,6 +111,7 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
uiBlock *block;
uiBut *but;
PointerRNA ptr;
+ short bwidth = width - 30; /* max button width */
/* init the RNA-pointer */
RNA_pointer_create(id, &RNA_FModifierFunctionGenerator, fcm, &ptr);
@@ -119,10 +120,10 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
/* col = uiLayoutColumn(layout, TRUE); */ /* UNUSED */
block = uiLayoutGetBlock(layout);
uiBlockBeginAlign(block);
- but = uiDefButR(block, MENU, B_FMODIFIER_REDRAW, NULL, 0, 0, width - 30, UI_UNIT_Y, &ptr, "mode", -1, 0, 0, -1, -1, NULL);
+ but = uiDefButR(block, MENU, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "mode", -1, 0, 0, -1, -1, NULL);
uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL);
-
- uiDefButR(block, TOG, B_FMODIFIER_REDRAW, NULL, 0, 0, width - 30, UI_UNIT_Y, &ptr, "use_additive", -1, 0, 0, -1, -1, NULL);
+
+ uiDefButR(block, TOG, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "use_additive", -1, 0, 0, -1, -1, NULL);
uiBlockEndAlign(block);
/* now add settings for individual modes */
@@ -132,50 +133,62 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s
float *cp = NULL;
char xval[32];
unsigned int i;
+ int maxXWidth;
/* draw polynomial order selector */
row = uiLayoutRow(layout, FALSE);
block = uiLayoutGetBlock(row);
- but = uiDefButI(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 10, 0, width - 30, 19,
+ but = uiDefButI(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 10, 0, bwidth, 20,
&data->poly_order, 1, 100, 0, 0,
TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)"));
uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL);
+ /* calculate maximum width of label for "x^n" labels */
+ if (data->arraysize > 2) {
+ BLI_snprintf(xval, sizeof(xval), "x^%u", data->arraysize);
+ maxXWidth = UI_GetStringWidth(xval) + 10; /* XXX: UI_GetStringWidth is not accurate */
+ }
+ else {
+ /* basic size (just "x") */
+ maxXWidth = 15;
+ }
+
/* draw controls for each coefficient and a + sign at end of row */
row = uiLayoutRow(layout, TRUE);
block = uiLayoutGetBlock(row);
cp = data->coefficients;
for (i = 0; (i < data->arraysize) && (cp); i++, cp++) {
- /* To align with first line */
+ /* To align with first line... */
if (i)
- uiDefBut(block, LABEL, 1, " ", 0, 0, 50, 20, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, LABEL, 1, " ", 0, 0, 40, 20, NULL, 0.0, 0.0, 0, 0, "");
else
- uiDefBut(block, LABEL, 1, "y =", 0, 0, 50, 20, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, LABEL, 1, "y =", 0, 0, 40, 20, NULL, 0.0, 0.0, 0, 0, "");
+
/* coefficient */
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, 150, 20, cp, -UI_FLT_MAX, UI_FLT_MAX,
+ uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, bwidth/2, 20, cp, -UI_FLT_MAX, UI_FLT_MAX,
10, 3, TIP_("Coefficient for polynomial"));
/* 'x' param (and '+' if necessary) */
if (i == 0)
- strcpy(xval, "");
+ BLI_strncpy(xval, "", sizeof(xval));
else if (i == 1)
- strcpy(xval, "x");
+ BLI_strncpy(xval, "x", sizeof(xval));
else
- sprintf(xval, "x^%u", i);
- uiDefBut(block, LABEL, 1, xval, 0, 0, 50, 20, NULL, 0.0, 0.0, 0, 0, TIP_("Power of x"));
+ BLI_snprintf(xval, sizeof(xval), "x^%u", i);
+ uiDefBut(block, LABEL, 1, xval, 0, 0, maxXWidth, 20, NULL, 0.0, 0.0, 0, 0, TIP_("Power of x"));
if ( (i != (data->arraysize - 1)) || ((i == 0) && data->arraysize == 2) ) {
- uiDefBut(block, LABEL, 1, "+", 0, 0, 30, 20, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, LABEL, 1, "+", 0, 0, 20, 20, NULL, 0.0, 0.0, 0, 0, "");
/* next coefficient on a new row */
row = uiLayoutRow(layout, TRUE);
block = uiLayoutGetBlock(row);
}
else {
- /* For alignement in UI! */
- uiDefBut(block, LABEL, 1, " ", 0, 0, 30, 20, NULL, 0.0, 0.0, 0, 0, "");
+ /* For alignment in UI! */
+ uiDefBut(block, LABEL, 1, " ", 0, 0, 20, 20, NULL, 0.0, 0.0, 0, 0, "");
}
}
break;
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 0454e88e320..f0c5f063e57 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -43,6 +43,8 @@
#include "BLI_dynstr.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
@@ -787,14 +789,15 @@ short insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *p
/* F-Curve not editable? */
if (fcurve_is_keyframable(fcu) == 0) {
BKE_reportf(reports, RPT_ERROR,
- "F-Curve with path = '%s' [%d] cannot be keyframed. Ensure that it is not locked or sampled. Also, try removing F-Modifiers",
+ "F-Curve with path = '%s' [%d] cannot be keyframed, ensure that it is not locked or sampled, "
+ "and try removing F-Modifiers",
fcu->rna_path, fcu->array_index);
return 0;
}
/* if no property given yet, try to validate from F-Curve info */
if ((ptr.id.data == NULL) && (ptr.data == NULL)) {
- BKE_report(reports, RPT_ERROR, "No RNA-pointer available to retrieve values for keyframing from");
+ BKE_report(reports, RPT_ERROR, "No RNA pointer available to retrieve values for keyframing from");
return 0;
}
if (prop == NULL) {
@@ -803,10 +806,10 @@ short insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *p
/* try to get property we should be affecting */
if ((RNA_path_resolve(&ptr, fcu->rna_path, &tmp_ptr, &prop) == 0) || (prop == NULL)) {
/* property not found... */
- const char *idname = (ptr.id.data) ? ((ID *)ptr.id.data)->name : "<No ID-Pointer>";
+ const char *idname = (ptr.id.data) ? ((ID *)ptr.id.data)->name : TIP_("<No ID pointer>");
BKE_reportf(reports, RPT_ERROR,
- "Could not insert keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)",
+ "Could not insert keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)",
idname, fcu->rna_path);
return 0;
}
@@ -906,15 +909,15 @@ short insert_keyframe(ReportList *reports, ID *id, bAction *act, const char grou
/* validate pointer first - exit if failure */
if (id == NULL) {
- BKE_reportf(reports, RPT_ERROR, "No ID-block to insert keyframe in (Path = %s)", rna_path);
+ BKE_reportf(reports, RPT_ERROR, "No ID block to insert keyframe in (path = %s)", rna_path);
return 0;
}
RNA_id_pointer_create(id, &id_ptr);
if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) {
BKE_reportf(reports, RPT_ERROR,
- "Could not insert keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)",
- (id) ? id->name : "<Missing ID-Block>", rna_path);
+ "Could not insert keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)",
+ (id) ? id->name : TIP_("<Missing ID block>"), rna_path);
return 0;
}
@@ -927,7 +930,7 @@ short insert_keyframe(ReportList *reports, ID *id, bAction *act, const char grou
if (act == NULL) {
BKE_reportf(reports, RPT_ERROR,
- "Could not insert keyframe, as this type does not support animation data (ID = %s, Path = %s)",
+ "Could not insert keyframe, as this type does not support animation data (ID = %s, path = %s)",
id->name, rna_path);
return 0;
}
@@ -997,14 +1000,16 @@ short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char grou
/* sanity checks */
if (ELEM(NULL, id, adt)) {
- BKE_report(reports, RPT_ERROR, "No ID-Block and/Or AnimData to delete keyframe from");
+ BKE_report(reports, RPT_ERROR, "No ID block and/or AnimData to delete keyframe from");
return 0;
}
/* validate pointer first - exit if failure */
RNA_id_pointer_create(id, &id_ptr);
if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) {
- BKE_reportf(reports, RPT_ERROR, "Could not delete keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", id->name, rna_path);
+ BKE_reportf(reports, RPT_ERROR,
+ "Could not delete keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)",
+ id->name, rna_path);
return 0;
}
@@ -1023,7 +1028,7 @@ short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char grou
cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
}
else {
- BKE_reportf(reports, RPT_ERROR, "No Action to delete keyframes from for ID = %s\n", id->name);
+ BKE_reportf(reports, RPT_ERROR, "No action to delete keyframes from for ID = %s\n", id->name);
return 0;
}
}
@@ -1096,14 +1101,16 @@ static short clear_keyframe(ReportList *reports, ID *id, bAction *act, const cha
/* sanity checks */
if (ELEM(NULL, id, adt)) {
- BKE_report(reports, RPT_ERROR, "No ID-Block and/Or AnimData to delete keyframe from");
+ BKE_report(reports, RPT_ERROR, "No ID block and/or AnimData to delete keyframe from");
return 0;
}
/* validate pointer first - exit if failure */
RNA_id_pointer_create(id, &id_ptr);
if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) {
- BKE_reportf(reports, RPT_ERROR, "Could not clear keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", id->name, rna_path);
+ BKE_reportf(reports, RPT_ERROR,
+ "Could not clear keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)",
+ id->name, rna_path);
return 0;
}
@@ -1119,7 +1126,7 @@ static short clear_keyframe(ReportList *reports, ID *id, bAction *act, const cha
act = adt->action;
}
else {
- BKE_reportf(reports, RPT_ERROR, "No Action to delete keyframes from for ID = %s\n", id->name);
+ BKE_reportf(reports, RPT_ERROR, "No action to delete keyframes from for ID = %s\n", id->name);
return 0;
}
}
@@ -1222,30 +1229,30 @@ static int insert_key_exec(bContext *C, wmOperator *op)
/* report failures */
if (ks == NULL) {
- BKE_report(op->reports, RPT_ERROR, "No active Keying Set");
+ BKE_report(op->reports, RPT_ERROR, "No active keying set");
return OPERATOR_CANCELLED;
}
/* try to insert keyframes for the channels specified by KeyingSet */
success = ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
if (G.debug & G_DEBUG)
- BKE_reportf(op->reports, RPT_INFO, "KeyingSet '%s' - Successfully added %d Keyframes\n", ks->name, success);
+ BKE_reportf(op->reports, RPT_INFO, "Keying set '%s' - successfully added %d keyframes\n", ks->name, success);
/* report failure or do updates? */
if (success == MODIFYKEY_INVALID_CONTEXT) {
- BKE_report(op->reports, RPT_ERROR, "No suitable context info for active Keying Set");
+ BKE_report(op->reports, RPT_ERROR, "No suitable context info for active keying set");
return OPERATOR_CANCELLED;
}
else if (success) {
/* if the appropriate properties have been set, make a note that we've inserted something */
if (RNA_boolean_get(op->ptr, "confirm_success"))
- BKE_reportf(op->reports, RPT_INFO, "Successfully added %d Keyframes for KeyingSet '%s'", success, ks->name);
+ BKE_reportf(op->reports, RPT_INFO, "Successfully added %d keyframes for keying set '%s'", success, ks->name);
/* send notifiers that keyframes have been changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
}
else
- BKE_report(op->reports, RPT_WARNING, "Keying Set failed to insert any keyframes");
+ BKE_report(op->reports, RPT_WARNING, "Keying set failed to insert any keyframes");
/* send updates */
DAG_ids_flush_update(bmain, 0);
@@ -1389,19 +1396,19 @@ static int delete_key_exec(bContext *C, wmOperator *op)
/* report failure or do updates? */
if (success == MODIFYKEY_INVALID_CONTEXT) {
- BKE_report(op->reports, RPT_ERROR, "No suitable context info for active Keying Set");
+ BKE_report(op->reports, RPT_ERROR, "No suitable context info for active keying set");
return OPERATOR_CANCELLED;
}
else if (success) {
/* if the appropriate properties have been set, make a note that we've inserted something */
if (RNA_boolean_get(op->ptr, "confirm_success"))
- BKE_reportf(op->reports, RPT_INFO, "Successfully removed %d Keyframes for KeyingSet '%s'", success, ks->name);
+ BKE_reportf(op->reports, RPT_INFO, "Successfully removed %d keyframes for keying set '%s'", success, ks->name);
/* send notifiers that keyframes have been changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
}
else
- BKE_report(op->reports, RPT_WARNING, "Keying Set failed to remove any keyframes");
+ BKE_report(op->reports, RPT_WARNING, "Keying set failed to remove any keyframes");
/* send updates */
DAG_ids_flush_update(bmain, 0);
@@ -1626,7 +1633,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
else {
if (G.debug & G_DEBUG)
printf("Button Insert-Key: no path to property\n");
- BKE_report(op->reports, RPT_WARNING, "Failed to resolve path to property. Try using a Keying Set instead");
+ BKE_report(op->reports, RPT_WARNING, "Failed to resolve path to property, try using a keying set instead");
}
}
else if (G.debug & G_DEBUG) {
diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c
index 04fd7f677b0..5844bd6708f 100644
--- a/source/blender/editors/animation/keyingsets.c
+++ b/source/blender/editors/animation/keyingsets.c
@@ -161,11 +161,11 @@ static int remove_active_keyingset_exec(bContext *C, wmOperator *op)
* - return error if it doesn't exist
*/
if (scene->active_keyingset == 0) {
- BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove");
+ BKE_report(op->reports, RPT_ERROR, "No active keying set to remove");
return OPERATOR_CANCELLED;
}
else if (scene->active_keyingset < 0) {
- BKE_report(op->reports, RPT_ERROR, "Cannot remove built in Keying Set");
+ BKE_report(op->reports, RPT_ERROR, "Cannot remove built in keying set");
return OPERATOR_CANCELLED;
}
else
@@ -209,7 +209,7 @@ static int add_empty_ks_path_exec(bContext *C, wmOperator *op)
* - return error if it doesn't exist
*/
if (scene->active_keyingset == 0) {
- BKE_report(op->reports, RPT_ERROR, "No active Keying Set to add empty path to");
+ BKE_report(op->reports, RPT_ERROR, "No active keying set to add empty path to");
return OPERATOR_CANCELLED;
}
else
@@ -258,12 +258,12 @@ static int remove_active_ks_path_exec(bContext *C, wmOperator *op)
ks->active_path--;
}
else {
- BKE_report(op->reports, RPT_ERROR, "No active Keying Set Path to remove");
+ BKE_report(op->reports, RPT_ERROR, "No active keying set path to remove");
return OPERATOR_CANCELLED;
}
}
else {
- BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove a path from");
+ BKE_report(op->reports, RPT_ERROR, "No active keying set to remove a path from");
return OPERATOR_CANCELLED;
}
@@ -322,7 +322,7 @@ static int add_keyingset_button_exec(bContext *C, wmOperator *op)
scene->active_keyingset = BLI_countlist(&scene->keyingsets);
}
else if (scene->active_keyingset < 0) {
- BKE_report(op->reports, RPT_ERROR, "Cannot add property to built in Keying Set");
+ BKE_report(op->reports, RPT_ERROR, "Cannot add property to built in keying set");
return OPERATOR_CANCELLED;
}
else
@@ -404,11 +404,11 @@ static int remove_keyingset_button_exec(bContext *C, wmOperator *op)
* - return error if it doesn't exist
*/
if (scene->active_keyingset == 0) {
- BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove property from");
+ BKE_report(op->reports, RPT_ERROR, "No active keying set to remove property from");
return OPERATOR_CANCELLED;
}
else if (scene->active_keyingset < 0) {
- BKE_report(op->reports, RPT_ERROR, "Cannot remove property from built in Keying Set");
+ BKE_report(op->reports, RPT_ERROR, "Cannot remove property from built in keying set");
return OPERATOR_CANCELLED;
}
else
@@ -947,7 +947,7 @@ int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSe
/* skip path if no ID pointer is specified */
if (ksp->id == NULL) {
BKE_reportf(reports, RPT_WARNING,
- "Skipping path in Keying Set, as it has no ID (KS = '%s', Path = '%s'[%d])",
+ "Skipping path in keying set, as it has no ID (KS = '%s', path = '%s'[%d])",
ks->name, ksp->rna_path, ksp->array_index);
continue;
}
diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c
index 707594ff590..8a75d07a678 100644
--- a/source/blender/editors/armature/editarmature.c
+++ b/source/blender/editors/armature/editarmature.c
@@ -654,17 +654,19 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op)
if (ob->type != OB_ARMATURE)
return OPERATOR_CANCELLED;
if (BKE_object_obdata_is_libdata(ob)) {
- BKE_report(op->reports, RPT_ERROR, "Cannot apply pose to lib-linked armature"); //error_libdata();
+ BKE_report(op->reports, RPT_ERROR, "Cannot apply pose to lib-linked armature"); /* error_libdata(); */
return OPERATOR_CANCELLED;
}
/* helpful warnings... */
/* TODO: add warnings to be careful about actions, applying deforms first, etc. */
if (ob->adt && ob->adt->action)
- BKE_report(op->reports, RPT_WARNING, "Actions on this armature will be destroyed by this new rest pose as the transforms stored are relative to the old rest pose");
+ BKE_report(op->reports, RPT_WARNING,
+ "Actions on this armature will be destroyed by this new rest pose as the "
+ "transforms stored are relative to the old rest pose");
/* Get editbones of active armature to alter */
- ED_armature_to_edit(ob);
+ ED_armature_to_edit(ob);
/* get pose of active object and move it out of posemode */
pose = ob->pose;
@@ -1591,7 +1593,8 @@ void ARMATURE_OT_select_linked(wmOperatorType *ot)
/* does bones and points */
/* note that BONE ROOT only gets drawn for root bones (or without IK) */
-static EditBone *get_nearest_editbonepoint(ViewContext *vc, const int mval[2], ListBase *edbo, int findunsel, int *selmask)
+static EditBone *get_nearest_editbonepoint(ViewContext *vc, const int mval[2],
+ ListBase *edbo, int findunsel, int *selmask)
{
EditBone *ebone;
rcti rect;
@@ -2096,7 +2099,7 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op)
}
sub_v3_v3v3(nor, ebone->tail, ebone->head);
- vec_roll_to_mat3(nor, ebone->roll, mat);
+ vec_roll_to_mat3(nor, ebone->roll, mat);
copy_v3_v3(vec, mat[2]);
}
else { /* Axis */
@@ -2556,7 +2559,8 @@ void updateDuplicateSubtarget(EditBone *dupBone, ListBase *editbones, Object *ob
}
-EditBone *duplicateEditBoneObjects(EditBone *curBone, const char *name, ListBase *editbones, Object *src_ob, Object *dst_ob)
+EditBone *duplicateEditBoneObjects(EditBone *curBone, const char *name, ListBase *editbones,
+ Object *src_ob, Object *dst_ob)
{
EditBone *eBone = MEM_mallocN(sizeof(EditBone), "addup_editbone");
@@ -2965,7 +2969,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
}
}
else {
- // FIXME.. figure out a method for multiple bones
+ /* FIXME.. figure out a method for multiple bones */
BKE_reportf(op->reports, RPT_ERROR, "Too many points selected: %d\n", count);
BLI_freelistN(&points);
return OPERATOR_CANCELLED;
@@ -3036,7 +3040,8 @@ static void bones_merge(Object *obedit, EditBone *start, EditBone *end, EditBone
newbone->parent = start->parent;
/* TODO, copy more things to the new bone */
- newbone->flag = start->flag & (BONE_HINGE | BONE_NO_DEFORM | BONE_NO_SCALE | BONE_NO_CYCLICOFFSET | BONE_NO_LOCAL_LOCATION | BONE_DONE);
+ newbone->flag = start->flag & (BONE_HINGE | BONE_NO_DEFORM | BONE_NO_SCALE |
+ BONE_NO_CYCLICOFFSET | BONE_NO_LOCAL_LOCATION | BONE_DONE);
/* step 2a: reparent any side chains which may be parented to any bone in the chain of bones to merge
* - potentially several tips for side chains leading to some tree exist...
@@ -3357,12 +3362,17 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
if (EBONE_VISIBLE(arm, ebone)) {
/* we extrude per definition the tip */
do_extrude = FALSE;
- if (ebone->flag & (BONE_TIPSEL | BONE_SELECTED))
+ if (ebone->flag & (BONE_TIPSEL | BONE_SELECTED)) {
do_extrude = TRUE;
+ }
else if (ebone->flag & BONE_ROOTSEL) {
/* but, a bone with parent deselected we do the root... */
- if (ebone->parent && (ebone->parent->flag & BONE_TIPSEL)) ;
- else do_extrude = 2;
+ if (ebone->parent && (ebone->parent->flag & BONE_TIPSEL)) {
+ /* pass */
+ }
+ else {
+ do_extrude = 2;
+ }
}
if (do_extrude) {
@@ -3813,7 +3823,7 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op)
/* there must be an active bone */
if (actbone == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Bone");
+ BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone");
return OPERATOR_CANCELLED;
}
else if (arm->flag & ARM_MIRROR_EDIT) {
@@ -4207,7 +4217,7 @@ static int armature_select_similar_exec(bContext *C, wmOperator *op)
/* Check for active bone */
if (ebone_act == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Bone");
+ BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone");
return OPERATOR_CANCELLED;
}
@@ -4399,7 +4409,7 @@ static int armature_align_bones_exec(bContext *C, wmOperator *op)
/* there must be an active bone */
if (actbone == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Bone");
+ BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone");
return OPERATOR_CANCELLED;
}
else if (arm->flag & ARM_MIRROR_EDIT) {
@@ -4476,7 +4486,8 @@ void ARMATURE_OT_align(wmOperatorType *ot)
/* ***************** Pose tools ********************* */
-// XXX bone_looper is only to be used when we want to access settings (i.e. editability/visibility/selected) that context doesn't offer
+/* XXX bone_looper is only to be used when we want to access settings
+ * (i.e. editability/visibility/selected) that context doesn't offer */
static int bone_looper(Object *ob, Bone *bone, void *data,
int (*bone_func)(Object *, Bone *, void *))
{
@@ -4506,7 +4517,8 @@ static int bone_looper(Object *ob, Bone *bone, void *data,
/* called from editview.c, for mode-less pose selection */
/* assumes scene obact and basact is still on old situation */
-int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, short extend, short deselect, short toggle)
+int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits,
+ short extend, short deselect, short toggle)
{
Object *ob = base->object;
Bone *nearBone;
@@ -4752,7 +4764,9 @@ static void add_vgroups__mapFunc(void *userData, int index, const float co[3],
copy_v3_v3(verts[index], co);
}
-static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], int numbones, Bone **bonelist, bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3], int *selected, float scale)
+static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], int numbones, Bone **bonelist,
+ bDeformGroup **dgrouplist, bDeformGroup **dgroupflip,
+ float (*root)[3], float (*tip)[3], int *selected, float scale)
{
/* Create vertex group weights from envelopes */
@@ -5138,7 +5152,7 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op,
/* sanity checks */
if (ELEM(NULL, clear_func, default_ksName)) {
- BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform func or Keying Set Name");
+ BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform function or keying set name");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c
index fad06f0d020..196d03020e7 100644
--- a/source/blender/editors/armature/editarmature_retarget.c
+++ b/source/blender/editors/armature/editarmature_retarget.c
@@ -1962,7 +1962,6 @@ static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc,
ReebArcIterator arc_iter;
BArcIterator *iter = (BArcIterator *)&arc_iter;
RigEdge *edge;
- EmbedBucket *bucket = NULL;
ReebNode *node_start, *node_end;
ReebArc *earc = iarc->link_mesh;
float angle_weight = 1.0; // GET FROM CONTEXT
@@ -1996,8 +1995,6 @@ static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc,
/* equal number of joints and potential position, just fill them in */
if (nb_joints == earc->bcount) {
- int i;
-
/* init with first values */
for (i = 0; i < nb_joints; i++) {
best_positions[i] = i + 1;
@@ -2011,7 +2008,6 @@ static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc,
MemoNode *result;
#endif
float **positions_cache = MEM_callocN(sizeof(float *) * (nb_positions + 2), "positions cache");
- int i;
positions_cache[0] = node_start->p;
positions_cache[nb_positions + 1] = node_end->p;
@@ -2053,7 +2049,7 @@ static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc,
{
float *no = NULL;
if (i < nb_joints) {
- bucket = IT_peek(iter, best_positions[i]);
+ EmbedBucket *bucket = IT_peek(iter, best_positions[i]);
vec1 = bucket->p;
no = bucket->no;
}
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
index 5ba4a232250..68d8a8d721e 100644
--- a/source/blender/editors/armature/editarmature_sketch.c
+++ b/source/blender/editors/armature/editarmature_sketch.c
@@ -646,7 +646,7 @@ static SK_Point *sk_snapPointStroke(bContext *C, SK_Stroke *stk, int mval[2], in
short pval[2];
int pdist;
- if (ED_view3d_project_short_global(ar, stk->points[i].p, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_short_global(ar, stk->points[i].p, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
@@ -682,7 +682,7 @@ static SK_Point *sk_snapPointArmature(bContext *C, Object *ob, ListBase *ebones,
{
copy_v3_v3(vec, bone->head);
mul_m4_v3(ob->obmat, vec);
- if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
@@ -699,7 +699,7 @@ static SK_Point *sk_snapPointArmature(bContext *C, Object *ob, ListBase *ebones,
copy_v3_v3(vec, bone->tail);
mul_m4_v3(ob->obmat, vec);
- if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
@@ -939,7 +939,7 @@ static void sk_projectDrawPoint(bContext *C, float vec[3], SK_Stroke *stk, SK_Dr
initgrabz(ar->regiondata, fp[0], fp[1], fp[2]);
/* method taken from editview.c - mouse_cursor() */
- if (ED_view3d_project_short_global(ar, fp, cval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_short_global(ar, fp, cval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
VECSUB2D(mval_f, cval, dd->mval);
ED_view3d_win_to_delta(ar, mval_f, dvec);
sub_v3_v3v3(vec, fp, dvec);
@@ -1793,8 +1793,8 @@ int sk_detectMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *UNUSED(sketc
short start_val[2], end_val[2];
short dist;
- if ((ED_view3d_project_short_global(ar, gest->stk->points[0].p, start_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) &&
- (ED_view3d_project_short_global(ar, sk_lastStrokePoint(gest->stk)->p, end_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS))
+ if ((ED_view3d_project_short_global(ar, gest->stk->points[0].p, start_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) &&
+ (ED_view3d_project_short_global(ar, sk_lastStrokePoint(gest->stk)->p, end_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK))
{
dist = MAX2(ABS(start_val[0] - end_val[0]), ABS(start_val[1] - end_val[1]));
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index 522622ec5c4..82fef00b1e6 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -1221,7 +1221,7 @@ static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *r
else
normal_quad_v3(no, face[0], face[1], face[2], face[3]);
- dist = len_v3v3(ray->origin, co)/len_v3(isec->vec);
+ dist = len_v3v3(ray->origin, co) / len_v3(isec->vec);
if (dist < hit->dist) {
hit->index = index;
hit->dist = dist;
@@ -1254,8 +1254,10 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float
hit.index = -1;
hit.dist = FLT_MAX;
- if (BLI_bvhtree_ray_cast(mdb->bvhtree, isect_mdef.start, isect_mdef.vec, 0.0, &hit, harmonic_ray_callback, data) != -1) {
- len= isect_mdef.labda;
+ if (BLI_bvhtree_ray_cast(mdb->bvhtree, isect_mdef.start, isect_mdef.vec,
+ 0.0, &hit, harmonic_ray_callback, data) != -1)
+ {
+ len = isect_mdef.labda;
isect_mdef.face = mface = mface1 + hit.index;
/* create MDefBoundIsect */
diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c
index cdcb3ab4683..31398948b82 100644
--- a/source/blender/editors/armature/poseSlide.c
+++ b/source/blender/editors/armature/poseSlide.c
@@ -631,6 +631,7 @@ static int pose_slide_modal(bContext *C, wmOperator *op, wmEvent *evt)
switch (evt->type) {
case LEFTMOUSE: /* confirm */
+ case RETKEY:
{
/* return to normal cursor and header status */
ED_area_headerprint(pso->sa, NULL);
diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c
index eea7424c59a..a05a98c58ca 100644
--- a/source/blender/editors/armature/poselib.c
+++ b/source/blender/editors/armature/poselib.c
@@ -298,7 +298,7 @@ static int poselib_sanitize_exec(bContext *C, wmOperator *op)
/* validate action */
if (act == NULL) {
- BKE_report(op->reports, RPT_WARNING, "No Action to validate");
+ BKE_report(op->reports, RPT_WARNING, "No action to validate");
return OPERATOR_CANCELLED;
}
@@ -547,7 +547,7 @@ static int poselib_remove_exec(bContext *C, wmOperator *op)
/* check if valid poselib */
if (act == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Object doesn't have PoseLib data");
+ BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data");
return OPERATOR_CANCELLED;
}
@@ -562,7 +562,7 @@ static int poselib_remove_exec(bContext *C, wmOperator *op)
/* get index (and pointer) of pose to remove */
marker = BLI_findlink(&act->markers, marker_index);
if (marker == NULL) {
- BKE_reportf(op->reports, RPT_ERROR, "Invalid Pose specified %d", marker_index);
+ BKE_reportf(op->reports, RPT_ERROR, "Invalid pose specified %d", marker_index);
return OPERATOR_CANCELLED;
}
@@ -628,14 +628,14 @@ static int poselib_rename_invoke(bContext *C, wmOperator *op, wmEvent *evt)
/* check if valid poselib */
if (act == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Object doesn't have PoseLib data");
+ BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data");
return OPERATOR_CANCELLED;
}
/* get index (and pointer) of pose to remove */
marker = BLI_findlink(&act->markers, act->active_marker - 1);
if (marker == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Invalid index for Pose");
+ BKE_report(op->reports, RPT_ERROR, "Invalid index for pose");
return OPERATOR_CANCELLED;
}
else {
@@ -657,14 +657,14 @@ static int poselib_rename_exec(bContext *C, wmOperator *op)
/* check if valid poselib */
if (act == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Object doesn't have PoseLib data");
+ BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data");
return OPERATOR_CANCELLED;
}
/* get index (and pointer) of pose to remove */
marker = BLI_findlink(&act->markers, RNA_int_get(op->ptr, "pose"));
if (marker == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Invalid index for Pose");
+ BKE_report(op->reports, RPT_ERROR, "Invalid index for pose");
return OPERATOR_CANCELLED;
}
@@ -1424,12 +1424,12 @@ static void poselib_preview_init_data(bContext *C, wmOperator *op)
/* check if valid poselib */
if (ELEM3(NULL, pld->ob, pld->pose, pld->arm)) {
- BKE_report(op->reports, RPT_ERROR, "PoseLib is only for Armatures in PoseMode");
+ BKE_report(op->reports, RPT_ERROR, "Pose lib is only for armatures in pose mode");
pld->state = PL_PREVIEW_ERROR;
return;
}
if (pld->act == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Object doesn't have a valid PoseLib");
+ BKE_report(op->reports, RPT_ERROR, "Object does not have a valid pose lib");
pld->state = PL_PREVIEW_ERROR;
return;
}
@@ -1438,10 +1438,10 @@ static void poselib_preview_init_data(bContext *C, wmOperator *op)
/* just use first one then... */
pld->marker = pld->act->markers.first;
if (pose_index > -2)
- BKE_report(op->reports, RPT_WARNING, "PoseLib had no active pose");
+ BKE_report(op->reports, RPT_WARNING, "Pose lib had no active pose");
}
else {
- BKE_report(op->reports, RPT_ERROR, "PoseLib has no poses to preview/apply");
+ BKE_report(op->reports, RPT_ERROR, "Pose lib has no poses to preview/apply");
pld->state = PL_PREVIEW_ERROR;
return;
}
diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c
index 189b2e977c2..99de90bc9fa 100644
--- a/source/blender/editors/armature/poseobject.c
+++ b/source/blender/editors/armature/poseobject.c
@@ -105,7 +105,7 @@ void ED_armature_enter_posemode(bContext *C, Base *base)
Object *ob = base->object;
if (ob->id.lib) {
- BKE_report(reports, RPT_WARNING, "Can't pose libdata");
+ BKE_report(reports, RPT_WARNING, "Cannot pose libdata");
return;
}
@@ -1236,7 +1236,7 @@ static int pose_copy_exec(bContext *C, wmOperator *op)
/* sanity checking */
if (ELEM(NULL, ob, ob->pose)) {
- BKE_report(op->reports, RPT_ERROR, "No Pose to Copy");
+ BKE_report(op->reports, RPT_ERROR, "No pose to copy");
return OPERATOR_CANCELLED;
}
@@ -1399,7 +1399,7 @@ void POSE_OT_group_remove(wmOperatorType *ot)
/* identifiers */
ot->name = "Remove Bone Group";
ot->idname = "POSE_OT_group_remove";
- ot->description = "Removes the active bone group";
+ ot->description = "Remove the active bone group";
/* api callbacks */
ot->exec = pose_group_remove_exec;
@@ -1511,7 +1511,7 @@ void POSE_OT_group_assign(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- RNA_def_int(ot->srna, "type", 0, 0, 10, "Bone Group Index", "", 0, INT_MAX);
+ RNA_def_int(ot->srna, "type", 0, 0, INT_MAX, "Bone Group Index", "", 0, 10);
}
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index afd6bc4c4b5..874b31dd1ca 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -1579,8 +1579,9 @@ static int deleteflagNurb(bContext *C, wmOperator *UNUSED(op), int flag)
BPoint *bp, *bpn, *newbp;
int a, b, newu, newv, sel;
- if (obedit->type == OB_SURF) ;
- else return OPERATOR_CANCELLED;
+ if (obedit->type != OB_SURF) {
+ return OPERATOR_CANCELLED;
+ }
cu->lastsel = NULL;
@@ -1593,8 +1594,12 @@ static int deleteflagNurb(bContext *C, wmOperator *UNUSED(op), int flag)
a = nu->pntsu * nu->pntsv;
while (a) {
a--;
- if (bp->f1 & flag) ;
- else break;
+ if (bp->f1 & flag) {
+ /* pass */
+ }
+ else {
+ break;
+ }
bp++;
}
if (a == 0) {
@@ -1715,8 +1720,12 @@ static short extrudeflagNurb(EditNurb *editnurb, int flag)
bp = nu->bp;
a = nu->pntsu;
while (a) {
- if (bp->f1 & flag) ;
- else break;
+ if (bp->f1 & flag) {
+ /* pass */
+ }
+ else {
+ break;
+ }
bp++;
a--;
}
@@ -3217,12 +3226,12 @@ void CURVE_OT_subdivide(wmOperatorType *ot)
/******************** find nearest ************************/
-static void findnearestNurbvert__doClosest(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y)
+static void findnearestNurbvert__doClosest(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2])
{
- struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; int dist, hpoint, select, mval[2]; } *data = userData;
+ struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; float dist; int hpoint, select; float mval_fl[2]; } *data = userData;
short flag;
- short temp;
+ float dist_test;
if (bp) {
flag = bp->f1;
@@ -3239,12 +3248,12 @@ static void findnearestNurbvert__doClosest(void *userData, Nurb *nu, BPoint *bp,
}
}
- temp = abs(data->mval[0] - x) + abs(data->mval[1] - y);
- if ((flag & 1) == data->select) temp += 5;
- if (bezt && beztindex == 1) temp += 3; /* middle points get a small disadvantage */
+ dist_test = len_manhattan_v2v2(data->mval_fl, screen_co);
+ if ((flag & SELECT) == data->select) dist_test += 5.0f;
+ if (bezt && beztindex == 1) dist_test += 3.0f; /* middle points get a small disadvantage */
- if (temp < data->dist) {
- data->dist = temp;
+ if (dist_test < data->dist) {
+ data->dist = dist_test;
data->bp = bp;
data->bezt = bezt;
@@ -3258,16 +3267,16 @@ static short findnearestNurbvert(ViewContext *vc, short sel, const int mval[2],
/* (sel == 1): selected gets a disadvantage */
/* in nurb and bezt or bp the nearest is written */
/* return 0 1 2: handlepunt */
- struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; int dist, hpoint, select, mval[2]; } data = {NULL};
+ struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; float dist; int hpoint, select; float mval_fl[2]; } data = {NULL};
data.dist = 100;
data.hpoint = 0;
data.select = sel;
- data.mval[0] = mval[0];
- data.mval[1] = mval[1];
+ data.mval_fl[0] = mval[0];
+ data.mval_fl[1] = mval[1];
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- nurbs_foreachScreenVert(vc, findnearestNurbvert__doClosest, &data);
+ nurbs_foreachScreenVert(vc, findnearestNurbvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
*nurb = data.nurb;
*bezt = data.bezt;
@@ -3762,20 +3771,28 @@ static void merge_2_nurb(wmOperator *op, ListBase *editnurb, Nurb *nu1, Nurb *nu
/* first nurbs: u = resolu-1 selected */
- if (is_u_selected(nu1, nu1->pntsu - 1) ) ;
+ if (is_u_selected(nu1, nu1->pntsu - 1) ) {
+ /* pass */
+ }
else {
/* For 2D curves blender uses (orderv = 0). It doesn't make any sense mathematically. */
/* but after rotating (orderu = 0) will be confusing. */
if (nu1->orderv == 0) nu1->orderv = 1;
rotate_direction_nurb(nu1);
- if (is_u_selected(nu1, nu1->pntsu - 1)) ;
+ if (is_u_selected(nu1, nu1->pntsu - 1)) {
+ /* pass */
+ }
else {
rotate_direction_nurb(nu1);
- if (is_u_selected(nu1, nu1->pntsu - 1)) ;
+ if (is_u_selected(nu1, nu1->pntsu - 1)) {
+ /* pass */
+ }
else {
rotate_direction_nurb(nu1);
- if (is_u_selected(nu1, nu1->pntsu - 1)) ;
+ if (is_u_selected(nu1, nu1->pntsu - 1)) {
+ /* pass */
+ }
else {
/* rotate again, now its OK! */
if (nu1->pntsv != 1) rotate_direction_nurb(nu1);
@@ -3786,17 +3803,25 @@ static void merge_2_nurb(wmOperator *op, ListBase *editnurb, Nurb *nu1, Nurb *nu
}
/* 2nd nurbs: u = 0 selected */
- if (is_u_selected(nu2, 0) ) ;
+ if (is_u_selected(nu2, 0) ) {
+ /* pass */
+ }
else {
if (nu2->orderv == 0) nu2->orderv = 1;
rotate_direction_nurb(nu2);
- if (is_u_selected(nu2, 0)) ;
+ if (is_u_selected(nu2, 0)) {
+ /* pass */
+ }
else {
rotate_direction_nurb(nu2);
- if (is_u_selected(nu2, 0)) ;
+ if (is_u_selected(nu2, 0)) {
+ /* pass */
+ }
else {
rotate_direction_nurb(nu2);
- if (is_u_selected(nu2, 0)) ;
+ if (is_u_selected(nu2, 0)) {
+ /* pass */
+ }
else {
/* rotate again, now its OK! */
if (nu1->pntsu == 1) rotate_direction_nurb(nu1);
@@ -3892,15 +3917,27 @@ static int merge_nurb(bContext *C, wmOperator *op)
/* resolution match, to avoid uv rotations */
if (nus1->nu->pntsv == 1) {
- if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsu == nus2->nu->pntsv) ;
- else ok = 0;
+ if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsu == nus2->nu->pntsv) {
+ /* pass */
+ }
+ else {
+ ok = 0;
+ }
}
else if (nus2->nu->pntsv == 1) {
- if (nus2->nu->pntsu == nus1->nu->pntsu || nus2->nu->pntsu == nus1->nu->pntsv) ;
- else ok = 0;
+ if (nus2->nu->pntsu == nus1->nu->pntsu || nus2->nu->pntsu == nus1->nu->pntsv) {
+ /* pass */
+ }
+ else {
+ ok = 0;
+ }
+ }
+ else if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsv == nus2->nu->pntsv) {
+ /* pass */
+ }
+ else if (nus1->nu->pntsu == nus2->nu->pntsv || nus1->nu->pntsv == nus2->nu->pntsu) {
+ /* pass */
}
- else if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsv == nus2->nu->pntsv) ;
- else if (nus1->nu->pntsu == nus2->nu->pntsv || nus1->nu->pntsv == nus2->nu->pntsu) ;
else {
ok = 0;
}
@@ -3949,8 +3986,12 @@ static int make_segment_exec(bContext *C, wmOperator *op)
if (isNurbsel_count(cu, nu) == 1) {
/* only 1 selected, not first or last, a little complex, but intuitive */
if (nu->pntsv == 1) {
- if ( (nu->bp->f1 & SELECT) || (nu->bp[nu->pntsu - 1].f1 & SELECT)) ;
- else break;
+ if ( (nu->bp->f1 & SELECT) || (nu->bp[nu->pntsu - 1].f1 & SELECT)) {
+ /* pass */
+ }
+ else {
+ break;
+ }
}
}
}
@@ -4380,7 +4421,7 @@ void CURVE_OT_spin(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_float_vector_xyz(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX);
- RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX);
+ RNA_def_float_vector(ot->srna, "axis", 3, NULL, -FLT_MAX, FLT_MAX, "Axis", "Axis in global view space", -1.0f, 1.0f);
}
/***************** add vertex operator **********************/
@@ -5611,7 +5652,7 @@ void CURVE_OT_select_nth(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_int(ot->srna, "nth", 2, 2, 100, "Nth Selection", "", 1, INT_MAX);
+ RNA_def_int(ot->srna, "nth", 2, 2, INT_MAX, "Nth Selection", "", 2, 100);
}
/********************** add duplicate operator *********************/
@@ -5684,8 +5725,12 @@ static int delete_exec(bContext *C, wmOperator *op)
a = nu->pntsu;
if (a) {
while (a) {
- if (BEZSELECTED_HIDDENHANDLES(cu, bezt) ) ;
- else break;
+ if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
+ /* pass */
+ }
+ else {
+ break;
+ }
a--;
bezt++;
}
@@ -5704,8 +5749,12 @@ static int delete_exec(bContext *C, wmOperator *op)
a = nu->pntsu * nu->pntsv;
if (a) {
while (a) {
- if (bp->f1 & SELECT) ;
- else break;
+ if (bp->f1 & SELECT) {
+ /* pass */
+ }
+ else {
+ break;
+ }
a--;
bp++;
}
@@ -6437,12 +6486,7 @@ Nurb *add_nurbs_primitive(bContext *C, Object *obedit, float mat[4][4], int type
vec[0] = vec[1] = 0.0;
vec[2] = -grid;
- if (newob && (U.flag & USER_ADD_VIEWALIGNED) == 0) {
- /* pass */
- }
- else {
- mul_mat3_m4_v3(mat, vec);
- }
+ mul_mat3_m4_v3(mat, vec);
translateflagNurb(editnurb, 1, vec);
extrudeflagNurb(cu->editnurb, 1);
@@ -6603,7 +6647,7 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf)
if (newob && enter_editmode)
ED_undo_push(C, "Enter Editmode");
- ED_object_new_primitive_matrix(C, obedit, loc, rot, mat);
+ ED_object_new_primitive_matrix(C, obedit, loc, rot, mat, TRUE);
nu = add_nurbs_primitive(C, obedit, mat, type, newob);
editnurb = object_editcurve_get(obedit);
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index b11d640256c..b379ce6e5cf 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -441,8 +441,9 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, float
obedit = BKE_object_add(scene, OB_FONT);
base = scene->basact;
-
- ED_object_base_init_transform(C, base, NULL, rot); /* seems to assume view align ? TODO - look into this, could be an operator option */
+ /* seems to assume view align ? TODO - look into this, could be an operator option */
+ ED_object_base_init_transform(C, base, NULL, rot);
+
BKE_object_where_is_calc(scene, obedit);
obedit->loc[0] += offset[0];
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index 5ff4ccbd126..3b26c46a410 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -149,7 +149,8 @@ static void gp_draw_stroke_buffer(tGPspoint *points, int totpoints, short thickn
/* ----- Existing Strokes Drawing (3D and Point) ------ */
/* draw a given stroke - just a single dot (only one point) */
-static void gp_draw_stroke_point(bGPDspoint *points, short thickness, short dflag, short sflag, int offsx, int offsy, int winx, int winy)
+static void gp_draw_stroke_point(bGPDspoint *points, short thickness, short dflag, short sflag,
+ int offsx, int offsy, int winx, int winy)
{
/* draw point */
if (sflag & GP_STROKE_3DSPACE) {
@@ -508,7 +509,8 @@ static void gp_draw_strokes(bGPDframe *gpf, int offsx, int offsy, int winx, int
glDepthMask(0);
glEnable(GL_DEPTH_TEST);
- /* first arg is normally rv3d->dist, but this isn't available here and seems to work quite well without */
+ /* first arg is normally rv3d->dist, but this isn't
+ * available here and seems to work quite well without */
bglPolygonOffset(1.0f, 1.0f);
#if 0
glEnable(GL_POLYGON_OFFSET_LINE);
@@ -579,7 +581,8 @@ static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy,
/* draw 'onionskins' (frame left + right) */
if (gpl->flag & GP_LAYER_ONIONSKIN) {
- /* drawing method - only immediately surrounding (gstep = 0), or within a frame range on either side (gstep > 0)*/
+ /* drawing method - only immediately surrounding (gstep = 0),
+ * or within a frame range on either side (gstep > 0)*/
if (gpl->gstep) {
bGPDframe *gf;
float fac;
@@ -640,7 +643,8 @@ static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy,
if (ED_gpencil_session_active() && (gpl->flag & GP_LAYER_ACTIVE) &&
(gpf->flag & GP_FRAME_PAINT))
{
- /* Buffer stroke needs to be drawn with a different linestyle to help differentiate them from normal strokes. */
+ /* Buffer stroke needs to be drawn with a different linestyle
+ * to help differentiate them from normal strokes. */
gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag);
}
}
@@ -724,8 +728,8 @@ void draw_gpencil_2dimage(const bContext *C)
}
/* draw grease-pencil sketches to specified 2d-view assuming that matrices are already set correctly
- * Note: this gets called twice - first time with onlyv2d=1 to draw 'canvas' strokes, second time with onlyv2d=0 for screen-aligned strokes
- */
+ * Note: this gets called twice - first time with onlyv2d=1 to draw 'canvas' strokes,
+ * second time with onlyv2d=0 for screen-aligned strokes */
void draw_gpencil_view2d(const bContext *C, short onlyv2d)
{
ScrArea *sa = CTX_wm_area(C);
@@ -750,9 +754,8 @@ void draw_gpencil_view2d(const bContext *C, short onlyv2d)
}
/* draw grease-pencil sketches to specified 3d-view assuming that matrices are already set correctly
- * Note: this gets called twice - first time with only3d=1 to draw 3d-strokes, second time with only3d=0 for screen-aligned strokes
- */
-
+ * Note: this gets called twice - first time with only3d=1 to draw 3d-strokes,
+ * second time with only3d=0 for screen-aligned strokes */
void draw_gpencil_view3d(Scene *scene, View3D *v3d, ARegion *ar, short only3d)
{
bGPdata *gpd;
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index de7c2c41a6d..e5afbdba50b 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -279,7 +279,7 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3]
/* method taken from editview.c - mouse_cursor() */
/* TODO, use ED_view3d_project_float_global */
- if (ED_view3d_project_int_global(p->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_int_global(p->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
VECSUB2D(mval_f, mval_prj, mval);
ED_view3d_win_to_delta(p->ar, mval_f, dvec);
sub_v3_v3v3(out, rvec, dvec);
@@ -395,8 +395,10 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure)
pts = &gps->points[gps->totpoints - 1];
- /* special case for poly lines: normally, depth is needed only when creating new stroke from buffer,
- * but poly lines are converting to stroke instantly, so initialize depth buffer before converting coordinates
+ /* special case for poly lines: normally,
+ * depth is needed only when creating new stroke from buffer,
+ * but poly lines are converting to stroke instantly,
+ * so initialize depth buffer before converting coordinates
*/
if (gpencil_project_check(p)) {
View3D *v3d = p->sa->spacedata.first;
@@ -785,13 +787,49 @@ static short gp_stroke_eraser_strokeinside(const int mval[], const int UNUSED(mv
int rad, int x0, int y0, int x1, int y1)
{
/* simple within-radius check for now */
- if (edge_inside_circle(mval[0], mval[1], rad, x0, y0, x1, y1))
- return 1;
+ const float mval_fl[2] = {mval[0], mval[1]};
+ const float screen_co_a[2] = {x0, y0};
+ const float screen_co_b[2] = {x1, y1};
+
+ if (edge_inside_circle(mval_fl, rad, screen_co_a, screen_co_b)) {
+ return TRUE;
+ }
/* not inside */
- return 0;
+ return FALSE;
}
+static void gp_point_to_xy(ARegion *ar, View2D *v2d, rctf *subrect, bGPDstroke *gps, bGPDspoint *pt,
+ int *r_x, int *r_y)
+{
+ int xyval[2];
+
+ if (gps->flag & GP_STROKE_3DSPACE) {
+ if (ED_view3d_project_int_global(ar, &pt->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
+ *r_x = xyval[0];
+ *r_y = xyval[1];
+ }
+ else {
+ *r_x = V2D_IS_CLIPPED;
+ *r_y = V2D_IS_CLIPPED;
+ }
+ }
+ else if (gps->flag & GP_STROKE_2DSPACE) {
+ UI_view2d_view_to_region(v2d, pt->x, pt->y, r_x, r_y);
+ }
+ else {
+ if (subrect == NULL) { /* normal 3D view */
+ *r_x = (int)(pt->x / 100 * ar->winx);
+ *r_y = (int)(pt->y / 100 * ar->winy);
+ }
+ else { /* camera view, use subrect */
+ *r_x = (int)((pt->x / 100) * BLI_rctf_size_x(subrect)) + subrect->xmin;
+ *r_y = (int)((pt->y / 100) * BLI_rctf_size_y(subrect)) + subrect->ymin;
+ }
+ }
+}
+
+
/* eraser tool - evaluation per stroke */
// TODO: this could really do with some optimization (KD-Tree/BVH?)
static void gp_stroke_eraser_dostroke(tGPsdata *p,
@@ -800,7 +838,6 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
{
bGPDspoint *pt1, *pt2;
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
- int xyval[2];
int i;
if (gps->totpoints == 0) {
@@ -810,33 +847,11 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
BLI_freelinkN(&gpf->strokes, gps);
}
else if (gps->totpoints == 1) {
- /* get coordinates */
- if (gps->flag & GP_STROKE_3DSPACE) {
- if (ED_view3d_project_int_global(p->ar, &gps->points->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) {
- x0 = xyval[0];
- y0 = xyval[1];
- }
- else {
- x0 = V2D_IS_CLIPPED;
- y0 = V2D_IS_CLIPPED;
- }
- }
- else if (gps->flag & GP_STROKE_2DSPACE) {
- UI_view2d_view_to_region(p->v2d, gps->points->x, gps->points->y, &x0, &y0);
- }
- else {
- if (p->subrect == NULL) { /* normal 3D view */
- x0 = (int)(gps->points->x / 100 * p->ar->winx);
- y0 = (int)(gps->points->y / 100 * p->ar->winy);
- }
- else { /* camera view, use subrect */
- x0 = (int)((gps->points->x / 100) * BLI_rctf_size_x(p->subrect)) + p->subrect->xmin;
- y0 = (int)((gps->points->y / 100) * BLI_rctf_size_y(p->subrect)) + p->subrect->ymin;
- }
- }
+ gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, gps->points, &x0, &y0);
/* do boundbox check first */
- if (BLI_rcti_isect_pt(rect, x0, y0)) {
+
+ if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) {
/* only check if point is inside */
if (((x0 - mval[0]) * (x0 - mval[0]) + (y0 - mval[1]) * (y0 - mval[1])) <= rad * rad) {
/* free stroke */
@@ -853,48 +868,13 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
/* get points to work with */
pt1 = gps->points + i;
pt2 = gps->points + i + 1;
-
- /* get coordinates */
- if (gps->flag & GP_STROKE_3DSPACE) {
- if (ED_view3d_project_int_global(p->ar, &pt1->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) {
- x0 = xyval[0];
- y0 = xyval[1];
- }
- else {
- x0 = V2D_IS_CLIPPED;
- y0 = V2D_IS_CLIPPED;
- }
- if (ED_view3d_project_int_global(p->ar, &pt2->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) {
- x1 = xyval[0];
- y1 = xyval[1];
- }
- else {
- x1 = V2D_IS_CLIPPED;
- y1 = V2D_IS_CLIPPED;
- }
- }
- else if (gps->flag & GP_STROKE_2DSPACE) {
- UI_view2d_view_to_region(p->v2d, pt1->x, pt1->y, &x0, &y0);
-
- UI_view2d_view_to_region(p->v2d, pt2->x, pt2->y, &x1, &y1);
- }
- else {
- if (p->subrect == NULL) { /* normal 3D view */
- x0 = (int)(pt1->x / 100 * p->ar->winx);
- y0 = (int)(pt1->y / 100 * p->ar->winy);
- x1 = (int)(pt2->x / 100 * p->ar->winx);
- y1 = (int)(pt2->y / 100 * p->ar->winy);
- }
- else { /* camera view, use subrect */
- x0 = (int)((pt1->x / 100) * BLI_rctf_size_x(p->subrect)) + p->subrect->xmin;
- y0 = (int)((pt1->y / 100) * BLI_rctf_size_y(p->subrect)) + p->subrect->ymin;
- x1 = (int)((pt2->x / 100) * BLI_rctf_size_x(p->subrect)) + p->subrect->xmin;
- y1 = (int)((pt2->y / 100) * BLI_rctf_size_y(p->subrect)) + p->subrect->ymin;
- }
- }
-
+
+ gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, pt1, &x0, &y0);
+ gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, pt2, &x1, &y1);
+
/* check that point segment of the boundbox of the eraser stroke */
- if (BLI_rcti_isect_pt(rect, x0, y0) || BLI_rcti_isect_pt(rect, x1, y1)) {
+ if (((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) ||
+ ((!ELEM(V2D_IS_CLIPPED, x1, y1)) && BLI_rcti_isect_pt(rect, x1, y1))) {
/* check if point segment of stroke had anything to do with
* eraser region (either within stroke painted, or on its lines)
* - this assumes that linewidth is irrelevant
@@ -1423,13 +1403,17 @@ static void gpencil_draw_status_indicators(tGPsdata *p)
/* print status info */
switch (p->paintmode) {
case GP_PAINTMODE_ERASER:
- ED_area_headerprint(p->sa, "Grease Pencil Erase Session: Hold and drag LMB or RMB to erase | ESC/Enter to end");
+ ED_area_headerprint(p->sa,
+ "Grease Pencil Erase Session: Hold and drag LMB or RMB to erase |"
+ " ESC/Enter to end");
break;
case GP_PAINTMODE_DRAW_STRAIGHT:
- ED_area_headerprint(p->sa, "Grease Pencil Line Session: Hold and drag LMB to draw | ESC/Enter to end");
+ ED_area_headerprint(p->sa, "Grease Pencil Line Session: Hold and drag LMB to draw | "
+ "ESC/Enter to end");
break;
case GP_PAINTMODE_DRAW:
- ED_area_headerprint(p->sa, "Grease Pencil Freehand Session: Hold and drag LMB to draw | ESC/Enter to end");
+ ED_area_headerprint(p->sa, "Grease Pencil Freehand Session: Hold and drag LMB to draw | "
+ "ESC/Enter to end");
break;
default: /* unhandled future cases */
@@ -1705,7 +1689,8 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
//printf("\t\tGP - start stroke\n");
/* we may need to set up paint env again if we're resuming */
- /* XXX: watch it with the paintmode! in future, it'd be nice to allow changing paint-mode when in sketching-sessions */
+ /* XXX: watch it with the paintmode! in future,
+ * it'd be nice to allow changing paint-mode when in sketching-sessions */
/* XXX: with tablet events, we may event want to check for eraser here, for nicer tablet support */
if (gp_session_initdata(C, p))
@@ -1889,7 +1874,10 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event)
case OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH:
/* event doesn't need to be handled */
- //printf("unhandled event -> %d (mmb? = %d | mmv? = %d)\n", event->type, event->type == MIDDLEMOUSE, event->type==MOUSEMOVE);
+#if 0
+ printf("unhandled event -> %d (mmb? = %d | mmv? = %d)\n",
+ event->type, event->type == MIDDLEMOUSE, event->type==MOUSEMOVE);
+#endif
break;
}
@@ -1900,10 +1888,10 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event)
/* ------------------------------- */
static EnumPropertyItem prop_gpencil_drawmodes[] = {
- {GP_PAINTMODE_DRAW, "DRAW", 0, "Draw Freehand", ""},
- {GP_PAINTMODE_DRAW_STRAIGHT, "DRAW_STRAIGHT", 0, "Draw Straight Lines", ""},
- {GP_PAINTMODE_DRAW_POLY, "DRAW_POLY", 0, "Draw Poly Line", ""},
- {GP_PAINTMODE_ERASER, "ERASER", 0, "Eraser", ""},
+ {GP_PAINTMODE_DRAW, "DRAW", 0, "Draw Freehand", "Draw freehand stroke(s)"},
+ {GP_PAINTMODE_DRAW_STRAIGHT, "DRAW_STRAIGHT", 0, "Draw Straight Lines", "Draw straight line segment(s)"},
+ {GP_PAINTMODE_DRAW_POLY, "DRAW_POLY", 0, "Draw Poly Line", "Click to place endpoints of straight line segments (connected)"},
+ {GP_PAINTMODE_ERASER, "ERASER", 0, "Eraser", "Erase Grease Pencil strokes"},
{0, NULL, 0, NULL, NULL}
};
@@ -1925,7 +1913,7 @@ void GPENCIL_OT_draw(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
/* settings for drawing */
- RNA_def_enum(ot->srna, "mode", prop_gpencil_drawmodes, 0, "Mode", "Way to interpret mouse movements");
+ ot->prop = RNA_def_enum(ot->srna, "mode", prop_gpencil_drawmodes, 0, "Mode", "Way to interpret mouse movements");
RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", "");
}
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index fbddd26c959..fba42a33f88 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -233,29 +233,29 @@ typedef enum eAnimFilter_Flags {
/* Dopesheet only */
/* 'Scene' channels */
-#define SEL_SCEC(sce) ((sce->flag & SCE_DS_SELECTED))
-#define EXPANDED_SCEC(sce) ((sce->flag & SCE_DS_COLLAPSED) == 0)
+#define SEL_SCEC(sce) (CHECK_TYPE_INLINE(sce, Scene), ((sce->flag & SCE_DS_SELECTED)))
+#define EXPANDED_SCEC(sce) (CHECK_TYPE_INLINE(sce, Scene), ((sce->flag & SCE_DS_COLLAPSED) == 0))
/* 'Sub-Scene' channels (flags stored in Data block) */
-#define FILTER_WOR_SCED(wo) ((wo->flag & WO_DS_EXPAND))
+#define FILTER_WOR_SCED(wo) (CHECK_TYPE_INLINE(wo, World), (wo->flag & WO_DS_EXPAND))
#define FILTER_LS_SCED(linestyle) ((linestyle->flag & LS_DS_EXPAND))
/* 'Object' channels */
-#define SEL_OBJC(base) ((base->flag & SELECT))
-#define EXPANDED_OBJC(ob) ((ob->nlaflag & OB_ADS_COLLAPSED) == 0)
+#define SEL_OBJC(base) (CHECK_TYPE_INLINE(base, Base), ((base->flag & SELECT)))
+#define EXPANDED_OBJC(ob) (CHECK_TYPE_INLINE(ob, Object), ((ob->nlaflag & OB_ADS_COLLAPSED) == 0))
/* 'Sub-object' channels (flags stored in Data block) */
-#define FILTER_SKE_OBJD(key) ((key->flag & KEY_DS_EXPAND))
-#define FILTER_MAT_OBJD(ma) ((ma->flag & MA_DS_EXPAND))
-#define FILTER_LAM_OBJD(la) ((la->flag & LA_DS_EXPAND))
-#define FILTER_CAM_OBJD(ca) ((ca->flag & CAM_DS_EXPAND))
-#define FILTER_CUR_OBJD(cu) ((cu->flag & CU_DS_EXPAND))
-#define FILTER_PART_OBJD(part) ((part->flag & PART_DS_EXPAND))
-#define FILTER_MBALL_OBJD(mb) ((mb->flag2 & MB_DS_EXPAND))
-#define FILTER_ARM_OBJD(arm) ((arm->flag & ARM_DS_EXPAND))
-#define FILTER_MESH_OBJD(me) ((me->flag & ME_DS_EXPAND))
-#define FILTER_LATTICE_OBJD(lt) ((lt->flag & LT_DS_EXPAND))
-#define FILTER_SPK_OBJD(spk) ((spk->flag & SPK_DS_EXPAND))
+#define FILTER_SKE_OBJD(key) (CHECK_TYPE_INLINE(key, Key), ((key->flag & KEY_DS_EXPAND)))
+#define FILTER_MAT_OBJD(ma) (CHECK_TYPE_INLINE(ma, Material), ((ma->flag & MA_DS_EXPAND)))
+#define FILTER_LAM_OBJD(la) (CHECK_TYPE_INLINE(la, Lamp), ((la->flag & LA_DS_EXPAND)))
+#define FILTER_CAM_OBJD(ca) (CHECK_TYPE_INLINE(ca, Camera), ((ca->flag & CAM_DS_EXPAND)))
+#define FILTER_CUR_OBJD(cu) (CHECK_TYPE_INLINE(cu, Curve), ((cu->flag & CU_DS_EXPAND)))
+#define FILTER_PART_OBJD(part) (CHECK_TYPE_INLINE(part, ParticleSettings), ((part->flag & PART_DS_EXPAND)))
+#define FILTER_MBALL_OBJD(mb) (CHECK_TYPE_INLINE(mb, MetaBall), ((mb->flag2 & MB_DS_EXPAND)))
+#define FILTER_ARM_OBJD(arm) (CHECK_TYPE_INLINE(arm, bArmature), ((arm->flag & ARM_DS_EXPAND)))
+#define FILTER_MESH_OBJD(me) (CHECK_TYPE_INLINE(me, Mesh), ((me->flag & ME_DS_EXPAND)))
+#define FILTER_LATTICE_OBJD(lt) (CHECK_TYPE_INLINE(lt, Lattice), ((lt->flag & LT_DS_EXPAND)))
+#define FILTER_SPK_OBJD(spk) (CHECK_TYPE_INLINE(spk, Speaker), ((spk->flag & SPK_DS_EXPAND)))
/* Variable use expanders */
-#define FILTER_NTREE_DATA(ntree) ((ntree->flag & NTREE_DS_EXPAND))
-#define FILTER_TEX_DATA(tex) ((tex->flag & TEX_DS_EXPAND))
+#define FILTER_NTREE_DATA(ntree) (CHECK_TYPE_INLINE(ntree, bNodeTree), ((ntree->flag & NTREE_DS_EXPAND)))
+#define FILTER_TEX_DATA(tex) (CHECK_TYPE_INLINE(tex, Tex), ((tex->flag & TEX_DS_EXPAND)))
/* 'Sub-object/Action' channels (flags stored in Action) */
#define SEL_ACTC(actc) ((actc->flag & ACT_SELECTED))
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index b9996c87194..efd10f3cb6b 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -93,9 +93,18 @@ typedef struct EditBone {
#define BONESEL_NOSEL (1 << 31) /* Indicates a negative number */
/* useful macros */
-#define EBONE_VISIBLE(arm, ebone) (((arm)->layer & (ebone)->layer) && !((ebone)->flag & BONE_HIDDEN_A))
+#define EBONE_VISIBLE(arm, ebone) ( \
+ CHECK_TYPE_INLINE(arm, bArmature), \
+ CHECK_TYPE_INLINE(ebone, EditBone), \
+ (((arm)->layer & (ebone)->layer) && !((ebone)->flag & BONE_HIDDEN_A)) \
+ )
+
#define EBONE_SELECTABLE(arm, ebone) (EBONE_VISIBLE(arm, ebone) && !(ebone->flag & BONE_UNSELECTABLE))
-#define EBONE_EDITABLE(ebone) (((ebone)->flag & BONE_SELECTED) && !((ebone)->flag & BONE_EDITMODE_LOCKED))
+
+#define EBONE_EDITABLE(ebone) ( \
+ CHECK_TYPE_INLINE(ebone, EditBone), \
+ (((ebone)->flag & BONE_SELECTED) && !((ebone)->flag & BONE_EDITMODE_LOCKED)) \
+ )
/* used in bone_select_hierachy() */
#define BONE_SELECT_PARENT 0
diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h
index 8a65699f404..ffee46e30c6 100644
--- a/source/blender/editors/include/ED_keyframes_draw.h
+++ b/source/blender/editors/include/ED_keyframes_draw.h
@@ -157,4 +157,3 @@ short compare_ab_cfraPtr(void *node, void *data);
short actkeyblock_is_valid(ActKeyBlock *ab, struct DLRBT_Tree *keys);
#endif /* __ED_KEYFRAMES_DRAW_H__ */
-
diff --git a/source/blender/editors/include/ED_mball.h b/source/blender/editors/include/ED_mball.h
index 5ce6db97305..1321765588d 100644
--- a/source/blender/editors/include/ED_mball.h
+++ b/source/blender/editors/include/ED_mball.h
@@ -38,7 +38,7 @@ struct wmKeyConfig;
void ED_operatortypes_metaball(void);
void ED_keymap_metaball(struct wmKeyConfig *keyconf);
-struct MetaElem *add_metaball_primitive(struct bContext *C, struct Object *obedit, float mat[4][4], int type, int newname);
+struct MetaElem *add_metaball_primitive(struct bContext *C, struct Object *obedit, float mat[4][4], float dia, int type, int newname);
int mouse_mball(struct bContext *C, const int mval[2], int extend, int deselect, int toggle);
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 093872c79f6..f55f7755668 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -142,9 +142,9 @@ int EDBM_backbuf_border_mask_init(struct ViewContext *vc, const int mcords[][2]
short xmin, short ymin, short xmax, short ymax);
int EDBM_backbuf_circle_init(struct ViewContext *vc, short xs, short ys, short rads);
-struct BMVert *EDBM_vert_find_nearest(struct ViewContext *vc, int *dist, short sel, short strict);
-struct BMEdge *EDBM_edge_find_nearest(struct ViewContext *vc, int *dist);
-struct BMFace *EDBM_face_find_nearest(struct ViewContext *vc, int *dist);
+struct BMVert *EDBM_vert_find_nearest(struct ViewContext *vc, float *r_dist, const short sel, const short strict);
+struct BMEdge *EDBM_edge_find_nearest(struct ViewContext *vc, float *r_dist);
+struct BMFace *EDBM_face_find_nearest(struct ViewContext *vc, float *r_dist);
int EDBM_select_pick(struct bContext *C, const int mval[2], short extend, short deselect, short toggle);
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 9836d690e53..d6ac9eb750d 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -35,22 +35,31 @@
extern "C" {
#endif
+struct BMEdge;
+struct BMFace;
+struct BMVert;
+struct BPoint;
struct Base;
-struct bConstraint;
-struct bContext;
-struct bPoseChannel;
+struct BezTriple;
struct Curve;
+struct EditBone;
struct EnumPropertyItem;
struct ID;
struct KeyBlock;
struct Lattice;
struct Main;
struct Mesh;
+struct MetaElem;
struct ModifierData;
+struct Nurb;
struct Object;
struct ReportList;
struct Scene;
struct View3D;
+struct ViewContext;
+struct bConstraint;
+struct bContext;
+struct bPoseChannel;
struct wmEvent;
struct wmKeyConfig;
struct wmKeyMap;
@@ -82,8 +91,10 @@ typedef enum eParentType {
PAR_TRIA
} eParentType;
+#ifdef __RNA_TYPES_H__
extern struct EnumPropertyItem prop_clear_parent_types[];
extern struct EnumPropertyItem prop_make_parent_types[];
+#endif
int ED_object_parent_set(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct Object *ob,
struct Object *par, int partype, int xmirror, int keep_transform);
@@ -123,7 +134,8 @@ void ED_object_location_from_view(struct bContext *C, float loc[3]);
void ED_object_rotation_from_view(struct bContext *C, float rot[3]);
void ED_object_base_init_transform(struct bContext *C, struct Base *base, const float loc[3], const float rot[3]);
float ED_object_new_primitive_matrix(struct bContext *C, struct Object *editob,
- const float loc[3], const float rot[3], float primmat[][4]);
+ const float loc[3], const float rot[3], float primmat[][4],
+ int apply_diameter);
void ED_object_add_generic_props(struct wmOperatorType *ot, int do_editmode);
int ED_object_add_generic_get_opts(struct bContext *C, struct wmOperator *op, float loc[3], float rot[3],
@@ -183,7 +195,7 @@ int ED_object_iter_other(struct Main *bmain, struct Object *orig_ob, int include
int ED_object_multires_update_totlevels_cb(struct Object *ob, void *totlevel_v);
-/* ibject_select.c */
+/* object_select.c */
void ED_object_select_linked_by_id(struct bContext *C, struct ID *id);
#ifdef __cplusplus
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index b81e08ed7ef..fc24f68f2d1 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -37,6 +37,7 @@ struct BMEdge;
struct BMFace;
struct BMVert;
struct BPoint;
+struct Base;
struct BezTriple;
struct BezTriple;
struct BoundBox;
@@ -50,9 +51,12 @@ struct Nurb;
struct Object;
struct RegionView3D;
struct Scene;
+struct ScrArea;
struct View3D;
struct ViewContext;
struct bContext;
+struct bPoseChannel;
+struct bScreen;
struct bglMats;
struct rcti;
struct wmOperator;
@@ -80,24 +84,8 @@ typedef struct ViewDepths {
char damaged;
} ViewDepths;
-/* enum for passing to foreach functions to test RV3D_CLIPPING */
-typedef enum eV3DClipTest {
- V3D_CLIP_TEST_OFF = 0, /* clipping is off */
- V3D_CLIP_TEST_RV3D_CLIPPING = 1, /* clip single points */
- V3D_CLIP_TEST_REGION = 2 /* use for edges to check if both verts are in the view, but not RV3D_CLIPPING */
-} eV3DClipTest;
-
float *give_cursor(struct Scene *scene, struct View3D *v3d);
-int initgrabz(struct RegionView3D *rv3d, float x, float y, float z);
-
-void ED_view3d_win_to_3d(struct ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]);
-void ED_view3d_win_to_delta(struct ARegion *ar, const float mval[2], float out[3]);
-void ED_view3d_win_to_vector(struct ARegion *ar, const float mval[2], float out[3]);
-void ED_view3d_win_to_segment_clip(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]);
-void ED_view3d_win_to_ray(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3]);
-
-void ED_view3d_global_to_vector(struct RegionView3D *rv3d, const float coord[3], float vec[3]);
void ED_view3d_to_m4(float mat[][4], const float ofs[3], const float quat[4], const float dist);
void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist);
@@ -119,7 +107,7 @@ void ED_view3d_depth_tag_update(struct RegionView3D *rv3d);
/* return values for ED_view3d_project_...() */
typedef enum {
- V3D_PROJ_RET_SUCCESS = 0,
+ V3D_PROJ_RET_OK = 0,
V3D_PROJ_RET_CLIP_NEAR = 1, /* can't avoid this when in perspective mode, (can't avoid) */
V3D_PROJ_RET_CLIP_BB = 2, /* bounding box clip - RV3D_CLIPPING */
V3D_PROJ_RET_CLIP_WIN = 3, /* outside window bounds */
@@ -133,50 +121,96 @@ typedef enum {
V3D_PROJ_TEST_CLIP_WIN = (1 << 1),
} eV3DProjTest;
+#define V3D_PROJ_TEST_CLIP_DEFAULT (V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN)
+#define V3D_PROJ_TEST_ALL (V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN)
+
+
+/* view3d_iterators.c */
+
+/* foreach iterators */
+void mesh_foreachScreenVert(
+ struct ViewContext *vc,
+ void (*func)(void *userData, struct BMVert *eve, const float screen_co[2], int index),
+ void *userData, const eV3DProjTest clip_flag);
+void mesh_foreachScreenEdge(
+ struct ViewContext *vc,
+ void (*func)(void *userData, struct BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2],
+ int index),
+ void *userData, const eV3DProjTest clip_flag);
+void mesh_foreachScreenFace(
+ struct ViewContext *vc,
+ void (*func)(void *userData, struct BMFace *efa, const float screen_co[2], int index),
+ void *userData, const eV3DProjTest clip_flag);
+void nurbs_foreachScreenVert(
+ struct ViewContext *vc,
+ void (*func)(void *userData, struct Nurb *nu, struct BPoint *bp, struct BezTriple *bezt,
+ int beztindex, const float screen_co[2]),
+ void *userData, const eV3DProjTest clip_flag);
+void mball_foreachScreenElem(
+ struct ViewContext *vc,
+ void (*func)(void *userData, struct MetaElem *ml, const float screen_co[2]),
+ void *userData, const eV3DProjTest clip_flag);
+void lattice_foreachScreenVert(
+ struct ViewContext *vc,
+ void (*func)(void *userData, struct BPoint *bp,
+ const float screen_co[2]),
+ void *userData, const eV3DProjTest clip_flag);
+void armature_foreachScreenBone(
+ struct ViewContext *vc,
+ void (*func)(void *userData, struct EditBone *ebone,
+ const float screen_co_a[2], const float screen_co_b[2]),
+ void *userData, const eV3DProjTest clip_flag);
+void pose_foreachScreenBone(
+ struct ViewContext *vc,
+ void (*func)(void *userData, struct bPoseChannel *pchan,
+ const float screen_co_a[2], const float screen_co_b[2]),
+ void *userData, const eV3DProjTest clip_flag);
+/* *** end iterators *** */
+
+
+/* view3d_project.c */
+void ED_view3d_project_float_v2_m4(const struct ARegion *a, const float co[3], float r_co[2], float mat[4][4]);
+void ED_view3d_project_float_v3_m4(struct ARegion *a, const float co[3], float r_co[3], float mat[4][4]);
+
+eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base);
/* *** short *** */
eV3DProjStatus ED_view3d_project_short_ex(struct ARegion *ar, float perspmat[4][4], const int is_local,
- const float co[3], short r_co[2], eV3DProjTest flag);
-eV3DProjStatus ED_view3d_project_short_global(struct ARegion *ar, const float co[3], short r_co[2], eV3DProjTest flag);
-eV3DProjStatus ED_view3d_project_short_object(struct ARegion *ar, const float co[3], short r_co[2], eV3DProjTest flag);
+ const float co[3], short r_co[2], const eV3DProjTest flag);
+eV3DProjStatus ED_view3d_project_short_global(struct ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag);
+eV3DProjStatus ED_view3d_project_short_object(struct ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag);
/* *** int *** */
eV3DProjStatus ED_view3d_project_int_ex(struct ARegion *ar, float perspmat[4][4], const int is_local,
- const float co[3], int r_co[2], eV3DProjTest flag);
-eV3DProjStatus ED_view3d_project_int_global(struct ARegion *ar, const float co[3], int r_co[2], eV3DProjTest flag);
-eV3DProjStatus ED_view3d_project_int_object(struct ARegion *ar, const float co[3], int r_co[2], eV3DProjTest flag);
+ const float co[3], int r_co[2], const eV3DProjTest flag);
+eV3DProjStatus ED_view3d_project_int_global(struct ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag);
+eV3DProjStatus ED_view3d_project_int_object(struct ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag);
/* *** float *** */
eV3DProjStatus ED_view3d_project_float_ex(struct ARegion *ar, float perspmat[4][4], const int is_local,
- const float co[3], float r_co[2], eV3DProjTest flag);
-eV3DProjStatus ED_view3d_project_float_global(struct ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag);
-eV3DProjStatus ED_view3d_project_float_object(struct ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag);
+ const float co[3], float r_co[2], const eV3DProjTest flag);
+eV3DProjStatus ED_view3d_project_float_global(struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag);
+eV3DProjStatus ED_view3d_project_float_object(struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag);
-void ED_view3d_project_float_v2_m4(const struct ARegion *a, const float co[3], float r_co[2], float mat[4][4]);
-void ED_view3d_project_float_v3_m4(struct ARegion *a, const float co[3], float r_co[3], float mat[4][4]);
+int initgrabz(struct RegionView3D *rv3d, float x, float y, float z);
+void ED_view3d_win_to_ray(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3]);
+void ED_view3d_global_to_vector(struct RegionView3D *rv3d, const float coord[3], float vec[3]);
+void ED_view3d_win_to_3d(struct ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]);
+void ED_view3d_win_to_delta(struct ARegion *ar, const float mval[2], float out[3]);
+void ED_view3d_win_to_vector(struct ARegion *ar, const float mval[2], float out[3]);
+void ED_view3d_win_to_segment_clip(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]);
+void ED_view3d_ob_project_mat_get(struct RegionView3D *v3d, struct Object *ob, float pmat[4][4]);
+void ED_view3d_unproject(struct bglMats *mats, float out[3], const float x, const float y, const float z);
+
+/* end */
-/* Base's get their own function since its a common operation */
-eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base);
-void ED_view3d_unproject(struct bglMats *mats, float out[3], const float x, const float y, const float z);
int ED_view3d_clip_range_get(struct View3D *v3d, struct RegionView3D *rv3d, float *clipsta, float *clipend);
int ED_view3d_viewplane_get(struct View3D *v3d, struct RegionView3D *rv3d, int winxi, int winyi, struct rctf *viewplane, float *clipsta, float *clipend);
-void ED_view3d_ob_project_mat_get(struct RegionView3D *v3d, struct Object *ob, float pmat[4][4]);
void ED_view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, struct rctf *viewborder_r, short no_shift);
void ED_view3d_calc_camera_border_size(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, float size_r[2]);
-/* drawobject.c iterators */
-void mesh_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct BMVert *eve, int x, int y, int index), void *userData, eV3DClipTest clipVerts);
-void mesh_foreachScreenEdge(struct ViewContext *vc, void (*func)(void *userData, struct BMEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, eV3DClipTest clipVerts);
-void mesh_foreachScreenFace(struct ViewContext *vc, void (*func)(void *userData, struct BMFace *efa, int x, int y, int index), void *userData);
-void nurbs_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct Nurb *nu, struct BPoint *bp, struct BezTriple *bezt, int beztindex, int x, int y), void *userData);
-void mball_foreachScreenElem(struct ViewContext *vc, void (*func)(void *userData, struct MetaElem *ml, int x, int y), void *userData);
-void lattice_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct BPoint *bp, int x, int y), void *userData);
-void armature_foreachScreenBone(struct ViewContext *vc, void (*func)(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1), void *userData);
-void pose_foreachScreenBone(struct ViewContext *vc, void (*func)(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1), void *userData);
-
-
void ED_view3d_clipping_calc(struct BoundBox *bb, float planes[4][4], struct bglMats *mats, const struct rcti *rect);
void ED_view3d_clipping_local(struct RegionView3D *rv3d, float mat[][4]);
int ED_view3d_clipping_test(struct RegionView3D *rv3d, const float vec[3], const int is_local);
@@ -191,7 +225,8 @@ void drawcircball(int mode, const float cent[3], float rad, float tmat[][4]);
/* backbuffer select and draw support */
void view3d_validate_backbuf(struct ViewContext *vc);
struct ImBuf *view3d_read_backbuf(struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax);
-unsigned int view3d_sample_backbuf_rect(struct ViewContext *vc, const int mval[2], int size, unsigned int min, unsigned int max, int *dist, short strict,
+unsigned int view3d_sample_backbuf_rect(struct ViewContext *vc, const int mval[2], int size,
+ unsigned int min, unsigned int max, float *dist, short strict,
void *handle, unsigned int (*indextest)(void *handle, unsigned int index));
unsigned int view3d_sample_backbuf(struct ViewContext *vc, int x, int y);
@@ -215,7 +250,7 @@ int view3d_get_view_aligned_coordinate(struct ViewContext *vc, float fp[3], cons
void view3d_get_transformation(const struct ARegion *ar, struct RegionView3D *rv3d, struct Object *ob, struct bglMats *mats);
/* XXX should move to BLI_math */
-int edge_inside_circle(int centx, int centy, int rad, int x1, int y1, int x2, int y2);
+int edge_inside_circle(const float cent[2], float radius, const float screen_co_a[2], const float screen_co_b[2]);
/* get 3d region from context, also if mouse is in header or toolbar */
struct RegionView3D *ED_view3d_context_rv3d(struct bContext *C);
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index ef7b8ed3a41..8f50edd1240 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -450,8 +450,8 @@ DEF_ICON(FORCE_CURVE)
DEF_ICON(FORCE_BOID)
DEF_ICON(FORCE_TURBULENCE)
DEF_ICON(FORCE_DRAG)
+DEF_ICON(FORCE_SMOKEFLOW)
#ifndef DEF_ICON_BLANK_SKIP
- DEF_ICON(BLANK672)
DEF_ICON(BLANK673)
DEF_ICON(BLANK674)
DEF_ICON(BLANK675)
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 2c00e39766c..fcde4186778 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1152,9 +1152,15 @@ static void ui_is_but_sel(uiBut *but, double *value)
}
}
- if (is_push == 2) ;
- else if (is_push == 1) but->flag |= UI_SELECT;
- else but->flag &= ~UI_SELECT;
+ if (is_push == 2) {
+ /* pass */
+ }
+ else if (is_push == 1) {
+ but->flag |= UI_SELECT;
+ }
+ else {
+ but->flag &= ~UI_SELECT;
+ }
}
static uiBut *ui_find_inlink(uiBlock *block, void *poin)
@@ -1522,7 +1528,9 @@ void ui_set_but_val(uiBut *but, double value)
* so leave this unset */
value = UI_BUT_VALUE_UNSET;
}
- else if (but->pointype == 0) ;
+ else if (but->pointype == 0) {
+ /* pass */
+ }
else if (but->type == HSVSLI) {
float *fp, hsv[3];
@@ -1715,8 +1723,9 @@ void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
BLI_strncpy(str, but->poin, maxlen);
return;
}
- else if (ui_but_anim_expression_get(but, str, maxlen))
- ; /* driver expression */
+ else if (ui_but_anim_expression_get(but, str, maxlen)) {
+ /* driver expression */
+ }
else {
/* number editing */
double value;
@@ -2474,7 +2483,9 @@ static void ui_block_do_align_but(uiBut *first, short nr)
if (rows > 0) {
uiBut *bt = but;
while (bt && bt->alignnr == nr) {
- if (bt->next && bt->next->alignnr == nr && buts_are_horiz(bt, bt->next) == 0) break;
+ if (bt->next && bt->next->alignnr == nr && buts_are_horiz(bt, bt->next) == 0) {
+ break;
+ }
bt = bt->next;
}
if (bt == NULL || bt->alignnr != nr) flag = UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_RIGHT;
@@ -2708,9 +2719,8 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
}
/* keep track of UI_interface.h */
- if (ELEM7(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, BUTM)) ;
- else if (ELEM(but->type, SCROLL, SEPR /* , FTPREVIEW */ )) ;
- else if (but->type >= SEARCH_MENU) ;
+ if (ELEM9(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, BUTM, SCROLL, SEPR /* , FTPREVIEW */)) {}
+ else if (but->type >= SEARCH_MENU) {}
else but->flag |= UI_BUT_UNDO;
BLI_addtail(&block->buttons, but);
@@ -2744,7 +2754,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *str,
- int x, int y, short width, short height,
+ int x, int y, short width, short height,
PointerRNA *ptr, PropertyRNA *prop, int index,
float min, float max, float a1, float a2, const char *tip)
{
@@ -3863,12 +3873,41 @@ void uiButGetStrInfo(bContext *C, uiBut *but, int nbr, ...)
}
}
else if (ELEM3(type, BUT_GET_RNAENUM_IDENTIFIER, BUT_GET_RNAENUM_LABEL, BUT_GET_RNAENUM_TIP)) {
+ PointerRNA *ptr = NULL;
+ PropertyRNA *prop = NULL;
+ int value = 0;
+
+ /* get the enum property... */
if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) {
+ /* enum property */
+ ptr = &but->rnapoin;
+ prop = but->rnaprop;
+ value = (but->type == ROW) ? (int)but->hardmax : (int)ui_get_but_val(but);
+ }
+ else if (but->optype) {
+ PointerRNA *opptr = uiButGetOperatorPtrRNA(but);
+ wmOperatorType *ot = but->optype;
+
+ /* if the default property of the operator is enum and it is set,
+ * fetch the tooltip of the selected value so that "Snap" and "Mirror"
+ * operator menus in the Anim Editors will show tooltips for the different
+ * operations instead of the meaningless generic operator tooltip
+ */
+ if (ot->prop && RNA_property_type(ot->prop) == PROP_ENUM) {
+ if (RNA_struct_contains_property(opptr, ot->prop)) {
+ ptr = opptr;
+ prop = ot->prop;
+ value = RNA_property_enum_get(opptr, ot->prop);
+ }
+ }
+ }
+
+ /* get strings from matching enum item */
+ if (ptr && prop) {
if (!item) {
int i;
- int value = (but->type == ROW) ? (int)but->hardmax : (int)ui_get_but_val(but);
- RNA_property_enum_items_gettexted(C, &but->rnapoin, but->rnaprop, &items, &totitems, &free_items);
-
+
+ RNA_property_enum_items_gettexted(C, ptr, prop, &items, &totitems, &free_items);
for (i = 0, item = items; i < totitems; i++, item++) {
if (item->identifier[0] && item->value == value)
break;
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 60e4c2aa90f..c4440cf07ed 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -704,7 +704,9 @@ static int ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, wmEvent *event)
BLI_rcti_rctf_copy(&rect, &but->rect);
- if (but->imb) ; /* use button size itself */
+ if (but->imb) {
+ /* use button size itself */
+ }
else if (but->flag & UI_ICON_LEFT) {
rect.xmax = rect.xmin + (BLI_rcti_size_y(&rect));
}
@@ -1184,7 +1186,9 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
/* numeric value */
if (ELEM4(but->type, NUM, NUMABS, NUMSLI, HSVSLI)) {
- if (but->poin == NULL && but->rnapoin.data == NULL) ;
+ if (but->poin == NULL && but->rnapoin.data == NULL) {
+ /* pass */
+ }
else if (mode == 'c') {
ui_get_but_string(but, buf, sizeof(buf));
WM_clipboard_text_set(buf, 0);
@@ -1205,7 +1209,9 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
else if (but->type == COLOR) {
float rgb[3];
- if (but->poin == NULL && but->rnapoin.data == NULL) ;
+ if (but->poin == NULL && but->rnapoin.data == NULL) {
+ /* pass */
+ }
else if (mode == 'c') {
ui_get_but_vectorf(but, rgb);
@@ -1234,7 +1240,9 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
else if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
uiHandleButtonData *active_data = but->active;
- if (but->poin == NULL && but->rnapoin.data == NULL) ;
+ if (but->poin == NULL && but->rnapoin.data == NULL) {
+ /* pass */
+ }
else if (mode == 'c') {
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
BLI_strncpy(buf, active_data->str, UI_MAX_DRAW_STR);
@@ -2297,7 +2305,9 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN) && event->val == KM_PRESS) {
- if (but->dt == UI_EMBOSSN && !event->ctrl) ;
+ if (but->dt == UI_EMBOSSN && !event->ctrl) {
+ /* pass */
+ }
else {
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
return WM_UI_HANDLER_BREAK;
@@ -6611,7 +6621,9 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
}
}
- if (menu->menuretval) ;
+ if (menu->menuretval) {
+ /* pass */
+ }
else if (event->type == ESCKEY && event->val == KM_PRESS) {
/* esc cancels this and all preceding menus */
menu->menuretval = UI_RETURN_CANCEL;
@@ -6763,9 +6775,13 @@ static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiPopupBlockHa
/* now handle events for our own menu */
if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) {
if (submenu && submenu->menuretval) {
+ int do_ret_out_parent = (submenu->menuretval & UI_RETURN_OUT_PARENT);
retval = ui_handle_menu_return_submenu(C, event, menu);
- /* we may wan't to quit the submenu and handle the even in this menu */
- if ((retval == WM_UI_HANDLER_BREAK) && (submenu->menuretval & UI_RETURN_OUT_PARENT)) {
+ submenu = NULL; /* hint not to use this, it may be freed by call above */
+ (void)submenu;
+ /* we may wan't to quit the submenu and handle the even in this menu,
+ * if its important to use it, check 'data->menu' first */
+ if ((retval == WM_UI_HANDLER_BREAK) && do_ret_out_parent) {
retval = ui_handle_menu_event(C, event, menu, level);
}
}
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 7a369019ac4..8e30b31f3fe 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -835,8 +835,9 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname
bt = block->buttons.last;
bt->flag = UI_TEXT_LEFT;
}
- else /* XXX bug here, collums draw bottom item badly */
+ else { /* XXX bug here, colums draw bottom item badly */
uiItemS(column);
+ }
}
}
@@ -2515,8 +2516,12 @@ static void ui_item_align(uiLayout *litem, short nr)
if (!bitem->but->alignnr)
bitem->but->alignnr = nr;
}
- else if (item->type == ITEM_LAYOUT_ABSOLUTE) ;
- else if (item->type == ITEM_LAYOUT_OVERLAP) ;
+ else if (item->type == ITEM_LAYOUT_ABSOLUTE) {
+ /* pass */
+ }
+ else if (item->type == ITEM_LAYOUT_OVERLAP) {
+ /* pass */
+ }
else if (item->type == ITEM_LAYOUT_BOX) {
box = (uiLayoutItemBx *)item;
box->roundbox->alignnr = nr;
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 1ee06b1ff64..017ffdcfb14 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -216,7 +216,7 @@ static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[3
/* set sample from accumulated values */
static void eyedropper_color_set_accum(bContext *C, Eyedropper *eye)
{
- float col[4];
+ float col[3];
mul_v3_v3fl(col, eye->accum_col, 1.0f / (float)eye->accum_tot);
eyedropper_color_set(C, eye, col);
}
@@ -807,8 +807,7 @@ static int editsource_text_edit(bContext *C, wmOperator *op,
}
if (text == NULL) {
- BKE_reportf(op->reports, RPT_WARNING,
- "file: '%s' can't be opened", filepath);
+ BKE_reportf(op->reports, RPT_WARNING, "File: '%s' can't be opened", filepath);
return OPERATOR_CANCELLED;
}
else {
@@ -820,8 +819,7 @@ static int editsource_text_edit(bContext *C, wmOperator *op,
st->text = text;
}
else {
- BKE_reportf(op->reports, RPT_INFO,
- "See '%s' in the text editor", text->id.name + 2);
+ BKE_reportf(op->reports, RPT_INFO, "See '%s' in the text editor", text->id.name + 2);
}
txt_move_toline(text, line - 1, FALSE);
@@ -857,8 +855,8 @@ static int editsource_exec(bContext *C, wmOperator *op)
!BLI_ghashIterator_isDone(&ghi);
BLI_ghashIterator_step(&ghi))
{
- uiBut *but = BLI_ghashIterator_getKey(&ghi);
- if (but && ui_editsource_uibut_match(&ui_editsource_info->but_orig, but)) {
+ uiBut *but_key = BLI_ghashIterator_getKey(&ghi);
+ if (but_key && ui_editsource_uibut_match(&ui_editsource_info->but_orig, but_key)) {
but_store = BLI_ghashIterator_getValue(&ghi);
break;
}
@@ -872,14 +870,12 @@ static int editsource_exec(bContext *C, wmOperator *op)
but_store->py_dbg_ln);
}
else {
- BKE_report(op->reports, RPT_ERROR,
- "Active button isn't from a script, cant edit source.");
+ BKE_report(op->reports, RPT_ERROR, "Active button isn't from a script, cant edit source");
ret = OPERATOR_CANCELLED;
}
}
else {
- BKE_report(op->reports, RPT_ERROR,
- "Active button match can't be found.");
+ BKE_report(op->reports, RPT_ERROR, "Active button match can't be found");
ret = OPERATOR_CANCELLED;
}
@@ -978,19 +974,19 @@ static int edittranslation_exec(bContext *C, wmOperator *op)
if (!BLI_is_dir(root)) {
BKE_report(op->reports, RPT_ERROR, "Please set your User Preferences' \"Translation Branches "
- "Directory\" path to a valid directory.");
+ "Directory\" path to a valid directory");
return OPERATOR_CANCELLED;
}
if (!WM_operatortype_find(EDTSRC_I18N_OP_NAME, 0)) {
BKE_reportf(op->reports, RPT_ERROR, "Could not find operator \"%s\"! Please enable ui_translate addon "
- "in the User Preferences.", EDTSRC_I18N_OP_NAME);
+ "in the User Preferences", EDTSRC_I18N_OP_NAME);
return OPERATOR_CANCELLED;
}
/* Try to find a valid po file for current language... */
edittranslation_find_po_file(root, uilng, popath, FILE_MAX);
/* printf("po path: %s\n", popath);*/
if (popath[0] == '\0') {
- BKE_reportf(op->reports, RPT_ERROR, "No valid po found for language '%s' under %s.", uilng, root);
+ BKE_reportf(op->reports, RPT_ERROR, "No valid po found for language '%s' under %s", uilng, root);
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 4dafb4b2d4b..14cb1cbe85a 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -2674,14 +2674,18 @@ void uiPupMenuReports(bContext *C, ReportList *reports)
ds = BLI_dynstr_new();
for (report = reports->list.first; report; report = report->next) {
- if (report->type < reports->printlevel)
- ; /* pass */
- else if (report->type >= RPT_ERROR)
+ if (report->type < reports->printlevel) {
+ /* pass */
+ }
+ else if (report->type >= RPT_ERROR) {
BLI_dynstr_appendf(ds, "Error %%i%d%%t|%s", ICON_ERROR, report->message);
- else if (report->type >= RPT_WARNING)
+ }
+ else if (report->type >= RPT_WARNING) {
BLI_dynstr_appendf(ds, "Warning %%i%d%%t|%s", ICON_ERROR, report->message);
- else if (report->type >= RPT_INFO)
+ }
+ else if (report->type >= RPT_INFO) {
BLI_dynstr_appendf(ds, "Info %%i%d%%t|%s", ICON_INFO, report->message);
+ }
}
str = BLI_dynstr_get_cstring(ds);
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 3fc20309264..3203237496f 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -891,8 +891,8 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect
/* calculate blend color */
if (ELEM4(but->type, TOG, ROW, TOGN, LISTROW)) {
- if (but->flag & UI_SELECT) ;
- else if (but->flag & UI_ACTIVE) ;
+ if (but->flag & UI_SELECT) {}
+ else if (but->flag & UI_ACTIVE) {}
else alpha = 0.5f;
}
@@ -3094,14 +3094,10 @@ static int widget_roundbox_set(uiBut *but, rcti *rect)
if (but->active) {
int direction = ui_button_open_menu_direction(but);
- if (direction == UI_TOP)
- roundbox &= ~(UI_CNR_TOP_RIGHT|UI_CNR_TOP_LEFT);
- else if (direction == UI_DOWN)
- roundbox &= ~(UI_CNR_BOTTOM_RIGHT|UI_CNR_BOTTOM_LEFT);
- else if (direction == UI_LEFT)
- roundbox &= ~(UI_CNR_TOP_LEFT|UI_CNR_BOTTOM_LEFT);
- else if (direction == UI_RIGHT)
- roundbox &= ~(UI_CNR_TOP_RIGHT|UI_CNR_BOTTOM_RIGHT);
+ if (direction == UI_TOP) roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_TOP_LEFT);
+ else if (direction == UI_DOWN) roundbox &= ~(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
+ else if (direction == UI_LEFT) roundbox &= ~(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
+ else if (direction == UI_RIGHT) roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT);
}
return roundbox;
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 5ac20829480..12e04d392b4 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -827,6 +827,11 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op)
dx = RNA_float_get(op->ptr, "deltax");
dy = RNA_float_get(op->ptr, "deltay");
+ if (U.uiflag & USER_ZOOM_INVERT) {
+ dx *= -1;
+ dy *= -1;
+ }
+
/* continuous zoom shouldn't move that fast... */
if (U.viewzoom == USER_ZOOM_CONT) { // XXX store this setting as RNA prop?
double time = PIL_check_seconds_timer();
@@ -849,12 +854,12 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op)
float mval_faci = 1.0f - mval_fac;
float ofs = (mval_fac * dx) - (mval_faci * dx);
- v2d->cur.xmin += ofs - dx;
- v2d->cur.xmax += ofs + dx;
+ v2d->cur.xmin += ofs + dx;
+ v2d->cur.xmax += ofs - dx;
}
else {
- v2d->cur.xmin -= dx;
- v2d->cur.xmax += dx;
+ v2d->cur.xmin += dx;
+ v2d->cur.xmax -= dx;
}
}
}
@@ -868,12 +873,12 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op)
float mval_faci = 1.0f - mval_fac;
float ofs = (mval_fac * dy) - (mval_faci * dy);
- v2d->cur.ymin += ofs - dy;
- v2d->cur.ymax += ofs + dy;
+ v2d->cur.ymin += ofs + dy;
+ v2d->cur.ymax += ofs - dy;
}
else {
- v2d->cur.ymin -= dy;
- v2d->cur.ymax += dy;
+ v2d->cur.ymin += dy;
+ v2d->cur.ymax -= dy;
}
}
}
@@ -1044,14 +1049,9 @@ static int view_zoomdrag_modal(bContext *C, wmOperator *op, wmEvent *event)
}
/* set transform amount, and add current deltas to stored total delta (for redo) */
- if (U.uiflag & USER_ZOOM_INVERT) {
- RNA_float_set(op->ptr, "deltax", -dx);
- RNA_float_set(op->ptr, "deltay", -dy);
- }
- else {
- RNA_float_set(op->ptr, "deltax", dx);
- RNA_float_set(op->ptr, "deltay", dy);
- }
+ RNA_float_set(op->ptr, "deltax", dx);
+ RNA_float_set(op->ptr, "deltay", dy);
+
vzd->dx += dx;
vzd->dy += dy;
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index 0ec99325752..ba93206e63a 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -143,7 +143,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
else {
- BKE_report(op->reports, RPT_WARNING, "Export file not created.");
+ BKE_report(op->reports, RPT_WARNING, "Export file not created");
return OPERATOR_CANCELLED;
}
}
@@ -307,7 +307,7 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op)
RNA_string_get(op->ptr, "filepath", filename);
if (collada_import(C, filename)) return OPERATOR_FINISHED;
- BKE_report(op->reports, RPT_ERROR, "Errors found during parsing COLLADA document. Please see console for error log.");
+ BKE_report(op->reports, RPT_ERROR, "Errors found during parsing COLLADA document (see console for details)");
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c
index a254a6a9278..e43c8a2b53b 100644
--- a/source/blender/editors/mask/mask_add.c
+++ b/source/blender/editors/mask/mask_add.c
@@ -46,6 +46,7 @@
#include "WM_types.h"
#include "ED_mask.h" /* own include */
+#include "ED_screen.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -97,7 +98,7 @@ static int find_nearest_diff_point(const bContext *C, Mask *mask, const float no
&tot_diff_point);
if (diff_points) {
- int i, tot_point;
+ int j, tot_point;
unsigned int tot_feather_point;
float *feather_points = NULL, *points;
@@ -114,26 +115,26 @@ static int find_nearest_diff_point(const bContext *C, Mask *mask, const float no
tot_point = tot_diff_point;
}
- for (i = 0; i < tot_point - 1; i++) {
+ for (j = 0; j < tot_point - 1; j++) {
float cur_dist, a[2], b[2];
- a[0] = points[2 * i] * scalex;
- a[1] = points[2 * i + 1] * scaley;
+ a[0] = points[2 * j] * scalex;
+ a[1] = points[2 * j + 1] * scaley;
- b[0] = points[2 * i + 2] * scalex;
- b[1] = points[2 * i + 3] * scaley;
+ b[0] = points[2 * j + 2] * scalex;
+ b[1] = points[2 * j + 3] * scaley;
cur_dist = dist_to_line_segment_v2(co, a, b);
if (cur_dist < dist) {
if (tangent)
- sub_v2_v2v2(tangent, &diff_points[2 * i + 2], &diff_points[2 * i]);
+ sub_v2_v2v2(tangent, &diff_points[2 * j + 2], &diff_points[2 * j]);
point_masklay = masklay;
point_spline = spline;
point = use_deform ? &spline->points[(cur_point - spline->points_deform)] : cur_point;
dist = cur_dist;
- u = (float)i / tot_point;
+ u = (float)j / tot_point;
}
}
@@ -562,6 +563,11 @@ static int add_vertex_exec(bContext *C, wmOperator *op)
float co[2];
+ if (mask == NULL) {
+ /* if there's no active mask, create one */
+ mask = ED_mask_new(C, NULL);
+ }
+
masklay = BKE_mask_layer_active(mask);
if (masklay && masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
@@ -647,7 +653,7 @@ void MASK_OT_add_vertex(wmOperatorType *ot)
/* api callbacks */
ot->exec = add_vertex_exec;
ot->invoke = add_vertex_invoke;
- ot->poll = ED_maskedit_mask_poll;
+ ot->poll = ED_operator_mask;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index a60b771d179..490389c6d0c 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -20,6 +20,7 @@
*
*
* Contributor(s): Blender Foundation,
+ * Campbell Barton,
* Sergey Sharybin
*
* ***** END GPL LICENSE BLOCK *****
@@ -41,7 +42,9 @@
#include "DNA_mask_types.h"
#include "DNA_screen_types.h"
#include "DNA_object_types.h" /* SELECT */
+#include "DNA_space_types.h"
+#include "ED_clip.h"
#include "ED_mask.h" /* own include */
#include "ED_space_api.h"
#include "BIF_gl.h"
@@ -120,13 +123,22 @@ static void draw_spline_parents(MaskLayer *UNUSED(masklay), MaskSpline *spline)
}
#endif
+static void mask_point_undistort_pos(SpaceClip *sc, float r_co[2], float co[2])
+{
+ BKE_mask_coord_to_movieclip(sc->clip, &sc->user, r_co, co);
+ ED_clip_point_undistorted_pos(sc, r_co, r_co);
+ BKE_mask_coord_from_movieclip(sc->clip, &sc->user, r_co, r_co);
+}
+
/* return non-zero if spline is selected */
-static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline,
+static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline *spline,
const char UNUSED(draw_flag), const char draw_type)
{
const int is_spline_sel = (spline->flag & SELECT) && (masklay->restrictflag & MASK_RESTRICT_SELECT) == 0;
unsigned char rgb_spline[4];
MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ int undistort = FALSE;
int i, hsize, tot_feather_point;
float (*feather_points)[2], (*fp)[2];
@@ -134,6 +146,9 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline,
if (!spline->tot_point)
return;
+ if (sc)
+ undistort = sc->clip && sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT;
+
/* TODO, add this to sequence editor */
hsize = 4; /* UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE); */
@@ -151,8 +166,14 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline,
int j;
for (j = 0; j < point->tot_uw + 1; j++) {
+ float feather_point[2];
int sel = FALSE;
+ copy_v2_v2(feather_point, *fp);
+
+ if (undistort)
+ mask_point_undistort_pos(sc, feather_point, feather_point);
+
if (j == 0) {
sel = MASKPOINT_ISSEL_ANY(point);
}
@@ -171,7 +192,7 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline,
}
glBegin(GL_POINTS);
- glVertex2fv(*fp);
+ glVertex2fv(feather_point);
glEnd();
fp++;
@@ -188,11 +209,17 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline,
BezTriple *bezt = &point_deform->bezt;
float handle[2];
- float *vert = bezt->vec[1];
+ float vert[2];
int has_handle = BKE_mask_point_has_handle(point);
+ copy_v2_v2(vert, bezt->vec[1]);
BKE_mask_point_handle(point_deform, handle);
+ if (undistort) {
+ mask_point_undistort_pos(sc, vert, vert);
+ mask_point_undistort_pos(sc, handle, handle);
+ }
+
/* draw handle segment */
if (has_handle) {
@@ -265,7 +292,7 @@ static void mask_color_active_tint(unsigned char r_rgb[4], const unsigned char r
}
}
-static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot_point,
+static void mask_draw_curve_type(const bContext *C, MaskSpline *spline, float (*orig_points)[2], int tot_point,
const short is_feather, const short is_smooth, const short is_active,
const unsigned char rgb_spline[4], const char draw_type)
{
@@ -273,6 +300,22 @@ static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot
const unsigned char rgb_black[4] = {0x00, 0x00, 0x00, 0xff};
// const unsigned char rgb_white[4] = {0xff, 0xff, 0xff, 0xff};
unsigned char rgb_tmp[4];
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ float (*points)[2] = orig_points;
+
+ if (sc) {
+ int undistort = sc->clip && sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT;
+
+ if (undistort) {
+ int i;
+
+ points = MEM_callocN(2 * tot_point * sizeof(float), "undistorthed mask curve");
+
+ for (i = 0; i < tot_point; i++) {
+ mask_point_undistort_pos(sc, points[i], orig_points[i]);
+ }
+ }
+ }
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, points);
@@ -347,8 +390,6 @@ static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot
glVertexPointer(2, GL_FLOAT, 0, points);
glDrawArrays(draw_method, 0, tot_point);
- glDrawArrays(draw_method, 0, tot_point);
-
if (is_smooth == FALSE && is_feather) {
glDisable(GL_BLEND);
}
@@ -358,9 +399,11 @@ static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot
glDisableClientState(GL_VERTEX_ARRAY);
+ if (points != orig_points)
+ MEM_freeN(points);
}
-static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline,
+static void draw_spline_curve(const bContext *C, MaskLayer *masklay, MaskSpline *spline,
const char draw_flag, const char draw_type,
const short is_active,
int width, int height)
@@ -395,7 +438,7 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline,
/* draw feather */
mask_spline_feather_color_get(masklay, spline, is_spline_sel, rgb_tmp);
- mask_draw_curve_type(spline, feather_points, tot_feather_point,
+ mask_draw_curve_type(C, spline, feather_points, tot_feather_point,
TRUE, is_smooth, is_active,
rgb_tmp, draw_type);
@@ -414,7 +457,7 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline,
}
/* same as above */
- mask_draw_curve_type(spline, feather_points, tot_feather_point,
+ mask_draw_curve_type(C, spline, feather_points, tot_feather_point,
TRUE, is_smooth, is_active,
rgb_tmp, draw_type);
}
@@ -423,7 +466,7 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline,
/* draw main curve */
mask_spline_color_get(masklay, spline, is_spline_sel, rgb_tmp);
- mask_draw_curve_type(spline, diff_points, tot_diff_point,
+ mask_draw_curve_type(C, spline, diff_points, tot_diff_point,
FALSE, is_smooth, is_active,
rgb_tmp, draw_type);
MEM_freeN(diff_points);
@@ -436,7 +479,7 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline,
(void)draw_type;
}
-static void draw_masklays(Mask *mask, const char draw_flag, const char draw_type,
+static void draw_masklays(const bContext *C, Mask *mask, const char draw_flag,const char draw_type,
int width, int height)
{
MaskLayer *masklay;
@@ -453,13 +496,13 @@ static void draw_masklays(Mask *mask, const char draw_flag, const char draw_type
for (spline = masklay->splines.first; spline; spline = spline->next) {
/* draw curve itself first... */
- draw_spline_curve(masklay, spline, draw_flag, draw_type, is_active, width, height);
+ draw_spline_curve(C, masklay, spline, draw_flag, draw_type, is_active, width, height);
// draw_spline_parents(masklay, spline);
if (!(masklay->restrictflag & MASK_RESTRICT_SELECT)) {
/* ...and then handles over the curve so they're nicely visible */
- draw_spline_points(masklay, spline, draw_flag, draw_type);
+ draw_spline_points(C, masklay, spline, draw_flag, draw_type);
}
/* show undeform for testing */
@@ -467,9 +510,9 @@ static void draw_masklays(Mask *mask, const char draw_flag, const char draw_type
void *back = spline->points_deform;
spline->points_deform = NULL;
- draw_spline_curve(masklay, spline, draw_flag, draw_type, is_active, width, height);
+ draw_spline_curve(C, masklay, spline, draw_flag, draw_type, is_active, width, height);
// draw_spline_parents(masklay, spline);
- draw_spline_points(masklay, spline, draw_flag, draw_type);
+ draw_spline_points(C, masklay, spline, draw_flag, draw_type);
spline->points_deform = back;
}
}
@@ -489,7 +532,7 @@ void ED_mask_draw(const bContext *C,
ED_mask_get_size(sa, &width, &height);
- draw_masklays(mask, draw_flag, draw_type, width, height);
+ draw_masklays(C, mask, draw_flag, draw_type, width, height);
}
/* sets up the opengl context.
@@ -500,7 +543,7 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar,
const float aspx, const float aspy,
const short do_scale_applied, const short do_post_draw,
float stabmat[4][4], /* optional - only used by clip */
- const bContext *C /* optional - only used when do_post_draw is set */
+ const bContext *C /* optional - only used when do_post_draw is set or called from clip editor */
)
{
struct View2D *v2d = &ar->v2d;
@@ -559,7 +602,7 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar,
}
/* draw! */
- draw_masklays(mask, draw_flag, draw_type, width, height);
+ draw_masklays(C, mask, draw_flag, draw_type, width, height);
if (do_post_draw) {
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h
index ffd4afca182..fcfcfb237e9 100644
--- a/source/blender/editors/mask/mask_intern.h
+++ b/source/blender/editors/mask/mask_intern.h
@@ -33,6 +33,7 @@
#define __MASK_INTERN_H__
struct bContext;
+struct Mask;
struct wmEvent;
struct wmOperatorType;
@@ -43,6 +44,8 @@ void MASK_OT_add_vertex(struct wmOperatorType *ot);
void MASK_OT_add_feather_vertex(struct wmOperatorType *ot);
/* mask_ops.c */
+struct Mask *ED_mask_new(struct bContext *C, const char *name);
+
void MASK_OT_new(struct wmOperatorType *ot);
void MASK_OT_layer_new(struct wmOperatorType *ot);
void MASK_OT_layer_remove(struct wmOperatorType *ot);
diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c
index 88fbb91edfb..35f85f3faee 100644
--- a/source/blender/editors/mask/mask_ops.c
+++ b/source/blender/editors/mask/mask_ops.c
@@ -258,13 +258,10 @@ int ED_mask_feather_find_nearest(const bContext *C, Mask *mask, float normal_co[
/******************** create new mask *********************/
-static int mask_new_exec(bContext *C, wmOperator *op)
+Mask *ED_mask_new(bContext *C, const char *name)
{
ScrArea *sa = CTX_wm_area(C);
Mask *mask;
- char name[MAX_ID_NAME - 2];
-
- RNA_string_get(op->ptr, "name", name);
mask = BKE_mask_new(name);
@@ -290,6 +287,17 @@ static int mask_new_exec(bContext *C, wmOperator *op)
}
}
+ return mask;
+}
+
+static int mask_new_exec(bContext *C, wmOperator *op)
+{
+ char name[MAX_ID_NAME - 2];
+
+ RNA_string_get(op->ptr, "name", name);
+
+ ED_mask_new(C, name);
+
return OPERATOR_FINISHED;
}
@@ -483,15 +491,15 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event)
customdata->uw = uw;
if (uw) {
- float co[2];
+ float co_uw[2];
float weight_scalar = BKE_mask_point_weight_scalar(spline, point, uw->u);
customdata->weight = uw->w;
customdata->weight_scalar = weight_scalar;
- BKE_mask_point_segment_co(spline, point, uw->u, co);
+ BKE_mask_point_segment_co(spline, point, uw->u, co_uw);
BKE_mask_point_normal(spline, point, uw->u, customdata->no);
- madd_v2_v2v2fl(customdata->feather, co, customdata->no, uw->w * weight_scalar);
+ madd_v2_v2v2fl(customdata->feather, co_uw, customdata->no, uw->w * weight_scalar);
}
else {
BezTriple *bezt = &point->bezt;
diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c
index 69cfdf4e51b..dc204909577 100644
--- a/source/blender/editors/mask/mask_select.c
+++ b/source/blender/editors/mask/mask_select.c
@@ -557,7 +557,7 @@ static int clip_lasso_select_exec(bContext *C, wmOperator *op)
select = !RNA_boolean_get(op->ptr, "deselect");
do_lasso_select_mask(C, mcords, mcords_tot, select);
- MEM_freeN(mcords);
+ MEM_freeN((void *)mcords);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt
index 246c323213c..9aa3f3633f3 100644
--- a/source/blender/editors/mesh/CMakeLists.txt
+++ b/source/blender/editors/mesh/CMakeLists.txt
@@ -21,6 +21,7 @@
set(INC
../include
../uvedit
+ ../../blenfont
../../blenkernel
../../blenlib
../../blenloader
@@ -68,4 +69,8 @@ if(WITH_GAMEENGINE)
)
endif()
+if(WITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
+endif()
+
blender_add_lib(bf_editor_mesh "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/editors/mesh/SConscript b/source/blender/editors/mesh/SConscript
index b3aba977b21..923bb3f9057 100644
--- a/source/blender/editors/mesh/SConscript
+++ b/source/blender/editors/mesh/SConscript
@@ -5,7 +5,7 @@ sources = env.Glob('*.c')
defs = []
-incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
+incs = '../include ../../blenfont ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
incs += ' ../../gpu ../../blenloader'
incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern'
@@ -24,4 +24,7 @@ if env['WITH_BF_GAMEENGINE']:
else:
sources.remove('mesh_navmesh.c')
+if env['WITH_BF_INTERNATIONAL']:
+ defs.append('WITH_INTERNATIONAL')
+
env.BlenderLib ( 'bf_editors_mesh', sources, Split(incs), defs, libtype=['core'], priority=[45] )
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index 5fd848ccb13..429b2148894 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -214,7 +214,9 @@ static void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int ind
/* fill array by selection */
mp = me->mpoly;
for (a = 0; a < me->totpoly; a++, mp++) {
- if (mp->flag & ME_HIDE) ;
+ if (mp->flag & ME_HIDE) {
+ /* pass */
+ }
else if (mp->flag & ME_FACE_SEL) {
hash_add_face(ehash, mp, me->mloop + mp->loopstart);
linkflag[a] = 1;
@@ -572,7 +574,9 @@ int do_paintface_box_select(ViewContext *vc, rcti *rect, int select, int extend)
mpoly = me->mpoly;
for (a = 1; a <= me->totpoly; a++, mpoly++) {
if (selar[a]) {
- if (mpoly->flag & ME_HIDE) ;
+ if (mpoly->flag & ME_HIDE) {
+ /* pass */
+ }
else {
if (select) mpoly->flag |= ME_FACE_SEL;
else mpoly->flag &= ~ME_FACE_SEL;
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index 0cf4ac48bf7..99ed86d7a06 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -73,7 +73,7 @@ static Object *make_prim_init(bContext *C, const char *idname,
*state = 1;
}
- *dia = ED_object_new_primitive_matrix(C, obedit, loc, rot, mat);
+ *dia = ED_object_new_primitive_matrix(C, obedit, loc, rot, mat, FALSE);
return obedit;
}
@@ -200,7 +200,7 @@ static int add_primitive_circle_exec(bContext *C, wmOperator *op)
if (!EDBM_op_call_and_selectf(em, op, "vertout",
"create_circle segments=%i diameter=%f cap_ends=%b cap_tris=%b mat=%m4",
- RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius"),
+ RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius") * dia,
cap_end, cap_tri, mat))
{
return OPERATOR_CANCELLED;
@@ -256,10 +256,10 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op)
em, op, "vertout",
"create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f mat=%m4",
RNA_int_get(op->ptr, "vertices"),
- RNA_float_get(op->ptr, "radius"),
- RNA_float_get(op->ptr, "radius"),
+ RNA_float_get(op->ptr, "radius") * dia,
+ RNA_float_get(op->ptr, "radius") * dia,
cap_end, cap_tri,
- RNA_float_get(op->ptr, "depth"), mat))
+ RNA_float_get(op->ptr, "depth") * dia, mat))
{
return OPERATOR_CANCELLED;
}
@@ -315,8 +315,8 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op)
if (!EDBM_op_call_and_selectf(
em, op, "vertout",
"create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f mat=%m4",
- RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius1"),
- RNA_float_get(op->ptr, "radius2"), cap_end, cap_tri, RNA_float_get(op->ptr, "depth"), mat))
+ RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius1") * dia,
+ RNA_float_get(op->ptr, "radius2") * dia, cap_end, cap_tri, RNA_float_get(op->ptr, "depth") * dia, mat))
{
return OPERATOR_CANCELLED;
}
@@ -421,6 +421,10 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op)
rot[0] += (float)M_PI / 2.0f;
obedit = make_prim_init(C, "Monkey", &dia, mat, &state, loc, rot, layer);
+ mat[0][0] *= dia;
+ mat[1][1] *= dia;
+ mat[2][2] *= dia;
+
em = BMEdit_FromObject(obedit);
if (!EDBM_op_call_and_selectf(em, op, "vertout", "create_monkey mat=%m4", mat)) {
@@ -465,7 +469,7 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op)
if (!EDBM_op_call_and_selectf(em, op, "vertout",
"create_uvsphere segments=%i revolutions=%i diameter=%f mat=%m4",
RNA_int_get(op->ptr, "segments"), RNA_int_get(op->ptr, "ring_count"),
- RNA_float_get(op->ptr, "size"), mat))
+ RNA_float_get(op->ptr, "size") * dia, mat))
{
return OPERATOR_CANCELLED;
}
@@ -517,7 +521,7 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op)
em, op, "vertout",
"create_icosphere subdivisions=%i diameter=%f mat=%m4",
RNA_int_get(op->ptr, "subdivisions"),
- RNA_float_get(op->ptr, "size"), mat))
+ RNA_float_get(op->ptr, "size") * dia, mat))
{
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/mesh/editmesh_bvh.c b/source/blender/editors/mesh/editmesh_bvh.c
index c249d764ac1..e84fa90fe5c 100644
--- a/source/blender/editors/mesh/editmesh_bvh.c
+++ b/source/blender/editors/mesh/editmesh_bvh.c
@@ -371,9 +371,9 @@ int BMBVH_VertVisible(BMBVHTree *tree, BMEdge *e, RegionView3D *r3d)
}
#endif
-static BMFace *edge_ray_cast(BMBVHTree *tree, const float co[3], const float dir[3], float *hitout, BMEdge *e)
+static BMFace *edge_ray_cast(BMBVHTree *tree, const float co[3], const float dir[3], float *r_hitout, BMEdge *e)
{
- BMFace *f = BMBVH_RayCast(tree, co, dir, hitout, NULL);
+ BMFace *f = BMBVH_RayCast(tree, co, dir, r_hitout, NULL);
if (f && BM_edge_in_face(f, e))
return NULL;
@@ -392,7 +392,7 @@ static void scale_point(float c1[3], const float p[3], const float s)
int BMBVH_EdgeVisible(BMBVHTree *tree, BMEdge *e, ARegion *ar, View3D *v3d, Object *obedit)
{
BMFace *f;
- float co1[3], co2[3], co3[3], dir1[4], dir2[4], dir3[4];
+ float co1[3], co2[3], co3[3], dir1[3], dir2[3], dir3[3];
float origin[3], invmat[4][4];
float epsilon = 0.01f;
float end[3];
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 4f4fc27582c..1d19d35ca34 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -1418,7 +1418,7 @@ static void knife_input_ray_cast(KnifeTool_OpData *kcd, const int mval_i[2],
static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float cageco[3], int *is_space)
{
BMFace *f;
- int dist = KMAXDIST;
+ float dist = KMAXDIST;
float origin[3];
float ray[3];
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index c0a36e24015..98fae2cc701 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -416,7 +416,7 @@ static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt)
Object *obedit = CTX_data_edit_object(C);
RingSelOpData *lcd;
BMEdge *edge;
- int dist = 75;
+ float dist = 75.0f;
if (modifiers_isDeformedByLattice(obedit) || modifiers_isDeformedByArmature(obedit))
BKE_report(op->reports, RPT_WARNING, "Loop cut doesn't work well on deformed edit mesh display");
@@ -513,7 +513,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
ED_region_tag_redraw(lcd->ar);
break;
case MOUSEMOVE: { /* mouse moved somewhere to select another loop */
- int dist = 75;
+ float dist = 75.0f;
BMEdge *edge;
lcd->vc.mval[0] = event->mval[0];
diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c
index 001d584416f..8fe2aa4b1a7 100644
--- a/source/blender/editors/mesh/editmesh_rip.c
+++ b/source/blender/editors/mesh/editmesh_rip.c
@@ -55,19 +55,59 @@
#include "mesh_intern.h"
-/* helper to find edge for edge_rip */
-static float edbm_rip_rip_edgedist(ARegion *ar, float mat[][4],
- const float co1[3], const float co2[3], const float mvalf[2])
+/**
+ * helper to find edge for edge_rip,
+ *
+ * \param inset is used so we get some useful distance
+ * when comparing multiple edges that meet at the same
+ * point and would result in teh same distance.
+ */
+#define INSET_DEFAULT 0.00001f
+static float edbm_rip_edgedist(ARegion *ar, float mat[][4],
+ const float co1[3], const float co2[3], const float mvalf[2],
+ const float inset)
{
- float vec1[3], vec2[3];
+ float vec1[2], vec2[2];
ED_view3d_project_float_v2_m4(ar, co1, vec1, mat);
ED_view3d_project_float_v2_m4(ar, co2, vec2, mat);
+ if (inset != 0.0f) {
+ const float dist = inset / len_v2v2(vec1, vec2);
+ interp_v2_v2v2(vec1, vec1, vec2, dist);
+ interp_v2_v2v2(vec2, vec2, vec1, dist);
+ }
+
/* TODO: use dist_squared_to_line_segment_v2() looks like we only ever use for comparison */
return dist_to_line_segment_v2(mvalf, vec1, vec2);
}
+#if 0
+static float edbm_rip_linedist(ARegion *ar, float mat[][4],
+ const float co1[3], const float co2[3], const float mvalf[2])
+{
+ float vec1[2], vec2[2];
+
+ ED_view3d_project_float_v2_m4(ar, co1, vec1, mat);
+ ED_view3d_project_float_v2_m4(ar, co2, vec2, mat);
+
+ return dist_to_line_v2(mvalf, vec1, vec2);
+}
+#endif
+
+/* calculaters a point along the loop tangent which can be used to measure against edges */
+static void edbm_calc_loop_co(BMLoop *l, float l_mid_co[3])
+{
+ BM_loop_calc_face_tangent(l, l_mid_co);
+
+ /* scale to average of surrounding edge size, only needs to be approx, but should
+ * be roughly equivalent to the check below which uses the middle of the edge. */
+ mul_v3_fl(l_mid_co, (BM_edge_calc_length(l->e) + BM_edge_calc_length(l->prev->e)) / 2.0f);
+
+ add_v3_v3(l_mid_co, l->v->co);
+}
+
+
static float edbm_rip_edge_side_measure(BMEdge *e, BMLoop *e_l,
ARegion *ar,
float projectMat[4][4], const float fmval[2])
@@ -237,7 +277,6 @@ static EdgeLoopPair *edbm_ripsel_looptag_helper(BMesh *bm)
uid_start = uid;
while ((e = edbm_ripsel_edge_mark_step(v_step, uid))) {
- BM_elem_flag_disable(e, BM_ELEM_SMOOTH);
v_step = BM_edge_other_vert((e_step = e), v_step);
uid++; /* only different line */
tot++;
@@ -254,7 +293,6 @@ static EdgeLoopPair *edbm_ripsel_looptag_helper(BMesh *bm)
v_step = e_first->v1;
while ((e = edbm_ripsel_edge_mark_step(v_step, uid))) {
- BM_elem_flag_disable(e, BM_ELEM_SMOOTH);
v_step = BM_edge_other_vert((e_step = e), v_step);
uid--; /* only different line */
tot++;
@@ -344,6 +382,145 @@ static void edbm_ripsel_deselect_helper(BMesh *bm, EdgeLoopPair *eloop_pairs,
}
/* --- end 'ripsel' selection handling code --- */
+
+/* --- face-fill code --- */
+/**
+ * return an un-ordered array of loop pairs
+ * use for rebuilding face-fill
+ *
+ * \note the method currenly used fails for edges with 3+ face users and gives
+ * nasty holes in the mesh, there isnt a good way of knowing ahead of time
+ * which loops will be split apart (its possible to figure out but quite involved).
+ * So for now this is a known limitation of current rip-fill option.
+ */
+
+typedef struct UnorderedLoopPair {
+ BMLoop *l_pair[2];
+ char flag;
+} UnorderedLoopPair;
+enum {
+ ULP_FLIP_0 = (1 << 0),
+ ULP_FLIP_1 = (1 << 1)
+};
+
+static UnorderedLoopPair *edbm_tagged_loop_pairs_to_fill(BMesh *bm)
+{
+ BMIter iter;
+ BMEdge *e;
+
+ unsigned int total_tag = 0;
+ /* count tags, could be pre-calculated */
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+ total_tag++;
+ }
+ }
+
+ if (total_tag) {
+ UnorderedLoopPair *uloop_pairs = MEM_mallocN(total_tag * sizeof(UnorderedLoopPair), __func__);
+ UnorderedLoopPair *ulp = uloop_pairs;
+
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+ BMLoop *l1, *l2;
+ if (BM_edge_loop_pair(e, &l1, &l2)) {
+ BMVert *v_cmp = l1->e->v1;
+ ulp->flag = (((l1->v != v_cmp) ? ULP_FLIP_0 : 0) |
+ ((l2->v == v_cmp) ? ULP_FLIP_1 : 0));
+ }
+ else {
+ ulp->flag = 0;
+ }
+ ulp->l_pair[0] = l1;
+ ulp->l_pair[1] = l2;
+
+ ulp++;
+ }
+ }
+
+ return uloop_pairs;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static void edbm_tagged_loop_pairs_do_fill_faces(BMesh *bm, UnorderedLoopPair *uloop_pairs)
+{
+ UnorderedLoopPair *ulp;
+ unsigned int total_tag = MEM_allocN_len(uloop_pairs) / sizeof(UnorderedLoopPair);
+ unsigned int i;
+
+ for (i = 0, ulp = uloop_pairs; i < total_tag; i++, ulp++) {
+ if ((ulp->l_pair[0] && ulp->l_pair[1]) &&
+ (ulp->l_pair[0]->e != ulp->l_pair[1]->e))
+ {
+ /* time has come to make a face! */
+ BMVert *v_shared = BM_edge_share_vert(ulp->l_pair[0]->e, ulp->l_pair[1]->e);
+ BMFace *f, *f_example = ulp->l_pair[0]->f;
+ BMLoop *l_iter;
+ BMVert *f_verts[4];
+
+ if (v_shared == NULL) {
+ /* quad */
+ f_verts[0] = ulp->l_pair[0]->e->v1;
+ f_verts[1] = ulp->l_pair[1]->e->v1;
+ f_verts[2] = ulp->l_pair[1]->e->v2;
+ f_verts[3] = ulp->l_pair[0]->e->v2;
+
+ if (ulp->flag & ULP_FLIP_0) {
+ SWAP(BMVert *, f_verts[0], f_verts[3]);
+ }
+ if (ulp->flag & ULP_FLIP_1) {
+ SWAP(BMVert *, f_verts[1], f_verts[2]);
+ }
+ }
+ else {
+ /* tri */
+ f_verts[0] = v_shared;
+ f_verts[1] = BM_edge_other_vert(ulp->l_pair[0]->e, v_shared);
+ f_verts[2] = BM_edge_other_vert(ulp->l_pair[1]->e, v_shared);
+ f_verts[3] = NULL;
+
+ /* don't use the flip flags */
+ if (v_shared == ulp->l_pair[0]->v) {
+ SWAP(BMVert *, f_verts[0], f_verts[1]);
+ }
+ }
+
+ /* face should never exist */
+ BLI_assert(BM_face_exists(bm, f_verts, f_verts[3] ? 4 : 3, &f) == FALSE);
+
+ f = BM_face_create_quad_tri_v(bm, f_verts, f_verts[3] ? 4 : 3, f_example, FALSE);
+
+ l_iter = BM_FACE_FIRST_LOOP(f);
+
+ if (f_verts[3]) {
+ BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]), l_iter); l_iter = l_iter->next;
+ BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, ulp->l_pair[1]->next), l_iter); l_iter = l_iter->next;
+ BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, ulp->l_pair[1]), l_iter); l_iter = l_iter->next;
+ BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]->next), l_iter);
+ }
+ else {
+ if (v_shared == f_verts[0]) {
+ BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]->next), l_iter); l_iter = l_iter->next;
+ BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]), l_iter); l_iter = l_iter->next;
+ BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, ulp->l_pair[1]->next), l_iter);
+ }
+ else {
+ BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]->next), l_iter); l_iter = l_iter->next;
+ BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]), l_iter); l_iter = l_iter->next;
+ BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, ulp->l_pair[1]), l_iter);
+ }
+ }
+
+ }
+ }
+}
+
+/* --- end 'face-fill' code --- */
+
+
static int edbm_rip_call_edgesplit(BMEditMesh *em, wmOperator *op)
{
BMOperator bmop;
@@ -366,6 +543,8 @@ static int edbm_rip_call_edgesplit(BMEditMesh *em, wmOperator *op)
*/
static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event)
{
+ const int do_fill = RNA_boolean_get(op->ptr, "use_fill");
+ UnorderedLoopPair *fill_uloop_pairs = NULL;
Object *obedit = CTX_data_edit_object(C);
ARegion *ar = CTX_wm_region(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -388,7 +567,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event)
ED_view3d_ob_project_mat_get(rv3d, obedit, projectMat);
/* find selected vert - same some time and check history first */
- if (BM_select_history_active_get(em->bm, &ese) && ese.htype == BM_VERT) {
+ if (BM_select_history_active_get(bm, &ese) && ese.htype == BM_VERT) {
v = (BMVert *)ese.ele;
}
else {
@@ -417,7 +596,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event)
totboundary_edge += (is_boundary != 0 || BM_edge_is_wire(e));
if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
if (is_boundary == FALSE && BM_edge_is_manifold(e)) {
- d = edbm_rip_rip_edgedist(ar, projectMat, e->v1->co, e->v2->co, fmval);
+ d = edbm_rip_edgedist(ar, projectMat, e->v1->co, e->v2->co, fmval, INSET_DEFAULT);
if (d < dist) {
dist = d;
e2 = e;
@@ -426,6 +605,42 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event)
}
}
+ /* if we are ripping a single vertex from 3 faces,
+ * then measure the distance to the face corner as well as the edge */
+ if (BM_vert_face_count(v) == 3 &&
+ BM_vert_edge_count(v) == 3)
+ {
+ BMEdge *e_all[3];
+ BMLoop *l_all[3];
+ int i1, i2;
+
+ BM_iter_as_array(bm, BM_EDGES_OF_VERT, v, (void **)e_all, 3);
+ BM_iter_as_array(bm, BM_LOOPS_OF_VERT, v, (void **)l_all, 3);
+
+ /* not do a loop similar to the one above, but test against loops */
+ for (i1 = 0; i1 < 3; i1++) {
+ /* consider wire as boundary for this purpose,
+ * otherwise we can't a face away from a wire edge */
+ float l_mid_co[3];
+ l = l_all[i1];
+ edbm_calc_loop_co(l, l_mid_co);
+ d = edbm_rip_edgedist(ar, projectMat, l->v->co, l_mid_co, fmval, INSET_DEFAULT);
+
+ if (d < dist) {
+ dist = d;
+
+ /* find the edge that is not in this loop */
+ e2 = NULL;
+ for (i2 = 0; i2 < 3; i2++) {
+ if (!BM_edge_in_loop(e_all[i2], l)) {
+ e2 = e_all[i2];
+ break;
+ }
+ }
+ BLI_assert(e2 != NULL);
+ }
+ }
+ }
}
/* should we go ahead with edge rip or do we need to do special case, split off vertex?:
@@ -459,7 +674,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event)
int vi_best = 0;
if (ese.ele) {
- BM_select_history_remove(em->bm, ese.ele);
+ BM_select_history_remove(bm, ese.ele);
}
dist = FLT_MAX;
@@ -473,14 +688,9 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event)
BM_ITER_ELEM (l, &iter, vout[i], BM_LOOPS_OF_VERT) {
if (!BM_elem_flag_test(l->f, BM_ELEM_HIDDEN)) {
float l_mid_co[3];
- BM_loop_calc_face_tangent(l, l_mid_co);
+ edbm_calc_loop_co(l, l_mid_co);
- /* scale to average of surrounding edge size, only needs to be approx, but should
- * be roughly equivalent to the check below which uses the middle of the edge. */
- mul_v3_fl(l_mid_co, (BM_edge_calc_length(l->e) + BM_edge_calc_length(l->prev->e)) / 2.0f);
- add_v3_v3(l_mid_co, v->co);
-
- d = edbm_rip_rip_edgedist(ar, projectMat, v->co, l_mid_co, fmval);
+ d = edbm_rip_edgedist(ar, projectMat, v->co, l_mid_co, fmval, INSET_DEFAULT);
if (d < dist) {
dist = d;
@@ -496,7 +706,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event)
float e_mid_co[3];
mid_v3_v3v3(e_mid_co, e->v1->co, e->v2->co);
- d = edbm_rip_rip_edgedist(ar, projectMat, v->co, e_mid_co, fmval);
+ d = edbm_rip_edgedist(ar, projectMat, v->co, e_mid_co, fmval, INSET_DEFAULT);
if (d < dist) {
dist = d;
@@ -512,7 +722,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event)
BM_vert_select_set(bm, v, TRUE);
if (ese.ele) {
- BM_select_history_store(em->bm, v);
+ BM_select_history_store(bm, v);
}
/* splice all others back together */
@@ -543,39 +753,65 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_CANCELLED;
}
+ /* *** Execute the split! *** */
+ /* unlike edge split, for single vertex split we only use the operator in one of the cases
+ * but both allocate fill */
+
/* rip two adjacent edges */
if (BM_edge_is_boundary(e2) || BM_vert_face_count(v) == 2) {
+ /* Don't run the edge split operator in this case */
+
+ BM_elem_flag_enable(e2, BM_ELEM_TAG); /* only for face-fill (we don't call the operator) */
+
+ /* keep directly before edgesplit */
+ if (do_fill) {
+ fill_uloop_pairs = edbm_tagged_loop_pairs_to_fill(bm);
+ }
+
l = e2->l;
ripvert = BM_face_vert_separate(bm, l->f, v);
BLI_assert(ripvert);
if (!ripvert) {
+ if (fill_uloop_pairs) MEM_freeN(fill_uloop_pairs);
return OPERATOR_CANCELLED;
}
}
- else if (BM_edge_is_manifold(e2)) {
- l = e2->l;
- e = BM_face_other_edge_loop(l->f, e2, v)->e;
- BM_elem_flag_enable(e, BM_ELEM_TAG);
+ else {
+ if (BM_edge_is_manifold(e2)) {
+ l = e2->l;
+ e = BM_face_other_edge_loop(l->f, e2, v)->e;
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+
+ l = e2->l->radial_next;
+ e = BM_face_other_edge_loop(l->f, e2, v)->e;
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+ }
+ else {
+ /* looks like there are no split edges, we could just return/report-error? - Campbell */
+ }
+
+ /* keep directly before edgesplit */
+ if (do_fill) {
+ fill_uloop_pairs = edbm_tagged_loop_pairs_to_fill(bm);
+ }
- l = e2->l->radial_next;
- e = BM_face_other_edge_loop(l->f, e2, v)->e;
- BM_elem_flag_enable(e, BM_ELEM_TAG);
+ if (!edbm_rip_call_edgesplit(em, op)) {
+ if (fill_uloop_pairs) MEM_freeN(fill_uloop_pairs);
+ return OPERATOR_CANCELLED;
+ }
}
dist = FLT_MAX;
- if (!edbm_rip_call_edgesplit(em, op)) {
- return OPERATOR_CANCELLED;
- }
- else {
+ {
/* --- select which vert --- */
BMVert *v_best = NULL;
float l_prev_co[3], l_next_co[3], l_corner_co[3];
float scale;
dist = FLT_MAX;
- BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
/* disable by default, re-enable winner at end */
BM_vert_select_set(bm, v, FALSE);
@@ -593,7 +829,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event)
add_v3_v3v3(l_corner_co, l_prev_co, l_next_co);
add_v3_v3(l_corner_co, l->v->co);
- d = edbm_rip_rip_edgedist(ar, projectMat, l->v->co, l_corner_co, fmval);
+ d = edbm_rip_edgedist(ar, projectMat, l->v->co, l_corner_co, fmval, INSET_DEFAULT);
if (d < dist) {
v_best = v;
dist = d;
@@ -605,11 +841,17 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event)
if (v_best) {
BM_vert_select_set(bm, v_best, TRUE);
if (ese.ele) {
- BM_select_history_store(em->bm, v_best);
+ BM_select_history_store(bm, v_best);
}
}
}
+ if (do_fill && fill_uloop_pairs) {
+ edbm_tagged_loop_pairs_do_fill_faces(bm, fill_uloop_pairs);
+ MEM_freeN(fill_uloop_pairs);
+ }
+
+
if (totvert_orig == bm->totvert) {
BKE_report(op->reports, RPT_ERROR, "No vertices could be ripped");
return OPERATOR_CANCELLED;
@@ -623,6 +865,8 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event)
*/
static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event)
{
+ const int do_fill = RNA_boolean_get(op->ptr, "use_fill");
+ UnorderedLoopPair *fill_uloop_pairs = NULL;
Object *obedit = CTX_data_edit_object(C);
ARegion *ar = CTX_wm_region(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -633,25 +877,25 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event)
BMEdge *e, *e2;
BMVert *v;
const int totedge_orig = bm->totedge;
- int i;
float projectMat[4][4], fmval[3] = {event->mval[0], event->mval[1]};
- int totedge;
- int all_minifold;
-
EdgeLoopPair *eloop_pairs;
ED_view3d_ob_project_mat_get(rv3d, obedit, projectMat);
- /* important this runs on the original selection, before tempering with tagging */
+ /* important this runs on the original selection, before tampering with tagging */
eloop_pairs = edbm_ripsel_looptag_helper(bm);
/* expand edge selection */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ int all_manifold;
+ int totedge_manifold; /* manifold, visible edges */
+ int i;
+
e2 = NULL;
i = 0;
- totedge = 0;
- all_minifold = TRUE;
+ totedge_manifold = 0;
+ all_manifold = TRUE;
BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
if (!BM_edge_is_wire(e) &&
@@ -663,22 +907,25 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event)
e2 = e;
i++;
}
- totedge++;
+ totedge_manifold++;
}
/** #BM_vert_other_disk_edge has no hidden checks so don't check hidden here */
- if ((all_minifold == TRUE) && (BM_edge_is_manifold(e) == FALSE)) {
- all_minifold = FALSE;
+ if ((all_manifold == TRUE) && (BM_edge_is_manifold(e) == FALSE)) {
+ all_manifold = FALSE;
}
}
/* single edge, extend */
if (i == 1 && e2->l) {
- if ((totedge == 4) || (all_minifold == FALSE)) {
+ /* note: if the case of 3 edges has one change in loop stepping,
+ * if this becomes more involved we may be better off splitting
+ * the 3 edge case into its own else-if branch */
+ if ((totedge_manifold == 4 || totedge_manifold == 3) || (all_manifold == FALSE)) {
BMLoop *l_a = e2->l;
BMLoop *l_b = l_a->radial_next;
- /* find the best face to follow, this what the edge won't point away from
+ /* find the best face to follow, this way the edge won't point away from
* the mouse when there are more then 4 (takes the shortest face fan around) */
l = (edbm_rip_edge_side_measure(e2, l_a, ar, projectMat, fmval) <
edbm_rip_edge_side_measure(e2, l_b, ar, projectMat, fmval)) ? l_a : l_b;
@@ -688,9 +935,12 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event)
* not crashing but adds duplicate edge. */
if (BM_edge_is_manifold(l->e)) {
l = l->radial_next;
- l = BM_face_other_edge_loop(l->f, l->e, v);
+
+ if (totedge_manifold != 3)
+ l = BM_face_other_edge_loop(l->f, l->e, v);
if (l) {
+ BLI_assert(!BM_elem_flag_test(l->e, BM_ELEM_TAG));
BM_elem_flag_enable(l->e, BM_ELEM_TAG);
}
}
@@ -699,13 +949,20 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event)
e = BM_vert_other_disk_edge(v, e2);
if (e) {
+ BLI_assert(!BM_elem_flag_test(e, BM_ELEM_TAG));
BM_elem_flag_enable(e, BM_ELEM_TAG);
}
}
}
}
+ /* keep directly before edgesplit */
+ if (do_fill) {
+ fill_uloop_pairs = edbm_tagged_loop_pairs_to_fill(bm);
+ }
+
if (!edbm_rip_call_edgesplit(em, op)) {
+ if (fill_uloop_pairs) MEM_freeN(fill_uloop_pairs);
return OPERATOR_CANCELLED;
}
@@ -718,6 +975,11 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event)
ar, projectMat, fmval);
MEM_freeN(eloop_pairs);
+ if (do_fill && fill_uloop_pairs) {
+ edbm_tagged_loop_pairs_do_fill_faces(bm, fill_uloop_pairs);
+ MEM_freeN(fill_uloop_pairs);
+ }
+
if (totedge_orig == bm->totedge) {
BKE_report(op->reports, RPT_ERROR, "No edges could be ripped");
return OPERATOR_CANCELLED;
@@ -740,7 +1002,7 @@ static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
int ret;
/* running in face mode hardly makes sense, so convert to region loop and rip */
- if (em->bm->totfacesel) {
+ if (bm->totfacesel) {
/* highly nifty but hard to support since the operator can fail and we're left
* with modified selection */
// WM_operator_name_call(C, "MESH_OT_region_to_loop", WM_OP_INVOKE_DEFAULT, NULL);
@@ -760,7 +1022,7 @@ static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
*/
/* BM_ELEM_SELECT --> BM_ELEM_TAG */
- BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
BM_elem_flag_set(e, BM_ELEM_TAG, BM_elem_flag_test(e, BM_ELEM_SELECT));
}
@@ -804,5 +1066,6 @@ void MESH_OT_rip(wmOperatorType *ot)
/* to give to transform */
Transform_Properties(ot, P_PROPORTIONAL);
- RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
+ RNA_def_boolean(ot->srna, "mirror", FALSE, "Mirror Editing", "");
+ RNA_def_boolean(ot->srna, "use_fill", FALSE, "Fill", "Fill the ripped region");
}
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index ae2d090fef3..bc792037443 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -57,6 +57,7 @@
#include "ED_mesh.h"
#include "ED_screen.h"
#include "ED_uvedit.h"
+#include "ED_object.h"
#include "ED_view3d.h"
#include "BIF_gl.h"
@@ -330,9 +331,9 @@ int EDBM_backbuf_circle_init(ViewContext *vc, short xs, short ys, short rads)
}
-static void findnearestvert__doClosest(void *userData, BMVert *eve, int x, int y, int index)
+static void findnearestvert__doClosest(void *userData, BMVert *eve, const float screen_co[2], int index)
{
- struct { short mval[2], pass, select, strict; int dist, lastIndex, closestIndex; BMVert *closest; } *data = userData;
+ struct { float mval_fl[2], pass, select, strict; float dist, lastIndex, closestIndex; BMVert *closest; } *data = userData;
if (data->pass == 0) {
if (index <= data->lastIndex)
@@ -344,18 +345,18 @@ static void findnearestvert__doClosest(void *userData, BMVert *eve, int x, int y
}
if (data->dist > 3) {
- int temp = abs(data->mval[0] - x) + abs(data->mval[1] - y);
+ float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co);
if (BM_elem_flag_test(eve, BM_ELEM_SELECT) == data->select) {
if (data->strict == 1) {
return;
}
else {
- temp += 5;
+ dist_test += 5;
}
}
- if (temp < data->dist) {
- data->dist = temp;
+ if (dist_test < data->dist) {
+ data->dist = dist_test;
data->closest = eve;
data->closestIndex = index;
}
@@ -382,10 +383,10 @@ static unsigned int findnearestvert__backbufIndextest(void *handle, unsigned int
* if 0, unselected vertice are given the bias
* strict: if 1, the vertice corresponding to the sel parameter are ignored and not just biased
*/
-BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short strict)
+BMVert *EDBM_vert_find_nearest(ViewContext *vc, float *r_dist, const short sel, const short strict)
{
if (vc->v3d->drawtype > OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)) {
- int distance;
+ float distance;
unsigned int index;
BMVert *eve;
@@ -400,8 +401,8 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short stri
eve = BM_vert_at_index(vc->em->bm, index - 1);
- if (eve && distance < *dist) {
- *dist = distance;
+ if (eve && distance < *r_dist) {
+ *r_dist = distance;
return eve;
}
else {
@@ -410,7 +411,7 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short stri
}
else {
- struct { short mval[2], pass, select, strict; int dist, lastIndex, closestIndex; BMVert *closest; } data;
+ struct { float mval_fl[2], pass, select, strict; float dist, lastIndex, closestIndex; BMVert *closest; } data;
static int lastSelectedIndex = 0;
static BMVert *lastSelected = NULL;
@@ -420,10 +421,10 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short stri
}
data.lastIndex = lastSelectedIndex;
- data.mval[0] = vc->mval[0];
- data.mval[1] = vc->mval[1];
+ data.mval_fl[0] = vc->mval[0];
+ data.mval_fl[1] = vc->mval[1];
data.select = sel;
- data.dist = *dist;
+ data.dist = *r_dist;
data.strict = strict;
data.closest = NULL;
data.closestIndex = 0;
@@ -432,14 +433,14 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short stri
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, V3D_CLIP_TEST_RV3D_CLIPPING);
+ mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
if (data.dist > 3) {
data.pass = 1;
- mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, V3D_CLIP_TEST_RV3D_CLIPPING);
+ mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
- *dist = data.dist;
+ *r_dist = data.dist;
lastSelected = data.closest;
lastSelectedIndex = data.closestIndex;
@@ -462,18 +463,12 @@ float labda_PdistVL2Dfl(const float v1[2], const float v2[2], const float v3[2])
}
/* note; uses v3d, so needs active 3d window */
-static void findnearestedge__doClosest(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int UNUSED(index))
+static void findnearestedge__doClosest(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int UNUSED(index))
{
- struct { ViewContext vc; float mval[2]; int dist; BMEdge *closest; } *data = userData;
- float v1[2], v2[2];
+ struct { ViewContext vc; float mval_fl[2]; float dist; BMEdge *closest; } *data = userData;
int distance;
-
- v1[0] = x0;
- v1[1] = y0;
- v2[0] = x1;
- v2[1] = y1;
-
- distance = dist_to_line_segment_v2(data->mval, v1, v2);
+
+ distance = dist_to_line_segment_v2(data->mval_fl, screen_co_a, screen_co_b);
if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
distance += 5;
@@ -481,7 +476,7 @@ static void findnearestedge__doClosest(void *userData, BMEdge *eed, int x0, int
if (distance < data->dist) {
if (data->vc.rv3d->rflag & RV3D_CLIPPING) {
- float labda = labda_PdistVL2Dfl(data->mval, v1, v2);
+ float labda = labda_PdistVL2Dfl(data->mval_fl, screen_co_a, screen_co_b);
float vec[3];
vec[0] = eed->v1->co[0] + labda * (eed->v2->co[0] - eed->v1->co[0]);
@@ -499,11 +494,11 @@ static void findnearestedge__doClosest(void *userData, BMEdge *eed, int x0, int
}
}
}
-BMEdge *EDBM_edge_find_nearest(ViewContext *vc, int *dist)
+BMEdge *EDBM_edge_find_nearest(ViewContext *vc, float *r_dist)
{
if (vc->v3d->drawtype > OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)) {
- int distance;
+ float distance;
unsigned int index;
BMEdge *eed;
@@ -512,8 +507,8 @@ BMEdge *EDBM_edge_find_nearest(ViewContext *vc, int *dist)
index = view3d_sample_backbuf_rect(vc, vc->mval, 50, bm_solidoffs, bm_wireoffs, &distance, 0, NULL, NULL);
eed = BM_edge_at_index(vc->em->bm, index - 1);
- if (eed && distance < *dist) {
- *dist = distance;
+ if (eed && distance < *r_dist) {
+ *r_dist = distance;
return eed;
}
else {
@@ -521,36 +516,37 @@ BMEdge *EDBM_edge_find_nearest(ViewContext *vc, int *dist)
}
}
else {
- struct { ViewContext vc; float mval[2]; int dist; BMEdge *closest; } data;
+ struct { ViewContext vc; float mval_fl[2]; float dist; BMEdge *closest; } data;
data.vc = *vc;
- data.mval[0] = vc->mval[0];
- data.mval[1] = vc->mval[1];
- data.dist = *dist;
+ data.mval_fl[0] = vc->mval[0];
+ data.mval_fl[1] = vc->mval[1];
+ data.dist = *r_dist;
data.closest = NULL;
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- mesh_foreachScreenEdge(vc, findnearestedge__doClosest, &data, V3D_CLIP_TEST_REGION);
+ mesh_foreachScreenEdge(vc, findnearestedge__doClosest, &data, V3D_PROJ_TEST_CLIP_WIN);
- *dist = data.dist;
+ *r_dist = data.dist;
return data.closest;
}
}
-static void findnearestface__getDistance(void *userData, BMFace *efa, int x, int y, int UNUSED(index))
+static void findnearestface__getDistance(void *userData, BMFace *efa, const float screen_co[2], int UNUSED(index))
{
- struct { short mval[2]; int dist; BMFace *toFace; } *data = userData;
+ struct { float mval_fl[2]; float dist; BMFace *toFace; } *data = userData;
if (efa == data->toFace) {
- int temp = abs(data->mval[0] - x) + abs(data->mval[1] - y);
+ const float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co);
- if (temp < data->dist)
- data->dist = temp;
+ if (dist_test < data->dist) {
+ data->dist = dist_test;
+ }
}
}
-static void findnearestface__doClosest(void *userData, BMFace *efa, int x, int y, int index)
+static void findnearestface__doClosest(void *userData, BMFace *efa, const float screen_co[2], int index)
{
- struct { short mval[2], pass; int dist, lastIndex, closestIndex; BMFace *closest; } *data = userData;
+ struct { float mval_fl[2], pass; float dist, lastIndex, closestIndex; BMFace *closest; } *data = userData;
if (data->pass == 0) {
if (index <= data->lastIndex)
@@ -562,17 +558,17 @@ static void findnearestface__doClosest(void *userData, BMFace *efa, int x, int y
}
if (data->dist > 3) {
- int temp = abs(data->mval[0] - x) + abs(data->mval[1] - y);
+ const float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co);
- if (temp < data->dist) {
- data->dist = temp;
+ if (dist_test < data->dist) {
+ data->dist = dist_test;
data->closest = efa;
data->closestIndex = index;
}
}
}
-BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist)
+BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist)
{
if (vc->v3d->drawtype > OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)) {
@@ -585,17 +581,17 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist)
efa = BM_face_at_index(vc->em->bm, index - 1);
if (efa) {
- struct { short mval[2]; int dist; BMFace *toFace; } data;
+ struct { float mval_fl[2]; float dist; BMFace *toFace; } data;
- data.mval[0] = vc->mval[0];
- data.mval[1] = vc->mval[1];
+ data.mval_fl[0] = vc->mval[0];
+ data.mval_fl[1] = vc->mval[1];
data.dist = 0x7FFF; /* largest short */
data.toFace = efa;
- mesh_foreachScreenFace(vc, findnearestface__getDistance, &data);
+ mesh_foreachScreenFace(vc, findnearestface__getDistance, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- if (vc->em->selectmode == SCE_SELECT_FACE || data.dist < *dist) { /* only faces, no dist check */
- *dist = data.dist;
+ if ((vc->em->selectmode == SCE_SELECT_FACE) || (data.dist < *r_dist)) { /* only faces, no dist check */
+ *r_dist = data.dist;
return efa;
}
}
@@ -603,7 +599,7 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist)
return NULL;
}
else {
- struct { short mval[2], pass; int dist, lastIndex, closestIndex; BMFace *closest; } data;
+ struct { float mval_fl[2], pass; float dist, lastIndex, closestIndex; BMFace *closest; } data;
static int lastSelectedIndex = 0;
static BMFace *lastSelected = NULL;
@@ -613,23 +609,23 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist)
}
data.lastIndex = lastSelectedIndex;
- data.mval[0] = vc->mval[0];
- data.mval[1] = vc->mval[1];
- data.dist = *dist;
+ data.mval_fl[0] = vc->mval[0];
+ data.mval_fl[1] = vc->mval[1];
+ data.dist = *r_dist;
data.closest = NULL;
data.closestIndex = 0;
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
data.pass = 0;
- mesh_foreachScreenFace(vc, findnearestface__doClosest, &data);
+ mesh_foreachScreenFace(vc, findnearestface__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
- if (data.dist > 3) {
+ if (data.dist > 3.0f) {
data.pass = 1;
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- mesh_foreachScreenFace(vc, findnearestface__doClosest, &data);
+ mesh_foreachScreenFace(vc, findnearestface__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
- *dist = data.dist;
+ *r_dist = data.dist;
lastSelected = data.closest;
lastSelectedIndex = data.closestIndex;
@@ -645,7 +641,7 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist)
static int unified_findnearest(ViewContext *vc, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa)
{
BMEditMesh *em = vc->em;
- int dist = 75;
+ float dist = 75.0f;
*r_eve = NULL;
*r_eed = NULL;
@@ -1006,7 +1002,7 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short ring)
BMEditMesh *em;
BMEdge *eed;
int select = TRUE;
- int dist = 50;
+ float dist = 50.0f;
float mvalf[2];
em_setup_viewcontext(C, &vc);
@@ -1061,11 +1057,11 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short ring)
/* We can't be sure this has already been set... */
ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
- if (ED_view3d_project_float_object(vc.ar, eed->v1->co, v1_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_float_object(vc.ar, eed->v1->co, v1_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
length_1 = len_squared_v2v2(mvalf, v1_co);
}
- if (ED_view3d_project_float_object(vc.ar, eed->v2->co, v2_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_float_object(vc.ar, eed->v2->co, v2_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
length_2 = len_squared_v2v2(mvalf, v2_co);
}
#if 0
@@ -1092,7 +1088,7 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short ring)
float co[2], tdist;
BM_face_calc_center_mean(f, cent);
- if (ED_view3d_project_float_object(vc.ar, cent, co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_float_object(vc.ar, cent, co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
tdist = len_squared_v2v2(mvalf, co);
if (tdist < best_dist) {
/* printf("Best face: %p (%f)\n", f, tdist);*/
@@ -1399,7 +1395,7 @@ static int mouse_mesh_shortest_path(bContext *C, int mval[2])
ViewContext vc;
BMEditMesh *em;
BMEdge *e;
- int dist = 50;
+ float dist = 75.0f;
em_setup_viewcontext(C, &vc);
vc.mval[0] = mval[0];
@@ -2179,11 +2175,19 @@ static void walker_deselect_nth(BMEditMesh *em, int nth, int offset, BMHeader *h
BMW_FLAG_NOP, /* don't use BMW_FLAG_TEST_HIDDEN here since we want to desel all */
BMW_NIL_LAY);
+ /* use tag to avoid touching the same verts twice */
+ BM_ITER_MESH (ele, &iter, bm, itertype) {
+ BM_elem_flag_disable(ele, BM_ELEM_TAG);
+ }
+
BLI_assert(walker.order == BMW_BREADTH_FIRST);
for (ele = BMW_begin(&walker, h_act); ele != NULL; ele = BMW_step(&walker)) {
- /* Deselect elements that aren't at "nth" depth from active */
- if ((offset + BMW_current_depth(&walker)) % nth) {
- BM_elem_select_set(bm, ele, FALSE);
+ if (!BM_elem_flag_test(ele, BM_ELEM_TAG)) {
+ /* Deselect elements that aren't at "nth" depth from active */
+ if ((offset + BMW_current_depth(&walker)) % nth) {
+ BM_elem_select_set(bm, ele, FALSE);
+ }
+ BM_elem_flag_enable(ele, BM_ELEM_TAG);
}
}
BMW_end(&walker);
@@ -2306,8 +2310,8 @@ void MESH_OT_select_nth(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_int(ot->srna, "nth", 2, 2, 100, "Nth Selection", "", 1, INT_MAX);
- RNA_def_int(ot->srna, "offset", 0, 0, 100, "Offset", "", 0, INT_MAX);
+ RNA_def_int(ot->srna, "nth", 2, 2, INT_MAX, "Nth Selection", "", 2, 100);
+ RNA_def_int(ot->srna, "offset", 0, 0, INT_MAX, "Offset", "", 0, 100);
}
void em_setup_viewcontext(bContext *C, ViewContext *vc)
diff --git a/source/blender/editors/mesh/editmesh_slide.c b/source/blender/editors/mesh/editmesh_slide.c
index e42b95c6013..d370b5a881e 100644
--- a/source/blender/editors/mesh/editmesh_slide.c
+++ b/source/blender/editors/mesh/editmesh_slide.c
@@ -34,6 +34,8 @@
#include "BLI_array.h"
#include "BLI_math.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
#include "BKE_report.h"
#include "BKE_tessmesh.h"
@@ -113,11 +115,11 @@ static int vtx_slide_init(bContext *C, wmOperator *op)
/* Custom data */
VertexSlideOp *vso;
- const char *header_str = "Vertex Slide: Hover over an edge and left-click to select slide edge. "
- "Left-Shift: Midpoint Snap, Left-Alt: Snap, Left-Ctrl: Snap&Merge";
+ const char *header_str = TIP_("Vertex Slide: Hover over an edge and left-click to select slide edge. "
+ "Left-Shift: Midpoint Snap, Left-Alt: Snap, Left-Ctrl: Snap & Merge");
if (!obedit) {
- BKE_report(op->reports, RPT_ERROR, "Vertex Slide Error: Not object in context");
+ BKE_report(op->reports, RPT_ERROR, "Vertex slide error: no object in context");
return FALSE;
}
@@ -126,7 +128,7 @@ static int vtx_slide_init(bContext *C, wmOperator *op)
/* Is there a starting vertex ? */
if (ese == NULL || (ese->htype != BM_VERT && ese->htype != BM_EDGE)) {
- BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex Slide Error: Select a (single) vertex");
+ BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex slide error: select a (single) vertex");
return FALSE;
}
@@ -177,7 +179,7 @@ static int vtx_slide_init(bContext *C, wmOperator *op)
/* Init frame */
if (!vtx_slide_set_frame(vso)) {
- BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex Slide: Can't find starting vertex!");
+ BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex slide error: cannot find starting vertex!");
vtx_slide_exit(C, op);
return FALSE;
}
@@ -390,8 +392,8 @@ static BMEdge *vtx_slide_nrst_in_frame(VertexSlideOp *vso, const float mval[2])
mul_v3_m4v3(v2_proj, vso->obj->obmat, edge->v2->co);
/* we could use ED_view3d_project_float_object here, but for now dont since we dont have the context */
- if ((ED_view3d_project_float_global(vso->active_region, v1_proj, v1_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) &&
- (ED_view3d_project_float_global(vso->active_region, v2_proj, v2_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS))
+ if ((ED_view3d_project_float_global(vso->active_region, v1_proj, v1_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) &&
+ (ED_view3d_project_float_global(vso->active_region, v2_proj, v2_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK))
{
const float dist = dist_to_line_segment_v2(mval, v1_proj, v2_proj);
if (dist < min_dist) {
@@ -409,7 +411,8 @@ static void vtx_slide_find_edge(VertexSlideOp *vso, wmEvent *event)
/* Nearest edge */
BMEdge *nst_edge = NULL;
- const float mval_float[] = { (float)event->mval[0], (float)event->mval[1]};
+ const float mval_float[2] = {(float)event->mval[0],
+ (float)event->mval[1]};
/* Set mouse coords */
copy_v2_v2_int(vso->view_context->mval, event->mval);
@@ -458,8 +461,8 @@ static void vtx_slide_update(VertexSlideOp *vso, wmEvent *event)
mul_v3_m4v3(start_vtx_proj, vso->obj->obmat, vso->start_vtx->co);
mul_v3_m4v3(edge_other_proj, vso->obj->obmat, other->co);
- if ((ED_view3d_project_float_global(vso->active_region, edge_other_proj, edge_other_proj, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) ||
- (ED_view3d_project_float_global(vso->active_region, start_vtx_proj, start_vtx_proj, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS))
+ if ((ED_view3d_project_float_global(vso->active_region, edge_other_proj, edge_other_proj, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) ||
+ (ED_view3d_project_float_global(vso->active_region, start_vtx_proj, start_vtx_proj, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK))
{
/* not much we can do here */
return;
@@ -718,7 +721,7 @@ static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_u
/* Is there a starting vertex ? */
if ((ese == NULL) || (ese->htype != BM_VERT && ese->htype != BM_EDGE)) {
- BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex Slide Error: Select a (single) vertex");
+ BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex slide error: select a (single) vertex");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index d73e7d81b9f..ee615093c86 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -41,7 +41,9 @@
#include "RNA_define.h"
#include "RNA_access.h"
+#include "BLI_array.h"
#include "BLI_blenlib.h"
+#include "BLI_noise.h"
#include "BLI_math.h"
#include "BLI_rand.h"
@@ -49,6 +51,7 @@
#include "BKE_context.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_depsgraph.h"
+#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_report.h"
#include "BKE_texture.h"
@@ -72,6 +75,8 @@
#include "mesh_intern.h"
+#define MVAL_PIXEL_MARGIN 5.0f
+
/* allow accumulated normals to form a new direction but don't
* accept direct opposite directions else they will cancel each other out */
static void add_normal_aligned(float nor[3], const float add[3])
@@ -153,6 +158,51 @@ void MESH_OT_subdivide(wmOperatorType *ot)
}
+static int edbm_unsubdivide_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BMEdit_FromObject(obedit);
+ BMOperator bmop;
+
+ int iterations = RNA_int_get(op->ptr, "iterations");
+
+ EDBM_op_init(em, &bmop, op,
+ "unsubdivide verts=%hv iterations=%i", BM_ELEM_SELECT, iterations);
+
+ BMO_op_exec(em->bm, &bmop);
+
+ if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
+ return 0;
+ }
+
+ if ((em->selectmode & SCE_SELECT_VERTEX) == 0) {
+ EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX); /* need to flush vert->face first */
+ }
+ EDBM_selectmode_flush(em);
+
+ EDBM_update_generic(C, em, TRUE);
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_unsubdivide(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Un-Subdivide";
+ ot->description = "UnSubdivide selected edges & faces";
+ ot->idname = "MESH_OT_unsubdivide";
+
+ /* api callbacks */
+ ot->exec = edbm_unsubdivide_exec;
+ ot->poll = ED_operator_editmesh;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* props */
+ RNA_def_int(ot->srna, "iterations", 2, 1, INT_MAX, "Iterations", "Number of times to unsubdivide", 1, 100);
+}
+
void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em)
{
Object *obedit = em->ob;
@@ -165,7 +215,7 @@ void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em)
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
float mval[2], co_proj[3], no_dummy[3];
int dist_dummy;
- if (ED_view3d_project_float_object(ar, eve->co, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_float_object(ar, eve->co, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
if (snapObjectsContext(C, mval, &dist_dummy, co_proj, no_dummy, SNAP_NOT_OBEDIT)) {
mul_v3_m4v3(eve->co, obedit->imat, co_proj);
}
@@ -429,8 +479,8 @@ void MESH_OT_extrude_repeat(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* props */
- RNA_def_float(ot->srna, "offset", 2.0f, 0.0f, 100.0f, "Offset", "", 0.0f, FLT_MAX);
- RNA_def_int(ot->srna, "steps", 10, 0, 180, "Steps", "", 0, INT_MAX);
+ RNA_def_float(ot->srna, "offset", 2.0f, 0.0f, FLT_MAX, "Offset", "", 0.0f, 100.0f);
+ RNA_def_int(ot->srna, "steps", 10, 0, INT_MAX, "Steps", "", 0, 180);
}
/* generic extern called extruder */
@@ -765,10 +815,10 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent
done = FALSE;
BM_ITER_MESH (eed, &iter, vc.em->bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
- float co1[3], co2[3];
+ float co1[2], co2[2];
- if ((ED_view3d_project_float_object(vc.ar, eed->v1->co, co1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) &&
- (ED_view3d_project_float_object(vc.ar, eed->v2->co, co2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS))
+ if ((ED_view3d_project_float_object(vc.ar, eed->v1->co, co1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) &&
+ (ED_view3d_project_float_object(vc.ar, eed->v2->co, co2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK))
{
/* 2D rotate by 90d while adding.
* (x, y) = (y, -x)
@@ -1215,11 +1265,14 @@ static int edbm_vert_connect(bContext *C, wmOperator *op)
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
return OPERATOR_CANCELLED;
}
+ else {
+ EDBM_selectmode_flush(em); /* so newly created edges get the selection state from the vertex */
EDBM_update_generic(C, em, TRUE);
return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
+}
void MESH_OT_vert_connect(wmOperatorType *ot)
{
@@ -1607,7 +1660,7 @@ void MESH_OT_vertices_smooth(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_int(ot->srna, "repeat", 1, 1, 100, "Number of times to smooth the mesh", "", 1, INT_MAX);
+ RNA_def_int(ot->srna, "repeat", 1, 1, 1000, "Number of times to smooth the mesh", "", 1, 100);
RNA_def_boolean(ot->srna, "xaxis", 1, "X-Axis", "Smooth along the X axis");
RNA_def_boolean(ot->srna, "yaxis", 1, "Y-Axis", "Smooth along the Y axis");
RNA_def_boolean(ot->srna, "zaxis", 1, "Z-Axis", "Smooth along the Z axis");
@@ -2080,7 +2133,7 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op)
}
count = totvert_orig - em->bm->totvert;
- BKE_reportf(op->reports, RPT_INFO, "Removed %d vert%s", count, (count == 1) ? "ex" : "ices");
+ BKE_reportf(op->reports, RPT_INFO, "Removed %d vertices", count);
EDBM_update_generic(C, em, TRUE);
@@ -2165,7 +2218,7 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op)
}
if (svert == NULL || evert == NULL) {
- BKE_report(op->reports, RPT_WARNING, "Path Selection requires that two vertices be selected");
+ BKE_report(op->reports, RPT_WARNING, "Path selection requires two vertices to be selected");
return OPERATOR_CANCELLED;
}
@@ -2772,7 +2825,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op)
screen_vert_coords = sco = MEM_mallocN(bm->totvert * sizeof(float) * 2, __func__);
BM_ITER_MESH_INDEX (bv, &iter, bm, BM_VERTS_OF_MESH, i) {
- if (ED_view3d_project_float_object(ar, bv->co, *sco, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_float_object(ar, bv->co, *sco, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) {
copy_v2_fl(*sco, FLT_MAX); /* set error value */
}
BM_elem_index_set(bv, i); /* set_ok */
@@ -3078,7 +3131,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
}
else {
if (type == 0) {
- BKE_report(op->reports, RPT_ERROR, "Selecton not supported in object mode");
+ BKE_report(op->reports, RPT_ERROR, "Selection not supported in object mode");
return OPERATOR_CANCELLED;
}
@@ -3542,7 +3595,7 @@ void MESH_OT_spin(wmOperatorType *ot)
RNA_def_float(ot->srna, "degrees", 90.0f, -FLT_MAX, FLT_MAX, "Degrees", "Degrees", -360.0f, 360.0f);
RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX);
- RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX);
+ RNA_def_float_vector(ot->srna, "axis", 3, NULL, -FLT_MAX, FLT_MAX, "Axis", "Axis in global view space", -1.0f, 1.0f);
}
@@ -3666,8 +3719,8 @@ void MESH_OT_screw(wmOperatorType *ot)
RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX,
"Center", "Center in global view space", -FLT_MAX, FLT_MAX);
- RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f,
- "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX);
+ RNA_def_float_vector(ot->srna, "axis", 3, NULL, -FLT_MAX, FLT_MAX,
+ "Axis", "Axis in global view space", -1.0f, 1.0f);
}
static int edbm_select_by_number_vertices_exec(bContext *C, wmOperator *op)
@@ -3851,8 +3904,8 @@ static void sort_bmelem_flag(Scene *scene, Object *ob,
char *pblock[3] = {NULL, NULL, NULL}, *pb;
BMElemSort *sblock[3] = {NULL, NULL, NULL}, *sb;
int *map[3] = {NULL, NULL, NULL}, *mp;
- int totelem[3] = {0, 0, 0}, tot;
- int affected[3] = {0, 0, 0}, aff;
+ int totelem[3] = {0, 0, 0};
+ int affected[3] = {0, 0, 0};
int i, j;
if (!(types && flag && action))
@@ -4227,8 +4280,8 @@ static void sort_bmelem_flag(Scene *scene, Object *ob,
if (pb && sb && !map[j]) {
char *p_blk;
BMElemSort *s_blk;
- tot = totelem[j];
- aff = affected[j];
+ int tot = totelem[j];
+ int aff = affected[j];
qsort(sb, aff, sizeof(BMElemSort), bmelemsort_comp);
@@ -4277,7 +4330,7 @@ static int edbm_sort_elements_exec(bContext *C, wmOperator *op)
if (ELEM(action, SRT_VIEW_ZAXIS, SRT_VIEW_XAXIS)) {
if (rv3d == NULL) {
- BKE_report(op->reports, RPT_ERROR, "View not found, can't sort by view axis");
+ BKE_report(op->reports, RPT_ERROR, "View not found, cannot sort by view axis");
return OPERATOR_CANCELLED;
}
}
@@ -4465,6 +4518,7 @@ typedef struct {
int li;
int mcenter[2];
float initial_length;
+ float pixel_size; /* use when mouse input is interpreted as spatial distance */
int is_modal;
NumInput num_input;
float shift_factor; /* The current factor when shift is pressed. Negative when shift not active. */
@@ -4662,8 +4716,10 @@ static int edbm_bevel_exec(bContext *C, wmOperator *op)
static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
/* TODO make modal keymap (see fly mode) */
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
BevelData *opdata;
float mlen[2];
+ float center_3d[3];
if (!edbm_bevel_init(C, op, TRUE)) {
return OPERATOR_CANCELLED;
@@ -4672,7 +4728,7 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event)
opdata = op->customdata;
/* initialize mouse values */
- if (!calculateTransformCenter(C, V3D_CENTROID, NULL, opdata->mcenter)) {
+ if (!calculateTransformCenter(C, V3D_CENTROID, center_3d, opdata->mcenter)) {
/* in this case the tool will likely do nothing,
* ideally this will never happen and should be checked for above */
opdata->mcenter[0] = opdata->mcenter[1] = 0;
@@ -4680,6 +4736,7 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event)
mlen[0] = opdata->mcenter[0] - event->mval[0];
mlen[1] = opdata->mcenter[1] - event->mval[1];
opdata->initial_length = len_v2(mlen);
+ opdata->pixel_size = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f;
edbm_bevel_update_header(op, C);
@@ -4693,6 +4750,44 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
+static float edbm_bevel_mval_factor(wmOperator *op, wmEvent *event)
+{
+ BevelData *opdata = op->customdata;
+ int use_dist = RNA_boolean_get(op->ptr, "use_dist");
+ float mdiff[2];
+ float factor;
+
+ mdiff[0] = opdata->mcenter[0] - event->mval[0];
+ mdiff[1] = opdata->mcenter[1] - event->mval[1];
+
+ if (use_dist) {
+ factor = ((len_v2(mdiff) - MVAL_PIXEL_MARGIN) - opdata->initial_length) * opdata->pixel_size;
+ }
+ else {
+ factor = (len_v2(mdiff) - MVAL_PIXEL_MARGIN) / opdata->initial_length;
+ factor = factor - 1.0f; /* a different kind of buffer where nothing happens */
+ }
+
+ /* Fake shift-transform... */
+ if (event->shift) {
+ if (opdata->shift_factor < 0.0f)
+ opdata->shift_factor = RNA_float_get(op->ptr, "percent");
+ factor = (factor - opdata->shift_factor) * 0.1f + opdata->shift_factor;
+ }
+ else if (opdata->shift_factor >= 0.0f)
+ opdata->shift_factor = -1.0f;
+
+ /* clamp differently based on distance/factor */
+ if (use_dist) {
+ if (factor < 0.0f) factor = 0.0f;
+ }
+ else {
+ CLAMP(factor, 0.0f, 1.0f);
+ }
+
+ return factor;
+}
+
static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
{
BevelData *opdata = op->customdata;
@@ -4720,25 +4815,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
case MOUSEMOVE:
if (!hasNumInput(&opdata->num_input)) {
- float factor;
- float mdiff[2];
-
- mdiff[0] = opdata->mcenter[0] - event->mval[0];
- mdiff[1] = opdata->mcenter[1] - event->mval[1];
-
- factor = opdata->initial_length / -len_v2(mdiff) + 1.0f;
-
- /* Fake shift-transform... */
- if (event->shift) {
- if (opdata->shift_factor < 0.0f)
- opdata->shift_factor = RNA_float_get(op->ptr, "percent");
- factor = (factor - opdata->shift_factor) * 0.1f + opdata->shift_factor;
- }
- else if (opdata->shift_factor >= 0.0f)
- opdata->shift_factor = -1.0f;
-
- CLAMP(factor, 0.0f, 1.0f);
-
+ const float factor = edbm_bevel_mval_factor(op, event);
RNA_float_set(op->ptr, "percent", factor);
edbm_bevel_calc(C, op);
@@ -4768,6 +4845,11 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
int use_dist = RNA_boolean_get(op->ptr, "use_dist");
RNA_boolean_set(op->ptr, "use_dist", !use_dist);
+ {
+ const float factor = edbm_bevel_mval_factor(op, event);
+ RNA_float_set(op->ptr, "percent", factor);
+ }
+
edbm_bevel_calc(C, op);
edbm_bevel_update_header(op, C);
}
@@ -4794,6 +4876,7 @@ void MESH_OT_bevel(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_POINTER | OPTYPE_BLOCKING;
+ /* take note, used as a factor _and_ a distance depending on 'use_dist' */
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); */
@@ -4858,8 +4941,9 @@ typedef struct {
float old_depth;
int mcenter[2];
int modify_depth;
- int is_modal;
float initial_length;
+ float pixel_size; /* use when mouse input is interpreted as spatial distance */
+ int is_modal;
int shift;
float shift_amount;
BMBackup backup;
@@ -5025,15 +5109,17 @@ static int edbm_inset_exec(bContext *C, wmOperator *op)
static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
InsetData *opdata;
float mlen[2];
+ float center_3d[3];
edbm_inset_init(C, op, TRUE);
opdata = op->customdata;
/* initialize mouse values */
- if (!calculateTransformCenter(C, V3D_CENTROID, NULL, opdata->mcenter)) {
+ if (!calculateTransformCenter(C, V3D_CENTROID, center_3d, opdata->mcenter)) {
/* in this case the tool will likely do nothing,
* ideally this will never happen and should be checked for above */
opdata->mcenter[0] = opdata->mcenter[1] = 0;
@@ -5041,6 +5127,7 @@ static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event)
mlen[0] = opdata->mcenter[0] - event->mval[0];
mlen[1] = opdata->mcenter[1] - event->mval[1];
opdata->initial_length = len_v2(mlen);
+ opdata->pixel_size = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f;
edbm_inset_calc(C, op);
@@ -5090,9 +5177,9 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event)
mdiff[1] = opdata->mcenter[1] - event->mval[1];
if (opdata->modify_depth)
- amount = opdata->old_depth + opdata->initial_length / len_v2(mdiff) - 1.0f;
+ amount = opdata->old_depth + ((len_v2(mdiff) - opdata->initial_length) * opdata->pixel_size);
else
- amount = opdata->old_thickness - opdata->initial_length / len_v2(mdiff) + 1.0f;
+ amount = opdata->old_thickness - ((len_v2(mdiff) - opdata->initial_length) * opdata->pixel_size);
/* Fake shift-transform... */
if (opdata->shift)
@@ -5393,6 +5480,57 @@ void MESH_OT_convex_hull(wmOperatorType *ot)
join_triangle_props(ot);
}
+static int mesh_symmetrize_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BMEdit_FromObject(obedit);
+ BMOperator bmop;
+
+ EDBM_op_init(em, &bmop, op, "symmetrize input=%hvef direction=%i",
+ BM_ELEM_SELECT, RNA_enum_get(op->ptr, "direction"));
+ BMO_op_exec(em->bm, &bmop);
+
+ if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ EDBM_update_generic(C, em, TRUE);
+ EDBM_selectmode_flush(em);
+ return OPERATOR_FINISHED;
+ }
+}
+
+void MESH_OT_symmetrize(struct wmOperatorType *ot)
+{
+ static EnumPropertyItem axis_direction_items[] = {
+ {BMO_SYMMETRIZE_NEGATIVE_X, "NEGATIVE_X", 0, "-X to +X", ""},
+ {BMO_SYMMETRIZE_POSITIVE_X, "POSITIVE_X", 0, "+X to -X", ""},
+
+ {BMO_SYMMETRIZE_NEGATIVE_Y, "NEGATIVE_Y", 0, "-Y to +Y", ""},
+ {BMO_SYMMETRIZE_POSITIVE_Y, "POSITIVE_Y", 0, "+Y to -Y", ""},
+
+ {BMO_SYMMETRIZE_NEGATIVE_Z, "NEGATIVE_Z", 0, "-Z to +Z", ""},
+ {BMO_SYMMETRIZE_POSITIVE_Z, "POSITIVE_Z", 0, "+Z to -Z", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ /* identifiers */
+ ot->name = "Symmetrize";
+ ot->description = "Enforce symmetry (both form and topological) across an axis";
+ ot->idname = "MESH_OT_symmetrize";
+
+ /* api callbacks */
+ ot->exec = mesh_symmetrize_exec;
+ ot->poll = ED_operator_editmesh;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ ot->prop = RNA_def_enum(ot->srna, "direction", axis_direction_items,
+ BMO_SYMMETRIZE_NEGATIVE_X,
+ "Direction", "Which sides to copy from and to");
+}
+
static int edbm_mark_freestyle_edge(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 735492cb553..4adf37a14c3 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -593,7 +593,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
/* Check context */
if (base == NULL || base->object->type != OB_MESH) {
- BKE_report(op->reports, RPT_ERROR, "Not an Object or Mesh");
+ BKE_report(op->reports, RPT_ERROR, "Not an object or mesh");
return OPERATOR_CANCELLED;
}
@@ -610,7 +610,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
if (!ima) {
- BKE_report(op->reports, RPT_ERROR, "Not an Image");
+ BKE_report(op->reports, RPT_ERROR, "Not an image");
return OPERATOR_CANCELLED;
}
@@ -1124,7 +1124,7 @@ static void mesh_remove_faces(Mesh *mesh, int len)
void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges, int faces)
{
if (mesh->edit_btmesh) {
- BKE_report(reports, RPT_ERROR, "Can't add geometry in edit mode");
+ BKE_report(reports, RPT_ERROR, "Cannot add geometry in edit mode");
return;
}
@@ -1140,12 +1140,12 @@ void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges,
void ED_mesh_tessfaces_add(Mesh *mesh, ReportList *reports, int count)
{
if (mesh->edit_btmesh) {
- BKE_report(reports, RPT_ERROR, "Can't add tessfaces in edit mode");
+ BKE_report(reports, RPT_ERROR, "Cannot add tessfaces in edit mode");
return;
}
if (mesh->mpoly) {
- BKE_report(reports, RPT_ERROR, "Can't add tessfaces to a mesh that already has polygons");
+ BKE_report(reports, RPT_ERROR, "Cannot add tessfaces to a mesh that already has polygons");
return;
}
@@ -1155,7 +1155,7 @@ void ED_mesh_tessfaces_add(Mesh *mesh, ReportList *reports, int count)
void ED_mesh_edges_add(Mesh *mesh, ReportList *reports, int count)
{
if (mesh->edit_btmesh) {
- BKE_report(reports, RPT_ERROR, "Can't add edges in edit mode");
+ BKE_report(reports, RPT_ERROR, "Cannot add edges in edit mode");
return;
}
@@ -1165,7 +1165,7 @@ void ED_mesh_edges_add(Mesh *mesh, ReportList *reports, int count)
void ED_mesh_vertices_add(Mesh *mesh, ReportList *reports, int count)
{
if (mesh->edit_btmesh) {
- BKE_report(reports, RPT_ERROR, "Can't add vertices in edit mode");
+ BKE_report(reports, RPT_ERROR, "Cannot add vertices in edit mode");
return;
}
@@ -1175,11 +1175,11 @@ void ED_mesh_vertices_add(Mesh *mesh, ReportList *reports, int count)
void ED_mesh_faces_remove(Mesh *mesh, ReportList *reports, int count)
{
if (mesh->edit_btmesh) {
- BKE_report(reports, RPT_ERROR, "Can't remove faces in edit mode");
+ BKE_report(reports, RPT_ERROR, "Cannot remove faces in edit mode");
return;
}
else if (count > mesh->totface) {
- BKE_report(reports, RPT_ERROR, "Can't remove more faces than the mesh contains");
+ BKE_report(reports, RPT_ERROR, "Cannot remove more faces than the mesh contains");
return;
}
@@ -1189,11 +1189,11 @@ void ED_mesh_faces_remove(Mesh *mesh, ReportList *reports, int count)
void ED_mesh_edges_remove(Mesh *mesh, ReportList *reports, int count)
{
if (mesh->edit_btmesh) {
- BKE_report(reports, RPT_ERROR, "Can't remove edges in edit mode");
+ BKE_report(reports, RPT_ERROR, "Cannot remove edges in edit mode");
return;
}
else if (count > mesh->totedge) {
- BKE_report(reports, RPT_ERROR, "Can't remove more edges than the mesh contains");
+ BKE_report(reports, RPT_ERROR, "Cannot remove more edges than the mesh contains");
return;
}
@@ -1203,11 +1203,11 @@ void ED_mesh_edges_remove(Mesh *mesh, ReportList *reports, int count)
void ED_mesh_vertices_remove(Mesh *mesh, ReportList *reports, int count)
{
if (mesh->edit_btmesh) {
- BKE_report(reports, RPT_ERROR, "Can't remove vertices in edit mode");
+ BKE_report(reports, RPT_ERROR, "Cannot remove vertices in edit mode");
return;
}
else if (count > mesh->totvert) {
- BKE_report(reports, RPT_ERROR, "Can't remove more vertices than the mesh contains");
+ BKE_report(reports, RPT_ERROR, "Cannot remove more vertices than the mesh contains");
return;
}
@@ -1217,7 +1217,7 @@ void ED_mesh_vertices_remove(Mesh *mesh, ReportList *reports, int count)
void ED_mesh_loops_add(Mesh *mesh, ReportList *reports, int count)
{
if (mesh->edit_btmesh) {
- BKE_report(reports, RPT_ERROR, "Can't add loops in edit mode.");
+ BKE_report(reports, RPT_ERROR, "Cannot add loops in edit mode");
return;
}
@@ -1227,7 +1227,7 @@ void ED_mesh_loops_add(Mesh *mesh, ReportList *reports, int count)
void ED_mesh_polys_add(Mesh *mesh, ReportList *reports, int count)
{
if (mesh->edit_btmesh) {
- BKE_report(reports, RPT_ERROR, "Can't add polys in edit mode.");
+ BKE_report(reports, RPT_ERROR, "Cannot add polygons in edit mode");
return;
}
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index b68c1836992..835b1ccd52d 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -145,6 +145,7 @@ extern struct EnumPropertyItem *corner_type_items;
void MESH_OT_merge(struct wmOperatorType *ot);
void MESH_OT_subdivide(struct wmOperatorType *ot);
+void MESH_OT_unsubdivide(struct wmOperatorType *ot);
void MESH_OT_remove_doubles(struct wmOperatorType *ot);
void MESH_OT_spin(struct wmOperatorType *ot);
void MESH_OT_screw(struct wmOperatorType *ot);
@@ -216,6 +217,8 @@ void MESH_OT_vert_slide(struct wmOperatorType *ot);
void MESH_OT_convex_hull(struct wmOperatorType *ot);
+void MESH_OT_symmetrize(struct wmOperatorType *ot);
+
/* ******************* mesh_navmesh.c */
void MESH_OT_navmesh_make(struct wmOperatorType *ot);
void MESH_OT_navmesh_face_copy(struct wmOperatorType *ot);
@@ -223,5 +226,4 @@ void MESH_OT_navmesh_face_add(struct wmOperatorType *ot);
void MESH_OT_navmesh_reset(struct wmOperatorType *ot);
void MESH_OT_navmesh_clear(struct wmOperatorType *ot);
-#endif // __MESH_INTERN_H__
-
+#endif /* __MESH_INTERN_H__ */
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index ccf91958e08..d06142d2654 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -74,6 +74,7 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_normals_make_consistent);
WM_operatortype_append(MESH_OT_merge);
WM_operatortype_append(MESH_OT_subdivide);
+ WM_operatortype_append(MESH_OT_unsubdivide);
WM_operatortype_append(MESH_OT_faces_select_linked_flat);
WM_operatortype_append(MESH_OT_edges_select_sharp);
WM_operatortype_append(MESH_OT_primitive_plane_add);
@@ -168,6 +169,8 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_convex_hull);
+ WM_operatortype_append(MESH_OT_symmetrize);
+
#ifdef WITH_GAMEENGINE
WM_operatortype_append(MESH_OT_navmesh_make);
WM_operatortype_append(MESH_OT_navmesh_face_copy);
@@ -211,7 +214,17 @@ void ED_operatormacros_mesh(void)
ot = WM_operatortype_append_macro("MESH_OT_rip_move", "Rip", "Rip polygons and move the result",
OPTYPE_UNDO | OPTYPE_REGISTER);
- WM_operatortype_macro_define(ot, "MESH_OT_rip");
+ otmacro = WM_operatortype_macro_define(ot, "MESH_OT_rip");
+ RNA_boolean_set(otmacro->ptr, "use_fill", FALSE);
+ otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
+ RNA_enum_set(otmacro->ptr, "proportional", 0);
+ RNA_boolean_set(otmacro->ptr, "mirror", FALSE);
+
+ /* annoying we can't pass 'use_fill' through the macro */
+ ot = WM_operatortype_append_macro("MESH_OT_rip_move_fill", "Rip Fill", "Rip-fill polygons and move the result",
+ OPTYPE_UNDO | OPTYPE_REGISTER);
+ otmacro = WM_operatortype_macro_define(ot, "MESH_OT_rip");
+ RNA_boolean_set(otmacro->ptr, "use_fill", TRUE);
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
RNA_enum_set(otmacro->ptr, "proportional", 0);
RNA_boolean_set(otmacro->ptr, "mirror", FALSE);
@@ -326,6 +339,8 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "MESH_OT_tris_convert_to_quads", JKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "MESH_OT_rip_move", VKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_rip_move_fill", VKEY, KM_PRESS, KM_ALT, 0);
+
WM_keymap_add_item(keymap, "MESH_OT_merge", MKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "TRANSFORM_OT_shrink_fatten", SKEY, KM_PRESS, KM_ALT, 0);
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 42d82fff38e..d8793505608 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -113,7 +113,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
CustomData vdata, edata, fdata, ldata, pdata;
if (scene->obedit) {
- BKE_report(op->reports, RPT_WARNING, "Cant join while in editmode");
+ BKE_report(op->reports, RPT_WARNING, "Cannot join while in editmode");
return OPERATOR_CANCELLED;
}
@@ -161,8 +161,8 @@ int join_mesh_exec(bContext *C, wmOperator *op)
}
if (totvert > MESH_MAX_VERTS) {
- BKE_reportf(op->reports, RPT_WARNING, "Joining results in %d vertices, limit is " STRINGIFY(MESH_MAX_VERTS), totvert);
- return OPERATOR_CANCELLED;
+ BKE_reportf(op->reports, RPT_WARNING, "Joining results in %d vertices, limit is %ld", totvert, MESH_MAX_VERTS);
+ return OPERATOR_CANCELLED;
}
/* new material indices and material array */
@@ -1192,7 +1192,7 @@ int ED_mesh_pick_face(bContext *C, Mesh *me, const int mval[2], unsigned int *in
/* sample rect to increase chances of selecting, so that when clicking
* on an edge in the backbuf, we can still select a face */
- int dummy_dist;
+ float dummy_dist;
*index = view3d_sample_backbuf_rect(&vc, mval, size, 1, me->totpoly + 1, &dummy_dist, 0, NULL, NULL);
}
else {
@@ -1237,7 +1237,7 @@ int ED_mesh_pick_face_vert(bContext *C, Mesh *me, Object *ob, const int mval[2],
const int v_idx = me->mloop[mp->loopstart + fidx].v;
dm->getVertCo(dm, v_idx, co);
mul_m4_v3(ob->obmat, co);
- if (ED_view3d_project_float_global(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_float_global(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
len = len_squared_v2v2(mval_f, sco);
if (len < len_best) {
len_best = len;
@@ -1277,7 +1277,7 @@ int ED_mesh_pick_vert(bContext *C, Mesh *me, const int mval[2], unsigned int *in
/* sample rect to increase chances of selecting, so that when clicking
* on an face in the backbuf, we can still select a vert */
- int dummy_dist;
+ float dummy_dist;
*index = view3d_sample_backbuf_rect(&vc, mval, size, 1, me->totvert + 1, &dummy_dist, 0, NULL, NULL);
}
else {
diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c
index e9063687506..b9018914633 100644
--- a/source/blender/editors/metaball/mball_edit.c
+++ b/source/blender/editors/metaball/mball_edit.c
@@ -98,7 +98,7 @@ void load_editMball(Object *UNUSED(obedit))
}
/* Add metaelem primitive to metaball object (which is in edit mode) */
-MetaElem *add_metaball_primitive(bContext *UNUSED(C), Object *obedit, float mat[4][4], int type, int UNUSED(newname))
+MetaElem *add_metaball_primitive(bContext *UNUSED(C), Object *obedit, float mat[4][4], float dia, int type, int UNUSED(newname))
{
MetaBall *mball = (MetaBall *)obedit->data;
MetaElem *ml;
@@ -111,6 +111,7 @@ MetaElem *add_metaball_primitive(bContext *UNUSED(C), Object *obedit, float mat[
}
ml = BKE_mball_element_add(mball, type);
+ ml->rad *= dia;
copy_v3_v3(&ml->x, mat[3]);
ml->flag |= SELECT;
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 43a32cd662e..9a2915a5d55 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -136,6 +136,7 @@ static EnumPropertyItem field_type_items[] = {
{PFIELD_BOID, "BOID", ICON_FORCE_BOID, "Boid", ""},
{PFIELD_TURBULENCE, "TURBULENCE", ICON_FORCE_TURBULENCE, "Turbulence", ""},
{PFIELD_DRAG, "DRAG", ICON_FORCE_DRAG, "Drag", ""},
+ {PFIELD_SMOKEFLOW, "SMOKE", ICON_FORCE_SMOKEFLOW, "Smoke Flow", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -185,7 +186,8 @@ void ED_object_base_init_transform(bContext *C, Base *base, const float loc[3],
/* Uses context to figure out transform for primitive.
* Returns standard diameter. */
float ED_object_new_primitive_matrix(bContext *C, Object *obedit,
- const float loc[3], const float rot[3], float primmat[][4])
+ const float loc[3], const float rot[3], float primmat[][4],
+ int apply_diameter)
{
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -208,8 +210,17 @@ float ED_object_new_primitive_matrix(bContext *C, Object *obedit,
invert_m3_m3(imat, mat);
mul_m3_v3(imat, primmat[3]);
- if (v3d)
- return ED_view3d_grid_scale(scene, v3d, NULL);
+ if (v3d) {
+ float dia = ED_view3d_grid_scale(scene, v3d, NULL);
+
+ if (apply_diameter) {
+ primmat[0][0] *= dia;
+ primmat[1][1] *= dia;
+ primmat[2][2] *= dia;
+ }
+
+ return dia;
+ }
return 1.0f;
}
@@ -356,7 +367,7 @@ Object *ED_object_add_type(bContext *C, int type, const float loc[3], const floa
Scene *scene = CTX_data_scene(C);
Object *ob;
- /* For as long scene has editmode... */
+ /* for as long scene has editmode... */
if (CTX_data_edit_object(C))
ED_object_exit_editmode(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); /* freedata, and undo */
@@ -441,7 +452,7 @@ static int effector_add_exec(bContext *C, wmOperator *op)
rename_id(&ob->id, "CurveGuide");
((Curve *)ob->data)->flag |= CU_PATH | CU_3D;
ED_object_enter_editmode(C, 0);
- ED_object_new_primitive_matrix(C, ob, loc, rot, mat);
+ ED_object_new_primitive_matrix(C, ob, loc, rot, mat, FALSE);
BLI_addtail(object_editcurve_get(ob), add_nurbs_primitive(C, ob, mat, CU_NURBS | CU_PRIM_PATH, 1));
if (!enter_editmode)
ED_object_exit_editmode(C, EM_FREEDATA);
@@ -546,6 +557,7 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op)
unsigned int layer;
float loc[3], rot[3];
float mat[4][4];
+ float dia;
if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL))
return OPERATOR_CANCELLED;
@@ -557,9 +569,9 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op)
else
DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
- ED_object_new_primitive_matrix(C, obedit, loc, rot, mat);
+ dia = ED_object_new_primitive_matrix(C, obedit, loc, rot, mat, FALSE);
- add_metaball_primitive(C, obedit, mat, RNA_enum_get(op->ptr, "type"), newob);
+ add_metaball_primitive(C, obedit, mat, dia, RNA_enum_get(op->ptr, "type"), newob);
/* userdef */
if (newob && !enter_editmode) {
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index 6d124377821..bc5d289d04c 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -900,7 +900,7 @@ static void finish_images(MultiresBakeRender *bkr)
RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, bkr->bake_filter);
- ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID;;
+ ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID;
if (ibuf->rect_float)
ibuf->userflags |= IB_RECT_INVALID;
@@ -937,7 +937,7 @@ static int multiresbake_check(bContext *C, wmOperator *op)
ob = base->object;
if (ob->type != OB_MESH) {
- BKE_report(op->reports, RPT_ERROR, "Basking of multires data only works with active object which is a mesh");
+ BKE_report(op->reports, RPT_ERROR, "Baking of multires data only works with an active mesh object");
ok = 0;
break;
@@ -985,7 +985,7 @@ static int multiresbake_check(bContext *C, wmOperator *op)
ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
if (!ibuf) {
- BKE_report(op->reports, RPT_ERROR, "Baking should happend to image with image buffer");
+ BKE_report(op->reports, RPT_ERROR, "Baking should happen to image with image buffer");
ok = 0;
}
@@ -1366,20 +1366,23 @@ static void finish_bake_internal(BakeRender *bkr)
if (bkr->prev_r_raytrace == 0)
bkr->scene->r.mode &= ~R_RAYTRACE;
-
/* force OpenGL reload and mipmap recalc */
for (ima = G.main->image.first; ima; ima = ima->id.next) {
ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
- if (bkr->result == BAKE_RESULT_OK) {
- if (ima->ok == IMA_OK_LOADED) {
- if (ibuf) {
- if (ibuf->userflags & IB_BITMAPDIRTY) {
- ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
- GPU_free_image(ima);
- imb_freemipmapImBuf(ibuf);
- }
+ /* some of the images could have been changed during bake,
+ * so recreate mipmaps regardless bake result status
+ */
+ if (ima->ok == IMA_OK_LOADED) {
+ if (ibuf) {
+ if (ibuf->userflags & IB_BITMAPDIRTY) {
+ GPU_free_image(ima);
+ imb_freemipmapImBuf(ibuf);
}
+
+ /* invalidate display buffers for changed images */
+ if (ibuf->userflags & IB_BITMAPDIRTY)
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
}
}
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 56f2426b1b0..80993d6cca7 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -853,7 +853,7 @@ static int childof_clear_inverse_exec(bContext *C, wmOperator *op)
bChildOfConstraint *data = (con) ? (bChildOfConstraint *)con->data : NULL;
if (data == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Childof constraint not found");
+ BKE_report(op->reports, RPT_ERROR, "Child Of constraint not found");
return OPERATOR_CANCELLED;
}
@@ -1073,7 +1073,7 @@ static int objectsolver_clear_inverse_exec(bContext *C, wmOperator *op)
bObjectSolverConstraint *data = (con) ? (bObjectSolverConstraint *)con->data : NULL;
if (data == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Childof constraint not found");
+ BKE_report(op->reports, RPT_ERROR, "Child Of constraint not found");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c
index a6afe6b2d04..8bc249974f2 100644
--- a/source/blender/editors/object/object_hook.c
+++ b/source/blender/editors/object/object_hook.c
@@ -442,7 +442,7 @@ static int add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob
ok = object_hook_index_array(scene, obedit, &tot, &indexar, name, cent);
if (!ok) {
- BKE_report(reports, RPT_ERROR, "Requires selected vertices or active Vertex Group");
+ BKE_report(reports, RPT_ERROR, "Requires selected vertices or active vertex group");
return FALSE;
}
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 4c83f6ef2ce..0be9c92897e 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -138,6 +138,7 @@ void OBJECT_OT_hook_recenter(struct wmOperatorType *ot);
/* object_lattice.c */
void LATTICE_OT_select_all(struct wmOperatorType *ot);
void LATTICE_OT_make_regular(struct wmOperatorType *ot);
+void LATTICE_OT_flip(struct wmOperatorType *ot);
/* object_group.c */
void GROUP_OT_create(struct wmOperatorType *ot);
@@ -204,6 +205,7 @@ void OBJECT_OT_vertex_group_remove_from(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_select(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_deselect(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_copy_to_linked(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_transfer_weight(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_copy_to_selected(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_normalize(struct wmOperatorType *ot);
@@ -214,6 +216,7 @@ void OBJECT_OT_vertex_group_fix(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_invert(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_blend(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_clean(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_limit_total(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_mirror(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_set_active(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_sort(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c
index 1f7be0bf9a6..ac9c4f7adee 100644
--- a/source/blender/editors/object/object_lattice.c
+++ b/source/blender/editors/object/object_lattice.c
@@ -46,6 +46,7 @@
#include "DNA_scene_types.h"
#include "RNA_access.h"
+#include "RNA_define.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
@@ -167,7 +168,7 @@ void load_editLatt(Object *obedit)
}
}
-/************************** Operators *************************/
+/************************** Select All Operator *************************/
void ED_setflagsLatt(Object *obedit, int flag)
{
@@ -254,6 +255,8 @@ void LATTICE_OT_select_all(wmOperatorType *ot)
WM_operator_properties_select_all(ot);
}
+/************************** Make Regular Operator *************************/
+
static int make_regular_poll(bContext *C)
{
Object *ob;
@@ -300,18 +303,265 @@ void LATTICE_OT_make_regular(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/************************** Flip Verts Operator *************************/
+
+/* flipping options */
+typedef enum eLattice_FlipAxes {
+ LATTICE_FLIP_U = 0,
+ LATTICE_FLIP_V = 1,
+ LATTICE_FLIP_W = 2
+} eLattice_FlipAxes;
+
+/* Helper macro for accessing item at index (u, v, w)
+ * < lt: (Lattice)
+ * < U: (int) u-axis coordinate of point
+ * < V: (int) v-axis coordinate of point
+ * < W: (int) w-axis coordinate of point
+ * < dimU: (int) number of points per row or number of columns (U-Axis)
+ * < dimV: (int) number of rows (V-Axis)
+ * > returns: (BPoint *) pointer to BPoint at this index
+ */
+#define LATTICE_PT(lt, U, V, W, dimU, dimV) \
+ ( (lt)->def + \
+ ((dimU) * (dimV)) * (W) + \
+ (dimU) * (V) + \
+ (U) \
+ )
+
+/* Flip midpoint value so that relative distances between midpoint and neighbour-pair is maintained
+ * ! Assumes that uvw <=> xyz (i.e. axis-aligned index-axes with coordinate-axes)
+ * - Helper for lattice_flip_exec()
+ */
+static void lattice_flip_point_value(Lattice *lt, int u, int v, int w, float mid, eLattice_FlipAxes axis)
+{
+ BPoint *bp;
+ float diff;
+
+ /* just the point in the middle (unpaired) */
+ bp = LATTICE_PT(lt, u, v, w, lt->pntsu, lt->pntsv);
+
+ /* flip over axis */
+ diff = mid - bp->vec[axis];
+ bp->vec[axis] = mid + diff;
+}
+
+/* Swap pairs of lattice points along a specified axis
+ * - Helper for lattice_flip_exec()
+ */
+static void lattice_swap_point_pairs(Lattice *lt, int u, int v, int w, float mid, eLattice_FlipAxes axis)
+{
+ BPoint *bpA, *bpB;
+
+ int numU = lt->pntsu;
+ int numV = lt->pntsv;
+ int numW = lt->pntsw;
+
+ int u0 = u, u1 = u;
+ int v0 = v, v1 = v;
+ int w0 = w, w1 = w;
+
+ /* get pair index by just overriding the relevant pair-value
+ * - "-1" else buffer overflow
+ */
+ switch (axis) {
+ case LATTICE_FLIP_U:
+ u1 = numU - u - 1;
+ break;
+ case LATTICE_FLIP_V:
+ v1 = numV - v - 1;
+ break;
+ case LATTICE_FLIP_W:
+ w1 = numW - w - 1;
+ break;
+ }
+
+ /* get points to operate on */
+ bpA = LATTICE_PT(lt, u0, v0, w0, numU, numV);
+ bpB = LATTICE_PT(lt, u1, v1, w1, numU, numV);
+
+ /* Swap all coordinates, so that flipped coordinates belong to
+ * the indices on the correct side of the lattice.
+ *
+ * Coords: (-2 4) |0| (3 4) --> (3 4) |0| (-2 4)
+ * Indices: (0,L) (1,R) --> (0,L) (1,R)
+ */
+ swap_v3_v3(bpA->vec, bpB->vec);
+
+ /* However, we need to mirror the coordinate values on the axis we're dealing with,
+ * otherwise we'd have effectively only rotated the points around. If we don't do this,
+ * we'd just be reimplementing the naive mirroring algorithm, which causes unwanted deforms
+ * such as flipped normals, etc.
+ *
+ * Coords: (3 4) |0| (-2 4) --\
+ * \-> (-3 4) |0| (2 4)
+ * Indices: (0,L) (1,R) --> (0,L) (1,R)
+ */
+ lattice_flip_point_value(lt, u0, v0, w0, mid, axis);
+ lattice_flip_point_value(lt, u1, v1, w1, mid, axis);
+}
+
+static int lattice_flip_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ Lattice *lt;
+
+ eLattice_FlipAxes axis = RNA_enum_get(op->ptr, "axis");
+ int numU, numV, numW;
+ int totP;
+
+ float mid = 0.0f;
+ short isOdd = 0;
+
+ /* get lattice - we need the "edit lattice" from the lattice... confusing... */
+ lt = (Lattice *)obedit->data;
+ lt = lt->editlatt->latt;
+
+ numU = lt->pntsu;
+ numV = lt->pntsv;
+ numW = lt->pntsw;
+ totP = numU * numV * numW;
+
+ /* First Pass: determine midpoint - used for flipping center verts if there are odd number of points on axis */
+ switch (axis) {
+ case LATTICE_FLIP_U:
+ isOdd = numU & 1;
+ break;
+ case LATTICE_FLIP_V:
+ isOdd = numV & 1;
+ break;
+ case LATTICE_FLIP_W:
+ isOdd = numW & 1;
+ break;
+
+ default:
+ printf("lattice_flip(): Unknown flipping axis (%d)\n", axis);
+ return OPERATOR_CANCELLED;
+ }
+
+ if (isOdd) {
+ BPoint *bp;
+ float avgInv = 1.0f / (float)totP;
+ int i;
+
+ /* midpoint calculation - assuming that u/v/w are axis-aligned */
+ for (i = 0, bp = lt->def; i < totP; i++, bp++) {
+ mid += bp->vec[axis] * avgInv;
+ }
+ }
+
+ /* Second Pass: swap pairs of vertices per axis, assuming they are all sorted */
+ switch (axis) {
+ case LATTICE_FLIP_U:
+ {
+ int u, v, w;
+
+ /* v/w strips - front to back, top to bottom */
+ for (w = 0; w < numW; w++) {
+ for (v = 0; v < numV; v++) {
+ /* swap coordinates of pairs of vertices on u */
+ for (u = 0; u < (numU / 2); u++) {
+ lattice_swap_point_pairs(lt, u, v, w, mid, axis);
+ }
+
+ /* flip u-coordinate of midpoint (i.e. unpaired point on u) */
+ if (isOdd) {
+ u = (numU / 2);
+ lattice_flip_point_value(lt, u, v, w, mid, axis);
+ }
+ }
+ }
+ }
+ break;
+ case LATTICE_FLIP_V:
+ {
+ int u, v, w;
+
+ /* u/w strips - front to back, left to right */
+ for (w = 0; w < numW; w++) {
+ for (u = 0; u < numU; u++) {
+ /* swap coordinates of pairs of vertices on v */
+ for (v = 0; v < (numV / 2); v++) {
+ lattice_swap_point_pairs(lt, u, v, w, mid, axis);
+ }
+
+ /* flip v-coordinate of midpoint (i.e. unpaired point on v) */
+ if (isOdd) {
+ v = (numV / 2);
+ lattice_flip_point_value(lt, u, v, w, mid, axis);
+ }
+ }
+ }
+ }
+ break;
+ case LATTICE_FLIP_W:
+ {
+ int u, v, w;
+
+ for (v = 0; v < numV; v++) {
+ for (u = 0; u < numU; u++) {
+ /* swap coordinates of pairs of vertices on w */
+ for (w = 0; w < (numW / 2); w++) {
+ lattice_swap_point_pairs(lt, u, v, w, mid, axis);
+ }
+
+ /* flip w-coordinate of midpoint (i.e. unpaired point on w) */
+ if (isOdd) {
+ w = (numW / 2);
+ lattice_flip_point_value(lt, u, v, w, mid, axis);
+ }
+ }
+ }
+ }
+ break;
+
+ default: /* shouldn't happen, but just in case */
+ break;
+ }
+
+ /* updates */
+ DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+
+ return OPERATOR_FINISHED;
+}
+
+void LATTICE_OT_flip(wmOperatorType *ot)
+{
+ static EnumPropertyItem flip_items[] = {
+ {LATTICE_FLIP_U, "U", 0, "U (X) Axis", ""},
+ {LATTICE_FLIP_V, "V", 0, "V (Y) Axis", ""},
+ {LATTICE_FLIP_W, "W", 0, "W (Z) Axis", ""},
+ {0, NULL, 0, NULL, NULL}};
+
+ /* identifiers */
+ ot->name = "Flip (Distortion Free)";
+ ot->description = "Mirror all control points without inverting the lattice deform";
+ ot->idname = "LATTICE_OT_flip";
+
+ /* api callbacks */
+ ot->poll = ED_operator_editlattice;
+ ot->invoke = WM_menu_invoke;
+ ot->exec = lattice_flip_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop = RNA_def_enum(ot->srna, "axis", flip_items, LATTICE_FLIP_U, "Flip Axis", "Coordinates along this axis get flipped");
+}
+
/****************************** Mouse Selection *************************/
-static void findnearestLattvert__doClosest(void *userData, BPoint *bp, int x, int y)
+static void findnearestLattvert__doClosest(void *userData, BPoint *bp, const float screen_co[2])
{
- struct { BPoint *bp; short dist, select; int mval[2]; } *data = userData;
- float temp = abs(data->mval[0] - x) + abs(data->mval[1] - y);
+ struct { BPoint *bp; float dist; int select; float mval_fl[2]; } *data = userData;
+ float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co);
- if ((bp->f1 & SELECT) == data->select)
- temp += 5;
+ if ((bp->f1 & SELECT) && data->select)
+ dist_test += 5.0f;
- if (temp < data->dist) {
- data->dist = temp;
+ if (dist_test < data->dist) {
+ data->dist = dist_test;
data->bp = bp;
}
@@ -322,15 +572,15 @@ static BPoint *findnearestLattvert(ViewContext *vc, const int mval[2], int sel)
/* sel==1: selected gets a disadvantage */
/* in nurb and bezt or bp the nearest is written */
/* return 0 1 2: handlepunt */
- struct { BPoint *bp; short dist, select; int mval[2]; } data = {NULL};
+ struct { BPoint *bp; float dist; int select; float mval_fl[2]; } data = {NULL};
data.dist = 100;
data.select = sel;
- data.mval[0] = mval[0];
- data.mval[1] = mval[1];
+ data.mval_fl[0] = mval[0];
+ data.mval_fl[1] = mval[1];
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- lattice_foreachScreenVert(vc, findnearestLattvert__doClosest, &data);
+ lattice_foreachScreenVert(vc, findnearestLattvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
return data.bp;
}
@@ -341,7 +591,7 @@ int mouse_lattice(bContext *C, const int mval[2], int extend, int deselect, int
BPoint *bp = NULL;
view3d_set_viewcontext(C, &vc);
- bp = findnearestLattvert(&vc, mval, 1);
+ bp = findnearestLattvert(&vc, mval, TRUE);
if (bp) {
if (extend) {
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index d75ef78fc4c..02070506937 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -1242,7 +1242,7 @@ static int multires_reshape_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
if (!secondob) {
- BKE_report(op->reports, RPT_ERROR, "Second selected mesh object require to copy shape from");
+ BKE_report(op->reports, RPT_ERROR, "Second selected mesh object required to copy shape from");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index fa40d579e2b..b6d3594c826 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -178,6 +178,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_vertex_group_select);
WM_operatortype_append(OBJECT_OT_vertex_group_deselect);
WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_linked);
+ WM_operatortype_append(OBJECT_OT_vertex_group_transfer_weight);
WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_selected);
WM_operatortype_append(OBJECT_OT_vertex_group_copy);
WM_operatortype_append(OBJECT_OT_vertex_group_normalize);
@@ -188,6 +189,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_vertex_group_levels);
WM_operatortype_append(OBJECT_OT_vertex_group_blend);
WM_operatortype_append(OBJECT_OT_vertex_group_clean);
+ WM_operatortype_append(OBJECT_OT_vertex_group_limit_total);
WM_operatortype_append(OBJECT_OT_vertex_group_mirror);
WM_operatortype_append(OBJECT_OT_vertex_group_set_active);
WM_operatortype_append(OBJECT_OT_vertex_group_sort);
@@ -209,6 +211,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(LATTICE_OT_select_all);
WM_operatortype_append(LATTICE_OT_make_regular);
+ WM_operatortype_append(LATTICE_OT_flip);
WM_operatortype_append(OBJECT_OT_group_add);
WM_operatortype_append(OBJECT_OT_group_link);
@@ -422,6 +425,8 @@ void ED_keymap_object(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "OBJECT_OT_vertex_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "LATTICE_OT_flip", FKEY, KM_PRESS, KM_CTRL, 0);
+
/* menus */
WM_keymap_add_menu(keymap, "VIEW3D_MT_hook", HKEY, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 446c0a51ed5..447ba29e203 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -423,29 +423,92 @@ void OBJECT_OT_proxy_make(wmOperatorType *ot)
/********************** Clear Parent Operator ******************* */
+typedef enum eObClearParentTypes {
+ CLEAR_PARENT_ALL = 0,
+ CLEAR_PARENT_KEEP_TRANSFORM,
+ CLEAR_PARENT_INVERSE
+} eObClearParentTypes;
+
EnumPropertyItem prop_clear_parent_types[] = {
- {0, "CLEAR", 0, "Clear Parent", ""},
- {1, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation", ""},
- {2, "CLEAR_INVERSE", 0, "Clear Parent Inverse", ""},
+ {CLEAR_PARENT_ALL, "CLEAR", 0, "Clear Parent", ""},
+ {CLEAR_PARENT_KEEP_TRANSFORM, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation", ""},
+ {CLEAR_PARENT_INVERSE, "CLEAR_INVERSE", 0, "Clear Parent Inverse", ""},
{0, NULL, 0, NULL, NULL}
};
-void ED_object_parent_clear(Object *ob, int type)
+/* Helper for ED_object_parent_clear() - Remove deform-modifiers associated with parent */
+static void object_remove_parent_deform_modifiers(Object *ob, const Object *par)
{
+ if (ELEM3(par->type, OB_ARMATURE, OB_LATTICE, OB_CURVE)) {
+ ModifierData *md, *mdn;
+
+ /* assume that we only need to remove the first instance of matching deform modifier here */
+ for (md = ob->modifiers.first; md; md = mdn) {
+ short free = FALSE;
+
+ mdn = md->next;
+
+ /* need to match types (modifier + parent) and references */
+ if ((md->type == eModifierType_Armature) && (par->type == OB_ARMATURE)) {
+ ArmatureModifierData *amd = (ArmatureModifierData *)md;
+ if (amd->object == par) {
+ free = TRUE;
+ }
+ }
+ else if ((md->type == eModifierType_Lattice) && (par->type == OB_LATTICE)) {
+ LatticeModifierData *lmd = (LatticeModifierData *)md;
+ if (lmd->object == par) {
+ free = TRUE;
+ }
+ }
+ else if ((md->type == eModifierType_Curve) && (par->type == OB_CURVE)) {
+ CurveModifierData *cmd = (CurveModifierData *)md;
+ if (cmd->object == par) {
+ free = TRUE;
+ }
+ }
+
+ /* free modifier if match */
+ if (free) {
+ BLI_remlink(&ob->modifiers, md);
+ modifier_free(md);
+ }
+ }
+ }
+}
+void ED_object_parent_clear(Object *ob, int type)
+{
if (ob->parent == NULL)
return;
+
+ switch (type) {
+ case CLEAR_PARENT_ALL:
+ {
+ /* for deformers, remove corresponding modifiers to prevent a large number of modifiers building up */
+ object_remove_parent_deform_modifiers(ob, ob->parent);
+
+ /* clear parenting relationship completely */
+ ob->parent = NULL;
+ }
+ break;
- if (type == 0) {
- ob->parent = NULL;
- }
- else if (type == 1) {
- ob->parent = NULL;
- BKE_object_apply_mat4(ob, ob->obmat, TRUE, FALSE);
- }
- else if (type == 2)
- unit_m4(ob->parentinv);
+ case CLEAR_PARENT_KEEP_TRANSFORM:
+ {
+ /* remove parent, and apply the parented transform result as object's local transforms */
+ ob->parent = NULL;
+ BKE_object_apply_mat4(ob, ob->obmat, TRUE, FALSE);
+ }
+ break;
+ case CLEAR_PARENT_INVERSE:
+ {
+ /* object stays parented, but the parent inverse (i.e. offset from parent to retain binding state) is cleared */
+ unit_m4(ob->parentinv);
+ }
+ break;
+ }
+
ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
}
@@ -606,23 +669,38 @@ int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object
ob->partype = PAROBJECT; /* note, dna define, not operator property */
//ob->partype= PARSKEL; /* note, dna define, not operator property */
- /* BUT, to keep the deforms, we need a modifier, and then we need to set the object that it uses */
+ /* BUT, to keep the deforms, we need a modifier, and then we need to set the object that it uses
+ * - We need to ensure that the modifier we're adding doesn't already exist, so we check this by
+ * assuming that the parent is selected too...
+ */
// XXX currently this should only happen for meshes, curves, surfaces, and lattices - this stuff isn't available for metas yet
if (ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
ModifierData *md;
switch (partype) {
case PAR_CURVE: /* curve deform */
- md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Curve);
- ((CurveModifierData *)md)->object = par;
+ if ( modifiers_isDeformedByCurve(ob) != par) {
+ md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Curve);
+ if (md) {
+ ((CurveModifierData *)md)->object = par;
+ }
+ }
break;
case PAR_LATTICE: /* lattice deform */
- md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Lattice);
- ((LatticeModifierData *)md)->object = par;
+ if (modifiers_isDeformedByLattice(ob) != par) {
+ md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Lattice);
+ if (md) {
+ ((LatticeModifierData *)md)->object = par;
+ }
+ }
break;
default: /* armature deform */
- md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Armature);
- ((ArmatureModifierData *)md)->object = par;
+ if (modifiers_isDeformedByArmature(ob) != par) {
+ md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Armature);
+ if (md) {
+ ((ArmatureModifierData *)md)->object = par;
+ }
+ }
break;
}
}
diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c
index cfd4945688b..86a55a9b278 100644
--- a/source/blender/editors/object/object_shapekey.c
+++ b/source/blender/editors/object/object_shapekey.c
@@ -162,15 +162,15 @@ static int object_shape_key_mirror(bContext *C, Object *ob)
kb = BLI_findlink(&key->block, ob->shapenr - 1);
if (kb) {
- int i1, i2;
- float *fp1, *fp2;
- float tvec[3];
char *tag_elem = MEM_callocN(sizeof(char) * kb->totelem, "shape_key_mirror");
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
MVert *mv;
+ int i1, i2;
+ float *fp1, *fp2;
+ float tvec[3];
mesh_octree_table(ob, NULL, NULL, 's');
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index 9129d651d4d..4c95884a51a 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -217,7 +217,7 @@ static int object_clear_transform_generic_exec(bContext *C, wmOperator *op,
/* sanity checks */
if (ELEM(NULL, clear_func, default_ksName)) {
- BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform func or Keying Set Name");
+ BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform function or Keying Set Name");
return OPERATOR_CANCELLED;
}
@@ -381,8 +381,8 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- float rsmat[3][3], tmat[3][3], obmat[3][3], iobmat[3][3], mat[4][4], scale;
- int a, change = 1;
+ float rsmat[3][3], obmat[3][3], iobmat[3][3], mat[4][4], scale;
+ int change = 1;
/* first check if we can execute */
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
@@ -417,7 +417,8 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo
cu = ob->data;
if (!(cu->flag & CU_3D) && (apply_rot || apply_loc)) {
- BKE_report(reports, RPT_ERROR, "Neither rotation nor location could be applied to a 2d curve, doing nothing");
+ BKE_report(reports, RPT_ERROR,
+ "Neither rotation nor location could be applied to a 2D curve, doing nothing");
change = 0;
}
if (cu->key) {
@@ -464,6 +465,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo
copy_v3_v3(mat[3], ob->loc);
if (!(apply_scale && apply_rot)) {
+ float tmat[3][3];
/* correct for scale and rotation that is still applied */
BKE_object_to_mat3(ob, obmat);
invert_m3_m3(iobmat, obmat);
@@ -476,6 +478,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
MVert *mvert;
+ int a;
if (apply_scale)
multiresModifier_scale_disp(scene, ob);
@@ -518,6 +521,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo
Nurb *nu;
BPoint *bp;
BezTriple *bezt;
+ int a;
scale = mat3_to_scale(rsmat);
@@ -896,6 +900,8 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
/* offset other selected objects */
if (do_inverse_offset && (centermode != GEOMETRY_TO_ORIGIN)) {
+ CollectionPointerLink *ctx_link_other;
+
/* was the object data modified
* note: the functions above must set 'cent' */
copy_v3_v3(centn, cent);
@@ -910,8 +916,16 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
ignore_parent_tx(bmain, scene, ob);
/* other users? */
- CTX_DATA_BEGIN (C, Object *, ob_other, selected_editable_objects)
+ //CTX_DATA_BEGIN (C, Object *, ob_other, selected_editable_objects)
+ //{
+
+ /* use existing context looper */
+ for (ctx_link_other = ctx_data_list.first;
+ ctx_link_other;
+ ctx_link_other = ctx_link_other->next)
{
+ Object *ob_other = ctx_link_other->ptr.data;
+
if ((ob_other->flag & OB_DONE) == 0 &&
((ob->data && (ob->data == ob_other->data)) ||
(ob->dup_group == ob_other->dup_group &&
@@ -931,7 +945,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
ignore_parent_tx(bmain, scene, ob_other);
}
}
- CTX_DATA_END;
+ //CTX_DATA_END;
}
}
}
@@ -948,9 +962,9 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
/* Warn if any errors occurred */
if (tot_lib_error + tot_multiuser_arm_error) {
- BKE_reportf(op->reports, RPT_WARNING, "%i Object(s) Not Centered, %i Changed:", tot_lib_error + tot_multiuser_arm_error, tot_change);
+ BKE_reportf(op->reports, RPT_WARNING, "%i object(s) not centered, %i changed:", tot_lib_error + tot_multiuser_arm_error, tot_change);
if (tot_lib_error)
- BKE_reportf(op->reports, RPT_WARNING, "|%i linked library objects", tot_lib_error);
+ BKE_reportf(op->reports, RPT_WARNING, "|%i linked library object(s)", tot_lib_error);
if (tot_multiuser_arm_error)
BKE_reportf(op->reports, RPT_WARNING, "|%i multiuser armature object(s)", tot_multiuser_arm_error);
}
@@ -962,8 +976,10 @@ void OBJECT_OT_origin_set(wmOperatorType *ot)
{
static EnumPropertyItem prop_set_center_types[] = {
{GEOMETRY_TO_ORIGIN, "GEOMETRY_ORIGIN", 0, "Geometry to Origin", "Move object geometry to object origin"},
- {ORIGIN_TO_GEOMETRY, "ORIGIN_GEOMETRY", 0, "Origin to Geometry", "Move object origin to center of object geometry"},
- {ORIGIN_TO_CURSOR, "ORIGIN_CURSOR", 0, "Origin to 3D Cursor", "Move object origin to position of the 3d cursor"},
+ {ORIGIN_TO_GEOMETRY, "ORIGIN_GEOMETRY", 0, "Origin to Geometry",
+ "Move object origin to center of object geometry"},
+ {ORIGIN_TO_CURSOR, "ORIGIN_CURSOR", 0, "Origin to 3D Cursor",
+ "Move object origin to position of the 3D cursor"},
{0, NULL, 0, NULL, NULL}
};
@@ -975,7 +991,7 @@ void OBJECT_OT_origin_set(wmOperatorType *ot)
/* identifiers */
ot->name = "Set Origin";
- ot->description = "Set the object's origin, by either moving the data, or set to center of data, or use 3d cursor";
+ ot->description = "Set the object's origin, by either moving the data, or set to center of data, or use 3D cursor";
ot->idname = "OBJECT_OT_origin_set";
/* api callbacks */
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index b31d2b8b076..1be09847ef2 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -20,7 +20,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Ove M Henriksen.
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -29,7 +29,6 @@
* \ingroup edobj
*/
-
#include <string.h>
#include <stddef.h>
#include <math.h>
@@ -83,6 +82,19 @@ static void vgroup_delete_edit_mode(Object *ob, bDeformGroup *defgroup);
static void vgroup_delete_object_mode(Object *ob, bDeformGroup *dg);
static void vgroup_delete_all(Object *ob);
+static int vertex_group_use_vert_sel(Object *ob)
+{
+ if (ob->mode == OB_MODE_EDIT) {
+ return TRUE;
+ }
+ else if (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) {
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
static Lattice *vgroup_edit_lattice(Object *ob)
{
Lattice *lt = ob->data;
@@ -377,6 +389,332 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from)
return 1;
}
+/***********************Start weight transfer (WT)*********************************/
+
+typedef enum WT_VertexGroupMode {
+ WT_REPLACE_ACTIVE_VERTEX_GROUP = 1,
+ WT_REPLACE_ALL_VERTEX_GROUPS = 2
+} WT_VertexGroupMode;
+
+typedef enum WT_Method {
+ WT_BY_INDEX = 1,
+ WT_BY_NEAREST_VERTEX = 2,
+ WT_BY_NEAREST_FACE = 3,
+ WT_BY_NEAREST_VERTEX_IN_FACE = 4
+} WT_Method;
+
+typedef enum WT_ReplaceMode {
+ WT_REPLACE_ALL_WEIGHTS = 1,
+ WT_REPLACE_EMPTY_WEIGHTS = 2,
+} WT_ReplaceMode;
+
+static EnumPropertyItem WT_vertex_group_mode_item[] = {
+ {WT_REPLACE_ACTIVE_VERTEX_GROUP, "WT_REPLACE_ACTIVE_VERTEX_GROUP", 1, "Active", "Transfer active vertex group from selected to active mesh."},
+ {WT_REPLACE_ALL_VERTEX_GROUPS, "WT_REPLACE_ALL_VERTEX_GROUPS", 1, "All", "Transfer all vertex groups from selected to active mesh."},
+ {0, NULL, 0, NULL, NULL}
+};
+
+static EnumPropertyItem WT_method_item[] = {
+ {WT_BY_INDEX, "WT_BY_INDEX", 1, "Vertex index", "Copy for identical meshes."},
+ {WT_BY_NEAREST_VERTEX, "WT_BY_NEAREST_VERTEX", 1, "Nearest vertex", "Copy weight from closest vertex."},
+ {WT_BY_NEAREST_FACE, "WT_BY_NEAREST_FACE", 1, "Nearest face", "Barycentric interpolation from nearest face."},
+ {WT_BY_NEAREST_VERTEX_IN_FACE, "WT_BY_NEAREST_VERTEX_IN_FACE", 1, "Nearest vertex in face", "Copy weight from closest vertex in nearest face."},
+ {0, NULL, 0, NULL, NULL}
+};
+
+static EnumPropertyItem WT_replace_mode_item[] = {
+ {WT_REPLACE_ALL_WEIGHTS, "WT_REPLACE_ALL_WEIGHTS", 1, "All", "Overwrites all weights."},
+ {WT_REPLACE_EMPTY_WEIGHTS, "WT_REPLACE_EMPTY_WEIGHTS", 1, "Empty", "Adds weights to vertices with no weight."},
+ {0, NULL, 0, NULL, NULL}
+};
+
+/*copy weight*/
+static void vgroup_transfer_weight(float *r_weight_dst, const float weight_src, const WT_ReplaceMode replace_mode)
+{
+ switch (replace_mode) {
+ case WT_REPLACE_ALL_WEIGHTS:
+ *r_weight_dst = weight_src;
+ break;
+
+ case WT_REPLACE_EMPTY_WEIGHTS:
+ if (*r_weight_dst == 0.0f) {
+ *r_weight_dst = weight_src;
+ }
+ break;
+
+ default:
+ BLI_assert(0);
+ break;
+ }
+}
+
+/* could be exposed externally */
+static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene,
+ WT_Method method, WT_ReplaceMode replace_mode, wmOperator *op)
+{
+ bDeformGroup *dg_dst;
+ Mesh *me_dst, *me_src;
+ DerivedMesh *dmesh_src;
+ BVHTreeFromMesh tree_mesh_vertices_src, tree_mesh_faces_src = {NULL};
+ MDeformVert **dv_array_src, **dv_array_dst, **dv_src, **dv_dst;
+ MVert *mv_dst, *mv_src;
+ MFace *mface_src, *mf;
+ BVHTreeNearest nearest;
+ MDeformWeight *dw_dst, *dw_src;
+ int dv_tot_src, dv_tot_dst, i, v_index, index_dst, index_src, index_nearest, index_nearest_vertex;
+ unsigned int f_index;
+ float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4], dist_v1, dist_v2, dist_v3, dist_v4;
+ const int use_vert_sel = vertex_group_use_vert_sel(ob_dst);
+
+ /* create new and overwrite vertex group on destination without data */
+ if (!defgroup_find_name(ob_dst, dg_src->name)) {
+ ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name));
+ ED_vgroup_add_name(ob_dst, dg_src->name);
+ }
+
+ /* get destination deformgroup */
+ dg_dst = defgroup_find_name(ob_dst, dg_src->name);
+
+ /* get meshes */
+ dmesh_src = mesh_get_derived_deform(scene, ob_src, CD_MASK_BAREMESH);
+ me_dst = ob_dst->data;
+ me_src = ob_src->data;
+
+ /* sanity check */
+ if (!me_src->dvert) {
+ BKE_report(op->reports, RPT_ERROR, "Transfer failed (source mesh does not have any vertex groups)");
+ return 0;
+ }
+
+ /* create data in memory when nothing there */
+ if (!me_dst->dvert) ED_vgroup_data_create(ob_dst->data);
+
+ /* get vertex group arrays */
+ ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE);
+ ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, use_vert_sel);
+
+ /* get indexes of vertex groups */
+ index_src = BLI_findindex(&ob_src->defbase, dg_src);
+ index_dst = BLI_findindex(&ob_dst->defbase, dg_dst);
+
+ /* get vertices */
+ mv_dst = me_dst->mvert;
+ mv_src = dmesh_src->getVertArray(dmesh_src);
+
+ /* prepare transformation matrix */
+ invert_m4_m4(ob_src->imat, ob_src->obmat);
+ mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat);
+
+ /* clear weights */
+ if (replace_mode == WT_REPLACE_ALL_WEIGHTS) {
+ for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++) {
+
+ if (*dv_dst == NULL) continue;
+
+ dw_dst = defvert_find_index(*dv_dst, index_dst);
+ /* remove vertex from group */
+ if (dw_dst) defvert_remove_group(*dv_dst, dw_dst);
+ }
+ }
+
+ switch (method) {
+
+ case WT_BY_INDEX:
+ /* check if indices are matching, delete and return if not */
+ if (ob_dst == ob_src || dv_tot_dst == 0 || dv_tot_dst != dv_tot_src ||
+ dv_array_src == NULL || dv_array_dst == NULL)
+ {
+ ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_dst->name));
+ if (dv_array_src) MEM_freeN(dv_array_src);
+ if (dv_array_dst) MEM_freeN(dv_array_dst);
+ dmesh_src->release(dmesh_src);
+ BKE_report(op->reports, RPT_ERROR, "Transfer failed (indices are not matching)");
+ return 0;
+ }
+
+ /* loop through the vertices*/
+ for (i = 0, dv_src = dv_array_src, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, dv_src++, mv_src++, mv_dst++) {
+
+ if (*dv_dst == NULL) {
+ continue;
+ }
+
+ /* copy weight */
+ dw_src = defvert_find_index(*dv_src, index_src);
+ if (dw_src && dw_src->weight) {
+ dw_dst = defvert_verify_index(*dv_dst, index_dst);
+ vgroup_transfer_weight(&dw_dst->weight, dw_src->weight, replace_mode);
+ }
+ }
+ break;
+
+ case WT_BY_NEAREST_VERTEX:
+ /* make node tree */
+ bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, FLT_EPSILON, 2, 6);
+
+ /* loop trough vertices */
+ for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) {
+
+ if (*dv_dst == NULL) {
+ continue;
+ }
+
+ /* reset nearest */
+ nearest.dist = FLT_MAX;
+ /* with current binary tree its marginally faster to start searching at the top, as opposed to previous search. */
+ nearest.index = -1;
+
+ /* transform into target space */
+ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co);
+
+ /* node tree accelerated search for closest vetex */
+ BLI_bvhtree_find_nearest(tree_mesh_vertices_src.tree, tmp_co,
+ &nearest, tree_mesh_vertices_src.nearest_callback, &tree_mesh_vertices_src);
+
+ /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */
+ dw_src = defvert_find_index(dv_array_src[nearest.index], index_src);
+ if (dw_src && dw_src->weight) {
+ dw_dst = defvert_verify_index(*dv_dst, index_dst);
+ vgroup_transfer_weight(&dw_dst->weight, dw_src->weight, replace_mode);
+ }
+ }
+
+ /* free memory */
+ free_bvhtree_from_mesh(&tree_mesh_vertices_src);
+ break;
+
+ case WT_BY_NEAREST_FACE:
+ /* get faces */
+ DM_ensure_tessface(dmesh_src);
+ mface_src = dmesh_src->getTessFaceArray(dmesh_src);
+
+ /* make node tree */
+ bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6);
+
+ /* loop through the vertices */
+ for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) {
+
+ if (*dv_dst == NULL) {
+ continue;
+ }
+
+ /* reset nearest */
+ nearest.dist = FLT_MAX;
+ /* with current binary tree its marginally faster to start searching at the top, as opposed to previous search. */
+ nearest.index = -1;
+
+ /* transform into target space */
+ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co);
+
+ /* node tree accelerated search for closest face */
+ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co,
+ &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src);
+ index_nearest = nearest.index;
+
+ /* project onto face */
+ mf = &mface_src[index_nearest];
+ normal_tri_v3(normal, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co);
+ project_v3_plane(tmp_co, normal, mv_src[mf->v1].co);
+
+ /* interpolate weights over face*/
+ f_index = mf->v4 ? 3 : 2;
+ if (f_index == 3) {
+ interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co, mv_src[mf->v4].co, tmp_co);
+ }
+ else {
+ interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co, NULL, tmp_co);
+ }
+
+ /* get weights from face*/
+ weight = 0;
+ do {
+ v_index = (&mf->v1)[f_index];
+ weight += tmp_weight[f_index] * defvert_find_weight(dv_array_src[v_index], index_src);
+ } while (f_index--);
+
+ /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */
+ if (weight > 0) {
+ dw_dst = defvert_verify_index(*dv_dst, index_dst);
+ vgroup_transfer_weight(&dw_dst->weight, weight, replace_mode);
+ }
+ }
+
+ /* free memory */
+ free_bvhtree_from_mesh(&tree_mesh_faces_src);
+ break;
+
+ case WT_BY_NEAREST_VERTEX_IN_FACE:
+ /* get faces */
+ DM_ensure_tessface(dmesh_src);
+ mface_src = dmesh_src->getTessFaceArray(dmesh_src);
+
+ /* make node tree */
+ bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6);
+
+ /* loop through the vertices */
+ for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) {
+
+ if (*dv_dst == NULL) {
+ continue;
+ }
+
+ /* reset nearest */
+ nearest.dist = FLT_MAX;
+ /* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */
+ nearest.index = -1;
+
+ /* transform into target space */
+ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co);
+
+ /* node tree accelerated search for closest face */
+ BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co,
+ &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src);
+ index_nearest = nearest.index;
+
+ /* get distances */
+ mf = &mface_src[index_nearest];
+ dist_v1 = len_squared_v3v3(tmp_co, mv_src[mf->v1].co);
+ dist_v2 = len_squared_v3v3(tmp_co, mv_src[mf->v2].co);
+ dist_v3 = len_squared_v3v3(tmp_co, mv_src[mf->v3].co);
+
+ /* get closest vertex */
+ f_index = mf->v4 ? 3 : 2;
+ if (dist_v1 < dist_v2 && dist_v1 < dist_v3) index_nearest_vertex = mf->v1;
+ else if (dist_v2 < dist_v3) index_nearest_vertex = mf->v2;
+ else index_nearest_vertex = mf->v3;
+ if (f_index == 3) {
+ dist_v4 = len_squared_v3v3(tmp_co, mv_src[mf->v4].co);
+ if (dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3) {
+ index_nearest_vertex = mf->v4;
+ }
+ }
+
+ /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */
+ dw_src = defvert_find_index(dv_array_src[index_nearest_vertex], index_src);
+ if (dw_src && dw_src->weight) {
+ dw_dst = defvert_verify_index(*dv_dst, index_dst);
+ vgroup_transfer_weight(&dw_dst->weight, dw_src->weight, replace_mode);
+ }
+ }
+
+ /* free memory */
+ free_bvhtree_from_mesh(&tree_mesh_faces_src);
+ break;
+
+ default:
+ BLI_assert(0);
+ break;
+ }
+
+ /*free memory*/
+ if (dv_array_src) MEM_freeN(dv_array_src);
+ if (dv_array_dst) MEM_freeN(dv_array_dst);
+ dmesh_src->release(dmesh_src);
+
+ return 1;
+}
+
+/***********************End weight transfer (WT)***********************************/
/* for Mesh in Object mode */
/* allows editmode for Lattice */
@@ -580,7 +918,6 @@ void ED_vgroup_select_by_name(Object *ob, const char *name)
static void vgroup_select_verts(Object *ob, int select)
{
const int def_nr = ob->actdef - 1;
- MDeformVert *dv;
if (!BLI_findlink(&ob->defbase, def_nr)) {
return;
@@ -596,7 +933,7 @@ static void vgroup_select_verts(Object *ob, int select)
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- dv = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
+ MDeformVert *dv = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
if (defvert_find_index(dv, def_nr)) {
BM_vert_select_set(em->bm, eve, select);
}
@@ -633,6 +970,7 @@ static void vgroup_select_verts(Object *ob, int select)
Lattice *lt = vgroup_edit_lattice(ob);
if (lt->dvert) {
+ MDeformVert *dv;
BPoint *bp;
int a, tot;
@@ -704,7 +1042,7 @@ static void vgroup_normalize(Object *ob)
int i, dvert_tot = 0;
const int def_nr = ob->actdef - 1;
- const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0;
+ const int use_vert_sel = vertex_group_use_vert_sel(ob);
if (!BLI_findlink(&ob->defbase, def_nr)) {
return;
@@ -1109,7 +1447,7 @@ static void vgroup_levels(Object *ob, float offset, float gain)
int i, dvert_tot = 0;
const int def_nr = ob->actdef - 1;
- const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0;
+ const int use_vert_sel = vertex_group_use_vert_sel(ob);
if (!BLI_findlink(&ob->defbase, def_nr)) {
return;
@@ -1143,7 +1481,7 @@ static void vgroup_normalize_all(Object *ob, int lock_active)
int i, dvert_tot = 0;
const int def_nr = ob->actdef - 1;
- const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0;
+ const int use_vert_sel = vertex_group_use_vert_sel(ob);
if (lock_active && !BLI_findlink(&ob->defbase, def_nr)) {
return;
@@ -1221,7 +1559,7 @@ static void vgroup_invert(Object *ob, const short auto_assign, const short auto_
MDeformVert *dv, **dvert_array = NULL;
int i, dvert_tot = 0;
const int def_nr = ob->actdef - 1;
- const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0;
+ const int use_vert_sel = vertex_group_use_vert_sel(ob);
if (!BLI_findlink(&ob->defbase, def_nr)) {
return;
@@ -1389,13 +1727,119 @@ static void vgroup_blend(Object *ob, const float fac)
}
}
+static int inv_cmp_mdef_vert_weights(const void *a1, const void *a2)
+{
+ /* qsort sorts in ascending order. We want descending order to save a memcopy
+ * so this compare function is inverted from the standard greater than comparison qsort needs.
+ * A normal compare function is called with two pointer arguments and should return an integer less than, equal to,
+ * or greater than zero corresponding to whether its first argument is considered less than, equal to,
+ * or greater than its second argument. This does the opposite. */
+ const struct MDeformWeight *dw1 = a1, *dw2 = a2;
+
+ if (dw1->weight < dw2->weight) return 1;
+ else if (dw1->weight > dw2->weight) return -1;
+ else if (&dw1 < &dw2) return 1; /* compare addresses so we have a stable sort algorithm */
+ else return -1;
+}
+
+/* Used for limiting the number of influencing bones per vertex when exporting
+ * skinned meshes. if all_deform_weights is True, limit all deform modifiers
+ * to max_weights regardless of type, otherwise, only limit the number of influencing bones per vertex*/
+static int vertex_group_limit_total(Object *ob,
+ const int max_weights,
+ const int all_deform_weights)
+{
+ MDeformVert *dv, **dvert_array = NULL;
+ int i, dvert_tot = 0;
+ const int use_vert_sel = vertex_group_use_vert_sel(ob);
+ int is_change = FALSE;
+
+ ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel);
+
+ if (dvert_array) {
+ int defbase_tot = BLI_countlist(&ob->defbase);
+ const char *vgroup_validmap = (all_deform_weights == FALSE) ?
+ BKE_objdef_validmap_get(ob, defbase_tot) :
+ NULL;
+ int num_to_drop = 0;
+
+ /* only the active group */
+ for (i = 0; i < dvert_tot; i++) {
+
+ /* in case its not selected */
+ if (!(dv = dvert_array[i])) {
+ continue;
+ }
+
+ if (all_deform_weights) {
+ /* keep only the largest weights, discarding the rest
+ * qsort will put array in descending order because of invCompare function */
+ num_to_drop = dv->totweight - max_weights;
+ if (num_to_drop > 0) {
+ qsort(dv->dw, dv->totweight, sizeof(MDeformWeight), inv_cmp_mdef_vert_weights);
+ dv->dw = MEM_reallocN(dv->dw, sizeof(MDeformWeight) * max_weights);
+ dv->totweight = max_weights;
+ is_change = TRUE;
+ }
+ }
+ else {
+ MDeformWeight *dw_temp;
+ int bone_count = 0, non_bone_count = 0;
+ int j;
+ /* only consider vgroups with bone modifiers attached (in vgroup_validmap) */
+
+ num_to_drop = dv->totweight - max_weights;
+
+ /* first check if we even need to test further */
+ if (num_to_drop > 0) {
+ /* re-pack dw array so that non-bone weights are first, bone-weighted verts at end
+ * sort the tail, then copy only the truncated array back to dv->dw */
+ dw_temp = MEM_mallocN(sizeof(MDeformWeight) * (dv->totweight), __func__);
+ bone_count = 0; non_bone_count = 0;
+ for (j = 0; j < dv->totweight; j++) {
+ BLI_assert(dv->dw[j].def_nr < defbase_tot);
+ if (!vgroup_validmap[(dv->dw[j]).def_nr]) {
+ dw_temp[non_bone_count] = dv->dw[j];
+ non_bone_count += 1;
+ }
+ else {
+ dw_temp[dv->totweight - 1 - bone_count] = dv->dw[j];
+ bone_count += 1;
+ }
+ }
+ BLI_assert(bone_count + non_bone_count == dv->totweight);
+ num_to_drop = bone_count - max_weights;
+ if (num_to_drop > 0) {
+ qsort(&dw_temp[non_bone_count], bone_count, sizeof(MDeformWeight), inv_cmp_mdef_vert_weights);
+ dv->totweight -= num_to_drop;
+ /* Do we want to clean/normalize here? */
+ MEM_freeN(dv->dw);
+ dv->dw = MEM_reallocN(dw_temp, sizeof(MDeformWeight) * dv->totweight);
+ is_change = TRUE;
+ }
+ else {
+ MEM_freeN(dw_temp);
+ }
+ }
+ }
+ }
+ MEM_freeN(dvert_array);
+
+ if (vgroup_validmap) {
+ MEM_freeN((void *)vgroup_validmap);
+ }
+ }
+
+ return is_change;
+}
+
static void vgroup_clean(Object *ob, const float epsilon, int keep_single)
{
MDeformWeight *dw;
MDeformVert *dv, **dvert_array = NULL;
int i, dvert_tot = 0;
const int def_nr = ob->actdef - 1;
- const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0;
+ const int use_vert_sel = vertex_group_use_vert_sel(ob);
if (!BLI_findlink(&ob->defbase, def_nr)) {
return;
@@ -1431,7 +1875,7 @@ static void vgroup_clean_all(Object *ob, const float epsilon, const int keep_sin
{
MDeformVert **dvert_array = NULL;
int i, dvert_tot = 0;
- const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0;
+ const int use_vert_sel = vertex_group_use_vert_sel(ob);
ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel);
@@ -2007,7 +2451,6 @@ static void vgroup_delete_all(Object *ob)
/* only in editmode */
static void vgroup_assign_verts(Object *ob, const float weight)
{
- MDeformVert *dv;
const int def_nr = ob->actdef - 1;
if (!BLI_findlink(&ob->defbase, def_nr))
@@ -2027,6 +2470,7 @@ static void vgroup_assign_verts(Object *ob, const float weight)
/* Go through the list of editverts and assign them */
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ MDeformVert *dv;
MDeformWeight *dw;
dv = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT); /* can be NULL */
dw = defvert_verify_index(dv, def_nr);
@@ -2061,6 +2505,7 @@ static void vgroup_assign_verts(Object *ob, const float weight)
}
else if (ob->type == OB_LATTICE) {
Lattice *lt = vgroup_edit_lattice(ob);
+ MDeformVert *dv;
BPoint *bp;
int a, tot;
@@ -2665,6 +3110,47 @@ void OBJECT_OT_vertex_group_clean(wmOperatorType *ot)
"Keep verts assigned to at least one group when cleaning");
}
+static int vertex_group_limit_total_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = ED_object_context(C);
+
+ const int limit = RNA_int_get(op->ptr, "limit");
+ const int all_deform_weights = RNA_boolean_get(op->ptr, "all_deform_weights");
+
+ if (vertex_group_limit_total(ob, limit, all_deform_weights)) {
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ BKE_report(op->reports, RPT_WARNING, "No vertex groups limited");
+
+ /* note, would normally return cancelled, except we want the redo
+ * UI to show up for users to change */
+ return OPERATOR_FINISHED;
+ }
+}
+
+void OBJECT_OT_vertex_group_limit_total(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Limit Number of Weights per Vertex";
+ ot->idname = "OBJECT_OT_vertex_group_limit_total";
+ ot->description = "Limits deform weights associated with a vertex to a specified number by removing lowest weights";
+
+ /* api callbacks */
+ ot->poll = vertex_group_poll;
+ ot->exec = vertex_group_limit_total_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_int(ot->srna, "limit", 4, 1, 32, "Limit", "Maximum number of deform weights", 1, 32);
+ RNA_def_boolean(ot->srna, "all_deform_weights", FALSE, "All Deform Weights", "Cull all deform weights, not just bones");
+}
static int vertex_group_mirror_exec(bContext *C, wmOperator *op)
{
@@ -2762,14 +3248,13 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op)
if ((change == 0 && fail == 0) || fail) {
BKE_reportf(op->reports, RPT_ERROR,
- "Copy to VGroups to Selected warning done %d, failed %d, object data must have matching indices",
+ "Copy VGroups to Selected warning, %d done, %d failed (object data must have matching indices)",
change, fail);
}
return OPERATOR_FINISHED;
}
-
void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot)
{
/* identifiers */
@@ -2785,6 +3270,86 @@ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob_act = CTX_data_active_object(C);
+ bDeformGroup *dg_src;
+ int fail = 0;
+
+ WT_VertexGroupMode vertex_group_mode = RNA_enum_get(op->ptr, "WT_vertex_group_mode");
+ WT_Method method = RNA_enum_get(op->ptr, "WT_method");
+ WT_ReplaceMode replace_mode = RNA_enum_get(op->ptr, "WT_replace_mode");
+
+ /* Macro to loop through selected objects and perform operation depending on function, option and method */
+ CTX_DATA_BEGIN (C, Object *, ob_slc, selected_editable_objects)
+ {
+
+ if (ob_act != ob_slc && ob_slc->defbase.first) {
+ switch (vertex_group_mode) {
+
+ case WT_REPLACE_ACTIVE_VERTEX_GROUP:
+ if (!ed_vgroup_transfer_weight(ob_act, ob_slc,
+ BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1),
+ scene, method, replace_mode, op))
+ {
+ fail++;
+ }
+ break;
+
+ case WT_REPLACE_ALL_VERTEX_GROUPS:
+ for (dg_src = ob_slc->defbase.first; dg_src; dg_src = dg_src->next) {
+ if (!ed_vgroup_transfer_weight(ob_act, ob_slc,
+ dg_src, scene, method, replace_mode, op))
+ {
+ fail++;
+ }
+ }
+ break;
+
+ default:
+ BLI_assert(0);
+ break;
+ }
+ }
+ }
+
+ /* Event notifiers for correct display of data */
+ DAG_id_tag_update(&ob_slc->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_slc);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob_slc->data);
+
+ CTX_DATA_END;
+
+ if (fail != 0) {
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ return OPERATOR_FINISHED;
+ }
+}
+
+/* transfers weight from active to selected */
+void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Transfer Weights";
+ ot->idname = "OBJECT_OT_vertex_group_transfer_weight";
+ ot->description = "Transfer weight paint to active from selected mesh";
+
+ /* api callbacks */
+ ot->poll = vertex_group_poll;
+ ot->exec = vertex_group_transfer_weight_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop = RNA_def_enum(ot->srna, "WT_vertex_group_mode", WT_vertex_group_mode_item, 1, "Group", "");
+ ot->prop = RNA_def_enum(ot->srna, "WT_method", WT_method_item, 3, "Method", "");
+ ot->prop = RNA_def_enum(ot->srna, "WT_replace_mode", WT_replace_mode_item, 1, "Replace", "");
+}
+
static EnumPropertyItem vgroup_items[] = {
{0, NULL, 0, NULL, NULL}
};
diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c
index 70fe87e5c01..467ad5c6ff9 100644
--- a/source/blender/editors/physics/dynamicpaint_ops.c
+++ b/source/blender/editors/physics/dynamicpaint_ops.c
@@ -73,9 +73,9 @@ static int surface_slot_add_exec(bContext *C, wmOperator *UNUSED(op))
/* set preview for this surface only and set active */
canvas->active_sur = 0;
- for (surface=surface->prev; surface; surface=surface->prev) {
- surface->flags &= ~MOD_DPAINT_PREVIEW;
- canvas->active_sur++;
+ for (surface = surface->prev; surface; surface = surface->prev) {
+ surface->flags &= ~MOD_DPAINT_PREVIEW;
+ canvas->active_sur++;
}
return OPERATOR_FINISHED;
@@ -94,26 +94,26 @@ void DPAINT_OT_surface_slot_add(wmOperatorType *ot)
ot->poll = ED_operator_object_active_editable;
/* flags */
- ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int surface_slot_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
DynamicPaintModifierData *pmd = NULL;
- Object *cObject = ED_object_context(C);
+ Object *obj_ctx = ED_object_context(C);
DynamicPaintCanvasSettings *canvas;
DynamicPaintSurface *surface;
- int id=0;
+ int id = 0;
/* Make sure we're dealing with a canvas */
- pmd = (DynamicPaintModifierData *)modifiers_findByType(cObject, eModifierType_DynamicPaint);
+ pmd = (DynamicPaintModifierData *)modifiers_findByType(obj_ctx, eModifierType_DynamicPaint);
if (!pmd || !pmd->canvas) return OPERATOR_CANCELLED;
canvas = pmd->canvas;
surface = canvas->surfaces.first;
/* find active surface and remove it */
- for (; surface; surface=surface->next) {
+ for (; surface; surface = surface->next) {
if (id == canvas->active_sur) {
canvas->active_sur -= 1;
dynamicPaint_freeSurface(surface);
@@ -123,8 +123,8 @@ static int surface_slot_remove_exec(bContext *C, wmOperator *UNUSED(op))
}
dynamicPaint_resetPreview(canvas);
- DAG_id_tag_update(&cObject->id, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, cObject);
+ DAG_id_tag_update(&obj_ctx->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, obj_ctx);
return OPERATOR_FINISHED;
}
@@ -142,7 +142,7 @@ void DPAINT_OT_surface_slot_remove(wmOperatorType *ot)
ot->poll = ED_operator_object_active_editable;
/* flags */
- ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int type_toggle_exec(bContext *C, wmOperator *op)
@@ -151,7 +151,7 @@ static int type_toggle_exec(bContext *C, wmOperator *op)
Object *cObject = ED_object_context(C);
Scene *scene = CTX_data_scene(C);
DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(cObject, eModifierType_DynamicPaint);
- int type= RNA_enum_get(op->ptr, "type");
+ int type = RNA_enum_get(op->ptr, "type");
if (!pmd) return OPERATOR_CANCELLED;
@@ -170,7 +170,7 @@ static int type_toggle_exec(bContext *C, wmOperator *op)
/* update dependency */
DAG_id_tag_update(&cObject->id, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, cObject);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, cObject);
DAG_scene_sort(CTX_data_main(C), scene);
return OPERATOR_FINISHED;
@@ -190,10 +190,10 @@ void DPAINT_OT_type_toggle(wmOperatorType *ot)
ot->poll = ED_operator_object_active_editable;
/* flags */
- ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- prop= RNA_def_enum(ot->srna, "type", prop_dynamicpaint_type_items, MOD_DYNAMICPAINT_TYPE_CANVAS, "Type", "");
+ prop = RNA_def_enum(ot->srna, "type", prop_dynamicpaint_type_items, MOD_DYNAMICPAINT_TYPE_CANVAS, "Type", "");
ot->prop = prop;
}
@@ -203,7 +203,7 @@ static int output_toggle_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
DynamicPaintSurface *surface;
DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(ob, eModifierType_DynamicPaint);
- int output= RNA_enum_get(op->ptr, "output"); /* currently only 1/0 */
+ int output = RNA_enum_get(op->ptr, "output"); /* currently only 1/0 */
if (!pmd || !pmd->canvas) return OPERATOR_CANCELLED;
surface = get_activeSurface(pmd->canvas);
@@ -258,7 +258,7 @@ void DPAINT_OT_output_toggle(wmOperatorType *ot)
ot->poll = ED_operator_object_active_editable;
/* flags */
- ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
ot->prop = RNA_def_enum(ot->srna, "output", prop_output_toggle_types, 0, "Output Toggle", "");
@@ -274,7 +274,7 @@ void DPAINT_OT_output_toggle(wmOperatorType *ot)
static int dynamicPaint_bakeImageSequence(bContext *C, DynamicPaintSurface *surface, Object *cObject)
{
DynamicPaintCanvasSettings *canvas = surface->canvas;
- Scene *scene= CTX_data_scene(C);
+ Scene *scene = CTX_data_scene(C);
wmWindow *win = CTX_wm_window(C);
int frame = 1;
int frames;
@@ -291,7 +291,7 @@ static int dynamicPaint_bakeImageSequence(bContext *C, DynamicPaintSurface *surf
if (!dynamicPaint_createUVSurface(surface)) return 0;
/* Loop through selected frames */
- for (frame=surface->start_frame; frame<=surface->end_frame; frame++) {
+ for (frame = surface->start_frame; frame <= surface->end_frame; frame++) {
float progress = (frame - surface->start_frame) / (float)frames * 100;
surface->current_frame = frame;
@@ -346,7 +346,6 @@ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op)
Object *ob = ED_object_context(C);
int status = 0;
double timer = PIL_check_seconds_timer();
- char result_str[80];
DynamicPaintSurface *surface;
/*
@@ -354,14 +353,14 @@ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op)
*/
pmd = (DynamicPaintModifierData *)modifiers_findByType(ob, eModifierType_DynamicPaint);
if (!pmd) {
- BKE_report(op->reports, RPT_ERROR, "Bake Failed: No Dynamic Paint modifier found.");
+ BKE_report(op->reports, RPT_ERROR, "Bake failed: no Dynamic Paint modifier found");
return 0;
}
/* Make sure we're dealing with a canvas */
canvas = pmd->canvas;
if (!canvas) {
- BKE_report(op->reports, RPT_ERROR, "Bake Failed: Invalid Canvas.");
+ BKE_report(op->reports, RPT_ERROR, "Bake failed: invalid canvas");
return 0;
}
surface = get_activeSurface(canvas);
@@ -381,23 +380,20 @@ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op)
/* Bake was successful:
* Report for ended bake and how long it took */
if (status) {
- /* Format time string */
+ /* Format time string */
char time_str[30];
double time = PIL_check_seconds_timer() - timer;
BLI_timestr(time, time_str);
/* Show bake info */
- BLI_snprintf(result_str, sizeof(result_str), "Bake Complete! (%s)", time_str);
- BKE_report(op->reports, RPT_INFO, result_str);
+ BKE_reportf(op->reports, RPT_INFO, "Bake complete! (%s)", time_str);
}
else {
- if (strlen(canvas->error)) { /* If an error occured */
- BLI_snprintf(result_str, sizeof(result_str), "Bake Failed: %s", canvas->error);
- BKE_report(op->reports, RPT_ERROR, result_str);
+ if (strlen(canvas->error)) { /* If an error occurred */
+ BKE_reportf(op->reports, RPT_ERROR, "Bake failed: %s", canvas->error);
}
- else { /* User canceled the bake */
- BLI_strncpy(result_str, "Baking Cancelled!", sizeof(result_str));
- BKE_report(op->reports, RPT_WARNING, result_str);
+ else { /* User canceled the bake */
+ BKE_report(op->reports, RPT_WARNING, "Baking canceled!");
}
}
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index ee2b5e08520..7343a44470a 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -411,7 +411,7 @@ static int key_test_depth(PEData *data, const float co[3], const int screen_co[2
/* used to calculate here but all callers have the screen_co already, so pass as arg */
#if 0
if (ED_view3d_project_int_global(data->vc.ar, co, screen_co,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS)
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK)
{
return 0;
}
@@ -448,7 +448,7 @@ static int key_inside_circle(PEData *data, float rad, const float co[3], float *
int screen_co[2];
/* TODO, should this check V3D_PROJ_TEST_CLIP_BB too? */
- if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK) {
return 0;
}
@@ -473,7 +473,7 @@ static int key_inside_rect(PEData *data, const float co[3])
{
int screen_co[2];
- if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK) {
return 0;
}
@@ -1665,7 +1665,7 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, short
LOOP_KEYS {
copy_v3_v3(co, key->co);
mul_m4_v3(mat, co);
- if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) &&
+ if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) &&
BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], IS_CLIPPED) &&
key_test_depth(&data, co, screen_co))
{
@@ -1685,7 +1685,7 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, short
copy_v3_v3(co, key->co);
mul_m4_v3(mat, co);
- if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) &&
+ if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) &&
BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], IS_CLIPPED) &&
key_test_depth(&data, co, screen_co))
{
@@ -2414,7 +2414,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op)
if (totremoved == 0)
return OPERATOR_CANCELLED;
- BKE_reportf(op->reports, RPT_INFO, "Remove %d double particles", totremoved);
+ BKE_reportf(op->reports, RPT_INFO, "Removed %d double particles", totremoved);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
@@ -2797,7 +2797,7 @@ static void brush_cut(PEData *data, int pa_index)
if (edit->points[pa_index].flag & PEP_HIDE)
return;
- if (ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS)
+ if (ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK)
return;
rad2= data->rad * data->rad;
@@ -2822,7 +2822,7 @@ static void brush_cut(PEData *data, int pa_index)
/* calculate path time closest to root that was inside the circle */
for (k=1, key++; k<=keys; k++, key++) {
- if ((ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) ||
+ if ((ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) ||
key_test_depth(data, key->co, screen_co) == 0)
{
x0 = (float)screen_co[0];
@@ -3989,7 +3989,9 @@ void PE_undo_step(Scene *scene, int step)
}
else if (step==1) {
- if (edit->curundo==NULL || edit->curundo->prev==NULL);
+ if (edit->curundo==NULL || edit->curundo->prev==NULL) {
+ /* pass */
+ }
else {
if (G.debug & G_DEBUG) printf("undo %s\n", edit->curundo->name);
edit->curundo= edit->curundo->prev;
@@ -3999,7 +4001,9 @@ void PE_undo_step(Scene *scene, int step)
else {
/* curundo has to remain current situation! */
- if (edit->curundo==NULL || edit->curundo->next==NULL);
+ if (edit->curundo==NULL || edit->curundo->next==NULL) {
+ /* pass */
+ }
else {
get_PTCacheUndo(edit, edit->curundo->next);
edit->curundo= edit->curundo->next;
diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c
index 218ae628d3f..bbce94b6215 100644
--- a/source/blender/editors/physics/physics_pointcache.c
+++ b/source/blender/editors/physics/physics_pointcache.c
@@ -325,9 +325,9 @@ static int ptcache_add_new_exec(bContext *C, wmOperator *UNUSED(op))
for (pid=pidlist.first; pid; pid=pid->next) {
if (pid->cache == cache) {
- PointCache *cache = BKE_ptcache_add(pid->ptcaches);
- cache->step = pid->default_step;
- *(pid->cache_ptr) = cache;
+ PointCache *cache_new = BKE_ptcache_add(pid->ptcaches);
+ cache_new->step = pid->default_step;
+ *(pid->cache_ptr) = cache_new;
break;
}
}
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index c08ea2b6429..b61280f14ce 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -80,7 +80,6 @@ void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volat
float *rectf = NULL;
int ymin, ymax, xmin, xmax;
int rymin, rxmin;
- /* unsigned char *rectc; */ /* UNUSED */
/* if renrect argument, we only refresh scanlines */
if (renrect) {
@@ -143,11 +142,10 @@ void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volat
imb_addrectImBuf(ibuf);
rectf += 4 * (rr->rectx * ymin + xmin);
- /* rectc = (unsigned char *)(ibuf->rect + ibuf->x * rymin + rxmin); */ /* UNUSED */
IMB_partial_display_buffer_update(ibuf, rectf, NULL, rr->rectx, rxmin, rymin,
&scene->view_settings, &scene->display_settings,
- rxmin, rymin, rxmin + xmax, rymin + ymax);
+ rxmin, rymin, rxmin + xmax, rymin + ymax, TRUE);
}
/* ****************************** render invoking ***************** */
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 85ae923f881..1d0e5bb6d44 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -342,7 +342,7 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op)
ofs = GPU_offscreen_create(sizex, sizey, err_out);
if (!ofs) {
- BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL offscreen buffer, %s", err_out);
+ BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer, %s", err_out);
return 0;
}
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 817067422af..694d2302fbd 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -273,16 +273,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
/* exception: don't apply render part of display transform for texture previews or icons */
if ((id && sp->pr_method == PR_ICON_RENDER) || id_type == ID_TE) {
- ColorManagedDisplaySettings *display_settings = &sce->display_settings;
- ColorManagedViewSettings *view_settings = &sce->view_settings;
-
- const char *default_view_name = IMB_colormanagement_view_get_default_name(display_settings->display_device);
-
- view_settings->exposure = 0.0f;
- view_settings->gamma = 1.0f;
- view_settings->flag &= ~COLORMANAGE_VIEW_USE_CURVES;
-
- BLI_strncpy(view_settings->view_transform, default_view_name, sizeof(view_settings->view_transform));
+ BKE_scene_disable_color_management(sce);
}
if ((id && sp->pr_method == PR_ICON_RENDER) && id_type != ID_WO)
@@ -550,7 +541,7 @@ static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int
* color managed as well?
*/
IMB_buffer_byte_from_float(rect_byte, rres.rectf,
- 4, dither, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, do_predivide,
+ 4, dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, do_predivide,
rres.rectx, rres.recty, rres.rectx, rres.rectx);
}
@@ -818,7 +809,7 @@ static void shader_preview_free(void *customdata)
/* get rid of copied world */
BLI_remlink(&pr_main->world, sp->worldcopy);
- BKE_world_free_ex(sp->worldcopy, FALSE);
+ BKE_world_free_ex(sp->worldcopy, TRUE); /* [#32865] - we need to unlink the texture copies, unlike for materials */
properties = IDP_GetProperties((ID *)sp->worldcopy, FALSE);
if (properties) {
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index b1b27e1424a..ebbdc90ab04 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -1362,7 +1362,11 @@ void TEXTURE_OT_envmap_save(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER; /* no undo since this doesnt modify the env-map */
/* properties */
- prop = RNA_def_float_array(ot->srna, "layout", 12, default_envmap_layout, 0.0f, 0.0f, "File layout", "Flat array describing the X,Y position of each cube face in the output image, where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] (use -1 to skip a face)", 0.0f, 0.0f);
+ prop = RNA_def_float_array(ot->srna, "layout", 12, default_envmap_layout, 0.0f, 0.0f,
+ "File layout",
+ "Flat array describing the X,Y position of each cube face in the output image, "
+ "where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] "
+ "(use -1 to skip a face)", 0.0f, 0.0f);
RNA_def_property_flag(prop, PROP_HIDDEN);
WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_SAVE,
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index 08ccf37265b..5b1c03f65df 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -74,12 +74,19 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated)
bScreen *sc;
ScrArea *sa;
ARegion *ar;
+ static int recursive_check = FALSE;
/* don't do this render engine update if we're updating the scene from
* other threads doing e.g. rendering or baking jobs */
if (!BLI_thread_is_main())
return;
+ /* don't call this recursively for frame updates */
+ if(recursive_check)
+ return;
+
+ recursive_check = TRUE;
+
C = CTX_create();
CTX_data_main_set(C, bmain);
CTX_data_scene_set(C, scene);
@@ -114,6 +121,8 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated)
}
CTX_free(C);
+
+ recursive_check = FALSE;
}
void ED_render_engine_area_exit(ScrArea *sa)
@@ -224,8 +233,12 @@ static void material_changed(Main *bmain, Material *ma)
/* find node materials using this */
for (parent = bmain->mat.first; parent; parent = parent->id.next) {
- if (parent->use_nodes && parent->nodetree && nodes_use_material(parent->nodetree, ma)) ;
- else continue;
+ if (parent->use_nodes && parent->nodetree && nodes_use_material(parent->nodetree, ma)) {
+ /* pass */
+ }
+ else {
+ continue;
+ }
BKE_icon_changed(BKE_icon_getid(&parent->id));
@@ -247,9 +260,15 @@ static void texture_changed(Main *bmain, Tex *tex)
/* find materials */
for (ma = bmain->mat.first; ma; ma = ma->id.next) {
- if (mtex_use_tex(ma->mtex, MAX_MTEX, tex)) ;
- else if (ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex)) ;
- else continue;
+ if (mtex_use_tex(ma->mtex, MAX_MTEX, tex)) {
+ /* pass */
+ }
+ else if (ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex)) {
+ /* pass */
+ }
+ else {
+ continue;
+ }
BKE_icon_changed(BKE_icon_getid(&ma->id));
@@ -259,18 +278,30 @@ static void texture_changed(Main *bmain, Tex *tex)
/* find lamps */
for (la = bmain->lamp.first; la; la = la->id.next) {
- if (mtex_use_tex(la->mtex, MAX_MTEX, tex)) ;
- else if (la->nodetree && nodes_use_tex(la->nodetree, tex)) ;
- else continue;
+ if (mtex_use_tex(la->mtex, MAX_MTEX, tex)) {
+ /* pass */
+ }
+ else if (la->nodetree && nodes_use_tex(la->nodetree, tex)) {
+ /* pass */
+ }
+ else {
+ continue;
+ }
BKE_icon_changed(BKE_icon_getid(&la->id));
}
/* find worlds */
for (wo = bmain->world.first; wo; wo = wo->id.next) {
- if (mtex_use_tex(wo->mtex, MAX_MTEX, tex)) ;
- else if (wo->nodetree && nodes_use_tex(wo->nodetree, tex)) ;
- else continue;
+ if (mtex_use_tex(wo->mtex, MAX_MTEX, tex)) {
+ /* pass */
+ }
+ else if (wo->nodetree && nodes_use_tex(wo->nodetree, tex)) {
+ /* pass */
+ }
+ else {
+ continue;
+ }
BKE_icon_changed(BKE_icon_getid(&wo->id));
}
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 01a5304451a..ad9b0f61eb1 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -407,8 +407,12 @@ void region_scissor_winrct(ARegion *ar, rcti *winrct)
ar = ar->prev;
if (BLI_rcti_isect(winrct, &ar->winrct, NULL)) {
- if (ar->flag & RGN_FLAG_HIDDEN) ;
- else if (ar->alignment & RGN_SPLIT_PREV) ;
+ if (ar->flag & RGN_FLAG_HIDDEN) {
+ /* pass */
+ }
+ else if (ar->alignment & RGN_SPLIT_PREV) {
+ /* pass */
+ }
else if (ar->alignment == RGN_OVERLAP_LEFT) {
winrct->xmin = ar->winrct.xmax + 1;
}
@@ -935,20 +939,25 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int
/* prefsize, for header we stick to exception */
prefsizex = ar->sizex ? ar->sizex : ar->type->prefsizex;
- if (ar->regiontype == RGN_TYPE_HEADER)
+ if (ar->regiontype == RGN_TYPE_HEADER) {
prefsizey = ar->type->prefsizey;
+ }
else if (ar->regiontype == RGN_TYPE_UI && sa->spacetype == SPACE_FILE) {
prefsizey = UI_UNIT_Y * 2 + (UI_UNIT_Y / 2);
}
- else
+ else {
prefsizey = ar->sizey ? ar->sizey : ar->type->prefsizey;
-
- /* hidden is user flag */
- if (ar->flag & RGN_FLAG_HIDDEN) ;
- /* XXX floating area region, not handled yet here */
- else if (alignment == RGN_ALIGN_FLOAT) ;
- /* remainder is too small for any usage */
+ }
+
+
+ if (ar->flag & RGN_FLAG_HIDDEN) {
+ /* hidden is user flag */
+ }
+ else if (alignment == RGN_ALIGN_FLOAT) {
+ /* XXX floating area region, not handled yet here */
+ }
else if (rct_fits(remainder, 'v', 1) < 0 || rct_fits(remainder, 'h', 1) < 0) {
+ /* remainder is too small for any usage */
ar->flag |= RGN_FLAG_TOO_SMALL;
}
else if (alignment == RGN_ALIGN_NONE) {
@@ -1517,7 +1526,7 @@ int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco)
but = uiDefIconTextButC(block, ICONTEXTROW, 0, ICON_VIEW3D,
editortype_pup(), xco, yco, UI_UNIT_X + 10, UI_UNIT_Y,
&(sa->butspacetype), 1.0, SPACEICONMAX, 0, 0,
- TIP_("Display current editor type (click for menu of available types)"));
+ TIP_("Display current editor type (click for a menu of available types)"));
uiButSetFunc(but, spacefunc, NULL, NULL);
uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index c64a4a37f3a..5eac841dec6 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -2716,6 +2716,8 @@ static int region_quadview_exec(bContext *C, wmOperator *op)
/* lock views and set them */
if (sa->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = sa->spacedata.first;
+
/* run ED_view3d_lock() so the correct 'rv3d->viewquat' is set,
* otherwise when restoring rv3d->localvd the 'viewquat' won't
* match the 'view', set on entering localview See: [#26315],
@@ -2743,7 +2745,15 @@ static int region_quadview_exec(bContext *C, wmOperator *op)
ar = ar->next;
rv3d = ar->regiondata;
- rv3d->view = RV3D_VIEW_CAMERA; rv3d->persp = RV3D_CAMOB;
+
+ /* check if we have a camera */
+ if (v3d->camera) {
+ rv3d->view = RV3D_VIEW_CAMERA; rv3d->persp = RV3D_CAMOB;
+ }
+ else {
+ rv3d->view = RV3D_VIEW_PERSPORTHO; rv3d->persp = RV3D_PERSP;
+ }
+
ED_view3d_lock(rv3d);
view3d_localview_update_rv3d(rv3d);
}
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index 6120229190d..5e23a144408 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -322,8 +322,8 @@ static int project_brush_radius(ViewContext *vc,
add_v3_v3v3(offset, location, ortho);
/* project the center of the brush, and the tangent point to the view onto the screen */
- if ((ED_view3d_project_float_global(vc->ar, location, p1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) &&
- (ED_view3d_project_float_global(vc->ar, offset, p2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS))
+ if ((ED_view3d_project_float_global(vc->ar, location, p1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) &&
+ (ED_view3d_project_float_global(vc->ar, offset, p2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK))
{
/* the distance between these points is the size of the projected brush in pixels */
return len_v2v2(p1, p2);
@@ -340,7 +340,6 @@ static int sculpt_get_brush_geometry(bContext *C, ViewContext *vc,
{
Scene *scene = CTX_data_scene(C);
Paint *paint = paint_get_active_from_context(C);
- Brush *brush = paint_brush(paint);
float window[2];
int hit;
@@ -350,6 +349,7 @@ static int sculpt_get_brush_geometry(bContext *C, ViewContext *vc,
if (vc->obact->sculpt && vc->obact->sculpt->pbvh &&
sculpt_stroke_get_location(C, location, window))
{
+ Brush *brush = paint_brush(paint);
*pixel_radius =
project_brush_radius(vc,
BKE_brush_unprojected_radius_get(scene, brush),
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index c6aaae6b879..34ff5efacc9 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -2554,7 +2554,6 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
float (*outset_uv)[2] = ps->faceSeamUVs[face_index];
float insetCos[4][3]; /* inset face coords. NOTE!!! ScreenSace for ortho, Worldspace in prespective view */
- float fac;
float *vCoSS[4]; /* vertex screenspace coords */
float bucket_clip_edges[2][2]; /* store the screenspace coords of the face, clipped by the bucket's screen aligned rectangle */
@@ -2636,6 +2635,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
/* test we're inside uvspace bucket and triangle bounds */
if (isect_point_quad_v2(uv, seam_subsection[0], seam_subsection[1], seam_subsection[2], seam_subsection[3])) {
+ float fac;
/* We need to find the closest point along the face edge,
* getting the screen_px_from_*** wont work because our actual location
@@ -2670,9 +2670,9 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
#if 1
/* get the UV on the line since we want to copy the pixels from there for bleeding */
float uv_close[2];
- float fac = closest_to_line_v2(uv_close, uv, tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2]);
- if (fac < 0.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx1]);
- else if (fac > 1.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx2]);
+ float uv_fac = closest_to_line_v2(uv_close, uv, tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2]);
+ if (uv_fac < 0.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx1]);
+ else if (uv_fac > 1.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx2]);
if (side) {
barycentric_weights_v2(tf_uv_pxoffset[0], tf_uv_pxoffset[2], tf_uv_pxoffset[3], uv_close, w);
@@ -2683,16 +2683,16 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
#else /* this is buggy with quads, don't use for now */
/* Cheat, we know where we are along the edge so work out the weights from that */
- fac = fac1 + (fac * (fac2 - fac1));
+ uv_fac = fac1 + (uv_fac * (fac2 - fac1));
w[0] = w[1] = w[2] = 0.0;
if (side) {
- w[fidx1 ? fidx1 - 1 : 0] = 1.0f - fac;
- w[fidx2 ? fidx2 - 1 : 0] = fac;
+ w[fidx1 ? fidx1 - 1 : 0] = 1.0f - uv_fac;
+ w[fidx2 ? fidx2 - 1 : 0] = uv_fac;
}
else {
- w[fidx1] = 1.0f - fac;
- w[fidx2] = fac;
+ w[fidx1] = 1.0f - uv_fac;
+ w[fidx2] = uv_fac;
}
#endif
}
@@ -4249,7 +4249,7 @@ static void imapaint_image_update(Scene *scene, SpaceImage *sima, Image *image,
IMB_partial_display_buffer_update(ibuf, ibuf->rect_float, (unsigned char *) ibuf->rect, ibuf->x, 0, 0,
&scene->view_settings, &scene->display_settings,
imapaintpartial.x1, imapaintpartial.y1,
- imapaintpartial.x2, imapaintpartial.y2);
+ imapaintpartial.x2, imapaintpartial.y2, FALSE);
}
else {
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
@@ -5890,7 +5890,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
if (!ibuf) {
/* Mostly happens when OpenGL offscreen buffer was failed to create, */
/* but could be other reasons. Should be handled in the future. nazgul */
- BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL offscreen buffer: %s", err_out);
+ BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer: %s", err_out);
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index 794e7755636..162e2fa15d6 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -51,7 +51,7 @@ struct wmOperator;
struct wmOperatorType;
/* paint_stroke.c */
-typedef int (*StrokeGetLocation)(struct bContext *C, float location[3], float mouse[2]);
+typedef int (*StrokeGetLocation)(struct bContext *C, float location[3], const float mouse[2]);
typedef int (*StrokeTestStart)(struct bContext *C, struct wmOperator *op, const float mouse[2]);
typedef void (*StrokeUpdateStep)(struct bContext *C, struct PaintStroke *stroke, struct PointerRNA *itemptr);
typedef void (*StrokeDone)(const struct bContext *C, struct PaintStroke *stroke);
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 7fabaf7f23d..2ae24db7c33 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -139,13 +139,13 @@ static float event_tablet_data(wmEvent *event, int *pen_flip)
}
/* Put the location of the next stroke dot into the stroke RNA and apply it to the mesh */
-static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *event, float mouse_in[2])
+static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *event, const float mouse_in[2])
{
Scene *scene = CTX_data_scene(C);
Paint *paint = paint_get_active_from_context(C);
Brush *brush = paint_brush(paint);
PaintStroke *stroke = op->customdata;
- float mouse[3];
+ float mouse_out[2];
PointerRNA itemptr;
float location[3];
float pressure;
@@ -159,24 +159,24 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *ev
if (stroke->vc.obact->sculpt) {
float delta[2];
- BKE_brush_jitter_pos(scene, brush, mouse_in, mouse);
+ BKE_brush_jitter_pos(scene, brush, mouse_in, mouse_out);
/* XXX: meh, this is round about because
* BKE_brush_jitter_pos isn't written in the best way to
* be reused here */
if (brush->flag & BRUSH_JITTER_PRESSURE) {
- sub_v2_v2v2(delta, mouse, mouse_in);
+ sub_v2_v2v2(delta, mouse_out, mouse_in);
mul_v2_fl(delta, pressure);
- add_v2_v2v2(mouse, mouse_in, delta);
+ add_v2_v2v2(mouse_out, mouse_in, delta);
}
}
else {
- copy_v2_v2(mouse, mouse_in);
+ copy_v2_v2(mouse_out, mouse_in);
}
/* TODO: can remove the if statement once all modes have this */
if (stroke->get_location)
- stroke->get_location(C, location, mouse);
+ stroke->get_location(C, location, mouse_out);
else
zero_v3(location);
@@ -184,12 +184,11 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *ev
RNA_collection_add(op->ptr, "stroke", &itemptr);
RNA_float_set_array(&itemptr, "location", location);
- RNA_float_set_array(&itemptr, "mouse", mouse);
+ RNA_float_set_array(&itemptr, "mouse", mouse_out);
RNA_boolean_set(&itemptr, "pen_flip", pen_flip);
RNA_float_set(&itemptr, "pressure", pressure);
- stroke->last_mouse_position[0] = mouse[0];
- stroke->last_mouse_position[1] = mouse[1];
+ copy_v2_v2(stroke->last_mouse_position, mouse_out);
stroke->update_step(C, stroke, &itemptr);
}
diff --git a/source/blender/editors/sculpt_paint/paint_undo.c b/source/blender/editors/sculpt_paint/paint_undo.c
index f5b9aa742c6..e406d4f5c3b 100644
--- a/source/blender/editors/sculpt_paint/paint_undo.c
+++ b/source/blender/editors/sculpt_paint/paint_undo.c
@@ -152,7 +152,9 @@ static int undo_stack_step(bContext *C, UndoStack *stack, int step, const char *
UndoElem *undo;
if (step == 1) {
- if (stack->current == NULL) ;
+ if (stack->current == NULL) {
+ /* pass */
+ }
else {
if (!name || strcmp(stack->current->name, name) == 0) {
if (G.debug & G_DEBUG_WM) {
@@ -165,7 +167,9 @@ static int undo_stack_step(bContext *C, UndoStack *stack, int step, const char *
}
}
else if (step == -1) {
- if ((stack->current != NULL && stack->current->next == NULL) || stack->elems.first == NULL) ;
+ if ((stack->current != NULL && stack->current->next == NULL) || stack->elems.first == NULL) {
+ /* pass */
+ }
else {
if (!name || strcmp(stack->current->name, name) == 0) {
undo = (stack->current && stack->current->next) ? stack->current->next : stack->elems.first;
@@ -254,7 +258,9 @@ int ED_undo_paint_valid(int type, const char *name)
else
return 0;
- if (stack->current == NULL) ;
+ if (stack->current == NULL) {
+ /* pass */
+ }
else {
if (name && strcmp(stack->current->name, name) == 0)
return 1;
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 5a79368ac49..bb931dd1ff2 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -848,7 +848,7 @@ static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float vert_n
{
float vertco[2];
- if (ED_view3d_project_float_global(vc->ar, vert_nor, vertco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_float_global(vc->ar, vert_nor, vertco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
float delta[2];
float dist_squared;
@@ -1535,7 +1535,6 @@ static void enforce_locks(MDeformVert *odv, MDeformVert *ndv,
}
else {
/* reset the weights */
- unsigned int i;
MDeformWeight *dw_old = odv->dw;
MDeformWeight *dw_new = ndv->dw;
@@ -2049,7 +2048,6 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UNU
Object *ob = CTX_data_active_object(C);
struct WPaintData *wpd;
Mesh *me;
- bDeformGroup *dg;
float mat[4][4], imat[4][4];
@@ -2098,12 +2096,14 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UNU
return FALSE;
}
- /* check if we are attempting to paint onto a locked vertex group,
- * and other options disallow it from doing anything useful */
- dg = BLI_findlink(&ob->defbase, (ob->actdef - 1));
- if (dg->flag & DG_LOCK_WEIGHT) {
- BKE_report(op->reports, RPT_WARNING, "Active group is locked, aborting");
- return FALSE;
+ {
+ /* check if we are attempting to paint onto a locked vertex group,
+ * and other options disallow it from doing anything useful */
+ bDeformGroup *dg = BLI_findlink(&ob->defbase, (ob->actdef - 1));
+ if (dg->flag & DG_LOCK_WEIGHT) {
+ BKE_report(op->reports, RPT_WARNING, "Active group is locked, aborting");
+ return FALSE;
+ }
}
/* ALLOCATIONS! no return after this line */
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 3d3e86d2acb..092ec32e724 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -3536,8 +3536,6 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
StrokeCache *cache = ss->cache;
Brush *brush = paint_brush(&sd->paint);
- int dx, dy;
-
/* RNA_float_get_array(ptr, "location", cache->traced_location); */
if (cache->first_time ||
@@ -3606,8 +3604,8 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
if (brush->flag & BRUSH_ANCHORED) {
int hit = 0;
- dx = cache->mouse[0] - cache->initial_mouse[0];
- dy = cache->mouse[1] - cache->initial_mouse[1];
+ const float dx = cache->mouse[0] - cache->initial_mouse[0];
+ const float dy = cache->mouse[1] - cache->initial_mouse[1];
sd->anchored_size = cache->pixel_radius = sqrt(dx * dx + dy * dy);
@@ -3617,8 +3615,8 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
float halfway[2];
float out[3];
- halfway[0] = (float)dx * 0.5f + cache->initial_mouse[0];
- halfway[1] = (float)dy * 0.5f + cache->initial_mouse[1];
+ halfway[0] = dx * 0.5f + cache->initial_mouse[0];
+ halfway[1] = dy * 0.5f + cache->initial_mouse[1];
if (sculpt_stroke_get_location(C, out, halfway)) {
copy_v3_v3(sd->anchored_location, out);
@@ -3665,8 +3663,8 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
sculpt_update_brush_delta(sd, ob, brush);
if (brush->sculpt_tool == SCULPT_TOOL_ROTATE) {
- dx = cache->mouse[0] - cache->initial_mouse[0];
- dy = cache->mouse[1] - cache->initial_mouse[1];
+ const float dx = cache->mouse[0] - cache->initial_mouse[0];
+ const float dy = cache->mouse[1] - cache->initial_mouse[1];
cache->vertex_rotation = -atan2f(dx, dy) * cache->bstrength;
@@ -3738,7 +3736,7 @@ static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin)
* (This allows us to ignore the GL depth buffer)
* Returns 0 if the ray doesn't hit the mesh, non-zero otherwise
*/
-int sculpt_stroke_get_location(bContext *C, float out[3], float mouse[2])
+int sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2])
{
ViewContext vc;
Object *ob;
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 0852378974e..acb906e4a91 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -65,7 +65,7 @@ void sculpt_update_mesh_elements(struct Scene *scene, struct Sculpt *sd, struct
void free_sculptsession_deformMats(struct SculptSession *ss);
/* Stroke */
-int sculpt_stroke_get_location(bContext *C, float out[3], float mouse[2]);
+int sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2]);
/* Undo */
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index 7635f85a37e..eeb297b7f57 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -976,8 +976,8 @@ void ACTION_OT_sample(wmOperatorType *ot)
/* defines for set extrapolation-type for selected keyframes tool */
static EnumPropertyItem prop_actkeys_expo_types[] = {
- {FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", ""},
- {FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", ""},
+ {FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", "Values on endpoint keyframes are held"},
+ {FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", "Straight-line slope of end segments are extended past the endpoint keyframes"},
{MAKE_CYCLIC_EXPO, "MAKE_CYCLIC", 0, "Make Cyclic (F-Modifier)", "Add Cycles F-Modifier if one doesn't exist already"},
{CLEAR_CYCLIC_EXPO, "CLEAR_CYCLIC", 0, "Clear Cyclic (F-Modifier)", "Remove Cycles F-Modifier if not needed anymore"},
@@ -1353,9 +1353,9 @@ static int actkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op))
void ACTION_OT_frame_jump(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Jump to Frame";
+ ot->name = "Jump to Keyframes";
ot->idname = "ACTION_OT_frame_jump";
- ot->description = "Set the current frame to the average frame of the selected keyframes";
+ ot->description = "Set the current frame to the average frame value of selected keyframes";
/* api callbacks */
ot->exec = actkeys_framejump_exec;
@@ -1369,10 +1369,14 @@ void ACTION_OT_frame_jump(wmOperatorType *ot)
/* defines for snap keyframes tool */
static EnumPropertyItem prop_actkeys_snap_types[] = {
- {ACTKEYS_SNAP_CFRA, "CFRA", 0, "Current frame", ""},
- {ACTKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", ""}, // XXX as single entry?
- {ACTKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", ""}, // XXX as single entry?
- {ACTKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", ""},
+ {ACTKEYS_SNAP_CFRA, "CFRA", 0, "Current frame",
+ "Snap selected keyframes to the current frame"},
+ {ACTKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame",
+ "Snap selected keyframes to the nearest (whole) frame (use to fix accidental sub-frame offsets)"},
+ {ACTKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second",
+ "Snap selected keyframes to the nearest second"},
+ {ACTKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker",
+ "Snap selected keyframes to the nearest marker"},
{0, NULL, 0, NULL, NULL}
};
@@ -1473,9 +1477,12 @@ void ACTION_OT_snap(wmOperatorType *ot)
/* defines for mirror keyframes tool */
static EnumPropertyItem prop_actkeys_mirror_types[] = {
- {ACTKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current frame", ""},
- {ACTKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0", ""},
- {ACTKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker", ""},
+ {ACTKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current frame",
+ "Flip times of selected keyframes using the current frame as the mirror line"},
+ {ACTKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0",
+ "Flip values of selected keyframes (i.e. negative values become positive, and vice versa)"},
+ {ACTKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker",
+ "Flip times of selected keyframes using the first selected marker as the reference point"},
{0, NULL, 0, NULL, NULL}
};
@@ -1497,12 +1504,8 @@ static void mirror_action_keys(bAnimContext *ac, short mode)
/* for 'first selected marker' mode, need to find first selected marker first! */
// XXX should this be made into a helper func in the API?
if (mode == ACTKEYS_MIRROR_MARKER) {
- TimeMarker *marker = NULL;
+ TimeMarker *marker = ED_markers_get_first_selected(ac->markers);
- /* find first selected marker */
- marker = ED_markers_get_first_selected(ac->markers);
-
- /* store marker's time (if available) */
if (marker)
ked.f1 = (float)marker->frame;
else
diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c
index e4a161e3e22..cca71bb1331 100644
--- a/source/blender/editors/space_action/action_ops.c
+++ b/source/blender/editors/space_action/action_ops.c
@@ -168,9 +168,8 @@ static void action_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
/* action_edit.c */
- /* snap - current frame to selected keys */
- // TODO: maybe since this is called jump, we're better to have it on <something>-J?
- WM_keymap_add_item(keymap, "ACTION_OT_frame_jump", SKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
+ /* jump to selected keyframes */
+ WM_keymap_add_item(keymap, "ACTION_OT_frame_jump", GKEY, KM_PRESS, KM_CTRL, 0);
/* menu + single-step transform */
WM_keymap_add_item(keymap, "ACTION_OT_snap", SKEY, KM_PRESS, KM_SHIFT, 0);
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index c41d2521ee8..7e232a02536 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -900,7 +900,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
}
else {
/* get settings from active particle system instead */
- PointerRNA *ptr = get_pointer_type(path, &RNA_ParticleSystem);
+ ptr = get_pointer_type(path, &RNA_ParticleSystem);
if (ptr && ptr->data) {
ParticleSettings *part = ((ParticleSystem *)ptr->data)->part;
diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c
index c8cf69e3e17..9a7284de660 100644
--- a/source/blender/editors/space_buttons/buttons_ops.c
+++ b/source/blender/editors/space_buttons/buttons_ops.c
@@ -207,7 +207,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, wmEvent *event)
* user-prefs exception - campbell */
if (RNA_struct_find_property(op->ptr, "relative_path")) {
if (!RNA_struct_property_is_set(op->ptr, "relative_path")) {
- /* annoying exception!, if were dealign with the user prefs, default relative to be off */
+ /* annoying exception!, if were dealing with the user prefs, default relative to be off */
RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS && (ptr.data != &U));
}
}
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index 5e940df2a30..d7936c1e2e8 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -117,6 +117,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
int *points, totseg, i, a;
float sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1);
MovieTracking *tracking = &clip->tracking;
+ MovieTrackingObject *act_object = BKE_tracking_object_get_active(tracking);
MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking);
MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking);
@@ -218,8 +219,8 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
/* solver keyframes */
glColor4ub(175, 255, 0, 255);
- draw_keyframe(tracking->settings.keyframe1 + clip->start_frame - 1, CFRA, sfra, framelen, 2);
- draw_keyframe(tracking->settings.keyframe2 + clip->start_frame - 1, CFRA, sfra, framelen, 2);
+ draw_keyframe(act_object->keyframe1 + clip->start_frame - 1, CFRA, sfra, framelen, 2);
+ draw_keyframe(act_object->keyframe2 + clip->start_frame - 1, CFRA, sfra, framelen, 2);
/* movie clip animation */
if ((sc->mode == SC_MODE_MASKEDIT) && sc->mask_info.mask) {
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index 167353e7cb7..b495ca32813 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -44,6 +44,7 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
+#include "BLI_string.h"
#include "BLI_rect.h"
#include "GPU_extensions.h"
@@ -692,7 +693,7 @@ int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf, const unsign
context->start_frame = clip->start_frame;
context->frame_offset = clip->frame_offset;
- strcpy(context->colorspace, clip->colorspace_settings.name);
+ BLI_strncpy(context->colorspace, clip->colorspace_settings.name, sizeof(context->colorspace));
}
else {
/* displaying exactly the same image which was loaded t oa texture,
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index 5c338f3e6f1..37eb0bcb7c1 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -41,6 +41,8 @@
#include "BLI_math.h"
#include "BLI_rect.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_report.h"
@@ -180,7 +182,7 @@ static int open_exec(bContext *C, wmOperator *op)
BLI_join_dirfile(str, sizeof(str), dir_only, file_only);
}
else {
- BKE_reportf(op->reports, RPT_ERROR, "No files selected to be opened");
+ BKE_report(op->reports, RPT_ERROR, "No files selected to be opened");
return OPERATOR_CANCELLED;
}
@@ -195,8 +197,8 @@ static int open_exec(bContext *C, wmOperator *op)
if (op->customdata)
MEM_freeN(op->customdata);
- BKE_reportf(op->reports, RPT_ERROR, "Can't read: \"%s\", %s.", str,
- errno ? strerror(errno) : "Unsupported movie clip format");
+ BKE_reportf(op->reports, RPT_ERROR, "Can't read \"%s\": %s", str,
+ errno ? strerror(errno) : TIP_("Unsupported movie clip format"));
return OPERATOR_CANCELLED;
}
@@ -514,9 +516,14 @@ static int view_zoom_exec(bContext *C, wmOperator *op)
static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
if (event->type == MOUSEZOOM) {
- float factor;
+ float delta, factor;
+
+ delta = event->x - event->prevx + event->y - event->prevy;
+
+ if (U.uiflag & USER_ZOOM_INVERT)
+ delta *= -1;
- factor = 1.0f + (event->x - event->prevx + event->y - event->prevy) / 300.0f;
+ factor = 1.0f + delta / 300.0f;
RNA_float_set(op->ptr, "factor", factor);
sclip_zoom_set_factor_exec(C, event, factor);
@@ -533,11 +540,16 @@ static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
static int view_zoom_modal(bContext *C, wmOperator *op, wmEvent *event)
{
ViewZoomData *vpd = op->customdata;
- float factor;
+ float delta, factor;
switch (event->type) {
case MOUSEMOVE:
- factor = 1.0f + (vpd->x - event->x + vpd->y - event->y) / 300.0f;
+ delta = event->x - vpd->x + event->y - vpd->y;
+
+ if (U.uiflag & USER_ZOOM_INVERT)
+ delta *= -1;
+
+ factor = 1.0f + delta / 300.0f;
RNA_float_set(op->ptr, "factor", factor);
sclip_zoom_set(C, vpd->zoom * factor, vpd->location);
ED_region_tag_redraw(CTX_wm_region(C));
@@ -579,7 +591,7 @@ void CLIP_OT_view_zoom(wmOperatorType *ot)
ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER;
/* properties */
- RNA_def_float(ot->srna, "factor", 0.0f, 0.0f, FLT_MAX,
+ RNA_def_float(ot->srna, "factor", 0.0f, -FLT_MAX, FLT_MAX,
"Factor", "Zoom factor, values higher than 1.0 zoom in, lower values zoom out", -FLT_MAX, FLT_MAX);
}
@@ -700,7 +712,7 @@ void CLIP_OT_view_zoom_ratio(wmOperatorType *ot)
ot->poll = ED_space_clip_view_clip_poll;
/* properties */
- RNA_def_float(ot->srna, "ratio", 0.0f, 0.0f, FLT_MAX,
+ RNA_def_float(ot->srna, "ratio", 0.0f, -FLT_MAX, FLT_MAX,
"Ratio", "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out", -FLT_MAX, FLT_MAX);
}
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index 97f7d7bf132..c061125b4d5 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -154,7 +154,7 @@ void CLIP_OT_add_marker(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX,
+ RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX,
"Location", "Location of marker on frame", -1.0f, 1.0f);
}
@@ -1343,7 +1343,6 @@ static int solve_camera_initjob(bContext *C, SolveCameraJob *scj, wmOperator *op
MovieClip *clip = ED_space_clip_get_clip(sc);
Scene *scene = CTX_data_scene(C);
MovieTracking *tracking = &clip->tracking;
- MovieTrackingSettings *settings = &clip->tracking.settings;
MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
int width, height;
@@ -1359,7 +1358,7 @@ static int solve_camera_initjob(bContext *C, SolveCameraJob *scj, wmOperator *op
scj->user = sc->user;
scj->context = BKE_tracking_reconstruction_context_new(tracking, object,
- settings->keyframe1, settings->keyframe2, width, height);
+ object->keyframe1, object->keyframe2, width, height);
tracking->stats = MEM_callocN(sizeof(MovieTrackingStats), "solve camera stats");
@@ -1401,7 +1400,7 @@ static void solve_camera_freejob(void *scv)
if (!solved)
BKE_report(scj->reports, RPT_WARNING, "Some data failed to reconstruct, see console for details");
else
- BKE_reportf(scj->reports, RPT_INFO, "Average re-projection error %.3f", tracking->reconstruction.error);
+ BKE_reportf(scj->reports, RPT_INFO, "Average re-projection error: %.3f", tracking->reconstruction.error);
/* set currently solved clip as active for scene */
if (scene->clip)
@@ -2767,7 +2766,7 @@ static int join_tracks_exec(bContext *C, wmOperator *op)
next = track->next;
if (TRACK_VIEW_SELECTED(sc, track) && track != act_track) {
- BKE_tracking_tracks_join(act_track, track);
+ BKE_tracking_tracks_join(tracking, act_track, track);
if (tracking->stabilization.rot_track == track)
tracking->stabilization.rot_track = act_track;
@@ -2859,14 +2858,14 @@ static int set_solver_keyframe_exec(bContext *C, wmOperator *op)
SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
- MovieTrackingSettings *settings = &tracking->settings;
+ MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
int keyframe = RNA_enum_get(op->ptr, "keyframe");
int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, sc->user.framenr);
if (keyframe == 0)
- settings->keyframe1 = framenr;
+ object->keyframe1 = framenr;
else
- settings->keyframe2 = framenr;
+ object->keyframe2 = framenr;
WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, clip);
diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c
index 4f62d3fdc2f..feb523237ba 100644
--- a/source/blender/editors/space_clip/tracking_select.c
+++ b/source/blender/editors/space_clip/tracking_select.c
@@ -291,7 +291,6 @@ static int select_invoke(bContext *C, wmOperator *op, wmEvent *event)
MovieTrackingTrack *track = tracking_marker_check_slide(C, event, NULL, NULL, NULL);
if (track) {
- SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
clip->tracking.act_track = track;
@@ -477,7 +476,7 @@ static int clip_lasso_select_exec(bContext *C, wmOperator *op)
select = !RNA_boolean_get(op->ptr, "deselect");
do_lasso_select_marker(C, mcords, mcords_tot, select);
- MEM_freeN(mcords);
+ MEM_freeN((void *)mcords);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c
index 4c2f0ac73d4..c4a5c2a0154 100644
--- a/source/blender/editors/space_console/console_draw.c
+++ b/source/blender/editors/space_console/console_draw.c
@@ -94,12 +94,14 @@ void console_scrollback_prompt_begin(struct SpaceConsole *sc, ConsoleLine *cl_du
{
/* fake the edit line being in the scroll buffer */
ConsoleLine *cl = sc->history.last;
+ int prompt_len = strlen(sc->prompt);
+
cl_dummy->type = CONSOLE_LINE_INPUT;
- cl_dummy->len = cl_dummy->len_alloc = strlen(sc->prompt) + cl->len;
+ cl_dummy->len = prompt_len + cl->len;
cl_dummy->len_alloc = cl_dummy->len + 1;
cl_dummy->line = MEM_mallocN(cl_dummy->len_alloc, "cl_dummy");
- memcpy(cl_dummy->line, sc->prompt, (cl_dummy->len_alloc - cl->len));
- memcpy(cl_dummy->line + ((cl_dummy->len_alloc - cl->len)) - 1, cl->line, cl->len + 1);
+ memcpy(cl_dummy->line, sc->prompt, prompt_len);
+ memcpy(cl_dummy->line + prompt_len, cl->line, cl->len + 1);
BLI_addtail(&sc->scrollback, cl_dummy);
}
void console_scrollback_prompt_end(struct SpaceConsole *sc, ConsoleLine *cl_dummy)
@@ -158,12 +160,13 @@ static int console_textview_line_color(struct TextViewContext *tvc, unsigned cha
const ConsoleLine *cl = (ConsoleLine *)sc->history.last;
const int prompt_len = strlen(sc->prompt);
const int cursor_loc = cl->cursor + prompt_len;
+ const int line_len = cl->len + prompt_len;
int xy[2] = {CONSOLE_DRAW_MARGIN, CONSOLE_DRAW_MARGIN};
int pen[2];
xy[1] += tvc->lheight / 6;
/* account for wrapping */
- if (cl->len < tvc->console_width) {
+ if (line_len < tvc->console_width) {
/* simple case, no wrapping */
pen[0] = tvc->cwidth * cursor_loc;
pen[1] = -2;
@@ -171,7 +174,7 @@ static int console_textview_line_color(struct TextViewContext *tvc, unsigned cha
else {
/* wrap */
pen[0] = tvc->cwidth * (cursor_loc % tvc->console_width);
- pen[1] = -2 + (((cl->len / tvc->console_width) - (cursor_loc / tvc->console_width)) * tvc->lheight);
+ pen[1] = -2 + (((line_len / tvc->console_width) - (cursor_loc / tvc->console_width)) * tvc->lheight);
}
/* cursor */
diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c
index 7efcbcceb3c..ecd9e316cef 100644
--- a/source/blender/editors/space_console/console_ops.c
+++ b/source/blender/editors/space_console/console_ops.c
@@ -580,7 +580,7 @@ static int console_delete_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
else {
- console_select_offset(sc, -1);
+ console_select_offset(sc, -stride);
}
console_textview_update_rect(sc, ar);
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index fcbeb064e4d..7a364eb8685 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -307,7 +307,7 @@ void FILE_OT_select_border(wmOperatorType *ot)
ot->poll = ED_operator_file_active;
ot->cancel = WM_border_select_cancel;
- /* rna */
+ /* properties */
WM_operator_properties_gesture_border(ot, 1);
}
@@ -347,6 +347,8 @@ static int file_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
void FILE_OT_select(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Activate/Select File";
ot->description = "Activate/select file";
@@ -356,10 +358,13 @@ void FILE_OT_select(wmOperatorType *ot)
ot->invoke = file_select_invoke;
ot->poll = ED_operator_file_active;
- /* rna */
- RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first");
- RNA_def_boolean(ot->srna, "fill", FALSE, "Fill", "Select everything beginning with the last selection");
- RNA_def_boolean(ot->srna, "open", TRUE, "Open", "Open a directory when selecting it");
+ /* properties */
+ prop = RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(ot->srna, "fill", FALSE, "Fill", "Select everything beginning with the last selection");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(ot->srna, "open", TRUE, "Open", "Open a directory when selecting it");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
static int file_select_all_exec(bContext *C, wmOperator *UNUSED(op))
@@ -404,9 +409,7 @@ void FILE_OT_select_all_toggle(wmOperatorType *ot)
ot->exec = file_select_all_exec;
ot->poll = ED_operator_file_active;
- /* rna */
-
-
+ /* properties */
}
/* ---------- BOOKMARKS ----------- */
@@ -432,6 +435,8 @@ static int bookmark_select_exec(bContext *C, wmOperator *op)
void FILE_OT_select_bookmark(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Select Directory";
ot->description = "Select a bookmarked directory";
@@ -441,7 +446,9 @@ void FILE_OT_select_bookmark(wmOperatorType *ot)
ot->exec = bookmark_select_exec;
ot->poll = ED_operator_file_active;
- RNA_def_string(ot->srna, "dir", "", 256, "Dir", "");
+ /* properties */
+ prop = RNA_def_string(ot->srna, "dir", "", FILE_MAXDIR, "Dir", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
static int bookmark_add_exec(bContext *C, wmOperator *UNUSED(op))
@@ -498,6 +505,8 @@ static int bookmark_delete_exec(bContext *C, wmOperator *op)
void FILE_OT_delete_bookmark(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Delete Bookmark";
ot->description = "Delete selected bookmark";
@@ -507,7 +516,9 @@ void FILE_OT_delete_bookmark(wmOperatorType *ot)
ot->exec = bookmark_delete_exec;
ot->poll = ED_operator_file_active;
- RNA_def_int(ot->srna, "index", -1, -1, 20000, "Index", "", -1, 20000);
+ /* properties */
+ prop = RNA_def_int(ot->srna, "index", -1, -1, 20000, "Index", "", -1, 20000);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
static int reset_recent_exec(bContext *C, wmOperator *UNUSED(op))
@@ -819,7 +830,8 @@ void FILE_OT_execute(struct wmOperatorType *ot)
/* api callbacks */
ot->exec = file_exec;
ot->poll = file_operator_poll;
-
+
+ /* properties */
prop = RNA_def_boolean(ot->srna, "need_active", 0, "Need Active",
"Only execute if there's an active selected file in the file list");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
@@ -1123,6 +1135,8 @@ int file_directory_new_exec(bContext *C, wmOperator *op)
void FILE_OT_directory_new(struct wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Create New Directory";
ot->description = "Create a new directory";
@@ -1133,7 +1147,8 @@ void FILE_OT_directory_new(struct wmOperatorType *ot)
ot->exec = file_directory_new_exec;
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
- RNA_def_string_dir_path(ot->srna, "directory", "", FILE_MAX, "Directory", "Name of new directory");
+ prop = RNA_def_string_dir_path(ot->srna, "directory", "", FILE_MAX, "Directory", "Name of new directory");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 699cb9b4feb..1408e8b801b 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -748,7 +748,9 @@ static int file_is_blend_backup(const char *str)
a = strlen(str);
b = 7;
- if (a == 0 || b >= a) ;
+ if (a == 0 || b >= a) {
+ /* pass */
+ }
else {
char *loc;
@@ -1224,11 +1226,12 @@ void filelist_from_main(struct FileList *filelist)
if (ok) {
if (!filelist->hide_dot || id->name[2] != '.') {
memset(files, 0, sizeof(struct direntry));
- if (id->lib == NULL)
+ if (id->lib == NULL) {
files->relname = BLI_strdup(id->name + 2);
+ }
else {
- files->relname = MEM_mallocN(FILE_MAX + 32, "filename for lib");
- sprintf(files->relname, "%s | %s", id->lib->name, id->name + 2);
+ files->relname = MEM_mallocN(FILE_MAX + (MAX_ID_NAME - 2), "filename for lib");
+ BLI_snprintf(files->relname, FILE_MAX + (MAX_ID_NAME - 2) + 3, "%s | %s", id->lib->name, id->name + 2);
}
files->type |= S_IFREG;
#if 0 // XXXXX TODO show the selection status of the objects
@@ -1238,7 +1241,7 @@ void filelist_from_main(struct FileList *filelist)
}
else if (idcode == ID_SCE) {
if ( ((Scene *)id)->r.scemode & R_BG_RENDER) files->selflag |= SELECTED_FILE;
- }
+ }
}
#endif
files->nr = totbl + 1;
@@ -1247,10 +1250,10 @@ void filelist_from_main(struct FileList *filelist)
if (idcode == ID_MA || idcode == ID_TE || idcode == ID_LA || idcode == ID_WO || idcode == ID_IM) {
files->flags |= IMAGEFILE;
}
- if (id->lib && fake) BLI_snprintf(files->extra, sizeof(files->extra), "LF %d", id->us);
- else if (id->lib) BLI_snprintf(files->extra, sizeof(files->extra), "L %d", id->us);
- else if (fake) BLI_snprintf(files->extra, sizeof(files->extra), "F %d", id->us);
- else BLI_snprintf(files->extra, sizeof(files->extra), " %d", id->us);
+ if (id->lib && fake) BLI_snprintf(files->extra, sizeof(files->extra), "LF %d", id->us);
+ else if (id->lib) BLI_snprintf(files->extra, sizeof(files->extra), "L %d", id->us);
+ else if (fake) BLI_snprintf(files->extra, sizeof(files->extra), "F %d", id->us);
+ else BLI_snprintf(files->extra, sizeof(files->extra), " %d", id->us);
if (id->lib) {
if (totlib == 0) firstlib = files;
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index 0d56b02e086..3e8f6f1c7fc 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -148,6 +148,7 @@ static void graph_panel_view(const bContext *C, Panel *pa)
row = uiLayoutSplit(sub, 0.7f, TRUE);
uiItemR(row, &sceneptr, "frame_current", 0, IFACE_("Cursor X"), ICON_NONE);
uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_CFRA);
+
row = uiLayoutSplit(sub, 0.7f, TRUE);
uiItemR(row, &spaceptr, "cursor_position_y", 0, IFACE_("Cursor Y"), ICON_NONE);
uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_VALUE);
@@ -308,44 +309,43 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa)
* - we use the button-versions of the calls so that we can attach special update handlers
* and unit conversion magic that cannot be achieved using a purely RNA-approach
*/
- // XXX:
col = uiLayoutColumn(layout, TRUE);
/* keyframe itself */
{
uiItemL(col, IFACE_("Key:"), ICON_NONE);
-
+
but = uiDefButR(block, NUM, B_REDR, IFACE_("Frame"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "co", 0, 0, 0, -1, -1, NULL);
uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt);
-
+
but = uiDefButR(block, NUM, B_REDR, IFACE_("Value"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "co", 1, 0, 0, -1, -1, NULL);
uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt);
uiButSetUnitType(but, unit);
}
-
+
/* previous handle - only if previous was Bezier interpolation */
if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ)) {
uiItemL(col, IFACE_("Left Handle:"), ICON_NONE);
-
+
but = uiDefButR(block, NUM, B_REDR, "X", 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "handle_left", 0, 0, 0, -1, -1, NULL);
uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);
-
+
but = uiDefButR(block, NUM, B_REDR, "Y", 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "handle_left", 1, 0, 0, -1, -1, NULL);
uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);
uiButSetUnitType(but, unit);
}
-
+
/* next handle - only if current is Bezier interpolation */
if (bezt->ipo == BEZT_IPO_BEZ) {
uiItemL(col, IFACE_("Right Handle:"), ICON_NONE);
-
+
but = uiDefButR(block, NUM, B_REDR, "X", 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "handle_right", 0, 0, 0, -1, -1, NULL);
uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);
-
+
but = uiDefButR(block, NUM, B_REDR, "Y", 0, 0, UI_UNIT_X, UI_UNIT_Y,
&bezt_ptr, "handle_right", 1, 0, 0, -1, -1, NULL);
uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);
@@ -437,7 +437,7 @@ static void driver_update_flags_cb(bContext *UNUSED(C), void *fcu_v, void *UNUSE
ChannelDriver *driver = fcu->driver;
/* clear invalid flags */
- fcu->flag &= ~FCURVE_DISABLED; // XXX?
+ fcu->flag &= ~FCURVE_DISABLED;
driver->flag &= ~DRIVER_FLAG_INVALID;
}
@@ -467,7 +467,6 @@ static void graph_panel_driverVar__singleProp(uiLayout *layout, ID *id, DriverVa
uiTemplateAnyID(row, &dtar_ptr, "id", "id_type", IFACE_("Prop:"));
/* Target Property */
- // TODO: make this less technical...
if (dtar->id) {
PointerRNA root_ptr;
@@ -630,12 +629,12 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
/* errors? */
if (driver->flag & DRIVER_FLAG_INVALID)
- uiItemL(col, IFACE_("ERROR: invalid Python expression"), ICON_ERROR);
+ uiItemL(col, IFACE_("ERROR: Invalid Python expression"), ICON_ERROR);
}
else {
/* errors? */
if (driver->flag & DRIVER_FLAG_INVALID)
- uiItemL(col, IFACE_("ERROR: invalid target channel(s)"), ICON_ERROR);
+ uiItemL(col, IFACE_("ERROR: Invalid target channel(s)"), ICON_ERROR);
}
col = uiLayoutColumn(pa->layout, TRUE);
@@ -706,15 +705,15 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
graph_panel_driverVar__transChan(box, ale->id, dvar);
break;
}
-
+
/* value of variable */
if (driver->flag & DRIVER_FLAG_SHOWDEBUG) {
char valBuf[32];
-
+
box = uiLayoutBox(col);
row = uiLayoutRow(box, TRUE);
uiItemL(row, IFACE_("Value:"), ICON_NONE);
-
+
BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", dvar->curval);
uiItemL(row, valBuf, ICON_NONE);
}
@@ -724,8 +723,8 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
MEM_freeN(ale);
}
-/* ******************* f-modifiers ******************************** */
-/* all the drawing code is in editors/animation/fmodifier_ui.c */
+/* ******************* F-Modifiers ******************************** */
+/* All the drawing code is in editors/animation/fmodifier_ui.c */
#define B_FMODIFIER_REDRAW 20
@@ -757,7 +756,9 @@ static void graph_panel_modifiers(const bContext *C, Panel *pa)
row = uiLayoutRow(pa->layout, FALSE);
block = uiLayoutGetBlock(row);
- // XXX for now, this will be a operator button which calls a 'add modifier' operator
+ /* this is an operator button which calls a 'add modifier' operator...
+ * a menu might be nicer but would be tricky as we need some custom filtering
+ */
uiDefButO(block, BUT, "GRAPH_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, IFACE_("Add Modifier"),
10, 0, 150, 20, TIP_("Adds a new F-Curve Modifier for the active F-Curve"));
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 7107a6a2369..30ec32ec0aa 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -1309,8 +1309,8 @@ void GRAPH_OT_sample(wmOperatorType *ot)
/* defines for set extrapolation-type for selected keyframes tool */
static EnumPropertyItem prop_graphkeys_expo_types[] = {
- {FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", ""},
- {FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", ""},
+ {FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", "Values on endpoint keyframes are held"},
+ {FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", "Straight-line slope of end segments are extended past the endpoint keyframes"},
{MAKE_CYCLIC_EXPO, "MAKE_CYCLIC", 0, "Make Cyclic (F-Modifier)", "Add Cycles F-Modifier if one doesn't exist already"},
{CLEAR_CYCLIC_EXPO, "CLEAR_CYCLIC", 0, "Clear Cyclic (F-Modifier)", "Remove Cycles F-Modifier if not needed anymore"},
@@ -1808,9 +1808,9 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op))
void GRAPH_OT_frame_jump(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Jump to Frame";
+ ot->name = "Jump to Keyframes";
ot->idname = "GRAPH_OT_frame_jump";
- ot->description = "Set the current frame to the average frame of the selected keyframes";
+ ot->description = "Place the cursor on the midpoint of selected keyframes";
/* api callbacks */
ot->exec = graphkeys_framejump_exec;
@@ -1824,12 +1824,18 @@ void GRAPH_OT_frame_jump(wmOperatorType *ot)
/* defines for snap keyframes tool */
static EnumPropertyItem prop_graphkeys_snap_types[] = {
- {GRAPHKEYS_SNAP_CFRA, "CFRA", 0, "Current Frame", ""},
- {GRAPHKEYS_SNAP_VALUE, "VALUE", 0, "Cursor Value", ""},
- {GRAPHKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", ""}, // XXX as single entry?
- {GRAPHKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", ""}, // XXX as single entry?
- {GRAPHKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", ""},
- {GRAPHKEYS_SNAP_HORIZONTAL, "HORIZONTAL", 0, "Flatten Handles", ""},
+ {GRAPHKEYS_SNAP_CFRA, "CFRA", 0, "Current Frame",
+ "Snap selected keyframes to the current frame"},
+ {GRAPHKEYS_SNAP_VALUE, "VALUE", 0, "Cursor Value",
+ "Set values of selected keyframes to the cursor value (Y/Horizontal component)"},
+ {GRAPHKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame",
+ "Snap selected keyframes to the nearest (whole) frame (use to fix accidental sub-frame offsets)"},
+ {GRAPHKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second",
+ "Snap selected keyframes to the nearest second"},
+ {GRAPHKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker",
+ "Snap selected keyframes to the nearest marker"},
+ {GRAPHKEYS_SNAP_HORIZONTAL, "HORIZONTAL", 0, "Flatten Handles",
+ "Flatten handles for a smoother transition"},
{0, NULL, 0, NULL, NULL}
};
@@ -1932,11 +1938,16 @@ void GRAPH_OT_snap(wmOperatorType *ot)
/* defines for mirror keyframes tool */
static EnumPropertyItem prop_graphkeys_mirror_types[] = {
- {GRAPHKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current Frame", ""},
- {GRAPHKEYS_MIRROR_VALUE, "VALUE", 0, "By Values over Cursor Value", ""},
- {GRAPHKEYS_MIRROR_YAXIS, "YAXIS", 0, "By Times over Time=0", ""},
- {GRAPHKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0", ""},
- {GRAPHKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker", ""},
+ {GRAPHKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current Frame",
+ "Flip times of selected keyframes using the current frame as the mirror line"},
+ {GRAPHKEYS_MIRROR_VALUE, "VALUE", 0, "By Values over Cursor Value",
+ "Flip values of selected keyframes using the cursor value (Y/Horizontal component) as the mirror line"},
+ {GRAPHKEYS_MIRROR_YAXIS, "YAXIS", 0, "By Times over Time=0",
+ "Flip times of selected keyframes, effectively reversing the order they appear in"},
+ {GRAPHKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0",
+ "Flip values of selected keyframes (i.e. negative values become positive, and vice versa)"},
+ {GRAPHKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker",
+ "Flip times of selected keyframes using the first selected marker as the reference point"},
{0, NULL, 0, NULL, NULL}
};
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index 08b13b49f55..9b031c015a9 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -346,9 +346,8 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
/* graph_edit.c */
- /* snap - current frame to selected keys */
- // TODO: maybe since this is called jump, we're better to have it on <something>-J?
- WM_keymap_add_item(keymap, "GRAPH_OT_frame_jump", SKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
+ /* jump to selected keyframes */
+ WM_keymap_add_item(keymap, "GRAPH_OT_frame_jump", GKEY, KM_PRESS, KM_CTRL, 0);
/* menu + single-step transform */
WM_keymap_add_item(keymap, "GRAPH_OT_snap", SKEY, KM_PRESS, KM_SHIFT, 0);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 4f57b2249d1..4793f995d98 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -430,11 +430,16 @@ static int image_view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
if (event->type == MOUSEZOOM) {
SpaceImage *sima = CTX_wm_space_image(C);
ARegion *ar = CTX_wm_region(C);
- float factor, location[2];
+ float delta, factor, location[2];
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &location[0], &location[1]);
- factor = 1.0f + (event->x - event->prevx + event->y - event->prevy) / 300.0f;
+ delta = event->x - event->prevx + event->y - event->prevy;
+
+ if (U.uiflag & USER_ZOOM_INVERT)
+ delta *= -1;
+
+ factor = 1.0f + delta / 300.0f;
RNA_float_set(op->ptr, "factor", factor);
sima_zoom_set(sima, ar, sima->zoom * factor, location);
ED_region_tag_redraw(CTX_wm_region(C));
@@ -452,11 +457,16 @@ static int image_view_zoom_modal(bContext *C, wmOperator *op, wmEvent *event)
SpaceImage *sima = CTX_wm_space_image(C);
ARegion *ar = CTX_wm_region(C);
ViewZoomData *vpd = op->customdata;
- float factor;
+ float delta, factor;
switch (event->type) {
case MOUSEMOVE:
- factor = 1.0f + (vpd->x - event->x + vpd->y - event->y) / 300.0f;
+ delta = event->x - vpd->x + event->y - vpd->y;
+
+ if (U.uiflag & USER_ZOOM_INVERT)
+ delta *= -1;
+
+ factor = 1.0f + delta / 300.0f;
RNA_float_set(op->ptr, "factor", factor);
sima_zoom_set(sima, ar, vpd->zoom * factor, vpd->location);
ED_region_tag_redraw(CTX_wm_region(C));
@@ -496,7 +506,7 @@ void IMAGE_OT_view_zoom(wmOperatorType *ot)
ot->flag = OPTYPE_BLOCKING;
/* properties */
- RNA_def_float(ot->srna, "factor", 0.0f, 0.0f, FLT_MAX,
+ RNA_def_float(ot->srna, "factor", 0.0f, -FLT_MAX, FLT_MAX,
"Factor", "Zoom factor, values higher than 1.0 zoom in, lower values zoom out", -FLT_MAX, FLT_MAX);
}
@@ -800,7 +810,7 @@ void IMAGE_OT_view_zoom_ratio(wmOperatorType *ot)
ot->poll = space_image_main_area_poll;
/* properties */
- RNA_def_float(ot->srna, "ratio", 0.0f, 0.0f, FLT_MAX,
+ RNA_def_float(ot->srna, "ratio", 0.0f, -FLT_MAX, FLT_MAX,
"Ratio", "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out", -FLT_MAX, FLT_MAX);
}
@@ -1259,8 +1269,7 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
BKE_image_release_renderresult(scene, ima);
}
else {
- if (BKE_imbuf_write_as(colormanaged_ibuf, simopts->filepath, &simopts->im_format, save_copy))
- {
+ if (BKE_imbuf_write_as(colormanaged_ibuf, simopts->filepath, &simopts->im_format, save_copy)) {
ok = TRUE;
}
}
@@ -1549,7 +1558,7 @@ static int image_save_sequence_exec(bContext *C, wmOperator *op)
BLI_strncpy(di, ibuf->name, FILE_MAX);
BLI_splitdirstring(di, fi);
- BKE_reportf(op->reports, RPT_INFO, "%d Image(s) will be saved in %s", tot, di);
+ BKE_reportf(op->reports, RPT_INFO, "%d image(s) will be saved in %s", tot, di);
for (ibuf = sima->image->ibufs.first; ibuf; ibuf = ibuf->next) {
if (ibuf->userflags & IB_BITMAPDIRTY) {
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 31cb6d91889..7f53f378042 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -414,8 +414,9 @@ static void image_refresh(const bContext *C, ScrArea *sa)
/* don't need to check for pin here, see above */
sima->image = tf->tpage;
- if (sima->flag & SI_EDITTILE) ;
- else sima->curtile = tf->tile;
+ if ((sima->flag & SI_EDITTILE) == 0) {
+ sima->curtile = tf->tile;
+ }
}
}
}
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
index 805ff1794c9..bb2d55fa0f6 100644
--- a/source/blender/editors/space_info/info_ops.c
+++ b/source/blender/editors/space_info/info_ops.c
@@ -124,7 +124,7 @@ static const EnumPropertyItem unpack_all_method_items[] = {
{PF_WRITE_LOCAL, "WRITE_LOCAL", 0, "Write files to current directory (overwrite existing files)", ""},
{PF_USE_ORIGINAL, "USE_ORIGINAL", 0, "Use files in original location (create when necessary)", ""},
{PF_WRITE_ORIGINAL, "WRITE_ORIGINAL", 0, "Write files to original location (overwrite existing files)", ""},
- {PF_KEEP, "KEEP", 0, "Disable AutoPack, keep all packed files", ""},
+ {PF_KEEP, "KEEP", 0, "Disable Auto-pack, keep all packed files", ""},
/* {PF_ASK, "ASK", 0, "Ask for each file", ""}, */
{0, NULL, 0, NULL, NULL}};
@@ -150,7 +150,7 @@ static int unpack_all_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)
count = countPackedFiles(bmain);
if (!count) {
- BKE_report(op->reports, RPT_WARNING, "No packed files. Autopack disabled");
+ BKE_report(op->reports, RPT_WARNING, "No packed files (auto-pack disabled)");
G.fileflags &= ~G_AUTOPACK;
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index 4ba196276da..cfab2542756 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -128,7 +128,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str
return 1;
}
- if (str_len > cdc->console_width) { /* wrap? */
+ if (tot_lines > 1) { /* wrap? */
const int initial_offset = ((tot_lines - 1) * cdc->console_width);
const char *line_stride = str + initial_offset; /* advance to the last line and draw it first */
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index 92f014fd804..5c8e7e99a8c 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -849,8 +849,6 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
/* draw NLA-action line 'status-icons' - only when there's an action */
if ((ale->type == ANIMTYPE_NLAACTION) && (ale->data)) {
- AnimData *adt = ale->adt;
-
offset += 16;
/* now draw some indicator icons */
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index 950060dde5f..e0e5007aff0 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -121,7 +121,7 @@ static int nlaedit_enable_tweakmode_exec(bContext *C, wmOperator *op)
/* if no blocks, popup error? */
if (anim_data.first == NULL) {
- BKE_report(op->reports, RPT_ERROR, "No AnimData blocks to enter tweakmode for");
+ BKE_report(op->reports, RPT_ERROR, "No AnimData blocks to enter tweak mode for");
return OPERATOR_CANCELLED;
}
@@ -147,7 +147,7 @@ static int nlaedit_enable_tweakmode_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
}
else {
- BKE_report(op->reports, RPT_ERROR, "No active strip(s) to enter tweakmode on");
+ BKE_report(op->reports, RPT_ERROR, "No active strip(s) to enter tweak mode on");
return OPERATOR_CANCELLED;
}
@@ -190,7 +190,7 @@ static int nlaedit_disable_tweakmode_exec(bContext *C, wmOperator *op)
/* if no blocks, popup error? */
if (anim_data.first == NULL) {
- BKE_report(op->reports, RPT_ERROR, "No AnimData blocks to enter tweakmode for");
+ BKE_report(op->reports, RPT_ERROR, "No AnimData blocks to enter tweak mode for");
return OPERATOR_CANCELLED;
}
@@ -405,7 +405,9 @@ static int nlaedit_add_actionclip_exec(bContext *C, wmOperator *op)
else if (act->idroot == 0) {
/* hopefully in this case (i.e. library of userless actions), the user knows what they're doing... */
BKE_reportf(op->reports, RPT_WARNING,
- "Action '%s' does not specify what datablocks it can be used on. Try setting the 'ID Root Type' setting from the Datablocks Editor for this Action to avoid future problems",
+ "Action '%s' does not specify what datablocks it can be used on "
+ "(try setting the 'ID Root Type' setting from the Datablocks Editor "
+ "for this Action to avoid future problems)",
act->id.name + 2);
}
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 470f82195a4..67508f2087a 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -3098,7 +3098,6 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode)
void *lock;
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
if (ibuf) {
- SpaceNode *snode = CTX_wm_space_node(C);
float x, y;
unsigned char *display_buffer;
void *cache_handle;
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 64a8d96a74f..f0afc647ed5 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -1935,7 +1935,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op))
bNodeTree *ntree = snode->edittree;
bNode *gnode = node_tree_get_editgroup(snode->nodetree);
float gnode_x = 0.0f, gnode_y = 0.0f;
- bNode *node, *new_node;
+ bNode *node;
bNodeLink *link, *newlink;
ED_preview_kill_jobs(C);
@@ -1950,6 +1950,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op))
for (node = ntree->nodes.first; node; node = node->next) {
if (node->flag & SELECT) {
+ bNode *new_node;
new_node = nodeCopyNode(NULL, node);
BKE_node_clipboard_add_node(new_node);
}
diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c
index b76cc05af5c..19a678a9c6e 100644
--- a/source/blender/editors/space_node/node_group.c
+++ b/source/blender/editors/space_node/node_group.c
@@ -583,7 +583,7 @@ static int node_group_ungroup_exec(bContext *C, wmOperator *op)
ntreeUpdateTree(snode->nodetree);
}
else {
- BKE_report(op->reports, RPT_WARNING, "Can't ungroup");
+ BKE_report(op->reports, RPT_WARNING, "Cannot ungroup");
return OPERATOR_CANCELLED;
}
@@ -755,13 +755,13 @@ static int node_group_separate_exec(bContext *C, wmOperator *op)
switch (type) {
case NODE_GS_COPY:
if (!node_group_separate_selected(snode->nodetree, gnode, 1)) {
- BKE_report(op->reports, RPT_WARNING, "Can't separate nodes");
+ BKE_report(op->reports, RPT_WARNING, "Cannot separate nodes");
return OPERATOR_CANCELLED;
}
break;
case NODE_GS_MOVE:
if (!node_group_separate_selected(snode->nodetree, gnode, 0)) {
- BKE_report(op->reports, RPT_WARNING, "Can't separate nodes");
+ BKE_report(op->reports, RPT_WARNING, "Cannot separate nodes");
return OPERATOR_CANCELLED;
}
break;
@@ -1036,7 +1036,7 @@ static int node_group_make_exec(bContext *C, wmOperator *op)
int type = RNA_enum_get(op->ptr, "type");
if (snode->edittree != snode->nodetree) {
- BKE_report(op->reports, RPT_WARNING, "Can not add a new Group in a Group");
+ BKE_report(op->reports, RPT_WARNING, "Cannot add a new group in a group");
return OPERATOR_CANCELLED;
}
@@ -1049,7 +1049,7 @@ static int node_group_make_exec(bContext *C, wmOperator *op)
}
if (gnode) {
- BKE_report(op->reports, RPT_WARNING, "Can not add RenderLayer in a Group");
+ BKE_report(op->reports, RPT_WARNING, "Cannot add a Render Layers node in a group");
return OPERATOR_CANCELLED;
}
}
@@ -1062,21 +1062,21 @@ static int node_group_make_exec(bContext *C, wmOperator *op)
gnode = node_group_make_from_selected(snode->nodetree);
}
else {
- BKE_report(op->reports, RPT_WARNING, "Can not make Group");
+ BKE_report(op->reports, RPT_WARNING, "Cannot make group");
return OPERATOR_CANCELLED;
}
break;
case NODE_GM_INSERT:
gnode = nodeGetActive(snode->nodetree);
if (!gnode || gnode->type != NODE_GROUP) {
- BKE_report(op->reports, RPT_WARNING, "No active Group node");
+ BKE_report(op->reports, RPT_WARNING, "No active group node");
return OPERATOR_CANCELLED;
}
if (node_group_make_test(snode->nodetree, gnode)) {
node_group_make_insert_selected(snode->nodetree, gnode);
}
else {
- BKE_report(op->reports, RPT_WARNING, "Can not insert into Group");
+ BKE_report(op->reports, RPT_WARNING, "Cannot insert into group");
return OPERATOR_CANCELLED;
}
break;
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index b0916a50c37..a3efa15c54a 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -593,7 +593,7 @@ static int node_lasso_select_exec(bContext *C, wmOperator *op)
select = !RNA_boolean_get(op->ptr, "deselect");
do_lasso_select_node(C, mcords, mcords_tot, select);
- MEM_freeN(mcords);
+ MEM_freeN((void *)mcords);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c
index 3d93a6c14a1..42480c0c2d9 100644
--- a/source/blender/editors/space_node/node_templates.c
+++ b/source/blender/editors/space_node/node_templates.c
@@ -147,7 +147,7 @@ static void node_socket_remove(Main *bmain, bNodeTree *ntree, bNode *node_to, bN
static void node_socket_add_replace(Main *bmain, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to, bNodeTemplate *ntemp, int sock_num)
{
bNode *node_from;
- bNodeSocket *sock_from;
+ bNodeSocket *sock_from_tmp;
bNode *node_prev = NULL;
/* unlink existing node */
@@ -183,8 +183,8 @@ static void node_socket_add_replace(Main *bmain, bNodeTree *ntree, bNode *node_t
nodeSetActive(ntree, node_from);
/* add link */
- sock_from = BLI_findlink(&node_from->outputs, sock_num);
- nodeAddLink(ntree, node_from, sock_from, node_to, sock_to);
+ sock_from_tmp = BLI_findlink(&node_from->outputs, sock_num);
+ nodeAddLink(ntree, node_from, sock_from_tmp, node_to, sock_to);
/* copy input sockets from previous node */
if (node_prev && node_from != node_prev) {
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index b70d66f60b4..76d1357a83c 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -254,6 +254,15 @@ static void node_area_listener(ScrArea *sa, wmNotifier *wmn)
}
}
break;
+
+ case NC_MOVIECLIP:
+ if (wmn->action == NA_EDITED) {
+ if (type == NTREE_COMPOSIT) {
+ if (nodeUpdateID(snode->nodetree, wmn->reference))
+ ED_area_tag_refresh(sa);
+ }
+ }
+ break;
}
}
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index a05588495e9..d2e47427b94 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -783,7 +783,9 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo
wmKeyMapItem *kmi = te->directdata;
/* modal map? */
- if (kmi->propvalue) ;
+ if (kmi->propvalue) {
+ /* pass */
+ }
else {
uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys + 1, butw1, UI_UNIT_Y - 1, "Assign new Operator");
}
@@ -1409,11 +1411,15 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
/* closed item, we draw the icons, not when it's a scene, or master-server list though */
if (!TSELEM_OPEN(tselem, soops)) {
if (te->subtree.first) {
- if (tselem->type == 0 && te->idcode == ID_SCE) ;
- else if (tselem->type != TSE_R_LAYER) { /* this tree element always has same amount of branches, so don't draw */
+ if (tselem->type == 0 && te->idcode == ID_SCE) {
+ /* pass */
+ }
+ else if (tselem->type != TSE_R_LAYER) {
+ /* this tree element always has same amount of branches, so don't draw */
+
int tempx = startx + offsx;
- // divider
+ /* divider */
UI_ThemeColorShade(TH_BACK, -40);
glRecti(tempx - 10, *starty + 4, tempx - 8, *starty + UI_UNIT_Y - 4);
@@ -1525,7 +1531,7 @@ static void outliner_draw_tree(bContext *C, uiBlock *block, Scene *scene, ARegio
{
TreeElement *te;
int starty, startx;
- float col[4];
+ float col[3];
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // only once
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 2ec23091019..8f059b0a735 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -368,12 +368,14 @@ void group_toggle_visibility_cb(bContext *UNUSED(C), Scene *scene, TreeElement *
static int outliner_toggle_visibility_exec(bContext *C, wmOperator *UNUSED(op))
{
+ Main *bmain = CTX_data_main(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
Scene *scene = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_visibility_cb);
+ DAG_id_type_tag(bmain, ID_OB);
WM_event_add_notifier(C, NC_SCENE | ND_OB_VISIBLE, scene);
ED_region_tag_redraw(ar);
@@ -464,11 +466,13 @@ void group_toggle_renderability_cb(bContext *UNUSED(C), Scene *scene, TreeElemen
static int outliner_toggle_renderability_exec(bContext *C, wmOperator *UNUSED(op))
{
+ Main *bmain = CTX_data_main(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
Scene *scene = CTX_data_scene(C);
outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_renderability_cb);
+ DAG_id_type_tag(bmain, ID_OB);
WM_event_add_notifier(C, NC_SCENE | ND_OB_RENDER, scene);
return OPERATOR_FINISHED;
@@ -1340,7 +1344,7 @@ static int outliner_keyingset_additems_exec(bContext *C, wmOperator *op)
/* check for invalid states */
if (ks == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Keying Set");
+ BKE_report(op->reports, RPT_ERROR, "Operation requires an active keying set");
return OPERATOR_CANCELLED;
}
if (soutliner == NULL)
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index bf76fdda61e..e4cd971dbd5 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -811,7 +811,7 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
ED_undo_push(C, "Unlink world");
break;
default:
- BKE_report(op->reports, RPT_WARNING, "Not Yet");
+ BKE_report(op->reports, RPT_WARNING, "Not yet");
break;
}
}
@@ -844,7 +844,7 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
break;
default:
- BKE_report(op->reports, RPT_WARNING, "Not Yet");
+ BKE_report(op->reports, RPT_WARNING, "Not yet");
break;
}
}
@@ -980,9 +980,9 @@ static int outliner_action_set_exec(bContext *C, wmOperator *op)
else if (act->idroot == 0) {
/* hopefully in this case (i.e. library of userless actions), the user knows what they're doing... */
BKE_reportf(op->reports, RPT_WARNING,
- "Action '%s' does not specify what datablocks it can be used on. "
- "Try setting the 'ID Root Type' setting from the Datablocks Editor "
- "for this Action to avoid future problems",
+ "Action '%s' does not specify what datablocks it can be used on "
+ "(try setting the 'ID Root Type' setting from the Datablocks Editor "
+ "for this Action to avoid future problems)",
act->id.name + 2);
}
@@ -1160,37 +1160,49 @@ static int outliner_data_operation_exec(bContext *C, wmOperator *op)
event = RNA_enum_get(op->ptr, "type");
set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
- if (datalevel == TSE_POSE_CHANNEL) {
- if (event > 0) {
+ if (event <= 0)
+ return OPERATOR_CANCELLED;
+
+ switch (datalevel) {
+ case TSE_POSE_CHANNEL:
+ {
outliner_do_data_operation(soops, datalevel, event, &soops->tree, pchan_cb, NULL);
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
ED_undo_push(C, "PoseChannel operation");
}
- }
- else if (datalevel == TSE_BONE) {
- if (event > 0) {
+ break;
+
+ case TSE_BONE:
+ {
outliner_do_data_operation(soops, datalevel, event, &soops->tree, bone_cb, NULL);
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
ED_undo_push(C, "Bone operation");
}
- }
- else if (datalevel == TSE_EBONE) {
- if (event > 0) {
+ break;
+
+ case TSE_EBONE:
+ {
outliner_do_data_operation(soops, datalevel, event, &soops->tree, ebone_cb, NULL);
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
ED_undo_push(C, "EditBone operation");
}
- }
- else if (datalevel == TSE_SEQUENCE) {
- if (event > 0) {
+ break;
+
+ case TSE_SEQUENCE:
+ {
Scene *scene = CTX_data_scene(C);
outliner_do_data_operation(soops, datalevel, event, &soops->tree, sequence_cb, scene);
}
- }
- else if (datalevel == TSE_RNA_STRUCT) {
- if (event == 5) {
- outliner_do_data_operation(soops, datalevel, event, &soops->tree, data_select_linked_cb, C);
- }
+ break;
+
+ case TSE_RNA_STRUCT:
+ if (event == 5) {
+ outliner_do_data_operation(soops, datalevel, event, &soops->tree, data_select_linked_cb, C);
+ }
+ break;
+
+ default:
+ break;
}
return OPERATOR_FINISHED;
@@ -1262,12 +1274,15 @@ static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, S
else {
if (datalevel == TSE_ANIM_DATA)
WM_operator_name_call(C, "OUTLINER_OT_animdata_operation", WM_OP_INVOKE_REGION_WIN, NULL);
- else if (datalevel == TSE_DRIVER_BASE)
- /* do nothing... no special ops needed yet */;
- else if (ELEM3(datalevel, TSE_R_LAYER_BASE, TSE_R_LAYER, TSE_R_PASS))
- /*WM_operator_name_call(C, "OUTLINER_OT_renderdata_operation", WM_OP_INVOKE_REGION_WIN, NULL)*/;
- else
+ else if (datalevel == TSE_DRIVER_BASE) {
+ /* do nothing... no special ops needed yet */
+ }
+ else if (ELEM3(datalevel, TSE_R_LAYER_BASE, TSE_R_LAYER, TSE_R_PASS)) {
+ /*WM_operator_name_call(C, "OUTLINER_OT_renderdata_operation", WM_OP_INVOKE_REGION_WIN, NULL)*/
+ }
+ else {
WM_operator_name_call(C, "OUTLINER_OT_data_operation", WM_OP_INVOKE_REGION_WIN, NULL);
+ }
}
}
@@ -1289,11 +1304,13 @@ static int outliner_operation(bContext *C, wmOperator *UNUSED(op), wmEvent *even
SpaceOops *soops = CTX_wm_space_outliner(C);
TreeElement *te;
float fmval[2];
-
+
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval + 1);
for (te = soops->tree.first; te; te = te->next) {
- if (do_outliner_operation_event(C, scene, ar, soops, te, event, fmval)) break;
+ if (do_outliner_operation_event(C, scene, ar, soops, te, event, fmval)) {
+ break;
+ }
}
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 3e1ce1fea6e..ef0542130ea 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -769,7 +769,9 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
else {
/* do not extend Armature when we have posemode */
tselem = TREESTORE(te->parent);
- if (GS(tselem->id->name) == ID_OB && ((Object *)tselem->id)->mode & OB_MODE_POSE) ;
+ if (GS(tselem->id->name) == ID_OB && ((Object *)tselem->id)->mode & OB_MODE_POSE) {
+ /* pass */
+ }
else {
Bone *curBone;
for (curBone = arm->bonebase.first; curBone; curBone = curBone->next) {
@@ -811,9 +813,15 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
te->parent = parent;
te->index = index; // for data arays
- if (ELEM3(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) ;
- else if (ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) ;
- else if (type == TSE_ANIM_DATA) ;
+ if (ELEM3(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) {
+ /* pass */
+ }
+ else if (ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
+ /* pass */
+ }
+ else if (type == TSE_ANIM_DATA) {
+ /* pass */
+ }
else {
te->name = id->name + 2; // default, can be overridden by Library or non-ID data
te->idcode = GS(id->name);
@@ -1055,8 +1063,12 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
if (key[0]) {
wmOperatorType *ot = NULL;
- if (kmi->propvalue) ;
- else ot = WM_operatortype_find(kmi->idname, 0);
+ if (kmi->propvalue) {
+ /* pass */
+ }
+ else {
+ ot = WM_operatortype_find(kmi->idname, 0);
+ }
if (ot || kmi->propvalue) {
TreeElement *ten = outliner_add_element(soops, &te->subtree, kmi, te, TSE_KEYMAP_ITEM, a);
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 204930e82a6..82d08be4da2 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -579,7 +579,9 @@ static Sequence *del_seq_find_replace_recurs(Scene *scene, Sequence *seq)
seq2 = del_seq_find_replace_recurs(scene, seq->seq2);
seq3 = del_seq_find_replace_recurs(scene, seq->seq3);
- if (seq1 == seq->seq1 && seq2 == seq->seq2 && seq3 == seq->seq3) ;
+ if (seq1 == seq->seq1 && seq2 == seq->seq2 && seq3 == seq->seq3) {
+ /* pass */
+ }
else if (seq1 || seq2 || seq3) {
seq->seq1 = (seq1) ? seq1 : (seq2) ? seq2 : seq3;
seq->seq2 = (seq2) ? seq2 : (seq1) ? seq1 : seq3;
@@ -1572,7 +1574,7 @@ static int apply_unique_name_cb(Sequence *seq, void *arg_pt)
Scene *scene = (Scene *)arg_pt;
char name[sizeof(seq->name) - 2];
- strcpy(name, seq->name + 2);
+ BLI_strncpy_utf8(name, seq->name + 2, sizeof(name));
BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq);
BKE_sequencer_dupe_animdata(scene, name, seq->name + 2);
return 1;
@@ -1851,7 +1853,7 @@ void SEQUENCER_OT_images_separate(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_int(ot->srna, "length", 1, 1, 1000, "Length", "Length of each frame", 1, INT_MAX);
+ RNA_def_int(ot->srna, "length", 1, 1, INT_MAX, "Length", "Length of each frame", 1, 1000);
}
@@ -2186,7 +2188,7 @@ void SEQUENCER_OT_view_zoom_ratio(wmOperatorType *ot)
ot->poll = ED_operator_sequencer_active;
/* properties */
- RNA_def_float(ot->srna, "ratio", 1.0f, 0.0f, FLT_MAX,
+ RNA_def_float(ot->srna, "ratio", 1.0f, -FLT_MAX, FLT_MAX,
"Ratio", "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out", -FLT_MAX, FLT_MAX);
}
@@ -2618,7 +2620,6 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
- Sequence *seq;
ListBase nseqbase = {NULL, NULL};
@@ -2654,8 +2655,11 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op)
seqbase_clipboard_frame = scene->r.cfra;
/* Need to remove anything that references the current scene */
- for (seq = seqbase_clipboard.first; seq; seq = seq->next) {
- seq_copy_del_sound(scene, seq);
+ {
+ Sequence *seq;
+ for (seq = seqbase_clipboard.first; seq; seq = seq->next) {
+ seq_copy_del_sound(scene, seq);
+ }
}
return OPERATOR_FINISHED;
@@ -2738,7 +2742,7 @@ static int sequencer_swap_data_exec(bContext *C, wmOperator *op)
const char *error_msg;
if (BKE_sequencer_active_get_pair(scene, &seq_act, &seq_other) == 0) {
- BKE_report(op->reports, RPT_ERROR, "Must select 2 strips");
+ BKE_report(op->reports, RPT_ERROR, "Please select two strips");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index 5111d20b8ee..a68524fcdd6 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -1741,6 +1741,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
char linenr[12];
int i, x, y, winx, linecount = 0, lineno = 0;
int wraplinecount = 0, wrap_skip = 0;
+ int margin_column_x;
if (st->lheight) st->viewlines = (int)ar->winy / st->lheight;
else st->viewlines = 0;
@@ -1845,10 +1846,14 @@ void draw_text_main(SpaceText *st, ARegion *ar)
if (st->flags & ST_SHOW_MARGIN) {
UI_ThemeColor(TH_HILITE);
- glBegin(GL_LINES);
- glVertex2i(x + st->cwidth * st->margin_column, 0);
- glVertex2i(x + st->cwidth * st->margin_column, ar->winy - 2);
- glEnd();
+ margin_column_x = x + st->cwidth * (st->margin_column - st->left);
+
+ if (margin_column_x >= x) {
+ glBegin(GL_LINES);
+ glVertex2i(margin_column_x, 0);
+ glVertex2i(margin_column_x, ar->winy - 2);
+ glEnd();
+ }
}
/* draw other stuff */
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 75b8e2f218d..b2fb16ff7fe 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -3352,7 +3352,7 @@ void TEXT_OT_to_3d_object(wmOperatorType *ot)
/* identifiers */
ot->name = "To 3D Object";
ot->idname = "TEXT_OT_to_3d_object";
- ot->description = "Create 3d text object from active text data block";
+ ot->description = "Create 3D text object from active text data block";
/* api callbacks */
ot->exec = text_to_3d_object_exec;
diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt
index 1bba237ed5c..35dd88c3209 100644
--- a/source/blender/editors/space_view3d/CMakeLists.txt
+++ b/source/blender/editors/space_view3d/CMakeLists.txt
@@ -51,7 +51,9 @@ set(SRC
view3d_edit.c
view3d_fly.c
view3d_header.c
+ view3d_iterators.c
view3d_ops.c
+ view3d_project.c
view3d_select.c
view3d_snap.c
view3d_toolbar.c
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index ecce12b8cba..31df13343ce 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -2226,9 +2226,16 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt)
}
/* restore */
- if (index != -1) glLoadName(-1);
- if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) ;
- else if (dt > OB_WIRE) bglPolygonOffset(rv3d->dist, 0.0f);
+ if (index != -1) {
+ glLoadName(-1);
+ }
+
+ if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) {
+ /* pass */
+ }
+ else if (dt > OB_WIRE) {
+ bglPolygonOffset(rv3d->dist, 0.0f);
+ }
/* finally names and axes */
if (arm->flag & (ARM_DRAWNAMES | ARM_DRAWAXES)) {
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index e4c21a9c2c8..cded7bbbdfc 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -533,8 +533,7 @@ static void update_tface_color_layer(DerivedMesh *dm)
}
else {
float col[3];
- Material *ma = give_current_material(Gtexdraw.ob, mface[i].mat_nr + 1);
-
+
if (ma) {
if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
else copy_v3_v3(col, &ma->r);
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index df04cc33e71..ec54ae09fd2 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -27,10 +27,6 @@
* \ingroup spview3d
*/
-
-#include <string.h>
-#include <math.h>
-
#include "MEM_guardedalloc.h"
#include "DNA_camera_types.h"
@@ -40,21 +36,14 @@
#include "DNA_lattice_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_meta_types.h"
#include "DNA_scene_types.h"
#include "DNA_smoke_types.h"
-#include "DNA_speaker_types.h"
#include "DNA_world_types.h"
-#include "DNA_armature_types.h"
#include "DNA_object_types.h"
-#include "BLI_utildefines.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_edgehash.h"
-#include "BLI_rand.h"
-#include "BLI_utildefines.h"
#include "BKE_anim.h" /* for the where_on_path function */
#include "BKE_armature.h"
@@ -79,13 +68,10 @@
#include "BKE_pointcache.h"
#include "BKE_scene.h"
#include "BKE_unit.h"
-#include "BKE_movieclip.h"
#include "BKE_tracking.h"
#include "BKE_tessmesh.h"
-#include "smoke_API.h"
-
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -100,16 +86,13 @@
#include "ED_screen.h"
#include "ED_sculpt.h"
#include "ED_types.h"
-#include "ED_curve.h" /* for curve_editnurbs */
-#include "ED_armature.h"
#include "UI_resources.h"
#include "WM_api.h"
-#include "wm_subwindow.h"
#include "BLF_api.h"
-#include "view3d_intern.h" /* own include */
+#include "view3d_intern.h" /* bad level include */
typedef enum eWireDrawMode {
OBDRAW_WIRE_OFF = 0,
@@ -117,28 +100,6 @@ typedef enum eWireDrawMode {
OBDRAW_WIRE_ON_DEPTH = 2
} eWireDrawMode;
-/* user data structures for derived mesh callbacks */
-typedef struct foreachScreenVert_userData {
- void (*func)(void *userData, BMVert *eve, int x, int y, int index);
- void *userData;
- ViewContext vc;
- eV3DClipTest clipVerts;
-} foreachScreenVert_userData;
-
-typedef struct foreachScreenEdge_userData {
- void (*func)(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index);
- void *userData;
- ViewContext vc;
- rcti win_rect; /* copy of: vc.ar->winx/winy, use for faster tests, minx/y will always be 0 */
- eV3DClipTest clipVerts;
-} foreachScreenEdge_userData;
-
-typedef struct foreachScreenFace_userData {
- void (*func)(void *userData, BMFace *efa, int x, int y, int index);
- void *userData;
- ViewContext vc;
-} foreachScreenFace_userData;
-
typedef struct drawDMVerts_userData {
BMEditMesh *em; /* BMESH BRANCH ONLY */
@@ -784,10 +745,10 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa
mul_m4_v3(mat, vos->vec);
if (ED_view3d_project_short_ex(ar,
- (vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob,
- (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0,
- vos->vec, vos->sco,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
+ (vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob,
+ (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0,
+ vos->vec, vos->sco,
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK)
{
tot++;
}
@@ -858,7 +819,9 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa
if (depth_write) {
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
}
- else glDepthMask(1);
+ else {
+ glDepthMask(1);
+ }
glMatrixMode(GL_PROJECTION);
glPopMatrix();
@@ -900,7 +863,7 @@ static void drawcube(void)
glEnd();
}
-/* draws a cube on given the scaling of the cube, assuming that
+/* draws a cube on given the scaling of the cube, assuming that
* all required matrices have been set (used for drawing empties)
*/
static void drawcube_size(float size)
@@ -1284,8 +1247,10 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base,
glVertex3fv(tvec);
glEnd();
}
- else circ(0.0, 0.0, fabsf(z));
-
+ else {
+ circ(0.0, 0.0, fabsf(z));
+ }
+
/* draw the circle/square representing spotbl */
if (la->type == LA_SPOT) {
float spotblcirc = fabs(z) * (1 - pow(la->spotblend, 2));
@@ -1429,7 +1394,7 @@ static void draw_limit_line(float sta, float end, unsigned int col)
glVertex3f(0.0, 0.0, -end);
glEnd();
glPointSize(1.0);
-}
+}
/* yafray: draw camera focus point (cross, similar to aqsis code in tuhopuu) */
@@ -1870,29 +1835,6 @@ static void lattice_draw_verts(Lattice *lt, DispList *dl, short sel)
bglEnd();
}
-void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPoint *bp, int x, int y), void *userData)
-{
- Object *obedit = vc->obedit;
- Lattice *lt = obedit->data;
- BPoint *bp = lt->editlatt->latt->def;
- DispList *dl = BKE_displist_find(&obedit->disp, DL_VERTS);
- float *co = dl ? dl->verts : NULL;
- int i, N = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
-
- ED_view3d_clipping_local(vc->rv3d, obedit->obmat); /* for local clipping lookups */
-
- for (i = 0; i < N; i++, bp++, co += 3) {
- if (bp->hide == 0) {
- int screen_co[2];
- if (ED_view3d_project_int_object(vc->ar, dl ? co : bp->vec, screen_co,
- V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
- {
- func(userData, bp, screen_co[0], screen_co[1]);
- }
- }
- }
-}
-
static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, int use_wcol)
{
int index = ((w * lt->pntsv + v) * lt->pntsu) + u;
@@ -1979,53 +1921,6 @@ static void drawlattice(Scene *scene, View3D *v3d, Object *ob)
/* ***************** ******************** */
-/* Note! - foreach funcs should be called while drawing or directly after
- * if not, ED_view3d_init_mats_rv3d() can be used for selection tools
- * but would not give correct results with dupli's for eg. which don't
- * use the object matrix in the usual way */
-static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const float co[3],
- const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
-{
- foreachScreenVert_userData *data = userData;
- BMVert *eve = EDBM_vert_at_index(data->vc.em, index);
-
- if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- const eV3DProjTest flag = (data->clipVerts == V3D_CLIP_TEST_OFF) ?
- V3D_PROJ_TEST_NOP :
- V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN;
- int screen_co[2];
-
- if (ED_view3d_project_int_object(data->vc.ar, co, screen_co, flag) != V3D_PROJ_RET_SUCCESS) {
- return;
- }
-
- data->func(data->userData, eve, screen_co[0], screen_co[1], index);
- }
-}
-
-void mesh_foreachScreenVert(
- ViewContext *vc,
- void (*func)(void *userData, BMVert *eve, int x, int y, int index),
- void *userData, eV3DClipTest clipVerts)
-{
- foreachScreenVert_userData data;
- DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
-
- data.vc = *vc;
- data.func = func;
- data.userData = userData;
- data.clipVerts = clipVerts;
-
- if (clipVerts != V3D_CLIP_TEST_OFF)
- ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
-
- EDBM_index_arrays_init(vc->em, 1, 0, 0);
- dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data);
- EDBM_index_arrays_free(vc->em);
-
- dm->release(dm);
-}
-
/* draw callback */
static void drawSelectedVertices__mapFunc(void *userData, int index, const float co[3],
const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
@@ -2054,286 +1949,9 @@ static void drawSelectedVertices(DerivedMesh *dm, Mesh *me)
glEnd();
}
-static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const float v0co[3], const float v1co[3])
-{
- foreachScreenEdge_userData *data = userData;
- BMEdge *eed = EDBM_edge_at_index(data->vc.em, index);
-
- if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
- int screen_co_a[2];
- int screen_co_b[2];
-
- const eV3DProjTest flag = (data->clipVerts == V3D_CLIP_TEST_RV3D_CLIPPING) ?
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN :
- V3D_PROJ_TEST_NOP;
-
- if (ED_view3d_project_int_object(data->vc.ar, v0co, screen_co_a, flag) != V3D_PROJ_RET_SUCCESS) {
- return;
- }
- if (ED_view3d_project_int_object(data->vc.ar, v1co, screen_co_b, flag) != V3D_PROJ_RET_SUCCESS) {
- return;
- }
-
- if (data->clipVerts == V3D_CLIP_TEST_RV3D_CLIPPING) {
- /* pass */
- }
- else {
- if (data->clipVerts == V3D_CLIP_TEST_REGION) {
- if (!BLI_rcti_isect_segment(&data->win_rect, screen_co_a, screen_co_b)) {
- return;
- }
- }
- }
-
- data->func(data->userData, eed,
- screen_co_a[0], screen_co_a[1],
- screen_co_b[0], screen_co_b[1], index);
- }
-}
-
-void mesh_foreachScreenEdge(
- ViewContext *vc,
- void (*func)(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index),
- void *userData, eV3DClipTest clipVerts)
-{
- foreachScreenEdge_userData data;
- DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
-
- data.vc = *vc;
-
- data.win_rect.xmin = 0;
- data.win_rect.ymin = 0;
- data.win_rect.xmax = vc->ar->winx;
- data.win_rect.ymax = vc->ar->winy;
-
- data.func = func;
- data.userData = userData;
- data.clipVerts = clipVerts;
-
- if (clipVerts != V3D_CLIP_TEST_OFF)
- ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
-
- EDBM_index_arrays_init(vc->em, 0, 1, 0);
- dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data);
- EDBM_index_arrays_free(vc->em);
-
- dm->release(dm);
-}
-
-static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const float cent[3], const float UNUSED(no[3]))
-{
- foreachScreenFace_userData *data = userData;
- BMFace *efa = EDBM_face_at_index(data->vc.em, index);
-
- if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
- int screen_co[2];
- if (ED_view3d_project_int_object(data->vc.ar, cent, screen_co,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
- {
- data->func(data->userData, efa, screen_co[0], screen_co[1], index);
- }
- }
-}
-
-void mesh_foreachScreenFace(
- ViewContext *vc,
- void (*func)(void *userData, BMFace *efa, int x, int y, int index),
- void *userData)
-{
- foreachScreenFace_userData data;
- DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
-
- data.vc = *vc;
- data.func = func;
- data.userData = userData;
-
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
-
- EDBM_index_arrays_init(vc->em, 0, 0, 1);
- dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data);
- EDBM_index_arrays_free(vc->em);
-
- dm->release(dm);
-}
-
-void nurbs_foreachScreenVert(
- ViewContext *vc,
- void (*func)(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y),
- void *userData)
-{
- Curve *cu = vc->obedit->data;
- Nurb *nu;
- int i;
- ListBase *nurbs = BKE_curve_editNurbs_get(cu);
-
- ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
-
- for (nu = nurbs->first; nu; nu = nu->next) {
- if (nu->type == CU_BEZIER) {
- for (i = 0; i < nu->pntsu; i++) {
- BezTriple *bezt = &nu->bezt[i];
-
- if (bezt->hide == 0) {
- int screen_co[2];
-
- if (cu->drawflag & CU_HIDE_HANDLES) {
- if (ED_view3d_project_int_object(vc->ar, bezt->vec[1], screen_co,
- V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
- {
- func(userData, nu, NULL, bezt, 1, screen_co[0], screen_co[1]);
- }
- }
- else {
- if (ED_view3d_project_int_object(vc->ar, bezt->vec[0], screen_co,
- V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
- {
- func(userData, nu, NULL, bezt, 0, screen_co[0], screen_co[1]);
- }
- if (ED_view3d_project_int_object(vc->ar, bezt->vec[1], screen_co,
- V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
- {
- func(userData, nu, NULL, bezt, 1, screen_co[0], screen_co[1]);
- }
- if (ED_view3d_project_int_object(vc->ar, bezt->vec[2], screen_co,
- V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
- {
- func(userData, nu, NULL, bezt, 2, screen_co[0], screen_co[1]);
- }
- }
- }
- }
- }
- else {
- for (i = 0; i < nu->pntsu * nu->pntsv; i++) {
- BPoint *bp = &nu->bp[i];
-
- if (bp->hide == 0) {
- int screen_co[2];
- if (ED_view3d_project_int_object(vc->ar, bp->vec, screen_co,
- V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
- {
- func(userData, nu, bp, NULL, -1, screen_co[0], screen_co[1]);
- }
- }
- }
- }
- }
-}
-
-/* ED_view3d_init_mats_rv3d must be called first */
-void mball_foreachScreenElem(
- struct ViewContext *vc,
- void (*func)(void *userData, struct MetaElem *ml, int x, int y),
- void *userData)
-{
- MetaBall *mb = (MetaBall *)vc->obedit->data;
- MetaElem *ml;
-
- for (ml = mb->editelems->first; ml; ml = ml->next) {
- int screen_co[2];
- if (ED_view3d_project_int_object(vc->ar, &ml->x, screen_co,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
- {
- func(userData, ml, screen_co[0], screen_co[1]);
- }
- }
-}
-
-/* ED_view3d_init_mats_rv3d must be called first */
-void armature_foreachScreenBone(
- struct ViewContext *vc,
- void (*func)(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1),
- void *userData)
-{
- bArmature *arm = vc->obedit->data;
- EditBone *ebone;
-
- for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
- if (EBONE_VISIBLE(arm, ebone)) {
- int screen_co_a[2], screen_co_b[2];
- int points_proj_tot = 0;
-
- /* project head location to screenspace */
- if (ED_view3d_project_int_object(vc->ar, ebone->head, screen_co_a,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
- {
- points_proj_tot++;
- }
- else {
- screen_co_a[0] = IS_CLIPPED; /* weak */
- /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */
- }
-
- /* project tail location to screenspace */
- if (ED_view3d_project_int_object(vc->ar, ebone->tail, screen_co_b,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
- {
- points_proj_tot++;
- }
- else {
- screen_co_b[0] = IS_CLIPPED; /* weak */
- /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */
- }
-
- if (points_proj_tot) { /* at least one point's projection worked */
- func(userData, ebone,
- screen_co_a[0], screen_co_a[1],
- screen_co_b[0], screen_co_b[1]);
- }
- }
- }
-}
-
-/* ED_view3d_init_mats_rv3d must be called first */
-/* almost _exact_ copy of #armature_foreachScreenBone */
-void pose_foreachScreenBone(
- struct ViewContext *vc,
- void (*func)(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1),
- void *userData)
-{
- bArmature *arm = vc->obact->data;
- bPose *pose = vc->obact->pose;
- bPoseChannel *pchan;
-
- for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
- if (PBONE_VISIBLE(arm, pchan->bone)) {
- int screen_co_a[2], screen_co_b[2];
- int points_proj_tot = 0;
-
- /* project head location to screenspace */
- if (ED_view3d_project_int_object(vc->ar, pchan->pose_head, screen_co_a,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
- {
- points_proj_tot++;
- }
- else {
- screen_co_a[0] = IS_CLIPPED; /* weak */
- /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */
- }
-
- /* project tail location to screenspace */
- if (ED_view3d_project_int_object(vc->ar, pchan->pose_tail, screen_co_b,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
- {
- points_proj_tot++;
- }
- else {
- screen_co_b[0] = IS_CLIPPED; /* weak */
- /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */
- }
-
- if (points_proj_tot) { /* at least one point's projection worked */
- func(userData, pchan,
- screen_co_a[0], screen_co_a[1],
- screen_co_b[0], screen_co_b[1]);
- }
- }
- }
-}
-
/* ************** DRAW MESH ****************** */
-/* First section is all the "simple" draw routines,
+/* First section is all the "simple" draw routines,
* ones that just pass some sort of primitive to GL,
* with perhaps various options to control lighting,
* color, etc.
@@ -2568,7 +2186,7 @@ static DMDrawOption draw_dm_edges_sel__setDrawOptions(void *userData, int index)
return DM_DRAW_OPTION_SKIP;
}
}
-static void draw_dm_edges_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol,
+static void draw_dm_edges_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol,
unsigned char *selCol, unsigned char *actCol, BMEdge *eed_act)
{
drawDMEdgesSel_userData data;
@@ -2590,7 +2208,7 @@ static DMDrawOption draw_dm_edges__setDrawOptions(void *userData, int index)
return DM_DRAW_OPTION_NORMAL;
}
-static void draw_dm_edges(BMEditMesh *em, DerivedMesh *dm)
+static void draw_dm_edges(BMEditMesh *em, DerivedMesh *dm)
{
dm->drawMappedEdges(dm, draw_dm_edges__setDrawOptions, em);
}
@@ -2729,7 +2347,7 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int
}
/* also draws the active face */
-static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol,
+static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol,
unsigned char *selCol, unsigned char *markCol, unsigned char *actCol, BMFace *efa_act)
{
drawDMFacesSel_userData data;
@@ -2827,9 +2445,9 @@ static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm)
/* EditMesh drawing routines*/
-static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit,
+static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit,
BMEditMesh *em, DerivedMesh *cageDM, BMVert *eve_act,
- RegionView3D *rv3d)
+ RegionView3D *rv3d)
{
ToolSettings *ts = scene->toolsettings;
int sel;
@@ -2949,7 +2567,7 @@ static void draw_em_fancy_edges(BMEditMesh *em, Scene *scene, View3D *v3d,
glEnable(GL_DEPTH_TEST);
}
}
-}
+}
static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitSettings *unit)
{
@@ -3214,7 +2832,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
if (ese->type == BM_FACE) {
efa_act = (BMFace *)ese->data;
}
- else
+ else
#endif
if (ese->htype == BM_EDGE) {
eed_act = (BMEdge *)ese->ele;
@@ -3397,13 +3015,12 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d,
static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm)
{
-
if ((v3d->transp == FALSE) && /* not when we draw the transparent pass */
(ob->mode & OB_MODE_ALL_PAINT) == FALSE) /* not when painting (its distracting) - campbell */
{
glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
glDepthMask(0);
-
+
/* if transparent, we cannot draw the edges for solid select... edges have no material info.
* drawFacesSolid() doesn't draw the transparent faces */
if (ob->dtx & OB_DRAWTRANSP) {
@@ -5896,7 +5513,7 @@ static void drawspiral(const float cent[3], float rad, float tmat[][4], int star
glEnd();
}
-/* draws a circle on x-z plane given the scaling of the circle, assuming that
+/* draws a circle on x-z plane given the scaling of the circle, assuming that
* all required matrices have been set (used for drawing empties)
*/
static void drawcircle_size(float size)
@@ -7041,72 +6658,76 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
}
/* only draw domains */
- if (smd->domain && smd->domain->fluid) {
- if (CFRA < smd->domain->point_cache[0]->startframe) {
- /* don't show smoke before simulation starts, this could be made an option in the future */
- }
- else if (!smd->domain->wt || !(smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) {
-// #if 0
- smd->domain->tex = NULL;
- GPU_create_smoke(smd, 0);
- draw_volume(ar, smd->domain->tex,
- smd->domain->p0, smd->domain->p1,
- smd->domain->res, smd->domain->dx,
- smd->domain->tex_shadow);
- GPU_free_smoke(smd);
-// #endif
-#if 0
- int x, y, z;
- float *density = smoke_get_density(smd->domain->fluid);
+ if (smd->domain) {
+ SmokeDomainSettings *sds = smd->domain;
+ float p0[3], p1[3], viewnormal[3];
+ BoundBox bb;
- glLoadMatrixf(rv3d->viewmat);
- // glMultMatrixf(ob->obmat);
+ glLoadMatrixf(rv3d->viewmat);
+ glMultMatrixf(ob->obmat);
- if (col || (ob->flag & SELECT)) cpack(0xFFFFFF);
- glDepthMask(GL_FALSE);
- glEnable(GL_BLEND);
-
+ /* draw adaptive domain bounds */
+ if (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) {
+ /* draw domain max bounds */
+ VECSUBFAC(p0, sds->p0, sds->cell_size, sds->adapt_res);
+ VECADDFAC(p1, sds->p1, sds->cell_size, sds->adapt_res);
+ BKE_boundbox_init_from_minmax(&bb, p0, p1);
+ draw_box(bb.vec);
- // glPointSize(3.0);
- bglBegin(GL_POINTS);
+ /* draw base resolution bounds */
+#if 0
+ BKE_boundbox_init_from_minmax(&bb, sds->p0, sds->p1);
+ draw_box(bb.vec);
+#endif
+ }
- for (x = 0; x < smd->domain->res[0]; x++) {
- for (y = 0; y < smd->domain->res[1]; y++) {
- for (z = 0; z < smd->domain->res[2]; z++) {
- float tmp[3];
- int index = smoke_get_index(x, smd->domain->res[0], y, smd->domain->res[1], z);
-
- if (density[index] > FLT_EPSILON) {
- float color[3];
- copy_v3_v3(tmp, smd->domain->p0);
- tmp[0] += smd->domain->dx * x + smd->domain->dx * 0.5;
- tmp[1] += smd->domain->dx * y + smd->domain->dx * 0.5;
- tmp[2] += smd->domain->dx * z + smd->domain->dx * 0.5;
- color[0] = color[1] = color[2] = density[index];
- glColor3fv(color);
- bglVertex3fv(tmp);
- }
- }
- }
+ /* don't show smoke before simulation starts, this could be made an option in the future */
+ if (smd->domain->fluid && CFRA >= smd->domain->point_cache[0]->startframe) {
+
+ // get view vector
+ copy_v3_v3(viewnormal, rv3d->viewinv[2]);
+ mul_mat3_m4_v3(ob->imat, viewnormal);
+ normalize_v3(viewnormal);
+
+ /* set dynamic boundaries to draw the volume */
+ p0[0] = sds->p0[0] + sds->cell_size[0] * sds->res_min[0] + sds->obj_shift_f[0];
+ p0[1] = sds->p0[1] + sds->cell_size[1] * sds->res_min[1] + sds->obj_shift_f[1];
+ p0[2] = sds->p0[2] + sds->cell_size[2] * sds->res_min[2] + sds->obj_shift_f[2];
+ p1[0] = sds->p0[0] + sds->cell_size[0] * sds->res_max[0] + sds->obj_shift_f[0];
+ p1[1] = sds->p0[1] + sds->cell_size[1] * sds->res_max[1] + sds->obj_shift_f[1];
+ p1[2] = sds->p0[2] + sds->cell_size[2] * sds->res_max[2] + sds->obj_shift_f[2];
+
+ /* scale cube to global space to equalize volume slicing on all axises
+ * (its scaled back before drawing) */
+ mul_v3_v3(p0, ob->size);
+ mul_v3_v3(p1, ob->size);
+
+ if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) {
+ smd->domain->tex = NULL;
+ GPU_create_smoke(smd, 0);
+ draw_smoke_volume(sds, ob, sds->tex,
+ p0, p1,
+ sds->res, sds->dx, sds->scale * sds->maxres,
+ viewnormal, sds->tex_shadow, sds->tex_flame);
+ GPU_free_smoke(smd);
+ }
+ else if (sds->wt && (sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) {
+ sds->tex = NULL;
+ GPU_create_smoke(smd, 1);
+ draw_smoke_volume(sds, ob, sds->tex,
+ p0, p1,
+ sds->res_wt, sds->dx, sds->scale * sds->maxres,
+ viewnormal, sds->tex_shadow, sds->tex_flame);
+ GPU_free_smoke(smd);
}
- bglEnd();
- glPointSize(1.0);
-
- glMultMatrixf(ob->obmat);
- glDisable(GL_BLEND);
- glDepthMask(GL_TRUE);
- if (col) cpack(col);
+ /* smoke debug render */
+#ifdef SMOKE_DEBUG_VELOCITY
+ draw_smoke_velocity(smd->domain, ob);
+#endif
+#ifdef SMOKE_DEBUG_HEAT
+ draw_smoke_heat(smd->domain, ob);
#endif
- }
- else if (smd->domain->wt && (smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) {
- smd->domain->tex = NULL;
- GPU_create_smoke(smd, 1);
- draw_volume(ar, smd->domain->tex,
- smd->domain->p0, smd->domain->p1,
- smd->domain->res_wt, smd->domain->dx_wt,
- smd->domain->tex_shadow);
- GPU_free_smoke(smd);
}
}
}
@@ -7368,7 +6989,7 @@ static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *dm, int offset)
dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, ptrs);
bglEnd();
glPointSize(1.0);
-}
+}
static DMDrawOption bbs_mesh_wire__setDrawOptions(void *userData, int index)
{
@@ -7388,7 +7009,7 @@ static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *dm, int offset)
{
void *ptrs[2] = {(void *)(intptr_t) offset, em};
dm->drawMappedEdges(dm, bbs_mesh_wire__setDrawOptions, ptrs);
-}
+}
static DMDrawOption bbs_mesh_solid__setSolidDrawOptions(void *userData, int index)
{
@@ -7567,7 +7188,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
/* assumes all matrices/etc set OK */
/* helper function for drawing object instances - meshes */
-static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d,
+static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d,
Object *ob, const short dt, int outline)
{
Mesh *me = ob->data;
diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c
index 2c2d4039225..ebb48960b80 100644
--- a/source/blender/editors/space_view3d/drawvolume.c
+++ b/source/blender/editors/space_view3d/drawvolume.c
@@ -36,6 +36,7 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
+#include "DNA_smoke_types.h"
#include "DNA_view3d_types.h"
#include "BLI_utildefines.h"
@@ -132,7 +133,7 @@ static int intersect_edges(float *points, float a, float b, float c, float d, fl
int i;
float t;
int numpoints = 0;
-
+
for (i = 0; i < 12; i++) {
t = -(a * edges[i][0][0] + b * edges[i][0][1] + c * edges[i][0][2] + d) /
(a * edges[i][1][0] + b * edges[i][1][1] + c * edges[i][1][2]);
@@ -156,12 +157,12 @@ static int convex(const float p0[3], const float up[3], const float a[3], const
return dot_v3v3(up, tmp) >= 0;
}
-void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int res[3], float dx, GPUTexture *tex_shadow)
+void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob,
+ GPUTexture *tex, float min[3], float max[3],
+ int res[3], float dx, float UNUSED(base_scale), float viewnormal[3],
+ GPUTexture *tex_shadow, GPUTexture *tex_flame)
{
- RegionView3D *rv3d = ar->regiondata;
-
- float viewnormal[3];
- int i, j, n, good_index;
+ int i, j, k, n, good_index;
float d /*, d0 */ /* UNUSED */, dd, ds;
float *points = NULL;
int numpoints = 0;
@@ -193,25 +194,76 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r
{{-1.0f, 1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}}
};
+ unsigned char *spec_data;
+ float *spec_pixels;
+ GPUTexture *tex_spec;
+
/* Fragment program to calculate the view3d of smoke */
- /* using 2 textures, density and shadow */
- const char *text = "!!ARBfp1.0\n"
- "PARAM dx = program.local[0];\n"
- "PARAM darkness = program.local[1];\n"
- "PARAM f = {1.442695041, 1.442695041, 1.442695041, 0.01};\n"
- "TEMP temp, shadow, value;\n"
- "TEX temp, fragment.texcoord[0], texture[0], 3D;\n"
- "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n"
- "MUL value, temp, darkness;\n"
- "MUL value, value, dx;\n"
- "MUL value, value, f;\n"
- "EX2 temp, -value.r;\n"
- "SUB temp.a, 1.0, temp.r;\n"
- "MUL temp.r, temp.r, shadow.r;\n"
- "MUL temp.g, temp.g, shadow.r;\n"
- "MUL temp.b, temp.b, shadow.r;\n"
- "MOV result.color, temp;\n"
- "END\n";
+ /* using 4 textures, density, shadow, flame and flame spectrum */
+ const char *shader_basic =
+ "!!ARBfp1.0\n"
+ "PARAM dx = program.local[0];\n"
+ "PARAM darkness = program.local[1];\n"
+ "PARAM render = program.local[2];\n"
+ "PARAM f = {1.442695041, 1.442695041, 1.442695041, 0.01};\n"
+ "TEMP temp, shadow, flame, spec, value;\n"
+ "TEX temp, fragment.texcoord[0], texture[0], 3D;\n"
+ "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n"
+ "TEX flame, fragment.texcoord[0], texture[2], 3D;\n"
+ "TEX spec, flame.r, texture[3], 1D;\n"
+ /* calculate shading factor from density */
+ "MUL value.r, temp.a, darkness.a;\n"
+ "MUL value.r, value.r, dx.r;\n"
+ "MUL value.r, value.r, f.r;\n"
+ "EX2 temp, -value.r;\n"
+ /* alpha */
+ "SUB temp.a, 1.0, temp.r;\n"
+ /* shade colors */
+ "MUL temp.r, temp.r, shadow.r;\n"
+ "MUL temp.g, temp.g, shadow.r;\n"
+ "MUL temp.b, temp.b, shadow.r;\n"
+ "MUL temp.r, temp.r, darkness.r;\n"
+ "MUL temp.g, temp.g, darkness.g;\n"
+ "MUL temp.b, temp.b, darkness.b;\n"
+ /* for now this just replace smoke shading if rendering fire */
+ "CMP result.color, render.r, temp, spec;\n"
+ "END\n";
+
+ /* color shader */
+ const char *shader_color =
+ "!!ARBfp1.0\n"
+ "PARAM dx = program.local[0];\n"
+ "PARAM darkness = program.local[1];\n"
+ "PARAM render = program.local[2];\n"
+ "PARAM f = {1.442695041, 1.442695041, 1.442695041, 1.442695041};\n"
+ "TEMP temp, shadow, flame, spec, value;\n"
+ "TEX temp, fragment.texcoord[0], texture[0], 3D;\n"
+ "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n"
+ "TEX flame, fragment.texcoord[0], texture[2], 3D;\n"
+ "TEX spec, flame.r, texture[3], 1D;\n"
+ /* unpremultiply volume texture */
+ "RCP value.r, temp.a;\n"
+ "MUL temp.r, temp.r, value.r;\n"
+ "MUL temp.g, temp.g, value.r;\n"
+ "MUL temp.b, temp.b, value.r;\n"
+ /* calculate shading factor from density */
+ "MUL value.r, temp.a, darkness.a;\n"
+ "MUL value.r, value.r, dx.r;\n"
+ "MUL value.r, value.r, f.r;\n"
+ "EX2 value.r, -value.r;\n"
+ /* alpha */
+ "SUB temp.a, 1.0, value.r;\n"
+ /* shade colors */
+ "MUL temp.r, temp.r, shadow.r;\n"
+ "MUL temp.g, temp.g, shadow.r;\n"
+ "MUL temp.b, temp.b, shadow.r;\n"
+ "MUL temp.r, temp.r, value.r;\n"
+ "MUL temp.g, temp.g, value.r;\n"
+ "MUL temp.b, temp.b, value.r;\n"
+ /* for now this just replace smoke shading if rendering fire */
+ "CMP result.color, render.r, temp, spec;\n"
+ "END\n";
+
GLuint prog;
@@ -223,6 +275,33 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r
}
tstart();
+ /* generate flame spectrum texture */
+ #define SPEC_WIDTH 256
+ #define FIRE_THRESH 7
+ #define MAX_FIRE_ALPHA 0.06f
+ #define FULL_ON_FIRE 100
+ spec_data = malloc(SPEC_WIDTH * 4 * sizeof(unsigned char));
+ flame_get_spectrum(spec_data, SPEC_WIDTH, 1500, 3000);
+ spec_pixels = malloc(SPEC_WIDTH * 4 * 16 * 16 * sizeof(float));
+ for (i = 0; i < 16; i++) {
+ for (j = 0; j < 16; j++) {
+ for (k = 0; k < SPEC_WIDTH; k++) {
+ int index = (j * SPEC_WIDTH * 16 + i * SPEC_WIDTH + k) * 4;
+ if (k >= FIRE_THRESH) {
+ spec_pixels[index] = ((float)spec_data[k * 4]) / 255.0f;
+ spec_pixels[index + 1] = ((float)spec_data[k * 4 + 1]) / 255.0f;
+ spec_pixels[index + 2] = ((float)spec_data[k * 4 + 2]) / 255.0f;
+ spec_pixels[index + 3] = MAX_FIRE_ALPHA * (
+ (k > FULL_ON_FIRE) ? 1.0f : (k - FIRE_THRESH) / ((float)FULL_ON_FIRE - FIRE_THRESH));
+ }
+ else {
+ spec_pixels[index] = spec_pixels[index + 1] = spec_pixels[index + 2] = spec_pixels[index + 3] = 0.0f;
+ }
+ }
+ }
+ }
+
+ tex_spec = GPU_texture_create_1D(SPEC_WIDTH, spec_pixels, NULL);
sub_v3_v3v3(size, max, min);
@@ -296,32 +375,17 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r
glGetBooleanv(GL_BLEND, (GLboolean *)&gl_blend);
glGetBooleanv(GL_DEPTH_TEST, (GLboolean *)&gl_depth);
- glLoadMatrixf(rv3d->viewmat);
- // glMultMatrixf(ob->obmat);
-
glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-#if 0
- printf("Viewinv:\n");
- printf("%f, %f, %f\n", rv3d->viewinv[0][0], rv3d->viewinv[0][1], rv3d->viewinv[0][2]);
- printf("%f, %f, %f\n", rv3d->viewinv[1][0], rv3d->viewinv[1][1], rv3d->viewinv[1][2]);
- printf("%f, %f, %f\n", rv3d->viewinv[2][0], rv3d->viewinv[2][1], rv3d->viewinv[2][2]);
-#endif
-
- /* get view vector */
- copy_v3_v3(viewnormal, rv3d->viewinv[2]);
- normalize_v3(viewnormal);
/* find cube vertex that is closest to the viewer */
for (i = 0; i < 8; i++) {
float x, y, z;
- x = cv[i][0] - viewnormal[0]*size[0]*0.5f;
- y = cv[i][1] - viewnormal[1]*size[1]*0.5f;
- z = cv[i][2] - viewnormal[2]*size[2]*0.5f;
+ x = cv[i][0] - viewnormal[0] * size[0] * 0.5f;
+ y = cv[i][1] - viewnormal[1] * size[1] * 0.5f;
+ z = cv[i][2] - viewnormal[2] * size[2] * 0.5f;
if ((x >= min[0]) && (x <= max[0]) &&
(y >= min[1]) && (y <= max[1]) &&
@@ -344,12 +408,19 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r
glGenProgramsARB(1, &prog);
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prog);
- glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(text), text);
+ /* set shader */
+ if (sds->active_fields & SM_ACTIVE_COLORS)
+ glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(shader_color), shader_color);
+ else
+ glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(shader_basic), shader_basic);
/* cell spacing */
glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, dx, dx, dx, 1.0);
/* custom parameter for smoke style (higher = thicker) */
- glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 7.0, 7.0, 7.0, 1.0);
+ if (sds->active_fields & SM_ACTIVE_COLORS)
+ glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 1.0, 1.0, 1.0, 10.0);
+ else
+ glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, sds->active_color[0], sds->active_color[1], sds->active_color[2], 10.0);
}
else
printf("Your gfx card does not support 3D View smoke drawing.\n");
@@ -360,6 +431,11 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r
else
printf("No volume shadow\n");
+ if (tex_flame) {
+ GPU_texture_bind(tex_flame, 2);
+ GPU_texture_bind(tex_spec, 3);
+ }
+
if (!GPU_non_power_of_two_support()) {
cor[0] = (float)res[0] / (float)power_of_2_max_i(res[0]);
cor[1] = (float)res[1] / (float)power_of_2_max_i(res[1]);
@@ -373,7 +449,7 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r
/* d0 = (viewnormal[0]*cv[i][0] + viewnormal[1]*cv[i][1] + viewnormal[2]*cv[i][2]); */ /* UNUSED */
ds = (ABS(viewnormal[0]) * size[0] + ABS(viewnormal[1]) * size[1] + ABS(viewnormal[2]) * size[2]);
- dd = ds / 96.f;
+ dd = MAX3(sds->global_size[0], sds->global_size[1], sds->global_size[2]) / 128.f;
n = 0;
good_index = i;
@@ -416,14 +492,29 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r
}
}
- // printf("numpoints: %d\n", numpoints);
+ /* render fire slice */
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+ glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, 1.0, 0.0, 0.0, 0.0);
+ glBegin(GL_POLYGON);
+ glColor3f(1.0, 1.0, 1.0);
+ for (i = 0; i < numpoints; i++) {
+ glTexCoord3d((points[i * 3 + 0] - min[0]) * cor[0] / size[0],
+ (points[i * 3 + 1] - min[1]) * cor[1] / size[1],
+ (points[i * 3 + 2] - min[2]) * cor[2] / size[2]);
+ glVertex3f(points[i * 3 + 0] / ob->size[0], points[i * 3 + 1] / ob->size[1], points[i * 3 + 2] / ob->size[2]);
+ }
+ glEnd();
+
+ /* render smoke slice */
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, -1.0, 0.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glColor3f(1.0, 1.0, 1.0);
for (i = 0; i < numpoints; i++) {
glTexCoord3d((points[i * 3 + 0] - min[0]) * cor[0] / size[0],
(points[i * 3 + 1] - min[1]) * cor[1] / size[1],
(points[i * 3 + 2] - min[2]) * cor[2] / size[2]);
- glVertex3f(points[i * 3 + 0], points[i * 3 + 1], points[i * 3 + 2]);
+ glVertex3f(points[i * 3 + 0] / ob->size[0], points[i * 3 + 1] / ob->size[1], points[i * 3 + 2] / ob->size[2]);
}
glEnd();
}
@@ -436,6 +527,14 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r
if (tex_shadow)
GPU_texture_unbind(tex_shadow);
GPU_texture_unbind(tex);
+ if (tex_flame) {
+ GPU_texture_unbind(tex_flame);
+ GPU_texture_unbind(tex_spec);
+ }
+ GPU_texture_free(tex_spec);
+
+ free(spec_data);
+ free(spec_pixels);
if (GLEW_ARB_fragment_program) {
glDisable(GL_FRAGMENT_PROGRAM_ARB);
@@ -451,6 +550,109 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r
if (gl_depth) {
glEnable(GL_DEPTH_TEST);
- glDepthMask(GL_TRUE);
+ glDepthMask(GL_TRUE);
}
}
+
+#ifdef SMOKE_DEBUG_VELOCITY
+void draw_smoke_velocity(SmokeDomainSettings *domain, Object *ob)
+{
+ float x, y, z;
+ float x0, y0, z0;
+ int *base_res = domain->base_res;
+ int *res = domain->res;
+ int *res_min = domain->res_min;
+ int *res_max = domain->res_max;
+ float *vel_x = smoke_get_velocity_x(domain->fluid);
+ float *vel_y = smoke_get_velocity_y(domain->fluid);
+ float *vel_z = smoke_get_velocity_z(domain->fluid);
+
+ float min[3];
+ float *cell_size = domain->cell_size;
+ float step_size = ((float)MAX3(base_res[0], base_res[1], base_res[2])) / 16.f;
+ float vf = domain->scale / 16.f * 2.f; /* velocity factor */
+
+ glLineWidth(1.0f);
+
+ /* set first position so that it doesn't jump when domain moves */
+ x0 = res_min[0] + fmod(-(float)domain->shift[0] + res_min[0], step_size);
+ y0 = res_min[1] + fmod(-(float)domain->shift[1] + res_min[1], step_size);
+ z0 = res_min[2] + fmod(-(float)domain->shift[2] + res_min[2], step_size);
+ if (x0 < res_min[0]) x0 += step_size;
+ if (y0 < res_min[1]) y0 += step_size;
+ if (z0 < res_min[2]) z0 += step_size;
+ add_v3_v3v3(min, domain->p0, domain->obj_shift_f);
+
+ for (x = floor(x0); x < res_max[0]; x += step_size)
+ for (y = floor(y0); y < res_max[1]; y += step_size)
+ for (z = floor(z0); z < res_max[2]; z += step_size) {
+ int index = (floor(x) - res_min[0]) + (floor(y) - res_min[1]) * res[0] + (floor(z) - res_min[2]) * res[0] * res[1];
+
+ float pos[3] = {min[0] + ((float)x + 0.5f) * cell_size[0], min[1] + ((float)y + 0.5f) * cell_size[1], min[2] + ((float)z + 0.5f) * cell_size[2]};
+ float vel = sqrtf(vel_x[index] * vel_x[index] + vel_y[index] * vel_y[index] + vel_z[index] * vel_z[index]);
+
+ /* draw heat as scaled "arrows" */
+ if (vel >= 0.01f) {
+ float col_g = 1.0f - vel;
+ CLAMP(col_g, 0.0f, 1.0f);
+ glColor3f(1.0f, col_g, 0.0f);
+ glPointSize(10.0f * vel);
+
+ glBegin(GL_LINES);
+ glVertex3f(pos[0], pos[1], pos[2]);
+ glVertex3f(pos[0] + vel_x[index] * vf, pos[1] + vel_y[index] * vf, pos[2] + vel_z[index] * vf);
+ glEnd();
+ glBegin(GL_POINTS);
+ glVertex3f(pos[0] + vel_x[index] * vf, pos[1] + vel_y[index] * vf, pos[2] + vel_z[index] * vf);
+ glEnd();
+ }
+ }
+}
+#endif
+
+#ifdef SMOKE_DEBUG_HEAT
+void draw_smoke_heat(SmokeDomainSettings *domain, Object *ob)
+{
+ float x, y, z;
+ float x0, y0, z0;
+ int *base_res = domain->base_res;
+ int *res = domain->res;
+ int *res_min = domain->res_min;
+ int *res_max = domain->res_max;
+ float *heat = smoke_get_heat(domain->fluid);
+
+ float min[3];
+ float *cell_size = domain->cell_size;
+ float step_size = ((float)MAX3(base_res[0], base_res[1], base_res[2])) / 16.f;
+ float vf = domain->scale / 16.f * 2.f; /* velocity factor */
+
+ /* set first position so that it doesn't jump when domain moves */
+ x0 = res_min[0] + fmod(-(float)domain->shift[0] + res_min[0], step_size);
+ y0 = res_min[1] + fmod(-(float)domain->shift[1] + res_min[1], step_size);
+ z0 = res_min[2] + fmod(-(float)domain->shift[2] + res_min[2], step_size);
+ if (x0 < res_min[0]) x0 += step_size;
+ if (y0 < res_min[1]) y0 += step_size;
+ if (z0 < res_min[2]) z0 += step_size;
+ add_v3_v3v3(min, domain->p0, domain->obj_shift_f);
+
+ for (x = floor(x0); x < res_max[0]; x += step_size)
+ for (y = floor(y0); y < res_max[1]; y += step_size)
+ for (z = floor(z0); z < res_max[2]; z += step_size) {
+ int index = (floor(x) - res_min[0]) + (floor(y) - res_min[1]) * res[0] + (floor(z) - res_min[2]) * res[0] * res[1];
+
+ float pos[3] = {min[0] + ((float)x + 0.5f) * cell_size[0], min[1] + ((float)y + 0.5f) * cell_size[1], min[2] + ((float)z + 0.5f) * cell_size[2]};
+
+ /* draw heat as different sized points */
+ if (heat[index] >= 0.01f) {
+ float col_gb = 1.0f - heat[index];
+ CLAMP(col_gb, 0.0f, 1.0f);
+ glColor3f(1.0f, col_gb, col_gb);
+ glPointSize(24.0f * heat[index]);
+
+ glBegin(GL_POINTS);
+ glVertex3f(pos[0], pos[1], pos[2]);
+ glEnd();
+ }
+ }
+}
+#endif
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index c8aca5674a4..9755c7d1b7c 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -86,13 +86,15 @@
#define B_REDR 2
#define B_OBJECTPANELMEDIAN 1008
+#define NBR_TRANSFORM_PROPERTIES 7
+
/* temporary struct for storing transform properties */
typedef struct {
float ob_eul[4]; /* used for quat too... */
float ob_scale[3]; /* need temp space due to linked values */
float ob_dims[3];
short link_scale;
- float ve_median[9];
+ float ve_median[NBR_TRANSFORM_PROPERTIES];
int curdef;
float *defweightp;
} TransformProperties;
@@ -131,17 +133,38 @@ static float compute_scale_factor(const float ve_median, const float median)
/* is used for both read and write... */
static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim)
{
+/* Get rid of those ugly magic numbers, even in a single func they become confusing! */
+/* Location, common to all. */
+/* XXX Those two *must* remain contiguous (used as array)! */
+#define LOC_X 0
+#define LOC_Y 1
+#define LOC_Z 2
+/* Meshes... */
+#define M_CREASE 3
+#define M_WEIGHT 4
+/* XXX Those two *must* remain contiguous (used as array)! */
+#define M_SKIN_X 5
+#define M_SKIN_Y 6
+/* Curves... */
+#define C_BWEIGHT 3
+#define C_WEIGHT 4
+#define C_RADIUS 5
+#define C_TILT 6
+/*Lattice... */
+#define L_WEIGHT 4
+
uiBlock *block = (layout) ? uiLayoutAbsoluteBlock(layout) : NULL;
MDeformVert *dvert = NULL;
TransformProperties *tfp;
- float median[9], ve_median[9];
- int tot, totw, totweight, totedge, totradius, totskinradius;
+ float median[NBR_TRANSFORM_PROPERTIES], ve_median[NBR_TRANSFORM_PROPERTIES];
+ int tot, totedgedata, totcurvedata, totlattdata, totskinradius, totcurvebweight;
+ int meshdata = FALSE;
char defstr[320];
- PointerRNA radius_ptr;
+ PointerRNA data_ptr;
- median[0] = median[1] = median[2] = median[3] = median[4] = median[5] = median[6] = median[7] = median[8] = 0.0;
- tot = totw = totweight = totedge = totradius = totskinradius = 0;
- defstr[0] = 0;
+ fill_vn_fl(median, NBR_TRANSFORM_PROPERTIES, 0.0f);
+ tot = totedgedata = totcurvedata = totlattdata = totskinradius = totcurvebweight = 0;
+ defstr[0] = '\0';
/* make sure we got storage */
if (v3d->properties_storage == NULL)
@@ -162,11 +185,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
evedef = eve;
tot++;
- add_v3_v3(median, eve->co);
+ add_v3_v3(&median[LOC_X], eve->co);
vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
if (vs) {
- add_v2_v2(median + 7, vs->radius); /* Third val not used currently. */
+ add_v2_v2(&median[M_SKIN_X], vs->radius); /* Third val not used currently. */
totskinradius++;
}
}
@@ -176,12 +199,12 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
float *f;
- totedge++;
+ totedgedata++;
f = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE);
- median[3] += f ? *f : 0.0f;
+ median[M_CREASE] += f ? *f : 0.0f;
f = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT);
- median[6] += f ? *f : 0.0f;
+ median[M_WEIGHT] += f ? *f : 0.0f;
}
}
@@ -211,6 +234,8 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
tfp->defweightp = &dvert->dw[0].weight;
}
}
+
+ meshdata = totedgedata || totskinradius;
}
else if (ob->type == OB_CURVE || ob->type == OB_SURF) {
Curve *cu = ob->data;
@@ -229,22 +254,24 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
a = nu->pntsu;
while (a--) {
if (bezt->f2 & SELECT) {
- add_v3_v3(median, bezt->vec[1]);
+ add_v3_v3(&median[LOC_X], bezt->vec[1]);
tot++;
- median[4] += bezt->weight;
- totweight++;
- median[5] += bezt->radius;
- totradius++;
- selp = bezt;
- seltype = &RNA_BezierSplinePoint;
+ median[C_WEIGHT] += bezt->weight;
+ median[C_RADIUS] += bezt->radius;
+ median[C_TILT] += bezt->alfa;
+ if (!totcurvedata) { /* I.e. first time... */
+ selp = bezt;
+ seltype = &RNA_BezierSplinePoint;
+ }
+ totcurvedata++;
}
else {
if (bezt->f1 & SELECT) {
- add_v3_v3(median, bezt->vec[0]);
+ add_v3_v3(&median[LOC_X], bezt->vec[0]);
tot++;
}
if (bezt->f3 & SELECT) {
- add_v3_v3(median, bezt->vec[2]);
+ add_v3_v3(&median[LOC_X], bezt->vec[2]);
tot++;
}
}
@@ -256,16 +283,18 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
a = nu->pntsu * nu->pntsv;
while (a--) {
if (bp->f1 & SELECT) {
- add_v3_v3(median, bp->vec);
- median[3] += bp->vec[3];
- totw++;
+ add_v3_v3(&median[LOC_X], bp->vec);
+ median[C_BWEIGHT] += bp->vec[3];
+ totcurvebweight++;
tot++;
- median[4] += bp->weight;
- totweight++;
- median[5] += bp->radius;
- totradius++;
- selp = bp;
- seltype = &RNA_SplinePoint;
+ median[C_WEIGHT] += bp->weight;
+ median[C_RADIUS] += bp->radius;
+ median[C_TILT] += bp->alfa;
+ if (!totcurvedata) { /* I.e. first time... */
+ selp = bp;
+ seltype = &RNA_SplinePoint;
+ }
+ totcurvedata++;
}
bp++;
}
@@ -273,84 +302,102 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
nu = nu->next;
}
- if (totradius == 1)
- RNA_pointer_create(&cu->id, seltype, selp, &radius_ptr);
+ if (totcurvedata == 1)
+ RNA_pointer_create(&cu->id, seltype, selp, &data_ptr);
}
else if (ob->type == OB_LATTICE) {
Lattice *lt = ob->data;
BPoint *bp;
int a;
+ StructRNA *seltype = NULL;
+ void *selp = NULL;
a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
bp = lt->editlatt->latt->def;
while (a--) {
if (bp->f1 & SELECT) {
- add_v3_v3(median, bp->vec);
+ add_v3_v3(&median[LOC_X], bp->vec);
tot++;
- median[4] += bp->weight;
- totweight++;
+ median[L_WEIGHT] += bp->weight;
+ if (!totlattdata) { /* I.e. first time... */
+ selp = bp;
+ seltype = &RNA_LatticePoint;
+ }
+ totlattdata++;
}
bp++;
}
+
+ if (totlattdata == 1)
+ RNA_pointer_create(&lt->id, seltype, selp, &data_ptr);
}
if (tot == 0) {
uiDefBut(block, LABEL, 0, IFACE_("Nothing selected"), 0, 130, 200, 20, NULL, 0, 0, 0, 0, "");
return;
}
- median[0] /= (float)tot;
- median[1] /= (float)tot;
- median[2] /= (float)tot;
- if (totedge) {
- median[3] /= (float)totedge;
- median[6] /= (float)totedge;
- }
- else if (totw)
- median[3] /= (float)totw;
- if (totweight)
- median[4] /= (float)totweight;
- if (totradius)
- median[5] /= (float)totradius;
- if (totskinradius) {
- median[7] /= (float)totskinradius;
- median[8] /= (float)totskinradius;
- }
+ /* Location, X/Y/Z */
+ mul_v3_fl(&median[LOC_X], 1.0f / (float)tot);
if (v3d->flag & V3D_GLOBAL_STATS)
- mul_m4_v3(ob->obmat, median);
+ mul_m4_v3(ob->obmat, &median[LOC_X]);
+
+ if (meshdata) {
+ if (totedgedata) {
+ median[M_CREASE] /= (float)totedgedata;
+ median[M_WEIGHT] /= (float)totedgedata;
+ }
+ if (totskinradius) {
+ median[M_SKIN_X] /= (float)totskinradius;
+ median[M_SKIN_Y] /= (float)totskinradius;
+ }
+ }
+ else if (totcurvedata) {
+ median[C_WEIGHT] /= (float)totcurvedata;
+ median[C_RADIUS] /= (float)totcurvedata;
+ median[C_TILT] /= (float)totcurvedata;
+ if (totcurvebweight)
+ median[C_BWEIGHT] /= (float)totcurvebweight;
+ }
+ else if (totlattdata)
+ median[L_WEIGHT] /= (float)totlattdata;
if (block) { /* buttons */
uiBut *but;
int yi = 200;
const int buth = 20 * UI_DPI_ICON_FAC;
const int but_margin = 2;
+ const char *c;
memcpy(tfp->ve_median, median, sizeof(tfp->ve_median));
uiBlockBeginAlign(block);
if (tot == 1) {
- uiDefBut(block, LABEL, 0, IFACE_("Vertex:"), 0, yi -= buth, 200, buth, NULL, 0, 0, 0, 0, "");
- }
- else {
- uiDefBut(block, LABEL, 0, IFACE_("Median:"), 0, yi -= buth, 200, buth, NULL, 0, 0, 0, 0, "");
+ if (totcurvedata) /* Curve */
+ c = IFACE_("Control Point:");
+ else /* Mesh or lattice */
+ c = IFACE_("Vertex:");
}
+ else
+ c = IFACE_("Median:");
+ uiDefBut(block, LABEL, 0, c, 0, yi -= buth, 200, buth, NULL, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
/* Should be no need to translate these. */
but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:", 0, yi -= buth, 200, buth,
- &(tfp->ve_median[0]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, "");
+ &(tfp->ve_median[LOC_X]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, "");
uiButSetUnitType(but, PROP_UNIT_LENGTH);
but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:", 0, yi -= buth, 200, buth,
- &(tfp->ve_median[1]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, "");
+ &(tfp->ve_median[LOC_Y]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, "");
uiButSetUnitType(but, PROP_UNIT_LENGTH);
but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:", 0, yi -= buth, 200, buth,
- &(tfp->ve_median[2]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, "");
+ &(tfp->ve_median[LOC_Z]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, "");
uiButSetUnitType(but, PROP_UNIT_LENGTH);
- if (totw == tot) {
+ if (totcurvebweight == tot) {
uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:", 0, yi -= buth, 200, buth,
- &(tfp->ve_median[3]), 0.01, 100.0, 1, 3, "");
+ &(tfp->ve_median[C_BWEIGHT]), 0.01, 100.0, 1, 3, "");
}
uiBlockBeginAlign(block);
@@ -362,60 +409,60 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
&v3d->flag, 0, 0, 0, 0, "Displays local values");
uiBlockEndAlign(block);
- if (totweight == 1) {
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Weight:"),
- 0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[4]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal"));
+ /* Meshes... */
+ if (meshdata) {
+ if (totedgedata) {
+ uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
+ totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"),
+ 0, yi -= buth + but_margin, 200, buth,
+ &(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier"));
+ uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
+ totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"),
+ 0, yi -= buth + but_margin, 200, buth,
+ &(tfp->ve_median[M_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier"));
+ }
+ if (totskinradius) {
+ uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
+ totskinradius == 1 ? IFACE_("Radius X:") : IFACE_("Mean Radius X:"),
+ 0, yi -= buth + but_margin, 200, buth,
+ &(tfp->ve_median[M_SKIN_X]), 0.0, 100.0, 1, 3, TIP_("X radius used by Skin modifier"));
+ uiDefButF(block, NUM, B_OBJECTPANELMEDIAN,
+ totskinradius == 1 ? IFACE_("Radius Y:") : IFACE_("Mean Radius Y:"),
+ 0, yi -= buth + but_margin, 200, buth,
+ &(tfp->ve_median[M_SKIN_Y]), 0.0, 100.0, 1, 3, TIP_("Y radius used by Skin modifier"));
+ }
}
- else if (totweight > 1) {
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"),
- 0, yi -= buth, 200, buth,
- &(tfp->ve_median[4]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal"));
+ /* Curve... */
+ else if (totcurvedata == 1) {
+ uiDefButR(block, NUM, 0, "Weight", 0, yi -= buth + but_margin, 200, buth,
+ &data_ptr, "weight_softbody", 0, 0.0, 1.0, 1, 3, NULL);
+ uiDefButR(block, NUM, 0, "Radius", 0, yi -= buth + but_margin, 200, buth,
+ &data_ptr, "radius", 0, 0.0, 100.0, 1, 3, NULL);
+ uiDefButR(block, NUM, 0, "Tilt", 0, yi -= buth + but_margin, 200, buth,
+ &data_ptr, "tilt", 0, -M_PI * 2.0f, M_PI * 2.0f, 1, 3, NULL);
}
-
- if (totradius == 1) {
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Radius:"),
+ else if (totcurvedata > 1) {
+ uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"),
0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, TIP_("Radius of curve control points"));
- }
- else if (totradius > 1) {
+ &(tfp->ve_median[C_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal"));
uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius:"),
0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, TIP_("Radius of curve control points"));
+ &(tfp->ve_median[C_RADIUS]), 0.0, 100.0, 1, 3, TIP_("Radius of curve control points"));
+ but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Tilt:"),
+ 0, yi -= buth + but_margin, 200, buth,
+ &(tfp->ve_median[C_TILT]), -M_PI * 2.0f, M_PI * 2.0f, 1, 3,
+ TIP_("Tilt of curve control points"));
+ uiButSetUnitType(but, PROP_UNIT_ROTATION);
}
-
- if (totskinradius == 1) {
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Radius X:"),
- 0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[7]), 0.0, 100.0, 1, 3, TIP_("X radius used by Skin modifier"));
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Radius Y:"),
- 0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[8]), 0.0, 100.0, 1, 3, TIP_("Y radius used by Skin modifier"));
+ /* Lattice... */
+ else if (totlattdata == 1) {
+ uiDefButR(block, NUM, 0, "Weight", 0, yi -= buth + but_margin, 200, buth,
+ &data_ptr, "weight_softbody", 0, 0.0, 1.0, 1, 3, NULL);
}
- else if (totskinradius > 1) {
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius X:"),
- 0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[7]), 0.0, 100.0, 1, 3, TIP_("Median X radius used by Skin modifier"));
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius Y:"),
- 0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[8]), 0.0, 100.0, 1, 3, TIP_("Median Y radius used by Skin modifier"));
- }
-
- if (totedge == 1) {
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Crease:"),
- 0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[3]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier"));
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Bevel Weight:"),
- 0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[6]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier"));
- }
- else if (totedge > 1) {
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Crease:"),
- 0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[3]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier"));
- uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Bevel Weight:"),
+ else if (totlattdata > 1) {
+ uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"),
0, yi -= buth + but_margin, 200, buth,
- &(tfp->ve_median[6]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier"));
+ &(tfp->ve_median[L_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal"));
}
uiBlockEndAlign(block);
@@ -423,42 +470,40 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
else { /* apply */
+ int i;
+
memcpy(ve_median, tfp->ve_median, sizeof(tfp->ve_median));
if (v3d->flag & V3D_GLOBAL_STATS) {
invert_m4_m4(ob->imat, ob->obmat);
- mul_m4_v3(ob->imat, median);
- mul_m4_v3(ob->imat, ve_median);
+ mul_m4_v3(ob->imat, &median[LOC_X]);
+ mul_m4_v3(ob->imat, &ve_median[LOC_X]);
}
- sub_v3_v3v3(median, ve_median, median);
- median[3] = ve_median[3] - median[3];
- median[4] = ve_median[4] - median[4];
- median[5] = ve_median[5] - median[5];
- median[6] = ve_median[6] - median[6];
- median[7] = ve_median[7] - median[7];
- median[8] = ve_median[8] - median[8];
+ i = NBR_TRANSFORM_PROPERTIES;
+ while (i--)
+ median[i] = ve_median[i] - median[i];
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
BMesh *bm = em->bm;
- BMVert *eve;
BMIter iter;
- if (len_v3(median) > 0.000001f) {
+ if (len_v3(&median[LOC_X]) > 0.000001f) {
+ BMVert *eve;
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- add_v3_v3(eve->co, median);
+ add_v3_v3(eve->co, &median[LOC_X]);
}
}
EDBM_mesh_normals_update(em);
}
- if (median[3] != 0.0f) {
+ if (median[M_CREASE] != 0.0f) {
BMEdge *eed;
- const float sca = compute_scale_factor(ve_median[3], median[3]);
+ const float sca = compute_scale_factor(ve_median[M_CREASE], median[M_CREASE]);
if (ELEM(sca, 0.0f, 1.0f)) {
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
@@ -494,9 +539,9 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
}
- if (median[6] != 0.0f) {
+ if (median[M_WEIGHT] != 0.0f) {
BMEdge *eed;
- const float sca = compute_scale_factor(ve_median[6], median[6]);
+ const float sca = compute_scale_factor(ve_median[M_WEIGHT], median[M_WEIGHT]);
if (ELEM(sca, 0.0f, 1.0f)) {
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
@@ -532,11 +577,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
}
- if (median[7] != 0.0f) {
+ if (median[M_SKIN_X] != 0.0f) {
BMVert *eve;
/* That one is not clamped to [0.0, 1.0]. */
- float sca = ve_median[7];
- if (ve_median[7] - median[7] == 0.0f) {
+ float sca = ve_median[M_SKIN_X];
+ if (ve_median[M_SKIN_X] - median[M_SKIN_X] == 0.0f) {
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
@@ -546,7 +591,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
}
else {
- sca /= (ve_median[7] - median[7]);
+ sca /= (ve_median[M_SKIN_X] - median[M_SKIN_X]);
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
@@ -556,11 +601,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
}
}
- if (median[8] != 0.0f) {
+ if (median[M_SKIN_Y] != 0.0f) {
BMVert *eve;
/* That one is not clamped to [0.0, 1.0]. */
- float sca = ve_median[8];
- if (ve_median[8] - median[8] == 0.0f) {
+ float sca = ve_median[M_SKIN_Y];
+ if (ve_median[M_SKIN_Y] - median[M_SKIN_Y] == 0.0f) {
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
@@ -570,7 +615,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
}
else {
- sca /= (ve_median[8] - median[8]);
+ sca /= (ve_median[M_SKIN_Y] - median[M_SKIN_Y]);
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN);
@@ -589,7 +634,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
BezTriple *bezt;
int a;
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
- const float scale_w = compute_scale_factor(ve_median[4], median[4]);
+ const float scale_w = compute_scale_factor(ve_median[C_WEIGHT], median[C_WEIGHT]);
nu = nurbs->first;
while (nu) {
@@ -598,11 +643,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
a = nu->pntsu;
while (a--) {
if (bezt->f2 & SELECT) {
- add_v3_v3(bezt->vec[0], median);
- add_v3_v3(bezt->vec[1], median);
- add_v3_v3(bezt->vec[2], median);
+ add_v3_v3(bezt->vec[0], &median[LOC_X]);
+ add_v3_v3(bezt->vec[1], &median[LOC_X]);
+ add_v3_v3(bezt->vec[2], &median[LOC_X]);
- if (median[4] != 0.0f) {
+ if (median[C_WEIGHT] != 0.0f) {
if (ELEM(scale_w, 0.0f, 1.0f)) {
bezt->weight = scale_w;
}
@@ -613,14 +658,15 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
}
- bezt->radius += median[5];
+ bezt->radius += median[C_RADIUS];
+ bezt->alfa += median[C_TILT];
}
else {
if (bezt->f1 & SELECT) {
- add_v3_v3(bezt->vec[0], median);
+ add_v3_v3(bezt->vec[0], &median[LOC_X]);
}
if (bezt->f3 & SELECT) {
- add_v3_v3(bezt->vec[2], median);
+ add_v3_v3(bezt->vec[2], &median[LOC_X]);
}
}
bezt++;
@@ -631,10 +677,10 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
a = nu->pntsu * nu->pntsv;
while (a--) {
if (bp->f1 & SELECT) {
- add_v3_v3(bp->vec, median);
- bp->vec[3] += median[3];
+ add_v3_v3(bp->vec, &median[LOC_X]);
+ bp->vec[3] += median[C_BWEIGHT];
- if (median[4] != 0.0f) {
+ if (median[C_WEIGHT] != 0.0f) {
if (ELEM(scale_w, 0.0f, 1.0f)) {
bp->weight = scale_w;
}
@@ -645,7 +691,8 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
}
}
- bp->radius += median[5];
+ bp->radius += median[C_RADIUS];
+ bp->alfa += median[C_TILT];
}
bp++;
}
@@ -660,15 +707,15 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
Lattice *lt = ob->data;
BPoint *bp;
int a;
- const float scale_w = compute_scale_factor(ve_median[4], median[4]);
+ const float scale_w = compute_scale_factor(ve_median[L_WEIGHT], median[L_WEIGHT]);
a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
bp = lt->editlatt->latt->def;
while (a--) {
if (bp->f1 & SELECT) {
- add_v3_v3(bp->vec, median);
+ add_v3_v3(bp->vec, &median[LOC_X]);
- if (median[4] != 0.0f) {
+ if (median[L_WEIGHT] != 0.0f) {
if (ELEM(scale_w, 0.0f, 1.0f)) {
bp->weight = scale_w;
}
@@ -685,7 +732,28 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
/* ED_undo_push(C, "Transform properties"); */
}
+
+/* Clean up! */
+/* Location, common to all. */
+#undef LOC_X
+#undef LOC_Y
+#undef LOC_Z
+/* Meshes (and lattice)... */
+#undef M_CREASE
+#undef M_WEIGHT
+#undef M_SKIN_X
+#undef M_SKIN_Y
+/* Curves... */
+#undef C_BWEIGHT
+#undef C_WEIGHT
+#undef C_RADIUS
+#undef C_TILT
+/* Lattice... */
+#undef L_WEIGHT
}
+#undef NBR_TRANSFORM_PROPERTIES
+
+
#define B_VGRP_PNL_COPY 1
#define B_VGRP_PNL_NORMALIZE 2
#define B_VGRP_PNL_EDIT_SINGLE 8 /* or greater */
@@ -1161,7 +1229,6 @@ static void view3d_panel_object(const bContext *C, Panel *pa)
uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
col = uiLayoutColumn(pa->layout, FALSE);
- /* row = uiLayoutRow(col, FALSE); */ /* UNUSED */
RNA_id_pointer_create(&ob->id, &obptr);
if (ob == obedit) {
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index ca768f2ef17..8e1b0716136 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -355,7 +355,9 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **
if (dx < GRID_MIN_PX_D) {
rv3d->gridview *= sublines;
dx *= sublines;
- if (dx < GRID_MIN_PX_D) ;
+ if (dx < GRID_MIN_PX_D) {
+ /* pass */
+ }
else {
UI_ThemeColor(TH_GRID);
drawgrid_draw(ar, wx, wy, x, y, dx);
@@ -556,7 +558,7 @@ static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d)
int co[2];
/* we don't want the clipping for cursor */
- if (ED_view3d_project_int_global(ar, give_cursor(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_int_global(ar, give_cursor(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
setlinestyle(0);
cpack(0xFF);
circ((float)co[0], (float)co[1], 10.0);
@@ -1460,7 +1462,7 @@ ImBuf *view3d_read_backbuf(ViewContext *vc, short xmin, short ymin, short xmax,
/* smart function to sample a rect spiralling outside, nice for backbuf selection */
unsigned int view3d_sample_backbuf_rect(ViewContext *vc, const int mval[2], int size,
- unsigned int min, unsigned int max, int *dist, short strict,
+ unsigned int min, unsigned int max, float *r_dist, short strict,
void *handle, unsigned int (*indextest)(void *handle, unsigned int index))
{
struct ImBuf *buf;
@@ -1498,13 +1500,13 @@ unsigned int view3d_sample_backbuf_rect(ViewContext *vc, const int mval[2], int
if (strict) {
indexok = indextest(handle, *tbuf - min + 1);
if (indexok) {
- *dist = (short) sqrt( (float)distance);
+ *r_dist = sqrtf((float)distance);
index = *tbuf - min + 1;
goto exit;
}
}
else {
- *dist = (short) sqrt( (float)distance); /* XXX, this distance is wrong - */
+ *r_dist = sqrtf((float)distance); /* XXX, this distance is wrong - */
index = *tbuf - min + 1; /* messy yah, but indices start at 1 */
goto exit;
}
@@ -2854,6 +2856,12 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw
engine->tile_x = ceil(ar->winx / (float)scene->r.xparts);
engine->tile_y = ceil(ar->winy / (float)scene->r.yparts);
+ /* clamp small tile sizes to prevent inefficient threading utilization
+ * the same happens for final renders as well
+ */
+ engine->tile_x = MAX2(engine->tile_x, 64);
+ engine->tile_y = MAX2(engine->tile_x, 64);
+
type->view_update(engine, C);
rv3d->render_engine = engine;
@@ -2870,12 +2878,20 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw
rctf viewborder;
rcti cliprct;
- ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, FALSE);
+ if (rv3d->persp == RV3D_CAMOB) {
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, FALSE);
- cliprct.xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder);
- cliprct.ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder);
- cliprct.xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder);
- cliprct.ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder);
+ cliprct.xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder);
+ cliprct.ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder);
+ cliprct.xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder);
+ cliprct.ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder);
+ }
+ else {
+ cliprct.xmin = v3d->render_border.xmin * ar->winx;
+ cliprct.xmax = v3d->render_border.xmax * ar->winx;
+ cliprct.ymin = v3d->render_border.ymin * ar->winy;
+ cliprct.ymax = v3d->render_border.ymax * ar->winy;
+ }
cliprct.xmin += ar->winrct.xmin;
cliprct.xmax += ar->winrct.xmin;
@@ -3121,8 +3137,20 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha
Object *ob;
- if (rv3d->persp == RV3D_CAMOB)
+ if (rv3d->persp == RV3D_CAMOB) {
drawviewborder(scene, ar, v3d);
+ }
+ else if (v3d->flag2 & V3D_RENDER_BORDER) {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ setlinestyle(3);
+ cpack(0x4040FF);
+
+ glRectf(v3d->render_border.xmin * ar->winx, v3d->render_border.ymin * ar->winy,
+ v3d->render_border.xmax * ar->winx, v3d->render_border.ymax * ar->winy);
+
+ setlinestyle(0);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ }
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
/* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */
@@ -3172,7 +3200,12 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
const char *grid_unit = NULL;
- int draw_border = (rv3d->persp == RV3D_CAMOB && (scene->r.mode & R_BORDER));
+ int draw_border = FALSE;
+
+ if (rv3d->persp == RV3D_CAMOB)
+ draw_border = scene->r.mode & R_BORDER;
+ else
+ draw_border = v3d->flag2 & V3D_RENDER_BORDER;
/* draw viewport using opengl */
if (v3d->drawtype != OB_RENDER || !view3d_main_area_do_render_draw(C) || draw_border) {
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 735f7b5ea4a..96264081f10 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -929,18 +929,6 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
}
-static int view3d_camera_active_poll(bContext *C)
-{
- if (ED_operator_view3d_active(C)) {
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- if (rv3d && rv3d->persp == RV3D_CAMOB) {
- return 1;
- }
- }
-
- return 0;
-}
-
/* test for unlocked camera view in quad view */
static int view3d_camera_user_poll(bContext *C)
{
@@ -966,7 +954,6 @@ static int viewrotate_cancel(bContext *C, wmOperator *op)
void VIEW3D_OT_rotate(wmOperatorType *ot)
{
-
/* identifiers */
ot->name = "Rotate view";
ot->description = "Rotate the view";
@@ -1637,7 +1624,7 @@ static void viewzoom_apply(ViewOpsData *vod, int x, int y, const short viewzoom,
if (use_cam_zoom) {
float delta;
delta = (x - vod->origx + y - vod->origy) / 10.0f;
- vod->rv3d->camzoom = vod->camzoom0 + (zoom_invert ? delta : -delta);
+ vod->rv3d->camzoom = vod->camzoom0 + (zoom_invert ? -delta : delta);
CLAMP(vod->rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX);
}
@@ -1692,11 +1679,11 @@ static void viewzoom_apply(ViewOpsData *vod, int x, int y, const short viewzoom,
if (use_cam_zoom) {
/* zfac is ignored in this case, see below */
#if 0
- zfac = vod->camzoom0 * (2.0f * ((len2 / len1) - 1.0f) + 1.0f) / vod->rv3d->camzoom;
+ zfac = vod->camzoom0 * (2.0f * ((len1 / len2) - 1.0f) + 1.0f) / vod->rv3d->camzoom;
#endif
}
else {
- zfac = vod->dist0 * (2.0f * ((len2 / len1) - 1.0f) + 1.0f) / vod->rv3d->dist;
+ zfac = vod->dist0 * (2.0f * ((len1 / len2) - 1.0f) + 1.0f) / vod->rv3d->dist;
}
}
@@ -1889,12 +1876,12 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
if (U.uiflag & USER_ZOOM_HORIZ) {
vod->origx = vod->oldx = event->x;
- viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, FALSE);
+ viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) == 0);
}
else {
/* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */
vod->origy = vod->oldy = vod->origy + event->x - event->prevx;
- viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, FALSE);
+ viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) == 0);
}
ED_view3d_depth_tag_update(vod->rv3d);
@@ -1972,7 +1959,7 @@ static void viewdolly_apply(ViewOpsData *vod, int x, int y, const short zoom_inv
if (zoom_invert)
SWAP(float, len1, len2);
- zfac = 1.0f + ((len2 - len1) * 0.01f * vod->rv3d->dist);
+ zfac = 1.0f + ((len1 - len2) * 0.01f * vod->rv3d->dist);
}
if (zfac != 1.0f)
@@ -2108,13 +2095,13 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, wmEvent *event)
if (U.uiflag & USER_ZOOM_HORIZ) {
vod->origx = vod->oldx = event->x;
- viewdolly_apply(vod, event->prevx, event->prevy, FALSE);
+ viewdolly_apply(vod, event->prevx, event->prevy, (U.uiflag & USER_ZOOM_INVERT) == 0);
}
else {
/* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */
vod->origy = vod->oldy = vod->origy + event->x - event->prevx;
- viewdolly_apply(vod, event->prevx, event->prevy, FALSE);
+ viewdolly_apply(vod, event->prevx, event->prevy, (U.uiflag & USER_ZOOM_INVERT) == 0);
}
ED_view3d_depth_tag_update(vod->rv3d);
@@ -2179,21 +2166,98 @@ void VIEW3D_OT_dolly(wmOperatorType *ot)
RNA_def_int(ot->srna, "my", 0, 0, INT_MAX, "Zoom Position Y", "", 0, INT_MAX);
}
+static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar,
+ const float min[3], const float max[3],
+ int ok_dist)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ float afm[3];
+ float size;
+
+ /* SMOOTHVIEW */
+ float new_ofs[3];
+ float new_dist;
+
+ sub_v3_v3v3(afm, max, min);
+ size = MAX3(afm[0], afm[1], afm[2]);
+
+ if (ok_dist) {
+ /* fix up zoom distance if needed */
+
+ if (rv3d->is_persp) {
+ if (size <= v3d->near * 1.5f) {
+ /* do not zoom closer than the near clipping plane */
+ size = v3d->near * 1.5f;
+ }
+ }
+ else { /* ortho */
+ if (size < 0.0001f) {
+ /* bounding box was a single point so do not zoom */
+ ok_dist = 0;
+ }
+ else {
+ /* adjust zoom so it looks nicer */
+ size *= 0.7f;
+ }
+ }
+ }
+
+ add_v3_v3v3(new_ofs, min, max);
+ mul_v3_fl(new_ofs, -0.5f);
+ new_dist = size;
+
+ /* correction for window aspect ratio */
+ if (ar->winy > 2 && ar->winx > 2) {
+ size = (float)ar->winx / (float)ar->winy;
+ if (size < 1.0f) size = 1.0f / size;
+ new_dist *= size;
+ }
+
+ if (rv3d->persp == RV3D_CAMOB && !ED_view3d_camera_lock_check(v3d, rv3d)) {
+ rv3d->persp = RV3D_PERSP;
+ view3d_smooth_view(C, v3d, ar, v3d->camera, NULL, new_ofs, NULL, ok_dist ? &new_dist : NULL, NULL);
+ }
+ else {
+ view3d_smooth_view(C, v3d, ar, NULL, NULL, new_ofs, NULL, ok_dist ? &new_dist : NULL, NULL);
+ }
+
+ /* smooth view does viewlock RV3D_BOXVIEW copy */
+}
+
+/* same as view3d_from_minmax but for all regions (except cameras) */
+static void view3d_from_minmax_multi(bContext *C, View3D *v3d,
+ const float min[3], const float max[3],
+ const int ok_dist)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar;
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ if (ar->regiontype == RGN_TYPE_WINDOW) {
+ RegionView3D *rv3d = ar->regiondata;
+ /* when using all regions, don't jump out of camera view,
+ * but _do_ allow locked cameras to be moved */
+ if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) {
+ view3d_from_minmax(C, v3d, ar, min, max, ok_dist);
+ }
+ }
+ }
+}
static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.4x */
{
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
Scene *scene = CTX_data_scene(C);
Base *base;
float *curs;
- const short skip_camera = ED_view3d_camera_lock_check(v3d, rv3d);
-
+ const short use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions");
+ const short skip_camera = (ED_view3d_camera_lock_check(v3d, ar->regiondata) ||
+ /* any one of the regions may be locked */
+ (use_all_regions && v3d->flag2 & V3D_LOCK_CAMERA));
int center = RNA_boolean_get(op->ptr, "center");
- float size, min[3], max[3], afm[3];
+ float min[3], max[3];
int ok = 1, onedone = FALSE;
if (center) {
@@ -2230,37 +2294,16 @@ static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in
return OPERATOR_FINISHED;
}
- sub_v3_v3v3(afm, max, min);
- size = 0.7f * MAX3(afm[0], afm[1], afm[2]);
- if (size == 0.0f) ok = 0;
-
- if (ok) {
- float new_dist;
- float new_ofs[3];
-
- new_dist = size;
- new_ofs[0] = -(min[0] + max[0]) / 2.0f;
- new_ofs[1] = -(min[1] + max[1]) / 2.0f;
- new_ofs[2] = -(min[2] + max[2]) / 2.0f;
-
- /* correction for window aspect ratio */
- if (ar->winy > 2 && ar->winx > 2) {
- size = (float)ar->winx / (float)ar->winy;
- if (size < 1.0f) size = 1.0f / size;
- new_dist *= size;
- }
-
- if ((rv3d->persp == RV3D_CAMOB) && !ED_view3d_camera_lock_check(v3d, rv3d)) {
- rv3d->persp = RV3D_PERSP;
- view3d_smooth_view(C, v3d, ar, v3d->camera, NULL, new_ofs, NULL, &new_dist, NULL);
- }
- else {
- view3d_smooth_view(C, v3d, ar, NULL, NULL, new_ofs, NULL, &new_dist, NULL);
- }
+ if (ok == 0) {
+ return OPERATOR_FINISHED;
}
-// XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
+ if (use_all_regions) {
+ view3d_from_minmax_multi(C, v3d, min, max, TRUE);
+ }
+ else {
+ view3d_from_minmax(C, v3d, ar, min, max, TRUE);
+ }
return OPERATOR_FINISHED;
}
@@ -2268,6 +2311,8 @@ static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in
void VIEW3D_OT_view_all(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "View All";
ot->description = "View all objects in scene";
@@ -2280,25 +2325,25 @@ void VIEW3D_OT_view_all(wmOperatorType *ot)
/* flags */
ot->flag = 0;
+ prop = RNA_def_boolean(ot->srna, "use_all_regions", 0, "All Regions", "View selected for all regions");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
RNA_def_boolean(ot->srna, "center", 0, "Center", "");
}
/* like a localview without local!, was centerview() in 2.4x */
-static int viewselected_exec(bContext *C, wmOperator *UNUSED(op))
+static int viewselected_exec(bContext *C, wmOperator *op)
{
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
Scene *scene = CTX_data_scene(C);
Object *ob = OBACT;
Object *obedit = CTX_data_edit_object(C);
- float size, min[3], max[3], afm[3];
+ float min[3], max[3];
int ok = 0, ok_dist = 1;
- const short skip_camera = ED_view3d_camera_lock_check(v3d, rv3d);
-
- /* SMOOTHVIEW */
- float new_ofs[3];
- float new_dist;
+ const short use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions");
+ const short skip_camera = (ED_view3d_camera_lock_check(v3d, ar->regiondata) ||
+ /* any one of the regions may be locked */
+ (use_all_regions && v3d->flag2 & V3D_LOCK_CAMERA));
INIT_MINMAX(min, max);
@@ -2369,54 +2414,17 @@ static int viewselected_exec(bContext *C, wmOperator *UNUSED(op))
}
}
- if (ok == 0) return OPERATOR_FINISHED;
-
- sub_v3_v3v3(afm, max, min);
- size = MAX3(afm[0], afm[1], afm[2]);
-
- if (ok_dist) {
- /* fix up zoom distance if needed */
-
- if (rv3d->is_persp) {
- if (size <= v3d->near * 1.5f) {
- /* do not zoom closer than the near clipping plane */
- size = v3d->near * 1.5f;
- }
- }
- else { /* ortho */
- if (size < 0.0001f) {
- /* bounding box was a single point so do not zoom */
- ok_dist = 0;
- }
- else {
- /* adjust zoom so it looks nicer */
- size *= 0.7f;
- }
- }
- }
-
- add_v3_v3v3(new_ofs, min, max);
- mul_v3_fl(new_ofs, -0.5f);
-
- new_dist = size;
-
- /* correction for window aspect ratio */
- if (ar->winy > 2 && ar->winx > 2) {
- size = (float)ar->winx / (float)ar->winy;
- if (size < 1.0f) size = 1.0f / size;
- new_dist *= size;
+ if (ok == 0) {
+ return OPERATOR_FINISHED;
}
- if (rv3d->persp == RV3D_CAMOB && !ED_view3d_camera_lock_check(v3d, rv3d)) {
- rv3d->persp = RV3D_PERSP;
- view3d_smooth_view(C, v3d, ar, v3d->camera, NULL, new_ofs, NULL, ok_dist ? &new_dist : NULL, NULL);
+ if (use_all_regions) {
+ view3d_from_minmax_multi(C, v3d, min, max, ok_dist);
}
else {
- view3d_smooth_view(C, v3d, ar, NULL, NULL, new_ofs, NULL, ok_dist ? &new_dist : NULL, NULL);
+ view3d_from_minmax(C, v3d, ar, min, max, ok_dist);
}
- /* smooth view does viewlock RV3D_BOXVIEW copy */
-
// XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
return OPERATOR_FINISHED;
@@ -2424,6 +2432,7 @@ static int viewselected_exec(bContext *C, wmOperator *UNUSED(op))
void VIEW3D_OT_view_selected(wmOperatorType *ot)
{
+ PropertyRNA *prop;
/* identifiers */
ot->name = "View Selected";
@@ -2436,6 +2445,10 @@ void VIEW3D_OT_view_selected(wmOperatorType *ot)
/* flags */
ot->flag = 0;
+
+ /* rna later */
+ prop = RNA_def_boolean(ot->srna, "use_all_regions", 0, "All Regions", "View selected for all regions");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
static int view_lock_clear_exec(bContext *C, wmOperator *UNUSED(op))
@@ -2608,42 +2621,71 @@ static int render_border_exec(bContext *C, wmOperator *op)
View3D *v3d = CTX_wm_view3d(C);
ARegion *ar = CTX_wm_region(C);
RegionView3D *rv3d = ED_view3d_context_rv3d(C);
+
Scene *scene = CTX_data_scene(C);
rcti rect;
- rctf vb;
+ rctf vb, border;
+
+ int camera_only = RNA_boolean_get(op->ptr, "camera_only");
+
+ if (camera_only && rv3d->persp != RV3D_CAMOB)
+ return OPERATOR_PASS_THROUGH;
/* get border select values using rna */
WM_operator_properties_border_to_rcti(op, &rect);
/* calculate range */
- ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, FALSE);
- scene->r.border.xmin = ((float)rect.xmin - vb.xmin) / BLI_rctf_size_x(&vb);
- scene->r.border.ymin = ((float)rect.ymin - vb.ymin) / BLI_rctf_size_y(&vb);
- scene->r.border.xmax = ((float)rect.xmax - vb.xmin) / BLI_rctf_size_x(&vb);
- scene->r.border.ymax = ((float)rect.ymax - vb.ymin) / BLI_rctf_size_y(&vb);
+ if (rv3d->persp == RV3D_CAMOB) {
+ ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, FALSE);
+ }
+ else {
+ vb.xmin = 0;
+ vb.ymin = 0;
+ vb.xmax = ar->winx;
+ vb.ymax = ar->winy;
+ }
+
+ border.xmin = ((float)rect.xmin - vb.xmin) / BLI_rctf_size_x(&vb);
+ border.ymin = ((float)rect.ymin - vb.ymin) / BLI_rctf_size_y(&vb);
+ border.xmax = ((float)rect.xmax - vb.xmin) / BLI_rctf_size_x(&vb);
+ border.ymax = ((float)rect.ymax - vb.ymin) / BLI_rctf_size_y(&vb);
/* actually set border */
- CLAMP(scene->r.border.xmin, 0.0f, 1.0f);
- CLAMP(scene->r.border.ymin, 0.0f, 1.0f);
- CLAMP(scene->r.border.xmax, 0.0f, 1.0f);
- CLAMP(scene->r.border.ymax, 0.0f, 1.0f);
+ CLAMP(border.xmin, 0.0f, 1.0f);
+ CLAMP(border.ymin, 0.0f, 1.0f);
+ CLAMP(border.xmax, 0.0f, 1.0f);
+ CLAMP(border.ymax, 0.0f, 1.0f);
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ scene->r.border = border;
+
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ }
+ else {
+ v3d->render_border = border;
+
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ }
/* drawing a border surrounding the entire camera view switches off border rendering
* or the border covers no pixels */
- if ((scene->r.border.xmin <= 0.0f && scene->r.border.xmax >= 1.0f &&
- scene->r.border.ymin <= 0.0f && scene->r.border.ymax >= 1.0f) ||
- (scene->r.border.xmin == scene->r.border.xmax ||
- scene->r.border.ymin == scene->r.border.ymax))
+ if ((border.xmin <= 0.0f && border.xmax >= 1.0f &&
+ border.ymin <= 0.0f && border.ymax >= 1.0f) ||
+ (border.xmin == border.xmax || border.ymin == border.ymax))
{
- scene->r.mode &= ~R_BORDER;
+ if (rv3d->persp == RV3D_CAMOB)
+ scene->r.mode &= ~R_BORDER;
+ else
+ v3d->flag2 &= ~V3D_RENDER_BORDER;
}
else {
- scene->r.mode |= R_BORDER;
+ if (rv3d->persp == RV3D_CAMOB)
+ scene->r.mode |= R_BORDER;
+ else
+ v3d->flag2 |= V3D_RENDER_BORDER;
}
-
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL);
return OPERATOR_FINISHED;
@@ -2662,7 +2704,7 @@ void VIEW3D_OT_render_border(wmOperatorType *ot)
ot->modal = WM_border_select_modal;
ot->cancel = WM_border_select_cancel;
- ot->poll = view3d_camera_active_poll;
+ ot->poll = ED_operator_view3d_active;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -2670,7 +2712,56 @@ void VIEW3D_OT_render_border(wmOperatorType *ot)
/* rna */
WM_operator_properties_border(ot);
+ RNA_def_boolean(ot->srna, "camera_only", 0, "Camera Only", "Set render border for camera view and final render only");
}
+
+/* ********************* Set render border operator ****************** */
+
+static int clear_render_border_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = ED_view3d_context_rv3d(C);
+
+ Scene *scene = CTX_data_scene(C);
+ rctf *border = NULL;
+
+ if (rv3d->persp == RV3D_CAMOB) {
+ scene->r.mode &= ~R_BORDER;
+ border = &scene->r.border;
+
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ }
+ else {
+ v3d->flag2 &= ~V3D_RENDER_BORDER;
+ border = &v3d->render_border;
+
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ }
+
+ border->xmin = 0.0f;
+ border->ymin = 0.0f;
+ border->xmax = 1.0f;
+ border->ymax = 1.0f;
+
+ return OPERATOR_FINISHED;
+
+}
+
+void VIEW3D_OT_clear_render_border(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Clear Render Border";
+ ot->description = "Clear the boundaries of the border render and enables border render";
+ ot->idname = "VIEW3D_OT_clear_render_border";
+
+ /* api callbacks */
+ ot->exec = clear_render_border_exec;
+ ot->poll = ED_operator_view3d_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
/* ********************* Border Zoom operator ****************** */
static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
@@ -2729,7 +2820,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
/* no depths to use, we cant do anything! */
if (depth_close == FLT_MAX) {
- BKE_report(op->reports, RPT_ERROR, "Depth Too Large");
+ BKE_report(op->reports, RPT_ERROR, "Depth too large");
return OPERATOR_CANCELLED;
}
/* convert border to 3d coordinates */
@@ -2901,7 +2992,7 @@ static EnumPropertyItem prop_view_items[] = {
{RV3D_VIEW_RIGHT, "RIGHT", 0, "Right", "View From the Right"},
{RV3D_VIEW_TOP, "TOP", 0, "Top", "View From the Top"},
{RV3D_VIEW_BOTTOM, "BOTTOM", 0, "Bottom", "View From the Bottom"},
- {RV3D_VIEW_CAMERA, "CAMERA", 0, "Camera", "View From the active camera"},
+ {RV3D_VIEW_CAMERA, "CAMERA", 0, "Camera", "View From the Active Camera"},
{0, NULL, 0, NULL, NULL}
};
@@ -3125,7 +3216,7 @@ void VIEW3D_OT_viewnumpad(wmOperatorType *ot)
/* identifiers */
ot->name = "View numpad";
- ot->description = "Set the view";
+ ot->description = "Use a preset viewpoint";
ot->idname = "VIEW3D_OT_viewnumpad";
/* api callbacks */
@@ -3135,8 +3226,8 @@ void VIEW3D_OT_viewnumpad(wmOperatorType *ot)
/* flags */
ot->flag = 0;
- prop = RNA_def_enum(ot->srna, "type", prop_view_items, 0, "View", "The Type of view");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_view_items, 0, "View", "Preset viewpoint to use");
+ RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
prop = RNA_def_boolean(ot->srna, "align_active", 0, "Align Active", "Align to the active object's axis");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
@@ -3213,7 +3304,9 @@ void VIEW3D_OT_view_orbit(wmOperatorType *ot)
/* flags */
ot->flag = 0;
- RNA_def_enum(ot->srna, "type", prop_view_orbit_items, 0, "Orbit", "Direction of View Orbit");
+
+ /* properties */
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_view_orbit_items, 0, "Orbit", "Direction of View Orbit");
}
static EnumPropertyItem prop_view_pan_items[] = {
@@ -3262,7 +3355,9 @@ void VIEW3D_OT_view_pan(wmOperatorType *ot)
/* flags */
ot->flag = 0;
- RNA_def_enum(ot->srna, "type", prop_view_pan_items, 0, "Pan", "Direction of View Pan");
+
+ /* Properties */
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_view_pan_items, 0, "Pan", "Direction of View Pan");
}
static int viewpersportho_exec(bContext *C, wmOperator *UNUSED(op))
@@ -3290,7 +3385,7 @@ void VIEW3D_OT_view_persportho(wmOperatorType *ot)
{
/* identifiers */
ot->name = "View Persp/Ortho";
- ot->description = "Switch the current view from perspective/orthographic";
+ ot->description = "Switch the current view from perspective/orthographic projection";
ot->idname = "VIEW3D_OT_view_persportho";
/* api callbacks */
@@ -3406,7 +3501,8 @@ void VIEW3D_OT_background_image_remove(wmOperatorType *ot)
/* flags */
ot->flag = 0;
-
+
+ /* properties */
RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Background image index to remove", 0, INT_MAX);
}
@@ -3534,7 +3630,7 @@ static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *
/* flip = */ initgrabz(rv3d, fp[0], fp[1], fp[2]);
}
- if (ED_view3d_project_float_global(ar, fp, mval_fl, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_float_global(ar, fp, mval_fl, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
short depth_used = FALSE;
if (U.uiflag & USER_ZBUF_CURSOR) { /* maybe this should be accessed some other way */
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index c743b88e889..cd358dea869 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -284,6 +284,11 @@ static int initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event
puts("\n-- fly begin --");
#endif
+ /* sanity check: for rare but possible case (if lib-linking the camera fails) */
+ if ((fly->rv3d->persp == RV3D_CAMOB) && (fly->v3d->camera == NULL)) {
+ fly->rv3d->persp = RV3D_PERSP;
+ }
+
if (fly->rv3d->persp == RV3D_CAMOB && fly->v3d->camera->id.lib) {
BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library");
return FALSE;
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 5bfabf4fc4a..3017891183e 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -40,6 +40,7 @@ struct ARegionType;
struct BoundBox;
struct DerivedMesh;
struct Object;
+struct SmokeDomainSettings;
struct ViewContext;
struct bAnimVizSettings;
struct bContext;
@@ -50,8 +51,6 @@ struct wmNDOFMotionData;
struct wmOperatorType;
struct wmWindowManager;
-#define BL_NEAR_CLIP 0.001
-
/* drawing flags: */
enum {
DRAW_PICKING = (1 << 0),
@@ -97,6 +96,7 @@ void VIEW3D_OT_cursor3d(struct wmOperatorType *ot);
void VIEW3D_OT_manipulator(struct wmOperatorType *ot);
void VIEW3D_OT_enable_manipulator(struct wmOperatorType *ot);
void VIEW3D_OT_render_border(struct wmOperatorType *ot);
+void VIEW3D_OT_clear_render_border(struct wmOperatorType *ot);
void VIEW3D_OT_zoom_border(struct wmOperatorType *ot);
void view3d_boxview_copy(ScrArea *sa, ARegion *ar);
@@ -212,7 +212,20 @@ ARegion *view3d_has_tools_region(ScrArea *sa);
extern const char *view3d_context_dir[]; /* doc access */
/* draw_volume.c */
-void draw_volume(struct ARegion *ar, struct GPUTexture *tex, float min[3], float max[3], int res[3], float dx, struct GPUTexture *tex_shadow);
+void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob,
+ struct GPUTexture *tex, float min[3], float max[3],
+ int res[3], float dx, float base_scale, float viewnormal[3],
+ struct GPUTexture *tex_shadow, struct GPUTexture *tex_flame);
+
+//#define SMOKE_DEBUG_VELOCITY
+//#define SMOKE_DEBUG_HEAT
+
+#ifdef SMOKE_DEBUG_VELOCITY
+void draw_smoke_velocity(struct SmokeDomainSettings *domain, struct Object *ob);
+#endif
+#ifdef SMOKE_DEBUG_HEAT
+void draw_smoke_heat(struct SmokeDomainSettings *domain, struct Object *ob);
+#endif
/* workaround for trivial but noticeable camera bug caused by imprecision
* between view border calculation in 2D/3D space, workaround for bug [#28037].
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
new file mode 100644
index 00000000000..0472f9f2c10
--- /dev/null
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -0,0 +1,415 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Blender Foundation, full recode and added functions
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/object/view3d_iterators.c
+ * \ingroup spview3d
+ */
+
+#include "DNA_curve_types.h"
+#include "DNA_lattice_types.h"
+#include "DNA_meta_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_object_types.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_listbase.h"
+#include "BLI_rect.h"
+
+#include "BKE_armature.h"
+#include "BKE_curve.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_displist.h"
+
+#include "bmesh.h"
+
+#include "ED_mesh.h"
+#include "ED_screen.h"
+#include "ED_armature.h"
+#include "ED_object.h"
+#include "ED_view3d.h"
+
+
+typedef struct foreachScreenVert_userData {
+ void (*func)(void *userData, BMVert *eve, const float screen_co_b[2], int index);
+ void *userData;
+ ViewContext vc;
+ eV3DProjTest clip_flag;
+} foreachScreenVert_userData;
+
+/* user data structures for derived mesh callbacks */
+typedef struct foreachScreenEdge_userData {
+ void (*func)(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index);
+ void *userData;
+ ViewContext vc;
+ rctf win_rect; /* copy of: vc.ar->winx/winy, use for faster tests, minx/y will always be 0 */
+ eV3DProjTest clip_flag;
+} foreachScreenEdge_userData;
+
+typedef struct foreachScreenFace_userData {
+ void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index);
+ void *userData;
+ ViewContext vc;
+ eV3DProjTest clip_flag;
+} foreachScreenFace_userData;
+
+
+/* Note! - foreach funcs should be called while drawing or directly after
+ * if not, ED_view3d_init_mats_rv3d() can be used for selection tools
+ * but would not give correct results with dupli's for eg. which don't
+ * use the object matrix in the usual way */
+
+/* ------------------------------------------------------------------------ */
+
+static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const float co[3],
+ const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
+{
+ foreachScreenVert_userData *data = userData;
+ BMVert *eve = EDBM_vert_at_index(data->vc.em, index);
+
+ if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
+ float screen_co[2];
+
+ if (ED_view3d_project_float_object(data->vc.ar, co, screen_co, data->clip_flag) != V3D_PROJ_RET_OK) {
+ return;
+ }
+
+ data->func(data->userData, eve, screen_co, index);
+ }
+}
+
+void mesh_foreachScreenVert(
+ ViewContext *vc,
+ void (*func)(void *userData, BMVert *eve, const float screen_co[2], int index),
+ void *userData, eV3DProjTest clip_flag)
+{
+ foreachScreenVert_userData data;
+ DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
+
+ data.vc = *vc;
+ data.func = func;
+ data.userData = userData;
+ data.clip_flag = clip_flag;
+
+ if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
+ ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
+ }
+
+ EDBM_index_arrays_init(vc->em, 1, 0, 0);
+ dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data);
+ EDBM_index_arrays_free(vc->em);
+
+ dm->release(dm);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const float v0co[3], const float v1co[3])
+{
+ foreachScreenEdge_userData *data = userData;
+ BMEdge *eed = EDBM_edge_at_index(data->vc.em, index);
+
+ if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
+ float screen_co_a[2];
+ float screen_co_b[2];
+
+ if (ED_view3d_project_float_object(data->vc.ar, v0co, screen_co_a, data->clip_flag) != V3D_PROJ_RET_OK) {
+ return;
+ }
+ if (ED_view3d_project_float_object(data->vc.ar, v1co, screen_co_b, data->clip_flag) != V3D_PROJ_RET_OK) {
+ return;
+ }
+
+ if (data->clip_flag & V3D_PROJ_TEST_CLIP_WIN) {
+ if (!BLI_rctf_isect_segment(&data->win_rect, screen_co_a, screen_co_b)) {
+ return;
+ }
+ }
+
+ data->func(data->userData, eed, screen_co_a, screen_co_b, index);
+ }
+}
+
+void mesh_foreachScreenEdge(
+ ViewContext *vc,
+ void (*func)(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index),
+ void *userData, eV3DProjTest clip_flag)
+{
+ foreachScreenEdge_userData data;
+ DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
+
+ data.vc = *vc;
+
+ data.win_rect.xmin = 0;
+ data.win_rect.ymin = 0;
+ data.win_rect.xmax = vc->ar->winx;
+ data.win_rect.ymax = vc->ar->winy;
+
+ data.func = func;
+ data.userData = userData;
+ data.clip_flag = clip_flag;
+
+ if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
+ ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
+ }
+
+ EDBM_index_arrays_init(vc->em, 0, 1, 0);
+ dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data);
+ EDBM_index_arrays_free(vc->em);
+
+ dm->release(dm);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const float cent[3], const float UNUSED(no[3]))
+{
+ foreachScreenFace_userData *data = userData;
+ BMFace *efa = EDBM_face_at_index(data->vc.em, index);
+
+ if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+ float screen_co[2];
+ if (ED_view3d_project_float_object(data->vc.ar, cent, screen_co, data->clip_flag) == V3D_PROJ_RET_OK) {
+ data->func(data->userData, efa, screen_co, index);
+ }
+ }
+}
+
+void mesh_foreachScreenFace(
+ ViewContext *vc,
+ void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index),
+ void *userData, const eV3DProjTest clip_flag)
+{
+ foreachScreenFace_userData data;
+ DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
+
+ data.vc = *vc;
+ data.func = func;
+ data.userData = userData;
+ data.clip_flag = clip_flag;
+
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
+
+ EDBM_index_arrays_init(vc->em, 0, 0, 1);
+ dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data);
+ EDBM_index_arrays_free(vc->em);
+
+ dm->release(dm);
+}
+
+/* ------------------------------------------------------------------------ */
+
+void nurbs_foreachScreenVert(
+ ViewContext *vc,
+ void (*func)(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co_b[2]),
+ void *userData, const eV3DProjTest clip_flag)
+{
+ Curve *cu = vc->obedit->data;
+ Nurb *nu;
+ int i;
+ ListBase *nurbs = BKE_curve_editNurbs_get(cu);
+
+ if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
+ ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
+ }
+
+ for (nu = nurbs->first; nu; nu = nu->next) {
+ if (nu->type == CU_BEZIER) {
+ for (i = 0; i < nu->pntsu; i++) {
+ BezTriple *bezt = &nu->bezt[i];
+
+ if (bezt->hide == 0) {
+ float screen_co[2];
+
+ if (cu->drawflag & CU_HIDE_HANDLES) {
+ if (ED_view3d_project_float_object(vc->ar, bezt->vec[1], screen_co,
+ V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK)
+ {
+ func(userData, nu, NULL, bezt, 1, screen_co);
+ }
+ }
+ else {
+ if (ED_view3d_project_float_object(vc->ar, bezt->vec[0], screen_co,
+ V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK)
+ {
+ func(userData, nu, NULL, bezt, 0, screen_co);
+ }
+ if (ED_view3d_project_float_object(vc->ar, bezt->vec[1], screen_co,
+ V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK)
+ {
+ func(userData, nu, NULL, bezt, 1, screen_co);
+ }
+ if (ED_view3d_project_float_object(vc->ar, bezt->vec[2], screen_co,
+ V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK)
+ {
+ func(userData, nu, NULL, bezt, 2, screen_co);
+ }
+ }
+ }
+ }
+ }
+ else {
+ for (i = 0; i < nu->pntsu * nu->pntsv; i++) {
+ BPoint *bp = &nu->bp[i];
+
+ if (bp->hide == 0) {
+ float screen_co[2];
+ if (ED_view3d_project_float_object(vc->ar, bp->vec, screen_co,
+ V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK)
+ {
+ func(userData, nu, bp, NULL, -1, screen_co);
+ }
+ }
+ }
+ }
+ }
+}
+
+/* ------------------------------------------------------------------------ */
+
+/* ED_view3d_init_mats_rv3d must be called first */
+void mball_foreachScreenElem(
+ struct ViewContext *vc,
+ void (*func)(void *userData, struct MetaElem *ml, const float screen_co_b[2]),
+ void *userData, const eV3DProjTest clip_flag)
+{
+ MetaBall *mb = (MetaBall *)vc->obedit->data;
+ MetaElem *ml;
+
+ for (ml = mb->editelems->first; ml; ml = ml->next) {
+ float screen_co[2];
+ if (ED_view3d_project_float_object(vc->ar, &ml->x, screen_co, clip_flag) == V3D_PROJ_RET_OK) {
+ func(userData, ml, screen_co);
+ }
+ }
+}
+
+/* ------------------------------------------------------------------------ */
+
+void lattice_foreachScreenVert(
+ ViewContext *vc,
+ void (*func)(void *userData, BPoint *bp, const float screen_co[2]),
+ void *userData, const eV3DProjTest clip_flag)
+{
+ Object *obedit = vc->obedit;
+ Lattice *lt = obedit->data;
+ BPoint *bp = lt->editlatt->latt->def;
+ DispList *dl = BKE_displist_find(&obedit->disp, DL_VERTS);
+ float *co = dl ? dl->verts : NULL;
+ int i, N = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
+
+ if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
+ ED_view3d_clipping_local(vc->rv3d, obedit->obmat); /* for local clipping lookups */
+ }
+
+ for (i = 0; i < N; i++, bp++, co += 3) {
+ if (bp->hide == 0) {
+ float screen_co[2];
+ if (ED_view3d_project_float_object(vc->ar, dl ? co : bp->vec, screen_co, clip_flag) == V3D_PROJ_RET_OK) {
+ func(userData, bp, screen_co);
+ }
+ }
+ }
+}
+
+/* ------------------------------------------------------------------------ */
+
+/* ED_view3d_init_mats_rv3d must be called first */
+void armature_foreachScreenBone(
+ struct ViewContext *vc,
+ void (*func)(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2]),
+ void *userData, const eV3DProjTest clip_flag)
+{
+ bArmature *arm = vc->obedit->data;
+ EditBone *ebone;
+
+ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ if (EBONE_VISIBLE(arm, ebone)) {
+ float screen_co_a[2], screen_co_b[2];
+ int points_proj_tot = 0;
+
+ /* project head location to screenspace */
+ if (ED_view3d_project_float_object(vc->ar, ebone->head, screen_co_a, clip_flag) == V3D_PROJ_RET_OK) {
+ points_proj_tot++;
+ }
+ else {
+ screen_co_a[0] = IS_CLIPPED; /* weak */
+ /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */
+ }
+
+ /* project tail location to screenspace */
+ if (ED_view3d_project_float_object(vc->ar, ebone->tail, screen_co_b, clip_flag) == V3D_PROJ_RET_OK) {
+ points_proj_tot++;
+ }
+ else {
+ screen_co_b[0] = IS_CLIPPED; /* weak */
+ /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */
+ }
+
+ if (points_proj_tot) { /* at least one point's projection worked */
+ func(userData, ebone, screen_co_a, screen_co_b);
+ }
+ }
+ }
+}
+
+/* ------------------------------------------------------------------------ */
+
+/* ED_view3d_init_mats_rv3d must be called first */
+/* almost _exact_ copy of #armature_foreachScreenBone */
+void pose_foreachScreenBone(
+ struct ViewContext *vc,
+ void (*func)(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2]),
+ void *userData, const eV3DProjTest clip_flag)
+{
+ bArmature *arm = vc->obact->data;
+ bPose *pose = vc->obact->pose;
+ bPoseChannel *pchan;
+
+ for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
+ if (PBONE_VISIBLE(arm, pchan->bone)) {
+ float screen_co_a[2], screen_co_b[2];
+ int points_proj_tot = 0;
+
+ /* project head location to screenspace */
+ if (ED_view3d_project_float_object(vc->ar, pchan->pose_head, screen_co_a, clip_flag) == V3D_PROJ_RET_OK) {
+ points_proj_tot++;
+ }
+ else {
+ screen_co_a[0] = IS_CLIPPED; /* weak */
+ /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */
+ }
+
+ /* project tail location to screenspace */
+ if (ED_view3d_project_float_object(vc->ar, pchan->pose_tail, screen_co_b, clip_flag) == V3D_PROJ_RET_OK) {
+ points_proj_tot++;
+ }
+ else {
+ screen_co_b[0] = IS_CLIPPED; /* weak */
+ /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */
+ }
+
+ if (points_proj_tot) { /* at least one point's projection worked */
+ func(userData, pchan, screen_co_a, screen_co_b);
+ }
+ }
+ }
+}
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index 14c02c2357e..73f1563417c 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -83,6 +83,7 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_select_circle);
WM_operatortype_append(VIEW3D_OT_smoothview);
WM_operatortype_append(VIEW3D_OT_render_border);
+ WM_operatortype_append(VIEW3D_OT_clear_render_border);
WM_operatortype_append(VIEW3D_OT_zoom_border);
WM_operatortype_append(VIEW3D_OT_manipulator);
WM_operatortype_append(VIEW3D_OT_enable_manipulator);
@@ -136,8 +137,10 @@ void view3d_keymap(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "VIEW3D_OT_move", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_dolly", MIDDLEMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
- WM_keymap_verify_item(keymap, "VIEW3D_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
- WM_keymap_verify_item(keymap, "VIEW3D_OT_view_center_cursor", PADPERIOD, KM_PRESS, KM_CTRL, 0);
+ kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", PADPERIOD, KM_PRESS, KM_CTRL, 0);
+ RNA_boolean_set(kmi->ptr, "use_all_regions", TRUE);
+ kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
+ RNA_boolean_set(kmi->ptr, "use_all_regions", FALSE);
WM_keymap_verify_item(keymap, "VIEW3D_OT_view_lock_to_active", PADPERIOD, KM_PRESS, KM_SHIFT, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_view_lock_clear", PADPERIOD, KM_PRESS, KM_ALT, 0);
@@ -169,6 +172,9 @@ void view3d_keymap(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "center", FALSE); /* only without camera view */
+ kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, KM_CTRL, 0);
+ RNA_boolean_set(kmi->ptr, "use_all_regions", TRUE);
+ RNA_boolean_set(kmi->ptr, "center", FALSE); /* only without camera view */
kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", CKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "center", TRUE);
@@ -340,7 +346,13 @@ void view3d_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "VIEW3D_OT_clip_border", BKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_zoom_border", BKEY, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_SHIFT, 0);
+
+ kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "camera_only", TRUE);
+ kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_CTRL, 0);
+ RNA_boolean_set(kmi->ptr, "camera_only", FALSE);
+
+ WM_keymap_add_item(keymap, "VIEW3D_OT_clear_render_border", BKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_camera_to_view", PAD0, KM_PRESS, KM_ALT | KM_CTRL, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_object_as_camera", PAD0, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
new file mode 100644
index 00000000000..5362f0377c3
--- /dev/null
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -0,0 +1,493 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_view3d/view3d_project.c
+ * \ingroup spview3d
+ */
+
+#include "DNA_object_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_view3d_types.h"
+
+#include "BLO_sys_types.h" /* int64_t */
+
+#include "BIF_gl.h" /* bglMats */
+#include "BIF_glutil.h" /* bglMats */
+
+#include "BLI_math_vector.h"
+
+#include "ED_view3d.h" /* own include */
+
+#define BL_NEAR_CLIP 0.001
+
+/* Non Clipping Projection Functions
+ * ********************************* */
+
+/**
+ * \note use #ED_view3d_ob_project_mat_get to get the projection matrix
+ */
+void ED_view3d_project_float_v2_m4(const ARegion *ar, const float co[3], float r_co[2], float mat[4][4])
+{
+ float vec4[4];
+
+ copy_v3_v3(vec4, co);
+ vec4[3] = 1.0;
+ /* r_co[0] = IS_CLIPPED; */ /* always overwritten */
+
+ mul_m4_v4(mat, vec4);
+
+ if (vec4[3] > FLT_EPSILON) {
+ r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3];
+ r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3];
+ }
+ else {
+ zero_v2(r_co);
+ }
+}
+
+/**
+ * \note use #ED_view3d_ob_project_mat_get to get projecting mat
+ */
+void ED_view3d_project_float_v3_m4(ARegion *ar, const float vec[3], float r_co[3], float mat[4][4])
+{
+ float vec4[4];
+
+ copy_v3_v3(vec4, vec);
+ vec4[3] = 1.0;
+ /* r_co[0] = IS_CLIPPED; */ /* always overwritten */
+
+ mul_m4_v4(mat, vec4);
+
+ if (vec4[3] > FLT_EPSILON) {
+ r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3];
+ r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3];
+ r_co[2] = vec4[2] / vec4[3];
+ }
+ else {
+ zero_v3(r_co);
+ }
+}
+
+
+/* Clipping Projection Functions
+ * ***************************** */
+
+eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base)
+{
+ eV3DProjStatus ret = ED_view3d_project_short_global(ar, base->object->obmat[3], &base->sx, V3D_PROJ_TEST_CLIP_DEFAULT);
+
+ if (ret != V3D_PROJ_RET_OK) {
+ base->sx = IS_CLIPPED;
+ base->sy = 0;
+ }
+
+ return ret;
+}
+
+/* perspmat is typically...
+ * - 'rv3d->perspmat', is_local == FALSE
+ * - 'rv3d->perspmatob', is_local == TRUE
+ */
+static eV3DProjStatus ed_view3d_project__internal(ARegion *ar,
+ float perspmat[4][4], const int is_local, /* normally hidden */
+ const float co[3], float r_co[2], const eV3DProjTest flag)
+{
+ float fx, fy, vec4[4];
+
+ /* check for bad flags */
+ BLI_assert((flag & V3D_PROJ_TEST_ALL) == flag);
+
+ if (flag & V3D_PROJ_TEST_CLIP_BB) {
+ RegionView3D *rv3d = ar->regiondata;
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ if (ED_view3d_clipping_test(rv3d, co, is_local)) {
+ return V3D_PROJ_RET_CLIP_BB;
+ }
+ }
+ }
+
+ copy_v3_v3(vec4, co);
+ vec4[3] = 1.0;
+ mul_m4_v4(perspmat, vec4);
+
+ if (vec4[3] > (float)BL_NEAR_CLIP) {
+ fx = ((float)ar->winx / 2.0f) * (1.0f + vec4[0] / vec4[3]);
+ if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fx > 0 && fx < ar->winx)) {
+ fy = ((float)ar->winy / 2.0f) * (1.0f + vec4[1] / vec4[3]);
+ if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fy > 0.0f && fy < (float)ar->winy)) {
+ r_co[0] = (short)floor(fx);
+ r_co[1] = (short)floor(fy);
+ }
+ else {
+ return V3D_PROJ_RET_CLIP_WIN;
+ }
+ }
+ else {
+ return V3D_PROJ_RET_CLIP_WIN;
+ }
+ }
+ else {
+ return V3D_PROJ_RET_CLIP_NEAR;
+ }
+
+ return V3D_PROJ_RET_OK;
+}
+
+eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], const int is_local,
+ const float co[3], short r_co[2], const eV3DProjTest flag)
+{
+ float tvec[2];
+ eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag);
+ if (ret == V3D_PROJ_RET_OK) {
+ if ((tvec[0] > -32700.0 && tvec[0] < 32700.0f) &&
+ (tvec[1] > -32700.0 && tvec[1] < 32700.0f))
+ {
+ r_co[0] = (short)floor(tvec[0]);
+ r_co[1] = (short)floor(tvec[1]);
+ }
+ else {
+ ret = V3D_PROJ_RET_OVERFLOW;
+ }
+ }
+ return ret;
+}
+
+eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const int is_local,
+ const float co[3], int r_co[2], const eV3DProjTest flag)
+{
+ float tvec[2];
+ eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag);
+ if (ret == V3D_PROJ_RET_OK) {
+ if ((tvec[0] > -2140000000.0 && tvec[0] < 2140000000.0f) &&
+ (tvec[1] > -2140000000.0 && tvec[1] < 2140000000.0f))
+ {
+ r_co[0] = (int)floor(tvec[0]);
+ r_co[1] = (int)floor(tvec[1]);
+ }
+ else {
+ ret = V3D_PROJ_RET_OVERFLOW;
+ }
+ }
+ return ret;
+}
+
+eV3DProjStatus ED_view3d_project_float_ex(ARegion *ar, float perspmat[4][4], const int is_local,
+ const float co[3], float r_co[2], const eV3DProjTest flag)
+{
+ float tvec[2];
+ eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag);
+ if (ret == V3D_PROJ_RET_OK) {
+ if (finite(tvec[0]) &&
+ finite(tvec[1]))
+ {
+ copy_v2_v2(r_co, tvec);
+ }
+ else {
+ ret = V3D_PROJ_RET_OVERFLOW;
+ }
+ }
+ return ret;
+}
+
+/* --- short --- */
+eV3DProjStatus ED_view3d_project_short_global(ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ return ED_view3d_project_short_ex(ar, rv3d->persmat, FALSE, co, r_co, flag);
+}
+/* object space, use ED_view3d_init_mats_rv3d before calling */
+eV3DProjStatus ED_view3d_project_short_object(ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ return ED_view3d_project_short_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag);
+}
+
+/* --- int --- */
+eV3DProjStatus ED_view3d_project_int_global(ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ return ED_view3d_project_int_ex(ar, rv3d->persmat, FALSE, co, r_co, flag);
+}
+/* object space, use ED_view3d_init_mats_rv3d before calling */
+eV3DProjStatus ED_view3d_project_int_object(ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ return ED_view3d_project_int_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag);
+}
+
+/* --- float --- */
+eV3DProjStatus ED_view3d_project_float_global(ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ return ED_view3d_project_float_ex(ar, rv3d->persmat, FALSE, co, r_co, flag);
+}
+/* object space, use ED_view3d_init_mats_rv3d before calling */
+eV3DProjStatus ED_view3d_project_float_object(ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ return ED_view3d_project_float_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag);
+}
+
+
+
+/* More Generic Window/Ray/Vector projection functions
+ * *************************************************** */
+
+/* odd function, need to document better */
+int initgrabz(RegionView3D *rv3d, float x, float y, float z)
+{
+ int flip = FALSE;
+ if (rv3d == NULL) return flip;
+ rv3d->zfac = rv3d->persmat[0][3] * x + rv3d->persmat[1][3] * y + rv3d->persmat[2][3] * z + rv3d->persmat[3][3];
+ if (rv3d->zfac < 0.0f)
+ flip = TRUE;
+ /* if x,y,z is exactly the viewport offset, zfac is 0 and we don't want that
+ * (accounting for near zero values)
+ */
+ if (rv3d->zfac < 1.e-6f && rv3d->zfac > -1.e-6f) rv3d->zfac = 1.0f;
+
+ /* Negative zfac means x, y, z was behind the camera (in perspective).
+ * This gives flipped directions, so revert back to ok default case.
+ */
+ /* NOTE: I've changed this to flip zfac to be positive again for now so that GPencil draws ok
+ * Aligorith, 2009Aug31 */
+ //if (rv3d->zfac < 0.0f) rv3d->zfac = 1.0f;
+ if (rv3d->zfac < 0.0f) rv3d->zfac = -rv3d->zfac;
+
+ return flip;
+}
+
+/**
+ * Calculate a 3d viewpoint and direction vector from 2d window coordinates.
+ * This ray_start is located at the viewpoint, ray_normal is the direction towards mval.
+ * ray_start is clipped by the view near limit so points in front of it are always in view.
+ * In orthographic view the resulting ray_normal will match the view vector.
+ * \param ar The region (used for the window width and height).
+ * \param v3d The 3d viewport (used for near clipping value).
+ * \param mval The area relative 2d location (such as event->mval, converted into float[2]).
+ * \param ray_start The world-space starting point of the segment.
+ * \param ray_normal The normalized world-space direction of towards mval.
+ */
+void ED_view3d_win_to_ray(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3])
+{
+ float ray_end[3];
+
+ ED_view3d_win_to_segment_clip(ar, v3d, mval, ray_start, ray_end);
+ sub_v3_v3v3(ray_normal, ray_end, ray_start);
+ normalize_v3(ray_normal);
+}
+
+/**
+ * Calculate a normalized 3d direction vector from the viewpoint towards a global location.
+ * In orthographic view the resulting vector will match the view vector.
+ * \param rv3d The region (used for the window width and height).
+ * \param coord The world-space location.
+ * \param vec The resulting normalized vector.
+ */
+void ED_view3d_global_to_vector(RegionView3D *rv3d, const float coord[3], float vec[3])
+{
+ if (rv3d->is_persp) {
+ float p1[4], p2[4];
+
+ copy_v3_v3(p1, coord);
+ p1[3] = 1.0f;
+ copy_v3_v3(p2, p1);
+ p2[3] = 1.0f;
+ mul_m4_v4(rv3d->viewmat, p2);
+
+ mul_v3_fl(p2, 2.0f);
+
+ mul_m4_v4(rv3d->viewinv, p2);
+
+ sub_v3_v3v3(vec, p1, p2);
+ }
+ else {
+ copy_v3_v3(vec, rv3d->viewinv[2]);
+ }
+ normalize_v3(vec);
+}
+
+/**
+ * Calculate a 3d location from 2d window coordinates.
+ * \param ar The region (used for the window width and height).
+ * \param depth_pt The reference location used to calculate the Z depth.
+ * \param mval The area relative location (such as event->mval converted to floats).
+ * \param out The resulting world-space location.
+ */
+void ED_view3d_win_to_3d(ARegion *ar, const float depth_pt[3], const float mval[2], float out[3])
+{
+ RegionView3D *rv3d = ar->regiondata;
+
+ float line_sta[3];
+ float line_end[3];
+
+ if (rv3d->is_persp) {
+ float mousevec[3];
+ copy_v3_v3(line_sta, rv3d->viewinv[3]);
+ ED_view3d_win_to_vector(ar, mval, mousevec);
+ add_v3_v3v3(line_end, line_sta, mousevec);
+
+ if (isect_line_plane_v3(out, line_sta, line_end, depth_pt, rv3d->viewinv[2], TRUE) == 0) {
+ /* highly unlikely to ever happen, mouse vec paralelle with view plane */
+ zero_v3(out);
+ }
+ }
+ else {
+ const float dx = (2.0f * mval[0] / (float)ar->winx) - 1.0f;
+ const float dy = (2.0f * mval[1] / (float)ar->winy) - 1.0f;
+ line_sta[0] = (rv3d->persinv[0][0] * dx) + (rv3d->persinv[1][0] * dy) + rv3d->viewinv[3][0];
+ line_sta[1] = (rv3d->persinv[0][1] * dx) + (rv3d->persinv[1][1] * dy) + rv3d->viewinv[3][1];
+ line_sta[2] = (rv3d->persinv[0][2] * dx) + (rv3d->persinv[1][2] * dy) + rv3d->viewinv[3][2];
+
+ add_v3_v3v3(line_end, line_sta, rv3d->viewinv[2]);
+ closest_to_line_v3(out, depth_pt, line_sta, line_end);
+ }
+}
+
+/**
+ * Calculate a 3d difference vector from 2d window offset.
+ * note that initgrabz() must be called first to determine
+ * the depth used to calculate the delta.
+ * \param ar The region (used for the window width and height).
+ * \param mval The area relative 2d difference (such as event->mval[0] - other_x).
+ * \param out The resulting world-space delta.
+ */
+void ED_view3d_win_to_delta(ARegion *ar, const float mval[2], float out[3])
+{
+ RegionView3D *rv3d = ar->regiondata;
+ float dx, dy;
+
+ dx = 2.0f * mval[0] * rv3d->zfac / ar->winx;
+ dy = 2.0f * mval[1] * rv3d->zfac / ar->winy;
+
+ out[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy);
+ out[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy);
+ out[2] = (rv3d->persinv[0][2] * dx + rv3d->persinv[1][2] * dy);
+}
+
+/**
+ * Calculate a 3d direction vector from 2d window coordinates.
+ * This direction vector starts and the view in the direction of the 2d window coordinates.
+ * In orthographic view all window coordinates yield the same vector.
+ *
+ * \note doesn't rely on initgrabz
+ * for perspective view, get the vector direction to
+ * the mouse cursor as a normalized vector.
+ *
+ * \param ar The region (used for the window width and height).
+ * \param mval The area relative 2d location (such as event->mval converted to floats).
+ * \param out The resulting normalized world-space direction vector.
+ */
+void ED_view3d_win_to_vector(ARegion *ar, const float mval[2], float out[3])
+{
+ RegionView3D *rv3d = ar->regiondata;
+
+ if (rv3d->is_persp) {
+ out[0] = 2.0f * (mval[0] / ar->winx) - 1.0f;
+ out[1] = 2.0f * (mval[1] / ar->winy) - 1.0f;
+ out[2] = -0.5f;
+ mul_project_m4_v3(rv3d->persinv, out);
+ sub_v3_v3(out, rv3d->viewinv[3]);
+ }
+ else {
+ copy_v3_v3(out, rv3d->viewinv[2]);
+ }
+ normalize_v3(out);
+}
+
+/**
+ * Calculate a 3d segment from 2d window coordinates.
+ * This ray_start is located at the viewpoint, ray_end is a far point.
+ * ray_start and ray_end are clipped by the view near and far limits
+ * so points along this line are always in view.
+ * In orthographic view all resulting segments will be parallel.
+ * \param ar The region (used for the window width and height).
+ * \param v3d The 3d viewport (used for near and far clipping range).
+ * \param mval The area relative 2d location (such as event->mval, converted into float[2]).
+ * \param ray_start The world-space starting point of the segment.
+ * \param ray_end The world-space end point of the segment.
+ */
+void ED_view3d_win_to_segment_clip(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3])
+{
+ RegionView3D *rv3d = ar->regiondata;
+
+ if (rv3d->is_persp) {
+ float vec[3];
+ ED_view3d_win_to_vector(ar, mval, vec);
+
+ copy_v3_v3(ray_start, rv3d->viewinv[3]);
+ madd_v3_v3v3fl(ray_start, rv3d->viewinv[3], vec, v3d->near);
+ madd_v3_v3v3fl(ray_end, rv3d->viewinv[3], vec, v3d->far);
+ }
+ else {
+ float vec[4];
+ vec[0] = 2.0f * mval[0] / ar->winx - 1;
+ vec[1] = 2.0f * mval[1] / ar->winy - 1;
+ vec[2] = 0.0f;
+ vec[3] = 1.0f;
+
+ mul_m4_v4(rv3d->persinv, vec);
+
+ madd_v3_v3v3fl(ray_start, vec, rv3d->viewinv[2], 1000.0f);
+ madd_v3_v3v3fl(ray_end, vec, rv3d->viewinv[2], -1000.0f);
+ }
+
+ /* clipping */
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ int a;
+ for (a = 0; a < 4; a++) {
+ clip_line_plane(ray_start, ray_end, rv3d->clip[a]);
+ }
+ }
+}
+
+
+/* Utility functions for projection
+ * ******************************** */
+
+void ED_view3d_ob_project_mat_get(RegionView3D *rv3d, Object *ob, float pmat[4][4])
+{
+ float vmat[4][4];
+
+ mult_m4_m4m4(vmat, rv3d->viewmat, ob->obmat);
+ mult_m4_m4m4(pmat, rv3d->winmat, vmat);
+}
+
+/**
+ * Uses window coordinates (x,y) and depth component z to find a point in
+ * modelspace */
+void ED_view3d_unproject(bglMats *mats, float out[3], const float x, const float y, const float z)
+{
+ double ux, uy, uz;
+
+ gluUnProject(x, y, z, mats->modelview, mats->projection,
+ (GLint *)mats->viewport, &ux, &uy, &uz);
+
+ out[0] = ux;
+ out[1] = uy;
+ out[2] = uz;
+}
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 53f2c2e9f5e..c30adf844a8 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -120,7 +120,7 @@ int view3d_get_view_aligned_coordinate(ViewContext *vc, float fp[3], const int m
initgrabz(vc->rv3d, fp[0], fp[1], fp[2]);
- if (ret == V3D_PROJ_RET_SUCCESS) {
+ if (ret == V3D_PROJ_RET_OK) {
const float mval_f[2] = {(float)(mval_cpy[0] - mval[0]),
(float)(mval_cpy[1] - mval[1])};
ED_view3d_win_to_delta(vc->ar, mval_f, dvec);
@@ -258,6 +258,8 @@ static void edbm_backbuf_check_and_select_tfaces(Mesh *me, int select)
typedef struct LassoSelectUserData {
ViewContext *vc;
const rcti *rect;
+ const rctf *rect_fl;
+ rctf _rect_fl;
const int (*mcords)[2];
int moves;
int select;
@@ -273,7 +275,11 @@ static void view3d_userdata_lassoselect_init(LassoSelectUserData *r_data,
const int moves, const int select)
{
r_data->vc = vc;
+
r_data->rect = rect;
+ r_data->rect_fl = &r_data->_rect_fl;
+ BLI_rctf_rcti_copy(&r_data->_rect_fl, rect);
+
r_data->mcords = mcords;
r_data->moves = moves;
r_data->select = select;
@@ -314,29 +320,29 @@ static int view3d_selectable_data(bContext *C)
/* helper also for borderselect */
-static int edge_fully_inside_rect(const rcti *rect, int x1, int y1, int x2, int y2)
+static int edge_fully_inside_rect(const rctf *rect, const float v1[2], const float v2[2])
{
- return BLI_rcti_isect_pt(rect, x1, y1) && BLI_rcti_isect_pt(rect, x2, y2);
+ return BLI_rctf_isect_pt_v(rect, v1) && BLI_rctf_isect_pt_v(rect, v2);
}
-static int edge_inside_rect(const rcti *rect, int x1, int y1, int x2, int y2)
+static int edge_inside_rect(const rctf *rect, const float v1[2], const float v2[2])
{
int d1, d2, d3, d4;
/* check points in rect */
- if (edge_fully_inside_rect(rect, x1, y1, x2, y2)) return 1;
+ if (edge_fully_inside_rect(rect, v1, v2)) return 1;
/* check points completely out rect */
- if (x1 < rect->xmin && x2 < rect->xmin) return 0;
- if (x1 > rect->xmax && x2 > rect->xmax) return 0;
- if (y1 < rect->ymin && y2 < rect->ymin) return 0;
- if (y1 > rect->ymax && y2 > rect->ymax) return 0;
+ if (v1[0] < rect->xmin && v2[0] < rect->xmin) return 0;
+ if (v1[0] > rect->xmax && v2[0] > rect->xmax) return 0;
+ if (v1[1] < rect->ymin && v2[1] < rect->ymin) return 0;
+ if (v1[1] > rect->ymax && v2[1] > rect->ymax) return 0;
/* simple check lines intersecting. */
- d1 = (y1 - y2) * (x1 - rect->xmin) + (x2 - x1) * (y1 - rect->ymin);
- d2 = (y1 - y2) * (x1 - rect->xmin) + (x2 - x1) * (y1 - rect->ymax);
- d3 = (y1 - y2) * (x1 - rect->xmax) + (x2 - x1) * (y1 - rect->ymax);
- d4 = (y1 - y2) * (x1 - rect->xmax) + (x2 - x1) * (y1 - rect->ymin);
+ d1 = (v1[1] - v2[1]) * (v1[0] - rect->xmin) + (v2[0] - v1[0]) * (v1[1] - rect->ymin);
+ d2 = (v1[1] - v2[1]) * (v1[0] - rect->xmin) + (v2[0] - v1[0]) * (v1[1] - rect->ymax);
+ d3 = (v1[1] - v2[1]) * (v1[0] - rect->xmax) + (v2[0] - v1[0]) * (v1[1] - rect->ymax);
+ d4 = (v1[1] - v2[1]) * (v1[0] - rect->xmax) + (v2[0] - v1[0]) * (v1[1] - rect->ymin);
if (d1 < 0 && d2 < 0 && d3 < 0 && d4 < 0) return 0;
if (d1 > 0 && d2 > 0 && d3 > 0 && d4 > 0) return 0;
@@ -344,7 +350,7 @@ static int edge_inside_rect(const rcti *rect, int x1, int y1, int x2, int y2)
return 1;
}
-static void do_lasso_select_pose__doSelectBone(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1)
+static void do_lasso_select_pose__doSelectBone(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2])
{
LassoSelectUserData *data = userData;
bArmature *arm = data->vc->obact->data;
@@ -353,6 +359,11 @@ static void do_lasso_select_pose__doSelectBone(void *userData, struct bPoseChann
int is_point_done = FALSE;
int points_proj_tot = 0;
+ const int x0 = screen_co_a[0];
+ const int y0 = screen_co_a[1];
+ const int x1 = screen_co_b[0];
+ const int y1 = screen_co_b[1];
+
/* project head location to screenspace */
if (x0 != IS_CLIPPED) {
points_proj_tot++;
@@ -387,6 +398,7 @@ static void do_lasso_select_pose__doSelectBone(void *userData, struct bPoseChann
}
static void do_lasso_select_pose(ViewContext *vc, Object *ob, const int mcords[][2], short moves, short select)
{
+ ViewContext vc_tmp;
LassoSelectUserData data;
rcti rect;
@@ -394,13 +406,16 @@ static void do_lasso_select_pose(ViewContext *vc, Object *ob, const int mcords[]
return;
}
+ vc_tmp = *vc;
+ vc_tmp.obact = ob;
+
+ BLI_lasso_boundbox(&rect, mcords, moves);
+
view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select);
ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d);
- BLI_lasso_boundbox(&rect, mcords, moves);
-
- pose_foreachScreenBone(vc, do_lasso_select_pose__doSelectBone, &data);
+ pose_foreachScreenBone(&vc_tmp, do_lasso_select_pose__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
if (data.is_change) {
bArmature *arm = ob->data;
@@ -445,23 +460,28 @@ static void do_lasso_select_objects(ViewContext *vc, const int mcords[][2], cons
}
}
-static void do_lasso_select_mesh__doSelectVert(void *userData, BMVert *eve, int x, int y, int UNUSED(index))
+static void do_lasso_select_mesh__doSelectVert(void *userData, BMVert *eve, const float screen_co[2], int UNUSED(index))
{
LassoSelectUserData *data = userData;
- if (BLI_rcti_isect_pt(data->rect, x, y) &&
- BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, IS_CLIPPED))
+ if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
+ BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED))
{
BM_vert_select_set(data->vc->em->bm, eve, data->select);
}
}
-static void do_lasso_select_mesh__doSelectEdge(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index)
+static void do_lasso_select_mesh__doSelectEdge(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
{
LassoSelectUserData *data = userData;
if (EDBM_backbuf_check(bm_solidoffs + index)) {
+ const int x0 = screen_co_a[0];
+ const int y0 = screen_co_a[1];
+ const int x1 = screen_co_b[0];
+ const int y1 = screen_co_b[1];
+
if (data->pass == 0) {
- if (edge_fully_inside_rect(data->rect, x0, y0, x1, y1) &&
+ if (edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b) &&
BLI_lasso_is_point_inside(data->mcords, data->moves, x0, y0, IS_CLIPPED) &&
BLI_lasso_is_point_inside(data->mcords, data->moves, x1, y1, IS_CLIPPED))
{
@@ -476,12 +496,12 @@ static void do_lasso_select_mesh__doSelectEdge(void *userData, BMEdge *eed, int
}
}
}
-static void do_lasso_select_mesh__doSelectFace(void *userData, BMFace *efa, int x, int y, int UNUSED(index))
+static void do_lasso_select_mesh__doSelectFace(void *userData, BMFace *efa, const float screen_co[2], int UNUSED(index))
{
LassoSelectUserData *data = userData;
- if (BLI_rcti_isect_pt(data->rect, x, y) &&
- BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, IS_CLIPPED))
+ if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
+ BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED))
{
BM_face_select_set(data->vc->em->bm, efa, data->select);
}
@@ -494,11 +514,11 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m
rcti rect;
int bbsel;
- BLI_lasso_boundbox(&rect, mcords, moves);
-
/* set editmesh */
vc->em = BMEdit_FromObject(vc->obedit);
+ BLI_lasso_boundbox(&rect, mcords, moves);
+
view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select);
if (extend == 0 && select)
@@ -515,17 +535,17 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m
edbm_backbuf_check_and_select_verts(vc->em, select);
}
else {
- mesh_foreachScreenVert(vc, do_lasso_select_mesh__doSelectVert, &data, V3D_CLIP_TEST_RV3D_CLIPPING);
+ mesh_foreachScreenVert(vc, do_lasso_select_mesh__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
if (ts->selectmode & SCE_SELECT_EDGE) {
/* Does both bbsel and non-bbsel versions (need screen cos for both) */
data.pass = 0;
- mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_CLIP_TEST_OFF);
+ mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_NOP);
if (data.is_done == 0) {
data.pass = 1;
- mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_CLIP_TEST_OFF);
+ mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_NOP);
}
}
@@ -534,7 +554,7 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m
edbm_backbuf_check_and_select_faces(vc->em, select);
}
else {
- mesh_foreachScreenFace(vc, do_lasso_select_mesh__doSelectFace, &data);
+ mesh_foreachScreenFace(vc, do_lasso_select_mesh__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
@@ -542,13 +562,13 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m
EDBM_selectmode_flush(vc->em);
}
-static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y)
+static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2])
{
LassoSelectUserData *data = userData;
Object *obedit = data->vc->obedit;
Curve *cu = (Curve *)obedit->data;
- if (BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, IS_CLIPPED)) {
+ if (BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED)) {
if (bp) {
bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT);
if (bp == cu->lastsel && !(bp->f1 & SELECT)) cu->lastsel = NULL;
@@ -578,38 +598,45 @@ static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BP
static void do_lasso_select_curve(ViewContext *vc, const int mcords[][2], short moves, short extend, short select)
{
LassoSelectUserData data;
+ rcti rect;
+
+ BLI_lasso_boundbox(&rect, mcords, moves);
- view3d_userdata_lassoselect_init(&data, vc, NULL, mcords, moves, select);
+ view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select);
if (extend == 0 && select)
CU_deselect_all(vc->obedit);
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
- nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data);
+ nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
-static void do_lasso_select_lattice__doSelect(void *userData, BPoint *bp, int x, int y)
+static void do_lasso_select_lattice__doSelect(void *userData, BPoint *bp, const float screen_co[2])
{
LassoSelectUserData *data = userData;
- if (BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, IS_CLIPPED)) {
+ if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
+ BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED)) {
bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT);
}
}
static void do_lasso_select_lattice(ViewContext *vc, const int mcords[][2], short moves, short extend, short select)
{
LassoSelectUserData data;
+ rcti rect;
- view3d_userdata_lassoselect_init(&data, vc, NULL, mcords, moves, select);
+ BLI_lasso_boundbox(&rect, mcords, moves);
+
+ view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select);
if (extend == 0 && select)
ED_setflagsLatt(vc->obedit, 0);
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
- lattice_foreachScreenVert(vc, do_lasso_select_lattice__doSelect, &data);
+ lattice_foreachScreenVert(vc, do_lasso_select_lattice__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
-static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1)
+static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2])
{
LassoSelectUserData *data = userData;
bArmature *arm = data->vc->obedit->data;
@@ -618,6 +645,11 @@ static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBo
int is_point_done = FALSE;
int points_proj_tot = 0;
+ const int x0 = screen_co_a[0];
+ const int y0 = screen_co_a[1];
+ const int x1 = screen_co_b[0];
+ const int y1 = screen_co_b[1];
+
/* project head location to screenspace */
if (x0 != IS_CLIPPED) {
points_proj_tot++;
@@ -660,16 +692,16 @@ static void do_lasso_select_armature(ViewContext *vc, const int mcords[][2], sho
LassoSelectUserData data;
rcti rect;
+ BLI_lasso_boundbox(&rect, mcords, moves);
+
view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select);
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- BLI_lasso_boundbox(&rect, mcords, moves);
-
if (extend == 0 && select)
ED_armature_deselect_all_visible(vc->obedit);
- armature_foreachScreenBone(vc, do_lasso_select_armature__doSelectBone, &data);
+ armature_foreachScreenBone(vc, do_lasso_select_armature__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
if (data.is_change) {
bArmature *arm = vc->obedit->data;
@@ -679,12 +711,12 @@ static void do_lasso_select_armature(ViewContext *vc, const int mcords[][2], sho
}
}
-static void do_lasso_select_mball__doSelectElem(void *userData, struct MetaElem *ml, int x, int y)
+static void do_lasso_select_mball__doSelectElem(void *userData, struct MetaElem *ml, const float screen_co[2])
{
LassoSelectUserData *data = userData;
- if (BLI_rcti_isect_pt(data->rect, x, y) &&
- BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, INT_MAX)) {
+ if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) &&
+ BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], INT_MAX)) {
if (data->select) ml->flag |= SELECT;
else ml->flag &= ~SELECT;
data->is_change = TRUE;
@@ -700,13 +732,13 @@ static void do_lasso_select_meta(ViewContext *vc, const int mcords[][2], short m
if (extend == 0 && select)
BKE_mball_deselect_all(mb);
+ BLI_lasso_boundbox(&rect, mcords, moves);
+
view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select);
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- BLI_lasso_boundbox(&rect, mcords, moves);
-
- mball_foreachScreenElem(vc, do_lasso_select_mball__doSelectElem, &data);
+ mball_foreachScreenElem(vc, do_lasso_select_mball__doSelectElem, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
static int do_paintvert_box_select(ViewContext *vc, rcti *rect, int select, int extend)
@@ -856,9 +888,10 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc,
do_lasso_select_paintface(vc, mcords, moves, extend, select);
else if (paint_vertsel_test(ob))
do_lasso_select_paintvert(vc, mcords, moves, extend, select);
- else if (ob && ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))
- ;
- else if (ob && ob->mode & OB_MODE_PARTICLE_EDIT)
+ else if (ob && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) {
+ /* pass */
+ }
+ else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT))
PE_lasso_select(C, mcords, moves, extend, select);
else {
do_lasso_select_objects(vc, mcords, moves, extend, select);
@@ -911,7 +944,7 @@ static int view3d_lasso_select_exec(bContext *C, wmOperator *op)
select = !RNA_boolean_get(op->ptr, "deselect");
view3d_lasso_select(C, &vc, mcords, mcords_tot, extend, select);
- MEM_freeN(mcords);
+ MEM_freeN((void *)mcords);
return OPERATOR_FINISHED;
}
@@ -1387,9 +1420,12 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese
View3D *v3d = CTX_wm_view3d(C);
Scene *scene = CTX_data_scene(C);
Base *base, *startbase = NULL, *basact = NULL, *oldbasact = NULL;
- int temp, a, dist = 100;
+ int a;
+ float dist = 100.0f;
int retval = 0;
short hits;
+ const float mval_fl[2] = {(float)mval[0], (float)mval[1]};
+
/* setup view context for argument to callbacks */
view3d_set_viewcontext(C, &vc);
@@ -1410,13 +1446,16 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese
base = startbase;
while (base) {
if (BASE_SELECTABLE(v3d, base)) {
- ED_view3d_project_base(ar, base);
- temp = abs(base->sx - mval[0]) + abs(base->sy - mval[1]);
- if (base == BASACT) temp += 10;
- if (temp < dist) {
-
- dist = temp;
- basact = base;
+ float screen_co[2];
+ if (ED_view3d_project_float_global(ar, base->object->obmat[3], screen_co,
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK)
+ {
+ float dist_temp = len_manhattan_v2v2(mval_fl, screen_co);
+ if (base == BASACT) dist_temp += 10.0f;
+ if (dist_temp < dist) {
+ dist = dist_temp;
+ basact = base;
+ }
}
}
base = base->next;
@@ -1506,7 +1545,8 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese
}
}
}
- else if (ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend, deselect, toggle) ) { /* then bone is found */
+ else if (ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend, deselect, toggle) ) {
+ /* then bone is found */
/* we make the armature selected:
* not-selected active object in posemode won't work well for tools */
@@ -1582,6 +1622,8 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese
typedef struct BoxSelectUserData {
ViewContext *vc;
const rcti *rect;
+ const rctf *rect_fl;
+ rctf _rect_fl;
int select;
/* runtime */
@@ -1594,7 +1636,11 @@ static void view3d_userdata_boxselect_init(BoxSelectUserData *r_data,
ViewContext *vc, const rcti *rect, const int select)
{
r_data->vc = vc;
+
r_data->rect = rect;
+ r_data->rect_fl = &r_data->_rect_fl;
+ BLI_rctf_rcti_copy(&r_data->_rect_fl, rect);
+
r_data->select = select;
/* runtime */
@@ -1603,23 +1649,20 @@ static void view3d_userdata_boxselect_init(BoxSelectUserData *r_data,
r_data->is_change = FALSE;
}
-int edge_inside_circle(int centx, int centy, int radius, int x1, int y1, int x2, int y2)
+int edge_inside_circle(const float cent[2], float radius, const float screen_co_a[2], const float screen_co_b[2])
{
int radius_squared = radius * radius;
/* check points in circle itself */
- if ((x1 - centx) * (x1 - centx) + (y1 - centy) * (y1 - centy) <= radius_squared) {
+ if (len_squared_v2v2(cent, screen_co_a) <= radius_squared) {
return TRUE;
}
- else if ((x2 - centx) * (x2 - centx) + (y2 - centy) * (y2 - centy) <= radius_squared) {
+ if (len_squared_v2v2(cent, screen_co_b) <= radius_squared) {
return TRUE;
}
else {
- const float cent[2] = {centx, centy};
- const float v1[2] = {x1, y1};
- const float v2[2] = {x2, y2};
/* pointdistline */
- if (dist_squared_to_line_segment_v2(cent, v1, v2) < (float)radius_squared) {
+ if (dist_squared_to_line_segment_v2(cent, screen_co_a, screen_co_b) < (float)radius_squared) {
return TRUE;
}
}
@@ -1627,13 +1670,13 @@ int edge_inside_circle(int centx, int centy, int radius, int x1, int y1, int x2,
return FALSE;
}
-static void do_nurbs_box_select__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y)
+static void do_nurbs_box_select__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2])
{
BoxSelectUserData *data = userData;
Object *obedit = data->vc->obedit;
Curve *cu = (Curve *)obedit->data;
- if (BLI_rcti_isect_pt(data->rect, x, y)) {
+ if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co)) {
if (bp) {
bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT);
if (bp == cu->lastsel && !(bp->f1 & SELECT)) cu->lastsel = NULL;
@@ -1669,16 +1712,16 @@ static int do_nurbs_box_select(ViewContext *vc, rcti *rect, int select, int exte
CU_deselect_all(vc->obedit);
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
- nurbs_foreachScreenVert(vc, do_nurbs_box_select__doSelect, &data);
+ nurbs_foreachScreenVert(vc, do_nurbs_box_select__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
return OPERATOR_FINISHED;
}
-static void do_lattice_box_select__doSelect(void *userData, BPoint *bp, int x, int y)
+static void do_lattice_box_select__doSelect(void *userData, BPoint *bp, const float screen_co[2])
{
BoxSelectUserData *data = userData;
- if (BLI_rcti_isect_pt(data->rect, x, y)) {
+ if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co)) {
bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT);
}
}
@@ -1692,42 +1735,42 @@ static int do_lattice_box_select(ViewContext *vc, rcti *rect, int select, int ex
ED_setflagsLatt(vc->obedit, 0);
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
- lattice_foreachScreenVert(vc, do_lattice_box_select__doSelect, &data);
+ lattice_foreachScreenVert(vc, do_lattice_box_select__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
return OPERATOR_FINISHED;
}
-static void do_mesh_box_select__doSelectVert(void *userData, BMVert *eve, int x, int y, int UNUSED(index))
+static void do_mesh_box_select__doSelectVert(void *userData, BMVert *eve, const float screen_co[2], int UNUSED(index))
{
BoxSelectUserData *data = userData;
- if (BLI_rcti_isect_pt(data->rect, x, y)) {
+ if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co)) {
BM_vert_select_set(data->vc->em->bm, eve, data->select);
}
}
-static void do_mesh_box_select__doSelectEdge(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index)
+static void do_mesh_box_select__doSelectEdge(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
{
BoxSelectUserData *data = userData;
if (EDBM_backbuf_check(bm_solidoffs + index)) {
if (data->pass == 0) {
- if (edge_fully_inside_rect(data->rect, x0, y0, x1, y1)) {
+ if (edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b)) {
BM_edge_select_set(data->vc->em->bm, eed, data->select);
data->is_done = TRUE;
}
}
else {
- if (edge_inside_rect(data->rect, x0, y0, x1, y1)) {
+ if (edge_inside_rect(data->rect_fl, screen_co_a, screen_co_b)) {
BM_edge_select_set(data->vc->em->bm, eed, data->select);
}
}
}
}
-static void do_mesh_box_select__doSelectFace(void *userData, BMFace *efa, int x, int y, int UNUSED(index))
+static void do_mesh_box_select__doSelectFace(void *userData, BMFace *efa, const float screen_co[2], int UNUSED(index))
{
BoxSelectUserData *data = userData;
- if (BLI_rcti_isect_pt(data->rect, x, y)) {
+ if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co)) {
BM_face_select_set(data->vc->em->bm, efa, data->select);
}
}
@@ -1753,18 +1796,18 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exten
edbm_backbuf_check_and_select_verts(vc->em, select);
}
else {
- mesh_foreachScreenVert(vc, do_mesh_box_select__doSelectVert, &data, V3D_CLIP_TEST_RV3D_CLIPPING);
+ mesh_foreachScreenVert(vc, do_mesh_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
if (ts->selectmode & SCE_SELECT_EDGE) {
/* Does both bbsel and non-bbsel versions (need screen cos for both) */
data.pass = 0;
- mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_CLIP_TEST_OFF);
+ mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_NOP);
if (data.is_done == 0) {
data.pass = 1;
- mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_CLIP_TEST_OFF);
+ mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_NOP);
}
}
@@ -1773,7 +1816,7 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exten
edbm_backbuf_check_and_select_faces(vc->em, select);
}
else {
- mesh_foreachScreenFace(vc, do_mesh_box_select__doSelectFace, &data);
+ mesh_foreachScreenFace(vc, do_mesh_box_select__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
@@ -1972,12 +2015,10 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, i
}
if (bone_selected) {
- Object *ob = base->object;
-
- if (ob && (ob->type == OB_ARMATURE)) {
- bArmature *arm = ob->data;
+ if (base->object && (base->object->type == OB_ARMATURE)) {
+ bArmature *arm = base->object->data;
- WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
+ WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, base->object);
if (arm && (arm->flag & ARM_HAS_VIZ_DEPS)) {
/* mask modifier ('armature' mode), etc. */
@@ -2215,7 +2256,8 @@ void VIEW3D_OT_select(wmOperatorType *ot)
typedef struct CircleSelectUserData {
ViewContext *vc;
short select;
- int mval[2];
+ int mval[2];
+ float mval_fl[2];
float radius;
float radius_squared;
@@ -2229,6 +2271,9 @@ static void view3d_userdata_circleselect_init(CircleSelectUserData *r_data,
r_data->vc = vc;
r_data->select = select;
copy_v2_v2_int(r_data->mval, mval);
+ r_data->mval_fl[0] = mval[0];
+ r_data->mval_fl[1] = mval[1];
+
r_data->radius = rad;
r_data->radius_squared = rad * rad;
@@ -2236,31 +2281,27 @@ static void view3d_userdata_circleselect_init(CircleSelectUserData *r_data,
r_data->is_change = FALSE;
}
-static void mesh_circle_doSelectVert(void *userData, BMVert *eve, int x, int y, int UNUSED(index))
+static void mesh_circle_doSelectVert(void *userData, BMVert *eve, const float screen_co[2], int UNUSED(index))
{
CircleSelectUserData *data = userData;
- const float delta[2] = {(float)(x - data->mval[0]),
- (float)(y - data->mval[1])};
- if (len_squared_v2(delta) <= data->radius_squared) {
+ if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
BM_vert_select_set(data->vc->em->bm, eve, data->select);
}
}
-static void mesh_circle_doSelectEdge(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int UNUSED(index))
+static void mesh_circle_doSelectEdge(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int UNUSED(index))
{
CircleSelectUserData *data = userData;
- if (edge_inside_circle(data->mval[0], data->mval[1], (int)data->radius, x0, y0, x1, y1)) {
+ if (edge_inside_circle(data->mval_fl, (int)data->radius, screen_co_a, screen_co_b)) {
BM_edge_select_set(data->vc->em->bm, eed, data->select);
}
}
-static void mesh_circle_doSelectFace(void *userData, BMFace *efa, int x, int y, int UNUSED(index))
+static void mesh_circle_doSelectFace(void *userData, BMFace *efa, const float screen_co[2], int UNUSED(index))
{
CircleSelectUserData *data = userData;
- const float delta[2] = {(float)(x - data->mval[0]),
- (float)(y - data->mval[1])};
- if (len_squared_v2(delta) <= data->radius_squared) {
+ if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
BM_face_select_set(data->vc->em->bm, efa, data->select);
}
}
@@ -2283,7 +2324,7 @@ static void mesh_circle_select(ViewContext *vc, int select, const int mval[2], f
edbm_backbuf_check_and_select_verts(vc->em, select == LEFTMOUSE);
}
else {
- mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, &data, V3D_CLIP_TEST_RV3D_CLIPPING);
+ mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
@@ -2292,7 +2333,7 @@ static void mesh_circle_select(ViewContext *vc, int select, const int mval[2], f
edbm_backbuf_check_and_select_edges(vc->em, select == LEFTMOUSE);
}
else {
- mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_CLIP_TEST_OFF);
+ mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_NOP);
}
}
@@ -2301,7 +2342,7 @@ static void mesh_circle_select(ViewContext *vc, int select, const int mval[2], f
edbm_backbuf_check_and_select_faces(vc->em, select == LEFTMOUSE);
}
else {
- mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, &data);
+ mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
@@ -2344,16 +2385,13 @@ static void paint_vertsel_circle_select(ViewContext *vc, int select, const int m
}
-static void nurbscurve_circle_doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y)
+static void nurbscurve_circle_doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2])
{
CircleSelectUserData *data = userData;
Object *obedit = data->vc->obedit;
Curve *cu = (Curve *)obedit->data;
- const float delta[2] = {(float)(x - data->mval[0]),
- (float)(y - data->mval[1])};
-
- if (len_squared_v2(delta) <= data->radius_squared) {
+ if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
if (bp) {
bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT);
@@ -2387,17 +2425,15 @@ static void nurbscurve_circle_select(ViewContext *vc, int select, const int mval
view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
- nurbs_foreachScreenVert(vc, nurbscurve_circle_doSelect, &data);
+ nurbs_foreachScreenVert(vc, nurbscurve_circle_doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
-static void latticecurve_circle_doSelect(void *userData, BPoint *bp, int x, int y)
+static void latticecurve_circle_doSelect(void *userData, BPoint *bp, const float screen_co[2])
{
CircleSelectUserData *data = userData;
- const float delta[2] = {(float)(x - data->mval[0]),
- (float)(y - data->mval[1])};
- if (len_squared_v2(delta) <= data->radius_squared) {
+ if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT);
}
}
@@ -2408,18 +2444,16 @@ static void lattice_circle_select(ViewContext *vc, int select, const int mval[2]
view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
- lattice_foreachScreenVert(vc, latticecurve_circle_doSelect, &data);
+ lattice_foreachScreenVert(vc, latticecurve_circle_doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
/* NOTE: pose-bone case is copied from editbone case... */
-static short pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, int x, int y)
+static short pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, const float screen_co[2])
{
CircleSelectUserData *data = userData;
- const float delta[2] = {(float)(x - data->mval[0]),
- (float)(y - data->mval[1])};
- if (len_squared_v2(delta) <= data->radius_squared) {
+ if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
if (data->select)
pchan->bone->flag |= BONE_SELECTED;
else
@@ -2428,7 +2462,7 @@ static short pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, int
}
return 0;
}
-static void do_circle_select_pose__doSelectBone(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1)
+static void do_circle_select_pose__doSelectBone(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2])
{
CircleSelectUserData *data = userData;
bArmature *arm = data->vc->obact->data;
@@ -2438,17 +2472,17 @@ static void do_circle_select_pose__doSelectBone(void *userData, struct bPoseChan
int points_proj_tot = 0;
/* project head location to screenspace */
- if (x0 != IS_CLIPPED) {
+ if (screen_co_a[0] != IS_CLIPPED) {
points_proj_tot++;
- if (pchan_circle_doSelectJoint(data, pchan, x0, y0)) {
+ if (pchan_circle_doSelectJoint(data, pchan, screen_co_a)) {
is_point_done = TRUE;
}
}
/* project tail location to screenspace */
- if (x1 != IS_CLIPPED) {
+ if (screen_co_b[0] != IS_CLIPPED) {
points_proj_tot++;
- if (pchan_circle_doSelectJoint(data, pchan, x1, y1)) {
+ if (pchan_circle_doSelectJoint(data, pchan, screen_co_a)) {
is_point_done = TRUE;
}
}
@@ -2461,7 +2495,7 @@ static void do_circle_select_pose__doSelectBone(void *userData, struct bPoseChan
* It works nicer to only do this if the head or tail are not in the circle,
* otherwise there is no way to circle select joints alone */
if ((is_point_done == FALSE) && (points_proj_tot == 2) &&
- edge_inside_circle(data->mval[0], data->mval[1], data->radius, x0, y0, x1, y1))
+ edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b))
{
if (data->select) pchan->bone->flag |= BONE_SELECTED;
else pchan->bone->flag &= ~BONE_SELECTED;
@@ -2479,7 +2513,7 @@ static void pose_circle_select(ViewContext *vc, int select, const int mval[2], f
ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */
- pose_foreachScreenBone(vc, do_circle_select_pose__doSelectBone, &data);
+ pose_foreachScreenBone(vc, do_circle_select_pose__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
if (data.is_change) {
bArmature *arm = vc->obact->data;
@@ -2493,13 +2527,11 @@ static void pose_circle_select(ViewContext *vc, int select, const int mval[2], f
}
}
-static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, int x, int y, short head)
+static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, const float screen_co[2], short head)
{
CircleSelectUserData *data = userData;
- const float delta[2] = {(float)(x - data->mval[0]),
- (float)(y - data->mval[1])};
-
- if (len_squared_v2(delta) <= data->radius_squared) {
+
+ if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
if (head) {
if (data->select)
ebone->flag |= BONE_ROOTSEL;
@@ -2516,7 +2548,7 @@ static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, int
}
return 0;
}
-static void do_circle_select_armature__doSelectBone(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1)
+static void do_circle_select_armature__doSelectBone(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2])
{
CircleSelectUserData *data = userData;
bArmature *arm = data->vc->obedit->data;
@@ -2526,17 +2558,17 @@ static void do_circle_select_armature__doSelectBone(void *userData, struct EditB
int points_proj_tot = 0;
/* project head location to screenspace */
- if (x0 != IS_CLIPPED) {
+ if (screen_co_a[0] != IS_CLIPPED) {
points_proj_tot++;
- if (armature_circle_doSelectJoint(data, ebone, x0, y0, TRUE)) {
+ if (armature_circle_doSelectJoint(data, ebone, screen_co_a, TRUE)) {
is_point_done = TRUE;
}
}
/* project tail location to screenspace */
- if (x1 != IS_CLIPPED) {
+ if (screen_co_b[0] != IS_CLIPPED) {
points_proj_tot++;
- if (armature_circle_doSelectJoint(data, ebone, x1, y1, FALSE)) {
+ if (armature_circle_doSelectJoint(data, ebone, screen_co_b, FALSE)) {
is_point_done = TRUE;
}
}
@@ -2549,7 +2581,7 @@ static void do_circle_select_armature__doSelectBone(void *userData, struct EditB
* It works nicer to only do this if the head or tail are not in the circle,
* otherwise there is no way to circle select joints alone */
if ((is_point_done == FALSE) && (points_proj_tot == 2) &&
- edge_inside_circle(data->mval[0], data->mval[1], data->radius, x0, y0, x1, y1))
+ edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b))
{
if (data->select) ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
else ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
@@ -2568,7 +2600,7 @@ static void armature_circle_select(ViewContext *vc, int select, const int mval[2
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- armature_foreachScreenBone(vc, do_circle_select_armature__doSelectBone, &data);
+ armature_foreachScreenBone(vc, do_circle_select_armature__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
if (data.is_change) {
ED_armature_sync_selection(arm->edbo);
@@ -2577,13 +2609,11 @@ static void armature_circle_select(ViewContext *vc, int select, const int mval[2
}
}
-static void do_circle_select_mball__doSelectElem(void *userData, struct MetaElem *ml, int x, int y)
+static void do_circle_select_mball__doSelectElem(void *userData, struct MetaElem *ml, const float screen_co[2])
{
CircleSelectUserData *data = userData;
- const float delta[2] = {(float)(x - data->mval[0]),
- (float)(y - data->mval[1])};
- if (len_squared_v2(delta) <= data->radius_squared) {
+ if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) {
if (data->select) ml->flag |= SELECT;
else ml->flag &= ~SELECT;
data->is_change = TRUE;
@@ -2597,7 +2627,7 @@ static void mball_circle_select(ViewContext *vc, int select, const int mval[2],
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- mball_foreachScreenElem(vc, do_circle_select_mball__doSelectElem, &data);
+ mball_foreachScreenElem(vc, do_circle_select_mball__doSelectElem, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
/** Callbacks for circle selection in Editmode */
@@ -2632,14 +2662,15 @@ static int object_circle_select(ViewContext *vc, int select, const int mval[2],
const float radius_squared = rad * rad;
const float mval_fl[2] = {mval[0], mval[1]};
int is_change = FALSE;
+ int select_flag = select ? SELECT : 0;
Base *base;
select = select ? BA_SELECT : BA_DESELECT;
for (base = FIRSTBASE; base; base = base->next) {
- if (((base->flag & SELECT) == 0) && BASE_SELECTABLE(vc->v3d, base)) {
+ if (BASE_SELECTABLE(vc->v3d, base) && ((base->flag & SELECT) != select_flag)) {
float screen_co[2];
if (ED_view3d_project_float_global(vc->ar, base->object->obmat[3], screen_co,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS)
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK)
{
if (len_squared_v2v2(mval_fl, screen_co) <= radius_squared) {
ED_base_object_select(base, select);
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index f138a95b0ef..de8cbd856e8 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -125,7 +125,7 @@ struct SmoothView3DStore {
/* will start timer if appropriate */
/* the arguments are the desired situation */
void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera, Object *camera,
- float *ofs, float *quat, float *dist, float *lens)
+ float *ofs, float *quat, float *dist, float *lens)
{
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
@@ -140,7 +140,7 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera
copy_qt_qt(sms.new_quat, rv3d->viewquat);
sms.new_dist = rv3d->dist;
sms.new_lens = v3d->lens;
- sms.to_camera = 0;
+ sms.to_camera = FALSE;
/* note on camera locking, this is a little confusing but works ok.
* we may be changing the view 'as if' there is no active camera, but in fact
@@ -162,22 +162,22 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera
if (camera) {
ED_view3d_from_object(camera, sms.new_ofs, sms.new_quat, &sms.new_dist, &sms.new_lens);
- sms.to_camera = 1; /* restore view3d values in end */
+ sms.to_camera = TRUE; /* restore view3d values in end */
}
if (C && U.smooth_viewtx) {
- int changed = 0; /* zero means no difference */
+ int changed = FALSE; /* zero means no difference */
if (oldcamera != camera)
- changed = 1;
+ changed = TRUE;
else if (sms.new_dist != rv3d->dist)
- changed = 1;
+ changed = TRUE;
else if (sms.new_lens != v3d->lens)
- changed = 1;
+ changed = TRUE;
else if (!equals_v3v3(sms.new_ofs, rv3d->ofs))
- changed = 1;
+ changed = TRUE;
else if (!equals_v4v4(sms.new_quat, rv3d->viewquat))
- changed = 1;
+ changed = TRUE;
/* The new view is different from the old one
* so animate the view */
@@ -241,13 +241,15 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera
/* if we get here nothing happens */
if (ok == FALSE) {
- if (sms.to_camera == 0) {
+ if (sms.to_camera == FALSE) {
copy_v3_v3(rv3d->ofs, sms.new_ofs);
copy_qt_qt(rv3d->viewquat, sms.new_quat);
rv3d->dist = sms.new_dist;
v3d->lens = sms.new_lens;
}
+ ED_view3d_camera_lock_sync(v3d, rv3d);
+
if (rv3d->viewlock & RV3D_BOXVIEW)
view3d_boxview_copy(sa, ar);
@@ -569,328 +571,27 @@ void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], bglMats *mats, co
}
}
-/**
- * Calculate a 3d segment from 2d window coordinates.
- * This ray_start is located at the viewpoint, ray_end is a far point.
- * ray_start and ray_end are clipped by the view near and far limits
- * so points along this line are always in view.
- * In orthographic view all resulting segments will be parallel.
- * \param ar The region (used for the window width and height).
- * \param v3d The 3d viewport (used for near and far clipping range).
- * \param mval The area relative 2d location (such as event->mval, converted into float[2]).
- * \param ray_start The world-space starting point of the segment.
- * \param ray_end The world-space end point of the segment.
- */
-void ED_view3d_win_to_segment_clip(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3])
-{
- RegionView3D *rv3d = ar->regiondata;
-
- if (rv3d->is_persp) {
- float vec[3];
- ED_view3d_win_to_vector(ar, mval, vec);
-
- copy_v3_v3(ray_start, rv3d->viewinv[3]);
- madd_v3_v3v3fl(ray_start, rv3d->viewinv[3], vec, v3d->near);
- madd_v3_v3v3fl(ray_end, rv3d->viewinv[3], vec, v3d->far);
- }
- else {
- float vec[4];
- vec[0] = 2.0f * mval[0] / ar->winx - 1;
- vec[1] = 2.0f * mval[1] / ar->winy - 1;
- vec[2] = 0.0f;
- vec[3] = 1.0f;
-
- mul_m4_v4(rv3d->persinv, vec);
-
- madd_v3_v3v3fl(ray_start, vec, rv3d->viewinv[2], 1000.0f);
- madd_v3_v3v3fl(ray_end, vec, rv3d->viewinv[2], -1000.0f);
- }
-
- /* clipping */
- if (rv3d->rflag & RV3D_CLIPPING) {
- int a;
- for (a = 0; a < 4; a++) {
- clip_line_plane(ray_start, ray_end, rv3d->clip[a]);
- }
- }
-}
-
-/**
- * Calculate a 3d viewpoint and direction vector from 2d window coordinates.
- * This ray_start is located at the viewpoint, ray_normal is the direction towards mval.
- * ray_start is clipped by the view near limit so points in front of it are always in view.
- * In orthographic view the resulting ray_normal will match the view vector.
- * \param ar The region (used for the window width and height).
- * \param v3d The 3d viewport (used for near clipping value).
- * \param mval The area relative 2d location (such as event->mval, converted into float[2]).
- * \param ray_start The world-space starting point of the segment.
- * \param ray_normal The normalized world-space direction of towards mval.
- */
-void ED_view3d_win_to_ray(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3])
-{
- float ray_end[3];
-
- ED_view3d_win_to_segment_clip(ar, v3d, mval, ray_start, ray_end);
- sub_v3_v3v3(ray_normal, ray_end, ray_start);
- normalize_v3(ray_normal);
-}
-
-/**
- * Calculate a normalized 3d direction vector from the viewpoint towards a global location.
- * In orthographic view the resulting vector will match the view vector.
- * \param rv3d The region (used for the window width and height).
- * \param coord The world-space location.
- * \param vec The resulting normalized vector.
- */
-void ED_view3d_global_to_vector(RegionView3D *rv3d, const float coord[3], float vec[3])
-{
- if (rv3d->is_persp) {
- float p1[4], p2[4];
-
- copy_v3_v3(p1, coord);
- p1[3] = 1.0f;
- copy_v3_v3(p2, p1);
- p2[3] = 1.0f;
- mul_m4_v4(rv3d->viewmat, p2);
-
- mul_v3_fl(p2, 2.0f);
-
- mul_m4_v4(rv3d->viewinv, p2);
-
- sub_v3_v3v3(vec, p1, p2);
- }
- else {
- copy_v3_v3(vec, rv3d->viewinv[2]);
- }
- normalize_v3(vec);
-}
-
-int initgrabz(RegionView3D *rv3d, float x, float y, float z)
-{
- int flip = FALSE;
- if (rv3d == NULL) return flip;
- rv3d->zfac = rv3d->persmat[0][3] * x + rv3d->persmat[1][3] * y + rv3d->persmat[2][3] * z + rv3d->persmat[3][3];
- if (rv3d->zfac < 0.0f)
- flip = TRUE;
- /* if x,y,z is exactly the viewport offset, zfac is 0 and we don't want that
- * (accounting for near zero values)
- */
- if (rv3d->zfac < 1.e-6f && rv3d->zfac > -1.e-6f) rv3d->zfac = 1.0f;
-
- /* Negative zfac means x, y, z was behind the camera (in perspective).
- * This gives flipped directions, so revert back to ok default case.
- */
- /* NOTE: I've changed this to flip zfac to be positive again for now so that GPencil draws ok
- * Aligorith, 2009Aug31 */
- //if (rv3d->zfac < 0.0f) rv3d->zfac = 1.0f;
- if (rv3d->zfac < 0.0f) rv3d->zfac = -rv3d->zfac;
-
- return flip;
-}
-
-/**
- * Calculate a 3d location from 2d window coordinates.
- * \param ar The region (used for the window width and height).
- * \param depth_pt The reference location used to calculate the Z depth.
- * \param mval The area relative location (such as event->mval converted to floats).
- * \param out The resulting world-space location.
- */
-void ED_view3d_win_to_3d(ARegion *ar, const float depth_pt[3], const float mval[2], float out[3])
-{
- RegionView3D *rv3d = ar->regiondata;
-
- float line_sta[3];
- float line_end[3];
-
- if (rv3d->is_persp) {
- float mousevec[3];
- copy_v3_v3(line_sta, rv3d->viewinv[3]);
- ED_view3d_win_to_vector(ar, mval, mousevec);
- add_v3_v3v3(line_end, line_sta, mousevec);
-
- if (isect_line_plane_v3(out, line_sta, line_end, depth_pt, rv3d->viewinv[2], TRUE) == 0) {
- /* highly unlikely to ever happen, mouse vec paralelle with view plane */
- zero_v3(out);
- }
- }
- else {
- const float dx = (2.0f * mval[0] / (float)ar->winx) - 1.0f;
- const float dy = (2.0f * mval[1] / (float)ar->winy) - 1.0f;
- line_sta[0] = (rv3d->persinv[0][0] * dx) + (rv3d->persinv[1][0] * dy) + rv3d->viewinv[3][0];
- line_sta[1] = (rv3d->persinv[0][1] * dx) + (rv3d->persinv[1][1] * dy) + rv3d->viewinv[3][1];
- line_sta[2] = (rv3d->persinv[0][2] * dx) + (rv3d->persinv[1][2] * dy) + rv3d->viewinv[3][2];
-
- add_v3_v3v3(line_end, line_sta, rv3d->viewinv[2]);
- closest_to_line_v3(out, depth_pt, line_sta, line_end);
- }
-}
-
-/**
- * Calculate a 3d difference vector from 2d window offset.
- * note that initgrabz() must be called first to determine
- * the depth used to calculate the delta.
- * \param ar The region (used for the window width and height).
- * \param mval The area relative 2d difference (such as event->mval[0] - other_x).
- * \param out The resulting world-space delta.
- */
-void ED_view3d_win_to_delta(ARegion *ar, const float mval[2], float out[3])
-{
- RegionView3D *rv3d = ar->regiondata;
- float dx, dy;
-
- dx = 2.0f * mval[0] * rv3d->zfac / ar->winx;
- dy = 2.0f * mval[1] * rv3d->zfac / ar->winy;
-
- out[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy);
- out[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy);
- out[2] = (rv3d->persinv[0][2] * dx + rv3d->persinv[1][2] * dy);
-}
-
-/**
- * Calculate a 3d direction vector from 2d window coordinates.
- * This direction vector starts and the view in the direction of the 2d window coordinates.
- * In orthographic view all window coordinates yield the same vector.
- *
- * \note doesn't rely on initgrabz
- * for perspective view, get the vector direction to
- * the mouse cursor as a normalized vector.
- *
- * \param ar The region (used for the window width and height).
- * \param mval The area relative 2d location (such as event->mval converted to floats).
- * \param out The resulting normalized world-space direction vector.
- */
-void ED_view3d_win_to_vector(ARegion *ar, const float mval[2], float out[3])
-{
- RegionView3D *rv3d = ar->regiondata;
-
- if (rv3d->is_persp) {
- out[0] = 2.0f * (mval[0] / ar->winx) - 1.0f;
- out[1] = 2.0f * (mval[1] / ar->winy) - 1.0f;
- out[2] = -0.5f;
- mul_project_m4_v3(rv3d->persinv, out);
- sub_v3_v3(out, rv3d->viewinv[3]);
- }
- else {
- copy_v3_v3(out, rv3d->viewinv[2]);
- }
- normalize_v3(out);
-}
-
-float ED_view3d_depth_read_cached(ViewContext *vc, int x, int y)
-{
- ViewDepths *vd = vc->rv3d->depths;
-
- x -= vc->ar->winrct.xmin;
- y -= vc->ar->winrct.ymin;
-
- if (vd && vd->depths && x > 0 && y > 0 && x < vd->w && y < vd->h)
- return vd->depths[y * vd->w + x];
- else
- return 1;
-}
-
-void ED_view3d_depth_tag_update(RegionView3D *rv3d)
-{
- if (rv3d->depths)
- rv3d->depths->damaged = 1;
-}
-
-void ED_view3d_ob_project_mat_get(RegionView3D *rv3d, Object *ob, float pmat[4][4])
-{
- float vmat[4][4];
-
- mult_m4_m4m4(vmat, rv3d->viewmat, ob->obmat);
- mult_m4_m4m4(pmat, rv3d->winmat, vmat);
-}
-
-/* Uses window coordinates (x,y) and depth component z to find a point in
- * modelspace */
-void ED_view3d_unproject(bglMats *mats, float out[3], const float x, const float y, const float z)
-{
- double ux, uy, uz;
-
- gluUnProject(x, y, z, mats->modelview, mats->projection,
- (GLint *)mats->viewport, &ux, &uy, &uz);
-
- out[0] = ux;
- out[1] = uy;
- out[2] = uz;
-}
-
-/* use #ED_view3d_ob_project_mat_get to get projecting mat */
-void ED_view3d_project_float_v2_m4(const ARegion *ar, const float co[3], float r_co[2], float mat[4][4])
-{
- float vec4[4];
-
- copy_v3_v3(vec4, co);
- vec4[3] = 1.0;
- /* r_co[0] = IS_CLIPPED; */ /* always overwritten */
-
- mul_m4_v4(mat, vec4);
-
- if (vec4[3] > FLT_EPSILON) {
- r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3];
- r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3];
- }
- else {
- zero_v2(r_co);
- }
-}
-
-/* use #ED_view3d_ob_project_mat_get to get projecting mat */
-void ED_view3d_project_float_v3_m4(ARegion *ar, const float vec[3], float r_co[3], float mat[4][4])
-{
- float vec4[4];
-
- copy_v3_v3(vec4, vec);
- vec4[3] = 1.0;
- /* r_co[0] = IS_CLIPPED; */ /* always overwritten */
-
- mul_m4_v4(mat, vec4);
-
- if (vec4[3] > FLT_EPSILON) {
- r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3];
- r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3];
- r_co[2] = vec4[2] / vec4[3];
- }
- else {
- zero_v3(r_co);
- }
-}
-
-eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base)
-{
- eV3DProjStatus ret = ED_view3d_project_short_global(ar, base->object->obmat[3], &base->sx,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN);
-
- if (ret != V3D_PROJ_RET_SUCCESS) {
- base->sx = IS_CLIPPED;
- base->sy = 0;
- }
-
- return ret;
-}
int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[][4], BoundBox *bb)
{
/* return 1: draw */
-
+
float mat[4][4];
float vec[4], min, max;
int a, flag = -1, fl;
-
+
if (bb == NULL) return 1;
if (bb->flag & OB_BB_DISABLED) return 1;
-
+
mult_m4_m4m4(mat, rv3d->persmat, obmat);
-
+
for (a = 0; a < 8; a++) {
copy_v3_v3(vec, bb->vec[a]);
vec[3] = 1.0;
mul_m4_v4(mat, vec);
max = vec[3];
min = -vec[3];
-
+
fl = 0;
if (vec[0] < min) fl += 1;
if (vec[0] > max) fl += 2;
@@ -898,153 +599,31 @@ int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[][4], BoundBox *bb)
if (vec[1] > max) fl += 8;
if (vec[2] < min) fl += 16;
if (vec[2] > max) fl += 32;
-
+
flag &= fl;
if (flag == 0) return 1;
}
-
- return 0;
-}
-
-/* perspmat is typically...
- * - 'rv3d->perspmat', is_local == FALSE
- * - 'rv3d->perspmatob', is_local == TRUE
- */
-static eV3DProjStatus ed_view3d_project__internal(ARegion *ar,
- float perspmat[4][4], const int is_local, /* normally hidden */
- const float co[3], float r_co[2], eV3DProjTest flag)
-{
- float fx, fy, vec4[4];
- if (flag & V3D_PROJ_TEST_CLIP_BB) {
- RegionView3D *rv3d = ar->regiondata;
- if (rv3d->rflag & RV3D_CLIPPING) {
- if (ED_view3d_clipping_test(rv3d, co, is_local)) {
- return V3D_PROJ_RET_CLIP_BB;
- }
- }
- }
-
- copy_v3_v3(vec4, co);
- vec4[3] = 1.0;
- mul_m4_v4(perspmat, vec4);
-
- if (vec4[3] > (float)BL_NEAR_CLIP) {
- fx = ((float)ar->winx / 2.0f) * (1.0f + vec4[0] / vec4[3]);
- if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fx > 0 && fx < ar->winx)) {
- fy = ((float)ar->winy / 2.0f) * (1.0f + vec4[1] / vec4[3]);
- if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fy > 0.0f && fy < (float)ar->winy)) {
- r_co[0] = (short)floor(fx);
- r_co[1] = (short)floor(fy);
- }
- else {
- return V3D_PROJ_RET_CLIP_WIN;
- }
- }
- else {
- return V3D_PROJ_RET_CLIP_WIN;
- }
- }
- else {
- return V3D_PROJ_RET_CLIP_NEAR;
- }
-
- return V3D_PROJ_RET_SUCCESS;
-}
-
-eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], const int is_local,
- const float co[3], short r_co[2], eV3DProjTest flag)
-{
- float tvec[2];
- eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag);
- if (ret == V3D_PROJ_RET_SUCCESS) {
- if ((tvec[0] > -32700.0 && tvec[0] < 32700.0f) &&
- (tvec[1] > -32700.0 && tvec[1] < 32700.0f))
- {
- r_co[0] = (short)floor(tvec[0]);
- r_co[1] = (short)floor(tvec[1]);
- }
- else {
- ret = V3D_PROJ_RET_OVERFLOW;
- }
- }
- return ret;
-}
-
-eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const int is_local,
- const float co[3], int r_co[2], eV3DProjTest flag)
-{
- float tvec[2];
- eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag);
- if (ret == V3D_PROJ_RET_SUCCESS) {
- if ((tvec[0] > -2140000000.0 && tvec[0] < 2140000000.0f) &&
- (tvec[1] > -2140000000.0 && tvec[1] < 2140000000.0f))
- {
- r_co[0] = (int)floor(tvec[0]);
- r_co[1] = (int)floor(tvec[1]);
- }
- else {
- ret = V3D_PROJ_RET_OVERFLOW;
- }
- }
- return ret;
-}
-
-eV3DProjStatus ED_view3d_project_float_ex(ARegion *ar, float perspmat[4][4], const int is_local,
- const float co[3], float r_co[2], eV3DProjTest flag)
-{
- float tvec[2];
- eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag);
- if (ret == V3D_PROJ_RET_SUCCESS) {
- if (finite(tvec[0]) &&
- finite(tvec[1]))
- {
- copy_v2_v2(r_co, tvec);
- }
- else {
- ret = V3D_PROJ_RET_OVERFLOW;
- }
- }
- return ret;
+ return 0;
}
-/* --- short --- */
-eV3DProjStatus ED_view3d_project_short_global(ARegion *ar, const float co[3], short r_co[2], eV3DProjTest flag)
-{
- RegionView3D *rv3d = ar->regiondata;
- return ED_view3d_project_short_ex(ar, rv3d->persmat, FALSE, co, r_co, flag);
-}
-/* object space, use ED_view3d_init_mats_rv3d before calling */
-eV3DProjStatus ED_view3d_project_short_object(ARegion *ar, const float co[3], short r_co[2], eV3DProjTest flag)
+float ED_view3d_depth_read_cached(ViewContext *vc, int x, int y)
{
- RegionView3D *rv3d = ar->regiondata;
- return ED_view3d_project_short_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag);
-}
+ ViewDepths *vd = vc->rv3d->depths;
+
+ x -= vc->ar->winrct.xmin;
+ y -= vc->ar->winrct.ymin;
-/* --- int --- */
-eV3DProjStatus ED_view3d_project_int_global(ARegion *ar, const float co[3], int r_co[2], eV3DProjTest flag)
-{
- RegionView3D *rv3d = ar->regiondata;
- return ED_view3d_project_int_ex(ar, rv3d->persmat, FALSE, co, r_co, flag);
-}
-/* object space, use ED_view3d_init_mats_rv3d before calling */
-eV3DProjStatus ED_view3d_project_int_object(ARegion *ar, const float co[3], int r_co[2], eV3DProjTest flag)
-{
- RegionView3D *rv3d = ar->regiondata;
- return ED_view3d_project_int_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag);
+ if (vd && vd->depths && x > 0 && y > 0 && x < vd->w && y < vd->h)
+ return vd->depths[y * vd->w + x];
+ else
+ return 1;
}
-/* --- float --- */
-eV3DProjStatus ED_view3d_project_float_global(ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag)
-{
- RegionView3D *rv3d = ar->regiondata;
- return ED_view3d_project_float_ex(ar, rv3d->persmat, FALSE, co, r_co, flag);
-}
-/* object space, use ED_view3d_init_mats_rv3d before calling */
-eV3DProjStatus ED_view3d_project_float_object(ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag)
+void ED_view3d_depth_tag_update(RegionView3D *rv3d)
{
- RegionView3D *rv3d = ar->regiondata;
- return ED_view3d_project_float_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag);
+ if (rv3d->depths)
+ rv3d->depths->damaged = 1;
}
/* copies logic of get_view3d_viewplane(), keep in sync */
@@ -1458,7 +1037,7 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL
locallay = free_localbit(bmain);
if (locallay == 0) {
- BKE_reportf(reports, RPT_ERROR, "No more than 8 localviews");
+ BKE_reportf(reports, RPT_ERROR, "No more than 8 local views");
ok = FALSE;
}
else {
@@ -1647,7 +1226,6 @@ static int localview_exec(bContext *C, wmOperator *op)
void VIEW3D_OT_localview(wmOperatorType *ot)
{
-
/* identifiers */
ot->name = "Local View";
ot->description = "Toggle display of selected object(s) separately and centered in view";
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index d2354a4a7ad..4a61978cc80 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -90,15 +90,12 @@
#include "BLI_linklist.h"
#include "BLI_smallhash.h"
#include "BLI_array.h"
-#include "PIL_time.h"
#include "UI_interface_icons.h"
#include "UI_resources.h"
#include "transform.h"
-#include <stdio.h> // XXX: duplicated???
-
static void drawTransformApply(const struct bContext *C, ARegion *ar, void *arg);
static int doEdgeSlide(TransInfo *t, float perc);
@@ -230,7 +227,7 @@ void projectIntView(TransInfo *t, const float vec[3], int adr[2])
{
if (t->spacetype == SPACE_VIEW3D) {
if (t->ar->regiontype == RGN_TYPE_WINDOW) {
- if (ED_view3d_project_int_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_int_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) {
adr[0] = (int)2140000000.0f; /* this is what was done in 2.64, perhaps we can be smarter? */
adr[1] = (int)2140000000.0f;
}
@@ -355,7 +352,7 @@ void projectFloatView(TransInfo *t, const float vec[3], float adr[2])
case SPACE_VIEW3D:
{
if (t->ar->regiontype == RGN_TYPE_WINDOW) {
- if (ED_view3d_project_float_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_float_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) {
/* XXX, 2.64 and prior did this, weak! */
adr[0] = t->ar->winx / 2.0f;
adr[1] = t->ar->winy / 2.0f;
@@ -1273,7 +1270,6 @@ int transformEvent(TransInfo *t, wmEvent *event)
t->redraw |= t->handleEvent(t, event);
if (handled || t->redraw) {
- t->last_update = PIL_check_seconds_timer();
return 0;
}
else {
@@ -1562,49 +1558,31 @@ static void drawTransformView(const struct bContext *C, ARegion *UNUSED(ar), voi
}
/* just draw a little warning message in the top-right corner of the viewport to warn that autokeying is enabled */
-static void drawAutoKeyWarning(TransInfo *t, ARegion *ar)
+static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *ar)
{
- int show_warning;
-
- /* red border around the viewport */
- UI_ThemeColor(TH_REDALERT);
+ const char printable[] = "Auto Keying On";
+ float printable_size[2];
+ int xco, yco;
+
+ BLF_width_and_height_default(printable, &printable_size[0], &printable_size[1]);
- glBegin(GL_LINE_LOOP);
- glVertex2f(1, 1);
- glVertex2f(1, ar->winy-1);
- glVertex2f(ar->winx-1, ar->winy-1);
- glVertex2f(ar->winx-1, 1);
- glEnd();
+ xco = ar->winx - (int)printable_size[0] - 10;
+ yco = ar->winy - (int)printable_size[1] - 10;
- /* Entire warning should "blink" to catch periphery attention without being overly distracting
- * much like how a traditional recording sign in the corner of a camcorder works
- *
- * - Blink frequency here is 0.5 secs (i.e. a compromise between epilepsy-inducing flicker + too slow to notice).
- * We multiply by two to speed up the odd/even time-in-seconds = on/off toggle.
- * - Always start with warning shown so that animators are more likely to notice when starting to transform
+ /* warning text (to clarify meaning of overlays)
+ * - original color was red to match the icon, but that clashes badly with a less nasty border
*/
- show_warning = (int)(t->last_update * 2.0) & 1;
+ UI_ThemeColorShade(TH_TEXT_HI, -50);
+ BLF_draw_default_ascii(xco, ar->winy - 17, 0.0f, printable, sizeof(printable));
- if ((show_warning) || (t->state == TRANS_STARTING)) {
- const char printable[] = "Auto Keying On";
- int xco, yco;
-
- xco = ar->winx - BLF_width_default(printable) - 10;
- yco = ar->winy - BLF_height_default(printable) - 10;
-
- /* red warning text */
- UI_ThemeColor(TH_REDALERT);
- BLF_draw_default_ascii(xco, ar->winy - 17, 0.0f, printable, sizeof(printable));
-
- /* autokey recording icon... */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- xco -= (ICON_DEFAULT_WIDTH + 2);
- UI_icon_draw(xco, yco, ICON_REC);
-
- glDisable(GL_BLEND);
- }
+ /* autokey recording icon... */
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ xco -= (ICON_DEFAULT_WIDTH + 2);
+ UI_icon_draw(xco, yco, ICON_REC);
+
+ glDisable(GL_BLEND);
}
static void drawTransformPixel(const struct bContext *UNUSED(C), ARegion *ar, void *arg)
@@ -1613,10 +1591,18 @@ static void drawTransformPixel(const struct bContext *UNUSED(C), ARegion *ar, vo
Scene *scene = t->scene;
Object *ob = OBACT;
- /* draw autokeyframing hint in the corner */
- if (ob && autokeyframe_cfra_can_key(scene, &ob->id)) {
- drawAutoKeyWarning(t, ar);
- }
+ /* draw autokeyframing hint in the corner
+ * - only draw if enabled (advanced users may be distracted/annoyed),
+ * for objects that will be autokeyframed (no point ohterwise),
+ * AND only for the active region (as showing all is too overwhelming)
+ */
+ if ((U.autokey_flag & AUTOKEY_FLAG_NOWARNING) == 0) {
+ if (ar == t->ar) {
+ if (ob && autokeyframe_cfra_can_key(scene, &ob->id)) {
+ drawAutoKeyWarning(t, ar);
+ }
+ }
+ }
}
void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
@@ -4037,12 +4023,15 @@ int Tilt(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, "Tilt: %s %s", &c[0], t->proptext);
+ sprintf(str, "Tilt: %s° %s", &c[0], t->proptext);
final = DEG2RADF(final);
+
+ /* XXX For some reason, this seems needed for this op, else RNA prop is not updated... :/ */
+ t->values[0] = final;
}
else {
- sprintf(str, "Tilt: %.2f %s", RAD2DEGF(final), t->proptext);
+ sprintf(str, "Tilt: %.2f° %s", RAD2DEGF(final), t->proptext);
}
for (i = 0; i < t->total; i++, td++) {
@@ -4853,7 +4842,7 @@ static void calcNonProportionalEdgeSlide(TransInfo *t, SlideData *sld, const flo
sv->edge_len = len_v3v3(dw_p, up_p);
mul_v3_m4v3(v_proj, t->obedit->obmat, sv->v->co);
- if (ED_view3d_project_float_global(t->ar, v_proj, v_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_float_global(t->ar, v_proj, v_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
dist = len_squared_v2v2(mval, v_proj);
if (dist < min_dist) {
min_dist = dist;
@@ -4871,10 +4860,9 @@ static int createSlideVerts(TransInfo *t)
{
BMEditMesh *em = BMEdit_FromObject(t->obedit);
BMesh *bm = em->bm;
- BMIter iter, iter2;
+ BMIter iter;
BMEdge *e, *e1;
BMVert *v, *v2, *first;
- BMLoop *l, *l1, *l2;
TransDataSlideVert *sv_array;
BMBVHTree *btree = BMBVH_NewBVH(em, BMBVH_RESPECT_HIDDEN, NULL, NULL);
SmallHash table;
@@ -4914,6 +4902,7 @@ static int createSlideVerts(TransInfo *t)
/*ensure valid selection*/
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+ BMIter iter2;
numsel = 0;
BM_ITER_ELEM (e, &iter2, v, BM_EDGES_OF_VERT) {
if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
@@ -4966,6 +4955,8 @@ static int createSlideVerts(TransInfo *t)
j = 0;
while (1) {
+ BMLoop *l, *l1, *l2;
+
v = NULL;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_TAG))
@@ -5099,7 +5090,7 @@ static int createSlideVerts(TransInfo *t)
if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
BMIter iter2;
BMEdge *e2;
- float vec1[3], mval[2] = {t->mval[0], t->mval[1]}, d;
+ float vec1[3], d;
/* search cross edges for visible edge to the mouse cursor,
* then use the shared vertex to calculate screen vector*/
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 40f53423d37..1f9775821d1 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -323,8 +323,6 @@ typedef struct TransInfo {
float axis[3];
float axis_orig[3]; /* TransCon can change 'axis', store the original value here */
- double last_update; /* Time of last update (in seconds) */
-
void *view;
struct bContext *context; /* Only valid (non null) during an operator called function. */
struct ScrArea *sa;
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 39a5da94798..2e9d1ee670f 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -3986,13 +3986,13 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count
*flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL);
if (t->frame_side == 'R') {
- if (right <= cfra) *count = *flag = 0; /* ignore */
- else if (left > cfra) ; /* keep the selection */
+ if (right <= cfra) { *count = *flag = 0; } /* ignore */
+ else if (left > cfra) { } /* keep the selection */
else *flag |= SEQ_RIGHTSEL;
}
else {
- if (left >= cfra) *count = *flag = 0; /* ignore */
- else if (right < cfra) ; /* keep the selection */
+ if (left >= cfra) { *count = *flag = 0; } /* ignore */
+ else if (right < cfra) { } /* keep the selection */
else *flag |= SEQ_LEFTSEL;
}
}
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 81a4c082dcc..fc0c174a525 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -605,8 +605,10 @@ static void TRANSFORM_OT_trackball(struct wmOperatorType *ot)
static void TRANSFORM_OT_rotate(struct wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
- ot->name = "Rotate";
+ ot->name = "Rotate";
ot->description = "Rotate selected items";
ot->idname = OP_ROTATION;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
@@ -618,19 +620,22 @@ static void TRANSFORM_OT_rotate(struct wmOperatorType *ot)
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
- RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2);
+ prop = RNA_def_float(ot->srna, "value", 0.0f, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2);
+ RNA_def_property_subtype(prop, PROP_ANGLE);
Transform_Properties(ot, P_AXIS | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP);
}
static void TRANSFORM_OT_tilt(struct wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
- ot->name = "Tilt";
+ ot->name = "Tilt";
/* optionals -
* "Tilt selected vertices"
- * "Specify an extra axis rotation for selected vertices of 3d curve" */
- ot->description = "Tilt selected control vertices of 3d curve";
+ * "Specify an extra axis rotation for selected vertices of 3D curve" */
+ ot->description = "Tilt selected control vertices of 3D curve";
ot->idname = OP_TILT;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
@@ -641,9 +646,10 @@ static void TRANSFORM_OT_tilt(struct wmOperatorType *ot)
ot->cancel = transform_cancel;
ot->poll = ED_operator_editcurve_3d;
- RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2);
+ prop = RNA_def_float(ot->srna, "value", 0.0, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2);
+ RNA_def_property_subtype(prop, PROP_ANGLE);
- Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_SNAP);
+ Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP);
}
static void TRANSFORM_OT_warp(struct wmOperatorType *ot)
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 0e25739c34a..845d5b73f0c 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -631,7 +631,6 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
/* if there's an edge available, use that for the tangent */
if (em->bm->totedgesel >= 1) {
BMEdge *eed = NULL;
- BMIter iter;
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
@@ -746,14 +745,14 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3],
MetaBall *mb = obedit->data;
if (mb->lastelem) {
- float mat[4][4];
+ float qmat[3][3];
/* Rotation of MetaElem is stored in quat */
- quat_to_mat4(mat, mb->lastelem->quat);
+ quat_to_mat3(qmat, mb->lastelem->quat);
- copy_v3_v3(normal, mat[2]);
+ copy_v3_v3(normal, qmat[2]);
- negate_v3_v3(plane, mat[1]);
+ negate_v3_v3(plane, qmat[1]);
result = ORIENTATION_FACE;
}
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 2f2b31de89d..94b8abb8850 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -317,7 +317,7 @@ void applyProject(TransInfo *t)
copy_v3_v3(iloc, td->ob->obmat[3]);
}
- if (ED_view3d_project_float_global(t->ar, iloc, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_float_global(t->ar, iloc, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
if (snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.modeSelect)) {
// if (t->flag & (T_EDIT|T_POSE)) {
// mul_m4_v3(imat, loc);
@@ -603,7 +603,7 @@ int updateSelectedSnapPoint(TransInfo *t)
int dx, dy;
int dist;
- if (ED_view3d_project_int_global(t->ar, p->co, screen_loc, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_int_global(t->ar, p->co, screen_loc, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) {
continue;
}
@@ -1236,7 +1236,7 @@ static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], sh
new_depth = len_v3v3(location, ray_start);
- if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]);
}
else {
@@ -1297,7 +1297,7 @@ static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[][4],
new_depth = len_v3v3(location, ray_start);
- if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) {
+ if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]);
}
else {
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index d6794912043..7aaae404d15 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -453,8 +453,6 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
int drawfaces, interpedges;
Image *ima = sima->image;
- StitchPreviewer *stitch_preview = uv_get_stitch_previewer();
-
activetf = EDBM_mtexpoly_active_get(em, &efa_act, FALSE, FALSE); /* will be set to NULL if hidden */
activef = BM_active_face_get(bm, FALSE, FALSE);
ts = scene->toolsettings;
@@ -823,51 +821,6 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
bglEnd();
}
- /* finally draw stitch preview */
- if (stitch_preview) {
- int i, index = 0;
- glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
- glEnableClientState(GL_VERTEX_ARRAY);
-
- glEnable(GL_BLEND);
-
- UI_ThemeColor4(TH_STITCH_PREVIEW_ACTIVE);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glVertexPointer(2, GL_FLOAT, 0, stitch_preview->static_tris);
- glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_static_tris * 3);
-
- glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_polys);
- for (i = 0; i < stitch_preview->num_polys; i++) {
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- UI_ThemeColor4(TH_STITCH_PREVIEW_FACE);
- glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- UI_ThemeColor4(TH_STITCH_PREVIEW_EDGE);
- glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]);
-
- index += stitch_preview->uvs_per_polygon[i];
- }
- glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
-#if 0
- UI_ThemeColor4(TH_STITCH_PREVIEW_VERT);
- glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_tris * 3);
-#endif
- glDisable(GL_BLEND);
-
- /* draw vert preview */
- glPointSize(pointsize * 2.0f);
- UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE);
- glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable);
- glDrawArrays(GL_POINTS, 0, stitch_preview->num_stitchable);
-
- UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE);
- glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable);
- glDrawArrays(GL_POINTS, 0, stitch_preview->num_unstitchable);
-
- glPopClientAttrib();
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- }
-
glPointSize(1.0);
}
diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h
index f0ff79ae25e..3a89d6ce892 100644
--- a/source/blender/editors/uvedit/uvedit_intern.h
+++ b/source/blender/editors/uvedit/uvedit_intern.h
@@ -75,30 +75,6 @@ void uv_find_nearest_edge(struct Scene *scene, struct Image *ima, struct BMEditM
struct UvElement *ED_uv_element_get(struct UvElementMap *map, struct BMFace *efa, struct BMLoop *l);
void uvedit_live_unwrap_update(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit);
-/* smart stitch */
-
-/* object that stores display data for previewing before accepting stitching */
-typedef struct StitchPreviewer {
- /* here we'll store the preview triangle indices of the mesh */
- float *preview_polys;
- /* uvs per polygon. */
- unsigned int *uvs_per_polygon;
- /*number of preview polygons */
- unsigned int num_polys;
- /* preview data. These will be either the previewed vertices or edges depending on stitch mode settings */
- float *preview_stitchable;
- float *preview_unstitchable;
- /* here we'll store the number of elements to be drawn */
- unsigned int num_stitchable;
- unsigned int num_unstitchable;
- unsigned int preview_uvs;
- /* ...and here we'll store the triangles*/
- float *static_tris;
- unsigned int num_static_tris;
-} StitchPreviewer;
-
-StitchPreviewer *uv_get_stitch_previewer(void);
-
/* operators */
void UV_OT_average_islands_scale(struct wmOperatorType *ot);
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 6e655faf35f..acc69309a8c 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -170,7 +170,6 @@ void ED_object_assign_active_image(Main *bmain, Object *ob, int mat_nr, Image *i
void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *ima, Image *previma)
{
BMEditMesh *em;
- BMFace *efa;
BMIter iter;
MTexPoly *tf;
int update = 0;
@@ -198,6 +197,8 @@ void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *im
ED_object_assign_active_image(bmain, obedit, efa->mat_nr + 1, ima);
}
else {
+ BMFace *efa;
+
/* old shading system, assign image to selected faces */
#ifdef USE_SWITCH_ASPECT
float prev_aspect[2], fprev_aspect;
@@ -771,13 +772,15 @@ static int nearest_uv_between(BMEditMesh *em, BMFace *efa, int UNUSED(nverts), i
BM_ITER_ELEM (l, &iter, efa, BM_LOOPS_OF_FACE) {
luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
- if (i == id1)
+ if (i == id1) {
uv1 = luv->uv;
- else if (i == id)
- ; /* uv2 = luv->uv; */ /* UNUSED */
- else if (i == id2)
+ }
+ else if (i == id) {
+ /* uv2 = luv->uv; */ /* UNUSED */
+ }
+ else if (i == id2) {
uv3 = luv->uv;
-
+ }
i++;
}
@@ -1310,9 +1313,7 @@ static void weld_align_uv(bContext *C, int tool)
Object *obedit;
Image *ima;
BMEditMesh *em;
- BMIter iter, liter;
MTexPoly *tf;
- MLoopUV *luv;
float cent[2], min[2], max[2];
scene = CTX_data_scene(C);
@@ -1324,6 +1325,7 @@ static void weld_align_uv(bContext *C, int tool)
INIT_MINMAX2(min, max);
if (tool == 'a') {
+ BMIter iter, liter;
BMFace *efa;
BMLoop *l;
@@ -1335,7 +1337,7 @@ static void weld_align_uv(bContext *C, int tool)
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_uv_select_test(em, scene, l)) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
DO_MINMAX2(luv->uv, min, max);
}
}
@@ -1347,6 +1349,7 @@ static void weld_align_uv(bContext *C, int tool)
uvedit_center(scene, ima, obedit, cent, 0);
if (tool == 'x' || tool == 'w') {
+ BMIter iter, liter;
BMFace *efa;
BMLoop *l;
@@ -1357,7 +1360,7 @@ static void weld_align_uv(bContext *C, int tool)
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_uv_select_test(em, scene, l)) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
luv->uv[0] = cent[0];
}
@@ -1366,6 +1369,7 @@ static void weld_align_uv(bContext *C, int tool)
}
if (tool == 'y' || tool == 'w') {
+ BMIter iter, liter;
BMFace *efa;
BMLoop *l;
@@ -1376,7 +1380,7 @@ static void weld_align_uv(bContext *C, int tool)
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_uv_select_test(em, scene, l)) {
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
luv->uv[1] = cent[1];
}
@@ -2131,7 +2135,7 @@ static int select_linked_internal(bContext *C, wmOperator *op, wmEvent *event, i
NearestHit hit, *hit_p = NULL;
if (ts->uv_flag & UV_SYNC_SELECTION) {
- BKE_report(op->reports, RPT_ERROR, "Can't select linked when sync selection is enabled");
+ BKE_report(op->reports, RPT_ERROR, "Cannot select linked when sync selection is enabled");
return OPERATOR_CANCELLED;
}
@@ -2238,7 +2242,7 @@ static int select_split_exec(bContext *C, wmOperator *op)
short change = FALSE;
if (ts->uv_flag & UV_SYNC_SELECTION) {
- BKE_report(op->reports, RPT_ERROR, "Can't split selection when sync selection is enabled");
+ BKE_report(op->reports, RPT_ERROR, "Cannot split selection when sync selection is enabled");
return OPERATOR_CANCELLED;
}
@@ -2279,6 +2283,7 @@ static int select_split_exec(bContext *C, wmOperator *op)
}
if (change) {
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_IMAGE, NULL);
return OPERATOR_FINISHED;
}
else {
@@ -2316,7 +2321,7 @@ static int unlink_selection_exec(bContext *C, wmOperator *op)
MLoopUV *luv;
if (ts->uv_flag & UV_SYNC_SELECTION) {
- BKE_report(op->reports, RPT_ERROR, "Can't unlink selection when sync selection is enabled");
+ BKE_report(op->reports, RPT_ERROR, "Cannot unlink selection when sync selection is enabled");
return OPERATOR_CANCELLED;
}
@@ -2487,13 +2492,16 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s
break;
if (efa_index != vlist_iter->f) {
+ BMLoop *l_other;
efa_vlist = EDBM_face_at_index(em, vlist_iter->f);
/* tf_vlist = CustomData_bmesh_get(&em->bm->pdata, efa_vlist->head.data, CD_MTEXPOLY); */ /* UNUSED */
+ l_other = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex);
+
if (select)
- uvedit_uv_select_enable(em, scene, BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex), FALSE);
+ uvedit_uv_select_enable(em, scene, l_other, FALSE);
else
- uvedit_uv_select_disable(em, scene, BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex));
+ uvedit_uv_select_disable(em, scene, l_other);
}
vlist_iter = vlist_iter->next;
}
@@ -2827,7 +2835,7 @@ static int uv_lasso_select_exec(bContext *C, wmOperator *op)
select = !RNA_boolean_get(op->ptr, "deselect");
change = do_lasso_select_mesh_uv(C, mcords, mcords_tot, select);
- MEM_freeN(mcords);
+ MEM_freeN((void *)mcords);
return change ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 4e0e7944e84..2b225118472 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -46,6 +46,8 @@
#include "BLI_math_vector.h"
#include "BLI_string.h"
+#include "BIF_gl.h"
+
#include "BKE_context.h"
#include "BKE_customdata.h"
#include "BKE_depsgraph.h"
@@ -55,6 +57,7 @@
#include "ED_mesh.h"
#include "ED_uvedit.h"
#include "ED_screen.h"
+#include "ED_space_api.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -63,11 +66,32 @@
#include "WM_types.h"
#include "UI_view2d.h"
+#include "UI_resources.h"
#include "uvedit_intern.h"
/* ********************** smart stitch operator *********************** */
+/* object that stores display data for previewing before accepting stitching */
+typedef struct StitchPreviewer {
+ /* here we'll store the preview triangle indices of the mesh */
+ float *preview_polys;
+ /* uvs per polygon. */
+ unsigned int *uvs_per_polygon;
+ /*number of preview polygons */
+ unsigned int num_polys;
+ /* preview data. These will be either the previewed vertices or edges depending on stitch mode settings */
+ float *preview_stitchable;
+ float *preview_unstitchable;
+ /* here we'll store the number of elements to be drawn */
+ unsigned int num_stitchable;
+ unsigned int num_unstitchable;
+ unsigned int preview_uvs;
+ /* ...and here we'll store the triangles*/
+ float *static_tris;
+ unsigned int num_static_tris;
+} StitchPreviewer;
+
struct IslandStitchData;
@@ -143,6 +167,8 @@ typedef struct StitchState {
int static_island;
/* store number of primitives per face so that we can allocate the active island buffer later */
unsigned int *tris_per_island;
+
+ void *draw_handle;
} StitchState;
typedef struct PreviewPosition {
@@ -216,7 +242,7 @@ static void stitch_preview_delete(void)
/* "getter method" */
-StitchPreviewer *uv_get_stitch_previewer(void)
+static StitchPreviewer *uv_get_stitch_previewer(void)
{
return _stitch_preview;
}
@@ -981,6 +1007,55 @@ static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *no
normalize_v2(normal);
}
+static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *UNUSED(arg))
+{
+ int i, index = 0;
+ float pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE);
+ StitchPreviewer *stitch_preview = uv_get_stitch_previewer();
+
+ glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
+ glEnableClientState(GL_VERTEX_ARRAY);
+
+ glEnable(GL_BLEND);
+
+ UI_ThemeColor4(TH_STITCH_PREVIEW_ACTIVE);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glVertexPointer(2, GL_FLOAT, 0, stitch_preview->static_tris);
+ glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_static_tris * 3);
+
+ glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_polys);
+ for (i = 0; i < stitch_preview->num_polys; i++) {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ UI_ThemeColor4(TH_STITCH_PREVIEW_FACE);
+ glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ UI_ThemeColor4(TH_STITCH_PREVIEW_EDGE);
+ glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]);
+
+ index += stitch_preview->uvs_per_polygon[i];
+ }
+ glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
+#if 0
+ UI_ThemeColor4(TH_STITCH_PREVIEW_VERT);
+ glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_tris * 3);
+#endif
+ glDisable(GL_BLEND);
+
+ /* draw vert preview */
+ glPointSize(pointsize * 2.0f);
+ UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE);
+ glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable);
+ glDrawArrays(GL_POINTS, 0, stitch_preview->num_stitchable);
+
+ UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE);
+ glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable);
+ glDrawArrays(GL_POINTS, 0, stitch_preview->num_unstitchable);
+
+ glPopClientAttrib();
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+
+}
+
static int stitch_init(bContext *C, wmOperator *op)
{
/* for fast edge lookup... */
@@ -1016,6 +1091,7 @@ static int stitch_init(bContext *C, wmOperator *op)
state->static_island = RNA_int_get(op->ptr, "static_island");
state->midpoints = RNA_boolean_get(op->ptr, "midpoint_snap");
state->clear_seams = RNA_boolean_get(op->ptr, "clear_seams");
+ state->draw_handle = ED_region_draw_cb_activate(CTX_wm_region(C)->type, stitch_draw, NULL, REGION_DRAW_POST_VIEW);
/* in uv synch selection, all uv's are visible */
if (ts->uv_flag & UV_SYNC_SELECTION) {
state->element_map = EDBM_uv_element_map_create(state->em, 0, 1);
@@ -1282,6 +1358,8 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished)
if (sa)
ED_area_headerprint(sa, NULL);
+ ED_region_draw_cb_exit(CTX_wm_region(C)->type, stitch_state->draw_handle);
+
DAG_id_tag_update(obedit->data, 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 7c06fbd2a9d..19a1c4339ad 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -223,7 +223,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em,
BMLoop *ls[3];
float *co[4];
float *uv[4];
- int i, lsel;
+ int lsel;
if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || (sel && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0))
continue;
@@ -245,6 +245,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em,
// tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); // UNUSED
if (efa->len == 3 || efa->len == 4) {
+ int i;
/* for quads let parametrize split, it can make better decisions
* about which split is best for unwrapping than scanfill */
i = 0;
@@ -291,6 +292,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em,
BLI_scanfill_calc_ex(&sf_ctx, TRUE, efa->no);
for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
+ int i;
ls[0] = sf_tri->v1->tmp.p;
ls[1] = sf_tri->v2->tmp.p;
ls[2] = sf_tri->v3->tmp.p;
@@ -727,12 +729,10 @@ static int pack_islands_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- if (RNA_struct_property_is_set(op->ptr, "margin")) {
+ if (RNA_struct_property_is_set(op->ptr, "margin"))
scene->toolsettings->uvcalc_margin = RNA_float_get(op->ptr, "margin");
- }
- else {
+ else
RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin);
- }
handle = construct_param_handle(scene, em, implicit, 0, 1, 1);
param_pack(handle, scene->toolsettings->uvcalc_margin);
@@ -759,7 +759,7 @@ void UV_OT_pack_islands(wmOperatorType *ot)
ot->poll = ED_operator_uvedit;
/* properties */
- RNA_def_float_factor(ot->srna, "margin", 0.0f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f);
+ RNA_def_float_factor(ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f);
}
/* ******************** Average Islands Scale operator **************** */
@@ -1184,7 +1184,8 @@ static int unwrap_exec(bContext *C, wmOperator *op)
mat4_to_size(obsize, obedit->obmat);
if (!compare_v3v3(obsize, unitsize, 1e-4f))
- BKE_report(op->reports, RPT_INFO, "Object scale is not 1.0. Unwrap will operate on a non-scaled version of the mesh.");
+ BKE_report(op->reports, RPT_INFO,
+ "Object scale is not 1.0, unwrap will operate on a non-scaled version of the mesh");
/* remember last method for live unwrap */
if (RNA_struct_property_is_set(op->ptr, "method"))
@@ -1192,6 +1193,12 @@ static int unwrap_exec(bContext *C, wmOperator *op)
else
RNA_enum_set(op->ptr, "method", scene->toolsettings->unwrapper);
+ /* remember packing marging */
+ if (RNA_struct_property_is_set(op->ptr, "margin"))
+ scene->toolsettings->uvcalc_margin = RNA_float_get(op->ptr, "margin");
+ else
+ RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin);
+
scene->toolsettings->uv_subsurf_level = subsurf_level;
if (fill_holes) scene->toolsettings->uvcalc_flag |= UVCALC_FILLHOLES;
@@ -1239,8 +1246,9 @@ void UV_OT_unwrap(wmOperatorType *ot)
"Map UVs taking image aspect ratio into account");
RNA_def_boolean(ot->srna, "use_subsurf_data", 0, "Use Subsurf Data",
"Map UVs taking vertex position after subsurf into account");
- RNA_def_int(ot->srna, "uv_subsurf_level", 1, 1, 6, "SubSurf Target",
+ RNA_def_int(ot->srna, "uv_subsurf_level", 1, 1, 6, "Subsurf Target",
"Number of times to subdivide before calculating UVs", 1, 6);
+ RNA_def_float_factor(ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f);
}
/**************** Project From View operator **************/