diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-12-19 05:49:58 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-12-19 05:49:58 +0400 |
commit | d433cd65f7127d60e17d05a824290423ad226eae (patch) | |
tree | f0a9c821f6046e97b74c6969d41269b558fd52ab /source/blender/editors | |
parent | 10f0f66560234a04aed3295c74fff20adacbc57f (diff) | |
parent | f10dea7e3b9b431edae9c787fa1a9e09cd567ed7 (diff) |
Merged changes in the trunk up to revision 53146.
Conflicts resolved:
release/datafiles/startup.blend
source/blender/blenkernel/CMakeLists.txt
source/blender/blenlib/intern/bpath.c
source/blender/blenloader/intern/readfile.c
Diffstat (limited to 'source/blender/editors')
186 files changed, 4893 insertions, 2932 deletions
diff --git a/source/blender/editors/SConscript b/source/blender/editors/SConscript index 6233ea0dc39..1ea2bc0e4ef 100644 --- a/source/blender/editors/SConscript +++ b/source/blender/editors/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') diff --git a/source/blender/editors/animation/SConscript b/source/blender/editors/animation/SConscript index 658ad2794a1..2a6b381ba66 100644 --- a/source/blender/editors/animation/SConscript +++ b/source/blender/editors/animation/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 643c2c4dfe0..038fbf291d3 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -83,7 +83,7 @@ #define EXTRA_SCROLL_PAD 100.0f /* size of indent steps */ -#define INDENT_STEP_SIZE 7 +#define INDENT_STEP_SIZE (0.35f * U.widget_unit) /* size of string buffers used for animation channel displayed names */ #define ANIM_CHAN_NAME_SIZE 256 @@ -306,15 +306,15 @@ static short acf_generic_group_offset(bAnimContext *ac, bAnimListElem *ale) if (ale->id) { /* texture animdata */ if (GS(ale->id->name) == ID_TE) { - offset += 21; + offset += U.widget_unit; } /* materials and particles animdata */ else if (ELEM(GS(ale->id->name), ID_MA, ID_PA)) - offset += 14; + offset += (short)(0.7f * U.widget_unit); /* if not in Action Editor mode, action-groups (and their children) must carry some offset too... */ else if (ac->datatype != ANIMCONT_ACTION) - offset += 14; + offset += (short)(0.7f * U.widget_unit); /* nodetree animdata */ if (GS(ale->id->name) == ID_NT) { @@ -2990,12 +2990,12 @@ void ANIM_channel_setting_set(bAnimContext *ac, bAnimListElem *ale, int setting, /* --------------------------- */ -// XXX hardcoded size of icons -#define ICON_WIDTH 17 -// XXX hardcoded width of sliders -#define SLIDER_WIDTH 80 -// XXX hardcoded width of rename textboxes -#define RENAME_TEXT_WIDTH 100 +// size of icons +#define ICON_WIDTH (0.85f * U.widget_unit) +// width of sliders +#define SLIDER_WIDTH (4 * U.widget_unit) +// width of rename textboxes +#define RENAME_TEXT_WIDTH (5 * U.widget_unit) /* Draw the given channel */ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc) @@ -3016,12 +3016,11 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float offset = 0; /* calculate appropriate y-coordinates for icon buttons - * 7 is hardcoded factor for half-height of icons */ y = (ymaxc - yminc) / 2 + yminc; - ymid = y - 7; + ymid = y - 0.5f * ICON_WIDTH; /* y-coordinates for text is only 4 down from middle */ - ytext = y - 4; + ytext = y - 0.2f * U.widget_unit; /* check if channel is selected */ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT)) @@ -3068,10 +3067,8 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float glColor3fv(fcu->color); /* just a solid color rect - * hardcoded 17 pixels width is slightly wider than icon width, so that - * there's a slight border around it */ - glRectf(offset, yminc, offset + 17, ymaxc); + glRectf(offset, yminc, offset + ICON_WIDTH, ymaxc); } /* icon is drawn as widget now... */ @@ -3165,7 +3162,7 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float } - /* finally draw a backdrop rect behind these + /* finally draw a backdrop rect behind these * - starts from the point where the first toggle/slider starts, * - ends past the space that might be reserved for a scroller */ @@ -3444,12 +3441,9 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale offset = 0; /* calculate appropriate y-coordinates for icon buttons - * 7 is hardcoded factor for half-height of icons */ y = (ymaxc - yminc) / 2 + yminc; - ymid = y - 7; - /* y-coordinates for text is only 4 down from middle */ - /* ytext = y - 4; */ + ymid = y - 0.5f * ICON_WIDTH; /* no button backdrop behind icons */ uiBlockSetEmboss(block, UI_EMBOSSN); diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index bb324337ffb..466bb178136 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -542,12 +542,26 @@ void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *f BLI_remlink(&adt->drivers, fcu); } else if (adt->action) { + bAction *act = adt->action; + /* remove from group or action, whichever one "owns" the F-Curve */ - if (fcu->grp) - action_groups_remove_channel(adt->action, fcu); - else - BLI_remlink(&adt->action->curves, fcu); + if (fcu->grp) { + bActionGroup *agrp = fcu->grp; + + /* remove F-Curve from group+action */ + action_groups_remove_channel(act, fcu); + /* if group has no more channels, remove it too, + * otherwise can have many dangling groups [#33541] + */ + if (agrp->channels.first == NULL) { + BLI_freelinkN(&act->groups, agrp); + } + } + else { + BLI_remlink(&act->curves, fcu); + } + /* if action has no more F-Curves as a result of this, unlink it from * AnimData if it did not come from a NLA Strip being tweaked. * @@ -555,12 +569,8 @@ void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *f * channel list that are empty, and linger around long after the data they * are for has disappeared (and probably won't come back). */ - // XXX: does everybody always want this? - /* XXX: there's a problem where many actions could build up in the file if multiple - * full add/delete cycles are performed on the same objects, but assume that this is rare - */ - if ((adt->action->curves.first == NULL) && (adt->flag & ADT_NLA_EDIT_ON) == 0) { - id_us_min(&adt->action->id); + if ((act->curves.first == NULL) && (adt->flag & ADT_NLA_EDIT_ON) == 0) { + id_us_min(&act->id); adt->action = NULL; } } @@ -1230,7 +1240,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op)) case ANIMTYPE_MASKLAYER: { - /* Grease Pencil layer */ + /* Mask layer */ Mask *mask = (Mask *)ale->id; MaskLayer *masklay = (MaskLayer *)ale->data; diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index 0f0584ad8fe..d83d1805f0e 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -33,9 +33,12 @@ #include "DNA_anim_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_userdef_types.h" + #include "BLI_math.h" #include "BKE_context.h" +#include "BKE_blender.h" #include "BKE_global.h" #include "BKE_nla.h" #include "BKE_object.h" @@ -197,15 +200,15 @@ static void draw_cfra_number(Scene *scene, View2D *v2d, float cfra, short time) /* get starting coordinates for drawing */ x = cfra * xscale; - y = 18; + y = 0.9f * U.widget_unit; /* draw green box around/behind text */ UI_ThemeColorShade(TH_CFRAME, 0); - glRectf(x, y, x + slen, y + 15); + glRectf(x, y, x + slen, y + 0.75f * U.widget_unit); /* draw current frame number - black text */ UI_ThemeColor(TH_TEXT); - UI_DrawString(x - 5, y + 3, numstr); + UI_DrawString(x - 0.25f * U.widget_unit, y + 0.15f * U.widget_unit, numstr); /* restore view transform */ glScalef(xscale, 1.0, 1.0); diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index 1b980790fdc..f684e57c2bc 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -395,7 +395,7 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag) ICON_MARKER; } - UI_icon_draw(xpos * xscale - 5.0f, 16.0f, icon_id); + UI_icon_draw(xpos * xscale - 0.3f * UI_DPI_ICON_SIZE, UI_DPI_ICON_SIZE, icon_id); glDisable(GL_BLEND); @@ -405,18 +405,18 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag) if (marker->flag & SELECT) { UI_ThemeColor(TH_TEXT_HI); - x = xpos * xscale + 4.0f; - y = (ypixels <= 39.0f) ? (ypixels - 10.0f) : 29.0f; + x = xpos * xscale + 4.0f * UI_DPI_FAC; + y = (ypixels <= 39.0f * UI_DPI_FAC) ? (ypixels - 10.0f * UI_DPI_FAC) : 29.0f * UI_DPI_FAC; } else { UI_ThemeColor(TH_TEXT); if ((marker->frame <= cfra) && (marker->frame + 5 > cfra)) { - x = xpos * xscale + 4.0f; - y = (ypixels <= 39.0f) ? (ypixels - 10.0f) : 29.0f; + x = xpos * xscale + 8.0f * UI_DPI_FAC; + y = (ypixels <= 39.0f * UI_DPI_FAC) ? (ypixels - 10.0f * UI_DPI_FAC) : 29.0f * UI_DPI_FAC; } else { - x = xpos * xscale + 4.0f; - y = 17.0f; + x = xpos * xscale + 8.0f * UI_DPI_FAC; + y = 17.0f * UI_DPI_FAC; } } diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index e520a95aa95..d9d2180e184 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -649,7 +649,7 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa ActKeyColumn *ak; ActKeyBlock *ab; float xscale; - + float iconsize = U.widget_unit / 4.0f; glEnable(GL_BLEND); /* get View2D scaling factor */ @@ -665,7 +665,7 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa else UI_ThemeColor4(TH_STRIP); - glRectf(ab->start, ypos - 5, ab->end, ypos + 5); + glRectf(ab->start, ypos - iconsize, ab->end, ypos + iconsize); } } } @@ -686,7 +686,7 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa /* draw using OpenGL - uglier but faster */ /* NOTE1: a previous version of this didn't work nice for some intel cards * NOTE2: if we wanted to go back to icons, these are icon = (ak->sel & SELECT) ? ICON_SPACE2 : ICON_SPACE3; */ - draw_keyframe_shape(ak->cfra, ypos, xscale, 5.0f, (ak->sel & SELECT), ak->key_type, KEYFRAME_SHAPE_BOTH, kalpha); + draw_keyframe_shape(ak->cfra, ypos, xscale, iconsize, (ak->sel & SELECT), ak->key_type, KEYFRAME_SHAPE_BOTH, kalpha); } } diff --git a/source/blender/editors/armature/BIF_generate.h b/source/blender/editors/armature/BIF_generate.h index 06ee3fbb64c..71109574fe0 100644 --- a/source/blender/editors/armature/BIF_generate.h +++ b/source/blender/editors/armature/BIF_generate.h @@ -40,9 +40,10 @@ int nextFixedSubdivision(struct ToolSettings *toolsettings, struct BArcIterator int nextLengthSubdivision(struct ToolSettings *toolsettings, struct BArcIterator *iter, int start, int end, float head[3], float p[3]); int nextAdaptativeSubdivision(struct ToolSettings *toolsettings, struct BArcIterator *iter, int start, int end, float head[3], float p[3]); -struct EditBone *subdivideArcBy(struct ToolSettings *toolsettings, struct bArmature *arm, ListBase *editbones, struct BArcIterator *iter, float invmat[][4], float tmat[][3], NextSubdivisionFunc next_subdividion); +struct EditBone *subdivideArcBy(struct ToolSettings *toolsettings, struct bArmature *arm, ListBase *editbones, struct BArcIterator *iter, + float invmat[4][4], float tmat[3][3], NextSubdivisionFunc next_subdividion); -void setBoneRollFromNormal(struct EditBone *bone, const float no[3], float invmat[][4], float tmat[][3]); +void setBoneRollFromNormal(struct EditBone *bone, const float no[3], float invmat[4][4], float tmat[3][3]); #endif /* __BIF_GENERATE_H__ */ diff --git a/source/blender/editors/armature/SConscript b/source/blender/editors/armature/SConscript index ba375f30093..1911d76a894 100644 --- a/source/blender/editors/armature/SConscript +++ b/source/blender/editors/armature/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index e801d3689e5..ffe58be0139 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -2062,7 +2062,7 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); /* can be NULL */ float cursor_local[3]; - float *cursor = give_cursor(scene, v3d); + const float *cursor = give_cursor(scene, v3d); copy_v3_v3(cursor_local, cursor); @@ -2323,7 +2323,8 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op)) View3D *v3d; bArmature *arm; EditBone *ebone, *newbone, *flipbone; - float *curs, mat[3][3], imat[3][3]; + float mat[3][3], imat[3][3]; + const float *curs; int a, to_root = 0; Object *obedit; Scene *scene; @@ -2418,7 +2419,7 @@ static int armature_click_extrude_invoke(bContext *C, wmOperator *op, wmEvent *e Scene *scene; ARegion *ar; View3D *v3d; - float *fp = NULL, tvec[3], oldcurs[3], mval_f[2]; + float *fp, tvec[3], oldcurs[3], mval_f[2]; int retv; scene = CTX_data_scene(C); diff --git a/source/blender/editors/armature/editarmature_generate.c b/source/blender/editors/armature/editarmature_generate.c index d9c7e78c01e..979c352c4b2 100644 --- a/source/blender/editors/armature/editarmature_generate.c +++ b/source/blender/editors/armature/editarmature_generate.c @@ -50,7 +50,7 @@ #include "armature_intern.h" #include "BIF_generate.h" -void setBoneRollFromNormal(EditBone *bone, const float no[3], float UNUSED(invmat[][4]), float tmat[][3]) +void setBoneRollFromNormal(EditBone *bone, const float no[3], float UNUSED(invmat[4][4]), float tmat[3][3]) { if (no != NULL && !is_zero_v3(no)) { float normal[3]; @@ -257,7 +257,8 @@ int nextLengthSubdivision(ToolSettings *toolsettings, BArcIterator *iter, int st return -1; } -EditBone *subdivideArcBy(ToolSettings *toolsettings, bArmature *arm, ListBase *UNUSED(editbones), BArcIterator *iter, float invmat[][4], float tmat[][3], NextSubdivisionFunc next_subdividion) +EditBone *subdivideArcBy(ToolSettings *toolsettings, bArmature *arm, ListBase *UNUSED(editbones), BArcIterator *iter, + float invmat[4][4], float tmat[3][3], NextSubdivisionFunc next_subdividion) { EditBone *lastBone = NULL; EditBone *child = NULL; diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index f9cf4a29269..b61aa86a52f 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -361,7 +361,7 @@ static void sk_autoname(bContext *C, ReebArc *arc) } } -static ReebNode *sk_pointToNode(SK_Point *pt, float imat[][4], float tmat[][3]) +static ReebNode *sk_pointToNode(SK_Point *pt, float imat[4][4], float tmat[3][3]) { ReebNode *node; @@ -375,7 +375,7 @@ static ReebNode *sk_pointToNode(SK_Point *pt, float imat[][4], float tmat[][3]) return node; } -static ReebArc *sk_strokeToArc(SK_Stroke *stk, float imat[][4], float tmat[][3]) +static ReebArc *sk_strokeToArc(SK_Stroke *stk, float imat[4][4], float tmat[3][3]) { ReebArc *arc; int i; diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 9152ea8e198..5376c897c29 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -862,7 +862,7 @@ static void rigid_add_edge_to_R(LaplacianSystem *sys, EditVert *v1, EditVert *v2 rigid_add_half_edge_to_R(sys, v2, v1, w); } -static void rigid_orthogonalize_R(float R[][3]) +static void rigid_orthogonalize_R(float R[3][3]) { HMatrix M, Q, S; @@ -1120,7 +1120,7 @@ typedef struct MeshDeformBind { typedef struct MeshDeformIsect { float start[3]; float vec[3]; - float labda; + float lambda; void *face; int isect; @@ -1227,7 +1227,7 @@ static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *r copy_v3_v3(hit->co, co); isec->isect = (dot_v3v3(no, ray->direction) <= 0.0f); - isec->labda = dist; + isec->lambda = dist; isec->face = mf; } } @@ -1245,7 +1245,7 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float /* setup isec */ memset(&isect_mdef, 0, sizeof(isect_mdef)); - isect_mdef.labda = 1e10f; + isect_mdef.lambda = 1e10f; add_v3_v3v3(isect_mdef.start, co1, epsilon); add_v3_v3v3(end, co2, epsilon); @@ -1256,7 +1256,7 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float 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; + len = isect_mdef.lambda; isect_mdef.face = mface = mface1 + hit.index; /* create MDefBoundIsect */ @@ -1956,7 +1956,7 @@ static void heat_weighting_bind(Scene *scene, DerivedMesh *dm, MeshDeformModifie } #endif -void mesh_deform_bind(Scene *scene, MeshDeformModifierData *mmd, float *vertexcos, int totvert, float cagemat[][4]) +void mesh_deform_bind(Scene *scene, MeshDeformModifierData *mmd, float *vertexcos, int totvert, float cagemat[4][4]) { MeshDeformBind mdb; MVert *mvert; diff --git a/source/blender/editors/curve/SConscript b/source/blender/editors/curve/SConscript index 95dd7fc6233..abefd3c6dd6 100644 --- a/source/blender/editors/curve/SConscript +++ b/source/blender/editors/curve/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 23fed4ce8fc..f4dccd01007 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -1493,7 +1493,7 @@ static void setflagsNurb(ListBase *editnurb, short flag) } } -static void rotateflagNurb(ListBase *editnurb, short flag, float *cent, float rotmat[][3]) +static void rotateflagNurb(ListBase *editnurb, short flag, float *cent, float rotmat[3][3]) { /* all verts with (flag & 'flag') rotate */ Nurb *nu; @@ -4278,7 +4278,7 @@ int mouse_nurb(bContext *C, const int mval[2], int extend, int deselect, int tog /* 'cent' is in object space and 'dvec' in worldspace. */ -static int spin_nurb(float viewmat[][4], Object *obedit, float *axis, float *cent) +static int spin_nurb(float viewmat[4][4], Object *obedit, float *axis, float *cent) { Curve *cu = (Curve *)obedit->data; ListBase *editnurb = object_editcurve_get(obedit); diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt index ec20e2d3d09..6d6b7ecdd82 100644 --- a/source/blender/editors/datafiles/CMakeLists.txt +++ b/source/blender/editors/datafiles/CMakeLists.txt @@ -46,7 +46,8 @@ if(WITH_BLENDER) # images data_to_c_simple(../../../../release/datafiles/splash.png SRC) - data_to_c_simple(../../../../release/datafiles/blender_icons.png SRC) + data_to_c_simple(../../../../release/datafiles/blender_icons16.png SRC) + data_to_c_simple(../../../../release/datafiles/blender_icons32.png SRC) data_to_c_simple(../../../../release/datafiles/prvicons.png SRC) # brushes diff --git a/source/blender/editors/datafiles/SConscript b/source/blender/editors/datafiles/SConscript index e0816f783d3..cb6fe11dbb2 100644 --- a/source/blender/editors/datafiles/SConscript +++ b/source/blender/editors/datafiles/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') # all source generated now @@ -14,7 +40,8 @@ sources.extend(( os.path.join(env['DATA_SOURCES'], "bmonofont.ttf.c"), os.path.join(env['DATA_SOURCES'], "splash.png.c"), - os.path.join(env['DATA_SOURCES'], "blender_icons.png.c"), + os.path.join(env['DATA_SOURCES'], "blender_icons16.png.c"), + os.path.join(env['DATA_SOURCES'], "blender_icons32.png.c"), os.path.join(env['DATA_SOURCES'], "prvicons.png.c"), os.path.join(env['DATA_SOURCES'], "startup.blend.c"), diff --git a/source/blender/editors/gpencil/SConscript b/source/blender/editors/gpencil/SConscript index 9d92a238eb7..f72e124e862 100644 --- a/source/blender/editors/gpencil/SConscript +++ b/source/blender/editors/gpencil/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 11e07584405..3e092ed8c5b 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -45,8 +45,10 @@ #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" +#include "DNA_userdef_types.h" #include "DNA_view3d_types.h" +#include "BKE_blender.h" #include "BKE_context.h" #include "BKE_global.h" #include "BKE_gpencil.h" diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c index 8a3c996a481..0aa109a0aef 100644 --- a/source/blender/editors/gpencil/gpencil_buttons.c +++ b/source/blender/editors/gpencil/gpencil_buttons.c @@ -312,6 +312,13 @@ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, Poin } } +void gpencil_panel_standard_header(const bContext *C, Panel *pa) +{ + PointerRNA ptr; + RNA_pointer_create((ID *)CTX_wm_screen(C), &RNA_Space, CTX_wm_space_data(C), &ptr); + + uiItemR(pa->layout, &ptr, "show_grease_pencil", 0, "", ICON_NONE); +} /* Standard panel to be included wherever Grease Pencil is used... */ void gpencil_panel_standard(const bContext *C, Panel *pa) diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index e9ca7392752..e4e640eeefc 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -451,7 +451,7 @@ static void gp_strokepoint_convertcoords(bContext *C, bGPDstroke *gps, bGPDspoin copy_v3_v3(p3d, &pt->x); } else { - float *fp = give_cursor(scene, v3d); + const float *fp = give_cursor(scene, v3d); float mvalf[2]; /* get screen coordinate */ diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 8fdca730674..c40312758fc 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -208,7 +208,7 @@ static int gpencil_project_check(tGPsdata *p) static void gp_get_3d_reference(tGPsdata *p, float vec[3]) { View3D *v3d = p->sa->spacedata.first; - float *fp = give_cursor(p->scene, v3d); + const float *fp = give_cursor(p->scene, v3d); /* the reference point used depends on the owner... */ #if 0 /* XXX: disabled for now, since we can't draw relative to the owner yet */ diff --git a/source/blender/editors/include/BIF_gl.h b/source/blender/editors/include/BIF_gl.h index 479e0b65177..cdf9b71972d 100644 --- a/source/blender/editors/include/BIF_gl.h +++ b/source/blender/editors/include/BIF_gl.h @@ -35,6 +35,14 @@ #include "GL/glew.h" +#ifdef __APPLE__ + +/* hacking pointsize and linewidth */ +#define glPointSize(f) glPointSize(U.pixelsize*(f)) +#define glLineWidth(f) glLineWidth(U.pixelsize*(f)) + +#endif + /* * these should be phased out. cpack should be replaced in * code with calls to glColor3ub. - zr diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index fba42a33f88..e288963553e 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -302,34 +302,34 @@ typedef enum eAnimFilter_Flags { /* -------------- Channel Defines -------------- */ /* channel heights */ -#define ACHANNEL_FIRST -16 -#define ACHANNEL_HEIGHT 16 -#define ACHANNEL_HEIGHT_HALF 8 -#define ACHANNEL_SKIP 2 +#define ACHANNEL_FIRST (-0.8f * U.widget_unit) +#define ACHANNEL_HEIGHT (0.8f * U.widget_unit) +#define ACHANNEL_HEIGHT_HALF (0.4f * U.widget_unit) +#define ACHANNEL_SKIP (0.1f * U.widget_unit) #define ACHANNEL_STEP (ACHANNEL_HEIGHT + ACHANNEL_SKIP) /* channel widths */ -#define ACHANNEL_NAMEWIDTH 200 +#define ACHANNEL_NAMEWIDTH (10 * U.widget_unit) /* channel toggle-buttons */ -#define ACHANNEL_BUTTON_WIDTH 16 +#define ACHANNEL_BUTTON_WIDTH (0.8f * U.widget_unit) /* -------------- NLA Channel Defines -------------- */ /* NLA channel heights */ // XXX: NLACHANNEL_FIRST isn't used? -#define NLACHANNEL_FIRST -16 -#define NLACHANNEL_HEIGHT(snla) ((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? 16 : 24) -#define NLACHANNEL_HEIGHT_HALF(snla) ((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? 8 : 12) -#define NLACHANNEL_SKIP 2 +#define NLACHANNEL_FIRST (-0.8f * U.widget_unit) +#define NLACHANNEL_HEIGHT(snla) ((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? (0.8f * U.widget_unit) : (1.2f * U.widget_unit)) +#define NLACHANNEL_HEIGHT_HALF(snla) ((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? (0.4f * U.widget_unit) : (0.6f * U.widget_unit)) +#define NLACHANNEL_SKIP (0.1f * U.widget_unit) #define NLACHANNEL_STEP(snla) (NLACHANNEL_HEIGHT(snla) + NLACHANNEL_SKIP) /* channel widths */ -#define NLACHANNEL_NAMEWIDTH 200 +#define NLACHANNEL_NAMEWIDTH (10 * U.widget_unit) /* channel toggle-buttons */ -#define NLACHANNEL_BUTTON_WIDTH 16 +#define NLACHANNEL_BUTTON_WIDTH (0.8f * U.widget_unit) /* ---------------- API -------------------- */ diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index efd10f3cb6b..4db79df033e 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -184,7 +184,7 @@ int BDR_drawSketchNames(struct ViewContext *vc); /* meshlaplacian.c */ void mesh_deform_bind(struct Scene *scene, struct MeshDeformModifierData *mmd, - float *vertexcos, int totvert, float cagemat[][4]); + float *vertexcos, int totvert, float cagemat[4][4]); #ifdef __cplusplus } diff --git a/source/blender/editors/include/ED_datafiles.h b/source/blender/editors/include/ED_datafiles.h index 8ad36397ce5..6d7bcecc630 100644 --- a/source/blender/editors/include/ED_datafiles.h +++ b/source/blender/editors/include/ED_datafiles.h @@ -36,8 +36,11 @@ extern int datatoc_startup_blend_size; extern char datatoc_startup_blend[]; -extern int datatoc_blender_icons_png_size; -extern char datatoc_blender_icons_png[]; +extern int datatoc_blender_icons16_png_size; +extern char datatoc_blender_icons16_png[]; + +extern int datatoc_blender_icons32_png_size; +extern char datatoc_blender_icons32_png[]; extern int datatoc_prvicons_png_size; extern char datatoc_prvicons_png[]; diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index 5cc1ecade3e..29d4097521d 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -81,6 +81,7 @@ void draw_gpencil_2dimage(const struct bContext *C); void draw_gpencil_view2d(const struct bContext *C, short onlyv2d); void draw_gpencil_view3d(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, short only3d); +void gpencil_panel_standard_header(const struct bContext *C, struct Panel *pa); void gpencil_panel_standard(const struct bContext *C, struct Panel *pa); /* ----------- Grease-Pencil AnimEdit API ------------------ */ diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 865da8f0e6e..1b4a67d38c0 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -86,11 +86,15 @@ void EDBM_mesh_clear(struct BMEditMesh *em); void EDBM_selectmode_to_scene(struct bContext *C); void EDBM_mesh_make(struct ToolSettings *ts, struct Scene *scene, struct Object *ob); -void EDBM_mesh_free(struct BMEditMesh *tm); +void EDBM_mesh_free(struct BMEditMesh *em); void EDBM_mesh_load(struct Object *ob); -void EDBM_index_arrays_init(struct BMEditMesh *em, int forvert, int foredge, int forface); +void EDBM_index_arrays_ensure(struct BMEditMesh *em, const char htype); +void EDBM_index_arrays_init(struct BMEditMesh *em, const char htype); void EDBM_index_arrays_free(struct BMEditMesh *em); +#ifndef NDEBUG +int EDBM_index_arrays_check(struct BMEditMesh *em); +#endif struct BMVert *EDBM_vert_at_index(struct BMEditMesh *em, int index); struct BMEdge *EDBM_edge_at_index(struct BMEditMesh *em, int index); struct BMFace *EDBM_face_at_index(struct BMEditMesh *em, int index); @@ -115,7 +119,7 @@ int EDBM_vert_color_check(struct BMEditMesh *em); void EDBM_mesh_hide(struct BMEditMesh *em, int swap); void EDBM_mesh_reveal(struct BMEditMesh *em); -void EDBM_update_generic(struct bContext *C, struct BMEditMesh *em, const short do_tessface); +void EDBM_update_generic(struct BMEditMesh *em, const short do_tessface, const short is_destructive); struct UvElementMap *EDBM_uv_element_map_create(struct BMEditMesh *em, int selected, int doIslands); void EDBM_uv_element_map_free(struct UvElementMap *vmap); @@ -126,7 +130,7 @@ struct MTexPoly *EDBM_mtexpoly_active_get(struct BMEditMesh *em, struct BMFace * void EDBM_uv_vert_map_free(struct UvVertMap *vmap); struct UvMapVert *EDBM_uv_vert_map_at_index(struct UvVertMap *vmap, unsigned int v); -struct UvVertMap *EDBM_uv_vert_map_create(struct BMEditMesh *em, int selected, int do_face_idx_array, const float limit[2]); +struct UvVertMap *EDBM_uv_vert_map_create(struct BMEditMesh *em, int selected, const float limit[2]); void EDBM_flag_enable_all(struct BMEditMesh *em, const char hflag); void EDBM_flag_disable_all(struct BMEditMesh *em, const char hflag); diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 0d0b8d8e797..533bfe2fa20 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -134,7 +134,7 @@ 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][4], int apply_diameter); void ED_object_add_generic_props(struct wmOperatorType *ot, int do_editmode); diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 860d176ffb3..72208a8e93d 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -64,9 +64,11 @@ void ED_region_panels(const struct bContext *C, struct ARegion *ar, int verti void ED_region_header_init(struct ARegion *ar); void ED_region_header(const struct bContext *C, struct ARegion *ar); void ED_region_toggle_hidden(struct bContext *C, struct ARegion *ar); -void region_scissor_winrct(struct ARegion *ar, struct rcti *winrct); void ED_region_info_draw(struct ARegion *ar, const char *text, int block, float alpha); void ED_region_grid_draw(struct ARegion *ar, float zoomx, float zoomy); +float ED_region_blend_factor(struct ARegion *ar); +void ED_region_visible_rect(struct ARegion *ar, struct rcti *rect); + /* spaces */ void ED_spacetypes_init(void); diff --git a/source/blender/editors/include/ED_sequencer.h b/source/blender/editors/include/ED_sequencer.h index 84fd5332316..23d173aebdc 100644 --- a/source/blender/editors/include/ED_sequencer.h +++ b/source/blender/editors/include/ED_sequencer.h @@ -38,6 +38,8 @@ int ED_space_sequencer_maskedit_mask_poll(struct bContext *C); int ED_space_sequencer_check_show_maskedit(struct SpaceSeq *sseq, struct Scene *scene); int ED_space_sequencer_maskedit_poll(struct bContext *C); +int ED_space_sequencer_check_show_imbuf(struct SpaceSeq *sseq); + void ED_operatormacros_sequencer(void); #endif /* __ED_SEQUENCER_H__ */ diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index d7e9fc323a6..03c1dd5a86d 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -124,7 +124,7 @@ void BIF_createTransformOrientation(struct bContext *C, struct ReportList *repor void BIF_selectTransformOrientation(struct bContext *C, struct TransformOrientation *ts); void BIF_selectTransformOrientationValue(struct bContext *C, int orientation); -void ED_getTransformOrientationMatrix(const struct bContext *C, float orientation_mat[][3], int activeOnly); +void ED_getTransformOrientationMatrix(const struct bContext *C, float orientation_mat[3][3], int activeOnly); struct EnumPropertyItem *BIF_enumTransformOrientation(struct bContext *C); const char *BIF_menustringTransformOrientation(const struct bContext *C, const char *title); /* the returned value was allocated and needs to be freed after use */ diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index f15f2418707..8ca7d5a023e 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -86,8 +86,8 @@ typedef struct ViewDepths { float *give_cursor(struct Scene *scene, struct View3D *v3d); -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); +void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist); +void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist); void ED_view3d_from_object(struct Object *ob, float ofs[3], float quat[4], float *dist, float *lens); void ED_view3d_to_object(struct Object *ob, const float ofs[3], const float quat[4], const float dist); @@ -208,7 +208,7 @@ void ED_view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar, struc void ED_view3d_calc_camera_border_size(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, float size_r[2]); 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]); +void ED_view3d_clipping_local(struct RegionView3D *rv3d, float mat[4][4]); int ED_view3d_clipping_test(struct RegionView3D *rv3d, const float vec[3], const int is_local); void ED_view3d_clipping_set(struct RegionView3D *rv3d); void ED_view3d_clipping_enable(void); @@ -219,7 +219,7 @@ float ED_view3d_pixel_size(struct RegionView3D *rv3d, const float co[3]); float ED_view3d_radius_to_persp_dist(const float angle, const float radius); float ED_view3d_radius_to_ortho_dist(const float lens, const float radius); -void drawcircball(int mode, const float cent[3], float rad, float tmat[][4]); +void drawcircball(int mode, const float cent[3], float rad, float tmat[4][4]); /* backbuffer select and draw support */ void view3d_validate_backbuf(struct ViewContext *vc); @@ -264,17 +264,17 @@ int ED_view3d_scene_layer_set(int lay, const int *values, int *active); int ED_view3d_context_activate(struct bContext *C); void ED_view3d_draw_offscreen_init(struct Scene *scene, struct View3D *v3d); void ED_view3d_draw_offscreen(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, - int winx, int winy, float viewmat[][4], float winmat[][4], int do_bgpic, int colormanage_background); + int winx, int winy, float viewmat[4][4], float winmat[4][4], int do_bgpic, int colormanage_background); struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag, int draw_background, int colormanage_background, char err_out[256]); struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(struct Scene *scene, struct Object *camera, int width, int height, unsigned int flag, int drawtype, - int draw_background, int colormanage_background, char err_out[256]); + int use_solid_tex, int draw_background, int colormanage_background, char err_out[256]); struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]); void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, short do_clip); -void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[][4], float winmat[][4]); +void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4]); int ED_view3d_lock(struct RegionView3D *rv3d); uint64_t ED_view3d_datamask(struct Scene *scene, struct View3D *v3d); @@ -295,7 +295,8 @@ void ED_view3D_background_image_remove(struct View3D *v3d, struct BGpic *bgpic); void ED_view3D_background_image_clear(struct View3D *v3d); #define VIEW3D_MARGIN 1.4f -float ED_view3d_offset_distance(float mat[4][4], float ofs[3]); +#define VIEW3D_DIST_FALLBACK 1.0f +float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float dist_fallback); float ED_scene_grid_scale(struct Scene *scene, const char **grid_unit); float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 2dc552d0fce..90f8779b2c7 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -175,12 +175,11 @@ typedef struct uiLayout uiLayout; /* uiBut->drawflag */ #define UI_BUT_DRAW_ENUM_ARROWS (1 << 0) /* draw enum-like up/down arrows for button */ -/* scale fixed button widths by this to account for DPI - * 8.4852 == sqrtf(72.0f)) */ -#define UI_DPI_FAC (sqrtf((float)U.dpi) / 8.48528137423857f) -#define UI_DPI_ICON_FAC (((float)U.dpi) / 72.0f) +/* scale fixed button widths by this to account for DPI */ + +#define UI_DPI_FAC ((U.pixelsize * (float)U.dpi) / 72.0f) /* 16 to copy ICON_DEFAULT_HEIGHT */ -#define UI_DPI_ICON_SIZE ((float)16 * UI_DPI_ICON_FAC) +#define UI_DPI_ICON_SIZE ((float)16 * UI_DPI_FAC) /* Button types, bits stored in 1 value... and a short even! * - bits 0-4: bitnr (0-31) @@ -287,7 +286,7 @@ void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float #define UI_SCROLL_PRESSED 1 #define UI_SCROLL_ARROWS 2 #define UI_SCROLL_NO_OUTLINE 4 -void uiWidgetScrollDraw(struct uiWidgetColors *wcol, struct rcti *rect, struct rcti *slider, int state); +void uiWidgetScrollDraw(struct uiWidgetColors *wcol, const struct rcti *rect, const struct rcti *slider, int state); /* Callbacks * @@ -885,7 +884,7 @@ void uiIDContextProperty(struct bContext *C, struct PointerRNA *ptr, struct Prop /* Styled text draw */ void uiStyleFontSet(struct uiFontStyle *fs); -void uiStyleFontDrawExt(struct uiFontStyle *fs, struct rcti *rect, const char *str, +void uiStyleFontDrawExt(struct uiFontStyle *fs, const struct rcti *rect, const char *str, float *r_xofs, float *r_yofs); void uiStyleFontDraw(struct uiFontStyle *fs, struct rcti *rect, const char *str); void uiStyleFontDrawRotated(struct uiFontStyle *fs, struct rcti *rect, const char *str); @@ -893,7 +892,10 @@ void uiStyleFontDrawRotated(struct uiFontStyle *fs, struct rcti *rect, const cha int UI_GetStringWidth(const char *str); // XXX temp void UI_DrawString(float x, float y, const char *str); // XXX temp void UI_DrawTriIcon(float x, float y, char dir); -uiStyle *UI_GetStyle(void); + +uiStyle *UI_GetStyle(void); /* use for fonts etc */ +uiStyle *UI_GetStyleDraw(void); /* DPI scaled settings for drawing */ + /* linker workaround ack! */ void UI_template_fix_linking(void); diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index 7391d29c9bf..a43e1705101 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -64,10 +64,11 @@ enum { TH_HEADER_TEXT, TH_HEADER_TEXT_HI, - /* float panels */ - TH_PANEL, - TH_PANEL_TEXT, - TH_PANEL_TEXT_HI, + /* panels */ + TH_PANEL_HEADER, + TH_PANEL_BACK, + TH_PANEL_SHOW_HEADER, + TH_PANEL_SHOW_BACK, TH_BUTBACK, TH_BUTBACK_TEXT, diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h index 24759fa778a..3ae1e93dc3d 100644 --- a/source/blender/editors/include/UI_view2d.h +++ b/source/blender/editors/include/UI_view2d.h @@ -102,11 +102,11 @@ enum { /* ------ Defines for Scrollers ----- */ /* scroller area */ -#define V2D_SCROLL_HEIGHT 17 -#define V2D_SCROLL_WIDTH 17 +#define V2D_SCROLL_HEIGHT (0.85f * U.widget_unit) +#define V2D_SCROLL_WIDTH (0.85f * U.widget_unit) /* scroller 'handles' hotspot radius for mouse */ -#define V2D_SCROLLER_HANDLE_SIZE 12 +#define V2D_SCROLLER_HANDLE_SIZE (0.6f * U.widget_unit) /* ------ Define for UI_view2d_sync ----- */ @@ -132,6 +132,7 @@ struct View2DScrollers; struct wmKeyConfig; struct bScreen; +struct Scene; struct ScrArea; struct ARegion; struct bContext; @@ -198,6 +199,7 @@ struct View2D *UI_view2d_fromcontext(const struct bContext *C); struct View2D *UI_view2d_fromcontext_rwin(const struct bContext *C); void UI_view2d_getscale(struct View2D *v2d, float *x, float *y); +void UI_view2d_getscale_inverse(struct View2D *v2d, float *x, float *y); short UI_view2d_mouse_in_scrollers(const struct bContext *C, struct View2D *v2d, int x, int y); diff --git a/source/blender/editors/interface/SConscript b/source/blender/editors/interface/SConscript index 2d6d5cd235e..8d277d6cd35 100644 --- a/source/blender/editors/interface/SConscript +++ b/source/blender/editors/interface/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index ce82e064531..807f5279821 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -69,7 +69,6 @@ #include "WM_api.h" #include "WM_types.h" #include "wm_subwindow.h" -#include "wm_window.h" #include "RNA_access.h" @@ -298,9 +297,9 @@ static void ui_centered_bounds_block(const bContext *C, uiBlock *block) /* note: this is used for the splash where window bounds event has not been * updated by ghost, get the window bounds from ghost directly */ - // wm_window_get_size(window, &xmax, &ymax); - wm_window_get_size_ghost(window, &xmax, &ymax); - + xmax = WM_window_pixels_x(window); + ymax = WM_window_pixels_y(window); + ui_bounds_block(block); width = BLI_rctf_size_x(&block->rect); @@ -326,7 +325,8 @@ static void ui_popup_bounds_block(const bContext *C, uiBlock *block, eBlockBound /* compute mouse position with user defined offset */ ui_bounds_block(block); - wm_window_get_size(window, &xmax, &ymax); + xmax = WM_window_pixels_x(window); + ymax = WM_window_pixels_y(window); oldwidth = BLI_rctf_size_x(&block->rect); oldheight = BLI_rctf_size_y(&block->rect); @@ -334,7 +334,7 @@ static void ui_popup_bounds_block(const bContext *C, uiBlock *block, eBlockBound /* first we ensure wide enough text bounds */ if (bounds_calc == UI_BLOCK_BOUNDS_POPUP_MENU) { if (block->flag & UI_BLOCK_LOOP) { - block->bounds = 50; + block->bounds = 2.5f * UI_UNIT_X; ui_text_bounds_block(block, block->rect.xmin); } } @@ -983,7 +983,8 @@ void ui_fontscale(short *points, float aspect) float pointsf = *points; /* for some reason scaling fonts goes too fast compared to widget size */ - aspect = sqrt(aspect); + /* XXX not true anymore? (ton) */ + //aspect = sqrt(aspect); pointsf /= aspect; if (aspect > 1.0f) @@ -1000,7 +1001,7 @@ static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, u ui_block_to_window_fl(ar, block, &rectf.xmin, &rectf.ymin); ui_block_to_window_fl(ar, block, &rectf.xmax, &rectf.ymax); - + rectf.xmin -= ar->winrct.xmin; rectf.ymin -= ar->winrct.ymin; rectf.xmax -= ar->winrct.xmin; @@ -1015,7 +1016,7 @@ static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, u /* uses local copy of style, to scale things down, and allow widgets to change stuff */ void uiDrawBlock(const bContext *C, uiBlock *block) { - uiStyle style = *UI_GetStyle(); /* XXX pass on as arg */ + uiStyle style = *UI_GetStyleDraw(); /* XXX pass on as arg */ ARegion *ar; uiBut *but; rcti rect; @@ -2650,7 +2651,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, BLI_assert(width >= 0); BLI_assert(height >= 0); - + /* we could do some more error checks here */ if ((type & BUTTYPE) == LABEL) { BLI_assert((poin != NULL || min != 0.0f || max != 0.0f || (a1 == 0.0f && a2 != 0.0f) || (a1 != 0.0f && a1 != 1.0f)) == FALSE); @@ -2786,6 +2787,10 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s uiBut *but; int freestr = 0, icon = 0; + if (ELEM3(type, COLOR, HSVCIRCLE, HSVCUBE)) { + BLI_assert(index == -1); + } + /* use rna values if parameters are not specified */ if (!str) { if (type == MENU && proptype == PROP_ENUM) { @@ -2826,12 +2831,13 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s EnumPropertyItem *item; int i, totitem, free; - /* TODO, translate after getting the item, saves many lookups */ - RNA_property_enum_items_gettexted(block->evil_C, ptr, prop, &item, &totitem, &free); + /* get untranslated, then translate the single string we need */ + RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free); for (i = 0; i < totitem; i++) { if (item[i].identifier[0] && item[i].value == (int)max) { - str = item[i].name; + str = CTX_IFACE_(RNA_property_translation_context(prop), item[i].name); icon = item[i].icon; + break; } } diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 4d96ad810d4..792553f842c 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -429,17 +429,18 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w #else ImBuf *ibuf = (ImBuf *)but->poin; //GLint scissor[4]; - //int w, h; + int w, h; if (!ibuf) return; + w = BLI_rcti_size_x(rect); + h = BLI_rcti_size_y(rect); + /* scissor doesn't seem to be doing the right thing...? */ #if 0 //glColor4f(1.0, 0.f, 0.f, 1.f); //fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax) - w = BLI_rcti_size_x(rect); - h = BLI_rcti_size_y(rect); /* prevent drawing outside widget area */ glGetIntegerv(GL_SCISSOR_BOX, scissor); glScissor(ar->winrct.xmin + rect->xmin, ar->winrct.ymin + rect->ymin, w, h); @@ -448,9 +449,16 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w glEnable(GL_BLEND); glColor4f(0.0, 0.0, 0.0, 0.0); + if (w != ibuf->x || h != ibuf->y) { + float facx = (float)w / (float)ibuf->x; + float facy = (float)h / (float)ibuf->y; + glPixelZoom(facx, facy); + } glaDrawPixelsSafe((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); //glaDrawPixelsTex((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect); + glPixelZoom(1.0f, 1.0f); + glDisable(GL_BLEND); #if 0 diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index b80025e0d77..86fed3c2760 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -397,6 +397,17 @@ static void ui_apply_autokey_undo(bContext *C, uiBut *but) /* try autokey */ ui_but_anim_autokey(C, but, scene, scene->r.cfra); + + /* make a little report about what we've done! */ + if (but->rnaprop) { + char *buf = WM_prop_pystring_assign(C, &but->rnapoin, but->rnaprop, but->rnaindex); + if (buf) { + BKE_report(CTX_wm_reports(C), RPT_PROPERTY, buf); + MEM_freeN(buf); + + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO_REPORT, NULL); + } + } } static void ui_apply_but_funcs_after(bContext *C) @@ -1674,10 +1685,11 @@ static int ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, int paste { char buf[UI_MAX_DRAW_STR] = {0}; char *str, *p, *pbuf; - int len, x, i, changed = 0; + int x, changed = 0; + int str_len, buf_len; str = data->str; - len = strlen(str); + str_len = strlen(str); /* paste */ if (paste) { @@ -1687,28 +1699,28 @@ static int ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, int paste if (p && p[0]) { unsigned int y; - i = 0; - while (*p && *p != '\r' && *p != '\n' && i < UI_MAX_DRAW_STR - 1) { - buf[i++] = *p; + buf_len = 0; + while (*p && *p != '\r' && *p != '\n' && buf_len < UI_MAX_DRAW_STR - 1) { + buf[buf_len++] = *p; p++; } - buf[i] = 0; + buf[buf_len] = 0; /* paste over the current selection */ if ((but->selend - but->selsta) > 0) { ui_textedit_delete_selection(but, data); - len = strlen(str); + str_len = strlen(str); } - for (y = 0; y < strlen(buf); y++) { + for (y = 0; y < buf_len; y++) { /* add contents of buffer */ - if (len + 1 < data->maxlen) { + if (str_len + 1 < data->maxlen) { for (x = data->maxlen; x > but->pos; x--) str[x] = str[x - 1]; str[but->pos] = buf[y]; but->pos++; - len++; - str[len] = '\0'; + str_len++; + str[str_len] = '\0'; } } @@ -4530,7 +4542,7 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg) wmKeyMapItem *kmi; PointerRNA ptr; uiLayout *layout; - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_GetStyleDraw(); IDProperty *prop = (but->opptr) ? but->opptr->data : NULL; int kmi_id = WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, 1, &km); @@ -4562,7 +4574,7 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg) wmKeyMapItem *kmi; PointerRNA ptr; uiLayout *layout; - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_GetStyleDraw(); IDProperty *prop = (but->opptr) ? but->opptr->data : NULL; int kmi_id; @@ -4629,7 +4641,6 @@ static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2)) static int ui_but_menu(bContext *C, uiBut *but) { - ARegion *ar = CTX_wm_region(C); uiPopupMenu *pup; uiLayout *layout; int length; @@ -4845,9 +4856,13 @@ static int ui_but_menu(bContext *C, uiBut *but) } /* Show header tools for header buttons. */ - if (ar->regiontype == RGN_TYPE_HEADER) { - uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL); - uiItemS(layout); + if (CTX_wm_region(C)) { + ARegion *ar = CTX_wm_region(C); + if (ar->regiontype == RGN_TYPE_HEADER) { + + uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL); + uiItemS(layout); + } } { /* Docs */ @@ -6924,11 +6939,12 @@ static int ui_handler_region_menu(bContext *C, wmEvent *event, void *UNUSED(user if (data->state == BUTTON_STATE_MENU_OPEN) { /* handle events for menus and their buttons recursively, * this will handle events from the top to the bottom menu */ - retval = ui_handle_menus_recursive(C, event, data->menu, 0); + if (data->menu) + retval = ui_handle_menus_recursive(C, event, data->menu, 0); /* handle events for the activated button */ if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) { - if (data->menu->menuretval) + if (data->menu && data->menu->menuretval) ui_handle_button_return_submenu(C, event, but); else ui_handle_button_event(C, event, but); diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index bb0cc1176d8..2dc77e96678 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -81,9 +81,9 @@ #define ICON_GRID_COLS 26 #define ICON_GRID_ROWS 30 -#define ICON_GRID_MARGIN 5 -#define ICON_GRID_W 16 -#define ICON_GRID_H 16 +#define ICON_GRID_MARGIN 10 +#define ICON_GRID_W 32 +#define ICON_GRID_H 32 typedef struct IconImage { int w; @@ -511,13 +511,15 @@ static void init_brush_icons(void) static void init_internal_icons(void) { - bTheme *btheme = UI_GetTheme(); - ImBuf *bbuf = NULL; +// bTheme *btheme = UI_GetTheme(); + ImBuf *b16buf = NULL, *b32buf = NULL; int x, y, icontype; - char iconfilestr[FILE_MAX]; - + +#if 0 // temp disabled if ((btheme != NULL) && btheme->tui.iconfile[0]) { char *icondir = BLI_get_folder(BLENDER_DATAFILES, "icons"); + char iconfilestr[FILE_MAX]; + if (icondir) { BLI_join_dirfile(iconfilestr, sizeof(iconfilestr), icondir, btheme->tui.iconfile); bbuf = IMB_loadiffname(iconfilestr, IB_rect, NULL); /* if the image is missing bbuf will just be NULL */ @@ -531,11 +533,16 @@ static void init_internal_icons(void) printf("%s: 'icons' data path not found, continuing\n", __func__); } } - if (bbuf == NULL) - bbuf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons_png, - datatoc_blender_icons_png_size, IB_rect, NULL, "<blender icons>"); +#endif + if (b16buf == NULL) + b16buf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons16_png, + datatoc_blender_icons16_png_size, IB_rect, NULL, "<blender icons>"); - if (bbuf) { + if (b32buf == NULL) + b32buf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons32_png, + datatoc_blender_icons32_png_size, IB_rect, NULL, "<blender icons>"); + + if (b16buf && b32buf) { /* free existing texture if any */ if (icongltex.id) { glDeleteTextures(1, &icongltex.id); @@ -547,17 +554,29 @@ static void init_internal_icons(void) glGenTextures(1, &icongltex.id); if (icongltex.id) { - icongltex.w = bbuf->x; - icongltex.h = bbuf->y; - icongltex.invw = 1.0f / bbuf->x; - icongltex.invh = 1.0f / bbuf->y; + int level = 2; + + icongltex.w = b32buf->x; + icongltex.h = b32buf->y; + icongltex.invw = 1.0f / b32buf->x; + icongltex.invh = 1.0f / b32buf->y; glBindTexture(GL_TEXTURE_2D, icongltex.id); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bbuf->x, bbuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, bbuf->rect); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, b32buf->x, b32buf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, b32buf->rect); + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, b16buf->x, b16buf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, b16buf->rect); + + while (b16buf->x > 1) { + b16buf = IMB_onehalf(b16buf); + glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, b16buf->x, b16buf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, b16buf->rect); + level++; + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glBindTexture(GL_TEXTURE_2D, 0); - + if (glGetError() == GL_OUT_OF_MEMORY) { glDeleteTextures(1, &icongltex.id); icongltex.id = 0; @@ -571,10 +590,10 @@ static void init_internal_icons(void) else icontype = ICON_TYPE_BUFFER; - if (bbuf) { + if (b16buf) { for (y = 0; y < ICON_GRID_ROWS; y++) { for (x = 0; x < ICON_GRID_COLS; x++) { - def_internal_icon(bbuf, BIFICONID_FIRST + y * ICON_GRID_COLS + x, + def_internal_icon(b32buf, BIFICONID_FIRST + y * ICON_GRID_COLS + x, x * (ICON_GRID_W + ICON_GRID_MARGIN) + ICON_GRID_MARGIN, y * (ICON_GRID_H + ICON_GRID_MARGIN) + ICON_GRID_MARGIN, ICON_GRID_W, icontype); @@ -593,7 +612,9 @@ static void init_internal_icons(void) def_internal_vicon(VICO_X_VEC, vicon_x_draw); def_internal_vicon(VICO_SMALL_TRI_RIGHT_VEC, vicon_small_tri_right_draw); - IMB_freeImBuf(bbuf); + IMB_freeImBuf(b16buf); + IMB_freeImBuf(b32buf); + } #endif /* WITH_HEADLESS */ @@ -750,7 +771,7 @@ static DrawInfo *icon_create_drawinfo(void) return di; } -/* note!, returns unscaled by DPI, may need to multiply result by UI_DPI_ICON_FAC */ +/* note!, returns unscaled by DPI */ int UI_icon_get_width(int icon_id) { Icon *icon = NULL; @@ -965,7 +986,7 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al Icon *icon = NULL; DrawInfo *di = NULL; IconImage *iimg; - float fdraw_size = is_preview ? draw_size : (draw_size * UI_DPI_ICON_FAC); + float fdraw_size = draw_size; int w, h; icon = BKE_icon_get(icon_id); @@ -1158,9 +1179,10 @@ void UI_icon_draw_aspect_color(float x, float y, int icon_id, float aspect, cons icon_draw_size(x, y, icon_id, aspect, 1.0f, rgb, ICON_SIZE_ICON, draw_size, FALSE, FALSE); } +/* draws icon with dpi scale factor */ void UI_icon_draw(float x, float y, int icon_id) { - UI_icon_draw_aspect(x, y, icon_id, 1.0f, 1.0f); + UI_icon_draw_aspect(x, y, icon_id, 1.0f / UI_DPI_FAC, 1.0f); } void UI_icon_draw_size(float x, float y, int size, int icon_id, float alpha) diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 23d3810e058..f088b3a54f4 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -267,7 +267,7 @@ struct uiBut { void *dragpoin; struct ImBuf *imb; float imb_scale; - + /* active button data */ struct uiHandleButtonData *active; @@ -358,7 +358,7 @@ struct uiBlock { char color_profile; /* color profile for correcting linear colors for display */ - char *display_device; /* display device name used to display this block, + const char *display_device; /* display device name used to display this block, * used by color widgets to transform colors from/to scene linear */ }; @@ -492,7 +492,7 @@ extern void ui_draw_aligned_panel(struct uiStyle *style, uiBlock *block, rcti *r /* interface_draw.c */ extern void ui_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int select); -void ui_draw_gradient(rcti *rect, const float hsv[3], const int type, const float alpha); +void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, const float alpha); void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect); void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect); @@ -517,8 +517,8 @@ void ui_draw_menu_back(struct uiStyle *style, uiBlock *block, rcti *rect); uiWidgetColors *ui_tooltip_get_theme(void); void ui_draw_tooltip_background(uiStyle *UNUSED(style), uiBlock * block, rcti * rect); void ui_draw_search_back(struct uiStyle *style, uiBlock *block, rcti *rect); -int ui_link_bezier_points(rcti * rect, float coord_array[][2], int resol); -void ui_draw_link_bezier(rcti *rect); +int ui_link_bezier_points(const rcti * rect, float coord_array[][2], int resol); +void ui_draw_link_bezier(const rcti *rect); extern void ui_draw_but(const struct bContext *C, ARegion *ar, struct uiStyle *style, uiBut *but, rcti *rect); /* theme color init */ diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 9759c22f30e..a15256bc86f 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -65,8 +65,6 @@ #define RNA_NO_INDEX -1 #define RNA_ENUM_VALUE -2 -#define EM_SEPR_X 6 -#define EM_SEPR_Y 6 // #define USE_OP_RESET_BUT // we may want to make this optional, disable for now. @@ -227,14 +225,16 @@ static int ui_layout_vary_direction(uiLayout *layout) /* estimated size of text + icon */ static int ui_text_icon_width(uiLayout *layout, const char *name, int icon, int compact) { + float f5 = 0.25f * UI_UNIT_X; + float f10 = 0.5f * UI_UNIT_X; int variable = ui_layout_vary_direction(layout) == UI_ITEM_VARY_X; if (icon && !name[0]) return UI_UNIT_X; /* icon only */ else if (icon) - return (variable) ? UI_GetStringWidth(name) + (compact ? 5 : 10) + UI_UNIT_X : 10 * UI_UNIT_X; /* icon + text */ + return (variable) ? UI_GetStringWidth(name) + (compact ? f5 : f10) + UI_UNIT_X : 10 * UI_UNIT_X; /* icon + text */ else - return (variable) ? UI_GetStringWidth(name) + (compact ? 5 : 10) + UI_UNIT_X : 10 * UI_UNIT_X; /* text only */ + return (variable) ? UI_GetStringWidth(name) + (compact ? f5 : f10) + UI_UNIT_X : 10 * UI_UNIT_X; /* text only */ } static void ui_item_size(uiItem *item, int *r_w, int *r_h) @@ -718,8 +718,11 @@ static const char *ui_menu_enumpropname(uiLayout *layout, PointerRNA *ptr, Prope int totitem, free; const char *name; - RNA_property_enum_items_gettexted(layout->root->block->evil_C, ptr, prop, &item, &totitem, &free); - if (RNA_enum_name(item, retval, &name) == 0) { + RNA_property_enum_items(layout->root->block->evil_C, ptr, prop, &item, &totitem, &free); + if (RNA_enum_name(item, retval, &name)) { + name = CTX_IFACE_(RNA_property_translation_context(prop), name); + } + else { name = ""; } @@ -904,10 +907,11 @@ void uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char UI_OPERATOR_ERROR_RET(ot, opname, return ); WM_operator_properties_create_ptr(&ptr, ot); - + /* enum lookup */ if ((prop = RNA_struct_find_property(&ptr, propname))) { - RNA_property_enum_items_gettexted(layout->root->block->evil_C, &ptr, prop, &item, NULL, &free); + /* no need for translations here */ + RNA_property_enum_items(layout->root->block->evil_C, &ptr, prop, &item, NULL, &free); if (item == NULL || RNA_enum_value_from_id(item, value_str, &value) == 0) { if (free) { MEM_freeN(item); @@ -924,9 +928,9 @@ void uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char RNA_warning("%s.%s not found", RNA_struct_identifier(ptr.type), propname); return; } - + RNA_property_enum_set(&ptr, prop, value); - + /* same as uiItemEnumO */ if (!name) name = ui_menu_enumpropname(layout, &ptr, prop, value); @@ -1172,7 +1176,7 @@ void uiItemEnumR_string(uiLayout *layout, struct PointerRNA *ptr, const char *pr return; } - RNA_property_enum_items_gettexted(layout->root->block->evil_C, ptr, prop, &item, NULL, &free); + RNA_property_enum_items(layout->root->block->evil_C, ptr, prop, &item, NULL, &free); if (!RNA_enum_value_from_id(item, value, &ivalue)) { if (free) { @@ -1185,7 +1189,9 @@ void uiItemEnumR_string(uiLayout *layout, struct PointerRNA *ptr, const char *pr for (a = 0; item[a].identifier; a++) { if (item[a].value == ivalue) { - uiItemFullR(layout, ptr, prop, RNA_ENUM_VALUE, ivalue, 0, name ? name : item[a].name, icon ? icon : item[a].icon); + const char *item_name = CTX_IFACE_(RNA_property_translation_context(prop), item[a].name); + + uiItemFullR(layout, ptr, prop, RNA_ENUM_VALUE, ivalue, 0, item_name ? item_name : name, icon ? icon : item[a].icon); break; } } @@ -1466,7 +1472,13 @@ static void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt) printf("%s: opening menu \"%s\"\n", __func__, mt->idname); } + if (layout->context) + CTX_store_set(C, layout->context); + mt->draw(C, &menu); + + if (layout->context) + CTX_store_set(C, NULL); } static void ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg, void *argN, const char *tip) @@ -1489,7 +1501,7 @@ static void ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCre h = UI_UNIT_Y; if (layout->root->type == UI_LAYOUT_HEADER) /* ugly .. */ - w -= 10; + w -= UI_UNIT_Y / 2; if (name[0] && icon) but = uiDefIconTextMenuBut(block, func, arg, icon, name, 0, 0, w, h, tip); @@ -1604,7 +1616,7 @@ void uiItemS(uiLayout *layout) uiBlock *block = layout->root->block; uiBlockSetCurLayout(block, layout); - uiDefBut(block, SEPR, 0, "", 0, 0, EM_SEPR_X, EM_SEPR_Y, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, SEPR, 0, "", 0, 0, 0.3f * UI_UNIT_X, 0.3f * UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); } /* level items */ @@ -2935,7 +2947,7 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op, col = uiLayoutColumn(layout, FALSE); block = uiLayoutGetBlock(col); - but = uiDefIconTextBut(block, BUT, 0, ICON_FILE_REFRESH, IFACE_("Reset"), 0, 0, 18, 20, + but = uiDefIconTextBut(block, BUT, 0, ICON_FILE_REFRESH, IFACE_("Reset"), 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Reset operator defaults")); uiButSetFunc(but, ui_layout_operator_buts__reset_cb, op, NULL); } diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 2b170ea546b..5f7ed644894 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -164,15 +164,20 @@ static int panels_re_align(ScrArea *sa, ARegion *ar, Panel **r_pa) /****************************** panels ******************************/ -static void panels_collapse_all(ScrArea *sa, ARegion *ar) +static void panels_collapse_all(ScrArea *sa, ARegion *ar, Panel *from_pa) { Panel *pa; + PanelType *pt, *from_pt; int flag = ((panel_aligned(sa, ar) == BUT_HORIZONTAL) ? PNL_CLOSEDX : PNL_CLOSEDY); for (pa = ar->panels.first; pa; pa = pa->next) { - if (pa->type && !(pa->type->flag & PNL_NO_HEADER)) { - pa->flag = flag; - } + pt = pa->type; + from_pt = from_pa->type; + + /* close panels with headers in the same context */ + if (pt && from_pt && !(pt->flag & PNL_NO_HEADER)) + if (!pt->context[0] || strcmp(pt->context, from_pt->context) == 0) + pa->flag = flag; } } @@ -305,7 +310,7 @@ void uiEndPanel(uiBlock *block, int width, int height) static void ui_offset_panel_block(uiBlock *block) { - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_GetStyleDraw(); uiBut *but; int ofsy; @@ -345,14 +350,18 @@ static void uiPanelPop(uiBlock *UNUSED(block)) /* triangle 'icon' for panel header */ void UI_DrawTriIcon(float x, float y, char dir) { + float f3 = 0.15 * U.widget_unit; + float f5 = 0.25 * U.widget_unit; + float f7 = 0.35 * U.widget_unit; + if (dir == 'h') { - ui_draw_anti_tria(x - 3, y - 5, x - 3, y + 5, x + 7, y); + ui_draw_anti_tria(x - f3, y - f5, x - f3, y + f5, x + f7, y); } else if (dir == 't') { - ui_draw_anti_tria(x - 5, y - 7, x + 5, y - 7, x, y + 3); + ui_draw_anti_tria(x - f5, y - f7, x + f5, y - f7, x, y + f3); } else { /* 'v' = vertical, down */ - ui_draw_anti_tria(x - 5, y + 3, x + 5, y + 3, x, y - 7); + ui_draw_anti_tria(x - f5, y + f3, x + f5, y + f3, x, y - f7); } } @@ -495,7 +504,6 @@ static void rectf_scale(rctf *rect, const float scale) /* panel integrated in buttonswindow, tool/property lists etc */ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect) { - bTheme *btheme = UI_GetTheme(); Panel *panel = block->panel; rcti headrect; rctf itemrect; @@ -517,10 +525,11 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect) glEnable(GL_BLEND); - if (btheme->tui.panel.show_header) { + + if (UI_GetThemeValue(TH_PANEL_SHOW_HEADER)) { /* draw with background color */ glEnable(GL_BLEND); - glColor4ubv((unsigned char *)btheme->tui.panel.header); + UI_ThemeColor4(TH_PANEL_HEADER); glRectf(minx, headrect.ymin + 1, maxx, y); fdrawline(minx, y, maxx, y); @@ -577,6 +586,14 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect) uiRoundRect(0.5f + rect->xmin, 0.5f + rect->ymin, 0.5f + rect->xmax, 0.5f + headrect.ymax + 1, 8); } + /* panel backdrop */ + if (UI_GetThemeValue(TH_PANEL_SHOW_BACK)) { + /* draw with background color */ + glEnable(GL_BLEND); + UI_ThemeColor4(TH_PANEL_BACK); + glRecti(rect->xmin, rect->ymin, rect->xmax, rect->ymax); + } + if (panel->control & UI_PNL_SCALE) ui_draw_panel_scalewidget(rect); } @@ -1016,7 +1033,7 @@ static void ui_do_drag(const bContext *C, wmEvent *event, Panel *panel) /* this function is supposed to call general window drawing too */ /* also it supposes a block has panel, and isn't a menu */ -static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, int my, int event) +static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, int my, int event, int ctrl) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); @@ -1049,6 +1066,9 @@ static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, in ED_region_tag_redraw(ar); } else { /* collapse */ + if(ctrl) + panels_collapse_all(sa, ar, block->panel); + if (block->panel->flag & PNL_CLOSED) { block->panel->flag &= ~PNL_CLOSED; /* snap back up so full panel aligns with screen edge */ @@ -1088,40 +1108,57 @@ static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, in int ui_handler_panel_region(bContext *C, wmEvent *event) { - ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); uiBlock *block; Panel *pa; - int retval, mx, my, inside_header = 0, inside_scale = 0, inside; + int retval, mx, my; retval = WM_UI_HANDLER_CONTINUE; for (block = ar->uiblocks.last; block; block = block->prev) { + int inside = 0, inside_header = 0, inside_scale = 0; + mx = event->x; my = event->y; ui_window_to_block(ar, block, &mx, &my); - /* check if inside boundbox */ - inside = 0; + /* checks for mouse position inside */ pa = block->panel; if (!pa || pa->paneltab != NULL) continue; if (pa->type && pa->type->flag & PNL_NO_HEADER) /* XXX - accessed freed panels when scripts reload, need to fix. */ continue; - - if (block->rect.xmin <= mx && block->rect.xmax >= mx) - if (block->rect.ymin <= my && block->rect.ymax + PNL_HEADER >= my) - inside = 1; + /* clicked at panel header? */ + if (pa->flag & PNL_CLOSEDX) { + if (block->rect.xmin <= mx && block->rect.xmin + PNL_HEADER >= mx) + inside_header = 1; + } + else if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my)) { + inside_header = 1; + } + else if (!(pa->flag & PNL_CLOSEDY)) { + /* open panel */ + if (pa->control & UI_PNL_SCALE) { + if (block->rect.xmax - PNL_HEADER <= mx) + if (block->rect.ymin + PNL_HEADER >= my) + inside_scale = 1; + } + if (block->rect.xmin <= mx && block->rect.xmax >= mx) + if (block->rect.ymin <= my && block->rect.ymax + PNL_HEADER >= my) + inside = 1; + } + + /* XXX hardcoded key warning */ if (inside && event->val == KM_PRESS) { if (event->type == AKEY && !ELEM4(KM_MOD_FIRST, event->ctrl, event->oskey, event->shift, event->alt)) { if (pa->flag & PNL_CLOSEDY) { if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my)) - ui_handle_panel_header(C, block, mx, my, event->type); + ui_handle_panel_header(C, block, mx, my, event->type, event->ctrl); } else - ui_handle_panel_header(C, block, mx, my, event->type); + ui_handle_panel_header(C, block, mx, my, event->type, event->ctrl); continue; } @@ -1131,40 +1168,33 @@ int ui_handler_panel_region(bContext *C, wmEvent *event) if (ui_button_is_active(ar)) continue; - if (inside) { - /* clicked at panel header? */ - if (pa->flag & PNL_CLOSEDX) { - if (block->rect.xmin <= mx && block->rect.xmin + PNL_HEADER >= mx) - inside_header = 1; - } - else if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my)) { - inside_header = 1; - } - else if (pa->control & UI_PNL_SCALE) { - if (block->rect.xmax - PNL_HEADER <= mx) - if (block->rect.ymin + PNL_HEADER >= my) - inside_scale = 1; - } + if (inside || inside_header) { if (event->val == KM_PRESS) { + /* open close on header */ if (ELEM(event->type, RETKEY, PADENTER)) { if (inside_header) { - ui_handle_panel_header(C, block, mx, my, RETKEY); + ui_handle_panel_header(C, block, mx, my, RETKEY, event->ctrl); + retval = WM_UI_HANDLER_BREAK; break; } } else if (event->type == LEFTMOUSE) { + /* all inside clicks should return in break - overlapping/float panels */ + retval = WM_UI_HANDLER_BREAK; + if (inside_header) { - if (event->ctrl) - panels_collapse_all(sa, ar); - ui_handle_panel_header(C, block, mx, my, 0); + ui_handle_panel_header(C, block, mx, my, 0, event->ctrl); + retval = WM_UI_HANDLER_BREAK; break; } else if (inside_scale && !(pa->flag & PNL_CLOSED)) { panel_activate_state(C, pa, PANEL_STATE_DRAG_SCALE); + retval = WM_UI_HANDLER_BREAK; break; } + } else if (event->type == ESCKEY) { /*XXX 2.50*/ diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index c13aadee069..60885f311ca 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -306,8 +306,9 @@ static ARegion *ui_add_temporary_region(bScreen *sc) static void ui_remove_temporary_region(bContext *C, bScreen *sc, ARegion *ar) { - if (CTX_wm_window(C)) - wm_draw_region_clear(CTX_wm_window(C), ar); + wmWindow *win = CTX_wm_window(C); + if (win) + wm_draw_region_clear(win, ar); ED_region_exit(C, ar); BKE_area_region_free(NULL, ar); /* NULL: no spacetype */ @@ -416,6 +417,7 @@ static void ui_tooltip_region_free_cb(ARegion *ar) ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) { + wmWindow *win = CTX_wm_window(C); uiStyle *style = UI_GetStyle(); static ARegionType type; ARegion *ar; @@ -423,7 +425,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) /* IDProperty *prop;*/ char buf[512]; float fonth, fontw, aspect = but->block->aspect; - int winx, winy, ofsx, ofsy, w, h, a; + int winx /*, winy */, ofsx, ofsy, w, h, a; rctf rect_fl; rcti rect_i; @@ -565,7 +567,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) char *data_path = NULL; /* never fails */ - id_path = RNA_path_from_ID_python(id); + id_path = RNA_path_full_ID_py(id); if (ptr->id.data && ptr->data && prop) { data_path = RNA_path_from_ID_to_property(ptr, prop); @@ -622,12 +624,14 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) /* set font, get bb */ data->fstyle = style->widget; /* copy struct */ data->fstyle.align = UI_STYLE_TEXT_CENTER; + ui_fontscale(&data->fstyle.points, aspect); + uiStyleFontSet(&data->fstyle); - /* these defines may need to be tweaked depending on font */ -#define TIP_MARGIN_Y 2 -#define TIP_BORDER_X 16.0f -#define TIP_BORDER_Y 6.0f + /* these defines tweaked depending on font */ +#define TIP_MARGIN_Y (2.0f / aspect) +#define TIP_BORDER_X (16.0f / aspect) +#define TIP_BORDER_Y (6.0f / aspect) h = BLF_height_max(data->fstyle.uifont_id); @@ -637,7 +641,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) fonth += (a == 0) ? h : h + TIP_MARGIN_Y; } - fontw *= aspect; + //fontw *= aspect; ar->regiondata = data; @@ -645,34 +649,30 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) data->lineh = h; data->spaceh = TIP_MARGIN_Y; - /* compute position */ - ofsx = (but->block->panel) ? but->block->panel->ofsx : 0; - ofsy = (but->block->panel) ? but->block->panel->ofsy : 0; + ofsx = 0; //(but->block->panel) ? but->block->panel->ofsx : 0; + ofsy = 0; //(but->block->panel) ? but->block->panel->ofsy : 0; + + rect_fl.xmin = (but->rect.xmin + but->rect.xmax) * 0.5f + ofsx - (TIP_BORDER_X ); + rect_fl.xmax = rect_fl.xmin + fontw + (TIP_BORDER_X ); + rect_fl.ymax = but->rect.ymin + ofsy - (TIP_BORDER_Y ); + rect_fl.ymin = rect_fl.ymax - fonth - (TIP_BORDER_Y ); - rect_fl.xmin = (but->rect.xmin + but->rect.xmax) * 0.5f + ofsx - (TIP_BORDER_X * aspect); - rect_fl.xmax = rect_fl.xmin + fontw + (TIP_BORDER_X * aspect); - rect_fl.ymax = but->rect.ymin + ofsy - (TIP_BORDER_Y * aspect); - rect_fl.ymin = rect_fl.ymax - fonth * aspect - (TIP_BORDER_Y * aspect); - #undef TIP_MARGIN_Y #undef TIP_BORDER_X #undef TIP_BORDER_Y - - /* copy to int, gets projected if possible too */ - BLI_rcti_rctf_copy(&rect_i, &rect_fl); + /* since the text has beens caled already, the size of tooltips is defined now */ + /* here we try to figure out the right location */ if (butregion) { - /* XXX temp, region v2ds can be empty still */ - if (butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) { - UI_view2d_to_region_no_clip(&butregion->v2d, rect_fl.xmin, rect_fl.ymin, &rect_i.xmin, &rect_i.ymin); - UI_view2d_to_region_no_clip(&butregion->v2d, rect_fl.xmax, rect_fl.ymax, &rect_i.xmax, &rect_i.ymax); - } - - BLI_rcti_translate(&rect_i, butregion->winrct.xmin, butregion->winrct.ymin); + float ofsx = rect_fl.xmin, ofsy = rect_fl.ymax; + ui_block_to_window_fl(butregion, but->block, &ofsx, &ofsy); + BLI_rctf_translate(&rect_fl, ofsx - rect_fl.xmin, ofsy - rect_fl.ymax); } + BLI_rcti_rctf_copy(&rect_i, &rect_fl); - wm_window_get_size(CTX_wm_window(C), &winx, &winy); + /* clip with window boundaries */ + winx = WM_window_pixels_x(win); if (rect_i.xmax > winx) { /* super size */ @@ -1097,6 +1097,7 @@ static void ui_searchbox_region_free_cb(ARegion *ar) ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) { + wmWindow *win = CTX_wm_window(C); uiStyle *style = UI_GetStyle(); static ARegionType type; ARegion *ar; @@ -1104,7 +1105,7 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) float aspect = but->block->aspect; rctf rect_fl; rcti rect_i; - int winx, winy, ofsx, ofsy; + int winx /*, winy */, ofsx, ofsy; int i; /* create area region */ @@ -1185,7 +1186,9 @@ ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but) BLI_rcti_translate(&rect_i, butregion->winrct.xmin, butregion->winrct.ymin); - wm_window_get_size(CTX_wm_window(C), &winx, &winy); + winx = WM_window_pixels_x(win); + // winy = WM_window_pixels_y(win); /* UNUSED */ + //wm_window_get_size(win, &winx, &winy); if (rect_i.xmax > winx) { /* super size */ @@ -1314,11 +1317,11 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, /* widget_roundbox_set has this correction too, keep in sync */ if (but->type != PULLDOWN) { if (but->flag & UI_BUT_ALIGN_TOP) - butrct.ymax += 1.0f; + butrct.ymax += U.pixelsize; if (but->flag & UI_BUT_ALIGN_LEFT) - butrct.xmin -= 1.0f; + butrct.xmin -= U.pixelsize; } - + /* calc block rect */ if (block->rect.xmin == 0.0f && block->rect.xmax == 0.0f) { if (block->buttons.first) { @@ -1334,7 +1337,7 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, block->rect.xmax = block->rect.ymax = 20; } } - + /* aspect = (float)(BLI_rcti_size_x(&block->rect) + 4);*/ /*UNUSED*/ ui_block_to_window_fl(butregion, but->block, &block->rect.xmin, &block->rect.ymin); ui_block_to_window_fl(butregion, but->block, &block->rect.xmax, &block->rect.ymax); @@ -1342,8 +1345,8 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, //block->rect.xmin -= 2.0; block->rect.ymin -= 2.0; //block->rect.xmax += 2.0; block->rect.ymax += 2.0; - xsize = BLI_rctf_size_x(&block->rect) + 4; /* 4 for shadow */ - ysize = BLI_rctf_size_y(&block->rect) + 4; + xsize = BLI_rctf_size_x(&block->rect) + 0.2f * UI_UNIT_X; /* 4 for shadow */ + ysize = BLI_rctf_size_y(&block->rect) + 0.2f * UI_UNIT_Y; /* aspect /= (float)xsize;*/ /*UNUSED*/ { @@ -1351,7 +1354,9 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, int winx, winy; // int offscreen; - wm_window_get_size(window, &winx, &winy); + winx = WM_window_pixels_x(window); + winy = WM_window_pixels_y(window); + // wm_window_get_size(window, &winx, &winy); if (block->direction & UI_CENTER) center = ysize / 2; else center = 0; @@ -1523,7 +1528,9 @@ static void ui_popup_block_clip(wmWindow *window, uiBlock *block) return; } - wm_window_get_size(window, &winx, &winy); + winx = WM_window_pixels_x(window); + winy = WM_window_pixels_y(window); + // wm_window_get_size(window, &winx, &winy); if (block->rect.xmin < MENU_SHADOW_SIDE) block->rect.xmin = MENU_SHADOW_SIDE; @@ -1635,7 +1642,6 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut /* if this is being created from a button */ if (but) { block->aspect = but->block->aspect; - ui_block_position(window, butregion, but, block); handle->direction = block->direction; } @@ -2019,10 +2025,10 @@ static void do_picker_new_mode_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(a picker_new_hide_reveal(bt->block, colormode); } -#define PICKER_H 150 -#define PICKER_W 150 -#define PICKER_SPACE 6 -#define PICKER_BAR 14 +#define PICKER_H (7.5f * U.widget_unit) +#define PICKER_W (7.5f * U.widget_unit) +#define PICKER_SPACE (0.3f * U.widget_unit) +#define PICKER_BAR (0.7f * U.widget_unit) #define PICKER_TOTAL_W (PICKER_W + PICKER_SPACE + PICKER_BAR) @@ -2031,11 +2037,11 @@ static void circle_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop) uiBut *bt; /* HS circle */ - bt = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, prop, 0, 0.0, 0.0, 0, 0, "Color"); + bt = uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, prop, -1, 0.0, 0.0, 0, 0, "Color"); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); /* value */ - bt = uiDefButR_prop(block, HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, ptr, prop, 0, 0.0, 0.0, UI_GRAD_V_ALT, 0, "Value"); + bt = uiDefButR_prop(block, HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H, ptr, prop, -1, 0.0, 0.0, UI_GRAD_V_ALT, 0, "Value"); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); } @@ -2046,11 +2052,11 @@ static void square_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, in int bartype = type + 3; /* HS square */ - bt = uiDefButR_prop(block, HSVCUBE, 0, "", 0, PICKER_BAR + PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, prop, 0, 0.0, 0.0, type, 0, "Color"); + bt = uiDefButR_prop(block, HSVCUBE, 0, "", 0, PICKER_BAR + PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, prop, -1, 0.0, 0.0, type, 0, "Color"); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); /* value */ - bt = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, prop, 0, 0.0, 0.0, bartype, 0, "Value"); + bt = uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, prop, -1, 0.0, 0.0, bartype, 0, "Value"); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); } @@ -2066,11 +2072,12 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper float rgb_gamma[3]; float min, max, step, precision; float *hsv = ui_block_hsv_get(block); + int yco; ui_block_hsv_get(block); width = PICKER_TOTAL_W; - butwidth = width - UI_UNIT_X - 10; + butwidth = width - 1.5f * UI_UNIT_X; /* existence of profile means storage is in linear color space, with display correction */ /* XXX That tip message is not use anywhere! */ @@ -2108,44 +2115,47 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper } /* mode */ + yco = -1.5f * UI_UNIT_Y; uiBlockBeginAlign(block); - bt = uiDefButS(block, ROW, 0, IFACE_("RGB"), 0, -30, width / 3, UI_UNIT_Y, &colormode, 0.0, 0.0, 0, 0, ""); + bt = uiDefButS(block, ROW, 0, IFACE_("RGB"), 0, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 0.0, 0, 0, ""); uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL); - bt = uiDefButS(block, ROW, 0, IFACE_("HSV"), width / 3, -30, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, ""); + bt = uiDefButS(block, ROW, 0, IFACE_("HSV"), width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, ""); uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL); - bt = uiDefButS(block, ROW, 0, IFACE_("Hex"), 2 * width / 3, -30, width / 3, UI_UNIT_Y, &colormode, 0.0, 2.0, 0, 0, ""); + bt = uiDefButS(block, ROW, 0, IFACE_("Hex"), 2 * width / 3, yco, width / 3, UI_UNIT_Y, &colormode, 0.0, 2.0, 0, 0, ""); uiButSetFunc(bt, do_picker_new_mode_cb, bt, NULL); uiBlockEndAlign(block); + yco = -3.0f * UI_UNIT_Y; if (show_picker) { - bt = uiDefIconButO(block, BUT, "UI_OT_eyedropper", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, butwidth + 10, -60, UI_UNIT_X, UI_UNIT_Y, NULL); + bt = uiDefIconButO(block, BUT, "UI_OT_eyedropper", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, butwidth + 10, yco, UI_UNIT_X, UI_UNIT_Y, NULL); uiButSetFunc(bt, close_popup_cb, bt, NULL); } /* RGB values */ uiBlockBeginAlign(block); - bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("R "), 0, -60, butwidth, UI_UNIT_Y, ptr, prop, 0, 0.0, 0.0, 0, 3, TIP_("Red")); + bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("R "), 0, yco, butwidth, UI_UNIT_Y, ptr, prop, 0, 0.0, 0.0, 0, 3, TIP_("Red")); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); - bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("G "), 0, -80, butwidth, UI_UNIT_Y, ptr, prop, 1, 0.0, 0.0, 0, 3, TIP_("Green")); + bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("G "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 1, 0.0, 0.0, 0, 3, TIP_("Green")); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); - bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("B "), 0, -100, butwidth, UI_UNIT_Y, ptr, prop, 2, 0.0, 0.0, 0, 3, TIP_("Blue")); + bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("B "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 2, 0.0, 0.0, 0, 3, TIP_("Blue")); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); /* could use uiItemFullR(col, ptr, prop, -1, 0, UI_ITEM_R_EXPAND|UI_ITEM_R_SLIDER, "", ICON_NONE); * but need to use uiButSetFunc for updating other fake buttons */ /* HSV values */ + yco = -3.0f * UI_UNIT_Y; uiBlockBeginAlign(block); - bt = uiDefButF(block, NUMSLI, 0, IFACE_("H "), 0, -60, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, TIP_("Hue")); + bt = uiDefButF(block, NUMSLI, 0, IFACE_("H "), 0, yco, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, TIP_("Hue")); uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv); - bt = uiDefButF(block, NUMSLI, 0, IFACE_("S "), 0, -80, butwidth, UI_UNIT_Y, hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation")); + bt = uiDefButF(block, NUMSLI, 0, IFACE_("S "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation")); uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv); - bt = uiDefButF(block, NUMSLI, 0, IFACE_("V "), 0, -100, butwidth, UI_UNIT_Y, hsv + 2, 0.0, max, 10, 3, TIP_("Value")); + bt = uiDefButF(block, NUMSLI, 0, IFACE_("V "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, max, 10, 3, TIP_("Value")); uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv); uiBlockEndAlign(block); if (rgba[3] != FLT_MAX) { - bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("A "), 0, -120, butwidth, UI_UNIT_Y, ptr, prop, 3, 0.0, 0.0, 0, 0, TIP_("Alpha")); + bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("A "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 3, 0.0, 0.0, 0, 0, TIP_("Alpha")); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); } else { @@ -2154,9 +2164,10 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper BLI_snprintf(hexcol, sizeof(hexcol), "%02X%02X%02X", FTOCHAR(rgb_gamma[0]), FTOCHAR(rgb_gamma[1]), FTOCHAR(rgb_gamma[2])); - bt = uiDefBut(block, TEX, 0, IFACE_("Hex: "), 0, -60, butwidth, UI_UNIT_Y, hexcol, 0, 8, 0, 0, TIP_("Hex triplet for color (#RRGGBB)")); + yco = -3.0f * UI_UNIT_Y; + bt = uiDefBut(block, TEX, 0, IFACE_("Hex: "), 0, yco, butwidth, UI_UNIT_Y, hexcol, 0, 8, 0, 0, TIP_("Hex triplet for color (#RRGGBB)")); uiButSetFunc(bt, do_hex_rna_cb, bt, hexcol); - uiDefBut(block, LABEL, 0, IFACE_("(Gamma Corrected)"), 0, -80, butwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 0, IFACE_("(Gamma Corrected)"), 0, yco - UI_UNIT_Y, butwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); rgb_to_hsv_v(rgba, hsv); @@ -2228,7 +2239,7 @@ uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_ uiBlockPicker(block, handle->retvec, &but->rnapoin, but->rnaprop, show_picker); block->flag = UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_KEEP_OPEN | UI_BLOCK_OUT_1 | UI_BLOCK_MOVEMOUSE_QUIT; - uiBoundsBlock(block, 10); + uiBoundsBlock(block, 0.5 * UI_UNIT_X); block->block_event_func = ui_picker_small_wheel_cb; @@ -2240,7 +2251,7 @@ uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_ /************************ Popup Menu Memory ****************************/ -static int ui_popup_string_hash(char *str) +static int ui_popup_string_hash(const char *str) { /* sometimes button contains hotkey, sometimes not, strip for proper compare */ int hash; @@ -2386,7 +2397,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi } block->minbounds = minwidth; - uiTextBoundsBlock(block, 50); + uiTextBoundsBlock(block, 2.5 * UI_UNIT_X); } /* if menu slides out of other menu, override direction */ @@ -2402,7 +2413,7 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut uiMenuCreateFunc menu_func, void *arg, char *str) { wmWindow *window = CTX_wm_window(C); - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_GetStyleDraw(); uiPopupBlockHandle *handle; uiPopupMenu *pup; pup = MEM_callocN(sizeof(uiPopupMenu), __func__); @@ -2466,7 +2477,7 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut /* only return handler, and set optional title */ uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon) { - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_GetStyleDraw(); uiPopupMenu *pup = MEM_callocN(sizeof(uiPopupMenu), "popup menu"); uiBut *but; diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c index 7e7db6aeaaa..ef24ea951e3 100644 --- a/source/blender/editors/interface/interface_style.c +++ b/source/blender/editors/interface/interface_style.c @@ -143,7 +143,7 @@ static uiFont *uifont_to_blfont(int id) /* *************** draw ************************ */ -void uiStyleFontDrawExt(uiFontStyle *fs, rcti *rect, const char *str, +void uiStyleFontDrawExt(uiFontStyle *fs, const rcti *rect, const char *str, float *r_xofs, float *r_yofs) { float height; @@ -166,7 +166,7 @@ void uiStyleFontDrawExt(uiFontStyle *fs, rcti *rect, const char *str, } /* clip is very strict, so we give it some space */ - BLF_clipping(fs->uifont_id, rect->xmin - 1, rect->ymin - 4, rect->xmax + 1, rect->ymax + 4); + BLF_clipping(fs->uifont_id, rect->xmin - 2, rect->ymin - 4, rect->xmax + 1, rect->ymax + 4); BLF_enable(fs->uifont_id, BLF_CLIPPING); BLF_position(fs->uifont_id, rect->xmin + xofs, rect->ymin + yofs, 0.0f); @@ -261,6 +261,32 @@ uiStyle *UI_GetStyle(void) return (style != NULL) ? style : U.uistyles.first; } +/* for drawing, scaled with DPI setting */ +uiStyle *UI_GetStyleDraw(void) +{ + uiStyle *style = UI_GetStyle(); + static uiStyle _style; + + _style = *style; + + _style.paneltitle.shadx = (short)(UI_DPI_FAC * _style.paneltitle.shadx); + _style.paneltitle.shady = (short)(UI_DPI_FAC * _style.grouplabel.shady); + _style.grouplabel.shadx = (short)(UI_DPI_FAC * _style.grouplabel.shadx); + _style.grouplabel.shady = (short)(UI_DPI_FAC * _style.paneltitle.shady); + _style.widgetlabel.shadx = (short)(UI_DPI_FAC * _style.widgetlabel.shadx); + _style.widgetlabel.shady = (short)(UI_DPI_FAC * _style.widgetlabel.shady); + + _style.columnspace = (short)(UI_DPI_FAC * _style.columnspace); + _style.templatespace = (short)(UI_DPI_FAC * _style.templatespace); + _style.boxspace = (short)(UI_DPI_FAC * _style.boxspace); + _style.buttonspacex = (short)(UI_DPI_FAC * _style.buttonspacex); + _style.buttonspacey = (short)(UI_DPI_FAC * _style.buttonspacey); + _style.panelspace = (short)(UI_DPI_FAC * _style.panelspace); + _style.panelouter = (short)(UI_DPI_FAC * _style.panelouter); + + return &_style; +} + /* temporarily, does widget font */ int UI_GetStringWidth(const char *str) { @@ -364,9 +390,9 @@ void uiStyleInit(void) * Yes, this build the glyph cache and create * the texture. */ - BLF_size(font->blf_id, 11, U.dpi); - BLF_size(font->blf_id, 12, U.dpi); - BLF_size(font->blf_id, 14, U.dpi); + BLF_size(font->blf_id, 11 * U.pixelsize, U.dpi); + BLF_size(font->blf_id, 12 * U.pixelsize, U.dpi); + BLF_size(font->blf_id, 14 * U.pixelsize, U.dpi); } } @@ -378,19 +404,19 @@ void uiStyleInit(void) if (blf_mono_font == -1) blf_mono_font = BLF_load_mem_unique("monospace", (unsigned char *)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size); - BLF_size(blf_mono_font, 12, 72); + BLF_size(blf_mono_font, 12 * U.pixelsize, 72); /* second for rendering else we get threading problems */ if (blf_mono_font_render == -1) blf_mono_font_render = BLF_load_mem_unique("monospace", (unsigned char *)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size); - BLF_size(blf_mono_font_render, 12, 72); + BLF_size(blf_mono_font_render, 12 * U.pixelsize, 72 ); } void uiStyleFontSet(uiFontStyle *fs) { uiFont *font = uifont_to_blfont(fs->uifont_id); - BLF_size(font->blf_id, fs->points, U.dpi); + BLF_size(font->blf_id, fs->points * U.pixelsize, U.dpi); } diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 2b8ee10af1a..456a8a95a58 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -179,13 +179,13 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem) /* preview thumbnails */ if (template.prv_rows > 0 && template.prv_cols > 0) { - int w = 96 * template.prv_cols; - int h = 96 * template.prv_rows + 20; + int w = 4 * U.widget_unit * template.prv_cols; + int h = 4 * U.widget_unit * template.prv_rows + U.widget_unit; /* fake button, it holds space for search items */ uiDefBut(block, LABEL, 0, "", 10, 15, w, h, NULL, 0, 0, 0, 0, NULL); - but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, 19, + but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, UI_UNIT_Y, template.prv_rows, template.prv_cols, ""); uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data); } @@ -193,15 +193,15 @@ static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem) else { const int searchbox_width = uiSearchBoxWidth(); const int searchbox_height = uiSearchBoxHeight(); + /* fake button, it holds space for search items */ uiDefBut(block, LABEL, 0, "", 10, 15, searchbox_width, searchbox_height, NULL, 0, 0, 0, 0, NULL); - but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, searchbox_width, UI_UNIT_Y - 1, 0, 0, ""); uiButSetSearchFunc(but, id_search_cb, &template, id_search_call_cb, idptr.data); } - uiBoundsBlock(block, 6); + uiBoundsBlock(block, 0.3f * U.widget_unit); uiBlockSetDirection(block, UI_DOWN); uiEndBlock(C, block); @@ -348,6 +348,7 @@ static const char *template_id_browse_tip(StructRNA *type) /* Return a type-based i18n context, needed e.g. by "New" button. * In most languages, this adjective takes different form based on gender of type name... */ +#ifdef WITH_INTERNATIONAL static const char *template_id_context(StructRNA *type) { if (type) { @@ -379,6 +380,7 @@ static const char *template_id_context(StructRNA *type) } return BLF_I18NCONTEXT_DEFAULT; } +#endif static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, short idcode, int flag, const char *newop, const char *openop, const char *unlinkop) @@ -389,7 +391,6 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str // ListBase *lb; // UNUSED ID *id, *idfrom; int editable = RNA_property_editable(&template->ptr, template->prop); - const char *i18n_ctxt = template_id_context(type); idptr = RNA_property_pointer_get(&template->ptr, template->prop); id = idptr.data; @@ -521,11 +522,11 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str if (newop) { but = uiDefIconTextButO(block, BUT, newop, WM_OP_INVOKE_DEFAULT, ICON_ZOOMIN, - (id) ? "" : CTX_IFACE_(i18n_ctxt, "New"), 0, 0, w, UI_UNIT_Y, NULL); + (id) ? "" : CTX_IFACE_(template_id_context(type), "New"), 0, 0, w, UI_UNIT_Y, NULL); uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW)); } else { - but = uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, (id) ? "" : CTX_IFACE_(i18n_ctxt, "New"), + but = uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, (id) ? "" : CTX_IFACE_(template_id_context(type), "New"), 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW)); } @@ -1440,7 +1441,7 @@ static void colorband_buttons_large(uiLayout *layout, uiBlock *block, ColorBand const int line2_y = yoffs + 65; if (coba == NULL) return; - + bt = uiDefBut(block, BUT, 0, IFACE_("Add"), 0 + xoffs, line1_y, 40, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Add a new color stop to the colorband")); uiButSetNFunc(bt, colorband_add_cb, MEM_dupallocN(cb), coba); @@ -1550,8 +1551,8 @@ void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname cb->ptr = *ptr; cb->prop = prop; - rect.xmin = 0; rect.xmax = 200; - rect.ymin = 0; rect.ymax = 190; + rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X; + rect.ymin = 0; rect.ymax = 19.5f * UI_UNIT_X; block = uiLayoutAbsoluteBlock(layout); colorband_buttons_layout(layout, block, cptr.data, &rect, !expand, cb); @@ -1582,8 +1583,8 @@ void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname cb->ptr = *ptr; cb->prop = prop; - rect.xmin = 0; rect.xmax = 200; - rect.ymin = 0; rect.ymax = 190; + rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X; + rect.ymin = 0; rect.ymax = 9.5f * UI_UNIT_Y; block = uiLayoutAbsoluteBlock(layout); //colorband_buttons_layout(layout, block, cptr.data, &rect, !expand, cb); @@ -1592,8 +1593,9 @@ void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname hist->height = (hist->height <= UI_UNIT_Y) ? UI_UNIT_Y : hist->height; - bt = uiDefBut(block, HISTOGRAM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), hist->height, hist, - 0, 0, 0, 0, ""); + bt = uiDefBut(block, HISTOGRAM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), UI_DPI_FAC * hist->height, + hist, 0, 0, 0, 0, ""); + uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); MEM_freeN(cb); @@ -1623,15 +1625,15 @@ void uiTemplateWaveform(uiLayout *layout, PointerRNA *ptr, const char *propname) cb->ptr = *ptr; cb->prop = prop; - rect.xmin = 0; rect.xmax = 200; - rect.ymin = 0; rect.ymax = 190; + rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X; + rect.ymin = 0; rect.ymax = 9.5f * UI_UNIT_Y; block = uiLayoutAbsoluteBlock(layout); scopes->wavefrm_height = (scopes->wavefrm_height <= UI_UNIT_Y) ? UI_UNIT_Y : scopes->wavefrm_height; - bt = uiDefBut(block, WAVEFORM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), scopes->wavefrm_height, scopes, - 0, 0, 0, 0, ""); + bt = uiDefBut(block, WAVEFORM, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), UI_DPI_FAC * scopes->wavefrm_height, + scopes, 0, 0, 0, 0, ""); (void)bt; /* UNUSED */ MEM_freeN(cb); @@ -1661,15 +1663,15 @@ void uiTemplateVectorscope(uiLayout *layout, PointerRNA *ptr, const char *propna cb->ptr = *ptr; cb->prop = prop; - rect.xmin = 0; rect.xmax = 200; - rect.ymin = 0; rect.ymax = 190; + rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X; + rect.ymin = 0; rect.ymax = 9.5f * UI_UNIT_Y; block = uiLayoutAbsoluteBlock(layout); scopes->vecscope_height = (scopes->vecscope_height <= UI_UNIT_Y) ? UI_UNIT_Y : scopes->vecscope_height; bt = uiDefBut(block, VECTORSCOPE, 0, "", rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), - scopes->vecscope_height, scopes, 0, 0, 0, 0, ""); + UI_DPI_FAC * scopes->vecscope_height, scopes, 0, 0, 0, 0, ""); uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); MEM_freeN(cb); @@ -2013,7 +2015,7 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe /* curve itself */ size = uiLayoutGetWidth(layout); row = uiLayoutRow(layout, FALSE); - uiDefBut(block, BUT_CURVE, 0, "", 0, 0, size, MIN2(size, 200), cumap, 0.0f, 1.0f, bg, 0, ""); + uiDefBut(block, BUT_CURVE, 0, "", 0, 0, size, MIN2(size, 10.0f * UI_UNIT_X), cumap, 0.0f, 1.0f, bg, 0, ""); /* sliders for selected point */ for (i = 0; i < cm->totpoint; i++) { @@ -2084,7 +2086,7 @@ void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, const char *propn /********************* ColorPicker Template ************************/ -#define WHEEL_SIZE 100 +#define WHEEL_SIZE (5 * U.widget_unit) /* This template now follows User Preference for type - name is not correct anymore... */ void uiTemplateColorPicker(uiLayout *layout, PointerRNA *ptr, const char *propname, int value_slider, diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index d363609fbd9..7c84784c46b 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -78,7 +78,7 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind if (arraylen && index == -1) { if (ELEM(RNA_property_subtype(prop), PROP_COLOR, PROP_COLOR_GAMMA)) - but = uiDefButR_prop(block, COLOR, 0, name, x1, y1, x2, y2, ptr, prop, 0, 0, 0, -1, -1, NULL); + but = uiDefButR_prop(block, COLOR, 0, name, x1, y1, x2, y2, ptr, prop, -1, 0, 0, -1, -1, NULL); } else if (RNA_property_subtype(prop) == PROP_PERCENTAGE || RNA_property_subtype(prop) == PROP_FACTOR) but = uiDefButR_prop(block, NUMSLI, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL); diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index c4b80f0a42f..e5b26148be5 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -119,7 +119,7 @@ typedef struct uiWidgetType { void (*state)(struct uiWidgetType *, int state); void (*draw)(uiWidgetColors *, rcti *, int state, int roundboxalign); void (*custom)(uiBut *, uiWidgetColors *, rcti *, int state, int roundboxalign); - void (*text)(uiFontStyle *, uiWidgetColors *, uiBut *, rcti *); + void (*text)(uiFontStyle *, uiWidgetColors *, uiBut *, rcti *); } uiWidgetType; @@ -251,7 +251,7 @@ static void widget_init(uiWidgetBase *wtb) /* helper call, makes shadow rect, with 'sun' above menu, so only shadow to left/right/bottom */ /* return tot */ -static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int roundboxalign, float step) +static int round_box_shadow_edges(float (*vert)[2], const rcti *rect, float rad, int roundboxalign, float step) { float vec[WIDGET_CURVE_RESOLU][2]; float minx, miny, maxx, maxy; @@ -329,14 +329,14 @@ static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int r } /* this call has 1 extra arg to allow mask outline */ -static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, float rad, float radi) +static void round_box__edges(uiWidgetBase *wt, int roundboxalign, const rcti *rect, float rad, float radi) { float vec[WIDGET_CURVE_RESOLU][2], veci[WIDGET_CURVE_RESOLU][2]; float minx = rect->xmin, miny = rect->ymin, maxx = rect->xmax, maxy = rect->ymax; - float minxi = minx + 1.0f; /* boundbox inner */ - float maxxi = maxx - 1.0f; - float minyi = miny + 1.0f; - float maxyi = maxy - 1.0f; + float minxi = minx + U.pixelsize; /* boundbox inner */ + float maxxi = maxx - U.pixelsize; + float minyi = miny + U.pixelsize; + float maxyi = maxy - U.pixelsize; float facxi = (maxxi != minxi) ? 1.0f / (maxxi - minxi) : 0.0f; /* for uv, can divide by zero */ float facyi = (maxyi != minyi) ? 1.0f / (maxyi - minyi) : 0.0f; int a, tot = 0, minsize; @@ -352,7 +352,7 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl rad = 0.5f * minsize; if (2.0f * (radi + 1.0f) > minsize) - radi = 0.5f * minsize - 1.0f; + radi = 0.5f * minsize - U.pixelsize; /* mult */ for (a = 0; a < WIDGET_CURVE_RESOLU; a++) { @@ -479,14 +479,14 @@ static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, fl wt->totvert = tot; } -static void round_box_edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, float rad) +static void round_box_edges(uiWidgetBase *wt, int roundboxalign, const rcti *rect, float rad) { - round_box__edges(wt, roundboxalign, rect, rad, rad - 1.0f); + round_box__edges(wt, roundboxalign, rect, rad, rad - U.pixelsize); } /* based on button rect, return scaled array of triangles */ -static void widget_num_tria(uiWidgetTrias *tria, rcti *rect, float triasize, char where) +static void widget_num_tria(uiWidgetTrias *tria, const rcti *rect, float triasize, char where) { float centx, centy, sizex, sizey, minsize; int a, i1 = 0, i2 = 1; @@ -521,7 +521,7 @@ static void widget_num_tria(uiWidgetTrias *tria, rcti *rect, float triasize, cha tria->index = num_tria_face; } -static void widget_scroll_circle(uiWidgetTrias *tria, rcti *rect, float triasize, char where) +static void widget_scroll_circle(uiWidgetTrias *tria, const rcti *rect, float triasize, char where) { float centx, centy, sizex, sizey, minsize; int a, i1 = 0, i2 = 1; @@ -564,21 +564,16 @@ static void widget_trias_draw(uiWidgetTrias *tria) glDisableClientState(GL_VERTEX_ARRAY); } -static void widget_menu_trias(uiWidgetTrias *tria, rcti *rect) +static void widget_menu_trias(uiWidgetTrias *tria, const rcti *rect) { - float centx, centy, size, asp; + float centx, centy, size; int a; /* center position and size */ - centx = rect->xmax - 0.5f * BLI_rcti_size_y(rect); - centy = rect->ymin + 0.5f * BLI_rcti_size_y(rect); + centx = rect->xmax - 0.32f * BLI_rcti_size_y(rect); + centy = rect->ymin + 0.50f * BLI_rcti_size_y(rect); size = 0.4f * (float)BLI_rcti_size_y(rect); - /* XXX exception */ - asp = ((float)BLI_rcti_size_x(rect)) / ((float)BLI_rcti_size_y(rect)); - if (asp > 1.2f && asp < 2.6f) - centx = rect->xmax - 0.4f * (float)BLI_rcti_size_y(rect); - for (a = 0; a < 6; a++) { tria->vec[a][0] = size * menu_tria_vert[a][0] + centx; tria->vec[a][1] = size * menu_tria_vert[a][1] + centy; @@ -588,7 +583,7 @@ static void widget_menu_trias(uiWidgetTrias *tria, rcti *rect) tria->index = menu_tria_face; } -static void widget_check_trias(uiWidgetTrias *tria, rcti *rect) +static void widget_check_trias(uiWidgetTrias *tria, const rcti *rect) { float centx, centy, size; int a; @@ -833,7 +828,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) #define PREVIEW_PAD 4 -static void widget_draw_preview(BIFIconID icon, float UNUSED(alpha), rcti *rect) +static void widget_draw_preview(BIFIconID icon, float UNUSED(alpha), const rcti *rect) { int w, h, size; @@ -861,9 +856,9 @@ static int ui_but_draw_menu_icon(uiBut *but) /* icons have been standardized... and this call draws in untransformed coordinates */ -static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect) +static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, const rcti *rect) { - int xs = 0, ys = 0; + float xs = 0.0f, ys = 0.0f; float aspect, height; if (but->flag & UI_ICON_PREVIEW) { @@ -874,20 +869,8 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect /* this icon doesn't need draw... */ if (icon == ICON_BLANK1 && (but->flag & UI_ICON_SUBMENU) == 0) return; - /* we need aspect from block, for menus... these buttons are scaled in uiPositionBlock() */ - aspect = but->block->aspect; - if (aspect != but->aspect) { - /* prevent scaling up icon in pupmenu */ - if (aspect < 1.0f) { - height = UI_DPI_ICON_SIZE; - aspect = 1.0f; - - } - else - height = UI_DPI_ICON_SIZE / aspect; - } - else - height = UI_DPI_ICON_SIZE; + aspect = but->block->aspect / UI_DPI_FAC; + height = ICON_DEFAULT_HEIGHT / aspect; /* calculate blend color */ if (ELEM4(but->type, TOG, ROW, TOGN, LISTROW)) { @@ -902,34 +885,36 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect glEnable(GL_BLEND); if (icon && icon != ICON_BLANK1) { + float ofs = 1.0f / aspect; + if (but->flag & UI_ICON_LEFT) { if (but->type == BUT_TOGDUAL) { if (but->drawstr[0]) { - xs = rect->xmin - 1; + xs = rect->xmin - ofs; } else { - xs = (rect->xmin + rect->xmax - height) / 2; + xs = (rect->xmin + rect->xmax - height) / 2.0f; } } else if (but->block->flag & UI_BLOCK_LOOP) { if (but->type == SEARCH_MENU) - xs = rect->xmin + 4; + xs = rect->xmin + 4.0f * ofs; else - xs = rect->xmin + 1; + xs = rect->xmin + ofs; } else if ((but->type == ICONROW) || (but->type == ICONTEXTROW)) { - xs = rect->xmin + 3; + xs = rect->xmin + 3.0f * ofs; } else { - xs = rect->xmin + 4; + xs = rect->xmin + 4.0f * ofs; } - ys = (rect->ymin + rect->ymax - height) / 2; + ys = (rect->ymin + rect->ymax - height) / 2.0f; } else { - xs = (rect->xmin + rect->xmax - height) / 2; - ys = (rect->ymin + rect->ymax - height) / 2; + xs = (rect->xmin + rect->xmax - height) / 2.0f; + ys = (rect->ymin + rect->ymax - height) / 2.0f; } - + /* to indicate draggable */ if (but->dragpoin && (but->flag & UI_ACTIVE)) { float rgb[3] = {1.25f, 1.25f, 1.25f}; @@ -940,8 +925,8 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect } if (ui_but_draw_menu_icon(but)) { - xs = rect->xmax - UI_DPI_ICON_SIZE - 1; - ys = (rect->ymin + rect->ymax - height) / 2; + xs = rect->xmax - UI_DPI_ICON_SIZE - aspect; + ys = (rect->ymin + rect->ymax - height) / 2.0f; UI_icon_draw_aspect(xs, ys, ICON_RIGHTARROW_THIN, aspect, alpha); } @@ -971,7 +956,7 @@ static void ui_text_clip_give_next_off(uiBut *but) * \note Sets but->ofs to make sure text is correctly visible. * \note Clips right in some cases, this function could be cleaned up. */ -static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, rcti *rect) +static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, const rcti *rect) { int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10; int okwidth = BLI_rcti_size_x(rect) - border; @@ -1000,7 +985,7 @@ static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, rcti *rect) /** * Cut off the text, taking into account the cursor location (text display while editing). */ -static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, rcti *rect) +static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, const rcti *rect) { int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10; int okwidth = BLI_rcti_size_x(rect) - border; @@ -1064,7 +1049,7 @@ static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, rcti *rect) * * \note deals with ': ' especially for number buttons */ -static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, rcti *rect) +static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti *rect) { int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10; int okwidth = BLI_rcti_size_x(rect) - border; @@ -1329,14 +1314,15 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB if (but->flag & UI_HAS_ICON) { widget_draw_icon(but, but->icon + but->iconadd, 1.0f, rect); - - rect->xmin += (int)((float)UI_icon_get_width(but->icon + but->iconadd) * UI_DPI_ICON_FAC); + + /* icons default draw 0.8f x height */ + rect->xmin += (int)(0.8f * BLI_rcti_size_y(rect)); if (but->editstr || (but->flag & UI_TEXT_LEFT)) - rect->xmin += 5; + rect->xmin += 0.4f * U.widget_unit; } else if ((but->flag & UI_TEXT_LEFT)) - rect->xmin += 5; + rect->xmin += 0.4f * U.widget_unit; /* always draw text for textbutton cursor */ widget_draw_text(fstyle, wcol, but, rect); @@ -1807,7 +1793,7 @@ static void widget_state_menu_item(uiWidgetType *wt, int state) /* ************ menu backdrop ************************* */ /* outside of rect, rad to left/bottom/right */ -static void widget_softshadow(rcti *rect, int roundboxalign, float radin, float radout) +static void widget_softshadow(const rcti *rect, int roundboxalign, const float radin, const float radout) { uiWidgetBase wtb; rcti rect1 = *rect; @@ -1816,17 +1802,20 @@ static void widget_softshadow(rcti *rect, int roundboxalign, float radin, float float quad_strip[WIDGET_SIZE_MAX * 2][2]; /* prevent tooltips to not show round shadow */ - if (2.0f * radout > 0.2f * BLI_rcti_size_y(&rect1)) + if (radout > 0.2f * BLI_rcti_size_y(&rect1)) rect1.ymax -= 0.2f * BLI_rcti_size_y(&rect1); else - rect1.ymax -= 2.0f * radout; + rect1.ymax -= radout; /* inner part */ totvert = round_box_shadow_edges(wtb.inner_v, &rect1, radin, roundboxalign & (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT), 0.0f); /* inverse linear shadow alpha */ - alpha = 0.15; - alphastep = 0.67; + alpha = 0.15f; + if (U.pixelsize > 1.0f) + alphastep = 0.78f; + else + alphastep = 0.67f; glEnableClientState(GL_VERTEX_ARRAY); @@ -1858,17 +1847,17 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir } else if (direction == UI_DOWN) { roundboxalign = (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT); - rect->ymin -= 4.0; + rect->ymin -= 0.1f * U.widget_unit; } else if (direction == UI_TOP) { roundboxalign = UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT; - rect->ymax += 4.0; + rect->ymax += 0.1f * U.widget_unit; } glEnable(GL_BLEND); - widget_softshadow(rect, roundboxalign, 5.0f, 8.0f); + widget_softshadow(rect, roundboxalign, 0.25f * U.widget_unit, 0.4f * U.widget_unit); - round_box_edges(&wtb, roundboxalign, rect, 5.0f); + round_box_edges(&wtb, roundboxalign, rect, 0.25f * U.widget_unit); wtb.emboss = 0; widgetbase_draw(&wtb, wcol); @@ -2000,7 +1989,7 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti * /* ************ custom buttons, old stuff ************** */ /* draws in resolution of 20x4 colors */ -void ui_draw_gradient(rcti *rect, const float hsv[3], const int type, const float alpha) +void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, const float alpha) { const float color_step = (type == UI_GRAD_H) ? 0.02f : 0.05f; int a; @@ -2139,16 +2128,24 @@ void ui_draw_gradient(rcti *rect, const float hsv[3], const int type, const floa -static void ui_draw_but_HSVCUBE(uiBut *but, rcti *rect) +static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect) { float rgb[3]; float x = 0.0f, y = 0.0f; float *hsv = ui_block_hsv_get(but->block); float hsv_n[3]; + int color_profile = but->block->color_profile; + + if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) + color_profile = FALSE; copy_v3_v3(hsv_n, hsv); ui_get_but_vectorf(but, rgb); + + if (color_profile && (int)but->a1 != UI_GRAD_SV) + ui_block_to_display_space_v3(but->block, rgb); + rgb_to_hsv_compat_v(rgb, hsv_n); ui_draw_gradient(rect, hsv_n, but->a1, 1.0f); @@ -2182,10 +2179,10 @@ static void ui_draw_but_HSVCUBE(uiBut *but, rcti *rect) } /* vertical 'value' slider, using new widget code */ -static void ui_draw_but_HSV_v(uiBut *but, rcti *rect) +static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect) { uiWidgetBase wtb; - float rad = 0.5f * BLI_rcti_size_x(rect); + const float rad = 0.5f * BLI_rcti_size_x(rect); float x, y; float rgb[3], hsv[3], v, range; int color_profile = but->block->color_profile; @@ -2230,7 +2227,7 @@ static void ui_draw_but_HSV_v(uiBut *but, rcti *rect) /* ************ separator, for menus etc ***************** */ -static void ui_draw_separator(rcti *rect, uiWidgetColors *wcol) +static void ui_draw_separator(const rcti *rect, uiWidgetColors *wcol) { int y = rect->ymin + BLI_rcti_size_y(rect) / 2 - 1; unsigned char col[4]; @@ -2251,7 +2248,7 @@ static void ui_draw_separator(rcti *rect, uiWidgetColors *wcol) static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign) { uiWidgetBase wtb; - float rad = 0.5f * BLI_rcti_size_y(rect); + const float rad = 0.5f * BLI_rcti_size_y(rect); float textofs = rad * 0.75f; if (state & UI_SELECT) @@ -2275,7 +2272,7 @@ static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int round rect->xmax -= textofs; } -int ui_link_bezier_points(rcti *rect, float coord_array[][2], int resol) +int ui_link_bezier_points(const rcti *rect, float coord_array[][2], int resol) { float dist, vec[4][2]; @@ -2299,7 +2296,7 @@ int ui_link_bezier_points(rcti *rect, float coord_array[][2], int resol) } #define LINK_RESOL 24 -void ui_draw_link_bezier(rcti *rect) +void ui_draw_link_bezier(const rcti *rect) { float coord_array[LINK_RESOL + 1][2]; @@ -2322,18 +2319,18 @@ void ui_draw_link_bezier(rcti *rect) } /* function in use for buttons and for view2d sliders */ -void uiWidgetScrollDraw(uiWidgetColors *wcol, rcti *rect, rcti *slider, int state) +void uiWidgetScrollDraw(uiWidgetColors *wcol, const rcti *rect, const rcti *slider, int state) { uiWidgetBase wtb; - float rad; int horizontal; + float rad; short outline = 0; widget_init(&wtb); /* determine horizontal/vertical */ horizontal = (BLI_rcti_size_x(rect) > BLI_rcti_size_y(rect)); - + if (horizontal) rad = 0.5f * BLI_rcti_size_y(rect); else @@ -2540,14 +2537,15 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s fac = ((float)value - but->softmin) * (BLI_rcti_size_x(&rect1) - offs) / (but->softmax - but->softmin); /* left part of slider, always rounded */ - rect1.xmax = rect1.xmin + ceil(offs + 1.0f); + rect1.xmax = rect1.xmin + ceil(offs + U.pixelsize); round_box_edges(&wtb1, roundboxalign & ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT), &rect1, offs); wtb1.outline = 0; widgetbase_draw(&wtb1, wcol); /* right part of slider, interpolate roundness */ rect1.xmax = rect1.xmin + fac + offs; - rect1.xmin += floor(offs - 1.0f); + rect1.xmin += floor(offs - U.pixelsize); + if (rect1.xmax + offs > rect->xmax) offs *= (rect1.xmax + offs - rect->xmax) / offs; else @@ -2577,12 +2575,14 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign) { uiWidgetBase wtb; - float col[4]; + float rad, col[4]; int color_profile = but->block->color_profile; col[3] = 1.0f; if (but->rnaprop) { + BLI_assert(but->rnaindex == -1); + if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) color_profile = FALSE; @@ -2594,7 +2594,8 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat widget_init(&wtb); /* half rounded */ - round_box_edges(&wtb, roundboxalign, rect, 5.0f); + rad = 0.25f * U.widget_unit; + round_box_edges(&wtb, roundboxalign, rect, rad); ui_get_but_vectorf(but, col); @@ -2608,7 +2609,7 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat rect->ymin += SWATCH_KEYED_BORDER; rect->ymax -= SWATCH_KEYED_BORDER; - round_box_edges(&wtb, roundboxalign, rect, 5.0f); + round_box_edges(&wtb, roundboxalign, rect, rad); } if (color_profile) @@ -2632,12 +2633,14 @@ static void widget_icon_has_anim(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti { if (state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_REDALERT)) { uiWidgetBase wtb; - + float rad; + widget_init(&wtb); wtb.outline = 0; /* rounded */ - round_box_edges(&wtb, UI_CNR_ALL, rect, 10.0f); + rad = 0.5f * BLI_rcti_size_y(rect); + round_box_edges(&wtb, UI_CNR_ALL, rect, rad); widgetbase_draw(&wtb, wcol); } } @@ -2646,6 +2649,7 @@ static void widget_icon_has_anim(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti static void widget_textbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign) { uiWidgetBase wtb; + float rad; if (state & UI_SELECT) SWAP(short, wcol->shadetop, wcol->shadedown); @@ -2653,7 +2657,8 @@ static void widget_textbut(uiWidgetColors *wcol, rcti *rect, int state, int roun widget_init(&wtb); /* half rounded */ - round_box_edges(&wtb, roundboxalign, rect, 4.0f); + rad = 0.2f * U.widget_unit; + round_box_edges(&wtb, roundboxalign, rect, rad); widgetbase_draw(&wtb, wcol); @@ -2663,11 +2668,13 @@ static void widget_textbut(uiWidgetColors *wcol, rcti *rect, int state, int roun static void widget_menubut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) { uiWidgetBase wtb; + float rad; widget_init(&wtb); /* half rounded */ - round_box_edges(&wtb, roundboxalign, rect, 4.0f); + rad = 0.2f * U.widget_unit; + round_box_edges(&wtb, roundboxalign, rect, rad); /* decoration */ widget_menu_trias(&wtb.tria1, rect); @@ -2681,11 +2688,13 @@ static void widget_menubut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), static void widget_menuiconbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) { uiWidgetBase wtb; + float rad; widget_init(&wtb); /* half rounded */ - round_box_edges(&wtb, roundboxalign, rect, 4.0f); + rad = 0.2f * U.widget_unit; + round_box_edges(&wtb, roundboxalign, rect, rad); /* decoration */ widgetbase_draw(&wtb, wcol); @@ -2696,11 +2705,13 @@ static void widget_menunodebut(uiWidgetColors *wcol, rcti *rect, int UNUSED(stat /* silly node link button hacks */ uiWidgetBase wtb; uiWidgetColors wcol_backup = *wcol; + float rad; widget_init(&wtb); /* half rounded */ - round_box_edges(&wtb, roundboxalign, rect, 4.0f); + rad = 0.2f * U.widget_unit; + round_box_edges(&wtb, roundboxalign, rect, rad); wcol->inner[0] += 15; wcol->inner[1] += 15; @@ -2718,7 +2729,7 @@ static void widget_pulldownbut(uiWidgetColors *wcol, rcti *rect, int state, int { if (state & UI_ACTIVE) { uiWidgetBase wtb; - float rad = 0.25f * BLI_rcti_size_y(rect); /* 4.0f */ + const float rad = 0.2f * U.widget_unit; widget_init(&wtb); @@ -2745,12 +2756,14 @@ static void widget_menu_itembut(uiWidgetColors *wcol, rcti *rect, int UNUSED(sta static void widget_list_itembut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign)) { uiWidgetBase wtb; + float rad; widget_init(&wtb); /* rounded, but no outline */ wtb.outline = 0; - round_box_edges(&wtb, UI_CNR_ALL, rect, 4.0f); + rad = 0.2f * U.widget_unit; + round_box_edges(&wtb, UI_CNR_ALL, rect, rad); widgetbase_draw(&wtb, wcol); } @@ -2759,6 +2772,7 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN { uiWidgetBase wtb; rcti recttemp = *rect; + float rad; int delta; widget_init(&wtb); @@ -2774,7 +2788,8 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN recttemp.ymax -= delta; /* half rounded */ - round_box_edges(&wtb, UI_CNR_ALL, &recttemp, 4.0f); + rad = 0.2f * U.widget_unit; + round_box_edges(&wtb, UI_CNR_ALL, &recttemp, rad); /* decoration */ if (state & UI_SELECT) { @@ -2791,11 +2806,13 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN static void widget_radiobut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) { uiWidgetBase wtb; + float rad; widget_init(&wtb); /* half rounded */ - round_box_edges(&wtb, roundboxalign, rect, 4.0f); + rad = 0.2f * U.widget_unit; + round_box_edges(&wtb, roundboxalign, rect, rad); widgetbase_draw(&wtb, wcol); @@ -2804,6 +2821,7 @@ static void widget_radiobut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) { uiWidgetBase wtb; + float rad; char old_col[3]; widget_init(&wtb); @@ -2818,7 +2836,8 @@ static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED( } /* half rounded */ - round_box_edges(&wtb, roundboxalign, rect, 4.0f); + rad = 0.2f * U.widget_unit; + round_box_edges(&wtb, roundboxalign, rect, rad); widgetbase_draw(&wtb, wcol); @@ -2833,12 +2852,14 @@ static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED( static void widget_but(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) { uiWidgetBase wtb; + float rad; widget_init(&wtb); /* half rounded */ - round_box_edges(&wtb, roundboxalign, rect, 4.0f); - + rad = 0.2f * U.widget_unit; + round_box_edges(&wtb, roundboxalign, rect, rad); + widgetbase_draw(&wtb, wcol); } @@ -2846,7 +2867,7 @@ static void widget_but(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) { uiWidgetBase wtb; - float rad = 5.0f; /* 0.5f * BLI_rcti_size_y(rect); */ + const float rad = 0.25f * U.widget_unit; widget_init(&wtb); @@ -2859,6 +2880,7 @@ static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *wt, rcti *rect) { uiWidgetBase wtb; + const float rad = 0.25f * U.widget_unit; unsigned char col[4]; /* state copy! */ @@ -2874,12 +2896,12 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType * UI_GetThemeColor3ubv(TH_BACK, col); glColor3ubv(col); - round_box__edges(&wtb, UI_CNR_ALL, rect, 0.0f, 4.0); + round_box__edges(&wtb, UI_CNR_ALL, rect, 0.0f, rad); widgetbase_outline(&wtb); } /* outline */ - round_box_edges(&wtb, UI_CNR_ALL, rect, 5.0f); + round_box_edges(&wtb, UI_CNR_ALL, rect, rad); wtb.outline = 1; wtb.inner = 0; widgetbase_draw(&wtb, &wt->wcol); @@ -2887,7 +2909,7 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType * } -static void widget_disabled(rcti *rect) +static void widget_disabled(const rcti *rect) { float col[4]; @@ -3068,9 +3090,9 @@ static int widget_roundbox_set(uiBut *but, rcti *rect) /* ui_block_position has this correction too, keep in sync */ if (but->flag & UI_BUT_ALIGN_TOP) - rect->ymax += 1; + rect->ymax += U.pixelsize; if (but->flag & UI_BUT_ALIGN_LEFT) - rect->xmin -= 1; + rect->xmin -= U.pixelsize; switch (but->flag & UI_BUT_ALIGN) { case UI_BUT_ALIGN_TOP: @@ -3381,7 +3403,7 @@ void ui_draw_search_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect) uiWidgetType *wt = widget_type(UI_WTYPE_BOX); glEnable(GL_BLEND); - widget_softshadow(rect, UI_CNR_ALL, 5.0f, 8.0f); + widget_softshadow(rect, UI_CNR_ALL, 0.25f * U.widget_unit, 0.4f * U.widget_unit); glDisable(GL_BLEND); wt->state(wt, 0); @@ -3408,7 +3430,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic fstyle->align = UI_STYLE_TEXT_LEFT; /* text location offset */ - rect->xmin += 5; + rect->xmin += 0.25f * UI_UNIT_X; if (iconid) rect->xmin += UI_DPI_ICON_SIZE; /* cut string in 2 parts? */ @@ -3433,10 +3455,16 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic *rect = _rect; if (iconid) { - int xs = rect->xmin + 4; + float height, aspect; + int xs = rect->xmin + 0.2f * UI_UNIT_X; int ys = 1 + (rect->ymin + rect->ymax - UI_DPI_ICON_SIZE) / 2; + + /* icons are 80% of height of button (16 pixels inside 20 height) */ + height = 0.8f * BLI_rcti_size_y(rect); + aspect = ICON_DEFAULT_HEIGHT / height; + glEnable(GL_BLEND); - UI_icon_draw_aspect(xs, ys, iconid, 1.2f, 0.5f); /* XXX scale weak get from fstyle? */ + UI_icon_draw_aspect(xs, ys, iconid, aspect, 0.5f); /* XXX scale weak get from fstyle? */ glDisable(GL_BLEND); } } diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index dce0de3fec0..b45d14bfa90 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -86,7 +86,7 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo static char error[4] = {240, 0, 240, 255}; static char alert[4] = {240, 60, 60, 255}; static char headerdesel[4] = {0, 0, 0, 255}; - + static char setting = 0; const char *cp = error; if (btheme) { @@ -216,13 +216,19 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo case TH_HEADER_TEXT_HI: cp = ts->header_text_hi; break; - case TH_PANEL: - cp = ts->panel; break; - case TH_PANEL_TEXT: - cp = ts->panel_text; break; - case TH_PANEL_TEXT_HI: - cp = ts->panel_text_hi; break; - + case TH_PANEL_HEADER: + cp = ts->panelcolors.header; break; + case TH_PANEL_BACK: + cp = ts->panelcolors.back; break; + case TH_PANEL_SHOW_HEADER: + cp = &setting; + setting = ts->panelcolors.show_header; + break; + case TH_PANEL_SHOW_BACK: + cp = &setting; + setting = ts->panelcolors.show_back; + break; + case TH_BUTBACK: cp = ts->button; break; case TH_BUTBACK_TEXT: @@ -607,9 +613,9 @@ static void ui_theme_init_new_do(ThemeSpace *ts) rgba_char_args_test_set(ts->header_title, 0, 0, 0, 255); rgba_char_args_test_set(ts->header_text_hi, 255, 255, 255, 255); - rgba_char_args_test_set(ts->panel_text, 0, 0, 0, 255); - rgba_char_args_test_set(ts->panel_title, 0, 0, 0, 255); - rgba_char_args_test_set(ts->panel_text_hi, 255, 255, 255, 255); +// rgba_char_args_test_set(ts->panel_text, 0, 0, 0, 255); +// rgba_char_args_test_set(ts->panel_title, 0, 0, 0, 255); +// rgba_char_args_test_set(ts->panel_text_hi, 255, 255, 255, 255); rgba_char_args_test_set(ts->button, 145, 145, 145, 245); rgba_char_args_test_set(ts->button_title, 0, 0, 0, 255); @@ -687,8 +693,8 @@ void ui_theme_init_default(void) rgba_char_args_set(btheme->tv3d.text_hi, 255, 255, 255, 255); rgba_char_args_set_fl(btheme->tv3d.header, 0.45, 0.45, 0.45, 1.0); - rgba_char_args_set_fl(btheme->tv3d.button, 0.45, 0.45, 0.45, 1.0); - rgba_char_args_set(btheme->tv3d.panel, 165, 165, 165, 127); + rgba_char_args_set_fl(btheme->tv3d.button, 0.45, 0.45, 0.45, 0.5); +// rgba_char_args_set(btheme->tv3d.panel, 165, 165, 165, 127); rgba_char_args_set(btheme->tv3d.shade1, 160, 160, 160, 100); rgba_char_args_set(btheme->tv3d.shade2, 0x7f, 0x70, 0x70, 100); @@ -769,14 +775,14 @@ void ui_theme_init_default(void) btheme->tbuts = btheme->tv3d; rgba_char_args_set_fl(btheme->tbuts.back, 0.45, 0.45, 0.45, 1.0); - rgba_char_args_set(btheme->tbuts.panel, 0x82, 0x82, 0x82, 255); +// rgba_char_args_set(btheme->tbuts.panel, 0x82, 0x82, 0x82, 255); /* graph editor */ btheme->tipo = btheme->tv3d; rgba_char_args_set_fl(btheme->tipo.back, 0.42, 0.42, 0.42, 1.0); rgba_char_args_set_fl(btheme->tipo.list, 0.4, 0.4, 0.4, 1.0); rgba_char_args_set(btheme->tipo.grid, 94, 94, 94, 255); - rgba_char_args_set(btheme->tipo.panel, 255, 255, 255, 150); +// rgba_char_args_set(btheme->tipo.panel, 255, 255, 255, 150); rgba_char_args_set(btheme->tipo.shade1, 150, 150, 150, 100); /* scrollbars */ rgba_char_args_set(btheme->tipo.shade2, 0x70, 0x70, 0x70, 100); rgba_char_args_set(btheme->tipo.vertex, 0, 0, 0, 255); @@ -822,11 +828,11 @@ void ui_theme_init_default(void) /* to have something initialized */ btheme->tfile = btheme->tv3d; rgba_char_args_set_fl(btheme->tfile.back, 0.3, 0.3, 0.3, 1); - rgba_char_args_set_fl(btheme->tfile.panel, 0.3, 0.3, 0.3, 1); +// rgba_char_args_set_fl(btheme->tfile.panel, 0.3, 0.3, 0.3, 1); rgba_char_args_set_fl(btheme->tfile.list, 0.4, 0.4, 0.4, 1); rgba_char_args_set(btheme->tfile.text, 250, 250, 250, 255); rgba_char_args_set(btheme->tfile.text_hi, 15, 15, 15, 255); - rgba_char_args_set(btheme->tfile.panel, 145, 145, 145, 255); /* bookmark/ui regions */ +// rgba_char_args_set(btheme->tfile.panel, 145, 145, 145, 255); /* bookmark/ui regions */ rgba_char_args_set(btheme->tfile.active, 130, 130, 130, 255); /* selected files */ rgba_char_args_set(btheme->tfile.hilite, 255, 140, 25, 255); /* selected files */ @@ -866,7 +872,8 @@ void ui_theme_init_default(void) rgba_char_args_set_fl(btheme->tima.preview_stitch_vert, 0.0, 0.0, 1.0, 0.2); rgba_char_args_set_fl(btheme->tima.preview_stitch_stitchable, 0.0, 1.0, 0.0, 1.0); rgba_char_args_set_fl(btheme->tima.preview_stitch_unstitchable, 1.0, 0.0, 0.0, 1.0); - + rgba_char_args_set_fl(btheme->tima.preview_stitch_active, 0.886, 0.824, 0.765, 0.140); + /* space text */ btheme->text = btheme->tv3d; rgba_char_args_set(btheme->text.back, 153, 153, 153, 255); @@ -2009,7 +2016,7 @@ void init_userdef_do_versions(void) if (U.dragthreshold == 0) U.dragthreshold = 5; if (U.widget_unit == 0) - U.widget_unit = (U.dpi * 20 + 36) / 72; + U.widget_unit = 20; if (U.anisotropic_filter <= 0) U.anisotropic_filter = 1; @@ -2028,6 +2035,55 @@ void init_userdef_do_versions(void) if (U.tweak_threshold == 0) U.tweak_threshold = 10; + if (bmain->versionfile < 265 || (bmain->versionfile == 265 && bmain->subversionfile < 1)) { + bTheme *btheme; + + for (btheme = U.themes.first; btheme; btheme = btheme->next) { + /* note: the toggle operator for transparent backdrops limits to these spacetypes */ + if (btheme->tnode.button[3] == 255) { + btheme->tv3d.button[3] = 128; + btheme->tnode.button[3] = 128; + btheme->tima.button[3] = 128; + btheme->tseq.button[3] = 128; + btheme->tclip.button[3] = 128; + } + } + } + + /* panel header/backdrop supported locally per editor now */ + if (bmain->versionfile < 265 || (bmain->versionfile == 265 && bmain->subversionfile < 2)) { + bTheme *btheme; + + for (btheme = U.themes.first; btheme; btheme = btheme->next) { + + /* new color, panel backdrop. Not used anywhere yet, until you enable it */ + copy_v3_v3_char(btheme->tui.panel.back, btheme->tbuts.button); + btheme->tui.panel.back[3] = 128; + + btheme->tbuts.panelcolors = btheme->tui.panel; + btheme->tv3d.panelcolors = btheme->tui.panel; + btheme->tfile.panelcolors = btheme->tui.panel; + btheme->tipo.panelcolors = btheme->tui.panel; + btheme->tinfo.panelcolors = btheme->tui.panel; + btheme->tact.panelcolors = btheme->tui.panel; + btheme->tnla.panelcolors = btheme->tui.panel; + btheme->tseq.panelcolors = btheme->tui.panel; + btheme->tima.panelcolors = btheme->tui.panel; + btheme->text.panelcolors = btheme->tui.panel; + btheme->toops.panelcolors = btheme->tui.panel; + btheme->ttime.panelcolors = btheme->tui.panel; + btheme->tnode.panelcolors = btheme->tui.panel; + btheme->tlogic.panelcolors = btheme->tui.panel; + btheme->tuserpref.panelcolors = btheme->tui.panel; + btheme->tconsole.panelcolors = btheme->tui.panel; + btheme->tclip.panelcolors = btheme->tui.panel; + } + } + + + if (U.pixelsize == 0.0f) + U.pixelsize = 1.0f; + /* funny name, but it is GE stuff, moves userdef stuff to engine */ // XXX space_set_commmandline_options(); /* this timer uses U */ diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index f1a3f59bc22..306b328b431 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -852,10 +852,11 @@ void UI_view2d_totRect_set_resize(View2D *v2d, int width, int height, int resize /* hrumf! */ /* XXX: there are work arounds for this in the panel and file browse code. */ + /* round to int, because this is called with width + V2D_SCROLL_WIDTH */ if (scroll & V2D_SCROLL_HORIZONTAL) - width -= V2D_SCROLL_WIDTH; + width -= (int)V2D_SCROLL_WIDTH; if (scroll & V2D_SCROLL_VERTICAL) - height -= V2D_SCROLL_HEIGHT; + height -= (int)V2D_SCROLL_HEIGHT; if (ELEM(0, width, height)) { if (G.debug & G_DEBUG) @@ -1150,7 +1151,7 @@ View2DGrid *UI_view2d_grid_calc(Scene *scene, View2D *v2d, pixels = (float)BLI_rcti_size_x(&v2d->mask); if (pixels != 0.0f) { - grid->dx = (U.v2d_min_gridsize * space) / (seconddiv * pixels); + grid->dx = (U.v2d_min_gridsize * U.pixelsize * space) / (seconddiv * pixels); step_to_grid(&grid->dx, &grid->powerx, xunits); grid->dx *= seconddiv; } @@ -1167,7 +1168,7 @@ View2DGrid *UI_view2d_grid_calc(Scene *scene, View2D *v2d, space = BLI_rctf_size_y(&v2d->cur); pixels = (float)winy; - grid->dy = U.v2d_min_gridsize * space / pixels; + grid->dy = U.v2d_min_gridsize * U.pixelsize * space / pixels; step_to_grid(&grid->dy, &grid->powery, yunits); if (yclamp == V2D_GRID_CLAMP) { @@ -1212,7 +1213,7 @@ void UI_view2d_grid_draw(View2D *v2d, View2DGrid *grid, int flag) vec2[1] = v2d->cur.ymax; /* minor gridlines */ - step = (BLI_rcti_size_x(&v2d->mask) + 1) / U.v2d_min_gridsize; + step = (BLI_rcti_size_x(&v2d->mask) + 1) / (U.v2d_min_gridsize * U.pixelsize); UI_ThemeColor(TH_GRID); for (a = 0; a < step; a++) { @@ -1246,7 +1247,7 @@ void UI_view2d_grid_draw(View2D *v2d, View2DGrid *grid, int flag) vec1[0] = grid->startx; vec2[0] = v2d->cur.xmax; - step = (BLI_rcti_size_y(&v2d->mask) + 1) / U.v2d_min_gridsize; + step = (BLI_rcti_size_y(&v2d->mask) + 1) / (U.v2d_min_gridsize * U.pixelsize); UI_ThemeColor(TH_GRID); for (a = 0; a <= step; a++) { @@ -1427,6 +1428,7 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d, rcti vert, hor; float fac1, fac2, totsize, scrollsize; int scroll = view2d_scroll_mapped(v2d->scroll); + int smaller; /* scrollers is allocated here... */ scrollers = MEM_callocN(sizeof(View2DScrollers), "View2DScrollers"); @@ -1435,19 +1437,20 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d, hor = v2d->hor; /* slider rects need to be smaller than region */ - hor.xmin += 4; - hor.xmax -= 4; + smaller = (int)(0.2f * U.widget_unit); + hor.xmin += smaller; + hor.xmax -= smaller; if (scroll & V2D_SCROLL_BOTTOM) - hor.ymin += 4; + hor.ymin += smaller; else - hor.ymax -= 4; + hor.ymax -= smaller; if (scroll & V2D_SCROLL_LEFT) - vert.xmin += 4; + vert.xmin += smaller; else - vert.xmax -= 4; - vert.ymin += 4; - vert.ymax -= 4; + vert.xmax -= smaller; + vert.ymin += smaller; + vert.ymax -= smaller; CLAMP(vert.ymin, vert.ymin, vert.ymax - V2D_SCROLLER_HANDLE_SIZE); CLAMP(hor.xmin, hor.xmin, hor.xmax - V2D_SCROLLER_HANDLE_SIZE); @@ -1621,6 +1624,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v uiWidgetColors wcol = btheme->tui.wcol_scroll; rcti slider; int state; + unsigned char col[4]; slider.xmin = vs->hor_min; slider.xmax = vs->hor_max; @@ -1643,8 +1647,12 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v state |= UI_SCROLL_ARROWS; } - UI_ThemeColor(TH_BACK); - glRecti(v2d->hor.xmin, v2d->hor.ymin, v2d->hor.xmax, v2d->hor.ymax); + /* clean rect behind slider, but not with transparent background */ + UI_GetThemeColor4ubv(TH_BACK, col); + if (col[3] == 255) { + glColor3ub(col[0], col[1], col[2]); + glRecti(v2d->hor.xmin, v2d->hor.ymin, v2d->hor.xmax, v2d->hor.ymax); + } uiWidgetScrollDraw(&wcol, &hor, &slider, state); } @@ -1680,12 +1688,12 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v /* draw numbers in the appropriate range */ if (dfac > 0.0f) { - float h = 2.0f + (float)(hor.ymin); + float h = 0.1f*UI_UNIT_Y + (float)(hor.ymin); - for (; fac < hor.xmax - 10; fac += dfac, val += grid->dx) { + for (; fac < hor.xmax - 0.5f * U.widget_unit; fac += dfac, val += grid->dx) { /* make prints look nicer for scrollers */ - if (fac < hor.xmin + 10) + if (fac < hor.xmin + 0.5f * U.widget_unit) continue; switch (vs->xunits) { @@ -1732,6 +1740,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v uiWidgetColors wcol = btheme->tui.wcol_scroll; rcti slider; int state; + unsigned char col[4]; slider.xmin = vert.xmin; slider.xmax = vert.xmax; @@ -1753,9 +1762,13 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v { state |= UI_SCROLL_ARROWS; } - - UI_ThemeColor(TH_BACK); - glRecti(v2d->vert.xmin, v2d->vert.ymin, v2d->vert.xmax, v2d->vert.ymax); + + /* clean rect behind slider, but not with transparent background */ + UI_GetThemeColor4ubv(TH_BACK, col); + if (col[3] == 255) { + glColor3ub(col[0], col[1], col[2]); + glRecti(v2d->vert.xmin, v2d->vert.ymin, v2d->vert.xmax, v2d->vert.ymax); + } uiWidgetScrollDraw(&wcol, &vert, &slider, state); } @@ -2047,6 +2060,12 @@ void UI_view2d_getscale(View2D *v2d, float *x, float *y) if (x) *x = BLI_rcti_size_x(&v2d->mask) / BLI_rctf_size_x(&v2d->cur); if (y) *y = BLI_rcti_size_y(&v2d->mask) / BLI_rctf_size_y(&v2d->cur); } +/* Same as UI_view2d_getscale() - 1.0f / x, y */ +void UI_view2d_getscale_inverse(View2D *v2d, float *x, float *y) +{ + if (x) *x = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask); + if (y) *y = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask); +} /* Check if mouse is within scrollers * - Returns appropriate code for match diff --git a/source/blender/editors/io/SConscript b/source/blender/editors/io/SConscript index d012576637c..cef73f33ddd 100644 --- a/source/blender/editors/io/SConscript +++ b/source/blender/editors/io/SConscript @@ -1,4 +1,29 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** Import ('env') diff --git a/source/blender/editors/mask/SConscript b/source/blender/editors/mask/SConscript index 4af000d038d..3200362b580 100644 --- a/source/blender/editors/mask/SConscript +++ b/source/blender/editors/mask/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/mask/mask_edit.c b/source/blender/editors/mask/mask_edit.c index 18384ad9de4..cd2995be439 100644 --- a/source/blender/editors/mask/mask_edit.c +++ b/source/blender/editors/mask/mask_edit.c @@ -324,15 +324,13 @@ void ED_mask_pixelspace_factor(ScrArea *sa, ARegion *ar, float *scalex, float *s case SPACE_CLIP: { SpaceClip *sc = sa->spacedata.first; - int width, height; - float zoomx, zoomy, aspx, aspy; + float aspx, aspy; - ED_space_clip_get_size(sc, &width, &height); - ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy); + UI_view2d_getscale(&ar->v2d, scalex, scaley); ED_space_clip_get_aspect(sc, &aspx, &aspy); - *scalex = ((float)width * aspx) * zoomx; - *scaley = ((float)height * aspy) * zoomy; + *scalex *= aspx; + *scaley *= aspy; break; } case SPACE_SEQ: @@ -343,15 +341,13 @@ void ED_mask_pixelspace_factor(ScrArea *sa, ARegion *ar, float *scalex, float *s case SPACE_IMAGE: { SpaceImage *sima = sa->spacedata.first; - int width, height; - float zoomx, zoomy, aspx, aspy; + float aspx, aspy; - ED_space_image_get_size(sima, &width, &height); - ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy); + UI_view2d_getscale(&ar->v2d, scalex, scaley); ED_space_image_get_aspect(sima, &aspx, &aspy); - *scalex = ((float)width * aspx) * zoomx; - *scaley = ((float)height * aspy) * zoomy; + *scalex *= aspx; + *scaley *= aspy; break; } default: diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c index a1f2539ce7c..2a1bdee32f7 100644 --- a/source/blender/editors/mask/mask_relationships.c +++ b/source/blender/editors/mask/mask_relationships.c @@ -31,6 +31,7 @@ #include "BLI_math.h" +#include "BLI_string.h" #include "BKE_context.h" #include "BKE_depsgraph.h" @@ -143,8 +144,8 @@ static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) if (MASKPOINT_ISSEL_ANY(point)) { point->parent.id_type = ID_MC; point->parent.id = &clip->id; - strcpy(point->parent.parent, tracking_object->name); - strcpy(point->parent.sub_parent, track->name); + BLI_strncpy(point->parent.parent, tracking_object->name, sizeof(point->parent.parent)); + BLI_strncpy(point->parent.sub_parent, track->name, sizeof(point->parent.sub_parent)); copy_v2_v2(point->parent.parent_orig, parmask_pos); } diff --git a/source/blender/editors/mesh/SConscript b/source/blender/editors/mesh/SConscript index 91ffdc91685..11c90a4a922 100644 --- a/source/blender/editors/mesh/SConscript +++ b/source/blender/editors/mesh/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 4350c005f95..05f2269c359 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -852,7 +852,7 @@ void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_to if (em) { if (skip_em_vert_array_init == FALSE) { - EDBM_index_arrays_init(em, 1, 0, 0); + EDBM_index_arrays_ensure(em, BM_VERT); } } @@ -888,11 +888,6 @@ void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_to last = a; } } - if (em) { - if (skip_em_vert_array_init == FALSE) { - EDBM_index_arrays_free(em); - } - } MEM_freeN(topo_pairs); topo_pairs = NULL; diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index 4a425c83d86..adcec5699a9 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -58,7 +58,7 @@ /* BMESH_TODO: 'state' is not a good name, should be flipped and called 'was_editmode', * or at least something more descriptive */ static Object *make_prim_init(bContext *C, const char *idname, - float *dia, float mat[][4], + float *dia, float mat[4][4], int *state, const float loc[3], const float rot[3], const unsigned int layer) { Object *obedit = CTX_data_edit_object(C); @@ -90,7 +90,7 @@ static void make_prim_finish(bContext *C, Object *obedit, int *state, int enter_ EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX); /* only recalc editmode tessface if we are staying in editmode */ - EDBM_update_generic(C, em, !exit_editmode); + EDBM_update_generic(em, !exit_editmode, TRUE); /* userdef */ if (exit_editmode) { diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index a59c491fe13..31d5eed83dc 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -720,7 +720,7 @@ static void knife_cut_through(KnifeTool_OpData *kcd) for (r = firstfaces.first; r; r = r->next) { f = r->ref; found = 0; - for (j = 0, lh2 = kcd->linehits; j < kcd->totlinehit; j++, lh2++) { + for (j = 0, lh2 = kcd->linehits; j < kcd->totlinehit && !found; j++, lh2++) { kfe2 = lh2->kfe; for (r2 = kfe2->faces.first; r2; r2 = r2->next) { if (r2->ref == f) { @@ -750,7 +750,7 @@ static void knife_cut_through(KnifeTool_OpData *kcd) for (r = kfe->faces.first; r; r = r->next) { f = r->ref; found = 0; - for (j = i + 1, lh2 = lh + 1; j < kcd->totlinehit; j++, lh2++) { + for (j = i + 1, lh2 = lh + 1; j < kcd->totlinehit && !found; j++, lh2++) { kfe2 = lh2->kfe; for (r2 = kfe2->faces.first; r2; r2 = r2->next) { if (r2->ref == f) { @@ -1594,10 +1594,10 @@ static KnifeEdge *knife_find_closest_edge(KnifeTool_OpData *kcd, float p[3], flo dis = dist_to_line_segment_v2(sco, kfe->v1->sco, kfe->v2->sco); if (dis < curdis && dis < maxdist) { if (kcd->vc.rv3d->rflag & RV3D_CLIPPING) { - float labda = line_point_factor_v2(sco, kfe->v1->sco, kfe->v2->sco); + float lambda = line_point_factor_v2(sco, kfe->v1->sco, kfe->v2->sco); float vec[3]; - interp_v3_v3v3(vec, kfe->v1->cageco, kfe->v2->cageco, labda); + interp_v3_v3v3(vec, kfe->v1->cageco, kfe->v2->cageco, lambda); if (ED_view3d_clipping_test(kcd->vc.rv3d, vec, TRUE) == 0) { cure = kfe; @@ -2591,10 +2591,8 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha BMLoop *lnew, *l_iter; int i; int nco = BLI_countlist(chain) - 1; - float (*cos)[3] = NULL; - KnifeVert **kverts; - BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, nco, __func__); - BLI_array_fixedstack_declare(kverts, BM_DEFAULT_NGON_STACK_SIZE, nco, __func__); + float (*cos)[3] = BLI_array_alloca(cos, nco); + KnifeVert **kverts = BLI_array_alloca(kverts, nco); kfe = ((Ref *)chain->first)->ref; v1 = kfe->v1->v ? kfe->v1->v : kfe->v2->v; @@ -2643,9 +2641,6 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha BM_edge_select_set(bm, lnew->e, TRUE); } } - - BLI_array_fixedstack_free(cos); - BLI_array_fixedstack_free(kverts); } static void knife_make_face_cuts(KnifeTool_OpData *kcd, BMFace *f, ListBase *kfedges) @@ -2835,7 +2830,7 @@ static void knife_make_cuts(KnifeTool_OpData *kcd) #endif /* called on tool confirmation */ -static void knifetool_finish(bContext *C, wmOperator *op) +static void knifetool_finish(wmOperator *op) { KnifeTool_OpData *kcd = op->customdata; @@ -2846,7 +2841,7 @@ static void knifetool_finish(bContext *C, wmOperator *op) #endif EDBM_mesh_normals_update(kcd->em); - EDBM_update_generic(C, kcd->em, TRUE); + EDBM_update_generic(kcd->em, TRUE, TRUE); } /* copied from paint_image.c */ @@ -3134,7 +3129,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event) /* finish */ ED_region_tag_redraw(kcd->ar); - knifetool_finish(C, op); + knifetool_finish(op); knifetool_exit(C, op); ED_area_headerprint(CTX_wm_area(C), NULL); diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index dec45b7f326..7721f878ce6 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -334,6 +334,9 @@ static void ringsel_finish(bContext *C, wmOperator *op) SUBDIV_SELECT_LOOPCUT, SUBD_PATH, 0, TRUE, use_only_quads, 0); + /* tessface is already re-recalculated */ + EDBM_update_generic(em, FALSE, TRUE); + /* force edge slide to edge select mode in in face select mode */ if (em->selectmode & SCE_SELECT_FACE) { if (em->selectmode == SCE_SELECT_FACE) @@ -345,11 +348,9 @@ static void ringsel_finish(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, CTX_data_scene(C)); } - else + else { EDBM_selectmode_flush(lcd->em); - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT | ND_DATA, lcd->ob->data); - DAG_id_tag_update(lcd->ob->data, 0); + } } else { /* XXX Is this piece of code ever used now? Simple loop select is now diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 2ecc20b2ddb..4909561f677 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -63,7 +63,7 @@ * point and would result in the same distance. */ #define INSET_DEFAULT 0.00001f -static float edbm_rip_edgedist(ARegion *ar, float mat[][4], +static float edbm_rip_edgedist(ARegion *ar, float mat[4][4], const float co1[3], const float co2[3], const float mvalf[2], const float inset) { @@ -83,7 +83,7 @@ static float edbm_rip_edgedist(ARegion *ar, float mat[][4], } #if 0 -static float edbm_rip_linedist(ARegion *ar, float mat[][4], +static float edbm_rip_linedist(ARegion *ar, float mat[4][4], const float co1[3], const float co2[3], const float mvalf[2]) { float vec1[2], vec2[2]; @@ -1044,7 +1044,7 @@ static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 68dfbf66ec3..2538ddfc886 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -107,21 +107,23 @@ void EDBM_select_mirrored(Object *UNUSED(obedit), BMEditMesh *em, int extend) void EDBM_automerge(Scene *scene, Object *obedit, int update) { - BMEditMesh *em; if ((scene->toolsettings->automerge) && (obedit && obedit->type == OB_MESH)) { - em = BMEdit_FromObject(obedit); - if (!em) + int ok; + BMEditMesh *em = BMEdit_FromObject(obedit); + + if (!em) { return; + } + + ok = BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS, + "automerge verts=%hv dist=%f", + BM_ELEM_SELECT, scene->toolsettings->doublimit); - BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS, - "automerge verts=%hv dist=%f", - BM_ELEM_SELECT, scene->toolsettings->doublimit); - if (update) { - DAG_id_tag_update(obedit->data, OB_RECALC_DATA); - BMEdit_RecalcTessellation(em); + if (LIKELY(ok) && update) { + EDBM_update_generic(em, TRUE, TRUE); } } } @@ -464,12 +466,12 @@ static void findnearestedge__doClosest(void *userData, BMEdge *eed, const float if (distance < data->dist) { if (data->vc.rv3d->rflag & RV3D_CLIPPING) { - float labda = line_point_factor_v2(data->mval_fl, screen_co_a, screen_co_b); + float lambda = line_point_factor_v2(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]); - vec[1] = eed->v1->co[1] + labda * (eed->v2->co[1] - eed->v1->co[1]); - vec[2] = eed->v1->co[2] + labda * (eed->v2->co[2] - eed->v1->co[2]); + vec[0] = eed->v1->co[0] + lambda * (eed->v2->co[0] - eed->v1->co[0]); + vec[1] = eed->v1->co[1] + lambda * (eed->v2->co[1] - eed->v1->co[1]); + vec[2] = eed->v1->co[2] + lambda * (eed->v2->co[2] - eed->v1->co[2]); if (ED_view3d_clipping_test(data->vc.rv3d, vec, TRUE) == 0) { data->dist = distance; @@ -573,7 +575,7 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist) data.mval_fl[0] = vc->mval[0]; data.mval_fl[1] = vc->mval[1]; - data.dist = 0x7FFF; /* largest short */ + data.dist = FLT_MAX; data.toFace = efa; mesh_foreachScreenFace(vc, findnearestface__getDistance, &data, V3D_PROJ_TEST_CLIP_DEFAULT); @@ -727,7 +729,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -769,7 +771,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -814,7 +816,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op) EDBM_selectmode_flush(em); - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -1438,7 +1440,7 @@ static int edgetag_shortest_path(Scene *scene, BMesh *bm, BMEdge *e_src, BMEdge /* ******************* mesh shortest path select, uses prev-selected edge ****************** */ /* since you want to create paths with multiple selects, it doesn't have extend option */ -static int mouse_mesh_shortest_path_edge(bContext *C, ViewContext *vc) +static int mouse_mesh_shortest_path_edge(ViewContext *vc) { BMEditMesh *em = vc->em; BMEdge *e_dst; @@ -1477,7 +1479,7 @@ static int mouse_mesh_shortest_path_edge(bContext *C, ViewContext *vc) BM_select_history_store(em->bm, e_dst); /* force drawmode for mesh */ - switch (CTX_data_tool_settings(C)->edge_mode) { + switch (vc->scene->toolsettings->edge_mode) { case EDGE_MODE_TAG_SEAM: me->drawflag |= ME_DRAWSEAMS; @@ -1497,7 +1499,7 @@ static int mouse_mesh_shortest_path_edge(bContext *C, ViewContext *vc) break; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(em, FALSE, FALSE); return TRUE; } @@ -1654,7 +1656,7 @@ static int facetag_shortest_path(Scene *scene, BMesh *bm, BMFace *f_src, BMFace return 1; } -static int mouse_mesh_shortest_path_face(bContext *C, ViewContext *vc) +static int mouse_mesh_shortest_path_face(ViewContext *vc) { BMEditMesh *em = vc->em; BMFace *f_dst; @@ -1688,7 +1690,7 @@ static int mouse_mesh_shortest_path_face(bContext *C, ViewContext *vc) BM_active_face_set(em->bm, f_dst); - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(em, FALSE, FALSE); return TRUE; } @@ -1713,7 +1715,7 @@ static int edbm_shortest_path_select_invoke(bContext *C, wmOperator *UNUSED(op), em = vc.em; if (em->selectmode & SCE_SELECT_EDGE) { - if (mouse_mesh_shortest_path_edge(C, &vc)) { + if (mouse_mesh_shortest_path_edge(&vc)) { return OPERATOR_FINISHED; } else { @@ -1721,7 +1723,7 @@ static int edbm_shortest_path_select_invoke(bContext *C, wmOperator *UNUSED(op), } } else if (em->selectmode & SCE_SELECT_FACE) { - if (mouse_mesh_shortest_path_face(C, &vc)) { + if (mouse_mesh_shortest_path_face(&vc)) { return OPERATOR_FINISHED; } else { @@ -2638,14 +2640,15 @@ static int edbm_select_nth_exec(bContext *C, wmOperator *op) int nth = RNA_int_get(op->ptr, "nth"); int offset = RNA_int_get(op->ptr, "offset"); - offset = MIN2(nth, offset); + /* so input of offset zero ends up being (nth - 1) */ + offset = (offset + (nth - 1)) % nth; if (edbm_deselect_nth(em, nth, offset) == 0) { BKE_report(op->reports, RPT_ERROR, "Mesh has no active vert/edge/face"); return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(em, FALSE, FALSE); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_slide.c b/source/blender/editors/mesh/editmesh_slide.c index 4fbe9c2534f..eb0a21261ce 100644 --- a/source/blender/editors/mesh/editmesh_slide.c +++ b/source/blender/editors/mesh/editmesh_slide.c @@ -264,7 +264,7 @@ static void vtx_slide_confirm(bContext *C, wmOperator *op) EDBM_selectmode_flush(em); /* NC_GEOM | ND_DATA & Retess */ - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, FALSE); ED_region_tag_redraw(vso->active_region); } @@ -752,7 +752,7 @@ static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_u if (do_update) { /* Update Geometry */ - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, FALSE); } return OPERATOR_FINISHED; diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 3f8f573cf07..df2722f1fbc 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -112,7 +112,7 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op) RNA_boolean_get(op->ptr, "quadtri"), TRUE, FALSE, RNA_int_get(op->ptr, "seed")); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -181,7 +181,7 @@ static int edbm_unsubdivide_exec(bContext *C, wmOperator *op) } EDBM_selectmode_flush(em); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -463,7 +463,7 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op) EDBM_mesh_normals_update(em); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -585,7 +585,7 @@ static int edbm_extrude_region_exec(bContext *C, wmOperator *op) * done.*/ EDBM_mesh_normals_update(em); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -678,7 +678,7 @@ static int edbm_extrude_faces_exec(bContext *C, wmOperator *op) edbm_extrude_discrete_faces(em, op, BM_ELEM_SELECT, nor); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -906,7 +906,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent BM_ELEM_SELECT, min); } else { - float *curs = give_cursor(vc.scene, vc.v3d); + const float *curs = give_cursor(vc.scene, vc.v3d); BMOperator bmop; BMOIter oiter; @@ -936,7 +936,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent * done. */ EDBM_mesh_normals_update(vc.em); - EDBM_update_generic(C, vc.em, TRUE); + EDBM_update_generic(vc.em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1001,7 +1001,7 @@ static int edbm_delete_exec(bContext *C, wmOperator *op) EDBM_flag_disable_all(em, BM_ELEM_SELECT); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1034,7 +1034,7 @@ static int edbm_collapse_edge_exec(bContext *C, wmOperator *op) if (!EDBM_op_callf(em, op, "collapse edges=%he", BM_ELEM_SELECT)) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1062,7 +1062,7 @@ static int edbm_collapse_edge_loop_exec(bContext *C, wmOperator *op) if (!EDBM_op_callf(em, op, "dissolve_edge_loop edges=%he", BM_ELEM_SELECT)) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1121,7 +1121,7 @@ static int edbm_add_edge_face_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1176,7 +1176,7 @@ static int edbm_mark_seam(bContext *C, wmOperator *op) } ED_uvedit_live_unwrap(scene, obedit); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1230,7 +1230,7 @@ static int edbm_mark_sharp(bContext *C, wmOperator *op) } } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1272,7 +1272,7 @@ static int edbm_vert_connect(bContext *C, wmOperator *op) else { EDBM_selectmode_flush(em); /* so newly created edges get the selection state from the vertex */ - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } @@ -1310,7 +1310,7 @@ static int edbm_edge_split_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } @@ -1349,7 +1349,7 @@ static int edbm_duplicate_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1388,7 +1388,7 @@ static int edbm_flip_normals_exec(bContext *C, wmOperator *op) if (!EDBM_op_callf(em, op, "reverse_faces faces=%hf", BM_ELEM_SELECT)) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1469,7 +1469,7 @@ static int edbm_edge_rotate_selected_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -1500,7 +1500,7 @@ static int edbm_hide_exec(bContext *C, wmOperator *op) EDBM_mesh_hide(em, RNA_boolean_get(op->ptr, "unselected")); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1530,7 +1530,7 @@ static int edbm_reveal_exec(bContext *C, wmOperator *UNUSED(op)) EDBM_mesh_reveal(em); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1563,7 +1563,7 @@ static int edbm_normals_make_consistent_exec(bContext *C, wmOperator *op) if (RNA_boolean_get(op->ptr, "inside")) EDBM_op_callf(em, op, "reverse_faces faces=%hf", BM_ELEM_SELECT); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1645,7 +1645,7 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op) EDBM_verts_mirror_cache_end(em); } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1721,7 +1721,7 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op) EDBM_verts_mirror_cache_end(em); } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -1775,7 +1775,7 @@ static int edbm_faces_shade_smooth_exec(bContext *C, wmOperator *UNUSED(op)) mesh_set_smooth_faces(em, 1); - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(em, FALSE, FALSE); return OPERATOR_FINISHED; } @@ -1802,7 +1802,7 @@ static int edbm_faces_shade_flat_exec(bContext *C, wmOperator *UNUSED(op)) mesh_set_smooth_faces(em, 0); - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(em, FALSE, FALSE); return OPERATOR_FINISHED; } @@ -1845,7 +1845,7 @@ static int edbm_rotate_uvs_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -1868,7 +1868,7 @@ static int edbm_reverse_uvs_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -1895,7 +1895,7 @@ static int edbm_rotate_colors_exec(bContext *C, wmOperator *op) } /* dependencies graph and notification stuff */ - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -1919,7 +1919,7 @@ static int edbm_reverse_colors_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -2033,7 +2033,8 @@ static int merge_target(BMEditMesh *em, Scene *scene, View3D *v3d, Object *ob, { BMIter iter; BMVert *v; - float *vco = NULL, co[3], cent[3] = {0.0f, 0.0f, 0.0f}; + float co[3], cent[3] = {0.0f, 0.0f, 0.0f}; + const float *vco = NULL; if (target) { vco = give_cursor(scene, v3d); @@ -2104,7 +2105,7 @@ static int edbm_merge_exec(bContext *C, wmOperator *op) if (!status) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -2221,7 +2222,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 vertices", count); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -2328,7 +2329,7 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op) EDBM_selectmode_flush(em); - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(em, FALSE, FALSE); /* we succeeded */ return OPERATOR_FINISHED; @@ -2403,7 +2404,7 @@ static int edbm_shape_propagate_to_all_exec(bContext *C, wmOperator *op) shape_propagate(em, op); - EDBM_update_generic(C, em, FALSE); + EDBM_update_generic(em, FALSE, FALSE); return OPERATOR_FINISHED; } @@ -2474,7 +2475,7 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op) } } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -2665,7 +2666,7 @@ static int edbm_solidify_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -2990,7 +2991,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3232,7 +3233,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op) else BLI_assert(0); if (retval) { - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); } } else { @@ -3332,7 +3333,7 @@ static int edbm_fill_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; @@ -3361,7 +3362,7 @@ static int edbm_beautify_fill_exec(bContext *C, wmOperator *op) if (!EDBM_op_callf(em, op, "beautify_fill faces=%hf", BM_ELEM_SELECT)) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3392,7 +3393,7 @@ static int edbm_quads_convert_to_tris_exec(bContext *C, wmOperator *op) if (!EDBM_op_callf(em, op, "triangulate faces=%hf use_beauty=%b", BM_ELEM_SELECT, use_beauty)) return OPERATOR_CANCELLED; - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3433,7 +3434,7 @@ static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3489,7 +3490,7 @@ static int edbm_dissolve_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3561,7 +3562,7 @@ static int edbm_dissolve_limited_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3606,7 +3607,7 @@ static int edbm_split_exec(bContext *C, wmOperator *op) /* Geometry has changed, need to recalc normals and looptris */ EDBM_mesh_normals_update(em); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3665,7 +3666,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3777,7 +3778,7 @@ static int edbm_screw_exec(bContext *C, wmOperator *op) if (!EDBM_op_init(em, &spinop, op, "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f use_duplicate=%b", - BM_ELEM_SELECT, cent, axis, dvec, turns * steps, 360.0f * turns, FALSE)) + BM_ELEM_SELECT, cent, axis, dvec, turns * steps, DEG2RADF(360.0f * turns), FALSE)) { return OPERATOR_CANCELLED; } @@ -3788,7 +3789,7 @@ static int edbm_screw_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } @@ -3822,8 +3823,8 @@ void MESH_OT_screw(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* props */ - RNA_def_int(ot->srna, "steps", 9, 0, INT_MAX, "Steps", "Steps", 0, 256); - RNA_def_int(ot->srna, "turns", 1, 0, INT_MAX, "Turns", "Turns", 0, 256); + RNA_def_int(ot->srna, "steps", 9, 1, INT_MAX, "Steps", "Steps", 3, 256); + RNA_def_int(ot->srna, "turns", 1, 1, INT_MAX, "Turns", "Turns", 1, 256); RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX); @@ -4603,7 +4604,7 @@ static int edbm_noise_exec(bContext *C, wmOperator *op) EDBM_mesh_normals_update(em); - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, FALSE); return OPERATOR_FINISHED; } @@ -4762,7 +4763,7 @@ static int edbm_bevel_init(bContext *C, wmOperator *op, int is_modal) return 1; } -static int edbm_bevel_calc(bContext *C, wmOperator *op) +static int edbm_bevel_calc(wmOperator *op) { BevelData *opdata = op->customdata; BMEditMesh *em = opdata->em; @@ -4827,7 +4828,7 @@ static int edbm_bevel_calc(bContext *C, wmOperator *op) EDBM_mesh_normals_update(opdata->em); - EDBM_update_generic(C, opdata->em, TRUE); + EDBM_update_generic(opdata->em, TRUE, TRUE); return 1; } @@ -4859,7 +4860,7 @@ static int edbm_bevel_cancel(bContext *C, wmOperator *op) BevelData *opdata = op->customdata; if (opdata->is_modal) { EDBM_redo_state_free(&opdata->mesh_backup, opdata->em, TRUE); - EDBM_update_generic(C, opdata->em, FALSE); + EDBM_update_generic(opdata->em, FALSE, TRUE); } edbm_bevel_exit(C, op); @@ -4877,7 +4878,7 @@ static int edbm_bevel_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - if (!edbm_bevel_calc(C, op)) { + if (!edbm_bevel_calc(op)) { edbm_bevel_cancel(C, op); return OPERATOR_CANCELLED; } @@ -4914,7 +4915,7 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event) edbm_bevel_update_header(op, C); - if (!edbm_bevel_calc(C, op)) { + if (!edbm_bevel_calc(op)) { edbm_bevel_cancel(C, op); return OPERATOR_CANCELLED; } @@ -4950,9 +4951,9 @@ static float edbm_bevel_mval_factor(wmOperator *op, wmEvent *event) if (event->shift) { if (opdata->shift_factor < 0.0f) { #ifdef NEW_BEVEL - opdata->shift_factor = RNA_float_get(op->ptr, "factor"); -#else opdata->shift_factor = RNA_float_get(op->ptr, "percent"); +#else + opdata->shift_factor = RNA_float_get(op->ptr, "factor"); #endif } factor = (factor - opdata->shift_factor) * 0.1f + opdata->shift_factor; @@ -4984,7 +4985,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) float value = RNA_float_get(op->ptr, "offset"); applyNumInput(&opdata->num_input, &value); RNA_float_set(op->ptr, "offset", value); - edbm_bevel_calc(C, op); + edbm_bevel_calc(op); edbm_bevel_update_header(op, C); return OPERATOR_RUNNING_MODAL; } @@ -5017,7 +5018,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) RNA_float_set(op->ptr, "percent", factor); #endif - edbm_bevel_calc(C, op); + edbm_bevel_calc(op); edbm_bevel_update_header(op, C); } break; @@ -5025,7 +5026,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) case LEFTMOUSE: case PADENTER: case RETKEY: - edbm_bevel_calc(C, op); + edbm_bevel_calc(op); edbm_bevel_exit(C, op); return OPERATOR_FINISHED; @@ -5037,7 +5038,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) segments++; RNA_int_set(op->ptr, "segments", segments); - edbm_bevel_calc(C, op); + edbm_bevel_calc(op); edbm_bevel_update_header(op, C); break; @@ -5048,7 +5049,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) segments = max_ii(segments - 1, 1); RNA_int_set(op->ptr, "segments", segments); - edbm_bevel_calc(C, op); + edbm_bevel_calc(op); edbm_bevel_update_header(op, C); break; @@ -5140,7 +5141,7 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op) } else { - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } } @@ -5263,7 +5264,7 @@ static int edbm_inset_cancel(bContext *C, wmOperator *op) opdata = op->customdata; if (opdata->is_modal) { EDBM_redo_state_free(&opdata->backup, opdata->em, TRUE); - EDBM_update_generic(C, opdata->em, FALSE); + EDBM_update_generic(opdata->em, FALSE, TRUE); } edbm_inset_exit(C, op); @@ -5273,7 +5274,7 @@ static int edbm_inset_cancel(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } -static int edbm_inset_calc(bContext *C, wmOperator *op) +static int edbm_inset_calc(wmOperator *op) { InsetData *opdata; BMEditMesh *em; @@ -5318,7 +5319,7 @@ static int edbm_inset_calc(bContext *C, wmOperator *op) return 0; } else { - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return 1; } } @@ -5327,7 +5328,7 @@ static int edbm_inset_exec(bContext *C, wmOperator *op) { edbm_inset_init(C, op, FALSE); - if (!edbm_inset_calc(C, op)) { + if (!edbm_inset_calc(op)) { edbm_inset_exit(C, op); return OPERATOR_CANCELLED; } @@ -5358,7 +5359,7 @@ static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event) opdata->initial_length = len_v2(mlen); opdata->pixel_size = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f; - edbm_inset_calc(C, op); + edbm_inset_calc(op); edbm_inset_update_header(op, C); @@ -5381,7 +5382,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) RNA_float_set(op->ptr, "thickness", amounts[0]); RNA_float_set(op->ptr, "depth", amounts[1]); - if (edbm_inset_calc(C, op)) { + if (edbm_inset_calc(op)) { edbm_inset_update_header(op, C); return OPERATOR_RUNNING_MODAL; } @@ -5422,7 +5423,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) RNA_float_set(op->ptr, "thickness", amount); } - if (edbm_inset_calc(C, op)) + if (edbm_inset_calc(op)) edbm_inset_update_header(op, C); else { edbm_inset_cancel(C, op); @@ -5434,7 +5435,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) case LEFTMOUSE: case PADENTER: case RETKEY: - edbm_inset_calc(C, op); + edbm_inset_calc(op); edbm_inset_exit(C, op); return OPERATOR_FINISHED; @@ -5483,7 +5484,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) if (event->val == KM_PRESS) { int use_outset = RNA_boolean_get(op->ptr, "use_outset"); RNA_boolean_set(op->ptr, "use_outset", !use_outset); - if (edbm_inset_calc(C, op)) { + if (edbm_inset_calc(op)) { edbm_inset_update_header(op, C); } else { @@ -5496,7 +5497,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) if (event->val == KM_PRESS) { int use_boundary = RNA_boolean_get(op->ptr, "use_boundary"); RNA_boolean_set(op->ptr, "use_boundary", !use_boundary); - if (edbm_inset_calc(C, op)) { + if (edbm_inset_calc(op)) { edbm_inset_update_header(op, C); } else { @@ -5581,7 +5582,7 @@ static int edbm_wireframe_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); return OPERATOR_FINISHED; } } @@ -5671,7 +5672,7 @@ static int edbm_convex_hull_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); EDBM_selectmode_flush(em); return OPERATOR_FINISHED; } @@ -5726,7 +5727,7 @@ static int mesh_symmetrize_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { - EDBM_update_generic(C, em, TRUE); + EDBM_update_generic(em, TRUE, TRUE); EDBM_selectmode_flush(em); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 2cf63586142..b1094c75f27 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -391,81 +391,129 @@ void EDBM_mesh_free(BMEditMesh *em) BMEdit_Free(em); } -void EDBM_index_arrays_init(BMEditMesh *tm, int forvert, int foredge, int forface) + +void EDBM_index_arrays_ensure(BMEditMesh *em, const char htype) { - EDBM_index_arrays_free(tm); + /* assume if the array is non-null then its valid and no need to recalc */ + const char htype_needed = ((em->vert_index ? 0 : BM_VERT) | + (em->edge_index ? 0 : BM_EDGE) | + (em->face_index ? 0 : BM_FACE)) & htype; - if (forvert) { - BMIter iter; - BMVert *ele; - int i = 0; - - tm->vert_index = MEM_mallocN(sizeof(void **) * tm->bm->totvert, "tm->vert_index"); + BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); - ele = BM_iter_new(&iter, tm->bm, BM_VERTS_OF_MESH, NULL); - for ( ; ele; ele = BM_iter_step(&iter)) { - tm->vert_index[i++] = ele; + /* in debug mode double check we didn't need to recalculate */ + BLI_assert(EDBM_index_arrays_check(em) == TRUE); + + if (htype_needed & BM_VERT) { + em->vert_index = MEM_mallocN(sizeof(void **) * em->bm->totvert, "em->vert_index"); + } + if (htype_needed & BM_EDGE) { + em->edge_index = MEM_mallocN(sizeof(void **) * em->bm->totedge, "em->edge_index"); + } + if (htype_needed & BM_FACE) { + em->face_index = MEM_mallocN(sizeof(void **) * em->bm->totface, "em->face_index"); + } + +#pragma omp parallel sections if (em->bm->totvert + em->bm->totedge + em->bm->totface >= BM_OMP_LIMIT) + { +#pragma omp section + { + if (htype_needed & BM_VERT) { + BM_iter_as_array(em->bm, BM_VERTS_OF_MESH, NULL, (void **)em->vert_index, em->bm->totvert); + } + } +#pragma omp section + { + if (htype_needed & BM_EDGE) { + BM_iter_as_array(em->bm, BM_EDGES_OF_MESH, NULL, (void **)em->edge_index, em->bm->totedge); + } + } +#pragma omp section + { + if (htype_needed & BM_FACE) { + BM_iter_as_array(em->bm, BM_FACES_OF_MESH, NULL, (void **)em->face_index, em->bm->totface); + } } } +} - if (foredge) { - BMIter iter; - BMEdge *ele; - int i = 0; - - tm->edge_index = MEM_mallocN(sizeof(void **) * tm->bm->totedge, "tm->edge_index"); +/* use EDBM_index_arrays_ensure where possible to avoid full rebuild */ +void EDBM_index_arrays_init(BMEditMesh *em, const char htype) +{ + BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); - ele = BM_iter_new(&iter, tm->bm, BM_EDGES_OF_MESH, NULL); - for ( ; ele; ele = BM_iter_step(&iter)) { - tm->edge_index[i++] = ele; - } + /* force recalc */ + EDBM_index_arrays_free(em); + EDBM_index_arrays_ensure(em, htype); +} + +void EDBM_index_arrays_free(BMEditMesh *em) +{ + if (em->vert_index) { + MEM_freeN(em->vert_index); + em->vert_index = NULL; } - if (forface) { - BMIter iter; - BMFace *ele; - int i = 0; - - tm->face_index = MEM_mallocN(sizeof(void **) * tm->bm->totface, "tm->face_index"); + if (em->edge_index) { + MEM_freeN(em->edge_index); + em->edge_index = NULL; + } - ele = BM_iter_new(&iter, tm->bm, BM_FACES_OF_MESH, NULL); - for ( ; ele; ele = BM_iter_step(&iter)) { - tm->face_index[i++] = ele; - } + if (em->face_index) { + MEM_freeN(em->face_index); + em->face_index = NULL; } } -void EDBM_index_arrays_free(BMEditMesh *tm) +/* debug check only - no need to optimize */ +#ifndef NDEBUG +int EDBM_index_arrays_check(BMEditMesh *em) { - if (tm->vert_index) { - MEM_freeN(tm->vert_index); - tm->vert_index = NULL; + BMIter iter; + BMElem *ele; + int i; + + if (em->vert_index) { + BM_ITER_MESH_INDEX (ele, &iter, em->bm, BM_VERTS_OF_MESH, i) { + if (ele != (BMElem *)em->vert_index[i]) { + return FALSE; + } + } } - if (tm->edge_index) { - MEM_freeN(tm->edge_index); - tm->edge_index = NULL; + if (em->edge_index) { + BM_ITER_MESH_INDEX (ele, &iter, em->bm, BM_EDGES_OF_MESH, i) { + if (ele != (BMElem *)em->edge_index[i]) { + return FALSE; + } + } } - if (tm->face_index) { - MEM_freeN(tm->face_index); - tm->face_index = NULL; + if (em->face_index) { + BM_ITER_MESH_INDEX (ele, &iter, em->bm, BM_FACES_OF_MESH, i) { + if (ele != (BMElem *)em->face_index[i]) { + return FALSE; + } + } } + + return TRUE; } +#endif -BMVert *EDBM_vert_at_index(BMEditMesh *tm, int index) +BMVert *EDBM_vert_at_index(BMEditMesh *em, int index) { - return tm->vert_index && index < tm->bm->totvert ? tm->vert_index[index] : NULL; + return em->vert_index && index < em->bm->totvert ? em->vert_index[index] : NULL; } -BMEdge *EDBM_edge_at_index(BMEditMesh *tm, int index) +BMEdge *EDBM_edge_at_index(BMEditMesh *em, int index) { - return tm->edge_index && index < tm->bm->totedge ? tm->edge_index[index] : NULL; + return em->edge_index && index < em->bm->totedge ? em->edge_index[index] : NULL; } -BMFace *EDBM_face_at_index(BMEditMesh *tm, int index) +BMFace *EDBM_face_at_index(BMEditMesh *em, int index) { - return (tm->face_index && index < tm->bm->totface && index >= 0) ? tm->face_index[index] : NULL; + return (em->face_index && index < em->bm->totface && index >= 0) ? em->face_index[index] : NULL; } void EDBM_selectmode_flush_ex(BMEditMesh *em, const short selectmode) @@ -639,7 +687,7 @@ void undo_push_mesh(bContext *C, const char *name) } /* write comment here */ -UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx_array, const float limit[2]) +UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, const float limit[2]) { BMVert *ev; BMFace *efa; @@ -652,11 +700,8 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx MLoopUV *luv; unsigned int a; int totverts, i, totuv; - - if (do_face_idx_array) - EDBM_index_arrays_init(em, 0, 0, 1); - BM_mesh_elem_index_ensure(em->bm, BM_VERT); + BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE); totverts = em->bm->totvert; totuv = 0; @@ -668,14 +713,10 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx } if (totuv == 0) { - if (do_face_idx_array) - EDBM_index_arrays_free(em); return NULL; } vmap = (UvVertMap *)MEM_callocN(sizeof(*vmap), "UvVertMap"); if (!vmap) { - if (do_face_idx_array) - EDBM_index_arrays_free(em); return NULL; } @@ -684,8 +725,6 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx if (!vmap->vert || !vmap->buf) { BKE_mesh_uv_vert_map_free(vmap); - if (do_face_idx_array) - EDBM_index_arrays_free(em); return NULL; } @@ -762,10 +801,7 @@ UvVertMap *EDBM_uv_vert_map_create(BMEditMesh *em, int selected, int do_face_idx vmap->vert[a] = newvlist; a++; } - - if (do_face_idx_array) - EDBM_index_arrays_free(em); - + return vmap; } @@ -840,7 +876,6 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_is if (!selected || ((!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) && BM_elem_flag_test(efa, BM_ELEM_SELECT))) { BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { buf->l = l; - buf->face = efa; buf->separate = 0; buf->island = INVALID_ISLAND; buf->tfindex = i; @@ -912,7 +947,7 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_is for (i = 0; i < totuv; i++) { if (element_map->buf[i].island == INVALID_ISLAND) { element_map->buf[i].island = nislands; - stack[0] = element_map->buf[i].face; + stack[0] = element_map->buf[i].l->f; island_number[BM_elem_index_get(stack[0])] = nislands; stacksize = 1; @@ -926,12 +961,11 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_is if (element->separate) initelement = element; - if (element->face == efa) { + if (element->l->f == efa) { /* found the uv corresponding to our face and vertex. Now fill it to the buffer */ element->island = nislands; map[element - element_map->buf] = islandbufsize; islandbuf[islandbufsize].l = element->l; - islandbuf[islandbufsize].face = element->face; islandbuf[islandbufsize].separate = element->separate; islandbuf[islandbufsize].tfindex = element->tfindex; islandbuf[islandbufsize].island = nislands; @@ -941,9 +975,9 @@ UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_is if (element->separate && element != initelement) break; - if (island_number[BM_elem_index_get(element->face)] == INVALID_ISLAND) { - stack[stacksize++] = element->face; - island_number[BM_elem_index_get(element->face)] = nislands; + if (island_number[BM_elem_index_get(element->l->f)] == INVALID_ISLAND) { + stack[stacksize++] = element->l->f; + island_number[BM_elem_index_get(element->l->f)] = nislands; } } break; @@ -1024,7 +1058,7 @@ UvElement *ED_uv_element_get(UvElementMap *map, BMFace *efa, BMLoop *l) element = map->vert[BM_elem_index_get(l->v)]; for (; element; element = element->next) - if (element->face == efa) + if (element->l->f == efa) return element; return NULL; @@ -1110,10 +1144,7 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const short use_select) topo = 1; } - if (!em->vert_index) { - EDBM_index_arrays_init(em, 1, 0, 0); - em->mirr_free_arrays = 1; - } + EDBM_index_arrays_ensure(em, BM_VERT); if (!CustomData_get_layer_named(&bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID)) { BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID); @@ -1205,11 +1236,6 @@ void EDBM_verts_mirror_cache_clear(BMEditMesh *em, BMVert *v) void EDBM_verts_mirror_cache_end(BMEditMesh *em) { - if (em->mirr_free_arrays) { - MEM_freeN(em->vert_index); - em->vert_index = NULL; - } - em->mirror_cdlayer = -1; } @@ -1283,6 +1309,7 @@ void EDBM_mesh_reveal(BMEditMesh *em) /* Use tag flag to remember what was hidden before all is revealed. * BM_ELEM_HIDDEN --> BM_ELEM_TAG */ +#pragma omp parallel for schedule(dynamic) if (em->bm->totvert + em->bm->totedge + em->bm->totface >= BM_OMP_LIMIT) for (i = 0; i < 3; i++) { BM_ITER_MESH (ele, &iter, em->bm, iter_types[i]) { BM_elem_flag_set(ele, BM_ELEM_TAG, BM_elem_flag_test(ele, BM_ELEM_HIDDEN)); @@ -1313,14 +1340,22 @@ void EDBM_mesh_reveal(BMEditMesh *em) /* so many tools call these that we better make it a generic function. */ -void EDBM_update_generic(bContext *C, BMEditMesh *em, const short do_tessface) +void EDBM_update_generic(BMEditMesh *em, const short do_tessface, const short is_destructive) { Object *ob = em->ob; /* order of calling isn't important */ DAG_id_tag_update(ob->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + WM_main_add_notifier(NC_GEOM | ND_DATA, ob->data); if (do_tessface) { BMEdit_RecalcTessellation(em); } + + if (is_destructive) { + EDBM_index_arrays_free(em); + } + else { + /* in debug mode double check we didn't need to recalculate */ + BLI_assert(EDBM_index_arrays_check(em) == TRUE); + } } diff --git a/source/blender/editors/mesh/mesh_navmesh.c b/source/blender/editors/mesh/mesh_navmesh.c index 83a1261e981..21564d2d348 100644 --- a/source/blender/editors/mesh/mesh_navmesh.c +++ b/source/blender/editors/mesh/mesh_navmesh.c @@ -375,7 +375,7 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh, BM_vert_create(em->bm, co, NULL, 0); } - EDBM_index_arrays_init(em, 1, 0, 0); + EDBM_index_arrays_ensure(em, BM_VERT); /* create faces */ for (j = 0; j < trinum; j++) { @@ -399,8 +399,6 @@ static Object *createRepresentation(bContext *C, struct recast_polyMesh *pmesh, polygonIdx = (int *)CustomData_bmesh_get(&em->bm->pdata, newFace->head.data, CD_RECAST); *polygonIdx = i + 1; /* add 1 to avoid zero idx */ } - - EDBM_index_arrays_free(em); } recast_destroyPolyMesh(pmesh); diff --git a/source/blender/editors/metaball/SConscript b/source/blender/editors/metaball/SConscript index b1a1ce935db..7083eff863e 100644 --- a/source/blender/editors/metaball/SConscript +++ b/source/blender/editors/metaball/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/object/SConscript b/source/blender/editors/object/SConscript index b53ea549853..df51198df92 100644 --- a/source/blender/editors/object/SConscript +++ b/source/blender/editors/object/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 7c4a547debc..b21b77e4e34 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -146,7 +146,7 @@ void ED_object_location_from_view(bContext *C, float loc[3]) { View3D *v3d = CTX_wm_view3d(C); Scene *scene = CTX_data_scene(C); - float *cursor; + const float *cursor; cursor = give_cursor(scene, v3d); @@ -186,7 +186,7 @@ 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][4], int apply_diameter) { Scene *scene = CTX_data_scene(C); @@ -936,6 +936,8 @@ static int object_delete_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + wmWindowManager *wm = CTX_wm_manager(C); + wmWindow *win; const short use_global = RNA_boolean_get(op->ptr, "use_global"); if (CTX_data_edit_object(C)) @@ -967,12 +969,22 @@ static int object_delete_exec(bContext *C, wmOperator *op) } CTX_DATA_END; - DAG_scene_sort(bmain, scene); + /* delete has to handle all open scenes */ + flag_listbase_ids(&bmain->scene, LIB_DOIT, 1); + for (win = wm->windows.first; win; win = win->next) { + scene = win->screen->scene; + + if (scene->id.flag & LIB_DOIT) { + scene->id.flag &= ~LIB_DOIT; + + DAG_scene_sort(bmain, scene); + + WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); + WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); + } + } DAG_ids_flush_update(bmain, 0); - WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); - WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); - return OPERATOR_FINISHED; } diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index e144c38a350..8b40379f88d 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -64,6 +64,7 @@ #include "RE_pipeline.h" #include "RE_shader_ext.h" +#include "RE_multires_bake.h" #include "PIL_time.h" @@ -95,829 +96,12 @@ typedef struct { ListBase data; int bake_clear, bake_filter; short mode, use_lores_mesh; + int number_of_rays; + float bias; + int raytrace_structure; + int octree_resolution; } MultiresBakeJob; -/* data passing to multires baker */ -typedef struct { - DerivedMesh *lores_dm, *hires_dm; - int simple, lvl, tot_lvl, bake_filter; - short mode, use_lores_mesh; - - int tot_obj, tot_image; - ListBase image; - - int baked_objects, baked_faces; - - short *stop; - short *do_update; - float *progress; -} MultiresBakeRender; - -typedef void (*MPassKnownData)(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data, - ImBuf *ibuf, const int face_index, const int lvl, const float st[2], - float tangmat[3][3], const int x, const int y); - -typedef void * (*MInitBakeData)(MultiresBakeRender *bkr, Image *ima); -typedef void (*MApplyBakeData)(void *bake_data); -typedef void (*MFreeBakeData)(void *bake_data); - -typedef struct { - MVert *mvert; - MFace *mface; - MTFace *mtface; - float *pvtangent; - float *precomputed_normals; - int w, h; - int face_index; - int i0, i1, i2; - DerivedMesh *lores_dm, *hires_dm; - int lvl; - void *bake_data; - ImBuf *ibuf; - MPassKnownData pass_data; -} MResolvePixelData; - -typedef void (*MFlushPixel)(const MResolvePixelData *data, const int x, const int y); - -typedef struct { - int w, h; - char *texels; - const MResolvePixelData *data; - MFlushPixel flush_pixel; -} MBakeRast; - -typedef struct { - float *heights; - float height_min, height_max; - Image *ima; - DerivedMesh *ssdm; - const int *orig_index_mf_to_mpoly; - const int *orig_index_mp_to_orig; -} MHeightBakeData; - -typedef struct { - const int *orig_index_mf_to_mpoly; - const int *orig_index_mp_to_orig; -} MNormalBakeData; - -static void multiresbake_get_normal(const MResolvePixelData *data, float norm[], const int face_num, const int vert_index) -{ - unsigned int indices[] = {data->mface[face_num].v1, data->mface[face_num].v2, - data->mface[face_num].v3, data->mface[face_num].v4}; - const int smoothnormal = (data->mface[face_num].flag & ME_SMOOTH); - - if (!smoothnormal) { /* flat */ - if (data->precomputed_normals) { - copy_v3_v3(norm, &data->precomputed_normals[3 * face_num]); - } - else { - float nor[3]; - float *p0, *p1, *p2; - const int iGetNrVerts = data->mface[face_num].v4 != 0 ? 4 : 3; - - p0 = data->mvert[indices[0]].co; - p1 = data->mvert[indices[1]].co; - p2 = data->mvert[indices[2]].co; - - if (iGetNrVerts == 4) { - float *p3 = data->mvert[indices[3]].co; - normal_quad_v3(nor, p0, p1, p2, p3); - } - else { - normal_tri_v3(nor, p0, p1, p2); - } - - copy_v3_v3(norm, nor); - } - } - else { - short *no = data->mvert[indices[vert_index]].no; - - normal_short_to_float_v3(norm, no); - normalize_v3(norm); - } -} - -static void init_bake_rast(MBakeRast *bake_rast, const ImBuf *ibuf, const MResolvePixelData *data, MFlushPixel flush_pixel) -{ - memset(bake_rast, 0, sizeof(MBakeRast)); - - bake_rast->texels = ibuf->userdata; - bake_rast->w = ibuf->x; - bake_rast->h = ibuf->y; - bake_rast->data = data; - bake_rast->flush_pixel = flush_pixel; -} - -static void flush_pixel(const MResolvePixelData *data, const int x, const int y) -{ - float st[2] = {(x + 0.5f) / data->w, (y + 0.5f) / data->h}; - float *st0, *st1, *st2; - float *tang0, *tang1, *tang2; - float no0[3], no1[3], no2[3]; - float fUV[2], from_tang[3][3], to_tang[3][3]; - float u, v, w, sign; - int r; - - const int i0 = data->i0; - const int i1 = data->i1; - const int i2 = data->i2; - - st0 = data->mtface[data->face_index].uv[i0]; - st1 = data->mtface[data->face_index].uv[i1]; - st2 = data->mtface[data->face_index].uv[i2]; - - tang0 = data->pvtangent + data->face_index * 16 + i0 * 4; - tang1 = data->pvtangent + data->face_index * 16 + i1 * 4; - tang2 = data->pvtangent + data->face_index * 16 + i2 * 4; - - multiresbake_get_normal(data, no0, data->face_index, i0); /* can optimize these 3 into one call */ - multiresbake_get_normal(data, no1, data->face_index, i1); - multiresbake_get_normal(data, no2, data->face_index, i2); - - resolve_tri_uv(fUV, st, st0, st1, st2); - - u = fUV[0]; - v = fUV[1]; - w = 1 - u - v; - - /* the sign is the same at all face vertices for any non degenerate face. - * Just in case we clamp the interpolated value though. */ - sign = (tang0[3] * u + tang1[3] * v + tang2[3] * w) < 0 ? (-1.0f) : 1.0f; - - /* this sequence of math is designed specifically as is with great care - * to be compatible with our shader. Please don't change without good reason. */ - for (r = 0; r < 3; r++) { - from_tang[0][r] = tang0[r] * u + tang1[r] * v + tang2[r] * w; - from_tang[2][r] = no0[r] * u + no1[r] * v + no2[r] * w; - } - - cross_v3_v3v3(from_tang[1], from_tang[2], from_tang[0]); /* B = sign * cross(N, T) */ - mul_v3_fl(from_tang[1], sign); - invert_m3_m3(to_tang, from_tang); - /* sequence end */ - - data->pass_data(data->lores_dm, data->hires_dm, data->bake_data, - data->ibuf, data->face_index, data->lvl, st, to_tang, x, y); -} - -static void set_rast_triangle(const MBakeRast *bake_rast, const int x, const int y) -{ - const int w = bake_rast->w; - const int h = bake_rast->h; - - if (x >= 0 && x < w && y >= 0 && y < h) { - if ((bake_rast->texels[y * w + x]) == 0) { - flush_pixel(bake_rast->data, x, y); - bake_rast->texels[y * w + x] = FILTER_MASK_USED; - } - } -} - -static void rasterize_half(const MBakeRast *bake_rast, - const float s0_s, const float t0_s, const float s1_s, const float t1_s, - const float s0_l, const float t0_l, const float s1_l, const float t1_l, - const int y0_in, const int y1_in, const int is_mid_right) -{ - const int s_stable = fabsf(t1_s - t0_s) > FLT_EPSILON ? 1 : 0; - const int l_stable = fabsf(t1_l - t0_l) > FLT_EPSILON ? 1 : 0; - const int w = bake_rast->w; - const int h = bake_rast->h; - int y, y0, y1; - - if (y1_in <= 0 || y0_in >= h) - return; - - y0 = y0_in < 0 ? 0 : y0_in; - y1 = y1_in >= h ? h : y1_in; - - for (y = y0; y < y1; y++) { - /*-b(x-x0) + a(y-y0) = 0 */ - int iXl, iXr, x; - float x_l = s_stable != 0 ? (s0_s + (((s1_s - s0_s) * (y - t0_s)) / (t1_s - t0_s))) : s0_s; - float x_r = l_stable != 0 ? (s0_l + (((s1_l - s0_l) * (y - t0_l)) / (t1_l - t0_l))) : s0_l; - - if (is_mid_right != 0) - SWAP(float, x_l, x_r); - - iXl = (int)ceilf(x_l); - iXr = (int)ceilf(x_r); - - if (iXr > 0 && iXl < w) { - iXl = iXl < 0 ? 0 : iXl; - iXr = iXr >= w ? w : iXr; - - for (x = iXl; x < iXr; x++) - set_rast_triangle(bake_rast, x, y); - } - } -} - -static void bake_rasterize(const MBakeRast *bake_rast, const float st0_in[2], const float st1_in[2], const float st2_in[2]) -{ - const int w = bake_rast->w; - const int h = bake_rast->h; - float slo = st0_in[0] * w - 0.5f; - float tlo = st0_in[1] * h - 0.5f; - float smi = st1_in[0] * w - 0.5f; - float tmi = st1_in[1] * h - 0.5f; - float shi = st2_in[0] * w - 0.5f; - float thi = st2_in[1] * h - 0.5f; - int is_mid_right = 0, ylo, yhi, yhi_beg; - - /* skip degenerates */ - if ((slo == smi && tlo == tmi) || (slo == shi && tlo == thi) || (smi == shi && tmi == thi)) - return; - - /* sort by T */ - if (tlo > tmi && tlo > thi) { - SWAP(float, shi, slo); - SWAP(float, thi, tlo); - } - else if (tmi > thi) { - SWAP(float, shi, smi); - SWAP(float, thi, tmi); - } - - if (tlo > tmi) { - SWAP(float, slo, smi); - SWAP(float, tlo, tmi); - } - - /* check if mid point is to the left or to the right of the lo-hi edge */ - is_mid_right = (-(shi - slo) * (tmi - thi) + (thi - tlo) * (smi - shi)) > 0 ? 1 : 0; - ylo = (int) ceilf(tlo); - yhi_beg = (int) ceilf(tmi); - yhi = (int) ceilf(thi); - - /*if (fTmi>ceilf(fTlo))*/ - rasterize_half(bake_rast, slo, tlo, smi, tmi, slo, tlo, shi, thi, ylo, yhi_beg, is_mid_right); - rasterize_half(bake_rast, smi, tmi, shi, thi, slo, tlo, shi, thi, yhi_beg, yhi, is_mid_right); -} - -static int multiresbake_test_break(MultiresBakeRender *bkr) -{ - if (!bkr->stop) { - /* this means baker is executed outside from job system */ - return 0; - } - - return G.is_break; -} - -static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, MPassKnownData passKnownData, - MInitBakeData initBakeData, MApplyBakeData applyBakeData, MFreeBakeData freeBakeData) -{ - DerivedMesh *dm = bkr->lores_dm; - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); - const int lvl = bkr->lvl; - const int tot_face = dm->getNumTessFaces(dm); - MVert *mvert = dm->getVertArray(dm); - MFace *mface = dm->getTessFaceArray(dm); - MTFace *mtface = dm->getTessFaceDataArray(dm, CD_MTFACE); - float *pvtangent = NULL; - - if (CustomData_get_layer_index(&dm->faceData, CD_TANGENT) == -1) - DM_add_tangent_layer(dm); - - pvtangent = DM_get_tessface_data_layer(dm, CD_TANGENT); - - if (tot_face > 0) { /* sanity check */ - int f = 0; - MBakeRast bake_rast; - MResolvePixelData data = {NULL}; - - data.mface = mface; - data.mvert = mvert; - data.mtface = mtface; - data.pvtangent = pvtangent; - data.precomputed_normals = dm->getTessFaceDataArray(dm, CD_NORMAL); /* don't strictly need this */ - data.w = ibuf->x; - data.h = ibuf->y; - data.lores_dm = dm; - data.hires_dm = bkr->hires_dm; - data.lvl = lvl; - data.pass_data = passKnownData; - - if (initBakeData) - data.bake_data = initBakeData(bkr, ima); - - init_bake_rast(&bake_rast, ibuf, &data, flush_pixel); - - for (f = 0; f < tot_face; f++) { - MTFace *mtfate = &mtface[f]; - int verts[3][2], nr_tris, t; - - if (multiresbake_test_break(bkr)) - break; - - if (mtfate->tpage != ima) - continue; - - data.face_index = f; - data.ibuf = ibuf; - - /* might support other forms of diagonal splits later on such as - * split by shortest diagonal.*/ - verts[0][0] = 0; - verts[1][0] = 1; - verts[2][0] = 2; - - verts[0][1] = 0; - verts[1][1] = 2; - verts[2][1] = 3; - - nr_tris = mface[f].v4 != 0 ? 2 : 1; - for (t = 0; t < nr_tris; t++) { - data.i0 = verts[0][t]; - data.i1 = verts[1][t]; - data.i2 = verts[2][t]; - - bake_rasterize(&bake_rast, mtfate->uv[data.i0], mtfate->uv[data.i1], mtfate->uv[data.i2]); - } - - bkr->baked_faces++; - - if (bkr->do_update) - *bkr->do_update = TRUE; - - if (bkr->progress) - *bkr->progress = ((float)bkr->baked_objects + (float)bkr->baked_faces / tot_face) / bkr->tot_obj; - } - - if (applyBakeData) - applyBakeData(data.bake_data); - - if (freeBakeData) - freeBakeData(data.bake_data); - } - - BKE_image_release_ibuf(ima, ibuf, NULL); -} - -/* mode = 0: interpolate normals, - * mode = 1: interpolate coord */ -static void interp_bilinear_grid(CCGKey *key, CCGElem *grid, float crn_x, float crn_y, int mode, float res[3]) -{ - int x0, x1, y0, y1; - float u, v; - float data[4][3]; - - x0 = (int) crn_x; - x1 = x0 >= (key->grid_size - 1) ? (key->grid_size - 1) : (x0 + 1); - - y0 = (int) crn_y; - y1 = y0 >= (key->grid_size - 1) ? (key->grid_size - 1) : (y0 + 1); - - u = crn_x - x0; - v = crn_y - y0; - - if (mode == 0) { - copy_v3_v3(data[0], CCG_grid_elem_no(key, grid, x0, y0)); - copy_v3_v3(data[1], CCG_grid_elem_no(key, grid, x1, y0)); - copy_v3_v3(data[2], CCG_grid_elem_no(key, grid, x1, y1)); - copy_v3_v3(data[3], CCG_grid_elem_no(key, grid, x0, y1)); - } - else { - copy_v3_v3(data[0], CCG_grid_elem_co(key, grid, x0, y0)); - copy_v3_v3(data[1], CCG_grid_elem_co(key, grid, x1, y0)); - copy_v3_v3(data[2], CCG_grid_elem_co(key, grid, x1, y1)); - copy_v3_v3(data[3], CCG_grid_elem_co(key, grid, x0, y1)); - } - - interp_bilinear_quad_v3(data, u, v, res); -} - -static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm, - const int *index_mf_to_mpoly, const int *index_mp_to_orig, - const int lvl, const int face_index, const float u, const float v, float co[3], float n[3]) -{ - MFace mface; - CCGElem **grid_data; - CCGKey key; - float crn_x, crn_y; - int grid_size, S, face_side; - int *grid_offset, g_index; - - lodm->getTessFace(lodm, face_index, &mface); - - grid_size = hidm->getGridSize(hidm); - grid_data = hidm->getGridData(hidm); - grid_offset = hidm->getGridOffset(hidm); - hidm->getGridKey(hidm, &key); - - face_side = (grid_size << 1) - 1; - - if (lvl == 0) { - g_index = grid_offset[face_index]; - S = mdisp_rot_face_to_crn(mface.v4 ? 4 : 3, face_side, u * (face_side - 1), v * (face_side - 1), &crn_x, &crn_y); - } - else { - int side = (1 << (lvl - 1)) + 1; - int grid_index = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, face_index); - int loc_offs = face_index % (1 << (2 * lvl)); - int cell_index = loc_offs % ((side - 1) * (side - 1)); - int cell_side = (grid_size - 1) / (side - 1); - int row = cell_index / (side - 1); - int col = cell_index % (side - 1); - - S = face_index / (1 << (2 * (lvl - 1))) - grid_offset[grid_index]; - g_index = grid_offset[grid_index]; - - crn_y = (row * cell_side) + u * cell_side; - crn_x = (col * cell_side) + v * cell_side; - } - - CLAMP(crn_x, 0.0f, grid_size); - CLAMP(crn_y, 0.0f, grid_size); - - if (n != NULL) - interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 0, n); - - if (co != NULL) - interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 1, co); -} - -/* mode = 0: interpolate normals, - * mode = 1: interpolate coord */ -static void interp_bilinear_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3]) -{ - float data[4][3]; - - if (mode == 0) { - dm->getVertNo(dm, mface->v1, data[0]); - dm->getVertNo(dm, mface->v2, data[1]); - dm->getVertNo(dm, mface->v3, data[2]); - dm->getVertNo(dm, mface->v4, data[3]); - } - else { - dm->getVertCo(dm, mface->v1, data[0]); - dm->getVertCo(dm, mface->v2, data[1]); - dm->getVertCo(dm, mface->v3, data[2]); - dm->getVertCo(dm, mface->v4, data[3]); - } - - interp_bilinear_quad_v3(data, u, v, res); -} - -/* mode = 0: interpolate normals, - * mode = 1: interpolate coord */ -static void interp_barycentric_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3]) -{ - float data[3][3]; - - if (mode == 0) { - dm->getVertNo(dm, mface->v1, data[0]); - dm->getVertNo(dm, mface->v2, data[1]); - dm->getVertNo(dm, mface->v3, data[2]); - } - else { - dm->getVertCo(dm, mface->v1, data[0]); - dm->getVertCo(dm, mface->v2, data[1]); - dm->getVertCo(dm, mface->v3, data[2]); - } - - interp_barycentric_tri_v3(data, u, v, res); -} - -static void *init_heights_data(MultiresBakeRender *bkr, Image *ima) -{ - MHeightBakeData *height_data; - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); - DerivedMesh *lodm = bkr->lores_dm; - - height_data = MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData"); - - height_data->ima = ima; - height_data->heights = MEM_callocN(sizeof(float) * ibuf->x * ibuf->y, "MultiresBake heights"); - height_data->height_max = -FLT_MAX; - height_data->height_min = FLT_MAX; - - if (!bkr->use_lores_mesh) { - SubsurfModifierData smd = {{NULL}}; - int ss_lvl = bkr->tot_lvl - bkr->lvl; - - CLAMP(ss_lvl, 0, 6); - - if (ss_lvl > 0) { - smd.levels = smd.renderLevels = ss_lvl; - smd.flags |= eSubsurfModifierFlag_SubsurfUv; - - if (bkr->simple) - smd.subdivType = ME_SIMPLE_SUBSURF; - - height_data->ssdm = subsurf_make_derived_from_derived(bkr->lores_dm, &smd, NULL, 0); - } - } - - height_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX); - height_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX); - - BKE_image_release_ibuf(ima, ibuf, NULL); - - return (void *)height_data; -} - -static void *init_normal_data(MultiresBakeRender *bkr, Image *UNUSED(ima)) -{ - MNormalBakeData *normal_data; - DerivedMesh *lodm = bkr->lores_dm; - - normal_data = MEM_callocN(sizeof(MNormalBakeData), "MultiresBake normalData"); - - normal_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX); - normal_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX); - - return (void *)normal_data; -} - -static void free_normal_data(void *bake_data) -{ - MNormalBakeData *normal_data = (MNormalBakeData *)bake_data; - - MEM_freeN(normal_data); -} - -static void apply_heights_data(void *bake_data) -{ - MHeightBakeData *height_data = (MHeightBakeData *)bake_data; - ImBuf *ibuf = BKE_image_acquire_ibuf(height_data->ima, NULL, NULL); - int x, y, i; - float height, *heights = height_data->heights; - float min = height_data->height_min, max = height_data->height_max; - - for (x = 0; x < ibuf->x; x++) { - for (y = 0; y < ibuf->y; y++) { - i = ibuf->x * y + x; - - if (((char *)ibuf->userdata)[i] != FILTER_MASK_USED) - continue; - - if (ibuf->rect_float) { - float *rrgbf = ibuf->rect_float + i * 4; - - if (max - min > 1e-5f) height = (heights[i] - min) / (max - min); - else height = 0; - - rrgbf[0] = rrgbf[1] = rrgbf[2] = height; - } - else { - char *rrgb = (char *)ibuf->rect + i * 4; - - if (max - min > 1e-5f) height = (heights[i] - min) / (max - min); - else height = 0; - - rrgb[0] = rrgb[1] = rrgb[2] = FTOCHAR(height); - } - } - } - - ibuf->userflags = IB_RECT_INVALID | IB_DISPLAY_BUFFER_INVALID; - - BKE_image_release_ibuf(height_data->ima, ibuf, NULL); -} - -static void free_heights_data(void *bake_data) -{ - MHeightBakeData *height_data = (MHeightBakeData *)bake_data; - - if (height_data->ssdm) - height_data->ssdm->release(height_data->ssdm); - - MEM_freeN(height_data->heights); - MEM_freeN(height_data); -} - -/* MultiresBake callback for heights baking - * general idea: - * - find coord of point with specified UV in hi-res mesh (let's call it p1) - * - find coord of point and normal with specified UV in lo-res mesh (or subdivided lo-res - * mesh to make texture smoother) let's call this point p0 and n. - * - height wound be dot(n, p1-p0) */ -static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data, - ImBuf *ibuf, const int face_index, const int lvl, const float st[2], - float UNUSED(tangmat[3][3]), const int x, const int y) -{ - MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE); - MFace mface; - MHeightBakeData *height_data = (MHeightBakeData *)bake_data; - float uv[2], *st0, *st1, *st2, *st3; - int pixel = ibuf->x * y + x; - float vec[3], p0[3], p1[3], n[3], len; - - lores_dm->getTessFace(lores_dm, face_index, &mface); - - st0 = mtface[face_index].uv[0]; - st1 = mtface[face_index].uv[1]; - st2 = mtface[face_index].uv[2]; - - if (mface.v4) { - st3 = mtface[face_index].uv[3]; - resolve_quad_uv(uv, st, st0, st1, st2, st3); - } - else - resolve_tri_uv(uv, st, st0, st1, st2); - - CLAMP(uv[0], 0.0f, 1.0f); - CLAMP(uv[1], 0.0f, 1.0f); - - get_ccgdm_data(lores_dm, hires_dm, - height_data->orig_index_mf_to_mpoly, height_data->orig_index_mf_to_mpoly, - lvl, face_index, uv[0], uv[1], p1, 0); - - if (height_data->ssdm) { - get_ccgdm_data(lores_dm, height_data->ssdm, - height_data->orig_index_mf_to_mpoly, height_data->orig_index_mf_to_mpoly, - 0, face_index, uv[0], uv[1], p0, n); - } - else { - lores_dm->getTessFace(lores_dm, face_index, &mface); - - if (mface.v4) { - interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 1, p0); - interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 0, n); - } - else { - interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 1, p0); - interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 0, n); - } - } - - sub_v3_v3v3(vec, p1, p0); - len = dot_v3v3(n, vec); - - height_data->heights[pixel] = len; - if (len < height_data->height_min) height_data->height_min = len; - if (len > height_data->height_max) height_data->height_max = len; - - if (ibuf->rect_float) { - float *rrgbf = ibuf->rect_float + pixel * 4; - rrgbf[3] = 1.0f; - - ibuf->userflags = IB_RECT_INVALID; - } - else { - char *rrgb = (char *)ibuf->rect + pixel * 4; - rrgb[3] = 255; - } - - ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; -} - -/* MultiresBake callback for normals' baking - * general idea: - * - find coord and normal of point with specified UV in hi-res mesh - * - multiply it by tangmat - * - vector in color space would be norm(vec) /2 + (0.5, 0.5, 0.5) */ -static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data, - ImBuf *ibuf, const int face_index, const int lvl, const float st[2], - float tangmat[3][3], const int x, const int y) -{ - MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE); - MFace mface; - MNormalBakeData *normal_data = (MNormalBakeData *)bake_data; - float uv[2], *st0, *st1, *st2, *st3; - int pixel = ibuf->x * y + x; - float n[3], vec[3], tmp[3] = {0.5, 0.5, 0.5}; - - lores_dm->getTessFace(lores_dm, face_index, &mface); - - st0 = mtface[face_index].uv[0]; - st1 = mtface[face_index].uv[1]; - st2 = mtface[face_index].uv[2]; - - if (mface.v4) { - st3 = mtface[face_index].uv[3]; - resolve_quad_uv(uv, st, st0, st1, st2, st3); - } - else - resolve_tri_uv(uv, st, st0, st1, st2); - - CLAMP(uv[0], 0.0f, 1.0f); - CLAMP(uv[1], 0.0f, 1.0f); - - get_ccgdm_data(lores_dm, hires_dm, - normal_data->orig_index_mf_to_mpoly, normal_data->orig_index_mp_to_orig, - lvl, face_index, uv[0], uv[1], NULL, n); - - mul_v3_m3v3(vec, tangmat, n); - normalize_v3(vec); - mul_v3_fl(vec, 0.5); - add_v3_v3(vec, tmp); - - if (ibuf->rect_float) { - float *rrgbf = ibuf->rect_float + pixel * 4; - rrgbf[0] = vec[0]; - rrgbf[1] = vec[1]; - rrgbf[2] = vec[2]; - rrgbf[3] = 1.0f; - - ibuf->userflags = IB_RECT_INVALID; - } - else { - unsigned char *rrgb = (unsigned char *)ibuf->rect + pixel * 4; - rgb_float_to_uchar(rrgb, vec); - rrgb[3] = 255; - } - - ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; -} - -static void count_images(MultiresBakeRender *bkr) -{ - int a, totface; - DerivedMesh *dm = bkr->lores_dm; - MTFace *mtface = CustomData_get_layer(&dm->faceData, CD_MTFACE); - - bkr->image.first = bkr->image.last = NULL; - bkr->tot_image = 0; - - totface = dm->getNumTessFaces(dm); - - for (a = 0; a < totface; a++) - mtface[a].tpage->id.flag &= ~LIB_DOIT; - - for (a = 0; a < totface; a++) { - Image *ima = mtface[a].tpage; - if ((ima->id.flag & LIB_DOIT) == 0) { - LinkData *data = BLI_genericNodeN(ima); - BLI_addtail(&bkr->image, data); - bkr->tot_image++; - ima->id.flag |= LIB_DOIT; - } - } - - for (a = 0; a < totface; a++) - mtface[a].tpage->id.flag &= ~LIB_DOIT; -} - -static void bake_images(MultiresBakeRender *bkr) -{ - LinkData *link; - - for (link = bkr->image.first; link; link = link->next) { - Image *ima = (Image *)link->data; - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); - - if (ibuf->x > 0 && ibuf->y > 0) { - ibuf->userdata = MEM_callocN(ibuf->y * ibuf->x, "MultiresBake imbuf mask"); - - switch (bkr->mode) { - case RE_BAKE_NORMALS: - do_multires_bake(bkr, ima, apply_tangmat_callback, init_normal_data, NULL, free_normal_data); - break; - case RE_BAKE_DISPLACEMENT: - do_multires_bake(bkr, ima, apply_heights_callback, init_heights_data, - apply_heights_data, free_heights_data); - break; - } - } - - BKE_image_release_ibuf(ima, ibuf, NULL); - - ima->id.flag |= LIB_DOIT; - } -} - -static void finish_images(MultiresBakeRender *bkr) -{ - LinkData *link; - - for (link = bkr->image.first; link; link = link->next) { - Image *ima = (Image *)link->data; - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); - - if (ibuf->x <= 0 || ibuf->y <= 0) - continue; - - RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, bkr->bake_filter); - - ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID; - - if (ibuf->rect_float) - ibuf->userflags |= IB_RECT_INVALID; - - if (ibuf->mipmap[0]) { - ibuf->userflags |= IB_MIPMAP_INVALID; - imb_freemipmapImBuf(ibuf); - } - - if (ibuf->userdata) { - MEM_freeN(ibuf->userdata); - ibuf->userdata = NULL; - } - - BKE_image_release_ibuf(ima, ibuf, NULL); - } -} - -static void multiresbake_start(MultiresBakeRender *bkr) -{ - count_images(bkr); - bake_images(bkr); - finish_images(bkr); -} - static int multiresbake_check(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); @@ -1023,6 +207,9 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l if (*lvl == 0) { DerivedMesh *tmp_dm = CDDM_from_mesh(me, ob); + + DM_set_only_copy(tmp_dm, CD_MASK_BAREMESH | CD_MASK_MTFACE); + dm = CDDM_copy(tmp_dm); tmp_dm->release(tmp_dm); } @@ -1030,6 +217,8 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l MultiresModifierData tmp_mmd = *mmd; DerivedMesh *cddm = CDDM_from_mesh(me, ob); + DM_set_only_copy(cddm, CD_MASK_BAREMESH | CD_MASK_MTFACE); + tmp_mmd.lvl = *lvl; tmp_mmd.sculptlvl = *lvl; dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0); @@ -1047,6 +236,14 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l DerivedMesh *cddm = CDDM_from_mesh(me, ob); DerivedMesh *dm; + DM_set_only_copy(cddm, CD_MASK_BAREMESH); + + /* TODO: DM_set_only_copy wouldn't set mask for loop and poly data, + * but we really need BAREMESH only to save lots of memory + */ + CustomData_set_only_copy(&cddm->loopData, CD_MASK_BAREMESH); + CustomData_set_only_copy(&cddm->polyData, CD_MASK_BAREMESH); + *lvl = mmd->totlvl; *simple = mmd->simple; @@ -1118,16 +315,16 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) bkr.bake_filter = scene->r.bake_filter; bkr.mode = scene->r.bake_mode; bkr.use_lores_mesh = scene->r.bake_flag & R_BAKE_LORES_MESH; + bkr.bias = scene->r.bake_biasdist; + bkr.number_of_rays = scene->r.bake_rays_number; + bkr.raytrace_structure = scene->r.raytrace_structure; + bkr.octree_resolution = scene->r.ocres; /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ - bkr.lores_dm = multiresbake_create_loresdm(scene, ob, &bkr.lvl); - - if (!bkr.lores_dm) - continue; - bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple); + bkr.lores_dm = multiresbake_create_loresdm(scene, ob, &bkr.lvl); - multiresbake_start(&bkr); + RE_multires_bake_images(&bkr); BLI_freelistN(&bkr.image); @@ -1155,24 +352,26 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj) bkj->mode = scene->r.bake_mode; bkj->use_lores_mesh = scene->r.bake_flag & R_BAKE_LORES_MESH; bkj->bake_clear = scene->r.bake_flag & R_BAKE_CLEAR; + bkj->bias = scene->r.bake_biasdist; + bkj->number_of_rays = scene->r.bake_rays_number; + bkj->raytrace_structure = scene->r.raytrace_structure; + bkj->octree_resolution = scene->r.ocres; CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { MultiresBakerJobData *data; - DerivedMesh *lores_dm; int lvl; + ob = base->object; multires_force_update(ob); - lores_dm = multiresbake_create_loresdm(scene, ob, &lvl); - if (!lores_dm) - continue; - data = MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data"); - data->lores_dm = lores_dm; - data->lvl = lvl; + + /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple); + data->lores_dm = multiresbake_create_loresdm(scene, ob, &lvl); + data->lvl = lvl; BLI_addtail(&bkj->data, data); } @@ -1219,7 +418,12 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa bkr.do_update = do_update; bkr.progress = progress; - multiresbake_start(&bkr); + bkr.bias = bkj->bias; + bkr.number_of_rays = bkj->number_of_rays; + bkr.raytrace_structure = bkj->raytrace_structure; + bkr.octree_resolution = bkj->octree_resolution; + + RE_multires_bake_images(&bkr); BLI_freelistN(&bkr.image); @@ -1472,7 +676,7 @@ static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), wmEven static int is_multires_bake(Scene *scene) { - if (ELEM(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT)) + if (ELEM3(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT, RE_BAKE_AO)) return scene->r.bake_flag & R_BAKE_MULTIRES; return 0; diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index d39e34824b9..12edb3e8edb 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -429,6 +429,10 @@ void ED_object_enter_editmode(bContext *C, int flag) ob = base->object; + /* this checks actual object->data, for cases when other scenes have it in editmode context */ + if ( BKE_object_is_in_editmode(ob) ) + return; + if (BKE_object_obdata_is_libdata(ob)) { error_libdata(); return; diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 900bf57b509..7a2eb5667a2 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -447,7 +447,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo float tmat[3][3], timat[3][3]; /* simple rotation matrix */ - BKE_object_rot_to_mat3(ob, rsmat); + BKE_object_rot_to_mat3(ob, rsmat, TRUE); /* correct for scale, note mul_m3_m3m3 has swapped args! */ BKE_object_scale_to_mat3(ob, tmat); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 1b135c0686e..f3e792def17 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -400,26 +400,34 @@ typedef enum WT_ReplaceMode { } WT_ReplaceMode; static EnumPropertyItem WT_vertex_group_mode_item[] = { - {WT_REPLACE_ACTIVE_VERTEX_GROUP, "WT_REPLACE_ACTIVE_VERTEX_GROUP", 0, "Active", "Transfer active vertex group from selected to active mesh"}, - {WT_REPLACE_ALL_VERTEX_GROUPS, "WT_REPLACE_ALL_VERTEX_GROUPS", 0, "All", "Transfer all vertex groups from selected to active mesh"}, + {WT_REPLACE_ACTIVE_VERTEX_GROUP, + "WT_REPLACE_ACTIVE_VERTEX_GROUP", 0, "Active", "Transfer active vertex group from selected to active mesh"}, + {WT_REPLACE_ALL_VERTEX_GROUPS, + "WT_REPLACE_ALL_VERTEX_GROUPS", 0, "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", 0, "Vertex index", "Copy for identical meshes"}, - {WT_BY_NEAREST_VERTEX, "WT_BY_NEAREST_VERTEX", 0, "Nearest vertex", "Copy weight from closest vertex"}, - {WT_BY_NEAREST_FACE, "WT_BY_NEAREST_FACE", 0, "Nearest face", "Barycentric interpolation from nearest face"}, - {WT_BY_NEAREST_VERTEX_IN_FACE, "WT_BY_NEAREST_VERTEX_IN_FACE", 0, "Nearest vertex in face", "Copy weight from closest vertex in nearest face"}, + {WT_BY_INDEX, + "WT_BY_INDEX", 0, "Vertex index", "Copy for identical meshes"}, + {WT_BY_NEAREST_VERTEX, + "WT_BY_NEAREST_VERTEX", 0, "Nearest vertex", "Copy weight from closest vertex"}, + {WT_BY_NEAREST_FACE, + "WT_BY_NEAREST_FACE", 0, "Nearest face", "Barycentric interpolation from nearest face"}, + {WT_BY_NEAREST_VERTEX_IN_FACE, + "WT_BY_NEAREST_VERTEX_IN_FACE", 0, "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", 0, "All", "Overwrite all weights"}, - {WT_REPLACE_EMPTY_WEIGHTS, "WT_REPLACE_EMPTY_WEIGHTS", 0, "Empty", "Add weights to vertices with no weight"}, + {WT_REPLACE_ALL_WEIGHTS, + "WT_REPLACE_ALL_WEIGHTS", 0, "All", "Overwrite all weights"}, + {WT_REPLACE_EMPTY_WEIGHTS, + "WT_REPLACE_EMPTY_WEIGHTS", 0, "Empty", "Add weights to vertices with no weight"}, {0, NULL, 0, NULL, NULL} }; -/*copy weight*/ +/* Copy weight.*/ static void vgroup_transfer_weight(float *r_weight_dst, const float weight_src, const WT_ReplaceMode replace_mode) { switch (replace_mode) { @@ -439,7 +447,9 @@ static void vgroup_transfer_weight(float *r_weight_dst, const float weight_src, } } -/* could be exposed externally */ +/* Could be exposed externally by implementing it in header with the rest. + * Simple refactoring will break something. + * For now, naming is ed_ instead of ED_*/ 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) { @@ -457,53 +467,52 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou 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 */ + /* Ensure vertex group on target.*/ 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 */ + /* Get destination deformgroup.*/ dg_dst = defgroup_find_name(ob_dst, dg_src->name); - /* get meshes */ + /* 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 */ + /* 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 */ + /* Create data in memory when nothing there.*/ if (!me_dst->dvert) ED_vgroup_data_create(ob_dst->data); - /* get vertex group arrays */ + /* 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 */ + /* 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 */ + /* Get vertices.*/ mv_dst = me_dst->mvert; mv_src = dmesh_src->getVertArray(dmesh_src); - /* prepare transformation matrix */ + /* 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 */ + /* 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 */ + /* Remove vertex from group.*/ if (dw_dst) defvert_remove_group(*dv_dst, dw_dst); } } @@ -511,7 +520,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou switch (method) { case WT_BY_INDEX: - /* check if indices are matching, delete and return if not */ + /* 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) { @@ -523,14 +532,15 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou 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++) { + /* 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 */ + /* 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); @@ -540,29 +550,30 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou break; case WT_BY_NEAREST_VERTEX: - /* make node tree */ + /* Make node tree.*/ bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, FLT_EPSILON, 2, 6); - /* loop trough vertices */ + /* 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 */ + /* Reset nearest.*/ nearest.dist = FLT_MAX; - /* with current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ + /* It is faster to start searching at the top of the tree instead of previous search result.*/ nearest.index = -1; - /* transform into target space */ + /* Transform into target space.*/ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - /* node tree accelerated search for closest vetex */ + /* 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. */ + /* Copy weight that are not NULL including weight value 0. In relevant cases, existing weights are + * overwritten prior to this. See the "Clear weights." step above.*/ 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); @@ -570,105 +581,108 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou } } - /* free memory */ + /* Free memory.*/ free_bvhtree_from_mesh(&tree_mesh_vertices_src); break; case WT_BY_NEAREST_FACE: - /* get faces */ + /* Get faces.*/ DM_ensure_tessface(dmesh_src); mface_src = dmesh_src->getTessFaceArray(dmesh_src); - /* make node tree */ + /* Make node tree.*/ bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6); - /* loop through the vertices */ + /* 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 */ + /* Reset nearest.*/ nearest.dist = FLT_MAX; - /* with current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ + /* It is faster to start searching at the top of the tree instead of previous search result.*/ nearest.index = -1; - /* transform into target space */ + /* Transform into target space.*/ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - /* node tree accelerated search for closest face */ + /* 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 */ + /* 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*/ + /* 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); + 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); + 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*/ + /* 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. */ + /* Copy weight that are not NULL including weight value 0. In relevant cases, existing weights are + * overwritten prior to this. See the "Clear weights." step above.*/ if (weight > 0) { dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(&dw_dst->weight, weight, replace_mode); } } - /* free memory */ + /* Free memory.*/ free_bvhtree_from_mesh(&tree_mesh_faces_src); break; case WT_BY_NEAREST_VERTEX_IN_FACE: - /* get faces */ + /* Get faces.*/ DM_ensure_tessface(dmesh_src); mface_src = dmesh_src->getTessFaceArray(dmesh_src); - /* make node tree */ + /* Make node tree.*/ bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6); - /* loop through the vertices */ + /* 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 */ + /* Reset nearest.*/ nearest.dist = FLT_MAX; - /* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ + /* It is faster to start searching at the top of the tree instead of previous search result.*/ nearest.index = -1; - /* transform into target space */ + /* Transform into target space.*/ mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); - /* node tree accelerated search for closest face */ + /* 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 */ + /* 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 */ + /* 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; @@ -680,7 +694,8 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou } } - /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */ + /* Copy weight that are not NULL including weight value 0. In relevant cases, existing weights are + * overwritten prior to this. See the "Clear weights." step above.*/ 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); @@ -688,7 +703,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou } } - /* free memory */ + /* Free memory.*/ free_bvhtree_from_mesh(&tree_mesh_faces_src); break; @@ -697,7 +712,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou break; } - /*free memory*/ + /* 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); @@ -1516,16 +1531,30 @@ static void vgroup_normalize_all(Object *ob, int lock_active) } } +enum { + VGROUP_TOGGLE, + VGROUP_LOCK, + VGROUP_UNLOCK, + VGROUP_INVERT +}; + +static EnumPropertyItem vgroup_lock_actions[] = { + {VGROUP_TOGGLE, "TOGGLE", 0, "Toggle", "Unlock all vertex groups if there is at least one locked group, lock all in other case"}, + {VGROUP_LOCK, "LOCK", 0, "Lock", "Lock all vertex groups"}, + {VGROUP_UNLOCK, "UNLOCK", 0, "Unlock", "Unlock all vertex groups"}, + {VGROUP_INVERT, "INVERT", 0, "Invert", "Invert the lock state of all vertex groups"}, + {0, NULL, 0, NULL, NULL} +}; static void vgroup_lock_all(Object *ob, int action) { bDeformGroup *dg; - if (action == SEL_TOGGLE) { - action = SEL_SELECT; + if (action == VGROUP_TOGGLE) { + action = VGROUP_LOCK; for (dg = ob->defbase.first; dg; dg = dg->next) { if (dg->flag & DG_LOCK_WEIGHT) { - action = SEL_DESELECT; + action = VGROUP_UNLOCK; break; } } @@ -1533,13 +1562,13 @@ static void vgroup_lock_all(Object *ob, int action) for (dg = ob->defbase.first; dg; dg = dg->next) { switch (action) { - case SEL_SELECT: + case VGROUP_LOCK: dg->flag |= DG_LOCK_WEIGHT; break; - case SEL_DESELECT: + case VGROUP_UNLOCK: dg->flag &= ~DG_LOCK_WEIGHT; break; - case SEL_INVERT: + case VGROUP_INVERT: dg->flag ^= DG_LOCK_WEIGHT; break; } @@ -2963,7 +2992,7 @@ void OBJECT_OT_vertex_group_lock(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - WM_operator_properties_select_all(ot); + RNA_def_enum(ot->srna, "action", vgroup_lock_actions, VGROUP_TOGGLE, "Action", "Lock action to execute on vertex groups"); } static int vertex_group_invert_exec(bContext *C, wmOperator *op) @@ -3274,7 +3303,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) 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 */ + /* 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) { @@ -3282,8 +3311,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) 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), + if (!ed_vgroup_transfer_weight(ob_act, ob_slc, BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), scene, method, replace_mode, op)) { fail++; @@ -3292,9 +3320,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) 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)) - { + if (!ed_vgroup_transfer_weight(ob_act, ob_slc, dg_src, scene, method, replace_mode, op)) { fail++; } } @@ -3307,7 +3333,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) } } - /* Event notifiers for correct display of data */ + /* 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); @@ -3325,19 +3351,19 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) /* transfers weight from active to selected */ void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) { - /* identifiers */ + /* 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 */ + /* API callbacks.*/ ot->poll = vertex_group_poll; ot->exec = vertex_group_transfer_weight_exec; - /* flags */ + /* Flags.*/ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - /* properties */ + /* 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", ""); diff --git a/source/blender/editors/physics/SConscript b/source/blender/editors/physics/SConscript index fffe05d6a0d..293f7769a6a 100644 --- a/source/blender/editors/physics/SConscript +++ b/source/blender/editors/physics/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index f5754297e9f..30508a793ae 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -53,10 +53,9 @@ #include "BLI_rand.h" #include "BLI_utildefines.h" -#include "BKE_DerivedMesh.h" -#include "BKE_depsgraph.h" - #include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_DerivedMesh.h" #include "BKE_global.h" #include "BKE_object.h" #include "BKE_mesh.h" @@ -193,6 +192,16 @@ ParticleEditSettings *PE_settings(Scene *scene) return scene->toolsettings ? &scene->toolsettings->particle : NULL; } +static float pe_brush_size_get(const Scene *UNUSED(scene), ParticleBrushData *brush) +{ + // here we can enable unified brush size, needs more work... + // UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; + // float size = (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size; + + return brush->size * U.pixelsize; +} + + /* always gets at least the first particlesystem even if PSYS_CURRENT flag is not set * * note: this function runs on poll, therefor it can runs many times a second @@ -516,7 +525,7 @@ static int point_is_selected(PTCacheEditPoint *point) typedef void (*ForPointFunc)(PEData *data, int point_index); typedef void (*ForKeyFunc)(PEData *data, int point_index, int key_index); -typedef void (*ForKeyMatFunc)(PEData *data, float mat[][4], float imat[][4], int point_index, int key_index, PTCacheEditKey *key); +typedef void (*ForKeyMatFunc)(PEData *data, float mat[4][4], float imat[4][4], int point_index, int key_index, PTCacheEditKey *key); static void for_mouse_hit_keys(PEData *data, ForKeyFunc func, int nearest) { @@ -2500,7 +2509,8 @@ void PARTICLE_OT_weight_set(wmOperatorType *ot) static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata)) { - ParticleEditSettings *pset= PE_settings(CTX_data_scene(C)); + Scene *scene = CTX_data_scene(C); + ParticleEditSettings *pset= PE_settings(scene); ParticleBrushData *brush; if (pset->brushtype < 0) @@ -2516,7 +2526,7 @@ static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata) glColor4ub(255, 255, 255, 128); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); - glutil_draw_lined_arc(0.0, M_PI*2.0, brush->size, 40); + glutil_draw_lined_arc(0.0, M_PI*2.0, pe_brush_size_get(scene, brush), 40); glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); @@ -2766,7 +2776,7 @@ void PARTICLE_OT_mirror(wmOperatorType *ot) /************************* brush edit callbacks ********************/ -static void brush_comb(PEData *data, float UNUSED(mat[][4]), float imat[][4], int point_index, int key_index, PTCacheEditKey *key) +static void brush_comb(PEData *data, float UNUSED(mat[4][4]), float imat[4][4], int point_index, int key_index, PTCacheEditKey *key) { ParticleEditSettings *pset= PE_settings(data->scene); float cvec[3], fac; @@ -3038,7 +3048,7 @@ static void brush_puff(PEData *data, int point_index) } -static void BKE_brush_weight_get(PEData *data, float UNUSED(mat[][4]), float UNUSED(imat[][4]), int point_index, int key_index, PTCacheEditKey *UNUSED(key)) +static void BKE_brush_weight_get(PEData *data, float UNUSED(mat[4][4]), float UNUSED(imat[4][4]), int point_index, int key_index, PTCacheEditKey *UNUSED(key)) { /* roots have full weight allways */ if (key_index) { @@ -3052,7 +3062,7 @@ static void BKE_brush_weight_get(PEData *data, float UNUSED(mat[][4]), float UNU } } -static void brush_smooth_get(PEData *data, float mat[][4], float UNUSED(imat[][4]), int UNUSED(point_index), int key_index, PTCacheEditKey *key) +static void brush_smooth_get(PEData *data, float mat[4][4], float UNUSED(imat[4][4]), int UNUSED(point_index), int key_index, PTCacheEditKey *key) { if (key_index) { float dvec[3]; @@ -3064,7 +3074,7 @@ static void brush_smooth_get(PEData *data, float mat[][4], float UNUSED(imat[][4 } } -static void brush_smooth_do(PEData *data, float UNUSED(mat[][4]), float imat[][4], int point_index, int key_index, PTCacheEditKey *key) +static void brush_smooth_do(PEData *data, float UNUSED(mat[4][4]), float imat[4][4], int point_index, int key_index, PTCacheEditKey *key) { float vec[3], dvec[3]; @@ -3535,7 +3545,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) selected= (short)count_selected_keys(scene, edit); dmax = max_ff(fabsf(dx), fabsf(dy)); - tot_steps = dmax/(0.2f * brush->size) + 1; + tot_steps = dmax/(0.2f * pe_brush_size_get(scene, brush)) + 1; dx /= (float)tot_steps; dy /= (float)tot_steps; @@ -3549,7 +3559,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) { const float mval_f[2] = {dx, dy}; data.mval= mval; - data.rad= (float)brush->size; + data.rad= pe_brush_size_get(scene, brush); data.combfac= (brush->strength - 0.5f) * 2.0f; if (data.combfac < 0.0f) @@ -3569,7 +3579,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) { if (edit->psys && edit->pathcache) { data.mval= mval; - data.rad= (float)brush->size; + data.rad= pe_brush_size_get(scene, brush); data.cutfac= brush->strength; if (selected) @@ -3590,7 +3600,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) { data.mval= mval; - data.rad= (float)brush->size; + data.rad= pe_brush_size_get(scene, brush); data.growfac= brush->strength / 50.0f; if (brush->invert ^ flip) @@ -3609,7 +3619,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) if (edit->psys) { data.dm= psmd->dm; data.mval= mval; - data.rad= (float)brush->size; + data.rad= pe_brush_size_get(scene, brush); data.select= selected; data.pufffac= (brush->strength - 0.5f) * 2.0f; @@ -3642,7 +3652,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) case PE_BRUSH_SMOOTH: { data.mval= mval; - data.rad= (float)brush->size; + data.rad= pe_brush_size_get(scene, brush); data.vec[0] = data.vec[1] = data.vec[2] = 0.0f; data.tot= 0; @@ -3665,7 +3675,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) if (edit->psys) { data.dm= psmd->dm; data.mval= mval; - data.rad= (float)brush->size; + data.rad= pe_brush_size_get(scene, brush); data.weightfac = brush->strength; /* note that this will never be zero */ diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c index 5304c64c2a9..db2023b7364 100644 --- a/source/blender/editors/physics/physics_fluid.c +++ b/source/blender/editors/physics/physics_fluid.c @@ -142,7 +142,7 @@ static int fluid_is_animated_mesh(FluidsimSettings *fss) #if 0 /* helper function */ -void fluidsimGetGeometryObjFilename(Object *ob, char *dst) { //, char *srcname) +void fluidsimGetGeometryObjFilename(Object *ob, char *dst) //, char *srcname) { //BLI_snprintf(dst, FILE_MAXFILE, "%s_cfgdata_%s.bobj.gz", srcname, ob->id.name); BLI_snprintf(dst, FILE_MAXFILE, "fluidcfgdata_%s.bobj.gz", ob->id.name); @@ -267,7 +267,7 @@ static void set_vertex_channel(float *channel, float time, struct Scene *scene, FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim); float *verts; int *tris=NULL, numVerts=0, numTris=0; - int modifierIndex = modifiers_indexInObject(ob, (ModifierData *)fluidmd); + int modifierIndex = BLI_findindex(&ob->modifiers, fluidmd); int framesize = (3*fobj->numVerts) + 1; int j; @@ -388,7 +388,7 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid if (fluid_is_animated_mesh(fluidmd->fss)) { float *verts=NULL; - int *tris=NULL, modifierIndex = modifiers_indexInObject(ob, (ModifierData *)fluidmd); + int *tris=NULL, modifierIndex = BLI_findindex(&ob->modifiers, (ModifierData *)fluidmd); initElbeemMesh(scene, ob, &fobj->numVerts, &verts, &fobj->numTris, &tris, 0, modifierIndex); fobj->VertexCache = MEM_callocN(length *((fobj->numVerts*CHANNEL_VEC)+1) * sizeof(float), "fluidobject VertexCache"); @@ -491,7 +491,7 @@ static void export_fluid_objects(ListBase *fobjects, Scene *scene, int length) for (fobj=fobjects->first; fobj; fobj=fobj->next) { Object *ob = fobj->object; FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim); - int modifierIndex = modifiers_indexInObject(ob, (ModifierData *)fluidmd); + int modifierIndex = BLI_findindex(&ob->modifiers, fluidmd); float *verts=NULL; int *tris=NULL; diff --git a/source/blender/editors/render/SConscript b/source/blender/editors/render/SConscript index 9f769a68ecf..15bcb9a907f 100644 --- a/source/blender/editors/render/SConscript +++ b/source/blender/editors/render/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 73f8abdf15f..16fe94ff2e5 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -232,7 +232,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender) else { /* shouldnt suddenly give errors mid-render but possible */ char err_out[256] = "unknown"; - ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey, IB_rectfloat, OB_SOLID, TRUE, FALSE, err_out); + ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey, IB_rectfloat, OB_SOLID, FALSE, TRUE, FALSE, err_out); camera = scene->camera; if (ibuf_view) { diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index 1ed1cbb2c6b..38535eca918 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -33,6 +33,7 @@ #include "DNA_lamp_types.h" #include "DNA_material_types.h" +#include "DNA_meshdata_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -46,6 +47,7 @@ #include "BKE_context.h" #include "BKE_depsgraph.h" +#include "BKE_DerivedMesh.h" #include "BKE_icons.h" #include "BKE_image.h" #include "BKE_main.h" @@ -56,6 +58,7 @@ #include "BKE_world.h" #include "GPU_material.h" +#include "GPU_buffers.h" #include "RE_engine.h" #include "RE_pipeline.h" @@ -232,6 +235,9 @@ static int nodes_use_material(bNodeTree *ntree, Material *ma) static void material_changed(Main *bmain, Material *ma) { Material *parent; + Object *ob; + Scene *scene; + int texture_draw = FALSE; /* icons */ BKE_icon_changed(BKE_icon_getid(&ma->id)); @@ -254,6 +260,33 @@ static void material_changed(Main *bmain, Material *ma) if (parent->gpumaterial.first) GPU_material_free(parent); } + + /* find if we have a scene with textured display */ + for (scene = bmain->scene.first; scene; scene = scene->id.next) { + if (scene->customdata_mask & CD_MASK_MTFACE) { + texture_draw = TRUE; + break; + } + } + + /* find textured objects */ + if (texture_draw && !(U.gameflags & USER_DISABLE_VBO)) { + for (ob = bmain->object.first; ob; ob = ob->id.next) { + DerivedMesh *dm = ob->derivedFinal; + Material ***material = give_matarar(ob); + short a, *totmaterial = give_totcolp(ob); + + if (dm && totmaterial && material) { + for (a = 0; a < *totmaterial; a++) { + if ((*material)[a] == ma) { + GPU_drawobject_free(dm); + break; + } + } + } + } + } + } static void lamp_changed(Main *bmain, Lamp *la) @@ -277,28 +310,33 @@ static void lamp_changed(Main *bmain, Lamp *la) GPU_material_free(&defmaterial); } +static int material_uses_texture(Material *ma, Tex *tex) +{ + if (mtex_use_tex(ma->mtex, MAX_MTEX, tex)) + return TRUE; + else if (ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex)) + return TRUE; + + return FALSE; +} + static void texture_changed(Main *bmain, Tex *tex) { Material *ma; Lamp *la; World *wo; Scene *scene; + Object *ob; bNode *node; + int texture_draw = FALSE; /* icons */ BKE_icon_changed(BKE_icon_getid(&tex->id)); /* find materials */ for (ma = bmain->mat.first; ma; ma = ma->id.next) { - 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 { + if (!material_uses_texture(ma, tex)) continue; - } BKE_icon_changed(BKE_icon_getid(&ma->id)); @@ -342,6 +380,27 @@ static void texture_changed(Main *bmain, Tex *tex) ED_node_changed_update(&scene->id, node); } } + + if (scene->customdata_mask & CD_MASK_MTFACE) + texture_draw = TRUE; + } + + /* find textured objects */ + if (texture_draw && !(U.gameflags & USER_DISABLE_VBO)) { + for (ob = bmain->object.first; ob; ob = ob->id.next) { + DerivedMesh *dm = ob->derivedFinal; + Material ***material = give_matarar(ob); + short a, *totmaterial = give_totcolp(ob); + + if (dm && totmaterial && material) { + for (a = 0; a < *totmaterial; a++) { + if (material_uses_texture((*material)[a], tex)) { + GPU_drawobject_free(dm); + break; + } + } + } + } } } diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c index 5ec7f4d05b6..f15f7b539f3 100644 --- a/source/blender/editors/render/render_view.c +++ b/source/blender/editors/render/render_view.c @@ -35,6 +35,7 @@ #include "BLI_utildefines.h" #include "DNA_scene_types.h" +#include "DNA_userdef_types.h" #include "BKE_blender.h" #include "BKE_context.h" @@ -151,9 +152,10 @@ void render_view_open(bContext *C, int mx, int my) if (sizex < 320) sizex = 320; if (sizey < 256) sizey = 256; - /* XXX some magic to calculate postition */ - rect.xmin = mx + win->posx - sizex / 2; - rect.ymin = my + win->posy - sizey / 2; + /* some magic to calculate postition */ + /* pixelsize: mouse coords are in U.pixelsize units :/ */ + rect.xmin = (mx / U.pixelsize) + win->posx - sizex / 2; + rect.ymin = (my / U.pixelsize) + win->posy - sizey / 2; rect.xmax = rect.xmin + sizex; rect.ymax = rect.ymin + sizey; diff --git a/source/blender/editors/screen/SConscript b/source/blender/editors/screen/SConscript index 0e894a13d28..c0a14ce5377 100644 --- a/source/blender/editors/screen/SConscript +++ b/source/blender/editors/screen/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index f30e0abb4f3..cde94ec46ee 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -235,8 +235,8 @@ static void region_draw_azone_icon(AZone *az) static void draw_azone_plus(float x1, float y1, float x2, float y2) { - float width = 2.0f; - float pad = 4.0f; + float width = 0.1f * U.widget_unit; + float pad = 0.2f * U.widget_unit; glRectf((x1 + x2 - width) * 0.5f, y1 + pad, (x1 + x2 + width) * 0.5f, y2 - pad); glRectf(x1 + pad, (y1 + y2 - width) * 0.5f, (x1 + x2 - width) * 0.5f, (y1 + y2 + width) * 0.5f); @@ -395,47 +395,14 @@ void ED_area_overdraw(bContext *C) } -/* get scissor rect, checking overlapping regions */ -void region_scissor_winrct(ARegion *ar, rcti *winrct) -{ - *winrct = ar->winrct; - - if (ELEM(ar->alignment, RGN_OVERLAP_LEFT, RGN_OVERLAP_RIGHT)) - return; - - while (ar->prev) { - ar = ar->prev; - - if (BLI_rcti_isect(winrct, &ar->winrct, NULL)) { - 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; - } - else if (ar->alignment == RGN_OVERLAP_RIGHT) { - winrct->xmax = ar->winrct.xmin - 1; - } - else break; - } - } -} - /* only exported for WM */ /* makes region ready for drawing, sets pixelspace */ void ED_region_set(const bContext *C, ARegion *ar) { wmWindow *win = CTX_wm_window(C); ScrArea *sa = CTX_wm_area(C); - rcti winrct; - /* checks other overlapping regions */ - region_scissor_winrct(ar, &winrct); - - ar->drawrct = winrct; + ar->drawrct = ar->winrct; /* note; this sets state, so we can use wmOrtho and friends */ wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct); @@ -452,24 +419,20 @@ void ED_region_do_draw(bContext *C, ARegion *ar) wmWindow *win = CTX_wm_window(C); ScrArea *sa = CTX_wm_area(C); ARegionType *at = ar->type; - rcti winrct; /* see BKE_spacedata_draw_locks() */ if (at->do_lock) return; - /* checks other overlapping regions */ - region_scissor_winrct(ar, &winrct); - /* if no partial draw rect set, full rect */ if (ar->drawrct.xmin == ar->drawrct.xmax) - ar->drawrct = winrct; + ar->drawrct = ar->winrct; else { /* extra clip for safety (intersect the rects, could use API func) */ - ar->drawrct.xmin = max_ii(winrct.xmin, ar->drawrct.xmin); - ar->drawrct.ymin = max_ii(winrct.ymin, ar->drawrct.ymin); - ar->drawrct.xmax = min_ii(winrct.xmax, ar->drawrct.xmax); - ar->drawrct.ymax = min_ii(winrct.ymax, ar->drawrct.ymax); + ar->drawrct.xmin = max_ii(ar->winrct.xmin, ar->drawrct.xmin); + ar->drawrct.ymin = max_ii(ar->winrct.ymin, ar->drawrct.ymin); + ar->drawrct.xmax = min_ii(ar->winrct.xmax, ar->drawrct.xmax); + ar->drawrct.ymax = min_ii(ar->winrct.ymax, ar->drawrct.ymax); } /* note; this sets state, so we can use wmOrtho and friends */ @@ -500,7 +463,7 @@ void ED_region_do_draw(bContext *C, ARegion *ar) uiFreeInactiveBlocks(C, &ar->uiblocks); if (sa) - region_draw_emboss(ar, &winrct); + region_draw_emboss(ar, &ar->winrct); } /* ********************************** @@ -627,8 +590,8 @@ static void area_azone_initialize(bScreen *screen, ScrArea *sa) BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); } -#define AZONEPAD_EDGE 4 -#define AZONEPAD_ICON 9 +#define AZONEPAD_EDGE (0.2f * U.widget_unit) +#define AZONEPAD_ICON (0.45f * U.widget_unit) static void region_azone_edge(AZone *az, ARegion *ar) { switch (az->edge) { @@ -720,8 +683,8 @@ static void region_azone_icon(ScrArea *sa, AZone *az, ARegion *ar) } } -#define AZONEPAD_TAB_PLUSW 14 -#define AZONEPAD_TAB_PLUSH 14 +#define AZONEPAD_TAB_PLUSW (0.7f * U.widget_unit) +#define AZONEPAD_TAB_PLUSH (0.7f * U.widget_unit) /* region already made zero sized, in shape of edge */ static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar) @@ -736,28 +699,28 @@ static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar) switch (az->edge) { case AE_TOP_TO_BOTTOMRIGHT: if (ar->winrct.ymax == sa->totrct.ymin) add = 1; else add = 0; - az->x1 = ar->winrct.xmax - 2.5 * AZONEPAD_TAB_PLUSW; + az->x1 = ar->winrct.xmax - 2.5f * AZONEPAD_TAB_PLUSW; az->y1 = ar->winrct.ymax - add; - az->x2 = ar->winrct.xmax - 1.5 * AZONEPAD_TAB_PLUSW; + az->x2 = ar->winrct.xmax - 1.5f * AZONEPAD_TAB_PLUSW; az->y2 = ar->winrct.ymax - add + AZONEPAD_TAB_PLUSH; break; case AE_BOTTOM_TO_TOPLEFT: - az->x1 = ar->winrct.xmax - 2.5 * AZONEPAD_TAB_PLUSW; + az->x1 = ar->winrct.xmax - 2.5f * AZONEPAD_TAB_PLUSW; az->y1 = ar->winrct.ymin - AZONEPAD_TAB_PLUSH; - az->x2 = ar->winrct.xmax - 1.5 * AZONEPAD_TAB_PLUSW; + az->x2 = ar->winrct.xmax - 1.5f * AZONEPAD_TAB_PLUSW; az->y2 = ar->winrct.ymin; break; case AE_LEFT_TO_TOPRIGHT: az->x1 = ar->winrct.xmin - AZONEPAD_TAB_PLUSH; - az->y1 = ar->winrct.ymax - 2.5 * AZONEPAD_TAB_PLUSW; + az->y1 = ar->winrct.ymax - 2.5f * AZONEPAD_TAB_PLUSW; az->x2 = ar->winrct.xmin; - az->y2 = ar->winrct.ymax - 1.5 * AZONEPAD_TAB_PLUSW; + az->y2 = ar->winrct.ymax - 1.5f * AZONEPAD_TAB_PLUSW; break; case AE_RIGHT_TO_TOPLEFT: az->x1 = ar->winrct.xmax - 1; - az->y1 = ar->winrct.ymax - 2.5 * AZONEPAD_TAB_PLUSW; + az->y1 = ar->winrct.ymax - 2.5f * AZONEPAD_TAB_PLUSW; az->x2 = ar->winrct.xmax - 1 + AZONEPAD_TAB_PLUSH; - az->y2 = ar->winrct.ymax - 1.5 * AZONEPAD_TAB_PLUSW; + az->y2 = ar->winrct.ymax - 1.5f * AZONEPAD_TAB_PLUSW; break; } /* rect needed for mouse pointer test */ @@ -765,8 +728,8 @@ static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar) } -#define AZONEPAD_TABW 18 -#define AZONEPAD_TABH 7 +#define AZONEPAD_TABW (0.9f * U.widget_unit) +#define AZONEPAD_TABH (0.35f * U.widget_unit) /* region already made zero sized, in shape of edge */ static void region_azone_tab(ScrArea *sa, AZone *az, ARegion *ar) @@ -809,8 +772,8 @@ static void region_azone_tab(ScrArea *sa, AZone *az, ARegion *ar) BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); } -#define AZONEPAD_TRIAW 16 -#define AZONEPAD_TRIAH 9 +#define AZONEPAD_TRIAW (0.8f * U.widget_unit) +#define AZONEPAD_TRIAH (0.45f * U.widget_unit) /* region already made zero sized, in shape of edge */ @@ -892,9 +855,9 @@ static void region_azone_add(ScrArea *sa, ARegion *ar, int alignment) region_azone_initialize(sa, ar, AE_BOTTOM_TO_TOPLEFT); else if (alignment == RGN_ALIGN_BOTTOM) region_azone_initialize(sa, ar, AE_TOP_TO_BOTTOMRIGHT); - else if (ELEM(alignment, RGN_ALIGN_RIGHT, RGN_OVERLAP_RIGHT)) + else if (alignment == RGN_ALIGN_RIGHT) region_azone_initialize(sa, ar, AE_LEFT_TO_TOPRIGHT); - else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_OVERLAP_LEFT)) + else if (alignment == RGN_ALIGN_LEFT) region_azone_initialize(sa, ar, AE_RIGHT_TO_TOPLEFT); } @@ -909,7 +872,50 @@ static int rct_fits(rcti *rect, char dir, int size) } } -static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int quad) +/* *************************************************************** */ + +/* ar should be overlapping */ +/* function checks if some overlapping region was defined before - on same place */ +static void region_overlap_fix(ARegion *ar) +{ + ARegion *ar1 = ar->prev; + + /* find overlapping previous region on same place */ + while (ar1) { + if (ar1->overlap) { + if ((ar1->alignment & RGN_SPLIT_PREV) == 0) + if (BLI_rcti_isect(&ar1->winrct, &ar->winrct, NULL)) + break; + } + ar1 = ar1->prev; + } + + /* translate */ + if (ar1) { + int align1 = ar1->alignment & ~RGN_SPLIT_PREV; + + if (align1 == RGN_ALIGN_LEFT) { + BLI_rcti_translate(&ar->winrct, ar1->winx, 0); + } + else if (align1 == RGN_ALIGN_RIGHT) { + BLI_rcti_translate(&ar->winrct, -ar1->winx, 0); + } + } + +} + +/* overlapping regions only in the following restricted cases */ +static int region_is_overlap(wmWindow *win, ScrArea *sa, ARegion *ar) +{ + if (U.uiflag2 & USER_REGION_OVERLAP) + if (WM_is_draw_triple(win)) + if (ELEM5(sa->spacetype, SPACE_VIEW3D, SPACE_IMAGE, SPACE_SEQ, SPACE_CLIP, SPACE_NODE)) + if (ELEM3(ar->regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI, RGN_TYPE_TOOL_PROPS)) + return 1; + return 0; +} + +static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti *remainder, int quad) { rcti *remainder_prev = remainder; int prefsizex, prefsizey; @@ -928,6 +934,9 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int alignment = ar->alignment & ~RGN_SPLIT_PREV; + /* set here, assuming userpref switching forces to call this again */ + ar->overlap = region_is_overlap(win, sa, ar); + /* clear state flags first */ ar->flag &= ~RGN_FLAG_TOO_SMALL; /* user errors */ @@ -935,15 +944,15 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int alignment = RGN_ALIGN_NONE; /* prefsize, for header we stick to exception */ - prefsizex = ar->sizex ? ar->sizex : ar->type->prefsizex; + prefsizex = ar->sizex > 1 ? ar->sizex : UI_DPI_FAC * ar->type->prefsizex; if (ar->regiontype == RGN_TYPE_HEADER) { - prefsizey = ar->type->prefsizey; + prefsizey = ED_area_headersize(); } else if (ar->regiontype == RGN_TYPE_UI && sa->spacetype == SPACE_FILE) { prefsizey = UI_UNIT_Y * 2 + (UI_UNIT_Y / 2); } else { - prefsizey = ar->sizey ? ar->sizey : ar->type->prefsizey; + prefsizey = ar->sizey > 1 ? ar->sizey : UI_DPI_FAC * ar->type->prefsizey; } @@ -985,7 +994,7 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int } } } - else if (ELEM4(alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT, RGN_OVERLAP_LEFT, RGN_OVERLAP_RIGHT)) { + else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) { if (rct_fits(remainder, 'h', prefsizex) < 0) { ar->flag |= RGN_FLAG_TOO_SMALL; @@ -998,14 +1007,14 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int ar->winrct = *remainder; - if (ELEM(alignment, RGN_ALIGN_RIGHT, RGN_OVERLAP_RIGHT)) { + if (alignment == RGN_ALIGN_RIGHT) { ar->winrct.xmin = ar->winrct.xmax - prefsizex + 1; - if (alignment == RGN_ALIGN_RIGHT) + if (ar->overlap == 0) remainder->xmax = ar->winrct.xmin - 1; } else { ar->winrct.xmax = ar->winrct.xmin + prefsizex - 1; - if (alignment == RGN_ALIGN_LEFT) + if (ar->overlap == 0) remainder->xmin = ar->winrct.xmax + 1; } } @@ -1082,6 +1091,14 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int ar->winx = BLI_rcti_size_x(&ar->winrct) + 1; ar->winy = BLI_rcti_size_y(&ar->winrct) + 1; + /* if region opened normally, we store this for hide/reveal usage */ + if (ar->winx > 1) ar->sizex = ar->winx; + if (ar->winy > 1) ar->sizey = ar->winy; + + /* exception for multiple aligned overlapping regions on same spot */ + if (ar->overlap) + region_overlap_fix(ar); + /* set winrect for azones */ if (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) { ar->winrct = *remainder; @@ -1090,9 +1107,9 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int ar->winrct.ymin = ar->winrct.ymax; else if (alignment == RGN_ALIGN_BOTTOM) ar->winrct.ymax = ar->winrct.ymin; - else if (ELEM(alignment, RGN_ALIGN_RIGHT, RGN_OVERLAP_RIGHT)) + else if (alignment == RGN_ALIGN_RIGHT) ar->winrct.xmin = ar->winrct.xmax; - else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_OVERLAP_LEFT)) + else if (alignment == RGN_ALIGN_LEFT) ar->winrct.xmax = ar->winrct.xmin; else /* prevent winrct to be valid */ ar->winrct.xmax = ar->winrct.xmin; @@ -1121,12 +1138,12 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int region_azone_add(sa, ar, alignment); } - region_rect_recursive(sa, ar->next, remainder, quad); + region_rect_recursive(win, sa, ar->next, remainder, quad); } static void area_calc_totrct(ScrArea *sa, int sizex, int sizey) { - short rt = 0; // CLAMPIS(G.debug_value, 0, 16); + short rt = U.pixelsize > 1.0f ? 1 : 0; if (sa->v1->vec.x > 0) sa->totrct.xmin = sa->v1->vec.x + 1 + rt; else sa->totrct.xmin = sa->v1->vec.x; @@ -1229,14 +1246,14 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa) ar->type = BKE_regiontype_from_id(sa->type, ar->regiontype); /* area sizes */ - area_calc_totrct(sa, win->sizex, win->sizey); + area_calc_totrct(sa, WM_window_pixels_x(win), WM_window_pixels_y(win)); /* clear all azones, add the area triange widgets */ area_azone_initialize(win->screen, sa); /* region rect sizes */ rect = sa->totrct; - region_rect_recursive(sa, sa->regionbase.first, &rect, 0); + region_rect_recursive(win, sa, sa->regionbase.first, &rect, 0); /* default area handlers */ ed_default_handlers(wm, sa, &sa->handlers, sa->type->keymapflag); @@ -1278,17 +1295,30 @@ void ED_region_init(bContext *C, ARegion *ar) glLoadIdentity(); } -void ED_region_toggle_hidden(bContext *C, ARegion *ar) +/* for quick toggle, can skip fades */ +void region_toggle_hidden(bContext *C, ARegion *ar, int do_fade) { ScrArea *sa = CTX_wm_area(C); - + ar->flag ^= RGN_FLAG_HIDDEN; + + if (do_fade && ar->overlap) { + /* starts a timer, and in end calls the stuff below itself (region_sblend_invoke()) */ + region_blend_start(C, sa, ar); + } + else { + if (ar->flag & RGN_FLAG_HIDDEN) + WM_event_remove_handlers(C, &ar->handlers); + + ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); + ED_area_tag_redraw(sa); + } +} - if (ar->flag & RGN_FLAG_HIDDEN) - WM_event_remove_handlers(C, &ar->handlers); - - ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); - ED_area_tag_redraw(sa); +/* exported to all editors, uses fading default */ +void ED_region_toggle_hidden(bContext *C, ARegion *ar) +{ + region_toggle_hidden(C, ar, 1); } /* sa2 to sa1, we swap spaces for fullscreen to keep all allocated data */ @@ -1441,7 +1471,7 @@ void ED_area_prevspace(bContext *C, ScrArea *sa) { SpaceLink *sl = (sa) ? sa->spacedata.first : CTX_wm_space_data(C); - if (sl->next) { + if (sl && sl->next) { /* workaround for case of double prevspace, render window * with a file browser on top of it */ if (sl->next->spacetype == SPACE_FILE && sl->next->next) @@ -1515,22 +1545,22 @@ int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco) { ScrArea *sa = CTX_wm_area(C); uiBut *but; - int xco = 8; + int xco = 0.4 * U.widget_unit; but = uiDefIconTextButC(block, ICONTEXTROW, 0, ICON_VIEW3D, - editortype_pup(), xco, yco, UI_UNIT_X + 10, UI_UNIT_Y, + editortype_pup(), xco, yco, 1.5 * U.widget_unit, U.widget_unit, &(sa->butspacetype), 1.0, SPACEICONMAX, 0, 0, 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 */ - return xco + UI_UNIT_X + 14; + return xco + 1.7 * U.widget_unit; } int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco) { ScrArea *sa = CTX_wm_area(C); - int xco = 8; + int xco = 0.4 * U.widget_unit; uiBut *but; if (!sa->full) @@ -1541,14 +1571,14 @@ int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco) if (sa->flag & HEADER_NO_PULLDOWN) { but = uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0, ICON_DISCLOSURE_TRI_RIGHT, - xco, yco, UI_UNIT_X, UI_UNIT_Y - 2, + xco, yco, U.widget_unit, U.widget_unit*0.9, &(sa->flag), 0, 0, 0, 0, "Show pulldown menus"); } else { but = uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0, ICON_DISCLOSURE_TRI_DOWN, - xco, yco, UI_UNIT_X, UI_UNIT_Y - 2, + xco, yco, U.widget_unit, U.widget_unit*0.9, &(sa->flag), 0, 0, 0, 0, "Hide pulldown menus"); } @@ -1557,7 +1587,7 @@ int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco) uiBlockSetEmboss(block, UI_EMBOSS); - return xco + UI_UNIT_X; + return xco + U.widget_unit; } /************************ standard UI regions ************************/ @@ -1565,14 +1595,14 @@ int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco) void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *context, int contextnr) { ScrArea *sa = CTX_wm_area(C); - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_GetStyleDraw(); uiBlock *block; PanelType *pt; Panel *panel; View2D *v2d = &ar->v2d; View2DScrollers *scrollers; int x, y, xco, yco, w, em, triangle, open, newcontext = 0; - + if (contextnr >= 0) newcontext = UI_view2d_tab_set(v2d, contextnr); @@ -1608,7 +1638,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * if (pt->draw_header && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) { /* for enabled buttons */ panel->layout = uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, - triangle, UI_UNIT_Y + style->panelspace + 2, UI_UNIT_Y, 1, style); + triangle, (UI_UNIT_Y * 1.1f) + style->panelspace, UI_UNIT_Y, 1, style); pt->draw_header(C, panel); @@ -1653,8 +1683,18 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * uiEndPanels(C, ar, &x, &y); /* clear */ - UI_ThemeClearColor((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK); - glClear(GL_COLOR_BUFFER_BIT); + if (ar->overlap) { + /* view should be in pixelspace */ + UI_view2d_view_restore(C); + glEnable(GL_BLEND); + UI_ThemeColor4((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK); + glRecti(0, 0, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct)); + glDisable(GL_BLEND); + } + else { + UI_ThemeClearColor((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK); + glClear(GL_COLOR_BUFFER_BIT); + } /* before setting the view */ if (vertical) { @@ -1663,7 +1703,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * v2d->keepofs &= ~(V2D_LOCKOFS_Y | V2D_KEEPOFS_X); v2d->scroll |= V2D_SCROLL_HORIZONTAL_HIDE; v2d->scroll &= ~V2D_SCROLL_VERTICAL_HIDE; - + /* ensure tot is set correctly, to keep views on bottons, with sliders */ y = min_ii(y, v2d->cur.ymin); y = -y; @@ -1684,8 +1724,8 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * y = -y; } - /* +V2D_SCROLL_HEIGHT is workaround to set the actual height */ - UI_view2d_totRect_set(v2d, x + V2D_SCROLL_WIDTH, y + V2D_SCROLL_HEIGHT); + /* +V2D_SCROLL_HEIGHT is workaround to set the actual height (needs to be int) */ + UI_view2d_totRect_set(v2d, x + (int)V2D_SCROLL_WIDTH, y + (int)V2D_SCROLL_HEIGHT); /* set the view */ UI_view2d_view_ortho(v2d); @@ -1725,7 +1765,7 @@ void ED_region_panels_init(wmWindowManager *wm, ARegion *ar) void ED_region_header(const bContext *C, ARegion *ar) { - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_GetStyleDraw(); uiBlock *block; uiLayout *layout; HeaderType *ht; @@ -1740,8 +1780,8 @@ void ED_region_header(const bContext *C, ARegion *ar) /* set view2d view matrix for scrolling (without scrollers) */ UI_view2d_view_ortho(&ar->v2d); - xco = maxco = 8; - yco = headery - 4; + xco = maxco = 0.4f * UI_UNIT_X; + yco = headery - floor(0.2f * UI_UNIT_Y); /* draw all headers types */ for (ht = ar->type->headertypes.first; ht; ht = ht->next) { @@ -1784,20 +1824,18 @@ void ED_region_header_init(ARegion *ar) /* UI_UNIT_Y is defined as U variable now, depending dpi */ int ED_area_headersize(void) { - return UI_UNIT_Y + 6; + return (int)(1.3f * UI_UNIT_Y); } void ED_region_info_draw(ARegion *ar, const char *text, int block, float alpha) { - const int header_height = 18; - uiStyle *style = UI_GetStyle(); + const int header_height = UI_UNIT_Y; + uiStyle *style = UI_GetStyleDraw(); int fontid = style->widget.uifont_id; rcti rect; - BLF_size(fontid, 11.0f, 72); - /* background box */ - rect = ar->winrct; + ED_region_visible_rect(ar, &rect); rect.xmin = 0; rect.ymin = BLI_rcti_size_y(&ar->winrct) - header_height; @@ -1881,3 +1919,32 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy) } glEnd(); } + +/* If the area has overlapping regions, it returns visible rect for Region *ar */ +/* rect gets returned in local region coordinates */ +void ED_region_visible_rect(ARegion *ar, rcti *rect) +{ + ARegion *arn = ar; + + /* allow function to be called without area */ + while (arn->prev) + arn = arn->prev; + + *rect = ar->winrct; + + /* check if a region overlaps with the current one */ + for (; arn; arn = arn->next) { + if (ar != arn && arn->overlap) { + if (BLI_rcti_isect(rect, &arn->winrct, NULL)) { + /* overlap left */ + if (rect->xmin == arn->winrct.xmin) + rect->xmin = arn->winrct.xmax; + /* overlap right */ + if (rect->xmax == arn->winrct.xmax) + rect->xmax = arn->winrct.xmin; + } + } + } + BLI_rcti_translate(rect, -ar->winrct.xmin, -ar->winrct.ymin); +} + diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index ce2d045dc80..d3947432004 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -33,11 +33,13 @@ #include "MEM_guardedalloc.h" +#include "DNA_userdef_types.h" #include "DNA_vec_types.h" #include "BLI_rect.h" #include "BLI_utildefines.h" +#include "BKE_blender.h" #include "BKE_colortools.h" #include "BLI_math.h" @@ -292,7 +294,10 @@ void setlinestyle(int nr) else { glEnable(GL_LINE_STIPPLE); - glLineStipple(nr, 0xAAAA); + if (U.pixelsize > 1.0f) + glLineStipple(nr, 0xCCCC); + else + glLineStipple(nr, 0xAAAA); } } diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 60aad14efcf..f71d63e5fef 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -263,6 +263,9 @@ int scredge_is_horizontal(ScrEdge *se) ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my) { ScrEdge *se; + int safety = U.widget_unit / 10; + + if (safety < 2) safety = 2; for (se = sc->edgebase.first; se; se = se->next) { if (scredge_is_horizontal(se)) { @@ -270,7 +273,7 @@ ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my) min = MIN2(se->v1->vec.x, se->v2->vec.x); max = MAX2(se->v1->vec.x, se->v2->vec.x); - if (abs(my - se->v1->vec.y) <= 2 && mx >= min && mx <= max) + if (abs(my - se->v1->vec.y) <= safety && mx >= min && mx <= max) return se; } else { @@ -278,7 +281,7 @@ ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my) min = MIN2(se->v1->vec.y, se->v2->vec.y); max = MAX2(se->v1->vec.y, se->v2->vec.y); - if (abs(mx - se->v1->vec.x) <= 2 && my >= min && my <= max) + if (abs(mx - se->v1->vec.x) <= safety && my >= min && my <= max) return se; } } @@ -428,9 +431,9 @@ bScreen *ED_screen_add(wmWindow *win, Scene *scene, const char *name) sc->winid = win->winid; sv1 = screen_addvert(sc, 0, 0); - sv2 = screen_addvert(sc, 0, win->sizey - 1); - sv3 = screen_addvert(sc, win->sizex - 1, win->sizey - 1); - sv4 = screen_addvert(sc, win->sizex - 1, 0); + sv2 = screen_addvert(sc, 0, WM_window_pixels_y(win) - 1); + sv3 = screen_addvert(sc, WM_window_pixels_x(win) - 1, WM_window_pixels_y(win) - 1); + sv4 = screen_addvert(sc, WM_window_pixels_x(win) - 1, 0); screen_addedge(sc, sv1, sv2); screen_addedge(sc, sv2, sv3); @@ -628,7 +631,7 @@ static void screen_test_scale(bScreen *sc, int winsizex, int winsizey) float facx, facy, tempf, min[2], max[2]; /* calculate size */ - min[0] = min[1] = 10000.0f; + min[0] = min[1] = 20000.0f; max[0] = max[1] = 0.0f; for (sv = sc->vertbase.first; sv; sv = sv->next) { @@ -669,6 +672,29 @@ static void screen_test_scale(bScreen *sc, int winsizex, int winsizey) CLAMP(sv->vec.y, 0, winsizey); } + + /* scale prefsizes of regions */ + for (sa = sc->areabase.first; sa; sa = sa->next) { + ARegion *ar; + + for (ar = sa->regionbase.first; ar; ar = ar->next) { + ar->sizex = (int)((float)ar->sizex * facx); + ar->sizey = (int)((float)ar->sizey * facy); + ar->winx = (int)((float)ar->winx * facx); + ar->winy = (int)((float)ar->winy * facy); + } + if (sa->spacedata.first) { + SpaceLink *sl = sa->spacedata.first; + for (sl = sl->next; sl; sl = sl->next) { + for (ar = sl->regionbase.first; ar; ar = ar->next) { + ar->sizex = (int)((float)ar->sizex * facx); + ar->sizey = (int)((float)ar->sizey * facy); + ar->winx = (int)((float)ar->winx * facx); + ar->winy = (int)((float)ar->winy * facy); + } + } + } + } } /* test for collapsed areas. This could happen in some blender version... */ @@ -676,7 +702,7 @@ static void screen_test_scale(bScreen *sc, int winsizex, int winsizey) /* make each window at least ED_area_headersize() high */ for (sa = sc->areabase.first; sa; sa = sa->next) { - int headery = ED_area_headersize() + 1; + int headery = ED_area_headersize() + U.pixelsize; if (sa->v1->vec.y + headery > sa->v2->vec.y) { /* lower edge */ @@ -907,18 +933,18 @@ static void drawscredge_area(ScrArea *sa, int sizex, int sizey, int center) short y1 = sa->v1->vec.y; short x2 = sa->v3->vec.x; short y2 = sa->v3->vec.y; - short a, rt; - - rt = 0; // CLAMPIS(G.debug_value, 0, 16); if (center == 0) { - cpack(0x505050); - for (a = -rt; a <= rt; a++) - if (a != 0) - drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, a); + if (U.pixelsize > 1.0f) { + + glColor3ub(0x50, 0x50, 0x50); + glLineWidth(1.5f * U.pixelsize); + drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, 0); + glLineWidth(1.0f); + } } else { - cpack(0x0); + glColor3ub(0, 0, 0); drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, 0); } } @@ -1002,10 +1028,10 @@ void ED_screen_draw(wmWindow *win) if (sa->flag & AREA_FLAG_DRAWJOINFROM) sa1 = sa; if (sa->flag & AREA_FLAG_DRAWJOINTO) sa2 = sa; if (sa->flag & (AREA_FLAG_DRAWSPLIT_H | AREA_FLAG_DRAWSPLIT_V)) sa3 = sa; - drawscredge_area(sa, win->sizex, win->sizey, 0); + drawscredge_area(sa, WM_window_pixels_x(win), WM_window_pixels_y(win), 0); } for (sa = win->screen->areabase.first; sa; sa = sa->next) - drawscredge_area(sa, win->sizex, win->sizey, 1); + drawscredge_area(sa, WM_window_pixels_x(win), WM_window_pixels_y(win), 1); /* blended join arrow */ if (sa1 && sa2) { @@ -1078,20 +1104,20 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win) rcti winrct; winrct.xmin = 0; - winrct.xmax = win->sizex - 1; + winrct.xmax = WM_window_pixels_x(win) - 1; winrct.ymin = 0; - winrct.ymax = win->sizey - 1; + winrct.ymax = WM_window_pixels_y(win) - 1; + + /* header size depends on DPI, let's verify */ + screen_refresh_headersizes(); - screen_test_scale(win->screen, win->sizex, win->sizey); + screen_test_scale(win->screen, WM_window_pixels_x(win), WM_window_pixels_y(win)); if (win->screen->mainwin == 0) win->screen->mainwin = wm_subwindow_open(win, &winrct); else wm_subwindow_position(win, win->screen->mainwin, &winrct); - /* header size depends on DPI, let's verify */ - screen_refresh_headersizes(); - for (sa = win->screen->areabase.first; sa; sa = sa->next) { /* set spacetype and region callbacks, calls init() */ /* sets subwindows for regions, adds handlers */ @@ -1142,6 +1168,9 @@ void ED_region_exit(bContext *C, ARegion *ar) MEM_freeN(ar->headerstr); ar->headerstr = NULL; + if (ar->regiontimer) + WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), ar->regiontimer); + CTX_wm_region_set(C, prevar); } @@ -1262,9 +1291,12 @@ void ED_screen_set_subwinactive(bContext *C, wmEvent *event) break; } if (sa) { + /* make overlap active when mouse over */ for (ar = sa->regionbase.first; ar; ar = ar->next) { - if (BLI_rcti_isect_pt_v(&ar->winrct, &event->x)) + if (BLI_rcti_isect_pt_v(&ar->winrct, &event->x)) { scr->subwinactive = ar->swinid; + break; + } } } else diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h index 86d99777e98..b811fc46188 100644 --- a/source/blender/editors/screen/screen_intern.h +++ b/source/blender/editors/screen/screen_intern.h @@ -35,10 +35,11 @@ struct wmWindow; struct Scene; -#define AZONESPOT 12 +#define AZONESPOT (0.6f * U.widget_unit) /* area.c */ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space); +void region_toggle_hidden(bContext *C, ARegion *ar, int do_fade); /* screen_edit.c */ ScrEdge *screen_findedge(bScreen *sc, ScrVert *v1, ScrVert *v2); @@ -57,12 +58,16 @@ ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my); struct AZone *is_in_area_actionzone(ScrArea *sa, const int xy[2]); /* screen_context.c */ -int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result); +int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result); extern const char *screen_context_dir[]; /* doc access */ /* screendump.c */ -void SCREEN_OT_screenshot(struct wmOperatorType *ot); -void SCREEN_OT_screencast(struct wmOperatorType *ot); +void SCREEN_OT_screenshot(struct wmOperatorType *ot); +void SCREEN_OT_screencast(struct wmOperatorType *ot); + +/* screen_ops.c */ +void region_blend_start(struct bContext *C, struct ScrArea *sa, struct ARegion *ar); + #endif /* __SCREEN_INTERN_H__ */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 67d4af916aa..a26f5e87090 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -140,9 +140,11 @@ static int screen_active_editable(bContext *C) /* when mouse is over area-edge */ int ED_operator_screen_mainwinactive(bContext *C) { + bScreen *screen; if (CTX_wm_window(C) == NULL) return 0; - if (CTX_wm_screen(C) == NULL) return 0; - if (CTX_wm_screen(C)->subwinactive != CTX_wm_screen(C)->mainwin) return 0; + screen = CTX_wm_screen(C); + if (screen == NULL) return 0; + if (screen->subwinactive != screen->mainwin) return 0; return 1; } @@ -965,7 +967,7 @@ typedef struct sAreaMoveData { static void area_move_set_limits(bScreen *sc, int dir, int *bigger, int *smaller) { ScrArea *sa; - int areaminy = ED_area_headersize() + 1; + int areaminy = ED_area_headersize() + U.pixelsize; // pixelsize is used as area divider /* we check all areas and test for free space with MINSIZE */ *bigger = *smaller = 100000; @@ -975,18 +977,18 @@ static void area_move_set_limits(bScreen *sc, int dir, int *bigger, int *smaller int y1 = sa->v2->vec.y - sa->v1->vec.y - areaminy; /* if top or down edge selected, test height */ - if (sa->v1->flag && sa->v4->flag) + if (sa->v1->editflag && sa->v4->editflag) *bigger = min_ii(*bigger, y1); - else if (sa->v2->flag && sa->v3->flag) + else if (sa->v2->editflag && sa->v3->editflag) *smaller = min_ii(*smaller, y1); } else { int x1 = sa->v4->vec.x - sa->v1->vec.x - AREAMINX; /* if left or right edge selected, test width */ - if (sa->v1->flag && sa->v2->flag) + if (sa->v1->editflag && sa->v2->editflag) *bigger = min_ii(*bigger, x1); - else if (sa->v3->flag && sa->v4->flag) + else if (sa->v3->editflag && sa->v4->editflag) *smaller = min_ii(*smaller, x1); } } @@ -999,6 +1001,7 @@ static int area_move_init(bContext *C, wmOperator *op) bScreen *sc = CTX_wm_screen(C); ScrEdge *actedge; sAreaMoveData *md; + ScrVert *v1; int x, y; /* required properties */ @@ -1017,7 +1020,9 @@ static int area_move_init(bContext *C, wmOperator *op) else md->origval = actedge->v1->vec.x; select_connected_scredge(sc, actedge); - /* now all vertices with 'flag==1' are the ones that can be moved. */ + /* now all vertices with 'flag==1' are the ones that can be moved. Move this to editflag */ + for (v1 = sc->vertbase.first; v1; v1 = v1->next) + v1->editflag = v1->flag; area_move_set_limits(sc, md->dir, &md->bigger, &md->smaller); @@ -1036,27 +1041,27 @@ static void area_move_apply_do(bContext *C, int origval, int delta, int dir, int delta = CLAMPIS(delta, -smaller, bigger); for (v1 = sc->vertbase.first; v1; v1 = v1->next) { - if (v1->flag) { + if (v1->editflag) { /* that way a nice AREAGRID */ - if ((dir == 'v') && v1->vec.x > 0 && v1->vec.x < win->sizex - 1) { + if ((dir == 'v') && v1->vec.x > 0 && v1->vec.x < WM_window_pixels_x(win) - 1) { v1->vec.x = origval + delta; if (delta != bigger && delta != -smaller) v1->vec.x -= (v1->vec.x % AREAGRID); } - if ((dir == 'h') && v1->vec.y > 0 && v1->vec.y < win->sizey - 1) { + if ((dir == 'h') && v1->vec.y > 0 && v1->vec.y < WM_window_pixels_y(win) - 1) { v1->vec.y = origval + delta; v1->vec.y += AREAGRID - 1; v1->vec.y -= (v1->vec.y % AREAGRID); /* prevent too small top header */ - if (v1->vec.y > win->sizey - areaminy) - v1->vec.y = win->sizey - areaminy; + if (v1->vec.y > WM_window_pixels_y(win) - areaminy) + v1->vec.y = WM_window_pixels_y(win) - areaminy; } } } for (sa = sc->areabase.first; sa; sa = sa->next) { - if (sa->v1->flag || sa->v2->flag || sa->v3->flag || sa->v4->flag) + if (sa->v1->editflag || sa->v2->editflag || sa->v3->editflag || sa->v4->editflag) ED_area_tag_redraw(sa); } @@ -1334,10 +1339,10 @@ static int area_split_apply(bContext *C, wmOperator *op) /* select newly created edge, prepare for moving edge */ for (sv = sc->vertbase.first; sv; sv = sv->next) - sv->flag = 0; + sv->editflag = 0; - sd->nedge->v1->flag = 1; - sd->nedge->v2->flag = 1; + sd->nedge->v1->editflag = 1; + sd->nedge->v2->editflag = 1; if (dir == 'h') sd->origval = sd->nedge->v1->vec.y; else sd->origval = sd->nedge->v1->vec.x; @@ -1720,9 +1725,9 @@ static int region_scale_invoke(bContext *C, wmOperator *op, wmEvent *event) /* if not set we do now, otherwise it uses type */ if (rmd->ar->sizex == 0) - rmd->ar->sizex = rmd->ar->type->prefsizex; + rmd->ar->sizex = rmd->ar->winx; if (rmd->ar->sizey == 0) - rmd->ar->sizey = rmd->ar->type->prefsizey; + rmd->ar->sizey = rmd->ar->winy; /* now copy to regionmovedata */ if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) { @@ -1734,7 +1739,7 @@ static int region_scale_invoke(bContext *C, wmOperator *op, wmEvent *event) /* limit headers to standard height for now */ if (rmd->ar->regiontype == RGN_TYPE_HEADER) - maxsize = rmd->ar->type->prefsizey; + maxsize = ED_area_headersize(); else maxsize = 1000; @@ -1786,7 +1791,7 @@ static void region_scale_validate_size(RegionMoveData *rmd) static void region_scale_toggle_hidden(bContext *C, RegionMoveData *rmd) { - ED_region_toggle_hidden(C, rmd->ar); + region_toggle_hidden(C, rmd->ar, 0); region_scale_validate_size(rmd); } @@ -2797,7 +2802,6 @@ static void SCREEN_OT_region_quadview(wmOperatorType *ot) } - /* ************** region flip operator ***************************** */ /* flip a region alignment */ @@ -3413,6 +3417,7 @@ static void SCREEN_OT_back_to_previous(struct wmOperatorType *ot) static int userpref_show_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) { + wmWindow *win = CTX_wm_window(C); rcti rect; int sizex, sizey; @@ -3420,8 +3425,9 @@ static int userpref_show_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *ev sizey = 480; /* some magic to calculate postition */ - rect.xmin = event->x + CTX_wm_window(C)->posx - sizex / 2; - rect.ymin = event->y + CTX_wm_window(C)->posy - sizey / 2; + /* pixelsize: mouse coords are in U.pixelsize units :/ */ + rect.xmin = (event->x / U.pixelsize) + win->posx - sizex / 2; + rect.ymin = (event->y / U.pixelsize) + win->posy - sizey / 2; rect.xmax = rect.xmin + sizex; rect.ymax = rect.ymin + sizey; @@ -3506,7 +3512,7 @@ static int scene_new_exec(bContext *C, wmOperator *op) int type = RNA_enum_get(op->ptr, "type"); if (type == SCE_COPY_NEW) { - newscene = BKE_scene_add("Scene"); + newscene = BKE_scene_add(bmain, "Scene"); } else { /* different kinds of copying */ newscene = BKE_scene_copy(scene, type); @@ -3583,6 +3589,149 @@ static void SCENE_OT_delete(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/* ***************** region alpha blending ***************** */ + +/* implementation note: a disapplearing region needs at least 1 last draw with 100% backbuffer + texture over it- then triple buffer will clear it entirely. + This because flag RGN_HIDDEN is set in end - region doesnt draw at all then */ + +typedef struct RegionAlphaInfo { + ScrArea *sa; + ARegion *ar, *child_ar; /* other region */ + int hidden; +} RegionAlphaInfo; + +#define TIMEOUT 0.2f +#define TIMESTEP 0.04f + +float ED_region_blend_factor(ARegion *ar) +{ + /* check parent too */ + if (ar->regiontimer == NULL && (ar->alignment & RGN_SPLIT_PREV) && ar->prev) { + ar = ar->prev; + } + + if (ar->regiontimer) { + RegionAlphaInfo *rgi = ar->regiontimer->customdata; + float alpha; + + alpha = (float)ar->regiontimer->duration / TIMEOUT; + /* makes sure the blend out works 100% - without area redraws */ + if (rgi->hidden) alpha = 0.9f - TIMESTEP - alpha; + + CLAMP(alpha, 0.0f, 1.0f); + return alpha; + } + return 1.0f; +} + +/* assumes region has running region-blend timer */ +static void region_blend_end(bContext *C, ARegion *ar, int is_running) +{ + RegionAlphaInfo *rgi = ar->regiontimer->customdata; + + /* always send redraw */ + ED_region_tag_redraw(ar); + if (rgi->child_ar) + ED_region_tag_redraw(rgi->child_ar); + + /* if running timer was hiding, the flag toggle went wrong */ + if (is_running) { + if (rgi->hidden) + rgi->ar->flag &= ~RGN_FLAG_HIDDEN; + } + else { + if (rgi->hidden) { + rgi->ar->flag |= rgi->hidden; + ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), rgi->sa); + } + /* area decoration needs redraw in end */ + ED_area_tag_redraw(rgi->sa); + } + WM_event_remove_timer(CTX_wm_manager(C), NULL, ar->regiontimer); /* frees rgi */ + ar->regiontimer = NULL; + +} +/* assumes that *ar itself is not a splitted version from previous region */ +void region_blend_start(bContext *C, ScrArea *sa, ARegion *ar) +{ + wmWindowManager *wm = CTX_wm_manager(C); + wmWindow *win = CTX_wm_window(C); + RegionAlphaInfo *rgi; + + /* end running timer */ + if (ar->regiontimer) { + + region_blend_end(C, ar, 1); + } + rgi = MEM_callocN(sizeof(RegionAlphaInfo), "RegionAlphaInfo"); + + rgi->hidden = ar->flag & RGN_FLAG_HIDDEN; + rgi->sa = sa; + rgi->ar = ar; + ar->flag &= ~RGN_FLAG_HIDDEN; + + /* blend in, reinitialize regions because it got unhidden */ + if (rgi->hidden == 0) + ED_area_initialize(wm, win, sa); + else + WM_event_remove_handlers(C, &ar->handlers); + + if (ar->next) { + if (ar->next->alignment & RGN_SPLIT_PREV) { + rgi->child_ar = ar->next; + } + } + + /* new timer */ + ar->regiontimer = WM_event_add_timer(wm, win, TIMERREGION, TIMESTEP); + ar->regiontimer->customdata = rgi; + +} + +/* timer runs in win->handlers, so it cannot use context to find area/region */ +static int region_blend_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) +{ + RegionAlphaInfo *rgi; + wmTimer *timer = event->customdata; + + /* event type is TIMERREGION, but we better check */ + if (event->type != TIMERREGION || timer == NULL) + return OPERATOR_PASS_THROUGH; + + rgi = timer->customdata; + + /* always send redraws */ + ED_region_tag_redraw(rgi->ar); + if (rgi->child_ar) + ED_region_tag_redraw(rgi->child_ar); + + /* end timer? */ + if (rgi->ar->regiontimer->duration > (double)TIMEOUT) { + region_blend_end(C, rgi->ar, 0); + return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH); + } + + return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH); +} + +static void SCREEN_OT_region_blend(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Region Alpha"; + ot->idname = "SCREEN_OT_region_blend"; + ot->description = "Blend in and out overlapping region"; + + /* api callbacks */ + ot->invoke = region_blend_invoke; + + /* flags */ + ot->flag = 0; + + /* properties */ +} + + /* **************** Assigning operatortypes to global list, adding handlers **************** */ @@ -3615,6 +3764,7 @@ void ED_operatortypes_screen(void) WM_operatortype_append(SCREEN_OT_screenshot); WM_operatortype_append(SCREEN_OT_screencast); WM_operatortype_append(SCREEN_OT_userpref_show); + WM_operatortype_append(SCREEN_OT_region_blend); /*frame changes*/ WM_operatortype_append(SCREEN_OT_frame_offset); @@ -3717,6 +3867,7 @@ void ED_keymap_screen(wmKeyConfig *keyconf) /* standard timers */ WM_keymap_add_item(keymap, "SCREEN_OT_animation_step", TIMER0, KM_ANY, KM_ANY, 0); + WM_keymap_add_item(keymap, "SCREEN_OT_region_blend", TIMERREGION, KM_ANY, KM_ANY, 0); RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_screen_set", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", 1); diff --git a/source/blender/editors/sculpt_paint/SConscript b/source/blender/editors/sculpt_paint/SConscript index 21439e6c6b2..6767e06f65b 100644 --- a/source/blender/editors/sculpt_paint/SConscript +++ b/source/blender/editors/sculpt_paint/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c index bdd73cd6db3..36fe4715fc0 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.c +++ b/source/blender/editors/sculpt_paint/paint_hide.c @@ -37,7 +37,6 @@ #include "BLI_bitmap.h" #include "BLI_listbase.h" #include "BLI_math_vector.h" -#include "BLI_pbvh.h" #include "BLI_utildefines.h" #include "DNA_mesh_types.h" @@ -45,6 +44,7 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "BKE_pbvh.h" #include "BKE_ccg.h" #include "BKE_context.h" #include "BKE_DerivedMesh.h" diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index 697d7c63d1f..9fe7fc1d3ac 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -38,8 +38,7 @@ #include "DNA_meshdata_types.h" #include "DNA_object_types.h" -#include "BLI_pbvh.h" - +#include "BKE_pbvh.h" #include "BKE_ccg.h" #include "BKE_context.h" #include "BKE_DerivedMesh.h" diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index cb4b6346c2a..e7d13bd080d 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -189,7 +189,7 @@ float paint_get_tex_pixel(Brush *br, float u, float v) /* 3D Paint */ -static void imapaint_project(Object *ob, float model[][4], float proj[][4], const float co[3], float pco[4]) +static void imapaint_project(Object *ob, float model[4][4], float proj[4][4], const float co[3], float pco[4]) { copy_v3_v3(pco, co); pco[3] = 1.0f; diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 94b00101dc2..9bbf99ff3cf 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -346,7 +346,7 @@ static void make_vertexcol(Object *ob) /* single ob */ if (me->edit_btmesh) return; /* copies from shadedisplist to mcol */ - if (!me->mloopcol) { + if (!me->mloopcol && me->totloop) { if (!me->mcol) { CustomData_add_layer(&me->fdata, CD_MCOL, CD_DEFAULT, NULL, me->totface); } @@ -657,11 +657,11 @@ BLI_INLINE unsigned int mcol_sub(unsigned int col1, unsigned int col2, int fac) cp = (unsigned char *)&col; temp = cp1[0] - ((fac * cp2[0]) / 255); - cp1[0] = (temp < 0) ? 0 : temp; + cp[0] = (temp < 0) ? 0 : temp; temp = cp1[1] - ((fac * cp2[1]) / 255); - cp1[1] = (temp < 0) ? 0 : temp; + cp[1] = (temp < 0) ? 0 : temp; temp = cp1[2] - ((fac * cp2[2]) / 255); - cp1[2] = (temp < 0) ? 0 : temp; + cp[2] = (temp < 0) ? 0 : temp; cp[3] = 255; return col; @@ -851,12 +851,12 @@ static int sample_backbuf_area(ViewContext *vc, int *indexar, int totface, int x } /* whats _dl mean? */ -static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float vert_nor[3], +static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float co[3], const float mval[2], const float brush_size_pressure) { float vertco[2]; - if (ED_view3d_project_float_global(vc->ar, vert_nor, vertco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { + if (ED_view3d_project_float_global(vc->ar, co, vertco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { float delta[2]; float dist_squared; @@ -873,24 +873,23 @@ static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float vert_n } static float calc_vp_alpha_dl(VPaint *vp, ViewContext *vc, - float vpimat[][3], const float *vert_nor, + float vpimat[3][3], const DMCoNo *v_co_no, const float mval[2], const float brush_size_pressure, const float brush_alpha_pressure) { - float strength = calc_vp_strength_dl(vp, vc, vert_nor, mval, brush_size_pressure); + float strength = calc_vp_strength_dl(vp, vc, v_co_no->co, mval, brush_size_pressure); if (strength > 0.0f) { float alpha = brush_alpha_pressure * strength; if (vp->flag & VP_NORMALS) { float dvec[3]; - const float *no = vert_nor + 3; /* transpose ! */ - dvec[2] = dot_v3v3(vpimat[2], no); + dvec[2] = dot_v3v3(vpimat[2], v_co_no->no); if (dvec[2] > 0.0f) { - dvec[0] = dot_v3v3(vpimat[0], no); - dvec[1] = dot_v3v3(vpimat[1], no); + dvec[0] = dot_v3v3(vpimat[0], v_co_no->no); + dvec[1] = dot_v3v3(vpimat[1], v_co_no->no); alpha *= dvec[2] / len_v3(dvec); } @@ -2038,7 +2037,7 @@ struct WPaintData { int *indexar; int vgroup_active; int vgroup_mirror; - float *vertexcosnos; + DMCoNo *vertexcosnos; float wpimat[3][3]; /* variables for auto normalize */ @@ -2286,7 +2285,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P ml = me->mloop + mpoly->loopstart; for (i = 0; i < mpoly->totloop; i++, ml++) { unsigned int vidx = ml->v; - const float fac = calc_vp_strength_dl(wp, vc, wpd->vertexcosnos + 6 * vidx, mval, brush_size_pressure); + const float fac = calc_vp_strength_dl(wp, vc, wpd->vertexcosnos[vidx].co, mval, brush_size_pressure); if (fac > 0.0f) { dw = dw_func(&me->dvert[vidx], wpi.vgroup_active); paintweight += dw ? (dw->weight * fac) : 0.0f; @@ -2312,7 +2311,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P unsigned int vidx = ml->v; if (me->dvert[vidx].flag) { - alpha = calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos + 6 * vidx, + alpha = calc_vp_alpha_dl(wp, vc, wpd->wpimat, &wpd->vertexcosnos[vidx], mval, brush_size_pressure, brush_alpha_pressure); if (alpha) { do_weight_paint_vertex(wp, ob, &wpi, vidx, alpha, paintweight); @@ -2548,7 +2547,7 @@ typedef struct VPaintData { ViewContext vc; unsigned int paintcol; int *indexar; - float *vertexcosnos; + DMCoNo *vertexcosnos; float vpimat[3][3]; /* modify 'me->mcol' directly, since the derived mesh is drawing from this array, @@ -2647,13 +2646,12 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const fl return 1; } -static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Object *ob, +static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me, const unsigned int index, const float mval[2], const float brush_size_pressure, const float brush_alpha_pressure) { ViewContext *vc = &vpd->vc; Brush *brush = paint_brush(&vp->paint); - Mesh *me = BKE_mesh_from_object(ob); MPoly *mpoly = &me->mpoly[index]; MFace *mf; MCol *mc; @@ -2696,7 +2694,7 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Object *ob, ml = me->mloop + mpoly->loopstart; for (i = 0; i < mpoly->totloop; i++, ml++) { alpha = calc_vp_alpha_dl(vp, vc, vpd->vpimat, - vpd->vertexcosnos + 6 * ml->v, mval, + &vpd->vertexcosnos[ml->v], mval, brush_size_pressure, brush_alpha_pressure); if (alpha > 0.0f) { const int alpha_i = (int)(alpha * 255.0f); @@ -2787,7 +2785,7 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P for (index = 0; index < totindex; index++) { if (indexar[index] && indexar[index] <= me->totpoly) { - vpaint_paint_poly(vp, vpd, ob, indexar[index] - 1, mval, brush_size_pressure, brush_alpha_pressure); + vpaint_paint_poly(vp, vpd, me, indexar[index] - 1, mval, brush_size_pressure, brush_alpha_pressure); } } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index e2ed7776b7e..8325b47beab 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -40,7 +40,6 @@ #include "BLI_utildefines.h" #include "BLI_dynstr.h" #include "BLI_ghash.h" -#include "BLI_pbvh.h" #include "BLI_threads.h" #include "BLI_rand.h" @@ -51,6 +50,7 @@ #include "DNA_scene_types.h" #include "DNA_brush_types.h" +#include "BKE_pbvh.h" #include "BKE_brush.h" #include "BKE_ccg.h" #include "BKE_cdderivedmesh.h" diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index acb906e4a91..44068122b89 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -38,7 +38,7 @@ #include "DNA_key_types.h" #include "BLI_bitmap.h" -#include "BLI_pbvh.h" +#include "BKE_pbvh.h" struct bContext; struct Brush; diff --git a/source/blender/editors/sound/SConscript b/source/blender/editors/sound/SConscript index e17bccdadd9..1eaf9c2e945 100644 --- a/source/blender/editors/sound/SConscript +++ b/source/blender/editors/sound/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_action/SConscript b/source/blender/editors/space_action/SConscript index 0fee8ff68ab..abaf6154a42 100644 --- a/source/blender/editors/space_action/SConscript +++ b/source/blender/editors/space_action/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_api/SConscript b/source/blender/editors/space_api/SConscript index 9b818b074ba..a07be054011 100644 --- a/source/blender/editors/space_api/SConscript +++ b/source/blender/editors/space_api/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_buttons/SConscript b/source/blender/editors/space_buttons/SConscript index 92579b6dedf..5250a1264a4 100644 --- a/source/blender/editors/space_buttons/SConscript +++ b/source/blender/editors/space_buttons/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c index abfefba02b9..935b15f3cd8 100644 --- a/source/blender/editors/space_buttons/buttons_texture.c +++ b/source/blender/editors/space_buttons/buttons_texture.c @@ -358,7 +358,17 @@ static void template_texture_user_menu(bContext *C, uiLayout *layout, void *UNUS } /* create button */ - BLI_snprintf(name, UI_MAX_NAME_STR, " %s", user->name); + if (user->prop) { + PointerRNA texptr = RNA_property_pointer_get(&user->ptr, user->prop); + Tex *tex = texptr.data; + + if (tex) + BLI_snprintf(name, UI_MAX_NAME_STR, " %s - %s", user->name, tex->id.name + 2); + else + BLI_snprintf(name, UI_MAX_NAME_STR, " %s", user->name); + } + else + BLI_snprintf(name, UI_MAX_NAME_STR, " %s", user->name); but = uiDefIconTextBut(block, BUT, 0, user->icon, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, ""); diff --git a/source/blender/editors/space_clip/SConscript b/source/blender/editors/space_clip/SConscript index c9c82aea68e..2cbefee0170 100644 --- a/source/blender/editors/space_clip/SConscript +++ b/source/blender/editors/space_clip/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c index 969b0e25928..2cb6d8c9234 100644 --- a/source/blender/editors/space_clip/clip_buttons.c +++ b/source/blender/editors/space_clip/clip_buttons.c @@ -78,6 +78,7 @@ void ED_clip_buttons_register(ARegionType *art) pt = MEM_callocN(sizeof(PanelType), "spacetype clip panel gpencil"); strcpy(pt->idname, "CLIP_PT_gpencil"); strcpy(pt->label, "Grease Pencil"); + pt->draw_header = gpencil_panel_standard_header; pt->draw = gpencil_panel_standard; pt->flag |= PNL_DEFAULT_CLOSED; pt->poll = clip_grease_pencil_panel_poll; diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 9cf389c4508..56f2998b047 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -103,11 +103,11 @@ static void draw_keyframe(int frame, int cfra, int sfra, float framelen, int wid if (width == 1) { glBegin(GL_LINES); glVertex2i(x, 0); - glVertex2i(x, height); + glVertex2i(x, height * UI_DPI_FAC); glEnd(); } else { - glRecti(x, 0, x + width, height); + glRecti(x, 0, x + width, height * UI_DPI_FAC); } } @@ -125,7 +125,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc /* cache background */ glColor4ub(128, 128, 255, 64); - glRecti(0, 0, ar->winx, 8); + glRecti(0, 0, ar->winx, 8 * UI_DPI_FAC); /* cached segments -- could be usefu lto debug caching strategies */ BKE_movieclip_get_cache_segments(clip, &sc->user, &totseg, &points); @@ -138,7 +138,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc x1 = (points[a * 2] - sfra) / (efra - sfra + 1) * ar->winx; x2 = (points[a * 2 + 1] - sfra + 1) / (efra - sfra + 1) * ar->winx; - glRecti(x1, 0, x2, 8); + glRecti(x1, 0, x2, 8 * UI_DPI_FAC); } } @@ -175,7 +175,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc else glColor4ub(255, 255, 0, 96); - glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 4); + glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 4 * UI_DPI_FAC); } } } @@ -203,7 +203,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc } if (!ok) - glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 8); + glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 8 * UI_DPI_FAC); } } @@ -213,9 +213,9 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc x = (sc->user.framenr - sfra) / (efra - sfra + 1) * ar->winx; UI_ThemeColor(TH_CFRAME); - glRecti(x, 0, x + ceilf(framelen), 8); + glRecti(x, 0, x + ceilf(framelen), 8 * UI_DPI_FAC); - clip_draw_curfra_label(sc->user.framenr, x, 8.0f); + clip_draw_curfra_label(sc->user.framenr, x, 8.0f * UI_DPI_FAC); /* solver keyframes */ glColor4ub(175, 255, 0, 255); @@ -796,11 +796,11 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo dy = 6.0f / height / sc->zoom; side = get_shortest_pattern_side(marker); - patdx = min_ff(dx * 2.0f / 3.0f, side / 6.0f); - patdy = min_ff(dy * 2.0f / 3.0f, side * width / height / 6.0f); + patdx = min_ff(dx * 2.0f / 3.0f, side / 6.0f) * UI_DPI_FAC; + patdy = min_ff(dy * 2.0f / 3.0f, side * width / height / 6.0f) * UI_DPI_FAC; - searchdx = min_ff(dx, (marker->search_max[0] - marker->search_min[0]) / 6.0f); - searchdy = min_ff(dy, (marker->search_max[1] - marker->search_min[1]) / 6.0f); + searchdx = min_ff(dx, (marker->search_max[0] - marker->search_min[0]) / 6.0f) * UI_DPI_FAC; + searchdy = min_ff(dy, (marker->search_max[1] - marker->search_min[1]) / 6.0f) * UI_DPI_FAC; px[0] = 1.0f / sc->zoom / width / sc->scale; px[1] = 1.0f / sc->zoom / height / sc->scale; diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 1a62af39600..3088243d266 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -38,6 +38,7 @@ #include "BKE_movieclip.h" #include "BKE_context.h" #include "BKE_tracking.h" +#include "BKE_library.h" #include "DNA_mask_types.h" #include "DNA_object_types.h" /* SELECT */ @@ -524,8 +525,7 @@ void ED_space_clip_set_clip(bContext *C, bScreen *screen, SpaceClip *sc, MovieCl old_clip = sc->clip; sc->clip = clip; - if (sc->clip && sc->clip->id.us == 0) - sc->clip->id.us = 1; + id_us_ensure_real((ID *)sc->clip); if (screen && sc->view == SC_VIEW_CLIP) { ScrArea *area; @@ -561,9 +561,7 @@ void ED_space_clip_set_mask(bContext *C, SpaceClip *sc, Mask *mask) { sc->mask_info.mask = mask; - if (sc->mask_info.mask && sc->mask_info.mask->id.us == 0) { - sc->mask_info.mask->id.us = 1; - } + id_us_ensure_real((ID *)sc->mask_info.mask); if (C) { WM_event_add_notifier(C, NC_MASK | NA_SELECTED, mask); diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h index d33f77c1064..ac5cfbaed11 100644 --- a/source/blender/editors/space_clip/clip_intern.h +++ b/source/blender/editors/space_clip/clip_intern.h @@ -43,10 +43,10 @@ struct SpaceClip; struct wmOperatorType; /* channel heights */ -#define CHANNEL_FIRST -UI_UNIT_Y -#define CHANNEL_HEIGHT UI_UNIT_Y -#define CHANNEL_HEIGHT_HALF (UI_UNIT_Y / 2.0f) -#define CHANNEL_SKIP 2 +#define CHANNEL_FIRST (-0.8f * U.widget_unit) +#define CHANNEL_HEIGHT (0.8f * U.widget_unit) +#define CHANNEL_HEIGHT_HALF (0.4f * U.widget_unit) +#define CHANNEL_SKIP (0.1f * U.widget_unit) #define CHANNEL_STEP (CHANNEL_HEIGHT + CHANNEL_SKIP) #define CHANNEL_PAD 4 @@ -54,7 +54,7 @@ struct wmOperatorType; /* extra padding for lengths (to go under scrollers) */ #define EXTRA_SCROLL_PAD 100.0f -#define STRIP_HEIGHT_HALF 5 +#define STRIP_HEIGHT_HALF (0.25 * UI_UNIT_Y) /* internal exports only */ diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 77e2a1bb3d3..dc7b6d77c9e 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -246,7 +246,7 @@ static SpaceLink *clip_new(const bContext *C) sc = MEM_callocN(sizeof(SpaceClip), "initclip"); sc->spacetype = SPACE_CLIP; sc->flag = SC_SHOW_MARKER_PATTERN | SC_SHOW_TRACK_PATH | SC_MANUAL_CALIBRATION | - SC_SHOW_GRAPH_TRACKS | SC_SHOW_GRAPH_FRAMES; + SC_SHOW_GRAPH_TRACKS | SC_SHOW_GRAPH_FRAMES | SC_SHOW_GPENCIL; sc->zoom = 1.0f; sc->path_length = 20; sc->scopes.track_preview_height = 120; @@ -592,9 +592,14 @@ static void clip_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_out", PADMINUS, KM_PRESS, 0, 0); + /* ctrl now works as well, shift + numpad works as arrow keys on Windows */ + RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 8.0f); + RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 4.0f); + RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 2.0f); RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 8.0f); RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 4.0f); RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 2.0f); + RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD1, KM_PRESS, 0, 0)->ptr, "ratio", 1.0f); RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD2, KM_PRESS, 0, 0)->ptr, "ratio", 0.5f); RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD4, KM_PRESS, 0, 0)->ptr, "ratio", 0.25f); @@ -1146,14 +1151,18 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar) } - /* Grease Pencil */ - clip_draw_grease_pencil((bContext *)C, 1); + if (sc->flag & SC_SHOW_GPENCIL) { + /* Grease Pencil */ + clip_draw_grease_pencil((bContext *)C, TRUE); + } /* reset view matrix */ UI_view2d_view_restore(C); - /* draw Grease Pencil - screen space only */ - clip_draw_grease_pencil((bContext *)C, 0); + if (sc->flag & SC_SHOW_GPENCIL) { + /* draw Grease Pencil - screen space only */ + clip_draw_grease_pencil((bContext *)C, FALSE); + } } static void clip_main_area_listener(ARegion *ar, wmNotifier *wmn) diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index a29524de36d..77662d8ac13 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -2025,7 +2025,7 @@ static void set_axis(Scene *scene, Object *ob, MovieClip *clip, MovieTrackingOb if (!flip) { float lmat[4][4], ilmat[4][4], rmat[3][3]; - BKE_object_rot_to_mat3(ob, rmat); + BKE_object_rot_to_mat3(ob, rmat, TRUE); invert_m3(rmat); mul_m4_m4m3(mat, mat, rmat); diff --git a/source/blender/editors/space_console/SConscript b/source/blender/editors/space_console/SConscript index f246f08d7ac..3e2c9d6dfdf 100644 --- a/source/blender/editors/space_console/SConscript +++ b/source/blender/editors/space_console/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c index a215b476094..22c260de1a1 100644 --- a/source/blender/editors/space_console/console_draw.c +++ b/source/blender/editors/space_console/console_draw.c @@ -50,7 +50,9 @@ #include "ED_datafiles.h" #include "ED_types.h" +#include "UI_interface.h" #include "UI_resources.h" +#include "UI_view2d.h" #include "console_intern.h" @@ -79,9 +81,9 @@ typedef struct ConsoleDrawContext { int cwidth; int lheight; int console_width; - int winx; int ymin, ymax; #if 0 /* used by textview, may use later */ + int winx; int *xy; // [2] int *sel; // [2] int *pos_pick; /* bottom of view == 0, top of file == combine chars, end of line is lower then start. */ @@ -111,15 +113,12 @@ void console_scrollback_prompt_end(struct SpaceConsole *sc, ConsoleLine *cl_dumm } #define CONSOLE_DRAW_MARGIN 4 -#define CONSOLE_DRAW_SCROLL 16 - - /* console textview callbacks */ static int console_textview_begin(TextViewContext *tvc) { SpaceConsole *sc = (SpaceConsole *)tvc->arg1; - tvc->lheight = sc->lheight; + tvc->lheight = sc->lheight * UI_DPI_FAC; tvc->sel_start = sc->sel_start; tvc->sel_end = sc->sel_end; @@ -195,7 +194,8 @@ static int console_textview_line_color(struct TextViewContext *tvc, unsigned cha } -static int console_textview_main__internal(struct SpaceConsole *sc, ARegion *ar, int draw, int mval[2], void **mouse_pick, int *pos_pick) +static int console_textview_main__internal(struct SpaceConsole *sc, ARegion *ar, int draw, + int mval[2], void **mouse_pick, int *pos_pick) { ConsoleLine cl_dummy = {NULL}; int ret = 0; @@ -217,10 +217,10 @@ static int console_textview_main__internal(struct SpaceConsole *sc, ARegion *ar, /* view */ tvc.sel_start = sc->sel_start; tvc.sel_end = sc->sel_end; - tvc.lheight = sc->lheight; + tvc.lheight = sc->lheight * UI_DPI_FAC; tvc.ymin = v2d->cur.ymin; tvc.ymax = v2d->cur.ymax; - tvc.winx = ar->winx; + tvc.winx = ar->winx - V2D_SCROLL_WIDTH; console_scrollback_prompt_begin(sc, &cl_dummy); ret = textview_draw(&tvc, draw, mval, mouse_pick, pos_pick); @@ -242,13 +242,13 @@ int console_textview_height(struct SpaceConsole *sc, ARegion *ar) return console_textview_main__internal(sc, ar, 0, mval, NULL, NULL); } -int console_char_pick(struct SpaceConsole *sc, ARegion *ar, int mval[2]) +int console_char_pick(struct SpaceConsole *sc, ARegion *ar, const int mval[2]) { int pos_pick = 0; void *mouse_pick = NULL; int mval_clamp[2]; - mval_clamp[0] = CLAMPIS(mval[0], CONSOLE_DRAW_MARGIN, ar->winx - (CONSOLE_DRAW_SCROLL + CONSOLE_DRAW_MARGIN)); + mval_clamp[0] = CLAMPIS(mval[0], CONSOLE_DRAW_MARGIN, ar->winx - CONSOLE_DRAW_MARGIN); mval_clamp[1] = CLAMPIS(mval[1], CONSOLE_DRAW_MARGIN, ar->winy - CONSOLE_DRAW_MARGIN); console_textview_main__internal(sc, ar, 0, mval_clamp, &mouse_pick, &pos_pick); diff --git a/source/blender/editors/space_console/console_intern.h b/source/blender/editors/space_console/console_intern.h index 3d30dcad710..1e79e4b9714 100644 --- a/source/blender/editors/space_console/console_intern.h +++ b/source/blender/editors/space_console/console_intern.h @@ -37,7 +37,7 @@ struct bContext; /* console_draw.c */ void console_textview_main(struct SpaceConsole *sc, struct ARegion *ar); int console_textview_height(struct SpaceConsole *sc, struct ARegion *ar); /* needed to calculate the scrollbar */ -int console_char_pick(struct SpaceConsole *sc, struct ARegion *ar, int mval[2]); +int console_char_pick(struct SpaceConsole *sc, struct ARegion *ar, const int mval[2]); void console_scrollback_prompt_begin(struct SpaceConsole *sc, ConsoleLine *cl_dummy); void console_scrollback_prompt_end(struct SpaceConsole *sc, ConsoleLine *cl_dummy); diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index be8febdab23..eed269ff70f 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -174,7 +174,7 @@ static void id_drop_copy(wmDrag *drag, wmDropBox *drop) ID *id = drag->poin; /* copy drag path to properties */ - text = RNA_path_from_ID_python(id); + text = RNA_path_full_ID_py(id); RNA_string_set(drop->ptr, "text", text); MEM_freeN(text); } diff --git a/source/blender/editors/space_file/SConscript b/source/blender/editors/space_file/SConscript index b387d489805..c3f8c6667f7 100644 --- a/source/blender/editors/space_file/SConscript +++ b/source/blender/editors/space_file/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c index a5647c06b92..5f1f9a3ab22 100644 --- a/source/blender/editors/space_file/fsmenu.c +++ b/source/blender/editors/space_file/fsmenu.c @@ -350,7 +350,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) #else #ifdef __APPLE__ { -#if (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4) +#if (MAC_OS_X_VERSION_MIN_REQUIRED <= 1040) OSErr err = noErr; int i; const char *home; diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index be037a0d5ba..7cc322c06bb 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -533,7 +533,7 @@ static void file_ui_area_draw(const bContext *C, ARegion *ar) { float col[3]; /* clear */ - UI_GetThemeColor3fv(TH_PANEL, col); + UI_GetThemeColor3fv(TH_BACK, col); glClearColor(col[0], col[1], col[2], 0.0); glClear(GL_COLOR_BUFFER_BIT); diff --git a/source/blender/editors/space_graph/SConscript b/source/blender/editors/space_graph/SConscript index 83239a5480a..84ac27a8962 100644 --- a/source/blender/editors/space_graph/SConscript +++ b/source/blender/editors/space_graph/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index f665b979559..256c90a1f1a 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -516,7 +516,7 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d */ /* grid->dx represents the number of 'frames' between gridlines, but we divide by U.v2d_min_gridsize to get pixels-steps */ /* TODO: perhaps we should have 1.0 frames as upper limit so that curves don't get too distorted? */ - samplefreq = dx / U.v2d_min_gridsize; + samplefreq = dx / (U.v2d_min_gridsize * U.pixelsize); if (samplefreq < 0.00001f) samplefreq = 0.00001f; diff --git a/source/blender/editors/space_image/SConscript b/source/blender/editors/space_image/SConscript index 737da4aac74..6e7c5982d6e 100644 --- a/source/blender/editors/space_image/SConscript +++ b/source/blender/editors/space_image/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 0a3db59096a..d02186e59dd 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -858,6 +858,7 @@ void image_buttons_register(ARegionType *art) pt = MEM_callocN(sizeof(PanelType), "spacetype image panel gpencil"); strcpy(pt->idname, "IMAGE_PT_gpencil"); strcpy(pt->label, "Grease Pencil"); + pt->draw_header = gpencil_panel_standard_header; pt->draw = gpencil_panel_standard; BLI_addtail(&art->paneltypes, pt); } diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c index c4e2230e7a7..34207e16f1c 100644 --- a/source/blender/editors/space_image/image_edit.c +++ b/source/blender/editors/space_image/image_edit.c @@ -40,6 +40,7 @@ #include "BKE_image.h" #include "BKE_main.h" #include "BKE_tessmesh.h" +#include "BKE_library.h" #include "IMB_imbuf_types.h" @@ -78,8 +79,7 @@ void ED_space_image_set(SpaceImage *sima, Scene *scene, Object *obedit, Image *i if (sima->image) BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE); - if (sima->image && ID_REAL_USERS(sima->image) <= 0) - sima->image->id.us = max_ii(sima->image->id.us, 0) + 1; + id_us_ensure_real((ID *)sima->image); if (obedit) WM_main_add_notifier(NC_GEOM | ND_DATA, obedit->data); @@ -97,8 +97,7 @@ void ED_space_image_set_mask(bContext *C, SpaceImage *sima, Mask *mask) sima->mask_info.mask = mask; /* weak, but same as image/space */ - if (sima->mask_info.mask && ID_REAL_USERS(sima->mask_info.mask) <= 0) - sima->mask_info.mask->id.us = max_ii(sima->mask_info.mask->id.us, 0) + 1; + id_us_ensure_real((ID *)sima->mask_info.mask); if (C) { WM_event_add_notifier(C, NC_MASK | NA_SELECTED, mask); @@ -194,9 +193,7 @@ void ED_space_image_get_size_fl(SpaceImage *sima, float size[2]) void ED_space_image_get_aspect(SpaceImage *sima, float *aspx, float *aspy) { Image *ima = sima->image; - if ((ima == NULL) || (ima->type == IMA_TYPE_R_RESULT) || (ima->type == IMA_TYPE_COMPOSITE) || - (ima->aspx == 0.0f || ima->aspy == 0.0f)) - { + if ((ima == NULL) || (ima->aspx == 0.0f || ima->aspy == 0.0f)) { *aspx = *aspy = 1.0; } else { diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index ea696772957..b0e9f8bcf99 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -151,6 +151,7 @@ static SpaceLink *image_new(const bContext *UNUSED(C)) simage->spacetype = SPACE_IMAGE; simage->zoom = 1.0f; simage->lock = TRUE; + simage->flag = SI_SHOW_GPENCIL; simage->iuser.ok = TRUE; simage->iuser.fie_ima = 2; @@ -292,9 +293,14 @@ static void image_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom", MOUSEZOOM, 0, 0, 0); + /* ctrl now works as well, shift + numpad works as arrow keys on Windows */ + RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 8.0f); + RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 4.0f); + RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_CTRL, 0)->ptr, "ratio", 2.0f); RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 8.0f); RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 4.0f); RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 2.0f); + RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD1, KM_PRESS, 0, 0)->ptr, "ratio", 1.0f); RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD2, KM_PRESS, 0, 0)->ptr, "ratio", 0.5f); RNA_float_set(WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_ratio", PAD4, KM_PRESS, 0, 0)->ptr, "ratio", 0.25f); @@ -669,16 +675,20 @@ static void image_main_area_draw(const bContext *C, ARegion *ar) ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); - /* Grease Pencil too (in addition to UV's) */ - draw_image_grease_pencil((bContext *)C, 1); + if (sima->flag & SI_SHOW_GPENCIL) { + /* Grease Pencil too (in addition to UV's) */ + draw_image_grease_pencil((bContext *)C, TRUE); + } /* sample line */ draw_image_sample_line(sima); UI_view2d_view_restore(C); - /* draw Grease Pencil - screen space only */ - draw_image_grease_pencil((bContext *)C, 0); + if (sima->flag & SI_SHOW_GPENCIL) { + /* draw Grease Pencil - screen space only */ + draw_image_grease_pencil((bContext *)C, FALSE); + } if (mask) { int width, height; diff --git a/source/blender/editors/space_info/SConscript b/source/blender/editors/space_info/SConscript index e4746aefa0c..bacc28161d3 100644 --- a/source/blender/editors/space_info/SConscript +++ b/source/blender/editors/space_info/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_info/info_draw.c b/source/blender/editors/space_info/info_draw.c index 5830c4574df..54afc9a0849 100644 --- a/source/blender/editors/space_info/info_draw.c +++ b/source/blender/editors/space_info/info_draw.c @@ -56,6 +56,8 @@ #include "ED_types.h" #include "UI_resources.h" +#include "UI_interface.h" +#include "UI_view2d.h" #include "info_intern.h" #include "../space_info/textview.h" @@ -139,7 +141,7 @@ static int report_textview_begin(TextViewContext *tvc) // SpaceConsole *sc = (SpaceConsole *)tvc->arg1; ReportList *reports = (ReportList *)tvc->arg2; - tvc->lheight = 14; //sc->lheight; + tvc->lheight = 14 * UI_DPI_FAC; //sc->lheight; tvc->sel_start = 0; tvc->sel_end = 0; @@ -269,10 +271,10 @@ static int info_textview_main__internal(struct SpaceInfo *sinfo, ARegion *ar, Re /* view */ tvc.sel_start = 0; tvc.sel_end = 0; - tvc.lheight = 14; //sc->lheight; + tvc.lheight = 14 * UI_DPI_FAC; //sc->lheight; tvc.ymin = v2d->cur.ymin; tvc.ymax = v2d->cur.ymax; - tvc.winx = ar->winx; + tvc.winx = ar->winx - V2D_SCROLL_WIDTH; ret = textview_draw(&tvc, draw, mval, mouse_pick, pos_pick); diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c index 48b5eaf7b44..e902a4ea6f4 100644 --- a/source/blender/editors/space_info/info_ops.c +++ b/source/blender/editors/space_info/info_ops.c @@ -40,7 +40,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_utildefines.h" #include "BKE_context.h" @@ -204,7 +204,7 @@ static int make_paths_relative_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - BLI_bpath_relative_convert(bmain, bmain->name, op->reports); + BKE_bpath_relative_convert(bmain, bmain->name, op->reports); /* redraw everything so any changed paths register */ WM_main_add_notifier(NC_WINDOW, NULL); @@ -237,7 +237,7 @@ static int make_paths_absolute_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - BLI_bpath_absolute_convert(bmain, bmain->name, op->reports); + BKE_bpath_absolute_convert(bmain, bmain->name, op->reports); /* redraw everything so any changed paths register */ WM_main_add_notifier(NC_WINDOW, NULL); @@ -266,7 +266,7 @@ static int report_missing_files_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); /* run the missing file check */ - BLI_bpath_missing_files_check(bmain, op->reports); + BKE_bpath_missing_files_check(bmain, op->reports); return OPERATOR_FINISHED; } @@ -291,7 +291,7 @@ static int find_missing_files_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); const char *searchpath = RNA_string_get_alloc(op->ptr, "filepath", NULL, 0); - BLI_bpath_missing_files_find(bmain, searchpath, op->reports); + BKE_bpath_missing_files_find(bmain, searchpath, op->reports); MEM_freeN((void *)searchpath); return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_info/info_report.c b/source/blender/editors/space_info/info_report.c index 049a50f89fc..023ffa50272 100644 --- a/source/blender/editors/space_info/info_report.c +++ b/source/blender/editors/space_info/info_report.c @@ -62,7 +62,7 @@ int info_report_mask(SpaceInfo *UNUSED(sinfo)) return report_mask; #endif - return RPT_DEBUG_ALL | RPT_INFO_ALL | RPT_OPERATOR_ALL | RPT_WARNING_ALL | RPT_ERROR_ALL; + return RPT_DEBUG_ALL | RPT_INFO_ALL | RPT_OPERATOR_ALL | RPT_PROPERTY_ALL | RPT_WARNING_ALL | RPT_ERROR_ALL; } // TODO, get this working again! @@ -77,7 +77,10 @@ static int report_replay_exec(bContext *C, wmOperator *UNUSED(op)) sc->type = CONSOLE_TYPE_PYTHON; for (report = reports->list.last; report; report = report->prev) { - if ((report->type & report_mask) && (report->type & RPT_OPERATOR_ALL) && (report->flag & SELECT)) { + if ((report->type & report_mask) && + (report->type & RPT_OPERATOR_ALL | RPT_PROPERTY_ALL) && + (report->flag & SELECT)) + { console_history_add_str(sc, report->message, 0); WM_operator_name_call(C, "CONSOLE_OT_execute", WM_OP_EXEC_DEFAULT, NULL); diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c index cba0a808d63..db9be22eedb 100644 --- a/source/blender/editors/space_info/space_info.c +++ b/source/blender/editors/space_info/space_info.c @@ -272,7 +272,7 @@ static void info_header_listener(ARegion *ar, wmNotifier *wmn) static void recent_files_menu_draw(const bContext *UNUSED(C), Menu *menu) { struct RecentFile *recent; - char file [FILE_MAX]; + char file[FILE_MAX]; uiLayout *layout = menu->layout; uiLayoutSetOperatorContext(layout, WM_OP_EXEC_REGION_WIN); if (G.recent_files.first) { diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c index f454b1dbe7d..e5f8d6553ed 100644 --- a/source/blender/editors/space_info/textview.c +++ b/source/blender/editors/space_info/textview.c @@ -45,7 +45,8 @@ static void console_font_begin(TextViewContext *sc) { - BLF_size(blf_mono_font, sc->lheight - 2, 72); + /* 0.875 is based on: 16 pixels lines get 14 pixel text */ + BLF_size(blf_mono_font, 0.875 * sc->lheight, 72); } typedef struct ConsoleDrawContext { @@ -61,7 +62,13 @@ typedef struct ConsoleDrawContext { int draw; } ConsoleDrawContext; -static void console_draw_sel(int sel[2], int xy[2], int str_len_draw, int cwidth, int lheight) +BLI_INLINE void console_step_sel(ConsoleDrawContext *cdc, const int step) +{ + cdc->sel[0] += step; + cdc->sel[1] += step; +} + +static void console_draw_sel(const int sel[2], const int xy[2], const int str_len_draw, int cwidth, int lheight) { if (sel[0] <= str_len_draw && sel[1] >= 0) { int sta = max_ii(sel[0], 0); @@ -84,9 +91,9 @@ static void console_draw_sel(int sel[2], int xy[2], int str_len_draw, int cwidth /* return 0 if the last line is off the screen * should be able to use this for any string type */ -static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str_len, unsigned char *fg, unsigned char *bg) +static int console_draw_string(ConsoleDrawContext *cdc, const char *str, const int str_len, + const unsigned char *fg, const unsigned char *bg) { -#define STEP_SEL(value) cdc->sel[0] += (value); cdc->sel[1] += (value) int rct_ofs = cdc->lheight / 4; int tot_lines = (str_len / cdc->console_width) + 1; /* total number of lines for wrapping */ int y_next = (str_len > cdc->console_width) ? cdc->xy[1] + cdc->lheight * tot_lines : cdc->xy[1] + cdc->lheight; @@ -120,7 +127,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str /* adjust selection even if not drawing */ if (cdc->sel[0] != cdc->sel[1]) { - STEP_SEL(-(str_len + 1)); + console_step_sel(cdc, -(str_len + 1)); } return 1; @@ -149,10 +156,10 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str BLF_draw(mono, line_stride, str_len - initial_offset); if (cdc->sel[0] != cdc->sel[1]) { - STEP_SEL(-initial_offset); + console_step_sel(cdc, -initial_offset); // glColor4ub(255, 0, 0, 96); // debug console_draw_sel(cdc->sel, cdc->xy, str_len % cdc->console_width, cdc->cwidth, cdc->lheight); - STEP_SEL(cdc->console_width); + console_step_sel(cdc, cdc->console_width); glColor3ubv(fg); } @@ -167,7 +174,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str if (cdc->sel[0] != cdc->sel[1]) { // glColor4ub(0, 255, 0, 96); // debug console_draw_sel(cdc->sel, cdc->xy, cdc->console_width, cdc->cwidth, cdc->lheight); - STEP_SEL(cdc->console_width); + console_step_sel(cdc, cdc->console_width); glColor3ubv(fg); } @@ -179,7 +186,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str } copy_v2_v2_int(cdc->sel, sel_orig); - STEP_SEL(-(str_len + 1)); + console_step_sel(cdc, -(str_len + 1)); } else { /* simple, no wrap */ @@ -201,7 +208,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str // glColor4ub(255, 255, 0, 96); // debug console_draw_sel(isel, cdc->xy, str_len, cdc->cwidth, cdc->lheight); - STEP_SEL(-(str_len + 1)); + console_step_sel(cdc, -(str_len + 1)); } cdc->xy[1] += cdc->lheight; @@ -211,13 +218,11 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str } return 1; -#undef STEP_SEL } #define CONSOLE_DRAW_MARGIN 4 -#define CONSOLE_DRAW_SCROLL 16 -int textview_draw(TextViewContext *tvc, int draw, int mval[2], void **mouse_pick, int *pos_pick) +int textview_draw(TextViewContext *tvc, const int draw, int mval[2], void **mouse_pick, int *pos_pick) { ConsoleDrawContext cdc = {0}; @@ -241,9 +246,10 @@ int textview_draw(TextViewContext *tvc, int draw, int mval[2], void **mouse_pick cdc.cwidth = (int)BLF_fixed_width(mono); assert(cdc.cwidth > 0); cdc.lheight = tvc->lheight; - cdc.console_width = (tvc->winx - (CONSOLE_DRAW_SCROLL + CONSOLE_DRAW_MARGIN * 2) ) / cdc.cwidth; + /* note, scroll bar must be already subtracted () */ + cdc.console_width = (tvc->winx - (CONSOLE_DRAW_MARGIN * 2) ) / cdc.cwidth; CLAMP(cdc.console_width, 1, INT_MAX); /* avoid divide by zero on small windows */ - cdc.winx = tvc->winx - (CONSOLE_DRAW_MARGIN + CONSOLE_DRAW_SCROLL); + cdc.winx = tvc->winx - CONSOLE_DRAW_MARGIN; cdc.ymin = tvc->ymin; cdc.ymax = tvc->ymax; cdc.xy = xy; diff --git a/source/blender/editors/space_info/textview.h b/source/blender/editors/space_info/textview.h index 33fbe556245..d0fab880dc3 100644 --- a/source/blender/editors/space_info/textview.h +++ b/source/blender/editors/space_info/textview.h @@ -54,7 +54,7 @@ typedef struct TextViewContext { } TextViewContext; -int textview_draw(struct TextViewContext *tvc, int draw, int mval[2], void **mouse_pick, int *pos_pick); +int textview_draw(struct TextViewContext *tvc, const int draw, int mval[2], void **mouse_pick, int *pos_pick); #define TVC_LINE_FG (1<<0) #define TVC_LINE_BG (1<<1) diff --git a/source/blender/editors/space_logic/SConscript b/source/blender/editors/space_logic/SConscript index e63d88ea5de..e5a19b7f30b 100644 --- a/source/blender/editors/space_logic/SConscript +++ b/source/blender/editors/space_logic/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c index 5a8a7cef119..00745062582 100644 --- a/source/blender/editors/space_logic/logic_window.c +++ b/source/blender/editors/space_logic/logic_window.c @@ -2270,11 +2270,11 @@ void logic_buttons(bContext *C, ARegion *ar) /* ****************** Controllers ****************** */ - xco= 420; yco= -10; width= 300; + xco= 21 * U.widget_unit; yco= - U.widget_unit / 2; width= 15 * U.widget_unit; layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, UI_GetStyle()); row = uiLayoutRow(layout, TRUE); - uiDefBlockBut(block, controller_menu, NULL, IFACE_("Controllers"), xco-10, yco, 300, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */ + uiDefBlockBut(block, controller_menu, NULL, IFACE_("Controllers"), xco - U.widget_unit / 2, yco, width, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */ uiItemR(row, &logic_ptr, "show_controllers_selected_objects", 0, IFACE_("Sel"), ICON_NONE); uiItemR(row, &logic_ptr, "show_controllers_active_object", 0, IFACE_("Act"), ICON_NONE); @@ -2301,7 +2301,7 @@ void logic_buttons(bContext *C, ARegion *ar) uiItemR(split, &settings_ptr, "show_state_panel", UI_ITEM_R_NO_BG, "", ICON_DISCLOSURE_TRI_RIGHT); row = uiLayoutRow(split, TRUE); - uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name+2, (short)(xco-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide controllers")); + uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name+2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide controllers")); RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr); uiLayoutSetContextPointer(row, "object", &object_ptr); @@ -2377,11 +2377,11 @@ void logic_buttons(bContext *C, ARegion *ar) /* ****************** Sensors ****************** */ - xco= 10; yco= -10; width= 340; + xco= U.widget_unit / 2; yco= -U.widget_unit / 2; width= 17 * U.widget_unit; layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, UI_GetStyle()); row = uiLayoutRow(layout, TRUE); - uiDefBlockBut(block, sensor_menu, NULL, IFACE_("Sensors"), xco-10, yco, 300, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */ + uiDefBlockBut(block, sensor_menu, NULL, IFACE_("Sensors"), xco - U.widget_unit / 2, yco, 15 * U.widget_unit, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */ uiItemR(row, &logic_ptr, "show_sensors_selected_objects", 0, IFACE_("Sel"), ICON_NONE); uiItemR(row, &logic_ptr, "show_sensors_active_object", 0, IFACE_("Act"), ICON_NONE); @@ -2398,7 +2398,7 @@ void logic_buttons(bContext *C, ARegion *ar) if ((ob->scavisflag & OB_VIS_SENS) == 0) continue; row = uiLayoutRow(layout, TRUE); - uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2, (short)(xco-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide sensors")); + uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide sensors")); RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr); uiLayoutSetContextPointer(row, "object", &object_ptr); @@ -2446,11 +2446,11 @@ void logic_buttons(bContext *C, ARegion *ar) /* ****************** Actuators ****************** */ - xco= 800; yco= -10; width= 340; + xco= 40 * U.widget_unit; yco= -U.widget_unit / 2; width= 17 * U.widget_unit; layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, UI_GetStyle()); row = uiLayoutRow(layout, TRUE); - uiDefBlockBut(block, actuator_menu, NULL, IFACE_("Actuators"), xco-10, yco, 300, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */ + uiDefBlockBut(block, actuator_menu, NULL, IFACE_("Actuators"), xco - U.widget_unit / 2, yco, 15 * U.widget_unit, UI_UNIT_Y, ""); /* replace this with uiLayout stuff later */ uiItemR(row, &logic_ptr, "show_actuators_selected_objects", 0, IFACE_("Sel"), ICON_NONE); uiItemR(row, &logic_ptr, "show_actuators_active_object", 0, IFACE_("Act"), ICON_NONE); @@ -2469,7 +2469,7 @@ void logic_buttons(bContext *C, ARegion *ar) } row = uiLayoutRow(layout, TRUE); - uiDefButBitS(block, TOG, OB_SHOWACT, B_REDR, ob->id.name+2, (short)(xco-10), yco, (short)(width-30), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide actuators")); + uiDefButBitS(block, TOG, OB_SHOWACT, B_REDR, ob->id.name+2, (short)(xco - U.widget_unit / 2), yco, (short)(width - 1.5f * U.widget_unit), UI_UNIT_Y, &ob->scaflag, 0, 31, 0, 0, TIP_("Object name, click to show/hide actuators")); RNA_pointer_create((ID *)ob, &RNA_Object, ob, &object_ptr); uiLayoutSetContextPointer(row, "object", &object_ptr); @@ -2516,7 +2516,7 @@ void logic_buttons(bContext *C, ARegion *ar) uiBlockLayoutResolve(block, NULL, &yco); /* stores final height in yco */ height = MIN2(height, yco); - UI_view2d_totRect_set(&ar->v2d, 1150, height); + UI_view2d_totRect_set(&ar->v2d, 57.5f * U.widget_unit, height); /* set the view */ UI_view2d_view_ortho(&ar->v2d); diff --git a/source/blender/editors/space_nla/SConscript b/source/blender/editors/space_nla/SConscript index ee010e6856f..18c6392eee9 100644 --- a/source/blender/editors/space_nla/SConscript +++ b/source/blender/editors/space_nla/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index fd999bf2476..0c89e3ecbcf 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -632,7 +632,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View for (ale = anim_data->first; ale; ale = ale->next) { const float yminc = (float)(y - NLACHANNEL_HEIGHT_HALF(snla)); const float ymaxc = (float)(y + NLACHANNEL_HEIGHT_HALF(snla)); - const float ydatac = (float)(y - 7); + const float ydatac = (float)(y - 0.35f * U.widget_unit); /* check if visible */ if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) || @@ -716,7 +716,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View if (ale->id) { /* special exception for textures */ if (GS(ale->id->name) == ID_TE) { - offset = 14; + offset = 0.7f * U.widget_unit; indent = 1; } /* special exception for nodetrees */ @@ -727,7 +727,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View case NTREE_SHADER: { /* same as for textures */ - offset = 14; + offset = 0.7f * U.widget_unit; indent = 1; } break; @@ -735,19 +735,19 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View case NTREE_TEXTURE: { /* even more */ - offset = 21; + offset = U.widget_unit; indent = 1; } break; default: /* normal will do */ - offset = 14; + offset = 0.7f * U.widget_unit; break; } } else { - offset = 14; + offset = 0.7f * U.widget_unit; } } else { @@ -779,7 +779,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View glColor4f(color[0], color[1], color[2], alpha); } - offset += 7 * indent; + offset += 0.35f * U.widget_unit * indent; /* only on top two corners, to show that this channel sits on top of the preceding ones */ uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT); @@ -797,7 +797,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View UI_ThemeColorShade(TH_HEADER, ((nonSolo == 0) ? 20 : -20)); indent += group; - offset += 7 * indent; + offset += 0.35f * U.widget_unit * indent; glBegin(GL_QUADS); glVertex2f(x + offset, yminc); glVertex2f(x + offset, ymaxc); @@ -809,14 +809,14 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View /* draw expand/collapse triangle */ if (expand > 0) { UI_icon_draw(x + offset, ydatac, expand); - offset += 17; + offset += 0.85f * U.widget_unit; } /* draw special icon indicating certain data-types */ if (special > -1) { /* for normal channels */ UI_icon_draw(x + offset, ydatac, special); - offset += 17; + offset += 0.85f * U.widget_unit; } glDisable(GL_BLEND); @@ -837,19 +837,19 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View /* draw protect 'lock' */ if (protect > -1) { - offset = 16; + offset = 0.8f * U.widget_unit; UI_icon_draw((float)(v2d->cur.xmax - offset), ydatac, protect); } /* draw mute 'eye' */ if (mute > -1) { - offset += 16; + offset += 0.8f * U.widget_unit; UI_icon_draw((float)(v2d->cur.xmax - offset), ydatac, mute); } /* draw NLA-action line 'status-icons' - only when there's an action */ if ((ale->type == ANIMTYPE_NLAACTION) && (ale->data)) { - offset += 16; + offset += 0.8f * U.widget_unit; /* now draw some indicator icons */ if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) { @@ -862,7 +862,7 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View fdrawline((float)(v2d->cur.xmax - offset), yminc, (float)(v2d->cur.xmax - offset), ymaxc); - offset += 16; + offset += 0.8f * U.widget_unit; /* 'tweaking action' indicator - not a button */ UI_icon_draw((float)(v2d->cur.xmax - offset), ydatac, ICON_EDIT); @@ -870,10 +870,10 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View else { /* XXX firstly draw a little rect to help identify that it's different from the toggles */ glBegin(GL_LINE_LOOP); - glVertex2f((float)v2d->cur.xmax - offset - 1, y - 7); - glVertex2f((float)v2d->cur.xmax - offset - 1, y + 9); - glVertex2f((float)v2d->cur.xmax - 1, y + 9); - glVertex2f((float)v2d->cur.xmax - 1, y - 7); + glVertex2f((float)v2d->cur.xmax - offset - 1, y - 0.35f * U.widget_unit); + glVertex2f((float)v2d->cur.xmax - offset - 1, y + 0.45f * U.widget_unit); + glVertex2f((float)v2d->cur.xmax - 1, y + 0.45f * U.widget_unit); + glVertex2f((float)v2d->cur.xmax - 1, y - 0.35f * U.widget_unit); glEnd(); // GL_LINES /* 'push down' icon for normal active-actions */ diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt index 996c6fb530f..3803f899ccc 100644 --- a/source/blender/editors/space_node/CMakeLists.txt +++ b/source/blender/editors/space_node/CMakeLists.txt @@ -52,6 +52,7 @@ set(SRC node_relationships.c node_select.c node_templates.c + node_toolbar.c node_view.c space_node.c diff --git a/source/blender/editors/space_node/SConscript b/source/blender/editors/space_node/SConscript index 7e311b1329d..70837fa766a 100644 --- a/source/blender/editors/space_node/SConscript +++ b/source/blender/editors/space_node/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 92edac356e6..f123bcdb94f 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -123,10 +123,10 @@ static void node_socket_button_string(const bContext *C, uiBlock *block, float slen; UI_ThemeColor(TH_TEXT); - slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect_sqrt; + slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect; /* XXX, check for dpis */ while (slen > (width * 0.5f) && *ui_name) { ui_name = BLI_str_find_next_char_utf8(ui_name, NULL); - slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect_sqrt; + slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect; } RNA_pointer_create(&ntree->id, &RNA_NodeSocket, sock, &ptr); @@ -208,7 +208,7 @@ static void node_socket_button_color(const bContext *C, uiBlock *block, bt = uiDefButR(block, COLOR, B_NODE_EXEC, "", x, y + 2, (labelw > 0 ? 40 : width), NODE_DY - 2, - &ptr, "default_value", 0, 0, 0, -1, -1, NULL); + &ptr, "default_value", -1, 0, 0, -1, -1, NULL); if (node) uiButSetFunc(bt, node_sync_cb, CTX_wm_space_node(C), node); @@ -229,19 +229,18 @@ static void node_draw_input_default(const bContext *C, uiBlock *block, node_socket_button_label(C, block, ntree, node, sock, IFACE_(name), x, y, width); } -static void node_draw_output_default(const bContext *C, uiBlock *block, +static void node_draw_output_default(const bContext *UNUSED(C), uiBlock *block, bNodeTree *UNUSED(ntree), bNode *node, bNodeSocket *sock, const char *name, int UNUSED(x), int UNUSED(y), int UNUSED(width)) { - SpaceNode *snode = CTX_wm_space_node(C); const char *ui_name = IFACE_(name); float slen; UI_ThemeColor(TH_TEXT); - slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect_sqrt; - while (slen > node->width && *ui_name) { + slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) ; + while (slen > NODE_WIDTH(node) && *ui_name) { ui_name = BLI_str_find_next_char_utf8(ui_name, NULL); - slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X) * snode->aspect_sqrt; + slen = (UI_GetStringWidth(ui_name) + NODE_MARGIN_X); } if (*ui_name) { @@ -509,14 +508,14 @@ static void node_update_group(const bContext *C, bNodeTree *ntree, bNode *gnode) bNodeSocket *sock, *gsock; float locx, locy; rctf *rect = &gnode->totr; - const float dpi_fac = UI_DPI_ICON_FAC; + const float dpi_fac = UI_DPI_FAC; const float node_group_frame = NODE_GROUP_FRAME * dpi_fac; const float group_header = 26 * dpi_fac; int counter; int dy; /* get "global" coords */ - nodeToView(gnode, 0.0f, 0.0f, &locx, &locy); + node_to_view(gnode, 0.0f, 0.0f, &locx, &locy); /* center them, is a bit of abuse of locx and locy though */ node_update_nodetree(C, ngroup, locx, locy); @@ -688,7 +687,7 @@ static void draw_group_socket_name(SpaceNode *snode, bNode *gnode, bNodeSocket * static void draw_group_socket(const bContext *C, SpaceNode *snode, bNodeTree *ntree, bNode *gnode, bNodeSocket *sock, bNodeSocket *gsock, int index, int in_out) { - const float dpi_fac = UI_DPI_ICON_FAC; + const float dpi_fac = 1.0f; bNodeTree *ngroup = (bNodeTree *)gnode->id; bNodeSocketType *stype = ntreeGetSocketType(gsock ? gsock->type : sock->type); uiBut *bt; @@ -800,7 +799,7 @@ static void node_draw_group(const bContext *C, ARegion *ar, SpaceNode *snode, bN uiLayout *layout; PointerRNA ptr; rctf rect = gnode->totr; - const float dpi_fac = UI_DPI_ICON_FAC; + const float dpi_fac = 1.0f; const float node_group_frame = NODE_GROUP_FRAME * dpi_fac; const float group_header = 26 * dpi_fac; @@ -925,7 +924,7 @@ static void node_uifunc_group(uiLayout *layout, bContext *C, PointerRNA *ptr) */ static void node_update_frame(const bContext *UNUSED(C), bNodeTree *ntree, bNode *node) { - const float margin = 30.0f; + const float margin = 1.5f * U.widget_unit; NodeFrame *data = (NodeFrame *)node->storage; int bbinit; bNode *tnode; @@ -933,8 +932,8 @@ static void node_update_frame(const bContext *UNUSED(C), bNodeTree *ntree, bNode float xmax, ymax; /* init rect from current frame size */ - nodeToView(node, node->offsetx, node->offsety, &rect.xmin, &rect.ymax); - nodeToView(node, node->offsetx + node->width, node->offsety - node->height, &rect.xmax, &rect.ymin); + node_to_view(node, node->offsetx, node->offsety, &rect.xmin, &rect.ymax); + node_to_view(node, node->offsetx + node->width, node->offsety - node->height, &rect.xmax, &rect.ymin); /* frame can be resized manually only if shrinking is disabled or no children are attached */ data->flag |= NODE_FRAME_RESIZEABLE; @@ -963,8 +962,8 @@ static void node_update_frame(const bContext *UNUSED(C), bNodeTree *ntree, bNode } /* now adjust the frame size from view-space bounding box */ - nodeFromView(node, rect.xmin, rect.ymax, &node->offsetx, &node->offsety); - nodeFromView(node, rect.xmax, rect.ymin, &xmax, &ymax); + node_from_view(node, rect.xmin, rect.ymax, &node->offsetx, &node->offsety); + node_from_view(node, rect.xmax, rect.ymin, &xmax, &ymax); node->width = xmax - node->offsetx; node->height = -ymax + node->offsety; @@ -1101,7 +1100,7 @@ static void node_update_reroute(const bContext *UNUSED(C), bNodeTree *UNUSED(ntr float size = NODE_REROUTE_SIZE; /* get "global" coords */ - nodeToView(node, 0.0f, 0.0f, &locx, &locy); + node_to_view(node, 0.0f, 0.0f, &locx, &locy); /* reroute node has exactly one input and one output, both in the same place */ nsock = node->outputs.first; @@ -1351,7 +1350,7 @@ static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, Poin uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE); uiItemR(layout, ptr, "projection", 0, "", ICON_NONE); - node_buts_image_user(layout, C, ptr, &imaptr, &iuserptr); + node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr); } static void node_shader_buts_tex_sky(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) @@ -3532,7 +3531,7 @@ void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, glDisable(GL_LINE_SMOOTH); /* restore previuos linewidth */ - glLineWidth(linew); + glLineWidth(1.0f); } } @@ -3618,7 +3617,7 @@ void node_draw_link_straight(View2D *v2d, SpaceNode *snode, bNodeLink *link, glDisable(GL_LINE_SMOOTH); /* restore previuos linewidth */ - glLineWidth(linew); + glLineWidth(1.0f); } #endif diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c index 96ac716f383..18ce2c81716 100644 --- a/source/blender/editors/space_node/node_add.c +++ b/source/blender/editors/space_node/node_add.c @@ -76,10 +76,14 @@ bNode *node_add_node(SpaceNode *snode, Main *bmain, Scene *scene, if (node) { node_select(node); + /* node location is mapped */ + locx /= UI_DPI_FAC; + locy /= UI_DPI_FAC; + gnode = node_tree_get_editgroup(snode->nodetree); // arbitrary y offset of 60 so its visible if (gnode) { - nodeFromView(gnode, locx, locy + 60.0f, &node->locx, &node->locy); + node_from_view(gnode, locx, locy + 60.0f, &node->locx, &node->locy); } else { node->locx = locx; @@ -203,7 +207,7 @@ static bNodeSocketLink *add_reroute_do_socket_section(bContext *C, bNodeSocketLi } add_v2_v2(insert_point, socklink->point); - ++num_links; + num_links++; } socklink = socklink->next; } @@ -215,7 +219,7 @@ static bNodeSocketLink *add_reroute_do_socket_section(bContext *C, bNodeSocketLi mul_v2_fl(insert_point, 1.0f / num_links); if (gnode) { - nodeFromView(gnode, insert_point[0], insert_point[1], &reroute_node->locx, &reroute_node->locy); + node_from_view(gnode, insert_point[0], insert_point[1], &reroute_node->locx, &reroute_node->locy); } else { reroute_node->locx = insert_point[0]; diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c index da077d93641..300328f5fd4 100644 --- a/source/blender/editors/space_node/node_buttons.c +++ b/source/blender/editors/space_node/node_buttons.c @@ -184,6 +184,7 @@ void node_buttons_register(ARegionType *art) pt = MEM_callocN(sizeof(PanelType), "spacetype node panel gpencil"); strcpy(pt->idname, "NODE_PT_gpencil"); strcpy(pt->label, "Grease Pencil"); + pt->draw_header = gpencil_panel_standard_header; pt->draw = gpencil_panel_standard; pt->poll = active_nodetree_poll; BLI_addtail(&art->paneltypes, pt); diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 72461cfb2a8..e1d5e4200b8 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -278,6 +278,21 @@ static void node_uiblocks_init(const bContext *C, bNodeTree *ntree) } } +void node_to_view(struct bNode *node, float x, float y, float *rx, float *ry) +{ + nodeToView(node, x, y, rx, ry); + *rx *= UI_DPI_FAC; + *ry *= UI_DPI_FAC; +} + +void node_from_view(struct bNode *node, float x, float y, float *rx, float *ry) +{ + x /= UI_DPI_FAC; + y /= UI_DPI_FAC; + nodeFromView(node, x, y, rx, ry); +} + + /* based on settings in node, sets drawing rect info. each redraw! */ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) { @@ -289,7 +304,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) int buty; /* get "global" coords */ - nodeToView(node, 0.0f, 0.0f, &locx, &locy); + node_to_view(node, 0.0f, 0.0f, &locx, &locy); dy = locy; /* header */ @@ -302,14 +317,14 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) /* output sockets */ for (nsock = node->outputs.first; nsock; nsock = nsock->next) { if (!nodeSocketIsHidden(nsock)) { - nsock->locx = locx + node->width; + nsock->locx = locx + NODE_WIDTH(node); nsock->locy = dy - NODE_DYS; dy -= NODE_DY; } } node->prvr.xmin = locx + NODE_DYS; - node->prvr.xmax = locx + node->width - NODE_DYS; + node->prvr.xmax = locx + NODE_WIDTH(node) - NODE_DYS; /* preview rect? */ if (node->flag & NODE_PREVIEW) { @@ -323,12 +338,13 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) node->prvr.ymax = dy; if (aspect <= 1.0f) - node->prvr.ymin = dy - aspect * (node->width - NODE_DY); + node->prvr.ymin = dy - aspect * (NODE_WIDTH(node) - NODE_DY); else { /* width correction of image */ - float dx = (node->width - NODE_DYS) - (node->width - NODE_DYS) / aspect; + /* XXX huh? (ton) */ + float dx = (NODE_WIDTH(node) - NODE_DYS) - (NODE_WIDTH(node) - NODE_DYS) / aspect; - node->prvr.ymin = dy - (node->width - NODE_DY); + node->prvr.ymin = dy - (NODE_WIDTH(node) - NODE_DY); node->prvr.xmin += 0.5f * dx; node->prvr.xmax -= 0.5f * dx; @@ -343,7 +359,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) else { float oldh = BLI_rctf_size_y(&node->prvr); if (oldh == 0.0f) - oldh = 0.6f * node->width - NODE_DY; + oldh = 0.6f * NODE_WIDTH(node) - NODE_DY; dy -= NODE_DYS / 2; node->prvr.ymax = dy; node->prvr.ymin = dy - oldh; @@ -357,21 +373,22 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) /* set this for uifunc() that don't use layout engine yet */ node->butr.xmin = 0; - node->butr.xmax = node->width - 2 * NODE_DYS; + node->butr.xmax = NODE_WIDTH(node) - 2 * NODE_DYS; node->butr.ymin = 0; node->butr.ymax = 0; RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr); + layout = uiBlockLayout(node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, - locx + NODE_DYS, dy, node->butr.xmax, NODE_DY, UI_GetStyle()); + locx + NODE_DYS, dy, node->butr.xmax, 0, UI_GetStyle()); uiLayoutSetContextPointer(layout, "node", &ptr); node->typeinfo->uifunc(layout, (bContext *)C, &ptr); uiBlockEndAlign(node->block); uiBlockLayoutResolve(node->block, NULL, &buty); - + dy = buty - NODE_DYS / 2; } @@ -389,7 +406,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node) dy -= NODE_DYS / 2; node->totr.xmin = locx; - node->totr.xmax = locx + node->width; + node->totr.xmax = locx + NODE_WIDTH(node); node->totr.ymax = locy; node->totr.ymin = min_ff(dy, locy - 2 * NODE_DY); @@ -412,7 +429,7 @@ static void node_update_hidden(bNode *node) int totin = 0, totout = 0, tot; /* get "global" coords */ - nodeToView(node, 0.0f, 0.0f, &locx, &locy); + node_to_view(node, 0.0f, 0.0f, &locx, &locy); /* calculate minimal radius */ for (nsock = node->inputs.first; nsock; nsock = nsock->next) @@ -700,7 +717,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN uiRoundBox(rct->xmin, rct->ymax - NODE_DY, rct->xmax, rct->ymax, BASIS_RAD); /* show/hide icons */ - iconofs = rct->xmax - 7.0f; + iconofs = rct->xmax - 0.35f * U.widget_unit; /* preview */ if (node->typeinfo->flag & NODE_PREVIEW) { @@ -742,13 +759,13 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN /* XXX button uses a custom triangle draw below, so make it invisible without icon */ uiBlockSetEmboss(node->block, UI_EMBOSSN); but = uiDefBut(node->block, TOGBUT, B_REDR, "", - rct->xmin + 10.0f - but_size / 2, rct->ymax - NODE_DY / 2.0f - but_size / 2, + rct->xmin + 0.5f * U.widget_unit - but_size / 2, rct->ymax - NODE_DY / 2.0f - but_size / 2, but_size, but_size, NULL, 0, 0, 0, 0, ""); uiButSetFunc(but, node_toggle_button_cb, node, (void *)"NODE_OT_hide_toggle"); uiBlockSetEmboss(node->block, UI_EMBOSS); /* custom draw function for this button */ - UI_DrawTriIcon(rct->xmin + 10.0f, rct->ymax - NODE_DY / 2.0f, 'v'); + UI_DrawTriIcon(rct->xmin + 0.5f * U.widget_unit, rct->ymax - NODE_DY / 2.0f, 'v'); } /* this isn't doing anything for the label, so commenting out */ @@ -765,7 +782,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN // BLI_snprintf(showname, sizeof(showname), "[%s]", showname); /* XXX - don't print into self! */ uiDefBut(node->block, LABEL, 0, showname, - (int)(rct->xmin + (NODE_MARGIN_X / snode->aspect_sqrt)), (int)(rct->ymax - NODE_DY), + (int)(rct->xmin + (NODE_MARGIN_X)), (int)(rct->ymax - NODE_DY), (short)(iconofs - rct->xmin - 18.0f), (short)NODE_DY, NULL, 0, 0, 0, 0, ""); @@ -808,8 +825,8 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE, sock->flag & SELECT); node->typeinfo->drawinputfunc(C, node->block, ntree, node, sock, IFACE_(sock->name), - sock->locx + (NODE_DYS / snode->aspect_sqrt), sock->locy - NODE_DYS, - node->width - NODE_DY); + sock->locx + (NODE_DYS), sock->locy - NODE_DYS, + NODE_WIDTH(node) - NODE_DY); } /* socket outputs */ @@ -820,8 +837,8 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE, sock->flag & SELECT); node->typeinfo->drawoutputfunc(C, node->block, ntree, node, sock, IFACE_(sock->name), - sock->locx - node->width + (NODE_DYS / snode->aspect_sqrt), sock->locy - NODE_DYS, - node->width - NODE_DY); + sock->locx - NODE_WIDTH(node) + (NODE_DYS), sock->locy - NODE_DYS, + NODE_WIDTH(node) - NODE_DY); } /* preview */ @@ -843,7 +860,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b rctf *rct = &node->totr; float dx, centy = BLI_rctf_cent_y(rct); float hiddenrad = BLI_rctf_size_y(rct) / 2.0f; - float socket_size = NODE_SOCKSIZE * UI_DPI_ICON_FAC; + float socket_size = NODE_SOCKSIZE; int color_id = node_get_colorid(node); char showname[128]; /* 128 is used below */ @@ -920,7 +937,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b // BLI_snprintf(showname, sizeof(showname), "[%s]", showname); /* XXX - don't print into self! */ uiDefBut(node->block, LABEL, 0, showname, - (int)(rct->xmin + (NODE_MARGIN_X / snode->aspect_sqrt)), (int)(centy - 10), + (int)(rct->xmin + (NODE_MARGIN_X)), (int)(centy - 10), (short)(BLI_rctf_size_x(rct) - 18.0f - 12.0f), (short)NODE_DY, NULL, 0, 0, 0, 0, ""); } @@ -1011,7 +1028,7 @@ void node_update_nodetree(const bContext *C, bNodeTree *ntree, float offsetx, fl /* update nodes front to back, so children sizes get updated before parents */ for (node = ntree->nodes.last; node; node = node->prev) { - /* XXX little hack */ + /* XXX little hack (not used anyore?) */ node->locx += offsetx; node->locy += offsety; @@ -1082,7 +1099,7 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d) SpaceNode *snode = CTX_wm_space_node(C); bNodeLinkDrag *nldrag; LinkData *linkdata; - + UI_ThemeClearColor(TH_BACK); glClear(GL_COLOR_BUFFER_BIT); @@ -1098,11 +1115,10 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d) /* aspect+font, set each time */ snode->aspect = BLI_rctf_size_x(&v2d->cur) / (float)ar->winx; - snode->aspect_sqrt = sqrtf(snode->aspect); // XXX snode->curfont = uiSetCurFont_ext(snode->aspect); /* grid */ - UI_view2d_multi_grid_draw(v2d, 25.0f, 5, 2); + UI_view2d_multi_grid_draw(v2d, U.widget_unit, 5, 2); /* backdrop */ draw_nodespace_back_pix(C, ar, snode); @@ -1156,16 +1172,22 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d) ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); - /* draw grease-pencil ('canvas' strokes) */ - if (snode->nodetree) - draw_gpencil_view2d(C, 1); + if (snode->flag & SNODE_SHOW_GPENCIL) { + /* draw grease-pencil ('canvas' strokes) */ + if (snode->nodetree) { + draw_gpencil_view2d(C, TRUE); + } + } /* reset view matrix */ UI_view2d_view_restore(C); - /* draw grease-pencil (screen strokes, and also paintbuffer) */ - if (snode->nodetree) - draw_gpencil_view2d(C, 0); + if (snode->flag & SNODE_SHOW_GPENCIL) { + /* draw grease-pencil (screen strokes, and also paintbuffer) */ + if (snode->nodetree) { + draw_gpencil_view2d(C, FALSE); + } + } /* scrollers */ scrollers = UI_view2d_scrollers_calc(C, v2d, 10, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY); diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index f757345bdcb..ae95d9ae074 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -874,8 +874,8 @@ static int node_resize_modal(bContext *C, wmOperator *op, wmEvent *event) case MOUSEMOVE: UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &mx, &my); - dx = mx - nsw->mxstart; - dy = my - nsw->mystart; + dx = (mx - nsw->mxstart) / UI_DPI_FAC; + dy = (my - nsw->mystart) / UI_DPI_FAC; if (node) { if (node->flag & NODE_HIDDEN) { @@ -894,8 +894,8 @@ static int node_resize_modal(bContext *C, wmOperator *op, wmEvent *event) } } else { - float widthmin = UI_DPI_FAC * node->typeinfo->minwidth; - float widthmax = UI_DPI_FAC * node->typeinfo->maxwidth; + float widthmin = node->typeinfo->minwidth; + float widthmax = node->typeinfo->maxwidth; if (nsw->directions & NODE_RESIZE_RIGHT) { node->width = nsw->oldwidth + dx; CLAMP(node->width, widthmin, widthmax); @@ -1967,7 +1967,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op)) /* get group node offset */ if (gnode) - nodeToView(gnode, 0.0f, 0.0f, &gnode_x, &gnode_y); + node_to_view(gnode, 0.0f, 0.0f, &gnode_x, &gnode_y); for (node = ntree->nodes.first; node; node = node->next) { if (node->flag & SELECT) { @@ -2080,7 +2080,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op) /* get group node offset */ if (gnode) { - nodeToView(gnode, 0.0f, 0.0f, &gnode_center[0], &gnode_center[1]); + node_to_view(gnode, 0.0f, 0.0f, &gnode_center[0], &gnode_center[1]); } else { zero_v2(gnode_center); diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 45509e02226..e8dd1cf1528 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -48,6 +48,7 @@ struct bNode; struct bNodeSocket; struct bNodeLink; struct Main; +struct wmKeyConfig; /* temp data to pass on to modal */ typedef struct bNodeLinkDrag { @@ -63,6 +64,7 @@ typedef struct bNodeLinkDrag { /* space_node.c */ ARegion *node_has_buttons_region(ScrArea *sa); +ARegion *node_has_tools_region(ScrArea *sa); /* node_header.c */ void node_menus_register(void); @@ -81,14 +83,21 @@ void node_draw_nodetree(const struct bContext *C, struct ARegion *ar, struct Spa void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d); void node_set_cursor(struct wmWindow *win, struct SpaceNode *snode); + /* DPI scaled coords */ +void node_to_view(struct bNode *node, float x, float y, float *rx, float *ry); +void node_from_view(struct bNode *node, float x, float y, float *rx, float *ry); /* node_buttons.c */ void node_buttons_register(struct ARegionType *art); void NODE_OT_properties(struct wmOperatorType *ot); +/* node_toolbar.c */ +void node_toolbar_register(struct ARegionType *art); +void NODE_OT_toolbar(struct wmOperatorType *ot); + /* node_ops.c */ void node_operatortypes(void); -void node_keymap(wmKeyConfig *keyconf); +void node_keymap(struct wmKeyConfig *keyconf); /* node_select.c */ void node_select(struct bNode *node); @@ -103,14 +112,14 @@ int node_select_same_type_np(struct SpaceNode *snode, int dir); void node_select_single(struct bContext *C, struct bNode *node); void NODE_OT_select(struct wmOperatorType *ot); -void NODE_OT_select_all(wmOperatorType *ot); -void NODE_OT_select_linked_to(wmOperatorType *ot); -void NODE_OT_select_linked_from(wmOperatorType *ot); +void NODE_OT_select_all(struct wmOperatorType *ot); +void NODE_OT_select_linked_to(struct wmOperatorType *ot); +void NODE_OT_select_linked_from(struct wmOperatorType *ot); void NODE_OT_select_border(struct wmOperatorType *ot); void NODE_OT_select_lasso(struct wmOperatorType *ot); void NODE_OT_select_same_type(struct wmOperatorType *ot); -void NODE_OT_select_same_type_next(wmOperatorType *ot); -void NODE_OT_select_same_type_prev(wmOperatorType *ot); +void NODE_OT_select_same_type_next(struct wmOperatorType *ot); +void NODE_OT_select_same_type_prev(struct wmOperatorType *ot); /* node_view.c */ void NODE_OT_view_all(struct wmOperatorType *ot); @@ -118,14 +127,14 @@ void NODE_OT_view_selected(struct wmOperatorType *ot); void NODE_OT_backimage_move(struct wmOperatorType *ot); void NODE_OT_backimage_zoom(struct wmOperatorType *ot); -void NODE_OT_backimage_sample(wmOperatorType *ot); +void NODE_OT_backimage_sample(struct wmOperatorType *ot); /* drawnode.c */ -void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link); -void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3); -int node_link_bezier_points(View2D * v2d, SpaceNode * snode, bNodeLink * link, float coord_array[][2], int resol); +void node_draw_link(struct View2D *v2d, struct SpaceNode *snode, struct bNodeLink *link); +void node_draw_link_bezier(struct View2D *v2d, struct SpaceNode *snode, struct bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3); +int node_link_bezier_points(struct View2D * v2d, struct SpaceNode * snode, struct bNodeLink * link, float coord_array[][2], int resol); // void node_draw_link_straight(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3 ); -void draw_nodespace_back_pix(const struct bContext *C, ARegion *ar, SpaceNode *snode); +void draw_nodespace_back_pix(const struct bContext *C, struct ARegion *ar, struct SpaceNode *snode); /* node_add.c */ @@ -167,10 +176,10 @@ void NODE_OT_link_viewer(struct wmOperatorType *ot); /* node_edit.c */ void node_tree_from_ID(ID *id, bNodeTree **ntree, bNodeTree **edittree, int *treetype); -void snode_notify(bContext *C, SpaceNode *snode); -void snode_dag_update(bContext *C, SpaceNode *snode); -void snode_set_context(SpaceNode *snode, Scene *scene); -void snode_make_group_editable(SpaceNode *snode, bNode *gnode); +void snode_notify(struct bContext *C, struct SpaceNode *snode); +void snode_dag_update(struct bContext *C, struct SpaceNode *snode); +void snode_set_context(struct SpaceNode *snode, Scene *scene); +void snode_make_group_editable(struct SpaceNode *snode, struct bNode *gnode); bNode *node_tree_get_editgroup(bNodeTree *ntree); void snode_update(struct SpaceNode *snode, struct bNode *node); @@ -179,7 +188,7 @@ int composite_node_active(struct bContext *C); int node_has_hidden_sockets(bNode *node); void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set); -int node_render_changed_exec(bContext *, wmOperator *); +int node_render_changed_exec(bContext *, struct wmOperator *); int node_find_indicated_socket(struct SpaceNode *snode, struct bNode **nodep, struct bNodeSocket **sockp, int in_out); void NODE_OT_duplicate(struct wmOperatorType *ot); @@ -212,13 +221,14 @@ extern const char *node_context_dir[]; // XXXXXX -// XXX from BSE_node.h -#define HIDDEN_RAD 15.0f -#define BASIS_RAD 8.0f +// nodes draw without dpi - the view zoom is flexible +#define HIDDEN_RAD (0.75f * U.widget_unit) +#define BASIS_RAD (0.4f * U.widget_unit) #define NODE_DYS (U.widget_unit / 2) #define NODE_DY U.widget_unit -#define NODE_MARGIN_X 15 -#define NODE_SOCKSIZE 5 +#define NODE_WIDTH(node) (node->width * UI_DPI_FAC) +#define NODE_MARGIN_X (0.75f * U.widget_unit) +#define NODE_SOCKSIZE (0.25f * U.widget_unit) #define NODE_LINK_RESOL 12 // XXX button events (butspace) diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index 64e5f67a348..8adccd9e6c4 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -49,6 +49,7 @@ void node_operatortypes(void) { WM_operatortype_append(NODE_OT_properties); + WM_operatortype_append(NODE_OT_toolbar); WM_operatortype_append(NODE_OT_select); WM_operatortype_append(NODE_OT_select_all); @@ -204,6 +205,7 @@ void node_keymap(struct wmKeyConfig *keyconf) keymap = WM_keymap_find(keyconf, "Node Generic", SPACE_NODE, 0); WM_keymap_add_item(keymap, "NODE_OT_properties", NKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "NODE_OT_toolbar", TKEY, KM_PRESS, 0, 0); /* Main Area only ----------------- */ keymap = WM_keymap_find(keyconf, "Node Editor", SPACE_NODE, 0); diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index 23f4e948794..ca85415cb5a 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -30,6 +30,7 @@ #include "DNA_node_types.h" #include "DNA_screen_types.h" +#include "DNA_space_types.h" #include "BLI_listbase.h" #include "BLI_string.h" @@ -52,6 +53,8 @@ #include "ED_util.h" +#include "node_intern.h" + /************************* Node Socket Manipulation **************************/ static void node_tag_recursive(bNode *node) diff --git a/source/blender/editors/space_node/node_toolbar.c b/source/blender/editors/space_node/node_toolbar.c new file mode 100644 index 00000000000..86da4009b17 --- /dev/null +++ b/source/blender/editors/space_node/node_toolbar.c @@ -0,0 +1,92 @@ +/* + * ***** 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) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Lukas Toenne + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_node/node_toolbar.c + * \ingroup nodes + */ + + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" + +#include "DNA_node_types.h" + +#include "BKE_context.h" +#include "BKE_node.h" +#include "BKE_screen.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "RNA_access.h" + +#include "ED_screen.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "node_intern.h" /* own include */ + + +/* ******************* node toolbar registration ************** */ + +void node_toolbar_register(ARegionType *UNUSED(art)) +{ +} + +/* ********** operator to open/close toolshelf region */ + +static int node_toolbar(bContext *C, wmOperator *UNUSED(op)) +{ + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = node_has_tools_region(sa); + + if (ar) + ED_region_toggle_hidden(C, ar); + + return OPERATOR_FINISHED; +} + +/* non-standard poll operator which doesn't care if there are any nodes */ +static int node_toolbar_poll(bContext *C) +{ + ScrArea *sa = CTX_wm_area(C); + return (sa && (sa->spacetype == SPACE_NODE)); +} + +void NODE_OT_toolbar(wmOperatorType *ot) +{ + ot->name = "Tool Shelf"; + ot->description = "Toggles tool shelf display"; + ot->idname = "NODE_OT_toolbar"; + + ot->exec = node_toolbar; + ot->poll = node_toolbar_poll; + + /* flags */ + ot->flag = 0; +} diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index f7e0d51ea03..513f6b43e9a 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -85,6 +85,30 @@ ARegion *node_has_buttons_region(ScrArea *sa) return arnew; } +ARegion *node_has_tools_region(ScrArea *sa) +{ + ARegion *ar, *arnew; + + ar = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS); + if (ar) return ar; + + /* add subdiv level; after header */ + ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER); + + /* is error! */ + if (ar == NULL) return NULL; + + arnew = MEM_callocN(sizeof(ARegion), "node tools"); + + BLI_insertlinkafter(&sa->regionbase, ar, arnew); + arnew->regiontype = RGN_TYPE_TOOLS; + arnew->alignment = RGN_ALIGN_LEFT; + + arnew->flag = RGN_FLAG_HIDDEN; + + return arnew; +} + /* ******************** default callbacks for node space ***************** */ static SpaceLink *node_new(const bContext *UNUSED(C)) @@ -95,6 +119,8 @@ static SpaceLink *node_new(const bContext *UNUSED(C)) snode = MEM_callocN(sizeof(SpaceNode), "initnode"); snode->spacetype = SPACE_NODE; + snode->flag = SNODE_SHOW_GPENCIL; + /* backdrop */ snode->zoom = 1.0f; @@ -118,15 +144,12 @@ static SpaceLink *node_new(const bContext *UNUSED(C)) BLI_addtail(&snode->regionbase, ar); ar->regiontype = RGN_TYPE_WINDOW; - ar->v2d.tot.xmin = -256.0f; - ar->v2d.tot.ymin = -256.0f; - ar->v2d.tot.xmax = 768.0f; - ar->v2d.tot.ymax = 768.0f; + ar->v2d.tot.xmin = -12.8f * U.widget_unit; + ar->v2d.tot.ymin = -12.8f * U.widget_unit; + ar->v2d.tot.xmax = 38.4f * U.widget_unit; + ar->v2d.tot.ymax = 38.4f * U.widget_unit; - ar->v2d.cur.xmin = -256.0f; - ar->v2d.cur.ymin = -256.0f; - ar->v2d.cur.xmax = 768.0f; - ar->v2d.cur.ymax = 768.0f; + ar->v2d.cur = ar->v2d.tot; ar->v2d.min[0] = 1.0f; ar->v2d.min[1] = 1.0f; @@ -342,6 +365,22 @@ static void node_buttons_area_draw(const bContext *C, ARegion *ar) ED_region_panels(C, ar, 1, NULL, -1); } +/* add handlers, stuff you only do once or on area/region changes */ +static void node_toolbar_area_init(wmWindowManager *wm, ARegion *ar) +{ + wmKeyMap *keymap; + + ED_region_panels_init(wm, ar); + + keymap = WM_keymap_find(wm->defaultconf, "Node Generic", SPACE_NODE, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); +} + +static void node_toolbar_area_draw(const bContext *C, ARegion *ar) +{ + ED_region_panels(C, ar, 1, NULL, -1); +} + static void node_cursor(wmWindow *win, ScrArea *sa, ARegion *ar) { SpaceNode *snode = sa->spacedata.first; @@ -570,6 +609,19 @@ void ED_spacetype_node(void) node_buttons_register(art); + /* regions: toolbar */ + art = MEM_callocN(sizeof(ARegionType), "spacetype view3d tools region"); + art->regionid = RGN_TYPE_TOOLS; + art->prefsizex = 160; /* XXX */ + art->prefsizey = 50; /* XXX */ + art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES; + art->listener = node_region_listener; + art->init = node_toolbar_area_init; + art->draw = node_toolbar_area_draw; + BLI_addhead(&st->regiontypes, art); + + node_toolbar_register(art); + BKE_spacetype_register(st); } diff --git a/source/blender/editors/space_outliner/SConscript b/source/blender/editors/space_outliner/SConscript index a6f2e3c2a5d..1bb71941a43 100644 --- a/source/blender/editors/space_outliner/SConscript +++ b/source/blender/editors/space_outliner/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index d37cb4be8fa..33217e042e5 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -893,7 +893,7 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa struct DrawIconArg { uiBlock *block; ID *id; - int xmax, x, y; + float xmax, x, y, xb, yb; float alpha; }; @@ -902,13 +902,11 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon) /* restrict column clip... it has been coded by simply overdrawing, doesnt work for buttons */ if (arg->x >= arg->xmax) { glEnable(GL_BLEND); - UI_icon_draw_aspect(arg->x, arg->y, icon, 1.0f, arg->alpha); + UI_icon_draw_aspect(arg->x, arg->y, icon, 1.0f / UI_DPI_FAC, arg->alpha); glDisable(GL_BLEND); } else { - /* XXX investigate: button placement of icons is way different than UI_icon_draw? */ - float ufac = UI_UNIT_X / 20.0f; - uiBut *but = uiDefIconBut(arg->block, LABEL, 0, icon, arg->x - 3.0f * ufac, arg->y, UI_UNIT_X - 4.0f * ufac, UI_UNIT_Y - 4.0f * ufac, NULL, 0.0, 0.0, 1.0, arg->alpha, (arg->id && arg->id->lib) ? arg->id->lib->name : ""); + uiBut *but = uiDefIconBut(arg->block, LABEL, 0, icon, arg->xb, arg->yb, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, arg->alpha, (arg->id && arg->id->lib) ? arg->id->lib->name : ""); if (arg->id) uiButSetDragID(but, arg->id); @@ -919,15 +917,24 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon) static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeStoreElem *tselem, TreeElement *te, float alpha) { struct DrawIconArg arg; + float aspect; + + /* icons tiny bit away from text */ + x -= 0.15f * UI_UNIT_Y; /* make function calls a bit compacter */ arg.block = block; arg.id = tselem->id; arg.xmax = xmax; - arg.x = x; - arg.y = y; + arg.xb = x; /* for ui buttons */ + arg.yb = y; arg.alpha = alpha; + /* placement of icons, copied from interface_widgets.c */ + aspect = (0.8f * UI_UNIT_Y) / ICON_DEFAULT_HEIGHT; + arg.x = x = x + 4.0f * aspect; + arg.y = y = y + 0.1f * UI_UNIT_Y; + if (tselem->type) { switch (tselem->type) { case TSE_ANIM_DATA: @@ -989,6 +996,7 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto case eModifierType_Array: UI_icon_draw(x, y, ICON_MOD_ARRAY); break; case eModifierType_UVProject: + case eModifierType_UVWarp: /* TODO, get own icon */ UI_icon_draw(x, y, ICON_MOD_UVPROJECT); break; case eModifierType_Displace: UI_icon_draw(x, y, ICON_MOD_DISPLACE); break; @@ -1219,11 +1227,11 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa float ufac = UI_UNIT_X / 20.0f; uiSetRoundBox(UI_CNR_ALL); - glColor4ub(255, 255, 255, 100); - uiRoundBox((float) *offsx - 0.5f * ufac, - (float)ys - 1.0f * ufac, - (float)*offsx + UI_UNIT_Y - 3.0f * ufac, - (float)ys + UI_UNIT_Y - 3.0f * ufac, + glColor4ub(255, 255, 255, 128); + uiRoundBox((float) *offsx - 1.0f * ufac, + (float)ys + 1.0f * ufac, + (float)*offsx + UI_UNIT_X - 1.0f * ufac, + (float)ys + UI_UNIT_Y - 1.0f * ufac, (float)UI_UNIT_Y / 2.0f - 2.0f * ufac); glEnable(GL_BLEND); /* roundbox disables */ } @@ -1270,6 +1278,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene if (*starty + 2 * UI_UNIT_Y >= ar->v2d.cur.ymin && *starty <= ar->v2d.cur.ymax) { int xmax = ar->v2d.cur.xmax; + unsigned char alpha = 128; /* icons can be ui buts, we don't want it to overlap with restrict */ if ((soops->flag & SO_HIDE_RESTRICTCOLS) == 0) @@ -1286,16 +1295,17 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene { char col[4]; UI_GetThemeColorType4ubv(TH_MATCH, SPACE_OUTLINER, col); - col[3] = 100; + col[3] = alpha; glColor4ubv((GLubyte *)col); glRecti(startx, *starty + 1, ar->v2d.cur.xmax, *starty + UI_UNIT_Y - 1); } /* colors for active/selected data */ if (tselem->type == 0) { + if (te->idcode == ID_SCE) { if (tselem->id == (ID *)scene) { - glColor4ub(255, 255, 255, 100); + glColor4ub(255, 255, 255, alpha); active = 2; } } @@ -1304,7 +1314,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene if (group_select_flag(gr)) { char col[4]; UI_GetThemeColorType4ubv(TH_SELECT, SPACE_VIEW3D, col); - col[3] = 100; + col[3] = alpha; glColor4ubv((GLubyte *)col); active = 2; @@ -1322,14 +1332,14 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene if (ob == OBACT) { if (ob->flag & SELECT) { UI_GetThemeColorType4ubv(TH_ACTIVE, SPACE_VIEW3D, col); - col[3] = 100; + col[3] = alpha; } active = 1; /* means it draws white text */ } else if (ob->flag & SELECT) { UI_GetThemeColorType4ubv(TH_SELECT, SPACE_VIEW3D, col); - col[3] = 100; + col[3] = alpha; } glColor4ubv((GLubyte *)col); @@ -1337,27 +1347,27 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene } else if (scene->obedit && scene->obedit->data == tselem->id) { - glColor4ub(255, 255, 255, 100); + glColor4ub(255, 255, 255, alpha); active = 2; } else { if (tree_element_active(C, scene, soops, te, 0)) { - glColor4ub(220, 220, 255, 100); + glColor4ub(220, 220, 255, alpha); active = 2; } } } else { if (tree_element_type_active(NULL, scene, soops, te, tselem, 0) ) active = 2; - glColor4ub(220, 220, 255, 100); + glColor4ub(220, 220, 255, alpha); } /* active circle */ if (active) { uiSetRoundBox(UI_CNR_ALL); - uiRoundBox((float)startx + UI_UNIT_Y - 1.5f * ufac, - (float)*starty + 2.0f * ufac, - (float)startx + 2.0f * UI_UNIT_Y - 4.0f * ufac, + uiRoundBox((float)startx + UI_UNIT_X - 1.0f * ufac, + (float)*starty + 1.0f * ufac, + (float)startx + 2.0f * UI_UNIT_X - 1.0f * ufac, (float)*starty + UI_UNIT_Y - 1.0f * ufac, UI_UNIT_Y / 2.0f - 2.0f * ufac); glEnable(GL_BLEND); /* roundbox disables it */ @@ -1384,8 +1394,8 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene /* datatype icon */ if (!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM))) { - // icons a bit higher - tselem_draw_icon(block, xmax, (float)startx + offsx - 0.5f * ufac, (float)*starty + 2.0f * ufac, tselem, te, 1.0f); + + tselem_draw_icon(block, xmax, (float)startx + offsx, (float)*starty, tselem, te, 1.0f); offsx += UI_UNIT_X; } @@ -1425,12 +1435,15 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene /* divider */ UI_ThemeColorShade(TH_BACK, -40); - glRecti(tempx - 10, *starty + 4, tempx - 8, *starty + UI_UNIT_Y - 4); + glRecti(tempx - 10.0f * ufac, + *starty + 4.0f * ufac, + tempx - 8.0f * ufac, + *starty + UI_UNIT_Y - 4.0f * ufac); glEnable(GL_BLEND); glPixelTransferf(GL_ALPHA_SCALE, 0.5); - outliner_draw_iconrow(C, block, scene, soops, &te->subtree, 0, xmax, &tempx, *starty + 2); + outliner_draw_iconrow(C, block, scene, soops, &te->subtree, 0, xmax, &tempx, *starty); glPixelTransferf(GL_ALPHA_SCALE, 1.0); glDisable(GL_BLEND); @@ -1625,7 +1638,7 @@ static void outliner_draw_restrictcols(ARegion *ar) /* ****************************************************** */ /* Main Entrypoint - Draw contents of Outliner editor */ - + void draw_outliner(const bContext *C) { Main *mainvar = CTX_data_main(C); @@ -1635,8 +1648,8 @@ void draw_outliner(const bContext *C) SpaceOops *soops = CTX_wm_space_outliner(C); uiBlock *block; int sizey = 0, sizex = 0, sizex_rna = 0; - - outliner_build_tree(mainvar, scene, soops); // always + + outliner_build_tree(mainvar, scene, soops); // always /* get extents of data */ outliner_height(soops, &soops->tree, &sizey); @@ -1709,7 +1722,7 @@ void draw_outliner(const bContext *C) uiEndBlock(C, block); uiDrawBlock(C, block); - + /* clear flag that allows quick redraws */ soops->storeflag &= ~SO_TREESTORE_REDRAW; } diff --git a/source/blender/editors/space_script/SConscript b/source/blender/editors/space_script/SConscript index c30e204f6f4..eff603a3e2d 100644 --- a/source/blender/editors/space_script/SConscript +++ b/source/blender/editors/space_script/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_sequencer/SConscript b/source/blender/editors/space_sequencer/SConscript index bc72786fc5f..060c7892bd1 100644 --- a/source/blender/editors/space_sequencer/SConscript +++ b/source/blender/editors/space_sequencer/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c index 7dbcabedccc..21128408a97 100644 --- a/source/blender/editors/space_sequencer/sequencer_buttons.c +++ b/source/blender/editors/space_sequencer/sequencer_buttons.c @@ -41,6 +41,7 @@ #include "ED_screen.h" #include "ED_gpencil.h" +#include "ED_sequencer.h" #include "WM_api.h" #include "WM_types.h" @@ -51,6 +52,14 @@ /* **************************** buttons ********************************* */ +static int sequencer_grease_pencil_panel_poll(const bContext *C, PanelType *UNUSED(pt)) +{ + SpaceSeq *sseq = CTX_wm_space_seq(C); + + /* don't show the gpencil if we are not showing the image */ + return ED_space_sequencer_check_show_imbuf(sseq); +} + void sequencer_buttons_register(ARegionType *art) { PanelType *pt; @@ -58,7 +67,9 @@ void sequencer_buttons_register(ARegionType *art) pt = MEM_callocN(sizeof(PanelType), "spacetype sequencer panel gpencil"); strcpy(pt->idname, "SEQUENCER_PT_gpencil"); strcpy(pt->label, N_("Grease Pencil")); + pt->draw_header = gpencil_panel_standard_header; pt->draw = gpencil_panel_standard; + pt->poll = sequencer_grease_pencil_panel_poll; BLI_addtail(&art->paneltypes, pt); } diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 1a84efa0b50..e3db9c23c41 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -62,6 +62,7 @@ #include "ED_gpencil.h" #include "ED_markers.h" #include "ED_mask.h" +#include "ED_sequencer.h" #include "ED_types.h" #include "ED_space_api.h" @@ -921,6 +922,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq GLuint last_texid; unsigned char *display_buffer; void *cache_handle = NULL; + const int is_imbuf = ED_space_sequencer_check_show_imbuf(sseq); if (G.is_rendering == FALSE) { /* stop all running jobs, except screen one. currently previews frustrate Render @@ -1125,8 +1127,12 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq setlinestyle(0); } - /* draw grease-pencil (image aligned) */ - draw_gpencil_2dimage(C); + if (sseq->flag & SEQ_SHOW_GPENCIL) { + if (is_imbuf) { + /* draw grease-pencil (image aligned) */ + draw_gpencil_2dimage(C); + } + } if (!scope) IMB_freeImBuf(ibuf); @@ -1134,9 +1140,12 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq /* ortho at pixel level */ UI_view2d_view_restore(C); - /* draw grease-pencil (screen aligned) */ - draw_gpencil_view2d(C, 0); - + if (sseq->flag & SEQ_SHOW_GPENCIL) { + if (is_imbuf) { + /* draw grease-pencil (screen aligned) */ + draw_gpencil_view2d(C, 0); + } + } /* NOTE: sequencer mask editing isnt finished, the draw code is working but editing not, diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index e7f77db3b9e..409f655bb79 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -496,6 +496,13 @@ int ED_space_sequencer_maskedit_poll(bContext *C) return FALSE; } +/* are we displaying the seq output (not channels or histogram)*/ +int ED_space_sequencer_check_show_imbuf(SpaceSeq *sseq) +{ + return (ELEM(sseq->view, SEQ_VIEW_PREVIEW, SEQ_VIEW_SEQUENCE_PREVIEW) && + ELEM(sseq->mainb, SEQ_DRAW_SEQUENCE, SEQ_DRAW_IMG_IMBUF)); +} + int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequence **selseq1, Sequence **selseq2, Sequence **selseq3, const char **error_str) { Editing *ed = BKE_sequencer_editing_get(scene, FALSE); diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index e8d47016608..d541e1d6c07 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -120,6 +120,8 @@ static SpaceLink *sequencer_new(const bContext *C) sseq->chanshown = 0; sseq->view = SEQ_VIEW_SEQUENCE; sseq->mainb = SEQ_DRAW_IMG_IMBUF; + sseq->flag = SEQ_SHOW_GPENCIL; + /* header */ ar = MEM_callocN(sizeof(ARegion), "header for sequencer"); diff --git a/source/blender/editors/space_text/SConscript b/source/blender/editors/space_text/SConscript index 373564520c8..4b6d9fbd693 100644 --- a/source/blender/editors/space_text/SConscript +++ b/source/blender/editors/space_text/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index 46ab2d9e688..24f40dbbe2a 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -65,7 +65,7 @@ static void text_font_begin(SpaceText *st) { - BLF_size(mono, st->lheight, 72); + BLF_size(mono, st->lheight_dpi, 72); } static void text_font_end(SpaceText *UNUSED(st)) @@ -734,7 +734,7 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w if (st->showsyntax && format) format_draw_color(format[a]); x += text_font_draw_character_utf8(st, x, y, str + ma); } - y -= st->lheight + TXT_LINE_SPACING; + y -= st->lheight_dpi + TXT_LINE_SPACING; x = basex; lines++; start = end; mstart = mend; @@ -852,7 +852,7 @@ static void text_update_drawcache(SpaceText *st, ARegion *ar) full_update |= drawcache->wordwrap != st->wordwrap; /* word-wrapping option was toggled */ full_update |= drawcache->showlinenrs != st->showlinenrs; /* word-wrapping option was toggled */ full_update |= drawcache->tabnumber != st->tabnumber; /* word-wrapping option was toggled */ - full_update |= drawcache->lheight != st->lheight; /* word-wrapping option was toggled */ + full_update |= drawcache->lheight != st->lheight_dpi; /* word-wrapping option was toggled */ full_update |= drawcache->cwidth != st->cwidth; /* word-wrapping option was toggled */ full_update |= strncmp(drawcache->text_id, txt->id.name, MAX_ID_NAME); /* text datablock was changed */ @@ -928,7 +928,7 @@ static void text_update_drawcache(SpaceText *st, ARegion *ar) /* store settings */ drawcache->winx = ar->winx; drawcache->wordwrap = st->wordwrap; - drawcache->lheight = st->lheight; + drawcache->lheight = st->lheight_dpi; drawcache->cwidth = st->cwidth; drawcache->showlinenrs = st->showlinenrs; drawcache->tabnumber = st->tabnumber; @@ -1237,9 +1237,9 @@ static void draw_documentation(SpaceText *st, ARegion *ar) x += SUGG_LIST_WIDTH * st->cwidth + 50; } - /* top = */ /* UNUSED */ y = ar->winy - st->lheight * l - 2; + /* top = */ /* UNUSED */ y = ar->winy - st->lheight_dpi * l - 2; boxw = DOC_WIDTH * st->cwidth + 20; - boxh = (DOC_HEIGHT + 1) * st->lheight; + boxh = (DOC_HEIGHT + 1) * st->lheight_dpi; /* Draw panel */ UI_ThemeColor(TH_BACK); @@ -1271,7 +1271,7 @@ static void draw_documentation(SpaceText *st, ARegion *ar) else if (*p == '\n') { buf[i] = '\0'; if (lines >= 0) { - y -= st->lheight; + y -= st->lheight_dpi; text_draw(st, buf, 0, 0, 1, x + 4, y - 3, NULL); } i = 0; br = DOC_WIDTH; lines++; @@ -1280,7 +1280,7 @@ static void draw_documentation(SpaceText *st, ARegion *ar) if (i == DOC_WIDTH) { /* Reached the width, go to last break and wrap there */ buf[br] = '\0'; if (lines >= 0) { - y -= st->lheight; + y -= st->lheight_dpi; text_draw(st, buf, 0, 0, 1, x + 4, y - 3, NULL); } p -= i - br - 1; /* Rewind pointer to last break */ @@ -1326,10 +1326,10 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar) else { x = st->cwidth * (st->text->curc - st->left) + TXT_OFFSET - 4; } - y = ar->winy - st->lheight * l - 2; + y = ar->winy - st->lheight_dpi * l - 2; boxw = SUGG_LIST_WIDTH * st->cwidth + 20; - boxh = SUGG_LIST_SIZE * st->lheight + 8; + boxh = SUGG_LIST_SIZE * st->lheight_dpi + 8; UI_ThemeColor(TH_SHADE1); glRecti(x - 1, y + 1, x + boxw + 1, y - boxh - 1); @@ -1341,7 +1341,7 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar) for (i = 0; i < SUGG_LIST_SIZE && item; i++, item = item->next) { - y -= st->lheight; + y -= st->lheight_dpi; BLI_strncpy(str, item->name, SUGG_LIST_WIDTH); @@ -1349,7 +1349,7 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar) if (item == sel) { UI_ThemeColor(TH_SHADE2); - glRecti(x + 16, y - 3, x + 16 + w, y + st->lheight - 3); + glRecti(x + 16, y - 3, x + 16 + w, y + st->lheight_dpi - 3); } b = 1; /* b=1 color block, text is default. b=0 no block, color text */ switch (item->type) { @@ -1376,7 +1376,7 @@ static void draw_cursor(SpaceText *st, ARegion *ar) Text *text = st->text; int vcurl, vcurc, vsell, vselc, hidden = 0; int x, y, w, i; - int lheight = st->lheight + TXT_LINE_SPACING; + int lheight = st->lheight_dpi + TXT_LINE_SPACING; /* Draw the selection */ if (text->curl != text->sell || text->curc != text->selc) { @@ -1399,9 +1399,9 @@ static void draw_cursor(SpaceText *st, ARegion *ar) if (vcurl == vsell) { y -= vcurl * lheight; if (vcurc < vselc) - glRecti(x + vcurc * st->cwidth - 1, y, x + vselc * st->cwidth, y - lheight + TXT_LINE_SPACING); + glRecti(x + vcurc * st->cwidth - 1, y, x + vselc * st->cwidth, y - lheight); else - glRecti(x + vselc * st->cwidth - 1, y, x + vcurc * st->cwidth, y - lheight + TXT_LINE_SPACING); + glRecti(x + vselc * st->cwidth - 1, y, x + vcurc * st->cwidth, y - lheight); } else { int froml, fromc, tol, toc; @@ -1420,7 +1420,7 @@ static void draw_cursor(SpaceText *st, ARegion *ar) for (i = froml + 1; i < tol; i++) glRecti(x - 4, y, ar->winx, y - lheight), y -= lheight; - glRecti(x - 4, y, x + toc * st->cwidth, y - lheight + TXT_LINE_SPACING); y -= lheight; + glRecti(x - 4, y, x + toc * st->cwidth, y - lheight); y -= lheight; } } else { @@ -1445,11 +1445,11 @@ static void draw_cursor(SpaceText *st, ARegion *ar) wrap_offset_in_line(st, ar, text->sell, text->selc, &offl, &offc); y1 = ar->winy - 2 - (vsell - offl) * lheight; - y2 = y1 - lheight * visible_lines + 1; + y2 = y1 - (lheight * visible_lines + TXT_LINE_SPACING); } else { y1 = ar->winy - 2 - vsell * lheight; - y2 = y1 - lheight + 1; + y2 = y1 - (lheight + TXT_LINE_SPACING); } if (!(y1 < 0 || y2 > ar->winy)) { /* check we need to draw */ @@ -1483,7 +1483,7 @@ static void draw_cursor(SpaceText *st, ARegion *ar) } else { UI_ThemeColor(TH_HILITE); - glRecti(x - 1, y, x + 1, y - lheight + TXT_LINE_SPACING); + glRecti(x - 1, y, x + 1, y - lheight); } } } @@ -1588,7 +1588,7 @@ static void draw_brackets(SpaceText *st, ARegion *ar) UI_ThemeColor(TH_HILITE); x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET; - y = ar->winy - st->lheight; + y = ar->winy - st->lheight_dpi; /* draw opening bracket */ ch = startl->line[startc]; @@ -1598,8 +1598,8 @@ static void draw_brackets(SpaceText *st, ARegion *ar) if (viewc >= 0) { viewl = txt_get_span(text->lines.first, startl) - st->top + offl; - text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * (st->lheight + TXT_LINE_SPACING), ch); - text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * (st->lheight + TXT_LINE_SPACING), ch); + text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * (st->lheight_dpi + TXT_LINE_SPACING), ch); + text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * (st->lheight_dpi + TXT_LINE_SPACING), ch); } /* draw closing bracket */ @@ -1610,8 +1610,8 @@ static void draw_brackets(SpaceText *st, ARegion *ar) if (viewc >= 0) { viewl = txt_get_span(text->lines.first, endl) - st->top + offl; - text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * (st->lheight + TXT_LINE_SPACING), ch); - text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * (st->lheight + TXT_LINE_SPACING), ch); + text_font_draw_character(st, x + viewc * st->cwidth, y - viewl * (st->lheight_dpi + TXT_LINE_SPACING), ch); + text_font_draw_character(st, x + viewc * st->cwidth + 1, y - viewl * (st->lheight_dpi + TXT_LINE_SPACING), ch); } } @@ -1627,7 +1627,10 @@ void draw_text_main(SpaceText *st, ARegion *ar) int wraplinecount = 0, wrap_skip = 0; int margin_column_x; - if (st->lheight) st->viewlines = (int)ar->winy / (st->lheight + TXT_LINE_SPACING); + /* dpi controlled line height and font size */ + st->lheight_dpi = (U.widget_unit * st->lheight) / 20; + + if (st->lheight_dpi) st->viewlines = (int)ar->winy / (st->lheight_dpi + TXT_LINE_SPACING); else st->viewlines = 0; /* if no text, nothing to do */ @@ -1686,7 +1689,7 @@ void draw_text_main(SpaceText *st, ARegion *ar) st->linenrs_tot = 0; /* not used */ x = TXT_OFFSET; } - y = ar->winy - st->lheight; + y = ar->winy - st->lheight_dpi; winx = ar->winx - TXT_SCROLL_WIDTH; /* draw cursor */ @@ -1716,12 +1719,12 @@ void draw_text_main(SpaceText *st, ARegion *ar) if (st->wordwrap) { /* draw word wrapped text */ int lines = text_draw_wrapped(st, tmp->line, x, y, winx - x, tmp->format, wrap_skip); - y -= lines * (st->lheight + TXT_LINE_SPACING); + y -= lines * (st->lheight_dpi + TXT_LINE_SPACING); } else { /* draw unwrapped text */ text_draw(st, tmp->line, st->left, ar->winx / st->cwidth, 1, x, y, tmp->format); - y -= st->lheight + TXT_LINE_SPACING; + y -= st->lheight_dpi + TXT_LINE_SPACING; } wrap_skip = 0; diff --git a/source/blender/editors/space_text/text_intern.h b/source/blender/editors/space_text/text_intern.h index ea61644cee9..6d3b184f6cf 100644 --- a/source/blender/editors/space_text/text_intern.h +++ b/source/blender/editors/space_text/text_intern.h @@ -54,12 +54,11 @@ void text_scroll_to_cursor(struct SpaceText *st, struct ScrArea *sa); void text_update_cursor_moved(struct bContext *C); /* TXT_OFFSET used to be 35 when the scrollbar was on the left... */ -#define TXT_OFFSET 15 -#define TXT_SCROLL_WIDTH 20 -#define TXT_SCROLL_SPACE 2 -#define TXT_LINE_SPACING 4 /* space between lines */ - -#define TEXTXLOC (st->cwidth * st->linenrs_tot) +#define TXT_OFFSET ((int)(0.75f * U.widget_unit)) +#define TXT_SCROLL_WIDTH U.widget_unit +#define TXT_SCROLL_SPACE ((int)(0.1f * U.widget_unit)) +#define TXT_LINE_SPACING ((int)(0.2f * U.widget_unit)) /* space between lines */ +#define TEXTXLOC (st->cwidth * st->linenrs_tot) #define SUGG_LIST_SIZE 7 #define SUGG_LIST_WIDTH 20 diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 5b7f92739ed..71044579df4 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -1131,21 +1131,20 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op) TextLine *tmp; FlattenString fs; size_t a, j; - char *text_check_line, *new_line; + char *new_line; int extra, number; //unknown for now int type = RNA_enum_get(op->ptr, "type"); - - tmp = text->lines.first; - + /* first convert to all space, this make it a lot easier to convert to tabs * because there is no mixtures of ' ' && '\t' */ - while (tmp) { - text_check_line = tmp->line; + for (tmp = text->lines.first; tmp; tmp = tmp->next) { + const char *text_check_line = tmp->line; + const int text_check_line_len = tmp->len; number = flatten_string(st, &fs, text_check_line) + 1; flatten_string_free(&fs); new_line = MEM_callocN(number, "Converted_Line"); j = 0; - for (a = 0; a < strlen(text_check_line); a++) { //foreach char in line + for (a = 0; a < text_check_line_len; a++) { //foreach char in line if (text_check_line[a] == '\t') { //checking for tabs //get the number of spaces this tabs is showing //i don't like doing it this way but will look into it later @@ -1175,20 +1174,19 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op) tmp->line = new_line; tmp->len = strlen(new_line); tmp->format = NULL; - tmp = tmp->next; } if (type == TO_TABS) { // Converting to tabs //start over from the beginning - tmp = text->lines.first; - while (tmp) { - text_check_line = tmp->line; + for (tmp = text->lines.first; tmp; tmp = tmp->next) { + const char *text_check_line = tmp->line; + const int text_check_line_len = tmp->len; extra = 0; - for (a = 0; a < strlen(text_check_line); a++) { + for (a = 0; a < text_check_line_len; a++) { number = 0; for (j = 0; j < (size_t)st->tabnumber; j++) { - if ((a + j) <= strlen(text_check_line)) { //check to make sure we are not pass the end of the line + if ((a + j) <= text_check_line_len) { //check to make sure we are not pass the end of the line if (text_check_line[a + j] != ' ') { number = 1; } @@ -1201,12 +1199,12 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op) } if (extra > 0) { //got tabs make malloc and do what you have to do - new_line = MEM_callocN(strlen(text_check_line) - (((st->tabnumber * extra) - extra) - 1), "Converted_Line"); + new_line = MEM_callocN(text_check_line_len - (((st->tabnumber * extra) - extra) - 1), "Converted_Line"); extra = 0; //reuse vars - for (a = 0; a < strlen(text_check_line); a++) { + for (a = 0; a < text_check_line_len; a++) { number = 0; for (j = 0; j < (size_t)st->tabnumber; j++) { - if ((a + j) <= strlen(text_check_line)) { //check to make sure we are not pass the end of the line + if ((a + j) <= text_check_line_len) { //check to make sure we are not pass the end of the line if (text_check_line[a + j] != ' ') { number = 1; } @@ -1233,7 +1231,6 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op) tmp->len = strlen(new_line); tmp->format = NULL; } - tmp = tmp->next; } } @@ -2106,10 +2103,10 @@ static void text_scroll_apply(bContext *C, wmOperator *op, wmEvent *event) if (!tsc->scrollbar) { txtdelta[0] = -tsc->delta[0] / st->cwidth; - txtdelta[1] = tsc->delta[1] / (st->lheight + TXT_LINE_SPACING); + txtdelta[1] = tsc->delta[1] / (st->lheight_dpi + TXT_LINE_SPACING); tsc->delta[0] %= st->cwidth; - tsc->delta[1] %= (st->lheight + TXT_LINE_SPACING); + tsc->delta[1] %= (st->lheight_dpi + TXT_LINE_SPACING); } else { txtdelta[1] = -tsc->delta[1] * st->pix_per_line; @@ -2204,7 +2201,7 @@ static int text_scroll_invoke(bContext *C, wmOperator *op, wmEvent *event) tsc->old[1] = event->y; /* Sensitivity of scroll set to 4pix per line/char */ tsc->delta[0] = (event->x - event->prevx) * st->cwidth / 4; - tsc->delta[1] = (event->y - event->prevy) * st->lheight / 4; + tsc->delta[1] = (event->y - event->prevy) * st->lheight_dpi / 4; tsc->first = 0; tsc->scrollbar = 0; text_scroll_apply(C, op, event); @@ -2503,7 +2500,7 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, int { Text *text = st->text; text_update_character_width(st); - y = (ar->winy - 2 - y) / (st->lheight + TXT_LINE_SPACING); + y = (ar->winy - 2 - y) / (st->lheight_dpi + TXT_LINE_SPACING); if (st->showlinenrs) x -= TXT_OFFSET + TEXTXLOC; else x -= TXT_OFFSET; diff --git a/source/blender/editors/space_text/text_python.c b/source/blender/editors/space_text/text_python.c index 4c9b4b900cc..a06144b8260 100644 --- a/source/blender/editors/space_text/text_python.c +++ b/source/blender/editors/space_text/text_python.c @@ -36,7 +36,9 @@ #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_text_types.h" +#include "DNA_userdef_types.h" +#include "BKE_blender.h" #include "BKE_suggestions.h" #include "BKE_text.h" @@ -78,10 +80,10 @@ int text_do_suggest_select(SpaceText *st, ARegion *ar) else { x = st->cwidth * (st->text->curc - st->left) + TXT_OFFSET - 4; } - y = ar->winy - st->lheight * l - 2; + y = ar->winy - st->lheight_dpi * l - 2; - w = SUGG_LIST_WIDTH * st->cwidth + 20; - h = SUGG_LIST_SIZE * st->lheight + 8; + w = SUGG_LIST_WIDTH * st->cwidth + U.widget_unit; + h = SUGG_LIST_SIZE * st->lheight_dpi + 0.4f * U.widget_unit; // XXX getmouseco_areawin(mval); @@ -92,7 +94,7 @@ int text_do_suggest_select(SpaceText *st, ARegion *ar) for (i = 0, item = first; i < *top && item->next; i++, item = item->next) ; /* Work out the target item index in the visible list */ - tgti = (y - mval[1] - 4) / st->lheight; + tgti = (y - mval[1] - 4) / st->lheight_dpi; if (tgti < 0 || tgti > SUGG_LIST_SIZE) return 1; diff --git a/source/blender/editors/space_time/SConscript b/source/blender/editors/space_time/SConscript index c08339ba692..32f02bff008 100644 --- a/source/blender/editors/space_time/SConscript +++ b/source/blender/editors/space_time/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_userpref/SConscript b/source/blender/editors/space_userpref/SConscript index 5c52e6f4c41..d5aa9304364 100644 --- a/source/blender/editors/space_userpref/SConscript +++ b/source/blender/editors/space_userpref/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_view3d/SConscript b/source/blender/editors/space_view3d/SConscript index ffe35019960..578f06ada16 100644 --- a/source/blender/editors/space_view3d/SConscript +++ b/source/blender/editors/space_view3d/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index beafee335d4..f37437b159d 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -637,7 +637,7 @@ static float co[16] = { /* smat, imat = mat & imat to draw screenaligned */ -static void draw_sphere_bone_dist(float smat[][4], float imat[][4], bPoseChannel *pchan, EditBone *ebone) +static void draw_sphere_bone_dist(float smat[4][4], float imat[4][4], bPoseChannel *pchan, EditBone *ebone) { float head, tail, dist /*, length*/; float *headvec, *tailvec, dirvec[3]; @@ -755,7 +755,7 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], bPoseChannel /* smat, imat = mat & imat to draw screenaligned */ -static void draw_sphere_bone_wire(float smat[][4], float imat[][4], +static void draw_sphere_bone_wire(float smat[4][4], float imat[4][4], int armflag, int boneflag, short constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) { @@ -1648,7 +1648,7 @@ static void draw_pose_dofs(Object *ob) } } -static void bone_matrix_translate_y(float mat[][4], float y) +static void bone_matrix_translate_y(float mat[4][4], float y) { float trans[3]; @@ -2069,7 +2069,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, } /* in editmode, we don't store the bone matrix... */ -static void get_matrix_editbone(EditBone *eBone, float bmat[][4]) +static void get_matrix_editbone(EditBone *eBone, float bmat[4][4]) { float delta[3]; float mat[3][3]; diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index 0ecde350b00..e36654323fd 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -415,14 +415,14 @@ static void draw_textured_end(void) static DMDrawOption draw_tface__set_draw_legacy(MTFace *tface, int has_mcol, int matnr) { Material *ma = give_current_material(Gtexdraw.ob, matnr + 1); - int validtexture = 0; + int invalidtexture = 0; if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return DM_DRAW_OPTION_SKIP; - validtexture = set_draw_settings_cached(0, tface, ma, Gtexdraw); + invalidtexture = set_draw_settings_cached(0, tface, ma, Gtexdraw); - if (tface && validtexture) { + if (tface && invalidtexture) { glColor3ub(0xFF, 0x00, 0xFF); return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */ } @@ -457,25 +457,14 @@ static DMDrawOption draw_mcol__set_draw_legacy(MTFace *UNUSED(tface), int has_mc return DM_DRAW_OPTION_NO_MCOL; } -static DMDrawOption draw_tface__set_draw(MTFace *tface, int has_mcol, int matnr) +static DMDrawOption draw_tface__set_draw(MTFace *UNUSED(tface), int UNUSED(has_mcol), int matnr) { Material *ma = give_current_material(Gtexdraw.ob, matnr + 1); if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0; - if (tface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) { - return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */ - } - else if (tface && (tface->mode & TF_OBCOL)) { - return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */ - } - else if (!has_mcol) { - /* XXX: this return value looks wrong (and doesn't match comment) */ - return DM_DRAW_OPTION_NORMAL; /* Don't set color */ - } - else { - return DM_DRAW_OPTION_NORMAL; /* Set color from mcol */ - } + /* always use color from mcol, as set in update_tface_color_layer */ + return DM_DRAW_OPTION_NORMAL; } static void update_tface_color_layer(DerivedMesh *dm) @@ -517,11 +506,11 @@ static void update_tface_color_layer(DerivedMesh *dm) finalCol[i * 4 + j].r = 255; } } - else if (tface && (tface->mode & TF_OBCOL)) { + else if (ma && (ma->shade_flag & MA_OBCOLOR)) { for (j = 0; j < 4; j++) { - finalCol[i * 4 + j].b = FTOCHAR(Gtexdraw.obcol[0]); - finalCol[i * 4 + j].g = FTOCHAR(Gtexdraw.obcol[1]); - finalCol[i * 4 + j].r = FTOCHAR(Gtexdraw.obcol[2]); + finalCol[i * 4 + j].b = Gtexdraw.obcol[0]; + finalCol[i * 4 + j].g = Gtexdraw.obcol[1]; + finalCol[i * 4 + j].r = Gtexdraw.obcol[2]; } } else if (!mcol) { diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index f272cb61c26..fd1eb7852c1 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -622,7 +622,7 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char BKE_image_release_ibuf(ima, ibuf, NULL); } -static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, float tmat[][4]) +static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, float tmat[4][4]) { float vx[3], vy[3]; float *viter = (float *)verts; @@ -638,7 +638,7 @@ static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3 } } -void drawcircball(int mode, const float cent[3], float rad, float tmat[][4]) +void drawcircball(int mode, const float cent[3], float rad, float tmat[4][4]) { float verts[CIRCLE_RESOL][3]; @@ -739,7 +739,7 @@ void view3d_cached_text_draw_add(const float co[3], memcpy(++vos, str, alloc_len); } -void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4]) +void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[4][4]) { RegionView3D *rv3d = ar->regiondata; ListBase *strings = &CachedText[CachedTextLevel - 1]; @@ -929,7 +929,7 @@ static void drawcube_size(const float size[3]) } #endif -static void drawshadbuflimits(Lamp *la, float mat[][4]) +static void drawshadbuflimits(Lamp *la, float mat[4][4]) { float sta[3], end[3], lavec[3]; @@ -2854,7 +2854,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, } } - EDBM_index_arrays_init(em, 1, 1, 1); + EDBM_index_arrays_ensure(em, BM_VERT | BM_EDGE | BM_FACE); if (dt > OB_WIRE) { if (check_object_draw_texture(scene, v3d, dt)) { @@ -3019,8 +3019,6 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, bglPolygonOffset(rv3d->dist, 0.0); GPU_disable_material(); } - - EDBM_index_arrays_free(em); } /* Mesh drawing routines */ @@ -4689,9 +4687,11 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit) if (!(point->flag & PEP_HIDE)) totkeys += point->totkey; - if (edit->points && !(edit->points->keys->flag & PEK_USE_WCO)) - pd = pdata = MEM_callocN(totkeys * 3 * sizeof(float), "particle edit point data"); - cd = cdata = MEM_callocN(totkeys * (timed ? 4 : 3) * sizeof(float), "particle edit color data"); + if (totkeys) { + if (edit->points && !(edit->points->keys->flag & PEK_USE_WCO)) + pd = pdata = MEM_callocN(totkeys * 3 * sizeof(float), "particle edit point data"); + cd = cdata = MEM_callocN(totkeys * (timed ? 4 : 3) * sizeof(float), "particle edit color data"); + } for (i = 0, point = edit->points; i < totpoint; i++, point++) { if (point->flag & PEP_HIDE) @@ -5462,10 +5462,10 @@ static void curve_draw_speed(Scene *scene, Object *ob) #endif /* XXX old animation system stuff */ -static void draw_textcurs(float textcurs[4][2]) +static void draw_textcurs(RegionView3D *rv3d, float textcurs[4][2]) { cpack(0); - + bglPolygonOffset(rv3d->dist, -1.0); set_inverted_drawing(1); glBegin(GL_QUADS); glVertex2fv(textcurs[0]); @@ -5474,9 +5474,10 @@ static void draw_textcurs(float textcurs[4][2]) glVertex2fv(textcurs[3]); glEnd(); set_inverted_drawing(0); + bglPolygonOffset(rv3d->dist, 0.0); } -static void drawspiral(const float cent[3], float rad, float tmat[][4], int start) +static void drawspiral(const float cent[3], float rad, float tmat[4][4], int start) { float vec[3], vx[3], vy[3]; const float tot_inv = (1.0f / (float)CIRCLE_RESOL); @@ -5565,7 +5566,7 @@ static void drawcircle_size(float size) } /* needs fixing if non-identity matrice used */ -static void drawtube(const float vec[3], float radius, float height, float tmat[][4]) +static void drawtube(const float vec[3], float radius, float height, float tmat[4][4]) { float cur[3]; drawcircball(GL_LINE_LOOP, vec, radius, tmat); @@ -5587,7 +5588,7 @@ static void drawtube(const float vec[3], float radius, float height, float tmat[ glEnd(); } /* needs fixing if non-identity matrice used */ -static void drawcone(const float vec[3], float radius, float height, float tmat[][4]) +static void drawcone(const float vec[3], float radius, float height, float tmat[4][4]) { float cur[3]; @@ -6394,7 +6395,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short case OB_FONT: cu = ob->data; if (cu->editfont) { - draw_textcurs(cu->editfont->textcurs); + draw_textcurs(rv3d, cu->editfont->textcurs); if (cu->flag & CU_FAST) { cpack(0xFFFFFF); @@ -7153,7 +7154,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec DerivedMesh *dm = editbmesh_get_derived_cage(scene, ob, em, CD_MASK_BAREMESH); - EDBM_index_arrays_init(em, 1, 1, 1); + EDBM_index_arrays_ensure(em, BM_VERT | BM_EDGE | BM_FACE); bbs_mesh_solid_EM(em, scene, v3d, ob, dm, ts->selectmode & SCE_SELECT_FACE); if (ts->selectmode & SCE_SELECT_FACE) @@ -7179,8 +7180,6 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec bglPolygonOffset(rv3d->dist, 0.0); dm->release(dm); - - EDBM_index_arrays_free(em); } else { Mesh *me = ob->data; diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index ebb48960b80..70690e2dce7 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -38,6 +38,7 @@ #include "DNA_screen_types.h" #include "DNA_smoke_types.h" #include "DNA_view3d_types.h" +#include "DNA_property_types.h" #include "BLI_utildefines.h" #include "BLI_blenlib.h" diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 1c31cd23e33..61649e105ee 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -117,7 +117,7 @@ ARegion *view3d_has_tools_region(ScrArea *sa) BLI_insertlinkafter(&sa->regionbase, arhead, artool); artool->regiontype = RGN_TYPE_TOOLS; - artool->alignment = RGN_ALIGN_LEFT; //RGN_OVERLAP_LEFT; + artool->alignment = RGN_ALIGN_LEFT; artool->flag = RGN_FLAG_HIDDEN; } @@ -261,14 +261,11 @@ static SpaceLink *view3d_new(const bContext *C) v3d->gridlines = 16; v3d->gridsubdiv = 10; v3d->drawtype = OB_SOLID; + + v3d->gridflag = V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_FLOOR; - v3d->gridflag |= V3D_SHOW_X; - v3d->gridflag |= V3D_SHOW_Y; - v3d->gridflag |= V3D_SHOW_FLOOR; - v3d->gridflag &= ~V3D_SHOW_Z; - - v3d->flag |= V3D_SELECT_OUTLINE; - v3d->flag2 |= V3D_SHOW_RECONSTRUCTION; + v3d->flag = V3D_SELECT_OUTLINE; + v3d->flag2 = V3D_SHOW_RECONSTRUCTION | V3D_SHOW_GPENCIL; v3d->lens = 35.0f; v3d->near = 0.01f; @@ -635,8 +632,7 @@ static void view3d_recalc_used_layers(ARegion *ar, wmNotifier *wmn, Scene *scene static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) { - bScreen *sc; - + /* context changes */ switch (wmn->category) { case NC_ANIMATION: @@ -659,7 +655,8 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) case NC_SCENE: switch (wmn->data) { case ND_LAYER_CONTENT: - view3d_recalc_used_layers(ar, wmn, wmn->reference); + if (wmn->reference) + view3d_recalc_used_layers(ar, wmn, wmn->reference); ED_region_tag_redraw(ar); break; case ND_FRAME: @@ -787,8 +784,10 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) case ND_SCREENSET: /* screen was changed, need to update used layers due to NC_SCENE|ND_LAYER_CONTENT */ /* updates used layers only for View3D in active screen */ - sc = wmn->reference; - view3d_recalc_used_layers(ar, wmn, sc->scene); + if (wmn->reference) { + bScreen *sc = wmn->reference; + view3d_recalc_used_layers(ar, wmn, sc->scene); + } ED_region_tag_redraw(ar); break; } diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index bf14d915412..6a095a8d2b1 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -365,7 +365,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float if (block) { /* buttons */ uiBut *but; int yi = 200; - const int buth = 20 * UI_DPI_ICON_FAC; + const int buth = 20 * UI_DPI_FAC; const int but_margin = 2; const char *c; @@ -439,7 +439,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float 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.0, M_PI * 2.0, 1, 3, NULL); + &data_ptr, "tilt", 0, -FLT_MAX, FLT_MAX, 1, 3, NULL); } else if (totcurvedata > 1) { uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"), @@ -450,7 +450,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float &(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.0, M_PI * 2.0, 1, 3, + &(tfp->ve_median[C_TILT]), -FLT_MAX, FLT_MAX, 1, 3, TIP_("Tilt of curve control points")); uiButSetUnitType(but, PROP_UNIT_ROTATION); } @@ -1260,6 +1260,7 @@ void view3d_buttons_register(ARegionType *art) pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil"); strcpy(pt->idname, "VIEW3D_PT_gpencil"); strcpy(pt->label, "Grease Pencil"); + pt->draw_header = gpencil_panel_standard_header; pt->draw = gpencil_panel_standard; BLI_addtail(&art->paneltypes, pt); diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 51261f4c341..7475f65317a 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -217,7 +217,7 @@ void ED_view3d_clipping_enable(void) } } -static int view3d_clipping_test(const float vec[3], float clip[][4]) +static int view3d_clipping_test(const float vec[3], float clip[6][4]) { float view[3]; copy_v3_v3(view, vec); @@ -563,41 +563,49 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit) if (v3d->zbuf && scene->obedit) glDepthMask(1); } + 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_OK) { + const float f5 = 0.25f * U.widget_unit; + const float f10 = 0.5f * U.widget_unit; + const float f20 = U.widget_unit; + setlinestyle(0); cpack(0xFF); - circ((float)co[0], (float)co[1], 10.0); - setlinestyle(4); + circ((float)co[0], (float)co[1], f10); + setlinestyle(4); cpack(0xFFFFFF); - circ((float)co[0], (float)co[1], 10.0); + circ((float)co[0], (float)co[1], f10); setlinestyle(0); cpack(0x0); - sdrawline(co[0] - 20, co[1], co[0] - 5, co[1]); - sdrawline(co[0] + 5, co[1], co[0] + 20, co[1]); - sdrawline(co[0], co[1] - 20, co[0], co[1] - 5); - sdrawline(co[0], co[1] + 5, co[0], co[1] + 20); + sdrawline(co[0] - f20, co[1], co[0] - f5, co[1]); + sdrawline(co[0] + f5, co[1], co[0] + f20, co[1]); + sdrawline(co[0], co[1] - f20, co[0], co[1] - f5); + sdrawline(co[0], co[1] + f5, co[0], co[1] + f20); } } /* Draw a live substitute of the view icon, which is always shown * colors copied from transform_manipulator.c, we should keep these matching. */ -static void draw_view_axis(RegionView3D *rv3d) +static void draw_view_axis(RegionView3D *rv3d, rcti *rect) { const float k = U.rvisize; /* axis size */ const float toll = 0.5; /* used to see when view is quasi-orthogonal */ - const float start = k + 1.0f; /* axis center in screen coordinates, x=y */ + float startx = k + 1.0f; /* axis center in screen coordinates, x=y */ + float starty = k + 1.0f; float ydisp = 0.0; /* vertical displacement to allow obj info text */ int bright = 25 * (float)U.rvibright + 5; /* axis alpha (rvibright has range 0-10) */ - float vec[3]; float dx, dy; + startx += rect->xmin; + starty += rect->ymin; + /* thickness of lines is proportional to k */ glLineWidth(2); @@ -613,12 +621,12 @@ static void draw_view_axis(RegionView3D *rv3d) UI_ThemeColorShadeAlpha(TH_AXIS_X, 0, bright); glBegin(GL_LINES); - glVertex2f(start, start + ydisp); - glVertex2f(start + dx, start + dy + ydisp); + glVertex2f(startx, starty + ydisp); + glVertex2f(startx + dx, starty + dy + ydisp); glEnd(); if (fabsf(dx) > toll || fabsf(dy) > toll) { - BLF_draw_default_ascii(start + dx + 2, start + dy + ydisp + 2, 0.0f, "x", 1); + BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, "x", 1); } /* BLF_draw_default disables blending */ @@ -633,12 +641,12 @@ static void draw_view_axis(RegionView3D *rv3d) UI_ThemeColorShadeAlpha(TH_AXIS_Y, 0, bright); glBegin(GL_LINES); - glVertex2f(start, start + ydisp); - glVertex2f(start + dx, start + dy + ydisp); + glVertex2f(startx, starty + ydisp); + glVertex2f(startx + dx, starty + dy + ydisp); glEnd(); if (fabsf(dx) > toll || fabsf(dy) > toll) { - BLF_draw_default_ascii(start + dx + 2, start + dy + ydisp + 2, 0.0f, "y", 1); + BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, "y", 1); } glEnable(GL_BLEND); @@ -652,12 +660,12 @@ static void draw_view_axis(RegionView3D *rv3d) UI_ThemeColorShadeAlpha(TH_AXIS_Z, 0, bright); glBegin(GL_LINES); - glVertex2f(start, start + ydisp); - glVertex2f(start + dx, start + dy + ydisp); + glVertex2f(startx, starty + ydisp); + glVertex2f(startx + dx, starty + dy + ydisp); glEnd(); if (fabsf(dx) > toll || fabsf(dy) > toll) { - BLF_draw_default_ascii(start + dx + 2, start + dy + ydisp + 2, 0.0f, "z", 1); + BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, "z", 1); } /* restore line-width */ @@ -770,7 +778,7 @@ static void draw_rotation_guide(RegionView3D *rv3d) glDepthMask(1); } -static void draw_view_icon(RegionView3D *rv3d) +static void draw_view_icon(RegionView3D *rv3d, rcti *rect) { BIFIconID icon; @@ -785,7 +793,7 @@ static void draw_view_icon(RegionView3D *rv3d) glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - UI_icon_draw(5.0, 5.0, icon); + UI_icon_draw(5.0 + rect->xmin, 5.0 + rect->ymin, icon); glDisable(GL_BLEND); } @@ -840,7 +848,7 @@ static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d) return name; } -static void draw_viewport_name(ARegion *ar, View3D *v3d) +static void draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect) { RegionView3D *rv3d = ar->regiondata; const char *name = view3d_get_name(v3d, rv3d); @@ -853,17 +861,17 @@ static void draw_viewport_name(ARegion *ar, View3D *v3d) if (name) { UI_ThemeColor(TH_TEXT_HI); - BLF_draw_default_ascii(22, ar->winy - 17, 0.0f, name, sizeof(tmpstr)); + BLF_draw_default_ascii(U.widget_unit + rect->xmin, rect->ymax - U.widget_unit, 0.0f, name, sizeof(tmpstr)); } } /* draw info beside axes in bottom left-corner: * framenum, object name, bone name (if available), marker name (if available) */ -static void draw_selected_name(Scene *scene, Object *ob) +static void draw_selected_name(Scene *scene, Object *ob, rcti *rect) { char info[256], *markern; - short offset = 30; + short offset = 30 + rect->xmin; /* get name of marker on current frame (if available) */ markern = BKE_scene_find_marker_name(scene, CFRA); @@ -946,9 +954,9 @@ static void draw_selected_name(Scene *scene, Object *ob) } if (U.uiflag & USER_SHOW_ROTVIEWICON) - offset = 14 + (U.rvisize * 2); + offset = U.widget_unit + (U.rvisize * 2) + rect->xmin; - BLF_draw_default(offset, 10, 0.0f, info, sizeof(info)); + BLF_draw_default(offset, 0.5f * U.widget_unit, 0.0f, info, sizeof(info)); } static void view3d_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, @@ -1289,7 +1297,6 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) RegionView3D *rv3d = ar->regiondata; struct Base *base = scene->basact; int multisample_enabled; - rcti winrct; BLI_assert(ar->regiontype == RGN_TYPE_WINDOW); @@ -1338,8 +1345,7 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) if (multisample_enabled) glDisable(GL_MULTISAMPLE_ARB); - region_scissor_winrct(ar, &winrct); - glScissor(winrct.xmin, winrct.ymin, BLI_rcti_size_x(&winrct), BLI_rcti_size_y(&winrct)); + glScissor(ar->winrct.xmin, ar->winrct.ymin, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct)); glClearColor(0.0, 0.0, 0.0, 0.0); if (v3d->zbuf) { @@ -2165,7 +2171,9 @@ void draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d) v3d->zbuf = TRUE; glEnable(GL_DEPTH_TEST); - draw_gpencil_view3d(scene, v3d, ar, 1); + if (v3d->flag2 & V3D_SHOW_GPENCIL) { + draw_gpencil_view3d(scene, v3d, ar, TRUE); + } v3d->zbuf = zbuf; @@ -2307,7 +2315,7 @@ typedef struct View3DShadow { } View3DShadow; static void gpu_render_lamp_update(Scene *scene, View3D *v3d, Object *ob, Object *par, - float obmat[][4], ListBase *shadows) + float obmat[4][4], ListBase *shadows) { GPULamp *lamp; Lamp *la = (Lamp *)ob->data; @@ -2466,7 +2474,7 @@ CustomDataMask ED_view3d_screen_datamask(bScreen *screen) return mask; } -void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[][4], float winmat[][4]) +void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]) { RegionView3D *rv3d = ar->regiondata; @@ -2509,7 +2517,7 @@ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float view } } -static void view3d_main_area_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[][4], float winmat[][4]) +static void view3d_main_area_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]) { RegionView3D *rv3d = ar->regiondata; @@ -2533,7 +2541,7 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d) * stuff like shadow buffers */ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, - int winx, int winy, float viewmat[][4], float winmat[][4], + int winx, int winy, float viewmat[4][4], float winmat[4][4], int do_bgpic, int colormanage_background) { RegionView3D *rv3d = ar->regiondata; @@ -2645,9 +2653,11 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, } /* must be before xray draw which clears the depth buffer */ - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - draw_gpencil_view3d(scene, v3d, ar, 1); - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); + if (v3d->flag2 & V3D_SHOW_GPENCIL) { + if (v3d->zbuf) glDisable(GL_DEPTH_TEST); + draw_gpencil_view3d(scene, v3d, ar, TRUE); + if (v3d->zbuf) glEnable(GL_DEPTH_TEST); + } /* transp and X-ray afterdraw stuff */ if (v3d->afterdraw_transp.first) view3d_draw_transp(scene, ar, v3d); @@ -2671,8 +2681,11 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, /* draw grease-pencil stuff */ ED_region_pixelspace(ar); - /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ - draw_gpencil_view3d(scene, v3d, ar, 0); + + if (v3d->flag2 & V3D_SHOW_GPENCIL) { + /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ + draw_gpencil_view3d(scene, v3d, ar, FALSE); + } /* freeing the images again here could be done after the operator runs, leaving for now */ GPU_free_images_anim(); @@ -2748,7 +2761,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, /* creates own 3d views, used by the sequencer */ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height, - unsigned int flag, int drawtype, int draw_background, + unsigned int flag, int drawtype, int use_solid_tex, int draw_background, int colormanage_background, char err_out[256]) { View3D v3d = {NULL}; @@ -2765,6 +2778,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w v3d.drawtype = drawtype; v3d.flag2 = V3D_RENDER_OVERRIDE; + if (use_solid_tex) + v3d.flag2 |= V3D_SOLID_TEX; + rv3d.persp = RV3D_CAMOB; copy_m4_m4(rv3d.viewinv, v3d.camera->obmat); @@ -2798,7 +2814,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w /* NOTE: the info that this uses is updated in ED_refresh_viewport_fps(), * which currently gets called during SCREEN_OT_animation_step. */ -static void draw_viewport_fps(Scene *scene, ARegion *ar) +static void draw_viewport_fps(Scene *scene, rcti *rect) { ScreenFrameRateInfo *fpsi = scene->fps_info; float fps; @@ -2843,7 +2859,7 @@ static void draw_viewport_fps(Scene *scene, ARegion *ar) BLI_snprintf(printable, sizeof(printable), "fps: %i", (int)(fps + 0.5f)); } - BLF_draw_default_ascii(22, ar->winy - 17, 0.0f, printable, sizeof(printable)); + BLF_draw_default_ascii(rect->xmin + U.widget_unit, rect->ymax - U.widget_unit, 0.0f, printable, sizeof(printable)); } static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit); @@ -3102,10 +3118,10 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const // REEB_draw(); - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { + if (v3d->flag2 & V3D_SHOW_GPENCIL) { /* must be before xray draw which clears the depth buffer */ if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - draw_gpencil_view3d(scene, v3d, ar, 1); + draw_gpencil_view3d(scene, v3d, ar, TRUE); if (v3d->zbuf) glEnable(GL_DEPTH_TEST); } @@ -3152,6 +3168,10 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); + rcti rect; + + /* local coordinate visible rect inside region, to accomodate overlapping ui */ + ED_region_visible_rect(ar, &rect); if (rv3d->persp == RV3D_CAMOB) { drawviewborder(scene, ar, v3d); @@ -3168,23 +3188,24 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } + if (v3d->flag2 & V3D_SHOW_GPENCIL) { + /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ + draw_gpencil_view3d(scene, v3d, ar, FALSE); + } + if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { Object *ob; - /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ - // if (v3d->flag2 & V3D_DISPGP) - draw_gpencil_view3d(scene, v3d, ar, 0); - drawcursor(scene, ar, v3d); if (U.uiflag & USER_SHOW_ROTVIEWICON) - draw_view_axis(rv3d); + draw_view_axis(rv3d, &rect); else - draw_view_icon(rv3d); + draw_view_icon(rv3d, &rect); ob = OBACT; if (U.uiflag & USER_DRAWVIEWINFO) - draw_selected_name(scene, ob); + draw_selected_name(scene, ob, &rect); } if (rv3d->render_engine) { @@ -3194,10 +3215,10 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_playing(wm)) { - draw_viewport_fps(scene, ar); + draw_viewport_fps(scene, &rect); } else if (U.uiflag & USER_SHOW_VIEWPORTNAME) { - draw_viewport_name(ar, v3d); + draw_viewport_name(ar, v3d, &rect); } if (grid_unit) { /* draw below the viewport name */ @@ -3208,7 +3229,8 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha BLI_snprintf(numstr, sizeof(numstr), "%s x %.4g", grid_unit, v3d->grid); } - BLF_draw_default_ascii(22, ar->winy - (USER_SHOW_VIEWPORTNAME ? 40 : 20), 0.0f, + BLF_draw_default_ascii(rect.xmin + U.widget_unit, + rect.ymax - (USER_SHOW_VIEWPORTNAME ? 2 * U.widget_unit : U.widget_unit), 0.0f, numstr[0] ? numstr : grid_unit, sizeof(numstr)); } } diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index d45013c40d9..a1f0bf69497 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -96,7 +96,8 @@ int ED_view3d_camera_lock_check(View3D *v3d, RegionView3D *rv3d) void ED_view3d_camera_lock_init(View3D *v3d, RegionView3D *rv3d) { if (ED_view3d_camera_lock_check(v3d, rv3d)) { - rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs); + /* using a fallback dist is OK here since ED_view3d_from_object() compensates for it */ + rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK); ED_view3d_from_object(v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL); } } @@ -431,8 +432,21 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event) copy_v3_v3(vod->ofs, rv3d->ofs); if (vod->use_dyn_ofs) { - /* If there's no selection, lastofs is unmodified and last value since static */ - calculateTransformCenter(C, V3D_CENTROID, lastofs, NULL); + Scene *scene = CTX_data_scene(C); + Object *ob = OBACT; + + if (ob && ob->mode & OB_MODE_ALL_PAINT) { + /* transformation is disabled for painting modes, which will make it + * so previous offset is used. This is annoying when you open file + * saved with active object in painting mode + */ + copy_v3_v3(lastofs, ob->obmat[3]); + } + else { + /* If there's no selection, lastofs is unmodified and last value since static */ + calculateTransformCenter(C, V3D_CENTROID, lastofs, NULL); + } + negate_v3_v3(vod->dyn_ofs, lastofs); } else if (U.uiflag & USER_ZBUF_ORBIT) { @@ -895,7 +909,7 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event) /* changed since 2.4x, use the camera view */ if (vod->v3d->camera) { - rv3d->dist = ED_view3d_offset_distance(vod->v3d->camera->obmat, rv3d->ofs); + rv3d->dist = ED_view3d_offset_distance(vod->v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK); ED_view3d_from_object(vod->v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL); } @@ -1910,7 +1924,7 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event) viewzoom_exec(C, op); } else { - if (event->type == MOUSEZOOM) { + if (event->type == MOUSEZOOM || event->type == MOUSEPAN) { /* Bypass Zoom invert flag for track pads (pass FALSE always) */ if (U.uiflag & USER_ZOOM_HORIZ) { @@ -3576,7 +3590,7 @@ static void calc_clipping_plane(float clip[6][4], BoundBox *clipbb) } } -static void calc_local_clipping(float clip_local[][4], BoundBox *clipbb, float mat[][4]) +static void calc_local_clipping(float clip_local[6][4], BoundBox *clipbb, float mat[4][4]) { BoundBox clipbb_local; float imat[4][4]; @@ -3591,7 +3605,7 @@ static void calc_local_clipping(float clip_local[][4], BoundBox *clipbb, float m calc_clipping_plane(clip_local, &clipbb_local); } -void ED_view3d_clipping_local(RegionView3D *rv3d, float mat[][4]) +void ED_view3d_clipping_local(RegionView3D *rv3d, float mat[4][4]) { if (rv3d->rflag & RV3D_CLIPPING) calc_local_clipping(rv3d->clip_local, rv3d->clipbb, mat); @@ -3669,10 +3683,9 @@ static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent * ARegion *ar = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); - float *fp = NULL; + float *fp = give_cursor(scene, v3d); float mval_fl[2]; int flip; - fp = give_cursor(scene, v3d); flip = initgrabz(rv3d, fp[0], fp[1], fp[2]); @@ -3977,16 +3990,28 @@ int ED_view3d_autodist_depth_seg(ARegion *ar, const int mval_sta[2], const int m return (*depth == FLT_MAX) ? 0 : 1; } -float ED_view3d_offset_distance(float mat[4][4], float ofs[3]) { +/* problem - ofs[3] can be on same location as camera itself. + * Blender needs proper dist value for zoom. + * use fallback_dist to override small values + */ +float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float fallback_dist) +{ float pos[4] = {0.0f, 0.0f, 0.0f, 1.0f}; float dir[4] = {0.0f, 0.0f, 1.0f, 0.0f}; - + float dist; + mul_m4_v4(mat, pos); add_v3_v3(pos, ofs); mul_m4_v4(mat, dir); normalize_v3(dir); - return dot_v3v3(pos, dir); + dist = dot_v3v3(pos, dir); + + if ((dist < FLT_EPSILON) && (fallback_dist != 0.0f)) { + dist = fallback_dist; + } + + return dist; } /** @@ -3997,7 +4022,7 @@ float ED_view3d_offset_distance(float mat[4][4], float ofs[3]) { * \param quat The view rotation, quaternion normally from RegionView3D.viewquat. * \param dist The view distance from ofs, normally from RegionView3D.dist. */ -void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist) +void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist) { /* Offset */ if (ofs) @@ -4034,7 +4059,7 @@ void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist) * \param quat The view rotation, quaternion normally from RegionView3D.viewquat. * \param dist The view distance from ofs, normally from RegionView3D.dist. */ -void ED_view3d_to_m4(float mat[][4], const float ofs[3], const float quat[4], const float dist) +void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist) { float iviewquat[4] = {-quat[0], quat[1], quat[2], quat[3]}; float dvec[3] = {0.0f, 0.0f, dist}; diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 5beeda9f220..f8a7cdde8a5 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -125,7 +125,7 @@ void drawaxes(float size, char drawtype); void view3d_cached_text_draw_begin(void); void view3d_cached_text_draw_add(const float co[3], const char *str, short xoffs, short flag, const unsigned char col[4]); -void view3d_cached_text_draw_end(View3D * v3d, ARegion * ar, int depth_write, float mat[][4]); +void view3d_cached_text_draw_end(View3D * v3d, ARegion * ar, int depth_write, float mat[4][4]); enum { V3D_CACHE_TEXT_ZBUF = (1 << 0), @@ -172,7 +172,7 @@ void VIEW3D_OT_localview(struct wmOperatorType *ot); void VIEW3D_OT_game_start(struct wmOperatorType *ot); -int ED_view3d_boundbox_clip(RegionView3D * rv3d, float obmat[][4], struct BoundBox *bb); +int ED_view3d_boundbox_clip(RegionView3D * rv3d, float obmat[4][4], struct BoundBox *bb); void view3d_smooth_view(struct bContext *C, struct View3D *v3d, struct ARegion *ar, struct Object *, struct Object *, float *ofs, float *quat, float *dist, float *lens); diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c index 37607729d0d..a0b36e57d69 100644 --- a/source/blender/editors/space_view3d/view3d_iterators.c +++ b/source/blender/editors/space_view3d/view3d_iterators.c @@ -113,9 +113,8 @@ void mesh_foreachScreenVert( ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ } - EDBM_index_arrays_init(vc->em, 1, 0, 0); + EDBM_index_arrays_ensure(vc->em, BM_VERT); dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data); - EDBM_index_arrays_free(vc->em); dm->release(dm); } @@ -172,9 +171,8 @@ void mesh_foreachScreenEdge( ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ } - EDBM_index_arrays_init(vc->em, 0, 1, 0); + EDBM_index_arrays_ensure(vc->em, BM_EDGE); dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data); - EDBM_index_arrays_free(vc->em); dm->release(dm); } @@ -209,9 +207,8 @@ void mesh_foreachScreenFace( ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - EDBM_index_arrays_init(vc->em, 0, 0, 1); + EDBM_index_arrays_ensure(vc->em, BM_FACE); dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data); - EDBM_index_arrays_free(vc->em); dm->release(dm); } diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 6105b5e4eb5..4101ced616a 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -39,6 +39,10 @@ #include "DNA_space_types.h" #include "DNA_view3d_types.h" +#include "BKE_blender.h" +#include "BKE_context.h" +#include "BKE_main.h" + #include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_utildefines.h" @@ -48,10 +52,75 @@ #include "WM_api.h" #include "WM_types.h" +#include "ED_screen.h" #include "ED_transform.h" #include "view3d_intern.h" +/* ************************** copy paste ***************************** */ + +static int view3d_copybuffer_exec(bContext *C, wmOperator *op) +{ + char str[FILE_MAX]; + + BKE_copybuffer_begin(); + + /* context, selection, could be generalized */ + CTX_DATA_BEGIN (C, Object *, ob, selected_objects) + { + BKE_copybuffer_tag_ID(&ob->id); + + } + CTX_DATA_END; + + BLI_make_file_string("/", str, BLI_temporary_dir(), "copybuffer.blend"); + BKE_copybuffer_save(str, op->reports); + + return OPERATOR_FINISHED; +} + +static void VIEW3D_OT_copybuffer(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name = "Copy Selection to Buffer"; + ot->idname = "VIEW3D_OT_copybuffer"; + ot->description = "Selected objects are saved in a temp file"; + + /* api callbacks */ + ot->invoke = WM_operator_confirm; + ot->exec = view3d_copybuffer_exec; + ot->poll = ED_operator_view3d_active; +} + +static int view3d_pastebuffer_exec(bContext *C, wmOperator *op) +{ + char str[FILE_MAX]; + + BLI_make_file_string("/", str, BLI_temporary_dir(), "copybuffer.blend"); + BKE_copybuffer_paste(C, str, op->reports); + + WM_event_add_notifier(C, NC_WINDOW, NULL); + + return OPERATOR_FINISHED; +} + +static void VIEW3D_OT_pastebuffer(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name = "Paste Selection from Buffer"; + ot->idname = "VIEW3D_OT_pastebuffer"; + ot->description = "Contents of copy buffer gets pasted"; + + /* api callbacks */ + ot->invoke = WM_operator_confirm; + ot->exec = view3d_pastebuffer_exec; + ot->poll = ED_operator_view3d_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} /* ************************** registration **********************************/ @@ -97,6 +166,8 @@ void view3d_operatortypes(void) WM_operatortype_append(VIEW3D_OT_game_start); WM_operatortype_append(VIEW3D_OT_fly); WM_operatortype_append(VIEW3D_OT_layers); + WM_operatortype_append(VIEW3D_OT_copybuffer); + WM_operatortype_append(VIEW3D_OT_pastebuffer); WM_operatortype_append(VIEW3D_OT_properties); WM_operatortype_append(VIEW3D_OT_toolshelf); @@ -117,13 +188,41 @@ void view3d_keymap(wmKeyConfig *keyconf) wmKeyMapItem *kmi; keymap = WM_keymap_find(keyconf, "3D View Generic", SPACE_VIEW3D, 0); - + WM_keymap_add_item(keymap, "VIEW3D_OT_properties", NKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_toolshelf", TKEY, KM_PRESS, 0, 0); /* only for region 3D window */ keymap = WM_keymap_find(keyconf, "3D View", SPACE_VIEW3D, 0); - + + + /* NDOF: begin */ + /* note: positioned here so keymaps show keyboard keys if assigned */ + /* 3D mouse */ + WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_orbit", NDOF_MOTION, 0, KM_CTRL, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_pan", NDOF_MOTION, 0, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_all", NDOF_MOTION, 0, 0, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", NDOF_BUTTON_FIT, KM_PRESS, 0, 0); + RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT); + RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BACK, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BACK); + RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_LEFT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_LEFT); + RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_RIGHT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_RIGHT); + RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_TOP); + RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BOTTOM, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BOTTOM); + + /* 3D mouse align */ + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, KM_SHIFT, 0); + RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_FRONT); + RNA_boolean_set(kmi->ptr, "align_active", TRUE); + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_RIGHT, KM_PRESS, KM_SHIFT, 0); + RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_RIGHT); + RNA_boolean_set(kmi->ptr, "align_active", TRUE); + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, KM_SHIFT, 0); + RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_TOP); + RNA_boolean_set(kmi->ptr, "align_active", TRUE); + /* NDOF: end */ + + kmi = WM_keymap_verify_item(keymap, "VIEW3D_OT_manipulator", LEFTMOUSE, KM_PRESS, KM_ANY, 0); RNA_boolean_set(kmi->ptr, "release_confirm", TRUE); /* @@ -153,6 +252,7 @@ void view3d_keymap(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "VIEW3D_OT_rotate", MOUSEROTATE, 0, 0, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_move", MOUSEPAN, 0, 0, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", MOUSEZOOM, 0, 0, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", MOUSEPAN, 0, KM_CTRL, 0); /*numpad +/-*/ RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", PADPLUSKEY, KM_PRESS, 0, 0)->ptr, "delta", 1); @@ -170,6 +270,8 @@ void view3d_keymap(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "VIEW3D_OT_view_center_camera", HOMEKEY, KM_PRESS, 0, 0); /* only with camera view */ + WM_keymap_add_item(keymap, "VIEW3D_OT_view_center_cursor", HOMEKEY, KM_PRESS, KM_ALT, 0); + 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); @@ -226,29 +328,6 @@ void view3d_keymap(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD7, KM_PRESS, KM_SHIFT | KM_CTRL, 0); RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_BOTTOM); RNA_boolean_set(kmi->ptr, "align_active", TRUE); - - /* 3D mouse */ - WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_orbit", NDOF_MOTION, 0, KM_CTRL, 0); - WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_pan", NDOF_MOTION, 0, KM_SHIFT, 0); - WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_all", NDOF_MOTION, 0, 0, 0); - WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", NDOF_BUTTON_FIT, KM_PRESS, 0, 0); - RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT); - RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BACK, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BACK); - RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_LEFT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_LEFT); - RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_RIGHT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_RIGHT); - RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_TOP); - RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BOTTOM, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BOTTOM); - - /* 3D mouse align */ - kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, KM_SHIFT, 0); - RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_FRONT); - RNA_boolean_set(kmi->ptr, "align_active", TRUE); - kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_RIGHT, KM_PRESS, KM_SHIFT, 0); - RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_RIGHT); - RNA_boolean_set(kmi->ptr, "align_active", TRUE); - kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, KM_SHIFT, 0); - RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_TOP); - RNA_boolean_set(kmi->ptr, "align_active", TRUE); WM_keymap_add_item(keymap, "VIEW3D_OT_localview", PADSLASHKEY, KM_PRESS, 0, 0); @@ -359,6 +438,13 @@ void view3d_keymap(wmKeyConfig *keyconf) WM_keymap_add_menu(keymap, "VIEW3D_MT_snap", SKEY, KM_PRESS, KM_SHIFT, 0); +#ifdef __APPLE__ + WM_keymap_add_item(keymap, "VIEW3D_OT_copybuffer", CKEY, KM_PRESS, KM_OSKEY, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_pastebuffer", VKEY, KM_PRESS, KM_OSKEY, 0); +#endif + WM_keymap_add_item(keymap, "VIEW3D_OT_copybuffer", CKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_pastebuffer", VKEY, KM_PRESS, KM_CTRL, 0); + /* context ops */ kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", COMMAKEY, KM_PRESS, 0, 0); RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point"); diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 7f1bbb22f24..f570ec38ae3 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -340,9 +340,8 @@ static void make_trans_verts(Object *obedit, float min[3], float max[3], int mod } if (transvmain && em->derivedCage) { - EDBM_index_arrays_init(em, 1, 0, 0); + EDBM_index_arrays_ensure(em, BM_VERT); em->derivedCage->foreachMappedVert(em->derivedCage, set_mapped_co, userdata); - EDBM_index_arrays_free(em); } } else if (obedit->type == OB_ARMATURE) { diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index ef15c1e734e..56ce9bda607 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -161,7 +161,7 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera if (lens) sms.new_lens = *lens; if (camera) { - sms.new_dist = ED_view3d_offset_distance(camera->obmat, ofs); + sms.new_dist = ED_view3d_offset_distance(camera->obmat, ofs, VIEW3D_DIST_FALLBACK); ED_view3d_from_object(camera, sms.new_ofs, sms.new_quat, &sms.new_dist, &sms.new_lens); sms.to_camera = TRUE; /* restore view3d values in end */ } @@ -186,7 +186,7 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera /* original values */ if (oldcamera) { - sms.orig_dist = ED_view3d_offset_distance(oldcamera->obmat, rv3d->ofs); + sms.orig_dist = ED_view3d_offset_distance(oldcamera->obmat, rv3d->ofs, 0.0f); ED_view3d_from_object(oldcamera, sms.orig_ofs, sms.orig_quat, &sms.orig_dist, &sms.orig_lens); } else { @@ -579,7 +579,7 @@ void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], bglMats *mats, co } -int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[][4], BoundBox *bb) +int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[4][4], BoundBox *bb) { /* return 1: draw */ @@ -1530,7 +1530,7 @@ float ED_view3d_pixel_size(RegionView3D *rv3d, const float co[3]) rv3d->persmat[0][3] * co[0] + rv3d->persmat[1][3] * co[1] + rv3d->persmat[2][3] * co[2]) - ) * rv3d->pixsize; + ) * rv3d->pixsize * U.pixelsize; } float ED_view3d_radius_to_persp_dist(const float angle, const float radius) diff --git a/source/blender/editors/transform/SConscript b/source/blender/editors/transform/SConscript index 9cf36a2d970..d579fd73db3 100644 --- a/source/blender/editors/transform/SConscript +++ b/source/blender/editors/transform/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 6145fec7e51..65b29cf6475 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1585,14 +1585,17 @@ 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 *UNUSED(t), ARegion *ar) { + rcti rect; const char printable[] = "Auto Keying On"; float printable_size[2]; int xco, yco; + ED_region_visible_rect(ar, &rect); + BLF_width_and_height_default(printable, &printable_size[0], &printable_size[1]); - xco = ar->winx - (int)printable_size[0] - 10; - yco = ar->winy - (int)printable_size[1] - 10; + xco = rect.xmax - (int)printable_size[0] - 10; + yco = rect.ymax - (int)printable_size[1] - 10; /* warning text (to clarify meaning of overlays) * - original color was red to match the icon, but that clashes badly with a less nasty border @@ -2579,7 +2582,8 @@ int handleEventWarp(TransInfo *t, wmEvent *event) int Warp(TransInfo *t, const int UNUSED(mval[2])) { TransData *td = t->data; - float vec[3], circumfac, dist, phi0, co, si, *curs, cursor[3], gcursor[3]; + float vec[3], circumfac, dist, phi0, co, si, cursor[3], gcursor[3]; + const float *curs; int i; char str[50]; @@ -2884,7 +2888,7 @@ BLI_INLINE int tx_vec_sign_flip(const float a[3], const float b[3]) } /* smat is reference matrix, only scaled */ -static void TransMat3ToSize(float mat[][3], float smat[][3], float size[3]) +static void TransMat3ToSize(float mat[3][3], float smat[3][3], float size[3]) { float vec[3]; @@ -4903,7 +4907,7 @@ static int createSlideVerts(TransInfo *t) BMEdge *e, *e1; BMVert *v, *v2, *first; TransDataSlideVert *sv_array; - BMBVHTree *btree = BMBVH_NewBVH(em, BMBVH_RESPECT_HIDDEN, NULL, NULL); + BMBVHTree *btree; SmallHash table; SlideData *sld = MEM_callocN(sizeof(*sld), "sld"); View3D *v3d = NULL; @@ -4915,6 +4919,7 @@ static int createSlideVerts(TransInfo *t) float vec[3], vec2[3] /*, lastvec[3], size, dis=0.0, z */ /* UNUSED */; float dir[3], maxdist, (*loop_dir)[3], *loop_maxdist; int numsel, i, j, loop_nr, l_nr; + int use_btree_disp; if (t->spacetype == SPACE_VIEW3D) { /* background mode support */ @@ -4922,6 +4927,15 @@ static int createSlideVerts(TransInfo *t) rv3d = t->ar ? t->ar->regiondata : NULL; } + use_btree_disp = (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE); + + if (use_btree_disp) { + btree = BMBVH_NewBVH(em, BMBVH_RESPECT_HIDDEN, NULL, NULL); + } + else { + btree = NULL; + } + sld->is_proportional = TRUE; sld->curr_sv_index = 0; sld->flipped_vtx = FALSE; @@ -4955,7 +4969,8 @@ static int createSlideVerts(TransInfo *t) if (numsel == 0 || numsel > 2) { MEM_freeN(sld); - BMBVH_FreeBVH(btree); + if (btree) + BMBVH_FreeBVH(btree); return 0; /* invalid edge selection */ } } @@ -4965,7 +4980,8 @@ static int createSlideVerts(TransInfo *t) if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { if (!BM_edge_is_manifold(e)) { MEM_freeN(sld); - BMBVH_FreeBVH(btree); + if (btree) + BMBVH_FreeBVH(btree); return 0; /* can only handle exactly 2 faces around each edge */ } } @@ -4985,7 +5001,8 @@ static int createSlideVerts(TransInfo *t) if (!j) { MEM_freeN(sld); - BMBVH_FreeBVH(btree); + if (btree) + BMBVH_FreeBVH(btree); return 0; } @@ -5140,9 +5157,7 @@ static int createSlideVerts(TransInfo *t) continue; /* This test is only relevant if object is not wire-drawn! See [#32068]. */ - if (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE && - !BMBVH_EdgeVisible(btree, e2, ar, v3d, t->obedit)) - { + if (use_btree_disp && !BMBVH_EdgeVisible(btree, e2, ar, v3d, t->obedit)) { continue; } @@ -5244,10 +5259,15 @@ static int createSlideVerts(TransInfo *t) t->customData = sld; BLI_smallhash_release(&table); - BMBVH_FreeBVH(btree); + if (btree) { + BMBVH_FreeBVH(btree); + } MEM_freeN(loop_dir); MEM_freeN(loop_maxdist); - + + /* arrays are dirty from copying faces: EDBM_index_arrays_free */ + EDBM_update_generic(em, FALSE, TRUE); + return 1; } @@ -5419,6 +5439,9 @@ void freeSlideTempFaces(SlideData *sld) BLI_smallhash_release(&sld->origfaces); sld->origfaces_init = FALSE; + + /* arrays are dirty from removing faces: EDBM_index_arrays_free */ + EDBM_update_generic(sld->em, FALSE, TRUE); } } diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index bc959a772d6..08fe1e7676b 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -572,7 +572,7 @@ void flushTransTracking(TransInfo *t); void flushTransMasking(TransInfo *t); /*********************** exported from transform_manipulator.c ********** */ -int gimbal_axis(struct Object *ob, float gmat[][3]); /* return 0 when no gimbal for selection */ +int gimbal_axis(struct Object *ob, float gmat[3][3]); /* return 0 when no gimbal for selection */ int calc_manipulator_stats(const struct bContext *C); /*********************** TransData Creation and General Handling *********** */ diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 51efa2b0e40..7da47425370 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -113,6 +113,7 @@ #include "WM_types.h" #include "UI_view2d.h" +#include "UI_interface.h" #include "RNA_access.h" @@ -271,7 +272,7 @@ static void createTransTexspace(TransInfo *t) copy_m3_m4(td->mtx, ob->obmat); copy_m3_m4(td->axismtx, ob->obmat); normalize_m3(td->axismtx); - invert_m3_m3(td->smtx, td->mtx); + pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON); if (BKE_object_obdata_texspace_get(ob, &texflag, &td->loc, &td->ext->size, &td->ext->rot)) { ob->dtx |= OB_TEXSPACE; @@ -315,7 +316,7 @@ static void createTransEdge(TransInfo *t) td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransCrease"); copy_m3_m4(mtx, t->obedit->obmat); - invert_m3_m3(smtx, mtx); + pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && (BM_elem_flag_test(eed, BM_ELEM_SELECT) || propmode)) { @@ -552,7 +553,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr invert_m3_m3(td->ext->r_smtx, td->ext->r_mtx); } - invert_m3_m3(td->smtx, td->mtx); + pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON); /* exceptional case: rotate the pose bone which also applies transformation * when a parentless bone has BONE_NO_LOCAL_LOCATION [] */ @@ -604,7 +605,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr /* only object matrix correction */ copy_m3_m3(td->mtx, omat); - invert_m3_m3(td->smtx, td->mtx); + pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON); } } @@ -1053,7 +1054,7 @@ static void createTransArmatureVerts(TransInfo *t) if (!t->total) return; copy_m3_m4(mtx, t->obedit->obmat); - invert_m3_m3(smtx, mtx); + pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransEditBone"); @@ -1221,7 +1222,7 @@ static void createTransMBallVerts(TransInfo *t) tx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), "MetaElement_TransExtension"); copy_m3_m4(mtx, t->obedit->obmat); - invert_m3_m3(smtx, mtx); + pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); for (ml = mb->editelems->first; ml; ml = ml->next) { if (propmode || (ml->flag & SELECT)) { @@ -1378,7 +1379,7 @@ static void createTransCurveVerts(TransInfo *t) t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Curve EditMode)"); copy_m3_m4(mtx, t->obedit->obmat); - invert_m3_m3(smtx, mtx); + pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); td = t->data; for (nu = nurbs->first; nu; nu = nu->next) { @@ -1569,7 +1570,7 @@ static void createTransLatticeVerts(TransInfo *t) t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Lattice EditMode)"); copy_m3_m4(mtx, t->obedit->obmat); - invert_m3_m3(smtx, mtx); + pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); td = t->data; bp = latt->def; @@ -1769,7 +1770,7 @@ void flushTransParticles(TransInfo *t) * but instead it's a depth-first search, fudged * to report shortest distances. I have no idea how fast * or slow this is. */ -static void editmesh_set_connectivity_distance(BMEditMesh *em, float mtx[][3], float *dists) +static void editmesh_set_connectivity_distance(BMEditMesh *em, float mtx[3][3], float *dists) { BMVert **queue = NULL; float *dqueue = NULL; @@ -1927,7 +1928,7 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx } else if (t->mode == TFM_SHRINKFATTEN) { td->ext = tx; - tx->isize[0] = BM_vert_calc_shell_factor(eve); + tx->isize[0] = BM_vert_calc_shell_factor_ex(eve, BM_ELEM_SELECT); } } @@ -2051,7 +2052,9 @@ static void createTransEditVerts(TransInfo *t) } copy_m3_m4(mtx, t->obedit->obmat); - invert_m3_m3(smtx, mtx); + /* we use a pseudoinverse so that when one of the axes is scaled to 0, + * matrix inversion still works and we can still moving along the other */ + pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); if (propmode & T_PROP_CONNECTED) { editmesh_set_connectivity_distance(em, mtx, dists); @@ -2195,7 +2198,12 @@ void flushTransNodes(TransInfo *t) /* flush to 2d vector from internally used 3d vector */ for (a = 0, td = t->data, td2d = t->data2d; a < t->total; a++, td++, td2d++) { bNode *node = td->extra; - add_v2_v2v2(&node->locx, td2d->loc, td2d->ih1); + float vec[2]; + + /* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */ + add_v2_v2v2(vec, td2d->loc, td2d->ih1); + node->locx = vec[0] / UI_DPI_FAC; + node->locy = vec[1] / UI_DPI_FAC; } /* handle intersection with noodles */ @@ -5091,7 +5099,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) * during cleanup - psy-fi */ freeSlideTempFaces(sld); } - EDBM_automerge(t->scene, t->obedit, 1); + EDBM_automerge(t->scene, t->obedit, TRUE); } else { if (t->mode == TFM_EDGE_SLIDE) { @@ -5592,7 +5600,8 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node) /* hold original location */ float locxy[2] = {BLI_rctf_cent_x(&node->totr), BLI_rctf_cent_y(&node->totr)}; - + float nodeloc[2]; + copy_v2_v2(td2d->loc, locxy); td2d->loc[2] = 0.0f; td2d->loc2d = td2d->loc; /* current location */ @@ -5617,7 +5626,10 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node) unit_m3(td->mtx); unit_m3(td->smtx); - sub_v2_v2v2(td2d->ih1, &node->locx, locxy); + /* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */ + nodeloc[0] = UI_DPI_FAC * node->locx; + nodeloc[1] = UI_DPI_FAC * node->locy; + sub_v2_v2v2(td2d->ih1, nodeloc, locxy); td->extra = node; } diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 615bb786071..6d7ddd4e0ed 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1445,7 +1445,7 @@ void calculateCenter2D(TransInfo *t) void calculateCenterCursor(TransInfo *t) { - float *cursor; + const float *cursor; cursor = give_cursor(t->scene, t->view); copy_v3_v3(t->center, cursor); diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c index 7e05fdae364..69569251d01 100644 --- a/source/blender/editors/transform/transform_input.c +++ b/source/blender/editors/transform/transform_input.c @@ -397,12 +397,13 @@ int handleMouseInput(TransInfo *t, MouseInput *mi, wmEvent *event) * store the mouse position where the normal movement ended */ copy_v2_v2_int(mi->precision_mval, event->mval); mi->precision = 1; + redraw = TREDRAW_HARD; } - else { + else if (event->val == KM_RELEASE) { t->modifiers &= ~MOD_PRECISION; mi->precision = 0; + redraw = TREDRAW_HARD; } - redraw = TREDRAW_HARD; break; } diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index a3f45acc02e..6b016bf4303 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -148,10 +148,8 @@ static void stats_pose(Scene *scene, RegionView3D *rv3d, bPoseChannel *pchan) Bone *bone = pchan->bone; if (bone) { - if (bone->flag & BONE_TRANSFORM) { - calc_tw_center(scene, pchan->pose_head); - protectflag_to_drawflags(pchan->protectflag, &rv3d->twdrawflag); - } + calc_tw_center(scene, pchan->pose_head); + protectflag_to_drawflags(pchan->protectflag, &rv3d->twdrawflag); } } @@ -199,7 +197,7 @@ static int test_rotmode_euler(short rotmode) return (ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT)) ? 0 : 1; } -int gimbal_axis(Object *ob, float gmat[][3]) +int gimbal_axis(Object *ob, float gmat[3][3]) { if (ob) { if (ob->mode & OB_MODE_POSE) { @@ -361,18 +359,35 @@ int calc_manipulator_stats(const bContext *C) else if (obedit->type == OB_ARMATURE) { bArmature *arm = obedit->data; EditBone *ebo; - for (ebo = arm->edbo->first; ebo; ebo = ebo->next) { - if (EBONE_VISIBLE(arm, ebo)) { - if (ebo->flag & BONE_TIPSEL) { - calc_tw_center(scene, ebo->tail); - totsel++; - } - if (ebo->flag & BONE_ROOTSEL) { - calc_tw_center(scene, ebo->head); - totsel++; - } - if (ebo->flag & BONE_SELECTED) { - stats_editbone(rv3d, ebo); + + if ((v3d->around == V3D_ACTIVE) && (ebo = arm->act_edbone)) { + /* doesn't check selection or visibility intentionally */ + if (ebo->flag & BONE_TIPSEL) { + calc_tw_center(scene, ebo->tail); + totsel++; + } + if ((ebo->flag & BONE_ROOTSEL) || + ((ebo->flag & BONE_TIPSEL) == FALSE)) /* ensure we get at least one point */ + { + calc_tw_center(scene, ebo->head); + totsel++; + } + stats_editbone(rv3d, ebo); + } + else { + for (ebo = arm->edbo->first; ebo; ebo = ebo->next) { + if (EBONE_VISIBLE(arm, ebo)) { + if (ebo->flag & BONE_TIPSEL) { + calc_tw_center(scene, ebo->tail); + totsel++; + } + if (ebo->flag & BONE_ROOTSEL) { + calc_tw_center(scene, ebo->head); + totsel++; + } + if (ebo->flag & BONE_SELECTED) { + stats_editbone(rv3d, ebo); + } } } } @@ -480,17 +495,35 @@ int calc_manipulator_stats(const bContext *C) else if (ob && (ob->mode & OB_MODE_POSE)) { bPoseChannel *pchan; int mode = TFM_ROTATION; // mislead counting bones... bah. We don't know the manipulator mode, could be mixed + int ok = FALSE; if ((ob->lay & v3d->lay) == 0) return 0; - totsel = count_set_pose_transflags(&mode, 0, ob); - - if (totsel) { - /* use channels to get stats */ - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + if ((v3d->around == V3D_ACTIVE) && (pchan = BKE_pose_channel_active(ob))) { + /* doesn't check selection or visibility intentionally */ + Bone *bone = pchan->bone; + if (bone) { stats_pose(scene, rv3d, pchan); + totsel = 1; + ok = TRUE; + } + } + else { + totsel = count_set_pose_transflags(&mode, 0, ob); + + if (totsel) { + /* use channels to get stats */ + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + Bone *bone = pchan->bone; + if (bone && (bone->flag & BONE_TRANSFORM)) { + stats_pose(scene, rv3d, pchan); + } + } + ok = TRUE; } + } + if (ok) { mul_v3_fl(scene->twcent, 1.0f / (float)totsel); // centroid! mul_m4_v3(ob->obmat, scene->twcent); mul_m4_v3(ob->obmat, scene->twmin); @@ -552,8 +585,9 @@ int calc_manipulator_stats(const bContext *C) switch (v3d->twmode) { case V3D_MANIP_GLOBAL: + { break; /* nothing to do */ - + } case V3D_MANIP_GIMBAL: { float mat[3][3]; @@ -562,28 +596,43 @@ int calc_manipulator_stats(const bContext *C) break; } /* if not gimbal, fall through to normal */ + /* pass through */ } case V3D_MANIP_NORMAL: + { if (obedit || ob->mode & OB_MODE_POSE) { float mat[3][3]; ED_getTransformOrientationMatrix(C, mat, (v3d->around == V3D_ACTIVE)); copy_m4_m3(rv3d->twmat, mat); break; } - /* no break we define 'normal' as 'local' in Object mode */ + /* no break we define 'normal' as 'local' in Object mode */ + /* pass through */ + } case V3D_MANIP_LOCAL: + { + if (ob->mode & OB_MODE_POSE) { + /* each bone moves on its own local axis, but to avoid confusion, + * use the active pones axis for display [#33575], this works as expected on a single bone + * and users who select many bones will understand whats going on and what local means + * when they start transforming */ + float mat[3][3]; + ED_getTransformOrientationMatrix(C, mat, (v3d->around == V3D_ACTIVE)); + copy_m4_m3(rv3d->twmat, mat); + break; + } copy_m4_m4(rv3d->twmat, ob->obmat); normalize_m4(rv3d->twmat); break; - + } case V3D_MANIP_VIEW: { float mat[3][3]; copy_m3_m4(mat, rv3d->viewinv); normalize_m3(mat); copy_m4_m3(rv3d->twmat, mat); + break; } - break; default: /* V3D_MANIP_CUSTOM */ { float mat[3][3]; @@ -638,7 +687,7 @@ static void test_manipulator_axis(const bContext *C) /* ******************** DRAWING STUFFIES *********** */ -static float screen_aligned(RegionView3D *rv3d, float mat[][4]) +static float screen_aligned(RegionView3D *rv3d, float mat[4][4]) { glTranslatef(mat[3][0], mat[3][1], mat[3][2]); @@ -826,7 +875,7 @@ static void draw_manipulator_axes(View3D *v3d, RegionView3D *rv3d, int colcode, } } -static void preOrthoFront(int ortho, float twmat[][4], int axis) +static void preOrthoFront(int ortho, float twmat[4][4], int axis) { if (ortho == 0) { float omat[4][4]; diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 70e4d4cd027..c9c4f7e2c7b 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -43,6 +43,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BKE_action.h" #include "BKE_armature.h" #include "BKE_curve.h" #include "BKE_context.h" @@ -437,7 +438,7 @@ int BIF_countTransformOrientation(const bContext *C) return count; } -void applyTransformOrientation(const bContext *C, float mat[3][3], char *name) +void applyTransformOrientation(const bContext *C, float mat[3][3], char name[MAX_NAME]) { TransformOrientation *ts; View3D *v3d = CTX_wm_view3d(C); @@ -448,8 +449,9 @@ void applyTransformOrientation(const bContext *C, float mat[3][3], char *name) for (i = 0, ts = CTX_data_scene(C)->transform_spaces.first; ts; ts = ts->next, i++) { if (selected_index == i) { - if (name) - strcpy(name, ts->name); + if (name) { + BLI_strncpy(name, ts->name, MAX_NAME); + } copy_m3_m3(mat, ts->mat); break; @@ -737,7 +739,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], } } - if (normal[0] != 0 || normal[1] != 0 || normal[2] != 0) { + if (!is_zero_v3(normal)) { result = ORIENTATION_NORMAL; } } @@ -760,29 +762,45 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], else if (obedit->type == OB_ARMATURE) { bArmature *arm = obedit->data; EditBone *ebone; + int ok = FALSE; - for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - if (arm->layer & ebone->layer) { - if (ebone->flag & BONE_SELECTED) { - float tmat[3][3]; - float vec[3]; - sub_v3_v3v3(vec, ebone->tail, ebone->head); - normalize_v3(vec); - add_v3_v3(normal, vec); - - vec_roll_to_mat3(vec, ebone->roll, tmat); - add_v3_v3(plane, tmat[2]); + /* grr,.but better then duplicate code */ +#define EBONE_CALC_NORMAL_PLANE { \ + float tmat[3][3]; \ + float vec[3]; \ + sub_v3_v3v3(vec, ebone->tail, ebone->head); \ + normalize_v3(vec); \ + add_v3_v3(normal, vec); \ + \ + vec_roll_to_mat3(vec, ebone->roll, tmat); \ + add_v3_v3(plane, tmat[2]); \ + } (void)0 + + + if (activeOnly && (ebone = arm->act_edbone)) { + EBONE_CALC_NORMAL_PLANE; + ok = TRUE; + } + else { + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + if (arm->layer & ebone->layer) { + if (ebone->flag & BONE_SELECTED) { + EBONE_CALC_NORMAL_PLANE; + ok = TRUE; + } } } } - normalize_v3(normal); - normalize_v3(plane); + if (ok) { + normalize_v3(normal); + normalize_v3(plane); - if (plane[0] != 0 || plane[1] != 0 || plane[2] != 0) { - result = ORIENTATION_EDGE; + if (!is_zero_v3(plane)) { + result = ORIENTATION_EDGE; + } } - +#undef EBONE_CALC_NORMAL_PLANE } /* Vectors from edges don't need the special transpose inverse multiplication */ @@ -798,19 +816,32 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], else if (ob && (ob->mode & OB_MODE_POSE)) { bArmature *arm = ob->data; bPoseChannel *pchan; - int totsel; - - totsel = count_bone_select(arm, &arm->bonebase, 1); - if (totsel) { - float imat[3][3], mat[3][3]; - - /* use channels to get stats */ - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) { - add_v3_v3(normal, pchan->pose_mat[2]); - add_v3_v3(plane, pchan->pose_mat[1]); + float imat[3][3], mat[3][3]; + int ok = FALSE; + + if (activeOnly && (pchan = BKE_pose_channel_active(ob))) { + add_v3_v3(normal, pchan->pose_mat[2]); + add_v3_v3(plane, pchan->pose_mat[1]); + ok = TRUE; + } + else { + int totsel; + + totsel = count_bone_select(arm, &arm->bonebase, 1); + if (totsel) { + /* use channels to get stats */ + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) { + add_v3_v3(normal, pchan->pose_mat[2]); + add_v3_v3(plane, pchan->pose_mat[1]); + } } + ok = TRUE; } + } + + /* use for both active & all */ + if (ok) { negate_v3(plane); /* we need the transpose of the inverse for a normal... */ @@ -851,7 +882,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], return result; } -void ED_getTransformOrientationMatrix(const bContext *C, float orientation_mat[][3], int activeOnly) +void ED_getTransformOrientationMatrix(const bContext *C, float orientation_mat[3][3], int activeOnly) { float normal[3] = {0.0, 0.0, 0.0}; float plane[3] = {0.0, 0.0, 0.0}; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 2d95e2ecdc6..5577619901a 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -1141,7 +1141,7 @@ static void TargetSnapClosest(TransInfo *t) } } -static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], float obmat[][4], float timat[][3], +static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], float obmat[4][4], float timat[3][3], const float ray_start[3], const float ray_start_local[3], const float ray_normal_local[3], const float mval[2], float r_loc[3], float r_no[3], int *r_dist, float *r_depth) { @@ -1228,7 +1228,7 @@ static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], sh return retval; } -static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[][4], float timat[][3], +static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[4][4], float timat[3][3], const float ray_start[3], const float ray_start_local[3], const float ray_normal_local[3], const float mval[2], float r_loc[3], float r_no[3], int *r_dist, float *r_depth) { @@ -1276,7 +1276,7 @@ static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[][4], return retval; } -static int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[][4], +static int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[4][4], const float ray_start[3], const float ray_normal[3], const float mval[2], float r_loc[3], float *UNUSED(r_no), int *r_dist, float *r_depth) { @@ -1339,7 +1339,7 @@ static int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm return retval; } -static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, BMEditMesh *em, float obmat[][4], +static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, BMEditMesh *em, float obmat[4][4], const float ray_start[3], const float ray_normal[3], const float mval[2], float r_loc[3], float r_no[3], int *r_dist, float *r_depth) { @@ -1417,7 +1417,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh if (em != NULL) { index_array = dm->getVertDataArray(dm, CD_ORIGINDEX); - EDBM_index_arrays_init(em, 1, 0, 0); + EDBM_index_arrays_ensure(em, BM_VERT); } for (i = 0; i < totvert; i++) { @@ -1452,9 +1452,6 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh } } - if (em != NULL) { - EDBM_index_arrays_free(em); - } break; } case SCE_SNAP_MODE_EDGE: @@ -1468,7 +1465,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh if (em != NULL) { index_array = dm->getEdgeDataArray(dm, CD_ORIGINDEX); - EDBM_index_arrays_init(em, 0, 1, 0); + EDBM_index_arrays_ensure(em, BM_EDGE); } for (i = 0; i < totedge; i++) { @@ -1505,9 +1502,6 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh } } - if (em != NULL) { - EDBM_index_arrays_free(em); - } break; } } @@ -1517,7 +1511,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh return retval; } -static int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[][4], +static int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[4][4], const float ray_start[3], const float ray_normal[3], const float mval[2], float r_loc[3], float r_no[3], int *r_dist, float *r_depth) { @@ -1670,7 +1664,7 @@ static void addDepthPeel(ListBase *depth_peels, float depth, float p[3], float n peel->flag = 0; } -static int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], +static int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[4][4], const float ray_start[3], const float ray_normal[3], const float UNUSED(mval[2]), ListBase *depth_peels) { diff --git a/source/blender/editors/util/SConscript b/source/blender/editors/util/SConscript index 74879e54850..1c1a8e46dd7 100644 --- a/source/blender/editors/util/SConscript +++ b/source/blender/editors/util/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/uvedit/SConscript b/source/blender/editors/uvedit/SConscript index d236b18a8fd..01316680d5d 100644 --- a/source/blender/editors/uvedit/SConscript +++ b/source/blender/editors/uvedit/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** 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) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index 9c2c300c530..607640090aa 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -60,48 +60,49 @@ #include "ED_uvedit.h" #include "UI_resources.h" +#include "UI_interface.h" +#include "UI_view2d.h" #include "uvedit_intern.h" void draw_image_cursor(SpaceImage *sima, ARegion *ar) { - float zoomx, zoomy, w, h; - int width, height; + float zoom[2], x_fac, y_fac; - ED_space_image_get_size(sima, &width, &height); - ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy); + UI_view2d_getscale_inverse(&ar->v2d, &zoom[0], &zoom[1]); - w = zoomx * width / 256.0f; - h = zoomy * height / 256.0f; + mul_v2_fl(zoom, 256.0f * UI_DPI_FAC); + x_fac = zoom[0]; + y_fac = zoom[1]; cpack(0xFFFFFF); glTranslatef(sima->cursor[0], sima->cursor[1], 0.0); - fdrawline(-0.05f / w, 0, 0, 0.05f / h); - fdrawline(0, 0.05f / h, 0.05f / w, 0.0f); - fdrawline(0.05f / w, 0.0f, 0.0f, -0.05f / h); - fdrawline(0.0f, -0.05f / h, -0.05f / w, 0.0f); + fdrawline(-0.05f * x_fac, 0, 0, 0.05f * y_fac); + fdrawline(0, 0.05f * y_fac, 0.05f * x_fac, 0.0f); + fdrawline(0.05f * x_fac, 0.0f, 0.0f, -0.05f * y_fac); + fdrawline(0.0f, -0.05f * y_fac, -0.05f * x_fac, 0.0f); setlinestyle(4); cpack(0xFF); - fdrawline(-0.05f / w, 0.0f, 0.0f, 0.05f / h); - fdrawline(0.0f, 0.05f / h, 0.05f / w, 0.0f); - fdrawline(0.05f / w, 0.0f, 0.0f, -0.05f / h); - fdrawline(0.0f, -0.05f / h, -0.05f / w, 0.0f); + fdrawline(-0.05f * x_fac, 0.0f, 0.0f, 0.05f * y_fac); + fdrawline(0.0f, 0.05f * y_fac, 0.05f * x_fac, 0.0f); + fdrawline(0.05f * x_fac, 0.0f, 0.0f, -0.05f * y_fac); + fdrawline(0.0f, -0.05f * y_fac, -0.05f * x_fac, 0.0f); setlinestyle(0.0f); cpack(0x0); - fdrawline(-0.020f / w, 0.0f, -0.1f / w, 0.0f); - fdrawline(0.1f / w, 0.0f, 0.020f / w, 0.0f); - fdrawline(0.0f, -0.020f / h, 0.0f, -0.1f / h); - fdrawline(0.0f, 0.1f / h, 0.0f, 0.020f / h); + fdrawline(-0.020f * x_fac, 0.0f, -0.1f * x_fac, 0.0f); + fdrawline(0.1f * x_fac, 0.0f, 0.020f * x_fac, 0.0f); + fdrawline(0.0f, -0.020f * y_fac, 0.0f, -0.1f * y_fac); + fdrawline(0.0f, 0.1f * y_fac, 0.0f, 0.020f * y_fac); setlinestyle(1); cpack(0xFFFFFF); - fdrawline(-0.020f / w, 0.0f, -0.1f / w, 0.0f); - fdrawline(0.1f / w, 0.0f, 0.020f / w, 0.0f); - fdrawline(0.0f, -0.020f / h, 0.0f, -0.1f / h); - fdrawline(0.0f, 0.1f / h, 0.0f, 0.020f / h); + fdrawline(-0.020f * x_fac, 0.0f, -0.1f * x_fac, 0.0f); + fdrawline(0.1f * x_fac, 0.0f, 0.020f * x_fac, 0.0f); + fdrawline(0.0f, -0.020f * y_fac, 0.0f, -0.1f * y_fac); + fdrawline(0.0f, 0.1f * y_fac, 0.0f, 0.020f * y_fac); glTranslatef(-sima->cursor[0], -sima->cursor[1], 0.0); setlinestyle(0); @@ -169,10 +170,8 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe MTexPoly *tf; MLoopUV *luv; Image *ima = sima->image; - BLI_array_declare(tf_uv); - BLI_array_declare(tf_uvorig); - float aspx, aspy, col[4], (*tf_uv)[2] = NULL, (*tf_uvorig)[2] = NULL; - int i, j, nverts; + float aspx, aspy, col[4]; + int i; ED_space_image_get_uv_aspect(sima, &aspx, &aspy); @@ -182,20 +181,14 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe float totarea = 0.0f, totuvarea = 0.0f, areadiff, uvarea, area; BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { + const int efa_len = efa->len; + float (*tf_uv)[2] = BLI_array_alloca(tf_uv, efa_len); + float (*tf_uvorig)[2] = BLI_array_alloca(tf_uvorig, efa_len); tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY); - - BLI_array_empty(tf_uv); - BLI_array_empty(tf_uvorig); - BLI_array_grow_items(tf_uv, efa->len); - BLI_array_grow_items(tf_uvorig, efa->len); - i = 0; - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); - copy_v2_v2(tf_uvorig[i], luv->uv); - - i++; } uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len); @@ -232,20 +225,15 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe else { BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { - area = BM_face_calc_area(efa) / totarea; + const int efa_len = efa->len; + float (*tf_uv)[2] = BLI_array_alloca(tf_uv, efa_len); + float (*tf_uvorig)[2] = BLI_array_alloca(tf_uvorig, efa_len); - BLI_array_empty(tf_uv); - BLI_array_empty(tf_uvorig); - BLI_array_grow_items(tf_uv, efa->len); - BLI_array_grow_items(tf_uvorig, efa->len); + area = BM_face_calc_area(efa) / totarea; - i = 0; - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); - copy_v2_v2(tf_uvorig[i], luv->uv); - - i++; } uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len); @@ -276,18 +264,9 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe } case SI_UVDT_STRETCH_ANGLE: { - float *uvang = NULL; - float *ang = NULL; - float (*av)[3] = NULL; /* use for 2d and 3d angle vectors */ - float (*auv)[2] = NULL; float a; - BLI_array_declare(uvang); - BLI_array_declare(ang); - BLI_array_declare(av); - BLI_array_declare(auv); - - col[3] = 0.5; /* hard coded alpha, not that nice */ + col[3] = 0.5f; /* hard coded alpha, not that nice */ glShadeModel(GL_SMOOTH); @@ -295,44 +274,40 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY); if (uvedit_face_visible_test(scene, ima, efa, tf)) { - nverts = efa->len; + const int efa_len = efa->len; + float (*tf_uv)[2] = BLI_array_alloca(tf_uv, efa_len); + float (*tf_uvorig)[2] = BLI_array_alloca(tf_uvorig, efa_len); + float *uvang = BLI_array_alloca(uvang, efa_len); + float *ang = BLI_array_alloca(ang, efa_len); + float (*av)[3] = BLI_array_alloca(av, efa_len); /* use for 2d and 3d angle vectors */ + float (*auv)[2] = BLI_array_alloca(auv, efa_len); + int j; + BM_elem_flag_enable(efa, BM_ELEM_TAG); - BLI_array_empty(tf_uv); - BLI_array_empty(tf_uvorig); - BLI_array_empty(uvang); - BLI_array_empty(ang); - BLI_array_empty(av); - BLI_array_empty(auv); - BLI_array_grow_items(tf_uv, nverts); - BLI_array_grow_items(tf_uvorig, nverts); - BLI_array_grow_items(uvang, nverts); - BLI_array_grow_items(ang, nverts); - BLI_array_grow_items(av, nverts); - BLI_array_grow_items(auv, nverts); BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); copy_v2_v2(tf_uvorig[i], luv->uv); } - uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, nverts); + uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa_len); - j = nverts - 1; + j = efa_len - 1; BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { sub_v2_v2v2(auv[i], tf_uv[j], tf_uv[i]); normalize_v2(auv[i]); sub_v3_v3v3(av[i], l->prev->v->co, l->v->co); normalize_v3(av[i]); j = i; } - for (i = 0; i < nverts; i++) { + for (i = 0; i < efa_len; i++) { #if 0 /* Simple but slow, better reuse normalized vectors * (Not ported to bmesh, copied for reference) */ uvang1 = RAD2DEG(angle_v2v2v2(tf_uv[3], tf_uv[0], tf_uv[1])); ang1 = RAD2DEG(angle_v3v3v3(efa->v4->co, efa->v1->co, efa->v2->co)); #endif - uvang[i] = angle_normalized_v2v2(auv[i], auv[(i + 1) % nverts]); - ang[i] = angle_normalized_v3v3(av[i], av[(i + 1) % nverts]); + uvang[i] = angle_normalized_v2v2(auv[i], auv[(i + 1) % efa_len]); + ang[i] = angle_normalized_v3v3(av[i], av[(i + 1) % efa_len]); } glBegin(GL_POLYGON); @@ -354,17 +329,9 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe glShadeModel(GL_FLAT); - BLI_array_free(uvang); - BLI_array_free(ang); - BLI_array_free(av); - BLI_array_free(auv); - break; } } - - BLI_array_free(tf_uv); - BLI_array_free(tf_uvorig); } static void draw_uvs_other(Scene *scene, Object *obedit, Image *curimage) diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index b42875f20c2..27bbba11e75 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -51,7 +51,7 @@ int uvedit_face_visible_nolocal(struct Scene *scene, struct BMFace *efa); /* geometric utilities */ float uv_poly_area(float uv[][2], int len); -void uv_poly_copy_aspect(float uv_orig [][2], float uv[][2], float aspx, float aspy, int len); +void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len); void uv_poly_center(struct BMEditMesh *em, struct BMFace *f, float r_cent[2]); /* find nearest */ diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index a384c777aab..4336eb02752 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -999,8 +999,8 @@ static int select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestHit int a, looking, nverts, starttotf, select; /* setup */ - EDBM_index_arrays_init(em, 0, 0, 1); - vmap = EDBM_uv_vert_map_create(em, 0, 0, limit); + EDBM_index_arrays_ensure(em, BM_FACE); + vmap = EDBM_uv_vert_map_create(em, 0, limit); BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE); @@ -1091,7 +1091,6 @@ static int select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestHit /* cleanup */ EDBM_uv_vert_map_free(vmap); - EDBM_index_arrays_free(em); return (select) ? 1 : -1; } @@ -1111,8 +1110,8 @@ static void select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float unsigned int a; char *flag; - EDBM_index_arrays_init(em, 0, 0, 1); /* we can use this too */ - vmap = EDBM_uv_vert_map_create(em, 1, 1, limit); + EDBM_index_arrays_ensure(em, BM_FACE); /* we can use this too */ + vmap = EDBM_uv_vert_map_create(em, 1, limit); if (vmap == NULL) return; @@ -1270,7 +1269,6 @@ static void select_linked(Scene *scene, Image *ima, BMEditMesh *em, const float MEM_freeN(stack); MEM_freeN(flag); EDBM_uv_vert_map_free(vmap); - EDBM_index_arrays_free(em); } /* WATCH IT: this returns first selected UV, @@ -2608,8 +2606,8 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s uvedit_pixel_to_float(sima, limit, 0.05); - EDBM_index_arrays_init(em, 0, 0, 1); - vmap = EDBM_uv_vert_map_create(em, 0, 0, limit); + EDBM_index_arrays_ensure(em, BM_FACE); + vmap = EDBM_uv_vert_map_create(em, 0, limit); /* verts are numbered above in make_uv_vert_map_EM, make sure this stays true! */ if (vmap == NULL) { @@ -2662,7 +2660,6 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s } } } - EDBM_index_arrays_free(em); EDBM_uv_vert_map_free(vmap); } @@ -3795,8 +3792,8 @@ static int seams_from_islands_exec(bContext *C, wmOperator *op) } /* This code sets editvert->tmp.l to the index. This will be useful later on. */ - EDBM_index_arrays_init(em, 0, 0, 1); - vmap = EDBM_uv_vert_map_create(em, 0, 0, limit); + EDBM_index_arrays_ensure(em, BM_FACE); + vmap = EDBM_uv_vert_map_create(em, 0, limit); BM_ITER_MESH (editedge, &iter, bm, BM_EDGES_OF_MESH) { /* flags to determine if we uv is separated from first editface match */ @@ -3875,7 +3872,6 @@ static int seams_from_islands_exec(bContext *C, wmOperator *op) me->drawflag |= ME_DRAWSEAMS; EDBM_uv_vert_map_free(vmap); - EDBM_index_arrays_free(em); DAG_id_tag_update(&me->id, 0); WM_event_add_notifier(C, NC_GEOM | ND_DATA, me); diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 4ca642690c4..bd50857c8b8 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -72,7 +72,7 @@ /* ********************** smart stitch operator *********************** */ -/* object that stores display data for previewing before accepting stitching */ +/* object that stores display data for previewing before confirming stitching */ typedef struct StitchPreviewer { /* here we'll store the preview triangle indices of the mesh */ float *preview_polys; @@ -87,7 +87,7 @@ typedef struct StitchPreviewer { unsigned int num_stitchable; unsigned int num_unstitchable; unsigned int preview_uvs; - /* ...and here we'll store the triangles*/ + /* ...and here we'll store the static island triangles*/ float *static_tris; unsigned int num_static_tris; } StitchPreviewer; @@ -124,9 +124,13 @@ typedef struct UvEdge { unsigned int uv1; unsigned int uv2; /* general use flag (Used to check if edge is boundary here, and propagates to adjacency elements) */ - char flag; - /* element that guarantees element->face has the face on element->tfindex and element->tfindex+1 is the second uv */ + unsigned char flag; + /* element that guarantees element->face has the edge on element->tfindex and element->tfindex+1 is the second uv */ UvElement *element; + /* next uv edge with the same exact vertices as this one.. Calculated at startup to save time */ + struct UvEdge *next; + /* point to first of common edges. Needed for iteration */ + struct UvEdge *first; } UvEdge; @@ -156,19 +160,26 @@ typedef struct StitchState { float *normals; /* edge storage */ UvEdge *edges; + /* hash for quick lookup of edges */ + GHash *edge_hash; /* count of separate uvs and edges */ - int total_boundary_edges; + int total_separate_edges; int total_separate_uvs; /* hold selection related information */ - UvElement **selection_stack; + void **selection_stack; int selection_size; /* island that stays in place */ int static_island; /* store number of primitives per face so that we can allocate the active island buffer later */ unsigned int *tris_per_island; + /* vert or edge mode used for stitching */ + char mode; + /* handle for drawing */ void *draw_handle; + /* preview data */ + StitchPreviewer *stitch_preview; } StitchState; typedef struct PreviewPosition { @@ -176,7 +187,7 @@ typedef struct PreviewPosition { int polycount_position; } PreviewPosition; /* - * defines for UvElement flags + * defines for UvElement/UcEdge flags */ #define STITCH_SELECTED 1 #define STITCH_STITCHABLE 2 @@ -186,83 +197,79 @@ typedef struct PreviewPosition { #define STITCH_NO_PREVIEW -1 -/* previewer stuff (see uvedit_intern.h for more info) */ -static StitchPreviewer *_stitch_preview; +enum StitchModes { + STITCH_VERT, + STITCH_EDGE +}; /* constructor */ static StitchPreviewer *stitch_preview_init(void) { - _stitch_preview = MEM_mallocN(sizeof(StitchPreviewer), "stitch_previewer"); - _stitch_preview->preview_polys = NULL; - _stitch_preview->preview_stitchable = NULL; - _stitch_preview->preview_unstitchable = NULL; - _stitch_preview->uvs_per_polygon = NULL; + StitchPreviewer *stitch_preview; - _stitch_preview->preview_uvs = 0; - _stitch_preview->num_polys = 0; - _stitch_preview->num_stitchable = 0; - _stitch_preview->num_unstitchable = 0; + stitch_preview = MEM_mallocN(sizeof(StitchPreviewer), "stitch_previewer"); + stitch_preview->preview_polys = NULL; + stitch_preview->preview_stitchable = NULL; + stitch_preview->preview_unstitchable = NULL; + stitch_preview->uvs_per_polygon = NULL; - _stitch_preview->static_tris = NULL; + stitch_preview->preview_uvs = 0; + stitch_preview->num_polys = 0; + stitch_preview->num_stitchable = 0; + stitch_preview->num_unstitchable = 0; - _stitch_preview->num_static_tris = 0; + stitch_preview->static_tris = NULL; - return _stitch_preview; + stitch_preview->num_static_tris = 0; + + return stitch_preview; } /* destructor...yeah this should be C++ :) */ -static void stitch_preview_delete(void) +static void stitch_preview_delete(StitchPreviewer *stitch_preview) { - if (_stitch_preview) { - if (_stitch_preview->preview_polys) { - MEM_freeN(_stitch_preview->preview_polys); - _stitch_preview->preview_polys = NULL; + if (stitch_preview) { + if (stitch_preview->preview_polys) { + MEM_freeN(stitch_preview->preview_polys); + stitch_preview->preview_polys = NULL; } - if (_stitch_preview->uvs_per_polygon) { - MEM_freeN(_stitch_preview->uvs_per_polygon); - _stitch_preview->uvs_per_polygon = NULL; + if (stitch_preview->uvs_per_polygon) { + MEM_freeN(stitch_preview->uvs_per_polygon); + stitch_preview->uvs_per_polygon = NULL; } - if (_stitch_preview->preview_stitchable) { - MEM_freeN(_stitch_preview->preview_stitchable); - _stitch_preview->preview_stitchable = NULL; + if (stitch_preview->preview_stitchable) { + MEM_freeN(stitch_preview->preview_stitchable); + stitch_preview->preview_stitchable = NULL; } - if (_stitch_preview->preview_unstitchable) { - MEM_freeN(_stitch_preview->preview_unstitchable); - _stitch_preview->preview_unstitchable = NULL; + if (stitch_preview->preview_unstitchable) { + MEM_freeN(stitch_preview->preview_unstitchable); + stitch_preview->preview_unstitchable = NULL; } - if (_stitch_preview->static_tris) { - MEM_freeN(_stitch_preview->static_tris); - _stitch_preview->static_tris = NULL; + if (stitch_preview->static_tris) { + MEM_freeN(stitch_preview->static_tris); + stitch_preview->static_tris = NULL; } - - MEM_freeN(_stitch_preview); - _stitch_preview = NULL; + MEM_freeN(stitch_preview); } } - -/* "getter method" */ -static StitchPreviewer *uv_get_stitch_previewer(void) -{ - return _stitch_preview; -} - #define HEADER_LENGTH 256 /* This function updates the header of the UV editor when the stitch tool updates its settings */ -static void stitch_update_header(StitchState *stitch_state, bContext *C) +static void stitch_update_header(StitchState *state, bContext *C) { - static char str[] = "(S)nap %s, (M)idpoints %s, (L)imit %.2f (Alt Wheel adjust) %s, Switch (I)sland, shift select vertices"; + static char str[] = "Mode(TAB) %s, (S)nap %s, (M)idpoints %s, (L)imit %.2f (Alt Wheel adjust) %s, Switch (I)sland, shift select vertices"; char msg[HEADER_LENGTH]; ScrArea *sa = CTX_wm_area(C); if (sa) { BLI_snprintf(msg, HEADER_LENGTH, str, - stitch_state->snap_islands ? "On" : "Off", - stitch_state->midpoints ? "On" : "Off", - stitch_state->limit_dist, - stitch_state->use_limit ? "On" : "Off"); + state->mode == STITCH_VERT ? "Vertex" : "Edge", + state->snap_islands ? "On" : "Off", + state->midpoints ? "On" : "Off", + state->limit_dist, + state->use_limit ? "On" : "Off"); ED_area_headerprint(sa, msg); } @@ -292,30 +299,29 @@ static void stitch_uv_rotate(float rotation, float medianPoint[2], float uv[2]) uv[1] = uv_rotation_result[1] + medianPoint[1]; } +/* check if two uvelements are stitchable. This should only operate on -different- separate UvElements */ static int stitch_check_uvs_stitchable(UvElement *element, UvElement *element_iter, StitchState *state) { float limit; - int do_limit; if (element_iter == element) { return 0; } limit = state->limit_dist; - do_limit = state->use_limit; - if (do_limit) { - MLoopUV *luv_orig, *luv_iter; - BMLoop *l_orig, *l_iter; + if (state->use_limit) { + MLoopUV *luv, *luv_iter; + BMLoop *l; - l_orig = element->l; - luv_orig = CustomData_bmesh_get(&state->em->bm->ldata, l_orig->head.data, CD_MLOOPUV); - l_iter = element_iter->l; - luv_iter = CustomData_bmesh_get(&state->em->bm->ldata, l_iter->head.data, CD_MLOOPUV); + l = element->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + l = element_iter->l; + luv_iter = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); - if (fabsf(luv_orig->uv[0] - luv_iter->uv[0]) < limit && - fabsf(luv_orig->uv[1] - luv_iter->uv[1]) < limit) + if (fabsf(luv->uv[0] - luv_iter->uv[0]) < limit && + fabsf(luv->uv[1] - luv_iter->uv[1]) < limit) { return 1; } @@ -328,6 +334,46 @@ static int stitch_check_uvs_stitchable(UvElement *element, UvElement *element_it } } +static int stitch_check_edges_stitchable(UvEdge *edge, UvEdge *edge_iter, StitchState *state) +{ + float limit; + + if (edge_iter == edge) { + return 0; + } + + limit = state->limit_dist; + + if (state->use_limit) { + BMLoop *l; + MLoopUV *luv_orig1, *luv_iter1; + MLoopUV *luv_orig2, *luv_iter2; + + l = state->uvs[edge->uv1]->l; + luv_orig1 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + l = state->uvs[edge_iter->uv1]->l; + luv_iter1 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + + l = state->uvs[edge->uv2]->l; + luv_orig2 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + l = state->uvs[edge_iter->uv2]->l; + luv_iter2 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + + if (fabsf(luv_orig1->uv[0] - luv_iter1->uv[0]) < limit && + fabsf(luv_orig1->uv[1] - luv_iter1->uv[1]) < limit && + fabsf(luv_orig2->uv[0] - luv_iter2->uv[0]) < limit && + fabsf(luv_orig2->uv[1] - luv_iter2->uv[1]) < limit) + { + return 1; + } + else { + return 0; + } + } + else { + return 1; + } +} static int stitch_check_uvs_state_stitchable(UvElement *element, UvElement *element_iter, StitchState *state) { @@ -341,6 +387,17 @@ static int stitch_check_uvs_state_stitchable(UvElement *element, UvElement *elem } +static int stitch_check_edges_state_stitchable(UvEdge *edge, UvEdge *edge_iter, StitchState *state) +{ + if ((state->snap_islands && edge->element->island == edge_iter->element->island) || + (!state->midpoints && edge->element->island == edge_iter->element->island)) + { + return 0; + } + + return stitch_check_edges_stitchable(edge, edge_iter, state); +} + /* calculate snapping for islands */ static void stitch_calculate_island_snapping(StitchState *state, PreviewPosition *preview_position, StitchPreviewer *preview, IslandStitchData *island_stitch_data, int final) { @@ -378,7 +435,7 @@ static void stitch_calculate_island_snapping(StitchState *state, PreviewPosition } else { - int face_preview_pos = preview_position[BM_elem_index_get(element->face)].data_position; + int face_preview_pos = preview_position[BM_elem_index_get(element->l->f)].data_position; stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, preview->preview_polys + face_preview_pos + 2 * element->tfindex); @@ -414,9 +471,14 @@ static void stitch_island_calculate_edge_rotation(UvEdge *edge, StitchState *sta l2 = element2->l; luv2 = CustomData_bmesh_get(&state->em->bm->ldata, l2->head.data, CD_MLOOPUV); - index1 = uvfinal_map[element1 - state->element_map->buf]; - index2 = uvfinal_map[element2 - state->element_map->buf]; - + if (state->mode == STITCH_VERT) { + index1 = uvfinal_map[element1 - state->element_map->buf]; + index2 = uvfinal_map[element2 - state->element_map->buf]; + } + else { + index1 = edge->uv1; + index2 = edge->uv2; + } /* the idea here is to take the directions of the edges and find the rotation between final and initial * direction. This, using inner and outer vector products, gives the angle. Directions are differences so... */ uv1[0] = luv2->uv[0] - luv1->uv[0]; @@ -461,7 +523,10 @@ static void stitch_island_calculate_vert_rotation(UvElement *element, StitchStat if (element_iter->separate && stitch_check_uvs_state_stitchable(element, element_iter, state)) { int index_tmp1, index_tmp2; float normal[2]; - /* easily possible*/ + + /* only calculate rotation against static island uv verts */ + if (!state->midpoints && element_iter->island != state->static_island) + continue; index_tmp1 = element_iter - state->element_map->buf; index_tmp1 = state->map[index_tmp1]; @@ -482,34 +547,114 @@ static void stitch_island_calculate_vert_rotation(UvElement *element, StitchStat } -static void stitch_state_delete(StitchState *stitch_state) +static void state_delete(StitchState *state) { - if (stitch_state) { - if (stitch_state->element_map) { - EDBM_uv_element_map_free(stitch_state->element_map); + if (state) { + if (state->element_map) { + EDBM_uv_element_map_free(state->element_map); + } + if (state->uvs) { + MEM_freeN(state->uvs); + } + if (state->selection_stack) { + MEM_freeN(state->selection_stack); } - if (stitch_state->uvs) { - MEM_freeN(stitch_state->uvs); + if (state->tris_per_island) { + MEM_freeN(state->tris_per_island); } - if (stitch_state->selection_stack) { - MEM_freeN(stitch_state->selection_stack); + if (state->map) { + MEM_freeN(state->map); } - if (stitch_state->tris_per_island) { - MEM_freeN(stitch_state->tris_per_island); + if (state->normals) { + MEM_freeN(state->normals); } - if (stitch_state->map) { - MEM_freeN(stitch_state->map); + if (state->edges) { + MEM_freeN(state->edges); } - if (stitch_state->normals) { - MEM_freeN(stitch_state->normals); + if (state->stitch_preview) { + stitch_preview_delete(state->stitch_preview); } - if (stitch_state->edges) { - MEM_freeN(stitch_state->edges); + if (state->edge_hash) { + BLI_ghash_free(state->edge_hash, NULL, NULL); } - MEM_freeN(stitch_state); + MEM_freeN(state); } } +static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState *state) +{ + UvEdge *edges = state->edges; + int *map = state->map; + UvElementMap *element_map = state->element_map; + UvElement *first_element = element_map->buf; + int i; + + for (i = 0; i < state->total_separate_edges; i++) { + UvEdge *edge = edges + i; + + if (edge->first) + continue; + + /* only boundary edges can be stitched. Yes. Sorry about that :p */ + if (edge->flag & STITCH_BOUNDARY) { + UvElement *element1 = state->uvs[edge->uv1]; + UvElement *element2 = state->uvs[edge->uv2]; + + /* Now iterate through all faces and try to find edges sharing the same vertices */ + UvElement *iter1 = element_map->vert[BM_elem_index_get(element1->l->v)]; + UvEdge *last_set = edge; + int elemindex2 = BM_elem_index_get(element2->l->v); + + edge->first = edge; + + for (; iter1; iter1 = iter1->next) { + UvElement *iter2 = NULL; + + /* check to see if other vertex of edge belongs to same vertex as */ + if (BM_elem_index_get(iter1->l->next->v) == elemindex2) + iter2 = ED_uv_element_get(element_map, iter1->l->f, iter1->l->next); + else if (BM_elem_index_get(iter1->l->prev->v) == elemindex2) + iter2 = ED_uv_element_get(element_map, iter1->l->f, iter1->l->prev); + + if (iter2) { + int index1 = map[iter1 - first_element]; + int index2 = map[iter2 - first_element]; + + /* make certain we do not have the same edge! */ + if (state->uvs[index2] != element2 && state->uvs[index1] != element1) { + UvEdge edgetmp; + UvEdge *edge2; + + + /* make sure the indices are well behaved */ + if (index1 < index2) { + edgetmp.uv1 = index1; + edgetmp.uv2 = index2; + } + else { + edgetmp.uv1 = index2; + edgetmp.uv2 = index1; + } + + /* get the edge from the hash */ + edge2 = BLI_ghash_lookup(edge_hash, &edgetmp); + + /* here I am taking care of non manifold case, assuming more than two matching edges. + * I am not too sure we want this though */ + last_set->next = edge2; + last_set = edge2; + /* set first, similarly to uv elements. Now we can iterate among common edges easily */ + edge2->first = edge; + } + } + } + } + else { + /* so stitchability code works */ + edge->first = edge; + } + } +} /* checks for remote uvs that may be stitched with a certain uv, flags them if stitchable. */ @@ -526,9 +671,6 @@ static void determine_uv_stitchability(UvElement *element, StitchState *state, I for (; element_iter; element_iter = element_iter->next) { if (element_iter->separate) { - if (element_iter == element) { - continue; - } if (stitch_check_uvs_stitchable(element, element_iter, state)) { island_stitch_data[element_iter->island].stitchableCandidate = 1; island_stitch_data[element->island].stitchableCandidate = 1; @@ -538,6 +680,19 @@ static void determine_uv_stitchability(UvElement *element, StitchState *state, I } } +static void determine_uv_edge_stitchability(UvEdge *edge, StitchState *state, IslandStitchData *island_stitch_data) +{ + UvEdge *edge_iter = edge->first; + + for (; edge_iter; edge_iter = edge_iter->next) { + if (stitch_check_edges_stitchable(edge, edge_iter, state)) { + island_stitch_data[edge_iter->element->island].stitchableCandidate = 1; + island_stitch_data[edge->element->island].stitchableCandidate = 1; + edge->flag |= STITCH_STITCHABLE_CANDIDATE; + } + } +} + /* set preview buffer position of UV face in editface->tmp.l */ static void stitch_set_face_preview_buffer_position(BMFace *efa, StitchPreviewer *preview, PreviewPosition *preview_position) @@ -555,7 +710,7 @@ static void stitch_set_face_preview_buffer_position(BMFace *efa, StitchPreviewer /* setup face preview for all coincident uvs and their faces */ static void stitch_setup_face_preview_for_uv_group(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data, PreviewPosition *preview_position) { - StitchPreviewer *preview = uv_get_stitch_previewer(); + StitchPreviewer *preview = state->stitch_preview; /* static island does not change so returning immediately */ if (state->snap_islands && !state->midpoints && state->static_island == element->island) @@ -566,17 +721,17 @@ static void stitch_setup_face_preview_for_uv_group(UvElement *element, StitchSta } do { - stitch_set_face_preview_buffer_position(element->face, preview, preview_position); + stitch_set_face_preview_buffer_position(element->l->f, preview, preview_position); element = element->next; } while (element && !element->separate); } /* checks if uvs are indeed stitchable and registers so that they can be shown in preview */ -static void stitch_validate_stichability(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data, +static void stitch_validate_uv_stichability(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data, PreviewPosition *preview_position) { UvElement *element_iter; - StitchPreviewer *preview; + StitchPreviewer *preview = state->stitch_preview; int vert_index; BMLoop *l; @@ -584,7 +739,6 @@ static void stitch_validate_stichability(UvElement *element, StitchState *state, vert_index = BM_elem_index_get(l->v); - preview = uv_get_stitch_previewer(); element_iter = state->element_map->vert[vert_index]; for (; element_iter; element_iter = element_iter->next) { @@ -608,6 +762,72 @@ static void stitch_validate_stichability(UvElement *element, StitchState *state, } } + +static void stitch_validate_edge_stichability(UvEdge *edge, StitchState *state, IslandStitchData *island_stitch_data, + PreviewPosition *preview_position) { + UvEdge *edge_iter = edge->first; + StitchPreviewer *preview = state->stitch_preview; + + for (; edge_iter; edge_iter = edge_iter->next) { + if (edge_iter == edge) + continue; + if (stitch_check_edges_state_stitchable(edge, edge_iter, state)) { + if ((edge_iter->element->island == state->static_island) || (edge->element->island == state->static_island)) { + edge->flag |= STITCH_STITCHABLE; + preview->num_stitchable++; + stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv1], state, island_stitch_data, preview_position); + stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv2], state, island_stitch_data, preview_position); + return; + } + } + } + + /* this can happen if the uvs to be stitched are not on a stitchable island */ + if (!(edge->flag & STITCH_STITCHABLE)) { + preview->num_unstitchable++; + } +} + + +static void stitch_propagate_uv_final_position (UvElement *element, int index, PreviewPosition *preview_position, UVVertAverage *final_position, StitchState *state, char final, Scene* scene) +{ + StitchPreviewer *preview = state->stitch_preview; + + if (element->flag & STITCH_STITCHABLE) { + UvElement *element_iter = element; + /* propagate to coincident uvs */ + do { + BMLoop *l; + MLoopUV *luv; + + l = element_iter->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + + element_iter->flag |= STITCH_PROCESSED; + /* either flush to preview or to the MTFace, if final */ + if (final) { + copy_v2_v2(luv->uv, final_position[index].uv); + + uvedit_uv_select_enable(state->em, scene, l, FALSE); + } + else { + int face_preview_pos = preview_position[BM_elem_index_get(element_iter->l->f)].data_position; + if (face_preview_pos != STITCH_NO_PREVIEW) { + copy_v2_v2(preview->preview_polys + face_preview_pos + 2 * element_iter->tfindex, + final_position[index].uv); + } + } + + /* end of calculations, keep only the selection flag */ + if ( (!state->snap_islands) || ((!state->midpoints) && (element_iter->island == state->static_island))) { + element_iter->flag &= STITCH_SELECTED; + } + + element_iter = element_iter->next; + } while (element_iter && !element_iter->separate); + } +} + /* main processing function. It calculates preview and final positions. */ static int stitch_process_data(StitchState *state, Scene *scene, int final) { @@ -618,6 +838,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) BMFace *efa; BMIter iter; UVVertAverage *final_position; + char stitch_midpoints = state->midpoints; /* used to map uv indices to uvaverage indices for selection */ unsigned int *uvfinal_map; @@ -625,8 +846,8 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) PreviewPosition *preview_position; /* cleanup previous preview */ - stitch_preview_delete(); - preview = stitch_preview_init(); + stitch_preview_delete(state->stitch_preview); + preview = state->stitch_preview = stitch_preview_init(); if (preview == NULL) return 0; @@ -649,8 +870,14 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) *****************************************/ for (i = 0; i < state->selection_size; i++) { - UvElement *element = state->selection_stack[i]; - determine_uv_stitchability(element, state, island_stitch_data); + if (state->mode == STITCH_VERT) { + UvElement *element = (UvElement *)state->selection_stack[i]; + determine_uv_stitchability(element, state, island_stitch_data); + } + else { + UvEdge *edge = (UvEdge *)state->selection_stack[i]; + determine_uv_edge_stitchability(edge, state, island_stitch_data); + } } /* set static island to one that is added for preview */ @@ -664,14 +891,26 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) } for (i = 0; i < state->selection_size; i++) { - UvElement *element = state->selection_stack[i]; - if (element->flag & STITCH_STITCHABLE_CANDIDATE) { - element->flag &= ~STITCH_STITCHABLE_CANDIDATE; - stitch_validate_stichability(element, state, island_stitch_data, preview_position); + if (state->mode == STITCH_VERT) { + UvElement *element = (UvElement *)state->selection_stack[i]; + if (element->flag & STITCH_STITCHABLE_CANDIDATE) { + element->flag &= ~STITCH_STITCHABLE_CANDIDATE; + stitch_validate_uv_stichability(element, state, island_stitch_data, preview_position); + } + else { + /* add to preview for unstitchable */ + preview->num_unstitchable++; + } } else { - /* add to preview for unstitchable */ - preview->num_unstitchable++; + UvEdge *edge = (UvEdge *)state->selection_stack[i]; + if (edge->flag & STITCH_STITCHABLE_CANDIDATE) { + edge->flag &= ~STITCH_STITCHABLE_CANDIDATE; + stitch_validate_edge_stichability(edge, state, island_stitch_data, preview_position); + } + else { + preview->num_unstitchable++; + } } } @@ -686,7 +925,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) numOfIslandUVs = getNumOfIslandUvs(state->element_map, i); element = &state->element_map->buf[state->element_map->islandIndices[i]]; for (j = 0; j < numOfIslandUVs; j++, element++) { - stitch_set_face_preview_buffer_position(element->face, preview, preview_position); + stitch_set_face_preview_buffer_position(element->l->f, preview, preview_position); } } } @@ -701,11 +940,12 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) MLoopUV *luv; unsigned int buffer_index = 0; int stitchBufferIndex = 0, unstitchBufferIndex = 0; + int preview_size = (state->mode == STITCH_VERT) ? 2 : 4; /* initialize the preview buffers */ preview->preview_polys = (float *)MEM_mallocN(preview->preview_uvs * sizeof(float) * 2, "tri_uv_stitch_prev"); preview->uvs_per_polygon = MEM_mallocN(preview->num_polys * sizeof(*preview->uvs_per_polygon), "tri_uv_stitch_prev"); - preview->preview_stitchable = (float *)MEM_mallocN(preview->num_stitchable * sizeof(float) * 2, "stitch_preview_stichable_data"); - preview->preview_unstitchable = (float *)MEM_mallocN(preview->num_unstitchable * sizeof(float) * 2, "stitch_preview_unstichable_data"); + preview->preview_stitchable = (float *)MEM_mallocN(preview->num_stitchable * sizeof(float) * preview_size, "stitch_preview_stichable_data"); + preview->preview_unstitchable = (float *)MEM_mallocN(preview->num_unstitchable * sizeof(float) * preview_size, "stitch_preview_unstichable_data"); preview->static_tris = (float *)MEM_mallocN(state->tris_per_island[state->static_island] * sizeof(float) * 6, "static_island_preview_tris"); @@ -715,7 +955,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) return 0; } - /* copy data from MTFaces to the preview display buffers */ + /* copy data from MLoopUVs to the preview display buffers */ BM_ITER_MESH (efa, &iter, state->em->bm, BM_FACES_OF_MESH) { /* just to test if face was added for processing. uvs of inselected vertices will return NULL */ UvElement *element = ED_uv_element_get(state->element_map, efa, BM_FACE_FIRST_LOOP(efa)); @@ -757,22 +997,56 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) } /* fill the appropriate preview buffers */ - for (i = 0; i < state->total_separate_uvs; i++) { - UvElement *element = (UvElement *)state->uvs[i]; - if (element->flag & STITCH_STITCHABLE) { - l = element->l; - luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + if (state->mode == STITCH_VERT) { + for (i = 0; i < state->total_separate_uvs; i++) { + UvElement *element = (UvElement *)state->uvs[i]; + if (element->flag & STITCH_STITCHABLE) { + l = element->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + + copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 2], luv->uv); - copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 2], luv->uv); + stitchBufferIndex++; + } + else if (element->flag & STITCH_SELECTED) { + l = element->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); - stitchBufferIndex++; + copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 2], luv->uv); + unstitchBufferIndex++; + } } - else if (element->flag & STITCH_SELECTED) { - l = element->l; - luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + } + else { + for (i = 0; i < state->total_separate_edges; i++) { + UvEdge *edge = state->edges + i; + UvElement *element1 = state->uvs[edge->uv1]; + UvElement *element2 = state->uvs[edge->uv2]; + + if (edge->flag & STITCH_STITCHABLE) { + l = element1->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4], luv->uv); + + l = element2->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4 + 2], luv->uv); - copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 2], luv->uv); - unstitchBufferIndex++; + stitchBufferIndex++; + BLI_assert(stitchBufferIndex <= preview->num_stitchable); + } + else if (edge->flag & STITCH_SELECTED) { + l = element1->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4], luv->uv); + + l = element2->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4 + 2], luv->uv); + + unstitchBufferIndex++; + BLI_assert(unstitchBufferIndex <= preview->num_unstitchable); + } } } } @@ -781,141 +1055,218 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) * Here we calculate the final coordinates of the uvs * ******************************************************/ - final_position = MEM_callocN(state->selection_size * sizeof(*final_position), "stitch_uv_average"); - uvfinal_map = MEM_mallocN(state->element_map->totalUVs * sizeof(*uvfinal_map), "stitch_uv_final_map"); + if (state->mode == STITCH_VERT) { + final_position = MEM_callocN(state->selection_size * sizeof(*final_position), "stitch_uv_average"); + uvfinal_map = MEM_mallocN(state->element_map->totalUVs * sizeof(*uvfinal_map), "stitch_uv_final_map"); + } + else { + final_position = MEM_callocN(state->total_separate_uvs * sizeof(*final_position), "stitch_uv_average"); + } /* first pass, calculate final position for stitchable uvs of the static island */ for (i = 0; i < state->selection_size; i++) { - UvElement *element = state->selection_stack[i]; - if (element->flag & STITCH_STITCHABLE) { - BMLoop *l; - MLoopUV *luv; - UvElement *element_iter; + if (state->mode == STITCH_VERT) { + UvElement *element = state->selection_stack[i]; - l = element->l; - luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + if (element->flag & STITCH_STITCHABLE) { + BMLoop *l; + MLoopUV *luv; + UvElement *element_iter; + l = element->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); - uvfinal_map[element - state->element_map->buf] = i; + uvfinal_map[element - state->element_map->buf] = i; - copy_v2_v2(final_position[i].uv, luv->uv); - final_position[i].count = 1; + copy_v2_v2(final_position[i].uv, luv->uv); + final_position[i].count = 1; - if (state->snap_islands && element->island == state->static_island && !stitch_midpoints) - continue; + if (state->snap_islands && element->island == state->static_island && !stitch_midpoints) + continue; - element_iter = state->element_map->vert[BM_elem_index_get(l->v)]; + element_iter = state->element_map->vert[BM_elem_index_get(l->v)]; + + for ( ; element_iter; element_iter = element_iter->next) { + if (element_iter->separate) { + if (stitch_check_uvs_state_stitchable(element, element_iter, state)) { + l = element_iter->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + if (stitch_midpoints) { + add_v2_v2(final_position[i].uv, luv->uv); + final_position[i].count++; + } + else if (element_iter->island == state->static_island) { + /* if multiple uvs on the static island exist, + * last checked remains. to disambiguate we need to limit or use + * edge stitch */ + copy_v2_v2(final_position[i].uv, luv->uv); + } + } + } + } + } + if (stitch_midpoints) { + final_position[i].uv[0] /= final_position[i].count; + final_position[i].uv[1] /= final_position[i].count; + } + } + else { + UvEdge *edge = state->selection_stack[i]; + + if (edge->flag & STITCH_STITCHABLE) { + MLoopUV *luv2, *luv1; + BMLoop *l; + UvEdge *edge_iter; + + l = state->uvs[edge->uv1]->l; + luv1 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + l = state->uvs[edge->uv2]->l; + luv2 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + + copy_v2_v2(final_position[edge->uv1].uv, luv1->uv); + copy_v2_v2(final_position[edge->uv2].uv, luv2->uv); + final_position[edge->uv1].count = 1; + final_position[edge->uv2].count = 1; + + state->uvs[edge->uv1]->flag |= STITCH_STITCHABLE; + state->uvs[edge->uv2]->flag |= STITCH_STITCHABLE; + + if (state->snap_islands && edge->element->island == state->static_island && !stitch_midpoints) + continue; + + for (edge_iter = edge->first; edge_iter; edge_iter = edge_iter->next) { + if (stitch_check_edges_state_stitchable (edge, edge_iter, state)) { + l = state->uvs[edge_iter->uv1]->l; + luv1 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + l = state->uvs[edge_iter->uv2]->l; + luv2 = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); - for ( ; element_iter; element_iter = element_iter->next) { - if (element_iter->separate) { - if (stitch_check_uvs_state_stitchable(element, element_iter, state)) { - l = element_iter->l; - luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); if (stitch_midpoints) { - add_v2_v2(final_position[i].uv, luv->uv); - final_position[i].count++; + add_v2_v2(final_position[edge->uv1].uv, luv1->uv); + final_position[edge->uv1].count++; + add_v2_v2(final_position[edge->uv2].uv, luv2->uv); + final_position[edge->uv2].count++; } - else if (element_iter->island == state->static_island) { - /* if multiple uvs on the static island exist, - * last checked remains. to disambiguate we need to limit or use - * edge stitch */ - copy_v2_v2(final_position[i].uv, luv->uv); + else if (edge_iter->element->island == state->static_island) { + copy_v2_v2(final_position[edge->uv1].uv, luv1->uv); + copy_v2_v2(final_position[edge->uv2].uv, luv2->uv); } } } } } - if (stitch_midpoints) { - final_position[i].uv[0] /= final_position[i].count; - final_position[i].uv[1] /= final_position[i].count; - } } /* second pass, calculate island rotation and translation before modifying any uvs */ if (state->snap_islands) { - for (i = 0; i < state->selection_size; i++) { - UvElement *element = state->selection_stack[i]; - if (element->flag & STITCH_STITCHABLE) { - BMLoop *l; - MLoopUV *luv; + if (state->mode == STITCH_VERT) { + for (i = 0; i < state->selection_size; i++) { + UvElement *element = state->selection_stack[i]; - l = element->l; - luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + if (element->flag & STITCH_STITCHABLE) { + BMLoop *l; + MLoopUV *luv; - /* accumulate each islands' translation from stitchable elements. it is important to do here - * because in final pass MTFaces get modified and result is zero. */ - island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv->uv[0]; - island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv->uv[1]; - island_stitch_data[element->island].medianPoint[0] += luv->uv[0]; - island_stitch_data[element->island].medianPoint[1] += luv->uv[1]; - island_stitch_data[element->island].numOfElements++; - } - } + l = element->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); - /* only calculate rotation when an edge has been fully selected */ - for (i = 0; i < state->total_boundary_edges; i++) { - UvEdge *edge = state->edges + i; - if ((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE)) { - stitch_island_calculate_edge_rotation(edge, state, final_position, uvfinal_map, island_stitch_data); - island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = TRUE; + /* accumulate each islands' translation from stitchable elements. it is important to do here + * because in final pass MTFaces get modified and result is zero. */ + island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv->uv[0]; + island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv->uv[1]; + island_stitch_data[element->island].medianPoint[0] += luv->uv[0]; + island_stitch_data[element->island].medianPoint[1] += luv->uv[1]; + island_stitch_data[element->island].numOfElements++; + } } - } - /* clear seams of stitched edges */ - if (final && state->clear_seams) { - for (i = 0; i < state->total_boundary_edges; i++) { + /* only calculate rotation when an edge has been fully selected */ + for (i = 0; i < state->total_separate_edges; i++) { UvEdge *edge = state->edges + i; - if ((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE)) - BM_elem_flag_disable(edge->element->l->e, BM_ELEM_SEAM); + if ((edge->flag & STITCH_BOUNDARY) && (state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE)) { + stitch_island_calculate_edge_rotation(edge, state, final_position, uvfinal_map, island_stitch_data); + island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = TRUE; + } } - } - for (i = 0; i < state->selection_size; i++) { - UvElement *element = state->selection_stack[i]; - if (!island_stitch_data[element->island].use_edge_rotation) { - if (element->flag & STITCH_STITCHABLE) { - stitch_island_calculate_vert_rotation(element, state, island_stitch_data); + /* clear seams of stitched edges */ + if (final && state->clear_seams) { + for (i = 0; i < state->total_separate_edges; i++) { + UvEdge *edge = state->edges + i; + if ((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE)) + BM_elem_flag_disable(edge->element->l->e, BM_ELEM_SEAM); + } + } + + for (i = 0; i < state->selection_size; i++) { + UvElement *element = state->selection_stack[i]; + if (!island_stitch_data[element->island].use_edge_rotation) { + if (element->flag & STITCH_STITCHABLE) { + stitch_island_calculate_vert_rotation(element, state, island_stitch_data); + } } } } + else { + for (i = 0; i < state->total_separate_uvs; i++) { + UvElement *element = state->uvs[i]; - } + if (stitch_midpoints) { + final_position[i].uv[0] /= final_position[i].count; + final_position[i].uv[1] /= final_position[i].count; + } - /* third pass, propagate changes to coincident uvs */ - for (i = 0; i < state->selection_size; i++) { - UvElement *element = state->selection_stack[i]; - if (element->flag & STITCH_STITCHABLE) { - UvElement *element_iter = element; - /* propagate to coincident uvs */ - do { - BMLoop *l; - MLoopUV *luv; + if (element->flag & STITCH_STITCHABLE) { + BMLoop *l; + MLoopUV *luv; - l = element_iter->l; - luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); + l = element->l; + luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV); - element_iter->flag |= STITCH_PROCESSED; - /* either flush to preview or to the MTFace, if final */ - if (final) { - copy_v2_v2(luv->uv, final_position[i].uv); + /* accumulate each islands' translation from stitchable elements. it is important to do here + * because in final pass MTFaces get modified and result is zero. */ + island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv->uv[0]; + island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv->uv[1]; + island_stitch_data[element->island].medianPoint[0] += luv->uv[0]; + island_stitch_data[element->island].medianPoint[1] += luv->uv[1]; + island_stitch_data[element->island].numOfElements++; + } + } + + for (i = 0; i < state->selection_size; i++) { + UvEdge *edge = state->selection_stack[i]; - uvedit_uv_select_enable(state->em, scene, l, FALSE); + if (edge->flag & STITCH_STITCHABLE) { + stitch_island_calculate_edge_rotation(edge, state, final_position, NULL, island_stitch_data); + island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = TRUE; } - else { - int face_preview_pos = preview_position[BM_elem_index_get(element_iter->face)].data_position; - if (face_preview_pos != STITCH_NO_PREVIEW) { - copy_v2_v2(preview->preview_polys + face_preview_pos + 2 * element_iter->tfindex, - final_position[i].uv); + } + + /* clear seams of stitched edges */ + if (final && state->clear_seams) { + for (i = 0; i < state->selection_size; i++) { + UvEdge *edge = state->selection_stack[i]; + if (edge->flag & STITCH_STITCHABLE) { + BM_elem_flag_disable(edge->element->l->e, BM_ELEM_SEAM); } } + } + } + } - /* end of calculations, keep only the selection flag */ - if ( (!state->snap_islands) || ((!stitch_midpoints) && (element_iter->island == state->static_island))) { - element_iter->flag &= STITCH_SELECTED; - } + /* third pass, propagate changes to coincident uvs */ + for (i = 0; i < state->selection_size; i++) { + if (state->mode == STITCH_VERT) { + UvElement *element = state->selection_stack[i]; - element_iter = element_iter->next; - } while (element_iter && !element_iter->separate); + stitch_propagate_uv_final_position (element, i, preview_position, final_position, state, final, scene); + } else { + UvEdge *edge = state->selection_stack[i]; + + stitch_propagate_uv_final_position (state->uvs[edge->uv1], edge->uv1, preview_position, final_position, state, final, scene); + stitch_propagate_uv_final_position (state->uvs[edge->uv2], edge->uv2, preview_position, final_position, state, final, scene); + + edge->flag &= (STITCH_SELECTED | STITCH_BOUNDARY); } } @@ -925,7 +1276,9 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final) } MEM_freeN(final_position); - MEM_freeN(uvfinal_map); + if (state->mode == STITCH_VERT) { + MEM_freeN(uvfinal_map); + } MEM_freeN(island_stitch_data); MEM_freeN(preview_position); @@ -937,8 +1290,8 @@ static unsigned int uv_edge_hash(const void *key) { UvEdge *edge = (UvEdge *)key; return - BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv2)) + - BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv1)); + BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv2)) + + BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv1)); } static int uv_edge_compare(const void *a, const void *b) @@ -952,13 +1305,41 @@ static int uv_edge_compare(const void *a, const void *b) return 1; } +/* select all common edges */ +static void stitch_select_edge(UvEdge *edge, StitchState *state, int always_select) +{ + UvEdge *eiter; + UvEdge **selection_stack = (UvEdge **)state->selection_stack; + + for (eiter = edge->first; eiter; eiter = eiter->next) { + if (eiter->flag & STITCH_SELECTED) { + int i; + if (always_select) + continue; + + eiter->flag &= ~STITCH_SELECTED; + for (i = 0; i < state->selection_size; i++) { + if (selection_stack[i] == eiter) { + (state->selection_size)--; + selection_stack[i] = selection_stack[state->selection_size]; + break; + } + } + } + else { + eiter->flag |= STITCH_SELECTED; + selection_stack[state->selection_size++] = eiter; + } + } +} + /* Select all common uvs */ static void stitch_select_uv(UvElement *element, StitchState *state, int always_select) { BMLoop *l; UvElement *element_iter; - UvElement **selection_stack = state->selection_stack; + UvElement **selection_stack = (UvElement **)state->selection_stack; l = element->l; @@ -989,6 +1370,55 @@ static void stitch_select_uv(UvElement *element, StitchState *state, int always_ } } +static void stitch_switch_selection_mode(StitchState *state) +{ + void **old_selection_stack = state->selection_stack; + int old_selection_size = state->selection_size; + state->selection_size = 0; + + if (state->mode == STITCH_VERT) { + int i; + state->selection_stack = MEM_mallocN(state->total_separate_edges*sizeof(*state->selection_stack), + "stitch_new_edge_selection_stack"); + + /* check if both elements of an edge are selected */ + for (i = 0; i < state->total_separate_edges; i++) { + UvEdge *edge = state->edges + i; + UvElement *element1 = state->uvs[edge->uv1]; + UvElement *element2 = state->uvs[edge->uv2]; + + if ((element1->flag & STITCH_SELECTED) && (element2->flag & STITCH_SELECTED)) + stitch_select_edge(edge, state, TRUE); + } + + /* unselect selected uvelements */ + for (i = 0; i < old_selection_size; i++) { + UvElement *element = old_selection_stack[i]; + + element->flag &= ~STITCH_SELECTED; + } + state->mode = STITCH_EDGE; + } + else { + int i; + state->selection_stack = MEM_mallocN(state->total_separate_uvs*sizeof(*state->selection_stack), + "stitch_new_vert_selection_stack"); + + for (i = 0; i < old_selection_size; i++) { + UvEdge *edge = old_selection_stack[i]; + UvElement *element1 = state->uvs[edge->uv1]; + UvElement *element2 = state->uvs[edge->uv2]; + + stitch_select_uv(element1, state, TRUE); + stitch_select_uv(element2, state, TRUE); + + edge->flag &= ~STITCH_SELECTED; + } + state->mode = STITCH_VERT; + } + MEM_freeN(old_selection_stack); +} + static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *normal) { BMLoop *l1 = edge->element->l; @@ -1007,11 +1437,12 @@ 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)) +static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg) { int i, index = 0; float pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE); - StitchPreviewer *stitch_preview = uv_get_stitch_previewer(); + StitchState *state = (StitchState *)arg; + StitchPreviewer *stitch_preview = state->stitch_preview; glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); glEnableClientState(GL_VERTEX_ARRAY); @@ -1042,24 +1473,58 @@ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *UN 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); + if (state->mode == STITCH_VERT) { + 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); + } + else { + UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE); + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable); + glDrawArrays(GL_LINES, 0, 2*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); + UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE); + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable); + glDrawArrays(GL_LINES, 0, 2*stitch_preview->num_unstitchable); + } glPopClientAttrib(); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glPointSize(1.0); +} + +static UvEdge *uv_edge_get (BMLoop *l, StitchState *state) +{ + UvEdge tmp_edge; + + UvElement *element1 = ED_uv_element_get(state->element_map, l->f, l); + UvElement *element2 = ED_uv_element_get(state->element_map, l->f, l->next); + + int uv1 = state->map[element1 - state->element_map->buf]; + int uv2 = state->map[element2 - state->element_map->buf]; + + if (uv1 < uv2) { + tmp_edge.uv1 = uv1; + tmp_edge.uv2 = uv2; + } + else { + tmp_edge.uv1 = uv2; + tmp_edge.uv2 = uv1; + } + + return BLI_ghash_lookup(state->edge_hash, &tmp_edge); } static int stitch_init(bContext *C, wmOperator *op) { /* for fast edge lookup... */ - GHash *edgeHash; + GHash *edge_hash; /* ...and actual edge storage */ UvEdge *edges; int total_edges; @@ -1097,21 +1562,41 @@ 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(ar->type, stitch_draw, NULL, REGION_DRAW_POST_VIEW); + if (RNA_struct_property_is_set(op->ptr, "mode")) { + state->mode = RNA_enum_get(op->ptr, "mode"); + } + else { + if (ts->uv_flag & UV_SYNC_SELECTION) { + if (ts->selectmode & SCE_SELECT_VERTEX) + state->mode = STITCH_VERT; + else + state->mode = STITCH_EDGE; + } + else { + if (ts->uv_selectmode & UV_SELECT_VERTEX) { + state->mode = STITCH_VERT; + } + else { + state->mode = STITCH_EDGE; + } + } + } + + state->draw_handle = ED_region_draw_cb_activate(ar->type, stitch_draw, state, 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); + state->element_map = EDBM_uv_element_map_create(state->em, FALSE, TRUE); } else { - state->element_map = EDBM_uv_element_map_create(state->em, 1, 1); + state->element_map = EDBM_uv_element_map_create(state->em, TRUE, TRUE); } if (!state->element_map) { - stitch_state_delete(state); + state_delete(state); return 0; } /* Entirely possible if redoing last operator that static island is bigger than total number of islands. - * This ensures we get no hang in the island checking code in stitch_process_data. */ + * This ensures we get no hang in the island checking code in stitch_stitch_process_data. */ state->static_island %= state->element_map->totalIslands; /* Count 'unique' uvs */ @@ -1121,22 +1606,21 @@ static int stitch_init(bContext *C, wmOperator *op) } } + /* explicitly set preview to NULL, to avoid deleting an invalid pointer on stitch_process_data */ + state->stitch_preview = NULL; /* Allocate the unique uv buffers */ state->uvs = MEM_mallocN(sizeof(*state->uvs) * counter, "uv_stitch_unique_uvs"); /* internal uvs need no normals but it is hard and slow to keep a map of * normals only for boundary uvs, so allocating for all uvs */ state->normals = MEM_callocN(sizeof(*state->normals) * counter * 2, "uv_stitch_normals"); state->total_separate_uvs = counter; - /* we can at most have totalUVs edges or uvs selected. Actually they are less, considering we store only - * unique uvs for processing but I am accounting for all bizarre cases, especially for edges, this way */ - state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * counter, "uv_stitch_selection_stack"); state->map = map = MEM_mallocN(sizeof(*map) * state->element_map->totalUVs, "uv_stitch_unique_map"); /* Allocate the edge stack */ - edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash"); + edge_hash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash"); all_edges = MEM_mallocN(sizeof(*all_edges) * state->element_map->totalUVs, "stitch_all_edges"); - if (!state->selection_stack || !state->uvs || !map || !edgeHash || !all_edges) { - stitch_state_delete(state); + if (!state->uvs || !map || !edge_hash || !all_edges) { + state_delete(state); return 0; } @@ -1169,6 +1653,8 @@ static int stitch_init(bContext *C, wmOperator *op) offset1 = map[itmp1]; offset2 = map[itmp2]; + all_edges[counter].next = NULL; + all_edges[counter].first = NULL; all_edges[counter].flag = 0; all_edges[counter].element = element; /* using an order policy, sort uvs according to address space. This avoids @@ -1182,12 +1668,12 @@ static int stitch_init(bContext *C, wmOperator *op) all_edges[counter].uv2 = offset1; } - if (BLI_ghash_haskey(edgeHash, &all_edges[counter])) { - char *flag = BLI_ghash_lookup(edgeHash, &all_edges[counter]); - *flag = 0; + if (BLI_ghash_haskey(edge_hash, &all_edges[counter])) { + UvEdge *edge = BLI_ghash_lookup(edge_hash, &all_edges[counter]); + edge->flag = 0; } else { - BLI_ghash_insert(edgeHash, &all_edges[counter], &(all_edges[counter].flag)); + BLI_ghash_insert(edge_hash, &all_edges[counter], &all_edges[counter]); all_edges[counter].flag = STITCH_BOUNDARY; } counter++; @@ -1195,55 +1681,55 @@ static int stitch_init(bContext *C, wmOperator *op) } - ghi = BLI_ghashIterator_new(edgeHash); - total_edges = 0; - /* fill the edges with data */ - for (; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) { - UvEdge *edge = ((UvEdge *)BLI_ghashIterator_getKey(ghi)); - if (edge->flag & STITCH_BOUNDARY) { - total_edges++; - } - } + ghi = BLI_ghashIterator_new(edge_hash); + total_edges = BLI_ghash_size(edge_hash); state->edges = edges = MEM_mallocN(sizeof(*edges) * total_edges, "stitch_edges"); - if (!ghi || !edges) { - MEM_freeN(all_edges); - stitch_state_delete(state); + + /* I assume any system will be able to at least allocate an iterator :p */ + if (!edges) { + BLI_ghashIterator_free(ghi); + state_delete(state); return 0; } - state->total_boundary_edges = total_edges; + state->total_separate_edges = total_edges; /* fill the edges with data */ - for (i = 0, BLI_ghashIterator_init(ghi, edgeHash); !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) { - UvEdge *edge = ((UvEdge *)BLI_ghashIterator_getKey(ghi)); - if (edge->flag & STITCH_BOUNDARY) { - edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi)); - } + for (i = 0, BLI_ghashIterator_init(ghi, edge_hash); !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) { + edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi)); } /* cleanup temporary stuff */ BLI_ghashIterator_free(ghi); MEM_freeN(all_edges); - /* refill hash with new pointers to cleanup duplicates */ - BLI_ghash_free(edgeHash, NULL, NULL); + BLI_ghash_free(edge_hash, NULL, NULL); + + /* refill an edge hash to create edge connnectivity data */ + state->edge_hash = edge_hash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash"); + for (i = 0; i < total_edges; i++) { + BLI_ghash_insert(edge_hash, edges + i, edges + i); + } + stitch_uv_edge_generate_linked_edges(edge_hash, state); /***** calculate 2D normals for boundary uvs *****/ /* we use boundary edges to calculate 2D normals. * to disambiguate the direction of the normal, we also need * a point "inside" the island, that can be provided by - * the opposite uv for a quad, or the next uv for a triangle. */ + * the winding of the polygon (assuming counter-clockwise flow). */ for (i = 0; i < total_edges; i++) { float normal[2]; - stitch_calculate_edge_normal(em, edges + i, normal); + if (edges[i].flag & STITCH_BOUNDARY) { + stitch_calculate_edge_normal(em, edges + i, normal); - add_v2_v2(state->normals + edges[i].uv1 * 2, normal); - add_v2_v2(state->normals + edges[i].uv2 * 2, normal); + add_v2_v2(state->normals + edges[i].uv1 * 2, normal); + add_v2_v2(state->normals + edges[i].uv2 * 2, normal); - normalize_v2(state->normals + edges[i].uv1 * 2); - normalize_v2(state->normals + edges[i].uv2 * 2); + normalize_v2(state->normals + edges[i].uv1 * 2); + normalize_v2(state->normals + edges[i].uv2 * 2); + } } @@ -1255,31 +1741,89 @@ static int stitch_init(bContext *C, wmOperator *op) if (RNA_struct_property_is_set(op->ptr, "selection")) { int faceIndex, elementIndex; UvElement *element; + enum StitchModes stored_mode = RNA_enum_get(op->ptr, "stored_mode"); - EDBM_index_arrays_init(em, 0, 0, 1); + EDBM_index_arrays_ensure(em, BM_FACE); - RNA_BEGIN (op->ptr, itemptr, "selection") - { - faceIndex = RNA_int_get(&itemptr, "face_index"); - elementIndex = RNA_int_get(&itemptr, "element_index"); - efa = EDBM_face_at_index(em, faceIndex); - element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex)); - stitch_select_uv(element, state, 1); + if (stored_mode == STITCH_VERT) { + state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs, "uv_stitch_selection_stack"); + + RNA_BEGIN (op->ptr, itemptr, "selection") + { + faceIndex = RNA_int_get(&itemptr, "face_index"); + elementIndex = RNA_int_get(&itemptr, "element_index"); + efa = EDBM_face_at_index(em, faceIndex); + element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex)); + stitch_select_uv(element, state, 1); + } + RNA_END; } - RNA_END; + else { + state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_edges, "uv_stitch_selection_stack"); + + RNA_BEGIN (op->ptr, itemptr, "selection") + { + UvEdge tmp_edge, *edge; + int uv1, uv2; + faceIndex = RNA_int_get(&itemptr, "face_index"); + elementIndex = RNA_int_get(&itemptr, "element_index"); + efa = EDBM_face_at_index(em, faceIndex); + element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex)); + uv1 = map[element - state->element_map->buf]; + + element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, (elementIndex + 1) % efa->len)); + uv2 = map[element - state->element_map->buf]; + + if (uv1 < uv2) { + tmp_edge.uv1 = uv1; + tmp_edge.uv2 = uv2; + } + else { + tmp_edge.uv1 = uv2; + tmp_edge.uv2 = uv1; + } + + edge = BLI_ghash_lookup(edge_hash, &tmp_edge); - EDBM_index_arrays_free(em); + stitch_select_edge(edge, state, TRUE); + } + RNA_END; + } + /* if user has switched the operator mode after operation, we need to convert + * the stored format */ + if (state->mode != stored_mode) { + state->mode = stored_mode; + stitch_switch_selection_mode(state); + } /* Clear the selection */ RNA_collection_clear(op->ptr, "selection"); } else { - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { - if (uvedit_uv_select_test(em, scene, l)) { - UvElement *element = ED_uv_element_get(state->element_map, efa, l); - if (element) { - stitch_select_uv(element, state, 1); + if (state->mode == STITCH_VERT) { + state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs, "uv_stitch_selection_stack"); + + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { + if (uvedit_uv_select_test(em, scene, l)) { + UvElement *element = ED_uv_element_get(state->element_map, efa, l); + if (element) { + stitch_select_uv(element, state, 1); + } + } + } + } + } + else { + state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_edges, "uv_stitch_selection_stack"); + + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { + if (uvedit_edge_select_test(em, scene, l)) { + UvEdge *edge = uv_edge_get(l, state); + if (edge) { + stitch_select_edge(edge, state, TRUE); + } } } } @@ -1302,8 +1846,9 @@ static int stitch_init(bContext *C, wmOperator *op) } } - if (!stitch_process_data(state, scene, 0)) { - stitch_state_delete(state); + if (!stitch_process_data(state, scene, FALSE)) { + + state_delete(state); return 0; } @@ -1324,7 +1869,7 @@ static int stitch_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) static void stitch_exit(bContext *C, wmOperator *op, int finished) { - StitchState *stitch_state; + StitchState *state; Scene *scene; SpaceImage *sima; ScrArea *sa = CTX_wm_area(C); @@ -1334,45 +1879,48 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished) obedit = CTX_data_edit_object(C); sima = CTX_wm_space_image(C); - stitch_state = (StitchState *)op->customdata; + state = (StitchState *)op->customdata; if (finished) { int i; - RNA_float_set(op->ptr, "limit", stitch_state->limit_dist); - RNA_boolean_set(op->ptr, "use_limit", stitch_state->use_limit); - RNA_boolean_set(op->ptr, "snap_islands", stitch_state->snap_islands); - RNA_int_set(op->ptr, "static_island", stitch_state->static_island); - RNA_boolean_set(op->ptr, "midpoint_snap", stitch_state->midpoints); + RNA_float_set(op->ptr, "limit", state->limit_dist); + RNA_boolean_set(op->ptr, "use_limit", state->use_limit); + RNA_boolean_set(op->ptr, "snap_islands", state->snap_islands); + RNA_int_set(op->ptr, "static_island", state->static_island); + RNA_boolean_set(op->ptr, "midpoint_snap", state->midpoints); + RNA_enum_set(op->ptr, "mode", state->mode); + RNA_enum_set(op->ptr, "stored_mode", state->mode); /* Store selection for re-execution of stitch */ - for (i = 0; i < stitch_state->selection_size; i++) { + for (i = 0; i < state->selection_size; i++) { + UvElement *element; PointerRNA itemptr; - UvElement *element = stitch_state->selection_stack[i]; - + if (state->mode == STITCH_VERT) { + element = state->selection_stack[i]; + } + else { + element = ((UvEdge *)state->selection_stack[i])->element; + } RNA_collection_add(op->ptr, "selection", &itemptr); - RNA_int_set(&itemptr, "face_index", BM_elem_index_get(element->face)); - + RNA_int_set(&itemptr, "face_index", BM_elem_index_get(element->l->f)); RNA_int_set(&itemptr, "element_index", element->tfindex); } - uvedit_live_unwrap_update(sima, scene, obedit); } if (sa) ED_area_headerprint(sa, NULL); - ED_region_draw_cb_exit(CTX_wm_region(C)->type, stitch_state->draw_handle); + ED_region_draw_cb_exit(CTX_wm_region(C)->type, state->draw_handle); DAG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); - stitch_state_delete(stitch_state); + state_delete(state); op->customdata = NULL; - - stitch_preview_delete(); } @@ -1398,7 +1946,7 @@ static int stitch_exec(bContext *C, wmOperator *op) } } -static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState *stitch_state) +static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState *state) { /* add uv under mouse to processed uv's */ float co[2]; @@ -1407,42 +1955,53 @@ static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState Image *ima = CTX_data_edit_image(C); UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]); - uv_find_nearest_vert(scene, ima, stitch_state->em, co, NULL, &hit); - if (hit.efa) { - /* Add vertex to selection, deselect all common uv's of vert other - * than selected and update the preview. This behavior was decided so that - * you can do stuff like deselect the opposite stitchable vertex and the initial still gets deselected */ + if (state->mode == STITCH_VERT) { + uv_find_nearest_vert(scene, ima, state->em, co, NULL, &hit); + + if (hit.efa) { + /* Add vertex to selection, deselect all common uv's of vert other + * than selected and update the preview. This behavior was decided so that + * you can do stuff like deselect the opposite stitchable vertex and the initial still gets deselected */ - /* This works due to setting of tmp in find nearest uv vert */ - UvElement *element = ED_uv_element_get(stitch_state->element_map, hit.efa, hit.l); - stitch_select_uv(element, stitch_state, 0); + /* This works due to setting of tmp in find nearest uv vert */ + UvElement *element = ED_uv_element_get(state->element_map, hit.efa, hit.l); + stitch_select_uv(element, state, FALSE); + } + } + else { + uv_find_nearest_edge(scene, ima, state->em, co, &hit); + + if (hit.efa) { + UvEdge *edge = uv_edge_get(hit.l, state); + stitch_select_edge(edge, state, FALSE); + } } } static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event) { - StitchState *stitch_state; + StitchState *state; Scene *scene = CTX_data_scene(C); - stitch_state = (StitchState *)op->customdata; + state = (StitchState *)op->customdata; switch (event->type) { case MIDDLEMOUSE: return OPERATOR_PASS_THROUGH; - /* Cancel */ + /* Cancel */ case ESCKEY: return stitch_cancel(C, op); case LEFTMOUSE: if (event->shift && (U.flag & USER_LMOUSESELECT)) { - if (event->val == KM_RELEASE) { - stitch_select(C, scene, event, stitch_state); + if (event->val == KM_PRESS) { + stitch_select(C, scene, event, state); - if (!stitch_process_data(stitch_state, scene, 0)) { + if (!stitch_process_data(state, scene, FALSE)) { return stitch_cancel(C, op); } } @@ -1451,7 +2010,7 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event) case PADENTER: case RETKEY: if (event->val == KM_PRESS) { - if (stitch_process_data(stitch_state, scene, 1)) { + if (stitch_process_data(state, scene, TRUE)) { stitch_exit(C, op, 1); return OPERATOR_FINISHED; } @@ -1462,12 +2021,12 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event) else { return OPERATOR_PASS_THROUGH; } - /* Increase limit */ + /* Increase limit */ case PADPLUSKEY: case WHEELUPMOUSE: if (event->val == KM_PRESS && event->alt) { - stitch_state->limit_dist += 0.01f; - if (!stitch_process_data(stitch_state, scene, 0)) { + state->limit_dist += 0.01f; + if (!stitch_process_data(state, scene, FALSE)) { return stitch_cancel(C, op); } break; @@ -1475,13 +2034,13 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event) else { return OPERATOR_PASS_THROUGH; } - /* Decrease limit */ + /* Decrease limit */ case PADMINUS: case WHEELDOWNMOUSE: if (event->val == KM_PRESS && event->alt) { - stitch_state->limit_dist -= 0.01f; - stitch_state->limit_dist = MAX2(0.01f, stitch_state->limit_dist); - if (!stitch_process_data(stitch_state, scene, 0)) { + state->limit_dist -= 0.01f; + state->limit_dist = MAX2(0.01f, state->limit_dist); + if (!stitch_process_data(state, scene, FALSE)) { return stitch_cancel(C, op); } break; @@ -1490,11 +2049,11 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_PASS_THROUGH; } - /* Use Limit (Default off)*/ + /* Use Limit (Default off)*/ case LKEY: if (event->val == KM_PRESS) { - stitch_state->use_limit = !stitch_state->use_limit; - if (!stitch_process_data(stitch_state, scene, 0)) { + state->use_limit = !state->use_limit; + if (!stitch_process_data(state, scene, FALSE)) { return stitch_cancel(C, op); } break; @@ -1503,10 +2062,10 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event) case IKEY: if (event->val == KM_PRESS) { - stitch_state->static_island++; - stitch_state->static_island %= stitch_state->element_map->totalIslands; + state->static_island++; + state->static_island %= state->element_map->totalIslands; - if (!stitch_process_data(stitch_state, scene, 0)) { + if (!stitch_process_data(state, scene, FALSE)) { return stitch_cancel(C, op); } break; @@ -1515,33 +2074,33 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event) case MKEY: if (event->val == KM_PRESS) { - stitch_state->midpoints = !stitch_state->midpoints; - if (!stitch_process_data(stitch_state, scene, 0)) { + state->midpoints = !state->midpoints; + if (!stitch_process_data(state, scene, FALSE)) { return stitch_cancel(C, op); } } break; - /* Select geometry*/ + /* Select geometry*/ case RIGHTMOUSE: if (!event->shift) { return stitch_cancel(C, op); } - if (event->val == KM_RELEASE && !(U.flag & USER_LMOUSESELECT)) { - stitch_select(C, scene, event, stitch_state); + if (event->val == KM_PRESS && !(U.flag & USER_LMOUSESELECT)) { + stitch_select(C, scene, event, state); - if (!stitch_process_data(stitch_state, scene, 0)) { + if (!stitch_process_data(state, scene, FALSE)) { return stitch_cancel(C, op); } break; } return OPERATOR_RUNNING_MODAL; - /* snap islands on/off */ + /* snap islands on/off */ case SKEY: if (event->val == KM_PRESS) { - stitch_state->snap_islands = !stitch_state->snap_islands; - if (!stitch_process_data(stitch_state, scene, 0)) { + state->snap_islands = !state->snap_islands; + if (!stitch_process_data(state, scene, FALSE)) { return stitch_cancel(C, op); } break; @@ -1550,12 +2109,23 @@ static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_RUNNING_MODAL; } + /* switch between edge/vertex mode */ + case TABKEY: + if (event->val == KM_PRESS) { + stitch_switch_selection_mode(state); + + if (!stitch_process_data(state, scene, FALSE)) { + return stitch_cancel(C, op); + } + } + break; + default: return OPERATOR_RUNNING_MODAL; } /* if updated settings, renew feedback message */ - stitch_update_header(stitch_state, C); + stitch_update_header(state, C); ED_region_tag_redraw(CTX_wm_region(C)); return OPERATOR_RUNNING_MODAL; } @@ -1564,6 +2134,12 @@ void UV_OT_stitch(wmOperatorType *ot) { PropertyRNA *prop; + static EnumPropertyItem stitch_modes[] = { + {STITCH_VERT, "VERTEX", 0, "Vertex", ""}, + {STITCH_EDGE, "EDGE", 0, "Edge", ""}, + {0, NULL, 0, NULL, NULL} + }; + /* identifiers */ ot->name = "Stitch"; ot->description = "Stitch selected UV vertices by proximity"; @@ -1590,6 +2166,11 @@ void UV_OT_stitch(wmOperatorType *ot) "UVs are stitched at midpoint instead of at static island"); RNA_def_boolean(ot->srna, "clear_seams", 1, "Clear Seams", "Clear seams of stitched edges"); + RNA_def_enum(ot->srna, "mode", stitch_modes, STITCH_VERT, "Operation Mode", + "Use vertex or edge stitching"); + prop = RNA_def_enum(ot->srna, "stored_mode", stitch_modes, STITCH_VERT, "Stored Operation Mode", + "Use vertex or edge stitching"); + RNA_def_property_flag(prop, PROP_HIDDEN); prop = RNA_def_collection_runtime(ot->srna, "selection", &RNA_SelectedUvElement, "Selection", ""); /* Selection should not be editable or viewed in toolbar */ RNA_def_property_flag(prop, PROP_HIDDEN); diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 1f3f21967f4..2ca711a4a6a 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -87,6 +87,24 @@ #include "uvedit_intern.h" #include "uvedit_parametrizer.h" +static void modifier_unwrap_state(Object *obedit, Scene *scene, short *use_subsurf) +{ + ModifierData *md; + short subsurf = scene->toolsettings->uvcalc_flag & UVCALC_USESUBSURF; + + md = obedit->modifiers.first; + + /* subsurf will take the modifier settings only if modifier is first or right after mirror */ + if (subsurf) { + if (md && md->type == eModifierType_Subsurf) + subsurf = TRUE; + else + subsurf = FALSE; + } + + *use_subsurf = subsurf; +} + static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit) { Main *bmain = CTX_data_main(C); @@ -379,6 +397,9 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B MEdge *edge; int i; + /* pointers to modifier data for unwrap control */ + ModifierData *md; + SubsurfModifierData *smd_real; /* modifier initialization data, will control what type of subdivision will happen*/ SubsurfModifierData smd = {{0}}; /* Used to hold subsurfed Mesh */ @@ -409,8 +430,11 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B } /* number of subdivisions to perform */ - smd.levels = scene->toolsettings->uv_subsurf_level; - smd.subdivType = ME_CC_SUBSURF; + md = ob->modifiers.first; + smd_real = (SubsurfModifierData *)md; + + smd.levels = smd_real->levels; + smd.subdivType = smd_real->subdivType; initialDerived = CDDM_from_editbmesh(em, FALSE, FALSE); derivedMesh = subsurf_make_derived_from_derived(initialDerived, &smd, @@ -434,7 +458,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B faceMap = MEM_mallocN(numOfFaces * sizeof(BMFace *), "unwrap_edit_face_map"); BM_mesh_elem_index_ensure(em->bm, BM_VERT); - EDBM_index_arrays_init(em, 0, 1, 1); + EDBM_index_arrays_ensure(em, BM_EDGE | BM_FACE); /* map subsurfed faces to original editFaces */ for (i = 0; i < numOfFaces; i++) @@ -445,12 +469,10 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B /* map subsurfed edges to original editEdges */ for (i = 0; i < numOfEdges; i++) { /* not all edges correspond to an old edge */ - edgeMap[i] = (origEdgeIndices[i] != -1) ? + edgeMap[i] = (origEdgeIndices[i] != ORIGINDEX_NONE) ? EDBM_edge_at_index(em, origEdgeIndices[i]) : NULL; } - EDBM_index_arrays_free(em); - /* Prepare and feed faces to the solver */ for (i = 0; i < numOfFaces; i++) { ParamKey key, vkeys[4]; @@ -815,16 +837,18 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit) BMEditMesh *em = BMEdit_FromObject(obedit); short abf = scene->toolsettings->unwrapper == 0; short fillholes = scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES; - short use_subsurf = scene->toolsettings->uvcalc_flag & UVCALC_USESUBSURF; + short use_subsurf; + + modifier_unwrap_state(obedit, scene, &use_subsurf); if (!ED_uvedit_test(obedit)) { return; } if (use_subsurf) - liveHandle = construct_param_handle_subsurfed(scene, obedit, em, fillholes, 0, 1); + liveHandle = construct_param_handle_subsurfed(scene, obedit, em, fillholes, FALSE, TRUE); else - liveHandle = construct_param_handle(scene, obedit, em, 0, fillholes, 0, 1); + liveHandle = construct_param_handle(scene, obedit, em, FALSE, fillholes, FALSE, TRUE); param_lscm_begin(liveHandle, PARAM_TRUE, abf); } @@ -871,16 +895,18 @@ void ED_uvedit_live_unwrap(Scene *scene, Object *obedit) static void uv_map_transform_center(Scene *scene, View3D *v3d, float *result, Object *ob, BMEditMesh *em) { - BMFace *efa; - BMLoop *l; - BMIter iter, liter; - float min[3], max[3], *cursx; int around = (v3d) ? v3d->around : V3D_CENTER; /* only operates on the edit object - this is all that's needed now */ switch (around) { case V3D_CENTER: /* bounding box center */ + { + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + float min[3], max[3]; + INIT_MINMAX(min, max); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { @@ -892,22 +918,23 @@ static void uv_map_transform_center(Scene *scene, View3D *v3d, float *result, } mid_v3_v3v3(result, min, max); break; - + } case V3D_CURSOR: /* cursor center */ - cursx = give_cursor(scene, v3d); + { + const float *curs = give_cursor(scene, v3d); /* shift to objects world */ - sub_v3_v3v3(result, cursx, ob->obmat[3]); + sub_v3_v3v3(result, curs, ob->obmat[3]); break; - + } case V3D_LOCAL: /* object center */ case V3D_CENTROID: /* multiple objects centers, only one object here*/ default: - result[0] = result[1] = result[2] = 0.0; + zero_v3(result); break; } } -static void uv_map_rotation_matrix(float result[][4], RegionView3D *rv3d, Object *ob, +static void uv_map_rotation_matrix(float result[4][4], RegionView3D *rv3d, Object *ob, float upangledeg, float sideangledeg, float radius) { float rotup[4][4], rotside[4][4], viewmatrix[4][4], rotobj[4][4]; @@ -1139,12 +1166,14 @@ void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel) const short fill_holes = scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES; const short correct_aspect = !(scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT); - const short use_subsurf = scene->toolsettings->uvcalc_flag & UVCALC_USESUBSURF; + short use_subsurf; + + modifier_unwrap_state(obedit, scene, &use_subsurf); if (use_subsurf) handle = construct_param_handle_subsurfed(scene, obedit, em, fill_holes, sel, correct_aspect); else - handle = construct_param_handle(scene, obedit, em, 0, fill_holes, sel, correct_aspect); + handle = construct_param_handle(scene, obedit, em, FALSE, fill_holes, sel, correct_aspect); param_lscm_begin(handle, PARAM_FALSE, scene->toolsettings->unwrapper == 0); param_lscm_solve(handle); @@ -1167,7 +1196,7 @@ static int unwrap_exec(bContext *C, wmOperator *op) int fill_holes = RNA_boolean_get(op->ptr, "fill_holes"); int correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect"); int use_subsurf = RNA_boolean_get(op->ptr, "use_subsurf_data"); - int subsurf_level = RNA_int_get(op->ptr, "uv_subsurf_level"); + short use_subsurf_final; float obsize[3]; short implicit = 0; @@ -1197,8 +1226,6 @@ static int unwrap_exec(bContext *C, wmOperator *op) 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; else scene->toolsettings->uvcalc_flag &= ~UVCALC_FILLHOLES; @@ -1208,6 +1235,12 @@ static int unwrap_exec(bContext *C, wmOperator *op) if (use_subsurf) scene->toolsettings->uvcalc_flag |= UVCALC_USESUBSURF; else scene->toolsettings->uvcalc_flag &= ~UVCALC_USESUBSURF; + /* double up the check here but better keep ED_unwrap_lscm interface simple and not + * pass operator for warning append */ + modifier_unwrap_state(obedit, scene, &use_subsurf_final); + if (use_subsurf != use_subsurf_final) + BKE_report(op->reports, RPT_INFO, "Subsurf modifier needs to be first to work with unwrap"); + /* execute unwrap */ ED_unwrap_lscm(scene, obedit, TRUE); @@ -1242,10 +1275,8 @@ void UV_OT_unwrap(wmOperatorType *ot) "Virtual fill holes in mesh before unwrapping, to better avoid overlaps and preserve symmetry"); RNA_def_boolean(ot->srna, "correct_aspect", 1, "Correct Aspect", "Map UVs taking image aspect ratio into account"); - RNA_def_boolean(ot->srna, "use_subsurf_data", 0, "Use Subsurf Data", + RNA_def_boolean(ot->srna, "use_subsurf_data", 0, "Use Subsurf Modifier", "Map UVs taking vertex position after subsurf into account"); - 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); } @@ -1413,8 +1444,7 @@ static void uv_map_mirror(BMEditMesh *em, BMFace *efa, MTexPoly *UNUSED(tf)) BMLoop *l; BMIter liter; MLoopUV *luv; - float **uvs = NULL; - BLI_array_fixedstack_declare(uvs, BM_DEFAULT_NGON_STACK_SIZE, efa->len, __func__); + float **uvs = BLI_array_alloca(uvs, efa->len); float dx; int i, mi; @@ -1436,8 +1466,6 @@ static void uv_map_mirror(BMEditMesh *em, BMFace *efa, MTexPoly *UNUSED(tf)) if (dx > 0.5f) uvs[i][0] += 1.0f; } } - - BLI_array_fixedstack_free(uvs); } static int sphere_project_exec(bContext *C, wmOperator *op) |