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 | |
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')
509 files changed, 13764 insertions, 6179 deletions
diff --git a/source/SConscript b/source/SConscript index fdd126b28c6..432cfb31c7d 100644 --- a/source/SConscript +++ b/source/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') SConscript(['blender/SConscript']) diff --git a/source/blender/SConscript b/source/blender/SConscript index 2b6db32f00a..ff1d6b5de0a 100644 --- a/source/blender/SConscript +++ b/source/blender/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') import sys diff --git a/source/blender/avi/SConscript b/source/blender/avi/SConscript index 4d2ce8fd845..0e46781b768 100644 --- a/source/blender/avi/SConscript +++ b/source/blender/avi/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('intern/*.c') diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h index 6f348ccc267..25b55eacd77 100644 --- a/source/blender/blenfont/BLF_api.h +++ b/source/blender/blenfont/BLF_api.h @@ -37,6 +37,7 @@ struct ColorManagedDisplay; int BLF_init(int points, int dpi); void BLF_exit(void); +void BLF_default_dpi(int dpi); void BLF_cache_clear(void); diff --git a/source/blender/blenfont/BLF_translation.h b/source/blender/blenfont/BLF_translation.h index 8eb40384044..eb3518ac997 100644 --- a/source/blender/blenfont/BLF_translation.h +++ b/source/blender/blenfont/BLF_translation.h @@ -85,8 +85,8 @@ const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid); /* #define _(msgid) msgid */ #define IFACE_(msgid) msgid #define TIP_(msgid) msgid - #define CTX_IFACE_(context, msgid) ((void)context, msgid) - #define CTX_TIP_(context, msgid) ((void)context, msgid) + #define CTX_IFACE_(context, msgid) msgid + #define CTX_TIP_(context, msgid) msgid #endif /* Helper macro, when we want to define a same msgid for multiple msgctxt... diff --git a/source/blender/blenfont/SConscript b/source/blender/blenfont/SConscript index c0591c877ef..a6ea724a51f 100644 --- a/source/blender/blenfont/SConscript +++ b/source/blender/blenfont/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 sys Import ('env') diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index 778b6c11e5a..16756769675 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -87,6 +87,11 @@ int BLF_init(int points, int dpi) return blf_font_init(); } +void BLF_default_dpi(int dpi) +{ + global_font_dpi = dpi; +} + void BLF_exit(void) { FontBLF *font; diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c index 0ed48623dd5..4d066ea8740 100644 --- a/source/blender/blenfont/intern/blf_lang.c +++ b/source/blender/blenfont/intern/blf_lang.c @@ -30,6 +30,8 @@ #include "BLF_translation.h" /* own include */ +#include "BLI_utildefines.h" + #ifdef WITH_INTERNATIONAL #include <stdio.h> @@ -50,7 +52,6 @@ #include "BLI_linklist.h" #include "BLI_path_util.h" #include "BLI_string.h" -#include "BLI_utildefines.h" /* Locale options. */ static const char **locales = NULL; @@ -254,9 +255,8 @@ void BLF_lang_free(void) return; } -void BLF_lang_set(const char *str) +void BLF_lang_set(const char *UNUSED(str)) { - (void)str; return; } diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 617c4cd2bc8..ed90c63d949 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -105,6 +105,11 @@ struct PBVH; * Also, the mface origindex layer indexes mpolys, not mfaces. */ +typedef struct DMCoNo { + float co[3]; + float no[3]; +} DMCoNo; + typedef struct DMGridAdjacency { int index[4]; int rotation[4]; @@ -603,7 +608,7 @@ void vDM_ColorBand_store(struct ColorBand *coba); /** Simple function to get me->totvert amount of vertices/normals, * correctly deformed and subsurfered. Needed especially when vertexgroups are involved. * In use now by vertex/weight paint and particles */ -float *mesh_get_mapped_verts_nors(struct Scene *scene, struct Object *ob); +DMCoNo *mesh_get_mapped_verts_nors(struct Scene *scene, struct Object *ob); /* */ DerivedMesh *mesh_get_derived_final(struct Scene *scene, struct Object *ob, diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index b0f372e0bac..765a00b8d4b 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -97,28 +97,28 @@ void BKE_pose_where_is_bone(struct Scene *scene, struct Object *ob, struct bPose void BKE_pose_where_is_bone_tail(struct bPoseChannel *pchan); /* get_objectspace_bone_matrix has to be removed still */ -void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[][4], int root, int posed); -void vec_roll_to_mat3(const float vec[3], const float roll, float mat[][3]); -void mat3_to_vec_roll(float mat[][3], float r_vec[3], float *r_roll); +void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[4][4], int root, int posed); +void vec_roll_to_mat3(const float vec[3], const float roll, float mat[3][3]); +void mat3_to_vec_roll(float mat[3][3], float r_vec[3], float *r_roll); /* Common Conversions Between Co-ordinate Spaces */ -void BKE_armature_mat_world_to_pose(struct Object *ob, float inmat[][4], float outmat[][4]); +void BKE_armature_mat_world_to_pose(struct Object *ob, float inmat[4][4], float outmat[4][4]); void BKE_armature_loc_world_to_pose(struct Object *ob, const float inloc[3], float outloc[3]); -void BKE_armature_mat_pose_to_bone(struct bPoseChannel *pchan, float inmat[][4], float outmat[][4]); +void BKE_armature_mat_pose_to_bone(struct bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]); void BKE_armature_loc_pose_to_bone(struct bPoseChannel *pchan, const float inloc[3], float outloc[3]); -void BKE_armature_mat_bone_to_pose(struct bPoseChannel *pchan, float inmat[][4], float outmat[][4]); -void BKE_armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4]); +void BKE_armature_mat_bone_to_pose(struct bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]); +void BKE_armature_mat_pose_to_delta(float delta_mat[4][4], float pose_mat[4][4], float arm_mat[4][4]); -void BKE_armature_mat_pose_to_bone_ex(struct Object *ob, struct bPoseChannel *pchan, float inmat[][4], float outmat[][4]); +void BKE_armature_mat_pose_to_bone_ex(struct Object *ob, struct bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]); -void BKE_pchan_mat3_to_rot(struct bPoseChannel *pchan, float mat[][3], short use_compat); -void BKE_pchan_apply_mat4(struct bPoseChannel *pchan, float mat[][4], short use_comat); +void BKE_pchan_mat3_to_rot(struct bPoseChannel *pchan, float mat[3][3], short use_compat); +void BKE_pchan_apply_mat4(struct bPoseChannel *pchan, float mat[4][4], short use_comat); void BKE_pchan_to_mat4(struct bPoseChannel *pchan, float chan_mat[4][4]); void BKE_pchan_calc_mat(struct bPoseChannel *pchan); /* Get the "pchan to pose" transform matrix. These matrices apply the effects of * HINGE/NO_SCALE/NO_LOCAL_LOCATION options over the pchan loc/rot/scale transformations. */ -void BKE_pchan_to_pose_mat(struct bPoseChannel *pchan, float rotscale_mat[][4], float loc_mat[][4]); +void BKE_pchan_to_pose_mat(struct bPoseChannel *pchan, float rotscale_mat[4][4], float loc_mat[4][4]); /* Rotation Mode Conversions - Used for PoseChannels + Objects... */ void BKE_rotMode_change_values(float quat[4], float eul[3], float axis[3], float *angle, short oldMode, short newMode); diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index b624d0f9c3a..570086e9b69 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 265 -#define BLENDER_SUBVERSION 0 +#define BLENDER_SUBVERSION 3 /* 262 was the last editmesh release but it has compatibility code for bmesh data */ #define BLENDER_MINVERSION 262 @@ -52,7 +52,7 @@ extern "C" { /* can be left blank, otherwise a,b,c... etc with no quotes */ #define BLENDER_VERSION_CHAR /* alpha/beta/rc/release, docs use this */ -#define BLENDER_VERSION_CYCLE release +#define BLENDER_VERSION_CYCLE alpha extern char versionstr[]; /* from blender.c */ @@ -62,6 +62,7 @@ struct bContext; struct ReportList; struct Scene; struct Main; +struct ID; int BKE_read_file(struct bContext *C, const char *filepath, struct ReportList *reports); @@ -72,12 +73,17 @@ int BKE_read_file(struct bContext *C, const char *filepath, struct ReportList *r int BKE_read_file_from_memory(struct bContext *C, char *filebuf, int filelength, struct ReportList *reports); int BKE_read_file_from_memfile(struct bContext *C, struct MemFile *memfile, struct ReportList *reports); +int BKE_read_file_userdef(const char *filepath, struct ReportList *reports); +int BKE_write_file_userdef(const char *filepath, struct ReportList *reports); + void free_blender(void); void initglobals(void); /* load new userdef from file, exit blender */ void BKE_userdef_free(void); - +/* handle changes in userdef */ +void BKE_userdef_state(void); + /* set this callback when a UI is running */ void set_blender_test_break_cb(void (*func)(void) ); int blender_test_break(void); @@ -93,9 +99,15 @@ extern void BKE_reset_undo(void); extern char *BKE_undo_menu_string(void); extern void BKE_undo_number(struct bContext *C, int nr); extern const char *BKE_undo_get_name(int nr, int *active); -extern void BKE_undo_save_quit(void); +extern int BKE_undo_save_file(const char *filename); extern struct Main *BKE_undo_get_main(struct Scene **scene); + /* copybuffer */ +void BKE_copybuffer_begin(void); +void BKE_copybuffer_tag_ID(struct ID *id); +int BKE_copybuffer_save(char *filename, struct ReportList *reports); + int BKE_copybuffer_paste(struct bContext *C, char *libname, struct ReportList *reports); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_bpath.h b/source/blender/blenkernel/BKE_bpath.h index 438bffb2fc5..16a8b1be85b 100644 --- a/source/blender/blenlib/BLI_bpath.h +++ b/source/blender/blenkernel/BKE_bpath.h @@ -25,14 +25,14 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file BLI_bpath.h - * \ingroup bli +/** \file BKE_bpath.h + * \ingroup bke * \attention Based on ghash, difference is ghash is not a fixed size, * so for BPath we don't need to malloc */ -#ifndef __BLI_BPATH_H__ -#define __BLI_BPATH_H__ +#ifndef __BKE_BPATH_H__ +#define __BKE_BPATH_H__ struct ID; struct ListBase; @@ -43,20 +43,20 @@ struct ReportList; * path has changed, and in that case, should write the result to pathOut. */ typedef int (*BPathVisitor)(void *userdata, char *path_dst, const char *path_src); /* Executes 'visit' for each path associated with 'id'. */ -void BLI_bpath_traverse_id(struct Main *bmain, struct ID *id, BPathVisitor visit_cb, const int flag, void *userdata); -void BLI_bpath_traverse_id_list(struct Main *bmain, struct ListBase *lb, BPathVisitor visit_cb, const int flag, void *userdata); -void BLI_bpath_traverse_main(struct Main *bmain, BPathVisitor visit_cb, const int flag, void *userdata); -int BLI_bpath_relocate_visitor(void *oldbasepath, char *path_dst, const char *path_src); +void BKE_bpath_traverse_id(struct Main *bmain, struct ID *id, BPathVisitor visit_cb, const int flag, void *userdata); +void BKE_bpath_traverse_id_list(struct Main *bmain, struct ListBase *lb, BPathVisitor visit_cb, const int flag, void *userdata); +void BKE_bpath_traverse_main(struct Main *bmain, BPathVisitor visit_cb, const int flag, void *userdata); +int BKE_bpath_relocate_visitor(void *oldbasepath, char *path_dst, const char *path_src); /* Functions for temp backup/restore of paths, path count must NOT change */ -void *BLI_bpath_list_backup(struct Main *bmain, const int flag); -void BLI_bpath_list_restore(struct Main *bmain, const int flag, void *ls_handle); -void BLI_bpath_list_free(void *ls_handle); +void *BKE_bpath_list_backup(struct Main *bmain, const int flag); +void BKE_bpath_list_restore(struct Main *bmain, const int flag, void *ls_handle); +void BKE_bpath_list_free(void *ls_handle); -#define BLI_BPATH_TRAVERSE_ABS (1 << 0) /* convert paths to absolute */ -#define BLI_BPATH_TRAVERSE_SKIP_LIBRARY (1 << 2) /* skip library paths */ -#define BLI_BPATH_TRAVERSE_SKIP_PACKED (1 << 3) /* skip packed data */ -#define BLI_BPATH_TRAVERSE_SKIP_MULTIFILE (1 << 4) /* skip paths where a single dir is used with an array of files, eg. +#define BKE_BPATH_TRAVERSE_ABS (1 << 0) /* convert paths to absolute */ +#define BKE_BPATH_TRAVERSE_SKIP_LIBRARY (1 << 2) /* skip library paths */ +#define BKE_BPATH_TRAVERSE_SKIP_PACKED (1 << 3) /* skip packed data */ +#define BKE_BPATH_TRAVERSE_SKIP_MULTIFILE (1 << 4) /* skip paths where a single dir is used with an array of files, eg. * sequence strip images and pointcache. in this case only use the first * file, this is needed for directory manipulation functions which might * otherwise modify the same directory multiple times */ @@ -64,9 +64,9 @@ void BLI_bpath_list_free(void *ls_handle); /* high level funcs */ /* creates a text file with missing files if there are any */ -void BLI_bpath_missing_files_check(struct Main *bmain, struct ReportList *reports); -void BLI_bpath_missing_files_find(struct Main *bmain, const char *searchpath, struct ReportList *reports); -void BLI_bpath_relative_convert(struct Main *bmain, const char *basedir, struct ReportList *reports); -void BLI_bpath_absolute_convert(struct Main *bmain, const char *basedir, struct ReportList *reports); +void BKE_bpath_missing_files_check(struct Main *bmain, struct ReportList *reports); +void BKE_bpath_missing_files_find(struct Main *bmain, const char *searchpath, struct ReportList *reports); +void BKE_bpath_relative_convert(struct Main *bmain, const char *basedir, struct ReportList *reports); +void BKE_bpath_absolute_convert(struct Main *bmain, const char *basedir, struct ReportList *reports); -#endif /* __BLI_BPATH_H__ */ +#endif /* __BKE_BPATH_H__ */ diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h index 686a60ab2c9..79e75127763 100644 --- a/source/blender/blenkernel/BKE_constraint.h +++ b/source/blender/blenkernel/BKE_constraint.h @@ -147,9 +147,9 @@ short proxylocked_constraints_owner(struct Object *ob, struct bPoseChannel *pcha struct bConstraintOb *constraints_make_evalob(struct Scene *scene, struct Object *ob, void *subdata, short datatype); void constraints_clear_evalob(struct bConstraintOb *cob); -void constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, float mat[][4], short from, short to); +void constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, float mat[4][4], short from, short to); -void get_constraint_target_matrix(struct Scene *scene, struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime); +void get_constraint_target_matrix(struct Scene *scene, struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[4][4], float ctime); void get_constraint_targets_for_solving(struct bConstraint *con, struct bConstraintOb *ob, struct ListBase *targets, float ctime); void solve_constraints(struct ListBase *conlist, struct bConstraintOb *cob, float ctime); diff --git a/source/blender/blenkernel/BKE_fluidsim.h b/source/blender/blenkernel/BKE_fluidsim.h index c3fa6621c98..433c10b82f1 100644 --- a/source/blender/blenkernel/BKE_fluidsim.h +++ b/source/blender/blenkernel/BKE_fluidsim.h @@ -47,7 +47,7 @@ void initElbeemMesh(struct Scene *scene, struct Object *ob, int useGlobalCoords, int modifierIndex); /* bounding box & memory estimate */ -void fluid_get_bb(struct MVert *mvert, int totvert, float obmat[][4], +void fluid_get_bb(struct MVert *mvert, int totvert, float obmat[4][4], float start[3], float size[3]); void fluid_estimate_memory(struct Object *ob, struct FluidsimSettings *fss, char *value); diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index f6276a69d57..38a88607119 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -149,7 +149,7 @@ enum { /* #define G_FILE_SHOW_PROFILE (1 << 6) */ /* deprecated */ #define G_FILE_LOCK (1 << 7) #define G_FILE_SIGN (1 << 8) -/* #define G_FILE_PUBLISH (1 << 9) */ /* deprecated */ +#define G_FILE_USERPREFS (1 << 9) #define G_FILE_NO_UI (1 << 10) /* #define G_FILE_GAME_TO_IPO (1 << 11) */ /* deprecated */ #define G_FILE_GAME_MAT (1 << 12) /* deprecated */ diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h index 34baa48dbe2..a0bebd752b5 100644 --- a/source/blender/blenkernel/BKE_lattice.h +++ b/source/blender/blenkernel/BKE_lattice.h @@ -59,7 +59,7 @@ void curve_deform_verts(struct Scene *scene, struct Object *cuOb, struct Object struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts, const char *vgroup, short defaxis); void curve_deform_vector(struct Scene *scene, struct Object *cuOb, struct Object *target, - float orco[3], float vec[3], float mat[][3], int no_rot_axis); + float orco[3], float vec[3], float mat[3][3], int no_rot_axis); void lattice_deform_verts(struct Object *laOb, struct Object *target, struct DerivedMesh *dm, float (*vertexCos)[3], diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index bc081b7f308..b9bb67fa509 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -62,6 +62,7 @@ void BKE_libblock_copy_data(struct ID *id, const struct ID *id_from, const shor void BKE_id_lib_local_paths(struct Main *bmain, struct Library *lib, struct ID *id); void id_lib_extern(struct ID *id); void BKE_library_filepath_set(struct Library *lib, const char *filepath); +void id_us_ensure_real(struct ID *id); void id_us_plus(struct ID *id); void id_us_min(struct ID *id); diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h index 06931662d3f..cb8f1a7d682 100644 --- a/source/blender/blenkernel/BKE_main.h +++ b/source/blender/blenkernel/BKE_main.h @@ -51,9 +51,10 @@ struct Library; typedef struct Main { struct Main *next, *prev; char name[1024]; /* 1024 = FILE_MAX */ - short versionfile, subversionfile; + short versionfile, subversionfile; /* see BLENDER_VERSION, BLENDER_SUBVERSION */ short minversionfile, minsubversionfile; - int revision; /* svn revision of binary that saved file */ + int revision; /* svn revision of binary that saved file */ + short recovered; /* indicate the main->name (file) is the recovered one */ struct Library *curlib; ListBase scene; @@ -92,6 +93,8 @@ typedef struct Main { char id_tag_update[256]; } Main; +#define MAIN_VERSION_ATLEAST(main, ver, subver) \ + ((main)->versionfile >= (ver) || (main->versionfile == (ver) && (main)->subversionfile >= (subver))) #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index e53d0efffbd..3fc1b7d6136 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -229,8 +229,6 @@ typedef struct UvElement { /* Next UvElement corresponding to same vertex */ struct UvElement *next; /* Face the element belongs to */ - struct BMFace *face; - /* Index in the editFace of the uv */ struct BMLoop *l; /* index in loop. */ unsigned short tfindex; diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 2fa78b30835..cc260b8f60c 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -358,8 +358,6 @@ int modifiers_isCorrectableDeformed(struct Object *ob); void modifier_freeTemporaryData(struct ModifierData *md); int modifiers_isPreview(struct Object *ob); -int modifiers_indexInObject(struct Object *ob, struct ModifierData *md); - typedef struct CDMaskLink { struct CDMaskLink *next; CustomDataMask mask; diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index ec0703248fd..bfae1bd2390 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -76,7 +76,8 @@ void BKE_object_copy_proxy_drivers(struct Object *ob, struct Object *target); void BKE_object_unlink(struct Object *ob); int BKE_object_exists_check(struct Object *obtest); - +int BKE_object_is_in_editmode(struct Object *ob); + struct Object *BKE_object_add_only_object(int type, const char *name); struct Object *BKE_object_add(struct Scene *scene, int type); void *BKE_object_obdata_add_from_type(int type); @@ -87,12 +88,12 @@ void BKE_object_make_local(struct Object *ob); int BKE_object_is_libdata(struct Object *ob); int BKE_object_obdata_is_libdata(struct Object *ob); -void BKE_object_scale_to_mat3(struct Object *ob, float mat[][3]); -void BKE_object_rot_to_mat3(struct Object *ob, float mat[][3]); -void BKE_object_mat3_to_rot(struct Object *ob, float mat[][3], short use_compat); -void BKE_object_to_mat3(struct Object *ob, float mat[][3]); -void BKE_object_to_mat4(struct Object *ob, float mat[][4]); -void BKE_object_apply_mat4(struct Object *ob, float mat[][4], const short use_compat, const short use_parent); +void BKE_object_scale_to_mat3(struct Object *ob, float mat[3][3]); +void BKE_object_rot_to_mat3(struct Object *ob, float mat[3][3], short use_drot); +void BKE_object_mat3_to_rot(struct Object *ob, float mat[3][3], short use_compat); +void BKE_object_to_mat3(struct Object *ob, float mat[3][3]); +void BKE_object_to_mat4(struct Object *ob, float mat[4][4]); +void BKE_object_apply_mat4(struct Object *ob, float mat[4][4], const short use_compat, const short use_parent); int BKE_object_pose_context_check(struct Object *ob); struct Object *BKE_object_pose_armature_get(struct Object *ob); diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index ec03f53dbdb..f15ad296e4a 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -20,7 +20,9 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Adaptive time step + * Classical SPH + * Copyright 2011-2012 AutoCRC * * ***** END GPL LICENSE BLOCK ***** */ @@ -58,6 +60,7 @@ struct RNG; struct SurfaceModifierData; struct BVHTreeRay; struct BVHTreeRayHit; +struct EdgeHash; #define PARTICLE_P ParticleData * pa; int p #define LOOP_PARTICLES for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++) @@ -85,6 +88,24 @@ typedef struct ParticleSimulationData { float courant_num; } ParticleSimulationData; +typedef struct SPHData { + ParticleSystem *psys[10]; + ParticleData *pa; + float mass; + struct EdgeHash *eh; + float *gravity; + float hfac; + /* Average distance to neighbours (other particles in the support domain), + for calculating the Courant number (adaptive time step). */ + int pass; + float element_size; + float flow[3]; + + /* Integrator callbacks. This allows different SPH implementations. */ + void (*force_cb) (void *sphdata_v, ParticleKey *state, float *force, float *impulse); + void (*density_cb) (void *rangedata_v, int index, float squared_dist); +} SPHData; + typedef struct ParticleTexture { float ivel; /* used in reset */ float time, life, exist, size; /* used in init */ @@ -247,7 +268,7 @@ void BKE_particlesettings_free(struct ParticleSettings *part); void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit); void psys_free(struct Object *ob, struct ParticleSystem *psys); -void psys_render_set(struct Object *ob, struct ParticleSystem *psys, float viewmat[][4], float winmat[][4], int winx, int winy, int timeoffset); +void psys_render_set(struct Object *ob, struct ParticleSystem *psys, float viewmat[4][4], float winmat[4][4], int winx, int winy, int timeoffset); void psys_render_restore(struct Object *ob, struct ParticleSystem *psys); int psys_render_simplify_distribution(struct ParticleThreadContext *ctx, int tot); int psys_render_simplify_params(struct ParticleSystem *psys, struct ChildParticle *cpa, float *params); @@ -283,12 +304,16 @@ float psys_get_child_size(struct ParticleSystem *psys, struct ChildParticle *cpa void psys_get_particle_on_path(struct ParticleSimulationData *sim, int pa_num, struct ParticleKey *state, int vel); int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, int always); +void psys_sph_init(struct ParticleSimulationData *sim, struct SPHData *sphdata); +void psys_sph_finalise(struct SPHData *sphdata); +void psys_sph_density(struct BVHTree *tree, struct SPHData* data, float co[3], float vars[2]); + /* for anim.c */ void psys_get_dupli_texture(struct ParticleSystem *psys, struct ParticleSettings *part, struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, float uv[2], float orco[3]); void psys_get_dupli_path_transform(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ChildParticle *cpa, - struct ParticleCacheKey *cache, float mat[][4], float *scale); + struct ParticleCacheKey *cache, float mat[4][4], float *scale); ParticleThread *psys_threads_create(struct ParticleSimulationData *sim); void psys_threads_free(ParticleThread *threads); @@ -322,9 +347,9 @@ void psys_free_children(struct ParticleSystem *psys); void psys_interpolate_particle(short type, struct ParticleKey keys[4], float dt, struct ParticleKey *result, int velocity); void psys_vec_rot_to_face(struct DerivedMesh *dm, struct ParticleData *pa, float vec[3]); -void psys_mat_hair_to_object(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]); -void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]); -void psys_mat_hair_to_orco(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]); +void psys_mat_hair_to_object(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]); +void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]); +void psys_mat_hair_to_orco(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]); float psys_get_dietime_from_cache(struct PointCache *cache, int index); diff --git a/source/blender/blenlib/BLI_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 59ecdb359c9..302de593963 100644 --- a/source/blender/blenlib/BLI_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -21,8 +21,8 @@ #ifndef __BLI_PBVH_H__ #define __BLI_PBVH_H__ -/** \file BLI_pbvh.h - * \ingroup bli +/** \file BKE_pbvh.h + * \ingroup bke * \brief A BVH for high poly meshes. */ diff --git a/source/blender/blenkernel/BKE_property.h b/source/blender/blenkernel/BKE_property.h index e0eb8c04b60..99e60757f15 100644 --- a/source/blender/blenkernel/BKE_property.h +++ b/source/blender/blenkernel/BKE_property.h @@ -47,6 +47,7 @@ void BKE_bproperty_object_set(struct Object *ob, struct bProperty * // int BKE_bproperty_cmp(struct bProperty *prop, const char *str); void BKE_bproperty_set(struct bProperty *prop, const char *str); void BKE_bproperty_add(struct bProperty *prop, const char *str); -void BKE_bproperty_set_valstr(struct bProperty *prop, char *str); +/* should really be called '_get_valstr()' or '_as_string()' */ +void BKE_bproperty_set_valstr(struct bProperty *prop, char str[MAX_PROPSTRING]); #endif diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 9927c7a42ed..6447b2a8dee 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -47,7 +47,7 @@ struct RenderData; struct SceneRenderLayer; struct Scene; struct Text; -struct Text; +struct Main; #define SCE_COPY_NEW 0 #define SCE_COPY_EMPTY 1 @@ -67,7 +67,7 @@ void free_avicodecdata(struct AviCodecData *acd); void free_qtcodecdata(struct QuicktimeCodecData *acd); void BKE_scene_free(struct Scene *sce); -struct Scene *BKE_scene_add(const char *name); +struct Scene *BKE_scene_add(struct Main *bmain, const char *name); /* base functions */ struct Base *BKE_scene_base_find(struct Scene *scene, struct Object *ob); diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 88294cb30b6..e3d9c513c5c 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -363,7 +363,7 @@ struct Sequence *BKE_sequencer_add_sound_strip(struct bContext *C, ListBase *seq struct Sequence *BKE_sequencer_add_movie_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load); /* view3d draw callback, run when not in background view */ -typedef struct ImBuf *(*SequencerDrawView)(struct Scene *, struct Object *, int, int, unsigned int, int, int, int, char[256]); +typedef struct ImBuf *(*SequencerDrawView)(struct Scene *, struct Object *, int, int, unsigned int, int, int, int, int, char[256]); extern SequencerDrawView sequencer_view3d_cb; /* copy/paste */ diff --git a/source/blender/blenkernel/BKE_tessmesh.h b/source/blender/blenkernel/BKE_tessmesh.h index dea5e726671..9462822e25f 100644 --- a/source/blender/blenkernel/BKE_tessmesh.h +++ b/source/blender/blenkernel/BKE_tessmesh.h @@ -80,12 +80,11 @@ typedef struct BMEditMesh { /*temp variables for x-mirror editing*/ int mirror_cdlayer; /* -1 is invalid */ - int mirr_free_arrays; } BMEditMesh; -void BMEdit_RecalcTessellation(BMEditMesh *tm); +void BMEdit_RecalcTessellation(BMEditMesh *em); BMEditMesh *BMEdit_Create(BMesh *bm, int do_tessellate); -BMEditMesh *BMEdit_Copy(BMEditMesh *tm); +BMEditMesh *BMEdit_Copy(BMEditMesh *em); BMEditMesh *BMEdit_FromObject(struct Object *ob); void BMEdit_Free(BMEditMesh *em); void BMEdit_UpdateLinkedCustomData(BMEditMesh *em); diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index e3b16fd92e2..70a3f927b23 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -66,6 +66,7 @@ set(SRC intern/bmfont.c intern/boids.c intern/booleanops_mesh.c + intern/bpath.c intern/brush.c intern/bullet.c intern/bvhutils.c @@ -103,9 +104,9 @@ set(SRC intern/lattice.c intern/library.c intern/linestyle.c + intern/mask.c intern/mask_evaluate.c intern/mask_rasterize.c - intern/mask.c intern/material.c intern/mball.c intern/mesh.c @@ -123,6 +124,7 @@ set(SRC intern/paint.c intern/particle.c intern/particle_system.c + intern/pbvh.c intern/pointcache.c intern/property.c intern/report.c @@ -161,6 +163,7 @@ set(SRC BKE_bmfont_types.h BKE_boids.h BKE_booleanops_mesh.h + BKE_bpath.h BKE_brush.h BKE_bullet.h BKE_bvhutils.h @@ -212,6 +215,7 @@ set(SRC BKE_packedFile.h BKE_paint.h BKE_particle.h + BKE_pbvh.h BKE_pointcache.h BKE_property.h BKE_report.h @@ -237,6 +241,7 @@ set(SRC BKE_world.h BKE_writeavi.h BKE_writeframeserver.h + depsgraph_private.h nla_private.h intern/CCGSubSurf.h diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index dc1c9b5a1a2..ccb21b209ea 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/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') import os diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index d09bea0f662..010839764b2 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -47,10 +47,10 @@ #include "BLI_math.h" #include "BLI_memarena.h" #include "BLI_array.h" -#include "BLI_pbvh.h" #include "BLI_utildefines.h" #include "BLI_linklist.h" +#include "BKE_pbvh.h" #include "BKE_cdderivedmesh.h" #include "BKE_displist.h" #include "BKE_key.h" @@ -1421,7 +1421,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos } /* grab modifiers until index i */ - if ((index >= 0) && (modifiers_indexInObject(ob, md) >= index)) + if ((index >= 0) && (BLI_findindex(&ob->modifiers, md) >= index)) break; } @@ -1666,7 +1666,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform); /* grab modifiers until index i */ - if ((index >= 0) && (modifiers_indexInObject(ob, md) >= index)) + if ((index >= 0) && (BLI_findindex(&ob->modifiers, md) >= index)) break; if (sculpt_mode && md->type == eModifierType_Multires) @@ -2334,29 +2334,29 @@ static void make_vertexcosnos__mapFunc(void *userData, int index, const float co /* it stores the normals as floats, but they can still be scaled as shorts (32767 = unit) */ /* in use now by vertex/weight paint and particle generating */ -float *mesh_get_mapped_verts_nors(Scene *scene, Object *ob) +DMCoNo *mesh_get_mapped_verts_nors(Scene *scene, Object *ob) { Mesh *me = ob->data; DerivedMesh *dm; - float *vertexcosnos; + DMCoNo *vertexcosnos; /* lets prevent crashing... */ if (ob->type != OB_MESH || me->totvert == 0) return NULL; dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); - vertexcosnos = MEM_callocN(6 * sizeof(float) * me->totvert, "vertexcosnos map"); + vertexcosnos = MEM_callocN(sizeof(DMCoNo) * me->totvert, "vertexcosnos map"); if (dm->foreachMappedVert) { dm->foreachMappedVert(dm, make_vertexcosnos__mapFunc, vertexcosnos); } else { - float *fp = vertexcosnos; + DMCoNo *v_co_no = vertexcosnos; int a; - for (a = 0; a < me->totvert; a++, fp += 6) { - dm->getVertCo(dm, a, fp); - dm->getVertNo(dm, a, fp + 3); + for (a = 0; a < me->totvert; a++, v_co_no++) { + dm->getVertCo(dm, a, v_co_no->co); + dm->getVertNo(dm, a, v_co_no->no); } } diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index dd27cc70ba3..83d1538ecbe 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -43,7 +43,6 @@ #include "DNA_object_types.h" #include "BLI_blenlib.h" -#include "BLI_bpath.h" #include "BLI_math.h" #include "BLI_utildefines.h" #include "BLI_ghash.h" diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 9a2462e9724..4058809c275 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -76,7 +76,7 @@ /* --------------------- */ /* forward declarations */ -static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], +static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[4][4], int persistent_id[MAX_DUPLI_RECUR], int level, int index, short flag); /* ******************************************************************** */ @@ -706,7 +706,7 @@ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float qua #define DUPLILIST_FOR_RENDER 2 #define DUPLILIST_ANIMATED 4 -static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, +static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[4][4], int lay, int persistent_id[MAX_DUPLI_RECUR], int level, int index, int type, short flag) { DupliObject *dob = MEM_callocN(sizeof(DupliObject), "dupliobject"); @@ -930,7 +930,7 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3], } } -static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int persistent_id[MAX_DUPLI_RECUR], +static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[4][4], int persistent_id[MAX_DUPLI_RECUR], int level, short flag) { Object *ob, *ob_iter; @@ -1054,7 +1054,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl dm->release(dm); } -static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int persistent_id[MAX_DUPLI_RECUR], +static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[4][4], int persistent_id[MAX_DUPLI_RECUR], int level, short flag) { Object *ob, *ob_iter; @@ -1240,7 +1240,8 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa dm->release(dm); } -static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int persistent_id[MAX_DUPLI_RECUR], ParticleSystem *psys, +static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[4][4], + int persistent_id[MAX_DUPLI_RECUR], ParticleSystem *psys, int level, short flag) { GroupObject *go; @@ -1479,7 +1480,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p /* blender internal needs this to be set to dupligroup to render * groups correctly, but we don't want this hack for cycles */ - if(dupli_type_hack && GS(id->name) == ID_GR) + if (dupli_type_hack && GS(id->name) == ID_GR) dupli_type = OB_DUPLIGROUP; /* to give ipos in object correct offset */ @@ -1635,7 +1636,7 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int persiste /* ------------- */ -static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], +static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[4][4], int persistent_id[MAX_DUPLI_RECUR], int level, int index, short flag) { if ((ob->transflag & OB_DUPLI) == 0) diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 1970df54339..9155d67dc36 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -37,7 +37,6 @@ #include "MEM_guardedalloc.h" -#include "BLI_bpath.h" #include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_utildefines.h" @@ -640,7 +639,7 @@ static void pchan_b_bone_defmats(bPoseChannel *pchan, bPoseChanDeform *pdef_info } } -static void b_bone_deform(bPoseChanDeform *pdef_info, Bone *bone, float co[3], DualQuat *dq, float defmat[][3]) +static void b_bone_deform(bPoseChanDeform *pdef_info, Bone *bone, float co[3], DualQuat *dq, float defmat[3][3]) { Mat4 *b_bone = pdef_info->b_bone_mats; float (*mat)[4] = b_bone[0].mat; @@ -722,7 +721,7 @@ float distfactor_to_bone(const float vec[3], const float b1[3], const float b2[3 } } -static void pchan_deform_mat_add(bPoseChannel *pchan, float weight, float bbonemat[][3], float mat[][3]) +static void pchan_deform_mat_add(bPoseChannel *pchan, float weight, float bbonemat[3][3], float mat[3][3]) { float wmat[3][3]; @@ -736,7 +735,7 @@ static void pchan_deform_mat_add(bPoseChannel *pchan, float weight, float bbonem } static float dist_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, float vec[3], DualQuat *dq, - float mat[][3], const float co[3]) + float mat[3][3], const float co[3]) { Bone *bone = pchan->bone; float fac, contrib = 0.0; @@ -783,7 +782,7 @@ static float dist_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, f } static void pchan_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, float weight, float vec[3], DualQuat *dq, - float mat[][3], const float co[3], float *contrib) + float mat[3][3], const float co[3], float *contrib) { float cop[3], bbonemat[3][3]; DualQuat bbonedq; @@ -1089,7 +1088,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float /* ************ END Armature Deform ******************* */ -void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[][4], int UNUSED(root), +void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[4][4], int UNUSED(root), int UNUSED(posed)) { copy_m4_m4(M_accumulatedMatrix, bone->arm_mat); @@ -1098,7 +1097,7 @@ void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[][ /* **************** Space to Space API ****************** */ /* Convert World-Space Matrix to Pose-Space Matrix */ -void BKE_armature_mat_world_to_pose(Object *ob, float inmat[][4], float outmat[][4]) +void BKE_armature_mat_world_to_pose(Object *ob, float inmat[4][4], float outmat[4][4]) { float obmat[4][4]; @@ -1132,7 +1131,7 @@ void BKE_armature_loc_world_to_pose(Object *ob, const float inloc[3], float outl /* Simple helper, computes the offset bone matrix. * offs_bone = yoffs(b-1) + root(b) + bonemat(b). * Not exported, as it is only used in this file currently... */ -static void get_offset_bone_mat(Bone *bone, float offs_bone[][4]) +static void get_offset_bone_mat(Bone *bone, float offs_bone[4][4]) { if (!bone->parent) return; @@ -1164,7 +1163,7 @@ static void get_offset_bone_mat(Bone *bone, float offs_bone[][4]) * pose-channel into its local space (i.e. 'visual'-keyframing). * (note: I don't understand that, so I keep it :p --mont29). */ -void BKE_pchan_to_pose_mat(bPoseChannel *pchan, float rotscale_mat[][4], float loc_mat[][4]) +void BKE_pchan_to_pose_mat(bPoseChannel *pchan, float rotscale_mat[4][4], float loc_mat[4][4]) { Bone *bone, *parbone; bPoseChannel *parchan; @@ -1253,7 +1252,7 @@ void BKE_pchan_to_pose_mat(bPoseChannel *pchan, float rotscale_mat[][4], float l /* Convert Pose-Space Matrix to Bone-Space Matrix. * NOTE: this cannot be used to convert to pose-space transforms of the supplied * pose-channel into its local space (i.e. 'visual'-keyframing) */ -void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[][4], float outmat[][4]) +void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]) { float rotscale_mat[4][4], loc_mat[4][4], inmat_[4][4]; @@ -1269,7 +1268,7 @@ void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[][4], float } /* Convert Bone-Space Matrix to Pose-Space Matrix. */ -void BKE_armature_mat_bone_to_pose(bPoseChannel *pchan, float inmat[][4], float outmat[][4]) +void BKE_armature_mat_bone_to_pose(bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]) { float rotscale_mat[4][4], loc_mat[4][4], inmat_[4][4]; @@ -1298,7 +1297,7 @@ void BKE_armature_loc_pose_to_bone(bPoseChannel *pchan, const float inloc[3], fl copy_v3_v3(outloc, nLocMat[3]); } -void BKE_armature_mat_pose_to_bone_ex(Object *ob, bPoseChannel *pchan, float inmat[][4], float outmat[][4]) +void BKE_armature_mat_pose_to_bone_ex(Object *ob, bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]) { bPoseChannel work_pchan = *pchan; @@ -1316,7 +1315,7 @@ void BKE_armature_mat_pose_to_bone_ex(Object *ob, bPoseChannel *pchan, float inm } /* same as BKE_object_mat3_to_rot() */ -void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, float mat[][3], short use_compat) +void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, float mat[3][3], short use_compat) { switch (pchan->rotmode) { case ROT_MODE_QUAT: @@ -1335,7 +1334,7 @@ void BKE_pchan_mat3_to_rot(bPoseChannel *pchan, float mat[][3], short use_compat /* Apply a 4x4 matrix to the pose bone, * similar to BKE_object_apply_mat4() */ -void BKE_pchan_apply_mat4(bPoseChannel *pchan, float mat[][4], short use_compat) +void BKE_pchan_apply_mat4(bPoseChannel *pchan, float mat[4][4], short use_compat) { float rot[3][3]; mat4_to_loc_rot_size(pchan->loc, rot, pchan->size, mat); @@ -1345,7 +1344,7 @@ void BKE_pchan_apply_mat4(bPoseChannel *pchan, float mat[][4], short use_compat) /* Remove rest-position effects from pose-transform for obtaining * 'visual' transformation of pose-channel. * (used by the Visual-Keyframing stuff) */ -void BKE_armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4]) +void BKE_armature_mat_pose_to_delta(float delta_mat[4][4], float pose_mat[4][4], float arm_mat[4][4]) { float imat[4][4]; @@ -1425,7 +1424,7 @@ void BKE_rotMode_change_values(float quat[4], float eul[3], float axis[3], float * *************************************************************************** */ /* Computes vector and roll based on a rotation. * "mat" must contain only a rotation, and no scaling. */ -void mat3_to_vec_roll(float mat[][3], float r_vec[3], float *r_roll) +void mat3_to_vec_roll(float mat[3][3], float r_vec[3], float *r_roll) { if (r_vec) { copy_v3_v3(r_vec, mat[1]); @@ -1444,7 +1443,7 @@ void mat3_to_vec_roll(float mat[][3], float r_vec[3], float *r_roll) /* Calculates the rest matrix of a bone based * On its vector and a roll around that vector */ -void vec_roll_to_mat3(const float vec[3], const float roll, float mat[][3]) +void vec_roll_to_mat3(const float vec[3], const float roll, float mat[3][3]) { float nor[3], axis[3], target[3] = {0, 1, 0}; float theta; diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index f0d201ea3f7..5c0856bc95b 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -54,9 +54,9 @@ #include "DNA_screen_types.h" #include "DNA_sequence_types.h" #include "DNA_sound_types.h" +#include "DNA_windowmanager_types.h" #include "BLI_blenlib.h" -#include "BLI_bpath.h" #include "BLI_dynstr.h" #include "BLI_utildefines.h" #include "BLI_callbacks.h" @@ -65,6 +65,7 @@ #include "IMB_moviecache.h" #include "BKE_blender.h" +#include "BKE_bpath.h" #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_displist.h" @@ -80,8 +81,11 @@ #include "BKE_screen.h" #include "BKE_sequencer.h" #include "BKE_sound.h" + #include "RE_pipeline.h" +#include "BLF_api.h" + #include "BLO_undofile.h" #include "BLO_readfile.h" #include "BLO_writefile.h" @@ -179,7 +183,7 @@ static void clean_paths(Main *main) { Scene *scene; - BLI_bpath_traverse_main(main, clean_paths_visit_cb, BLI_BPATH_TRAVERSE_SKIP_MULTIFILE, NULL); + BKE_bpath_traverse_main(main, clean_paths_visit_cb, BKE_BPATH_TRAVERSE_SKIP_MULTIFILE, NULL); for (scene = main->scene.first; scene; scene = scene->id.next) { BLI_clean(scene->r.pic); @@ -230,6 +234,9 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath /* but use new Scene pointer */ curscene = bfd->curscene; if (curscene == NULL) curscene = bfd->main->scene.first; + /* empty file, we add a scene to make Blender work */ + if (curscene == NULL) curscene = BKE_scene_add(bfd->main, "Empty"); + /* and we enforce curscene to be in current screen */ if (curscreen) curscreen->scene = curscene; /* can run in bgmode */ @@ -270,7 +277,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath G.fileflags = bfd->fileflags; CTX_wm_manager_set(C, G.main->wm.first); CTX_wm_screen_set(C, bfd->curscreen); - CTX_data_scene_set(C, bfd->curscreen->scene); + CTX_data_scene_set(C, bfd->curscene); CTX_wm_area_set(C, NULL); CTX_wm_region_set(C, NULL); CTX_wm_menu_set(C, NULL); @@ -280,7 +287,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath if (CTX_data_scene(C) == NULL) { /* in case we don't even have a local scene, add one */ if (!G.main->scene.first) - BKE_scene_add("Scene"); + BKE_scene_add(G.main, "Scene"); CTX_data_scene_set(C, G.main->scene.first); CTX_wm_screen(C)->scene = CTX_data_scene(C); @@ -310,23 +317,38 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath if (G.main->versionfile < 250) do_versions_ipos_to_animato(G.main); - if (recover && bfd->filename[0] && G.relbase_valid) { + G.main->recovered = 0; + + /* startup.blend or recovered startup */ + if (bfd->filename[0] == 0) { + G.main->name[0] = 0; + } + else if (recover && G.relbase_valid) { /* in case of autosave or quit.blend, use original filename instead * use relbase_valid to make sure the file is saved, else we get <memory2> in the filename */ filepath = bfd->filename; + G.main->recovered = 1; + + /* these are the same at times, should never copy to the same location */ + if (G.main->name != filepath) + BLI_strncpy(G.main->name, filepath, FILE_MAX); } -#if 0 - else if (!G.relbase_valid) { - /* otherwise, use an empty string as filename, rather than <memory2> */ - filepath = ""; - } -#endif - /* these are the same at times, should never copy to the same location */ - if (G.main->name != filepath) - BLI_strncpy(G.main->name, filepath, FILE_MAX); - /* baseflags, groups, make depsgraph, etc */ + /* first handle case if other windows have different scenes visible */ + if (mode == 0) { + wmWindowManager *wm = G.main->wm.first; + + if (wm) { + wmWindow *win; + + for (win = wm->windows.first; win; win = win->next) { + if (win->screen && win->screen->scene) /* zealous check... */ + if (win->screen->scene != CTX_data_scene(C)) + BKE_scene_set_background(G.main, win->screen->scene); + } + } + } BKE_scene_set_background(G.main, CTX_data_scene(C)); if (mode != 'u') { @@ -335,7 +357,6 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath MEM_freeN(bfd); - (void)curscene; /* quiet warning */ } static int handle_subversion_warning(Main *main, ReportList *reports) @@ -393,6 +414,14 @@ void BKE_userdef_free(void) BLI_freelistN(&U.addons); } +/* handle changes in settings that need recalc */ +void BKE_userdef_state(void) +{ + BLF_default_dpi(U.pixelsize * U.dpi); + U.widget_unit = (U.pixelsize * U.dpi * 20 + 36) / 72; + +} + int BKE_read_file(bContext *C, const char *filepath, ReportList *reports) { BlendFileData *bfd; @@ -439,14 +468,57 @@ int BKE_read_file_from_memfile(bContext *C, MemFile *memfile, ReportList *report BlendFileData *bfd; bfd = BLO_read_from_memfile(CTX_data_main(C), G.main->name, memfile, reports); - if (bfd) + if (bfd) { + /* remove the unused screens and wm */ + while (bfd->main->wm.first) + BKE_libblock_free(&bfd->main->wm, bfd->main->wm.first); + while (bfd->main->screen.first) + BKE_libblock_free(&bfd->main->screen, bfd->main->screen.first); + setup_app_data(C, bfd, "<memory1>"); + } else BKE_reports_prepend(reports, "Loading failed: "); return (bfd ? 1 : 0); } +/* only read the userdef from a .blend */ +int BKE_read_file_userdef(const char *filepath, ReportList *reports) +{ + BlendFileData *bfd; + int retval = 0; + + bfd = BLO_read_from_file(filepath, reports); + if (bfd->user) { + retval = BKE_READ_FILE_OK_USERPREFS; + + /* only here free userdef themes... */ + BKE_userdef_free(); + + U = *bfd->user; + MEM_freeN(bfd->user); + } + free_main(bfd->main); + MEM_freeN(bfd); + + return retval; +} + +/* only write the userdef in a .blend */ +int BKE_write_file_userdef(const char *filepath, ReportList *reports) +{ + Main *mainb = MEM_callocN(sizeof(Main), "empty main"); + int retval = 0; + + if (BLO_write_file(mainb, filepath, G_FILE_USERPREFS, reports, NULL)) { + retval = 1; + } + + MEM_freeN(mainb); + + return retval; +} /* ***************** testing for break ************* */ @@ -728,48 +800,39 @@ char *BKE_undo_menu_string(void) return menu; } -/* saves quit.blend */ -void BKE_undo_save_quit(void) +/* saves .blend using undo buffer, returns 1 == success */ +int BKE_undo_save_file(const char *filename) { UndoElem *uel; MemFileChunk *chunk; - char str[FILE_MAX]; const int flag = O_BINARY + O_WRONLY + O_CREAT + O_TRUNC + O_EXCL; int file; if ((U.uiflag & USER_GLOBALUNDO) == 0) { - return; + return 0; } uel = curundo; if (uel == NULL) { fprintf(stderr, "No undo buffer to save recovery file\n"); - return; - } - - /* no undo state to save */ - if (undobase.first == undobase.last) { - return; + return 0; } - /* save the undo state as quit.blend */ - BLI_make_file_string("/", str, BLI_temporary_dir(), "quit.blend"); - /* first try create the file, if it exists call without 'O_CREAT', * to avoid writing to a symlink - use 'O_EXCL' (CVE-2008-1103) */ errno = 0; - file = BLI_open(str, flag, 0666); + file = BLI_open(filename, flag, 0666); if (file == -1) { if (errno == EEXIST) { errno = 0; - file = BLI_open(str, flag & ~O_CREAT, 0666); + file = BLI_open(filename, flag & ~O_CREAT, 0666); } } if (file == -1) { fprintf(stderr, "Unable to save '%s': %s\n", - str, errno ? strerror(errno) : "Unknown error opening file"); - return; + filename, errno ? strerror(errno) : "Unknown error opening file"); + return 0; } for (chunk = uel->memfile.chunks.first; chunk; chunk = chunk->next) { @@ -777,16 +840,15 @@ void BKE_undo_save_quit(void) break; } } - + close(file); if (chunk) { fprintf(stderr, "Unable to save '%s': %s\n", - str, errno ? strerror(errno) : "Unknown error writing file"); - } - else { - printf("Saved session recovery to '%s'\n", str); + filename, errno ? strerror(errno) : "Unknown error writing file"); + return 0; } + return 1; } /* sets curscene */ @@ -806,3 +868,131 @@ Main *BKE_undo_get_main(Scene **scene) return mainp; } +/* ************** copy paste .blend, partial saves ********** */ + +/* assumes data is in G.main */ + +void BKE_copybuffer_begin(void) +{ + /* set all id flags to zero; */ + flag_all_listbases_ids(LIB_NEED_EXPAND | LIB_DOIT, 0); +} + +void BKE_copybuffer_tag_ID(ID *id) +{ + id->flag |= LIB_NEED_EXPAND | LIB_DOIT; +} + +static void copybuffer_doit(void *UNUSED(handle), Main *UNUSED(bmain), void *vid) +{ + if (vid) { + ID *id = vid; + id->flag |= LIB_NEED_EXPAND | LIB_DOIT; + } +} + +/* frees main in end */ +int BKE_copybuffer_save(char *filename, ReportList *reports) +{ + Main *mainb = MEM_callocN(sizeof(Main), "copybuffer"); + ListBase *lbarray[MAX_LIBARRAY], *fromarray[MAX_LIBARRAY]; + int a, retval; + + BLO_main_expander(copybuffer_doit); + BLO_expand_main(NULL, G.main); + + /* move over all tagged blocks */ + set_listbasepointers(G.main, fromarray); + a = set_listbasepointers(mainb, lbarray); + while (a--) { + ID *id, *nextid; + ListBase *lb1 = lbarray[a], *lb2 = fromarray[a]; + + for (id = lb2->first; id; id = nextid) { + nextid = id->next; + if (id->flag & LIB_DOIT) { + BLI_remlink(lb2, id); + BLI_addtail(lb1, id); + } + } + } + + + /* save the buffer */ + retval = BLO_write_file(mainb, filename, 0, reports, NULL); + + /* move back the main, now sorted again */ + set_listbasepointers(G.main, lbarray); + a = set_listbasepointers(mainb, fromarray); + while (a--) { + ID *id; + ListBase *lb1 = lbarray[a], *lb2 = fromarray[a]; + + while (lb2->first) { + id = lb2->first; + BLI_remlink(lb2, id); + BLI_addtail(lb1, id); + id_sort_by_name(lb1, id); + } + } + + MEM_freeN(mainb); + + /* set id flag to zero; */ + flag_all_listbases_ids(LIB_NEED_EXPAND | LIB_DOIT, 0); + + return retval; +} + +/* return success (1) */ +int BKE_copybuffer_paste(bContext *C, char *libname, ReportList *reports) +{ + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + Main *mainl = NULL; + Library *lib; + BlendHandle *bh; + + bh = BLO_blendhandle_from_file(libname, reports); + + if (bh == NULL) { + /* error reports will have been made by BLO_blendhandle_from_file() */ + return 0; + } + + BKE_scene_base_deselect_all(scene); + + /* tag everything, all untagged data can be made local + * its also generally useful to know what is new + * + * take extra care flag_all_listbases_ids(LIB_LINK_TAG, 0) is called after! */ + flag_all_listbases_ids(LIB_PRE_EXISTING, 1); + + /* here appending/linking starts */ + mainl = BLO_library_append_begin(bmain, &bh, libname); + + BLO_library_append_all(mainl, bh); + + BLO_library_append_end(C, mainl, &bh, 0, 0); + + /* mark all library linked objects to be updated */ + recalc_all_library_objects(bmain); + IMB_colormanagement_check_file_config(bmain); + + /* append, rather than linking */ + lib = BLI_findstring(&bmain->library, libname, offsetof(Library, filepath)); + BKE_library_make_local(bmain, lib, 1); + + /* important we unset, otherwise these object wont + * link into other scenes from this blend file */ + flag_all_listbases_ids(LIB_PRE_EXISTING, 0); + + /* recreate dependency graph to include new objects */ + DAG_scene_sort(bmain, scene); + DAG_ids_flush_update(bmain, 0); + + BLO_blendhandle_close(bh); + /* remove library... */ + + return 1; +} diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c index e97ad3b11ba..24b13b062f3 100644 --- a/source/blender/blenlib/intern/bpath.c +++ b/source/blender/blenkernel/intern/bpath.c @@ -70,10 +70,8 @@ #include "DNA_vfont_types.h" #include "DNA_scene_types.h" #include "DNA_smoke_types.h" -#include "DNA_freestyle_types.h" #include "BLI_blenlib.h" -#include "BLI_bpath.h" #include "BLI_utildefines.h" #include "BKE_font.h" @@ -84,6 +82,8 @@ #include "BKE_sequencer.h" #include "BKE_image.h" /* so we can check the image's type */ +#include "BKE_bpath.h" /* own include */ + static int checkMissingFiles_visit_cb(void *userdata, char *UNUSED(path_dst), const char *path_src) { ReportList *reports = (ReportList *)userdata; @@ -96,9 +96,9 @@ static int checkMissingFiles_visit_cb(void *userdata, char *UNUSED(path_dst), co } /* high level function */ -void BLI_bpath_missing_files_check(Main *bmain, ReportList *reports) +void BKE_bpath_missing_files_check(Main *bmain, ReportList *reports) { - BLI_bpath_traverse_main(bmain, checkMissingFiles_visit_cb, BLI_BPATH_TRAVERSE_ABS, reports); + BKE_bpath_traverse_main(bmain, checkMissingFiles_visit_cb, BKE_BPATH_TRAVERSE_ABS, reports); } typedef struct BPathRemap_Data { @@ -133,7 +133,7 @@ static int makeFilesRelative_visit_cb(void *userdata, char *path_dst, const char } } -void BLI_bpath_relative_convert(Main *bmain, const char *basedir, ReportList *reports) +void BKE_bpath_relative_convert(Main *bmain, const char *basedir, ReportList *reports) { BPathRemap_Data data = {NULL}; @@ -145,7 +145,7 @@ void BLI_bpath_relative_convert(Main *bmain, const char *basedir, ReportList *re data.basedir = basedir; data.reports = reports; - BLI_bpath_traverse_main(bmain, makeFilesRelative_visit_cb, 0, (void *)&data); + BKE_bpath_traverse_main(bmain, makeFilesRelative_visit_cb, 0, (void *)&data); BKE_reportf(reports, data.count_failed ? RPT_WARNING : RPT_INFO, "Total files %d | Changed %d | Failed %d", @@ -175,8 +175,8 @@ static int makeFilesAbsolute_visit_cb(void *userdata, char *path_dst, const char } } -/* similar to BLI_bpath_relative_convert - keep in sync! */ -void BLI_bpath_absolute_convert(Main *bmain, const char *basedir, ReportList *reports) +/* similar to BKE_bpath_relative_convert - keep in sync! */ +void BKE_bpath_absolute_convert(Main *bmain, const char *basedir, ReportList *reports) { BPathRemap_Data data = {NULL}; @@ -188,7 +188,7 @@ void BLI_bpath_absolute_convert(Main *bmain, const char *basedir, ReportList *re data.basedir = basedir; data.reports = reports; - BLI_bpath_traverse_main(bmain, makeFilesAbsolute_visit_cb, 0, (void *)&data); + BKE_bpath_traverse_main(bmain, makeFilesAbsolute_visit_cb, 0, (void *)&data); BKE_reportf(reports, data.count_failed ? RPT_WARNING : RPT_INFO, "Total files %d | Changed %d | Failed %d", @@ -299,14 +299,14 @@ static int findMissingFiles_visit_cb(void *userdata, char *path_dst, const char } } -void BLI_bpath_missing_files_find(Main *bmain, const char *searchpath, ReportList *reports) +void BKE_bpath_missing_files_find(Main *bmain, const char *searchpath, ReportList *reports) { struct BPathFind_Data data = {NULL}; data.reports = reports; BLI_split_dir_part(searchpath, data.searchdir, sizeof(data.searchdir)); - BLI_bpath_traverse_main(bmain, findMissingFiles_visit_cb, 0, (void *)&data); + BKE_bpath_traverse_main(bmain, findMissingFiles_visit_cb, 0, (void *)&data); } /* Run a visitor on a string, replacing the contents of the string as needed. */ @@ -384,11 +384,11 @@ static int rewrite_path_alloc(char **path, BPathVisitor visit_cb, const char *ab } /* Run visitor function 'visit' on all paths contained in 'id'. */ -void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int flag, void *bpath_user_data) +void BKE_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int flag, void *bpath_user_data) { - const char *absbase = (flag & BLI_BPATH_TRAVERSE_ABS) ? ID_BLEND_PATH(bmain, id) : NULL; + const char *absbase = (flag & BKE_BPATH_TRAVERSE_ABS) ? ID_BLEND_PATH(bmain, id) : NULL; - if ((flag & BLI_BPATH_TRAVERSE_SKIP_LIBRARY) && id->lib) { + if ((flag & BKE_BPATH_TRAVERSE_SKIP_LIBRARY) && id->lib) { return; } @@ -397,7 +397,7 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int { Image *ima; ima = (Image *)id; - if (ima->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) { + if (ima->packedfile == NULL || (flag & BKE_BPATH_TRAVERSE_SKIP_PACKED) == 0) { if (ELEM3(ima->source, IMA_SRC_FILE, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { rewrite_path_fixed(ima->name, visit_cb, absbase, bpath_user_data); } @@ -476,7 +476,7 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int case ID_SO: { bSound *sound = (bSound *)id; - if (sound->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) { + if (sound->packedfile == NULL || (flag & BKE_BPATH_TRAVERSE_SKIP_PACKED) == 0) { rewrite_path_fixed(sound->name, visit_cb, absbase, bpath_user_data); } break; @@ -489,7 +489,7 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int case ID_VF: { VFont *vfont = (VFont *)id; - if (vfont->packedfile == NULL || (flag & BLI_BPATH_TRAVERSE_SKIP_PACKED) == 0) { + if (vfont->packedfile == NULL || (flag & BKE_BPATH_TRAVERSE_SKIP_PACKED) == 0) { if (BKE_vfont_is_builtin(vfont) == FALSE) { rewrite_path_fixed(((VFont *)id)->name, visit_cb, absbase, bpath_user_data); } @@ -540,7 +540,6 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int case ID_SCE: { Scene *scene = (Scene *)id; - SceneRenderLayer *srl= scene->r.layers.first; if (scene->ed) { Sequence *seq; @@ -557,7 +556,7 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int int len = MEM_allocN_len(se) / sizeof(*se); int i; - if (flag & BLI_BPATH_TRAVERSE_SKIP_MULTIFILE) { + if (flag & BKE_BPATH_TRAVERSE_SKIP_MULTIFILE) { /* only operate on one path */ len = MIN2(1, len); } @@ -576,12 +575,6 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int } SEQ_END } - for(; srl; srl= srl->next) { - FreestyleModuleConfig* module= srl->freestyleConfig.modules.first; - for (; module; module= module->next) { - rewrite_path_fixed(module->module_path, visit_cb, absbase, bpath_user_data); - } - } break; } case ID_ME: @@ -612,26 +605,26 @@ void BLI_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int } } -void BLI_bpath_traverse_id_list(Main *bmain, ListBase *lb, BPathVisitor visit_cb, const int flag, void *bpath_user_data) +void BKE_bpath_traverse_id_list(Main *bmain, ListBase *lb, BPathVisitor visit_cb, const int flag, void *bpath_user_data) { ID *id; for (id = lb->first; id; id = id->next) { - BLI_bpath_traverse_id(bmain, id, visit_cb, flag, bpath_user_data); + BKE_bpath_traverse_id(bmain, id, visit_cb, flag, bpath_user_data); } } -void BLI_bpath_traverse_main(Main *bmain, BPathVisitor visit_cb, const int flag, void *bpath_user_data) +void BKE_bpath_traverse_main(Main *bmain, BPathVisitor visit_cb, const int flag, void *bpath_user_data) { ListBase *lbarray[MAX_LIBARRAY]; int a = set_listbasepointers(bmain, lbarray); while (a--) { - BLI_bpath_traverse_id_list(bmain, lbarray[a], visit_cb, flag, bpath_user_data); + BKE_bpath_traverse_id_list(bmain, lbarray[a], visit_cb, flag, bpath_user_data); } } /* Rewrites a relative path to be relative to the main file - unless the path is * absolute, in which case it is not altered. */ -int BLI_bpath_relocate_visitor(void *pathbase_v, char *path_dst, const char *path_src) +int BKE_bpath_relocate_visitor(void *pathbase_v, char *path_dst, const char *path_src) { /* be sure there is low chance of the path being too short */ char filepath[(FILE_MAXDIR * 2) + FILE_MAXFILE]; @@ -708,23 +701,23 @@ static int bpath_list_restore(void *userdata, char *path_dst, const char *path_s } /* return ls_handle */ -void *BLI_bpath_list_backup(Main *bmain, const int flag) +void *BKE_bpath_list_backup(Main *bmain, const int flag) { ListBase *ls = MEM_callocN(sizeof(ListBase), __func__); - BLI_bpath_traverse_main(bmain, bpath_list_append, flag, ls); + BKE_bpath_traverse_main(bmain, bpath_list_append, flag, ls); return ls; } -void BLI_bpath_list_restore(Main *bmain, const int flag, void *ls_handle) +void BKE_bpath_list_restore(Main *bmain, const int flag, void *ls_handle) { ListBase *ls = ls_handle; - BLI_bpath_traverse_main(bmain, bpath_list_restore, flag, ls); + BKE_bpath_traverse_main(bmain, bpath_list_restore, flag, ls); } -void BLI_bpath_list_free(void *ls_handle) +void BKE_bpath_list_free(void *ls_handle) { ListBase *ls = ls_handle; BLI_assert(ls->first == NULL); /* assumes we were used */ diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index f310895f590..405b1efb25d 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -39,18 +39,19 @@ #include "DNA_color_types.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" +#include "DNA_userdef_types.h" #include "DNA_windowmanager_types.h" #include "WM_types.h" #include "RNA_access.h" -#include "BLI_bpath.h" #include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_rand.h" #include "BLI_utildefines.h" +#include "BKE_blender.h" #include "BKE_brush.h" #include "BKE_colortools.h" #include "BKE_global.h" @@ -644,8 +645,9 @@ void BKE_brush_size_set(Scene *scene, Brush *brush, int size) int BKE_brush_size_get(const Scene *scene, Brush *brush) { UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; - - return (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size; + int size = (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size; + + return (int)((float)size * U.pixelsize); } int BKE_brush_use_locked_size(const Scene *scene, Brush *brush) diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 54bbe4bf495..34adeb4fefb 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -40,12 +40,12 @@ #include "BLI_blenlib.h" #include "BLI_edgehash.h" #include "BLI_math.h" -#include "BLI_pbvh.h" #include "BLI_array.h" #include "BLI_smallhash.h" #include "BLI_utildefines.h" #include "BLI_scanfill.h" +#include "BKE_pbvh.h" #include "BKE_cdderivedmesh.h" #include "BKE_global.h" #include "BKE_mesh.h" diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 4641a02265a..f0043d9fa77 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -567,7 +567,9 @@ Object **get_collisionobjects(Scene *scene, Object *self, Group *group, unsigned Scene *sce_iter; /* add objects in same layer in scene */ for (SETLOOPER(scene, sce_iter, base)) { - if (base->lay & self->lay) + /* Need to check for active layers, too. + Otherwise this check fails if the objects are not on the same layer - DG */ + if ((base->lay & self->lay) || (base->lay & scene->lay)) add_collision_object(&objs, &numobj, &maxobj, base->object, self, 0, modifier_type); } diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 97d750854f4..c3aab22fe5a 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -219,7 +219,7 @@ void constraints_clear_evalob(bConstraintOb *cob) * of a matrix from one space to another for constraint evaluation. * For now, this is only implemented for Objects and PoseChannels. */ -void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[][4], short from, short to) +void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[4][4], short from, short to) { float diff_mat[4][4]; float imat[4][4]; @@ -345,7 +345,7 @@ void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[][4] /* ------------ General Target Matrix Tools ---------- */ /* function that sets the given matrix based on given vertex group in mesh */ -static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[][4]) +static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[4][4]) { DerivedMesh *dm = NULL; BMEditMesh *em = BMEdit_FromObject(ob); @@ -441,7 +441,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[ } /* function that sets the given matrix based on given vertex group in lattice */ -static void contarget_get_lattice_mat(Object *ob, const char *substring, float mat[][4]) +static void contarget_get_lattice_mat(Object *ob, const char *substring, float mat[4][4]) { Lattice *lt = (Lattice *)ob->data; @@ -494,7 +494,7 @@ static void contarget_get_lattice_mat(Object *ob, const char *substring, float m /* generic function to get the appropriate matrix for most target cases */ /* The cases where the target can be object data have not been implemented */ -static void constraint_target_to_mat4(Object *ob, const char *substring, float mat[][4], short from, short to, float headtail) +static void constraint_target_to_mat4(Object *ob, const char *substring, float mat[4][4], short from, short to, float headtail) { /* Case OBJECT */ if (!strlen(substring)) { @@ -890,7 +890,7 @@ static int basis_cross(int n, int m) } } -static void vectomat(const float vec[3], const float target_up[3], short axis, short upflag, short flags, float m[][3]) +static void vectomat(const float vec[3], const float target_up[3], short axis, short upflag, short flags, float m[3][3]) { float n[3]; float u[3]; /* vector specifying the up axis */ @@ -4610,7 +4610,7 @@ short proxylocked_constraints_owner(Object *ob, bPoseChannel *pchan) * None of the actual calculations of the matrices should be done here! Also, this function is * not to be used by any new constraints, particularly any that have multiple targets. */ -void get_constraint_target_matrix(struct Scene *scene, bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime) +void get_constraint_target_matrix(struct Scene *scene, bConstraint *con, int n, short ownertype, void *ownerdata, float mat[4][4], float ctime) { bConstraintTypeInfo *cti = constraint_get_typeinfo(con); ListBase targets = {NULL, NULL}; diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 754a4fbc0c8..1d199cdf1e2 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -36,7 +36,6 @@ #include "MEM_guardedalloc.h" -#include "BLI_bpath.h" #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" @@ -68,7 +67,7 @@ /* local */ static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], const float v4[3], short cox, short coy, - float *labda, float *mu, float vec[3]); + float *lambda, float *mu, float vec[3]); void BKE_curve_unlink(Curve *cu) { @@ -1615,7 +1614,7 @@ void BKE_curve_bevel_make(Scene *scene, Object *ob, ListBase *disp, int forRende static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], const float v4[3], short cox, short coy, - float *labda, float *mu, float vec[3]) + float *lambda, float *mu, float vec[3]) { /* return: * -1: collinear @@ -1629,22 +1628,22 @@ static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], c if (deler == 0.0f) return -1; - *labda = (v1[coy] - v3[coy]) * (v3[cox] - v4[cox]) - (v1[cox] - v3[cox]) * (v3[coy] - v4[coy]); - *labda = -(*labda / deler); + *lambda = (v1[coy] - v3[coy]) * (v3[cox] - v4[cox]) - (v1[cox] - v3[cox]) * (v3[coy] - v4[coy]); + *lambda = -(*lambda / deler); deler = v3[coy] - v4[coy]; if (deler == 0) { deler = v3[cox] - v4[cox]; - *mu = -(*labda * (v2[cox] - v1[cox]) + v1[cox] - v3[cox]) / deler; + *mu = -(*lambda * (v2[cox] - v1[cox]) + v1[cox] - v3[cox]) / deler; } else { - *mu = -(*labda * (v2[coy] - v1[coy]) + v1[coy] - v3[coy]) / deler; + *mu = -(*lambda * (v2[coy] - v1[coy]) + v1[coy] - v3[coy]) / deler; } - vec[cox] = *labda * (v2[cox] - v1[cox]) + v1[cox]; - vec[coy] = *labda * (v2[coy] - v1[coy]) + v1[coy]; + vec[cox] = *lambda * (v2[cox] - v1[cox]) + v1[cox]; + vec[coy] = *lambda * (v2[coy] - v1[coy]) + v1[coy]; - if (*labda >= 0.0f && *labda <= 1.0f && *mu >= 0.0f && *mu <= 1.0f) { - if (*labda == 0.0f || *labda == 1.0f || *mu == 0.0f || *mu == 1.0f) + if (*lambda >= 0.0f && *lambda <= 1.0f && *mu >= 0.0f && *mu <= 1.0f) { + if (*lambda == 0.0f || *lambda == 1.0f || *mu == 0.0f || *mu == 1.0f) return 1; return 2; } @@ -1654,7 +1653,7 @@ static int cu_isectLL(const float v1[3], const float v2[3], const float v3[3], c static short bevelinside(BevList *bl1, BevList *bl2) { - /* is bl2 INSIDE bl1 ? with left-right method and "labda's" */ + /* is bl2 INSIDE bl1 ? with left-right method and "lambda's" */ /* returns '1' if correct hole */ BevPoint *bevp, *prevbevp; float min, max, vec[3], hvec1[3], hvec2[3], lab, mu; diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index b2f8db0dcce..0f352dede23 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2104,7 +2104,7 @@ int CustomData_set_layer_name(const CustomData *data, int type, int n, const cha if (layer_index < 0) return 0; if (!name) return 0; - strcpy(data->layers[layer_index].name, name); + BLI_strncpy(data->layers[layer_index].name, name, sizeof(data->layers[layer_index].name)); return 1; } @@ -2854,10 +2854,11 @@ void CustomData_validate_layer_name(const CustomData *data, int type, const char * deleted, so assign the active layer to name */ index = CustomData_get_active_layer_index(data, type); - strcpy(outname, data->layers[index].name); + BLI_strncpy(outname, data->layers[index].name, MAX_CUSTOMDATA_LAYER_NAME); + } + else { + BLI_strncpy(outname, name, MAX_CUSTOMDATA_LAYER_NAME); } - else - strcpy(outname, name); } int CustomData_verify_versions(struct CustomData *data, int index) diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 3ed759392b6..6ba140fcec1 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -2482,30 +2482,51 @@ void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const s } -static void dag_current_scene_layers(Main *bmain, Scene **sce, unsigned int *lay) +/* struct returned by DagSceneLayer */ +typedef struct DagSceneLayer { + struct DagSceneLayer *next, *prev; + Scene *scene; + unsigned int layer; +} DagSceneLayer; + +/* returns visible scenes with valid DAG */ +static void dag_current_scene_layers(Main *bmain, ListBase *lb) { wmWindowManager *wm; wmWindow *win; + + lb->first = lb->last = NULL; - /* only one scene supported currently, making more scenes work - * correctly requires changes beyond just the dependency graph */ - - *sce = NULL; - *lay = 0; - + /* if we have a windowmanager, look into windows */ if ((wm = bmain->wm.first)) { - /* if we have a windowmanager, look into windows */ + + flag_listbase_ids(&bmain->scene, LIB_DOIT, 1); + for (win = wm->windows.first; win; win = win->next) { - if (win->screen) { - if (*sce == NULL) *sce = win->screen->scene; - *lay |= BKE_screen_visible_layers(win->screen, win->screen->scene); + if (win->screen && win->screen->scene->theDag) { + Scene *scene = win->screen->scene; + + if (scene->id.flag & LIB_DOIT) { + DagSceneLayer *dsl = MEM_mallocN(sizeof(DagSceneLayer), "dag scene layer"); + + BLI_addtail(lb, dsl); + + dsl->scene = scene; + dsl->layer = BKE_screen_visible_layers(win->screen, scene); + + scene->id.flag &= ~LIB_DOIT; + } } } } else { /* if not, use the first sce */ - *sce = bmain->scene.first; - if (*sce) *lay = (*sce)->lay; + DagSceneLayer *dsl = MEM_mallocN(sizeof(DagSceneLayer), "dag scene layer"); + + BLI_addtail(lb, dsl); + + dsl->scene = bmain->scene.first; + dsl->layer = dsl->scene->lay; /* XXX for background mode, we should get the scene * from somewhere, for the -S option, but it's in @@ -2515,29 +2536,36 @@ static void dag_current_scene_layers(Main *bmain, Scene **sce, unsigned int *lay void DAG_ids_flush_update(Main *bmain, int time) { - Scene *sce; - unsigned int lay; - - dag_current_scene_layers(bmain, &sce, &lay); + ListBase listbase; + DagSceneLayer *dsl; + + /* get list of visible scenes and layers */ + dag_current_scene_layers(bmain, &listbase); - if (sce) - DAG_scene_flush_update(bmain, sce, lay, time); + for (dsl = listbase.first; dsl; dsl = dsl->next) + DAG_scene_flush_update(bmain, dsl->scene, dsl->layer, time); + + BLI_freelistN(&listbase); } void DAG_on_visible_update(Main *bmain, const short do_time) { - Scene *scene; - Base *base; - Object *ob; - Group *group; - GroupObject *go; - DagNode *node; - unsigned int lay, oblay; - - dag_current_scene_layers(bmain, &scene, &lay); - - if (scene && scene->theDag) { + ListBase listbase; + DagSceneLayer *dsl; + + /* get list of visible scenes and layers */ + dag_current_scene_layers(bmain, &listbase); + + for (dsl = listbase.first; dsl; dsl = dsl->next) { + Scene *scene = dsl->scene; Scene *sce_iter; + Base *base; + Object *ob; + Group *group; + GroupObject *go; + DagNode *node; + unsigned int lay = dsl->layer, oblay; + /* derivedmeshes and displists are not saved to file so need to be * remade, tag them so they get remade in the scene update loop, * note armature poses or object matrices are preserved and do not @@ -2574,6 +2602,8 @@ void DAG_on_visible_update(Main *bmain, const short do_time) DAG_scene_update_flags(bmain, scene, lay, do_time); scene->lay_updated |= lay; } + + BLI_freelistN(&listbase); /* hack to get objects updating on layer changes */ DAG_id_type_tag(bmain, ID_OB); @@ -2758,14 +2788,15 @@ static void dag_id_flush_update(Scene *sce, ID *id) void DAG_ids_flush_tagged(Main *bmain) { + ListBase listbase; + DagSceneLayer *dsl; ListBase *lbarray[MAX_LIBARRAY]; - Scene *sce; - unsigned int lay; int a, do_flush = FALSE; + + /* get list of visible scenes and layers */ + dag_current_scene_layers(bmain, &listbase); - dag_current_scene_layers(bmain, &sce, &lay); - - if (!sce || !sce->theDag) + if (listbase.first == NULL) return; /* loop over all ID types */ @@ -2780,7 +2811,10 @@ void DAG_ids_flush_tagged(Main *bmain) if (id && bmain->id_tag_update[id->name[0]]) { for (; id; id = id->next) { if (id->flag & (LIB_ID_RECALC | LIB_ID_RECALC_DATA)) { - dag_id_flush_update(sce, id); + + for (dsl = listbase.first; dsl; dsl = dsl->next) + dag_id_flush_update(dsl->scene, id); + do_flush = TRUE; } } @@ -2788,8 +2822,12 @@ void DAG_ids_flush_tagged(Main *bmain) } /* flush changes to other objects */ - if (do_flush) - DAG_scene_flush_update(bmain, sce, lay, 0); + if (do_flush) { + for (dsl = listbase.first; dsl; dsl = dsl->next) + DAG_scene_flush_update(bmain, dsl->scene, dsl->layer, 0); + } + + BLI_freelistN(&listbase); } void DAG_ids_check_recalc(Main *bmain, Scene *scene, int time) diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index ed85e5b627b..56b9db94108 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -397,7 +397,7 @@ void dynamicPaintSurface_updateType(struct DynamicPaintSurface *surface) } else { strcpy(surface->output_name, "dp_"); - strcpy(surface->output_name2, surface->output_name); + BLI_strncpy(surface->output_name2, surface->output_name, sizeof(surface->output_name2)); surface->flags &= ~MOD_DPAINT_ANTIALIAS; surface->depth_clamp = 0.0f; } @@ -1193,7 +1193,68 @@ void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct Dyn /* Copy data */ if (tpmd->canvas) { + DynamicPaintSurface *surface; tpmd->canvas->pmd = tpmd; + /* free default surface */ + if (tpmd->canvas->surfaces.first) + dynamicPaint_freeSurface(tpmd->canvas->surfaces.first); + + /* copy existing surfaces */ + for (surface = pmd->canvas->surfaces.first; surface; surface = surface->next) { + DynamicPaintSurface *t_surface = dynamicPaint_createNewSurface(tpmd->canvas, NULL); + + /* surface settings */ + t_surface->brush_group = surface->brush_group; + MEM_freeN(t_surface->effector_weights); + t_surface->effector_weights = MEM_dupallocN(surface->effector_weights); + + BLI_strncpy(t_surface->name, surface->name, sizeof(t_surface->name)); + t_surface->format = surface->format; + t_surface->type = surface->type; + t_surface->disp_type = surface->disp_type; + t_surface->image_fileformat = surface->image_fileformat; + t_surface->effect_ui = surface->effect_ui; + t_surface->preview_id = surface->preview_id; + t_surface->init_color_type = surface->init_color_type; + t_surface->flags = surface->flags; + t_surface->effect = surface->effect; + + t_surface->image_resolution = surface->image_resolution; + t_surface->substeps = surface->substeps; + t_surface->start_frame = surface->start_frame; + t_surface->end_frame = surface->end_frame; + + copy_v4_v4(t_surface->init_color, surface->init_color); + t_surface->init_texture = surface->init_texture; + BLI_strncpy(t_surface->init_layername, surface->init_layername, sizeof(t_surface->init_layername)); + + t_surface->dry_speed = surface->dry_speed; + t_surface->diss_speed = surface->diss_speed; + t_surface->color_dry_threshold = surface->color_dry_threshold; + t_surface->depth_clamp = surface->depth_clamp; + t_surface->disp_factor = surface->disp_factor; + + + t_surface->spread_speed = surface->spread_speed; + t_surface->color_spread_speed = surface->color_spread_speed; + t_surface->shrink_speed = surface->shrink_speed; + t_surface->drip_vel = surface->drip_vel; + t_surface->drip_acc = surface->drip_acc; + + t_surface->influence_scale = surface->influence_scale; + t_surface->radius_scale = surface->radius_scale; + + t_surface->wave_damping = surface->wave_damping; + t_surface->wave_speed = surface->wave_speed; + t_surface->wave_timescale = surface->wave_timescale; + t_surface->wave_spring = surface->wave_spring; + + BLI_strncpy(t_surface->uvlayer_name, surface->uvlayer_name, sizeof(t_surface->uvlayer_name)); + BLI_strncpy(t_surface->image_output_path, surface->image_output_path, sizeof(t_surface->image_output_path)); + BLI_strncpy(t_surface->output_name, surface->output_name, sizeof(t_surface->output_name)); + BLI_strncpy(t_surface->output_name2, surface->output_name2, sizeof(t_surface->output_name2)); + } + dynamicPaint_resetPreview(tpmd->canvas); } else if (tpmd->brush) { DynamicPaintBrushSettings *brush = pmd->brush, *t_brush = tpmd->brush; diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 321a61ce238..bb8df834d0f 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -39,8 +39,8 @@ #include "BLI_blenlib.h" #include "BLI_edgehash.h" #include "BLI_math.h" -#include "BLI_pbvh.h" +#include "BKE_pbvh.h" #include "BKE_cdderivedmesh.h" #include "BKE_global.h" #include "BKE_mesh.h" @@ -71,24 +71,24 @@ extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */ BMEditMesh *BMEdit_Create(BMesh *bm, int do_tessellate) { - BMEditMesh *tm = MEM_callocN(sizeof(BMEditMesh), __func__); + BMEditMesh *em = MEM_callocN(sizeof(BMEditMesh), __func__); - tm->bm = bm; + em->bm = bm; if (do_tessellate) { - BMEdit_RecalcTessellation(tm); + BMEdit_RecalcTessellation(em); } - return tm; + return em; } -BMEditMesh *BMEdit_Copy(BMEditMesh *tm) +BMEditMesh *BMEdit_Copy(BMEditMesh *em) { - BMEditMesh *tm2 = MEM_callocN(sizeof(BMEditMesh), __func__); - *tm2 = *tm; + BMEditMesh *em_copy = MEM_callocN(sizeof(BMEditMesh), __func__); + *em_copy = *em; - tm2->derivedCage = tm2->derivedFinal = NULL; + em_copy->derivedCage = em_copy->derivedFinal = NULL; - tm2->bm = BM_mesh_copy(tm->bm); + em_copy->bm = BM_mesh_copy(em->bm); /* The tessellation is NOT calculated on the copy here, * because currently all the callers of this function use @@ -97,22 +97,22 @@ BMEditMesh *BMEdit_Copy(BMEditMesh *tm) * reasons, in that case it makes more sense to do the * tessellation only when/if that copy ends up getting * used.*/ - tm2->looptris = NULL; + em_copy->looptris = NULL; - tm2->vert_index = NULL; - tm2->edge_index = NULL; - tm2->face_index = NULL; + em_copy->vert_index = NULL; + em_copy->edge_index = NULL; + em_copy->face_index = NULL; - return tm2; + return em_copy; } -static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm) +static void BMEdit_RecalcTessellation_intern(BMEditMesh *em) { /* use this to avoid locking pthread for _every_ polygon * and calling the fill function */ #define USE_TESSFACE_SPEEDUP - BMesh *bm = tm->bm; + BMesh *bm = em->bm; BMLoop *(*looptris)[3] = NULL; BLI_array_declare(looptris); BMIter iter, liter; @@ -125,26 +125,26 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm) #if 0 /* note, we could be clever and re-use this array but would need to ensure * its realloced at some point, for now just free it */ - if (tm->looptris) MEM_freeN(tm->looptris); + if (em->looptris) MEM_freeN(em->looptris); - /* Use tm->tottri when set, this means no reallocs while transforming, + /* Use em->tottri when set, this means no reallocs while transforming, * (unless scanfill fails), otherwise... */ /* allocate the length of totfaces, avoid many small reallocs, * if all faces are tri's it will be correct, quads == 2x allocs */ - BLI_array_reserve(looptris, (tm->tottri && tm->tottri < bm->totface * 3) ? tm->tottri : bm->totface); + BLI_array_reserve(looptris, (em->tottri && em->tottri < bm->totface * 3) ? em->tottri : bm->totface); #else /* this means no reallocs for quad dominant models, for */ - if ( (tm->looptris != NULL) && - (tm->tottri != 0) && + if ( (em->looptris != NULL) && + (em->tottri != 0) && /* (totrti <= bm->totface * 2) would be fine for all quads, * but in case there are some ngons, still re-use the array */ - (tm->tottri <= bm->totface * 3)) + (em->tottri <= bm->totface * 3)) { - looptris = tm->looptris; + looptris = em->looptris; } else { - if (tm->looptris) MEM_freeN(tm->looptris); + if (em->looptris) MEM_freeN(em->looptris); BLI_array_reserve(looptris, bm->totface); } @@ -237,8 +237,8 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm) } } - tm->tottri = i; - tm->looptris = looptris; + em->tottri = i; + em->looptris = looptris; #undef USE_TESSFACE_SPEEDUP diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index a7d0152a799..0c83bb8d39a 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -183,7 +183,7 @@ bGPDlayer *gpencil_layer_addnew(bGPdata *gpd, const char *name, int setactive) gpl->thickness = 3; /* auto-name */ - strcpy(gpl->info, name); + BLI_strncpy(gpl->info, name, sizeof(gpl->info)); BLI_uniquename(&gpd->layers, gpl, "GP_Layer", '.', offsetof(bGPDlayer, info), sizeof(gpl->info)); /* make this one the active one */ diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index f09f128e874..7f0475cf155 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -68,7 +68,6 @@ #include "BLI_blenlib.h" #include "BLI_threads.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" #include "BKE_bmfont.h" #include "BKE_colortools.h" @@ -1400,7 +1399,9 @@ static void timecode_simple_string(char *text, size_t text_size, const int cfra, } } -/* could allow access externally - 512 is for long names, 64 is for id names */ +#define STAMP_NAME_SIZE ((MAX_ID_NAME - 2) + 16) +/* could allow access externally - 512 is for long names, + * STAMP_NAME_SIZE is for id names, allowing them some room for description */ typedef struct StampData { char file[512]; char note[512]; @@ -1408,12 +1409,13 @@ typedef struct StampData { char marker[512]; char time[512]; char frame[512]; - char camera[64]; - char cameralens[64]; - char scene[64]; - char strip[64]; - char rendertime[64]; + char camera[STAMP_NAME_SIZE]; + char cameralens[STAMP_NAME_SIZE]; + char scene[STAMP_NAME_SIZE]; + char strip[STAMP_NAME_SIZE]; + char rendertime[STAMP_NAME_SIZE]; } StampData; +#undef STAMP_NAME_SIZE static void stampdata(Scene *scene, Object *camera, StampData *stamp_data, int do_prefix) { diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 782d796b8a7..ad95f09826a 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -1078,7 +1078,7 @@ static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, const int if (key->slurph && key->type != KEY_RELATIVE) { const float ctime_scaled = key->ctime / 100.0f; float delta = (float)key->slurph / tot; - float cfra = (float)scene->r.cfra; + float cfra = (float)scene->r.cfra + scene->r.subframe; int step, a; if (tot > 100 && slurph_opt) { @@ -1176,7 +1176,7 @@ static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, const in if (key->slurph && key->type != KEY_RELATIVE) { const float ctime_scaled = key->ctime / 100.0f; float delta = (float)key->slurph / tot; - float cfra = (float)scene->r.cfra; + float cfra = (float)scene->r.cfra + scene->r.subframe; Nurb *nu; int i = 0, remain = 0; int step, a; @@ -1258,7 +1258,7 @@ static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, const int if (key->slurph && key->type != KEY_RELATIVE) { const float ctime_scaled = key->ctime / 100.0f; float delta = (float)key->slurph / tot; - float cfra = (float)scene->r.cfra; + float cfra = (float)scene->r.cfra + scene->r.subframe; int a; for (a = 0; a < tot; a++, cfra += delta) { @@ -1373,7 +1373,7 @@ float *do_ob_key(Scene *scene, Object *ob) } else { /* do shapekey local drivers */ - float ctime = (float)scene->r.cfra; // XXX this needs to be checked + float ctime = (float)scene->r.cfra + scene->r.subframe; BKE_animsys_evaluate_animdata(scene, &key->id, key->adt, ctime, ADT_RECALC_DRIVERS); diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index a15ca7cb5ce..d98188d8a6f 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -37,7 +37,6 @@ #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" -#include "BLI_bpath.h" #include "BLI_math.h" #include "BLI_utildefines.h" @@ -753,7 +752,7 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target, /* orco is original not-animated or deformed reference point */ /* result written in vec and mat */ void curve_deform_vector(Scene *scene, Object *cuOb, Object *target, - float orco[3], float vec[3], float mat[][3], int no_rot_axis) + float orco[3], float vec[3], float mat[3][3], int no_rot_axis) { CurveDeform cd; float quat[4]; diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index db96567a4da..d21a12b9e6a 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -71,7 +71,7 @@ #include "BLI_blenlib.h" #include "BLI_dynstr.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BKE_animsys.h" #include "BKE_camera.h" @@ -137,9 +137,9 @@ void BKE_id_lib_local_paths(Main *bmain, Library *lib, ID *id) { char *bpath_user_data[2] = {bmain->name, lib->filepath}; - BLI_bpath_traverse_id(bmain, id, - BLI_bpath_relocate_visitor, - BLI_BPATH_TRAVERSE_SKIP_MULTIFILE, + BKE_bpath_traverse_id(bmain, id, + BKE_bpath_relocate_visitor, + BKE_BPATH_TRAVERSE_SKIP_MULTIFILE, bpath_user_data); } @@ -153,6 +153,14 @@ void id_lib_extern(ID *id) } } +/* ensure we have a real user */ +void id_us_ensure_real(ID *id) +{ + if (ID_REAL_USERS(id) <= 0) { + id->us = MAX2(id->us, 0) + 1; + } +} + void id_us_plus(ID *id) { if (id) { diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 445ea2d4b3b..3bfd4f4f760 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -52,7 +52,6 @@ #include "BLI_math.h" #include "BLI_listbase.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" #include "BLI_string.h" #include "BKE_animsys.h" @@ -1857,7 +1856,7 @@ static void convert_tfacematerial(Main *main, Material *ma) mat_new = BKE_material_copy(ma); if (mat_new) { /* rename the material*/ - strcpy(mat_new->id.name, idname); + BLI_strncpy(mat_new->id.name, idname, sizeof(mat_new->id.name)); id_us_min((ID *)mat_new); mat_nr = mesh_addmaterial(me, mat_new); diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index 805e77cf84f..5c882fd97d6 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -50,8 +50,6 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" - #include "BKE_global.h" #include "BKE_main.h" diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 036f8f5e673..55cf2743bfa 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -46,7 +46,6 @@ #include "BLI_utildefines.h" #include "BLI_blenlib.h" -#include "BLI_bpath.h" #include "BLI_math.h" #include "BLI_edgehash.h" #include "BLI_scanfill.h" @@ -3009,9 +3008,9 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart, else { int i; MLoop *l_iter = loopstart; - float area, polynorm_local[3], (*vertexcos)[3]; + float area, polynorm_local[3]; + float (*vertexcos)[3] = BLI_array_alloca(vertexcos, mpoly->totloop); const float *no = polynormal ? polynormal : polynorm_local; - BLI_array_fixedstack_declare(vertexcos, BM_DEFAULT_NGON_STACK_SIZE, mpoly->totloop, __func__); /* pack vertex cos into an array for area_poly_v3 */ for (i = 0; i < mpoly->totloop; i++, l_iter++) { @@ -3026,8 +3025,6 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart, /* finally calculate the area */ area = area_poly_v3(mpoly->totloop, vertexcos, no); - BLI_array_fixedstack_free(vertexcos); - return area; } } diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 25b70ce1793..2aeda614f07 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -621,16 +621,6 @@ int modifiers_isPreview(Object *ob) return FALSE; } -int modifiers_indexInObject(Object *ob, ModifierData *md_seek) -{ - int i = 0; - ModifierData *md; - - for (md = ob->modifiers.first; (md && md_seek != md); md = md->next, i++) ; - if (!md) return -1; /* modifier isn't in the object */ - return i; -} - void modifier_freeTemporaryData(ModifierData *md) { if (md->type == eModifierType_Armature) { diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index 381e4350391..7df7561a1a1 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -40,7 +40,11 @@ #include "BKE_bmesh.h" #include "BKE_tessmesh.h" -/* main function for copying DerivedMesh data into BMesh */ +/** + * The main function for copying DerivedMesh data into BMesh. + * + * \note The mesh may already have geometry. see 'is_init' + */ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) { MVert *mv, *mvert; @@ -56,6 +60,14 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BLI_array_declare(edges); int i, j, k, totvert, totedge /* , totface */ /* UNUSED */ ; int is_init = (bm->totvert == 0) && (bm->totedge == 0) && (bm->totface == 0); + char has_orig_hflag = 0; + + if (is_init == FALSE) { + /* check if we have an origflag */ + has_orig_hflag |= CustomData_has_layer(&bm->vdata, CD_ORIGINDEX) ? BM_VERT : 0; + has_orig_hflag |= CustomData_has_layer(&bm->edata, CD_ORIGINDEX) ? BM_EDGE : 0; + has_orig_hflag |= CustomData_has_layer(&bm->pdata, CD_ORIGINDEX) ? BM_FACE : 0; + } /*merge custom data layout*/ CustomData_bmesh_merge(&dm->vertData, &bm->vdata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_VERT); @@ -85,10 +97,15 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BM_elem_index_set(v, i); /* set_inline */ CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data); + vtable[i] = v; /* add bevel weight */ BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mv->bweight / 255.0f); - vtable[i] = v; + + if (UNLIKELY(has_orig_hflag & BM_VERT)) { + int *orig_index = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_ORIGINDEX); + *orig_index = ORIGINDEX_NONE; + } } MEM_freeN(mvert); if (is_init) bm->elem_index_dirty &= ~BM_VERT; @@ -109,6 +126,11 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (float)me->crease / 255.0f); /* add bevel weight */ BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)me->bweight / 255.0f); + + if (UNLIKELY(has_orig_hflag & BM_EDGE)) { + int *orig_index = CustomData_bmesh_get(&bm->edata, e->head.data, CD_ORIGINDEX); + *orig_index = ORIGINDEX_NONE; + } } MEM_freeN(medge); if (is_init) bm->elem_index_dirty &= ~BM_EDGE; @@ -158,6 +180,11 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) else { BM_face_normal_update(f); } + + if (UNLIKELY(has_orig_hflag & BM_FACE)) { + int *orig_index = CustomData_bmesh_get(&bm->pdata, f->head.data, CD_ORIGINDEX); + *orig_index = ORIGINDEX_NONE; + } } if (is_init) bm->elem_index_dirty &= ~BM_FACE; diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index c737dccc5d2..06d7cf55d49 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -43,9 +43,9 @@ #include "BLI_bitmap.h" #include "BLI_blenlib.h" #include "BLI_math.h" -#include "BLI_pbvh.h" #include "BLI_utildefines.h" +#include "BKE_pbvh.h" #include "BKE_ccg.h" #include "BKE_cdderivedmesh.h" #include "BKE_mesh.h" diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 9ea1c3e8c74..bf4e32ef122 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -57,14 +57,14 @@ #include "DNA_view3d_types.h" #include "DNA_world_types.h" #include "DNA_object_types.h" +#include "DNA_property_types.h" #include "BLI_blenlib.h" -#include "BLI_bpath.h" #include "BLI_math.h" -#include "BLI_pbvh.h" #include "BLI_utildefines.h" #include "BLI_linklist.h" +#include "BKE_pbvh.h" #include "BKE_main.h" #include "BKE_global.h" #include "BKE_idprop.h" @@ -739,6 +739,50 @@ void BKE_object_unlink(Object *ob) } } +/* actual check for internal data, not context or flags */ +int BKE_object_is_in_editmode(Object *ob) +{ + if (ob->data == NULL) + return 0; + + if (ob->type == OB_MESH) { + Mesh *me = ob->data; + if (me->edit_btmesh) + return 1; + } + else if (ob->type == OB_ARMATURE) { + bArmature *arm = ob->data; + + if (arm->edbo) + return 1; + } + else if (ob->type == OB_FONT) { + Curve *cu = ob->data; + + if (cu->editfont) + return 1; + } + else if (ob->type == OB_MBALL) { + MetaBall *mb = ob->data; + + if (mb->editelems) + return 1; + } + else if (ob->type == OB_LATTICE) { + Lattice *lt = ob->data; + + if (lt->editlatt) + return 1; + } + else if (ob->type == OB_SURF || ob->type == OB_CURVE) { + Curve *cu = ob->data; + + if (cu->editnurb) + return 1; + } + return 0; +} + int BKE_object_exists_check(Object *obtest) { Object *ob; @@ -1498,14 +1542,14 @@ void BKE_object_make_proxy(Object *ob, Object *target, Object *gob) /* *************** CALC ****************** */ -void BKE_object_scale_to_mat3(Object *ob, float mat[][3]) +void BKE_object_scale_to_mat3(Object *ob, float mat[3][3]) { float vec[3]; mul_v3_v3v3(vec, ob->size, ob->dscale); size_to_mat3(mat, vec); } -void BKE_object_rot_to_mat3(Object *ob, float mat[][3]) +void BKE_object_rot_to_mat3(Object *ob, float mat[3][3], short use_drot) { float rmat[3][3], dmat[3][3]; @@ -1536,10 +1580,13 @@ void BKE_object_rot_to_mat3(Object *ob, float mat[][3]) } /* combine these rotations */ - mul_m3_m3m3(mat, dmat, rmat); + if (use_drot) + mul_m3_m3m3(mat, dmat, rmat); + else + copy_m3_m3(mat, rmat); } -void BKE_object_mat3_to_rot(Object *ob, float mat[][3], short use_compat) +void BKE_object_mat3_to_rot(Object *ob, float mat[3][3], short use_compat) { switch (ob->rotmode) { case ROT_MODE_QUAT: @@ -1642,7 +1689,7 @@ void BKE_object_tfm_protected_restore(Object *ob, } /* see BKE_pchan_apply_mat4() for the equivalent 'pchan' function */ -void BKE_object_apply_mat4(Object *ob, float mat[][4], const short use_compat, const short use_parent) +void BKE_object_apply_mat4(Object *ob, float mat[4][4], const short use_compat, const short use_parent) { float rot[3][3]; @@ -1671,7 +1718,7 @@ void BKE_object_apply_mat4(Object *ob, float mat[][4], const short use_compat, c /* BKE_object_mat3_to_rot handles delta rotations */ } -void BKE_object_to_mat3(Object *ob, float mat[][3]) /* no parent */ +void BKE_object_to_mat3(Object *ob, float mat[3][3]) /* no parent */ { float smat[3][3]; float rmat[3][3]; @@ -1681,11 +1728,11 @@ void BKE_object_to_mat3(Object *ob, float mat[][3]) /* no parent */ BKE_object_scale_to_mat3(ob, smat); /* rot */ - BKE_object_rot_to_mat3(ob, rmat); + BKE_object_rot_to_mat3(ob, rmat, TRUE); mul_m3_m3m3(mat, rmat, smat); } -void BKE_object_to_mat4(Object *ob, float mat[][4]) +void BKE_object_to_mat4(Object *ob, float mat[4][4]) { float tmat[3][3]; @@ -1699,7 +1746,7 @@ void BKE_object_to_mat4(Object *ob, float mat[][4]) /* extern */ int enable_cu_speed = 1; -static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4]) +static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[4][4]) { Curve *cu; float vec[4], dir[3], quat[4], radius, ctime; @@ -1783,7 +1830,7 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4]) } } -static void ob_parbone(Object *ob, Object *par, float mat[][4]) +static void ob_parbone(Object *ob, Object *par, float mat[4][4]) { bPoseChannel *pchan; float vec[3]; @@ -1913,7 +1960,7 @@ static void give_parvert(Object *par, int nr, float vec[3]) } } -static void ob_parvert3(Object *ob, Object *par, float mat[][4]) +static void ob_parvert3(Object *ob, Object *par, float mat[4][4]) { float cmat[3][3], v1[3], v2[3], v3[3], q[4]; @@ -1941,7 +1988,7 @@ static void ob_parvert3(Object *ob, Object *par, float mat[][4]) } } -static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[][4], float slowmat[][4], int simul) +static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4][4], float slowmat[4][4], int simul) { float totmat[4][4]; float tmat[4][4]; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 5f5a713064d..b2851962b49 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -55,7 +55,6 @@ #include "BLI_rand.h" #include "BLI_threads.h" #include "BLI_linklist.h" -#include "BLI_bpath.h" #include "BKE_anim.h" #include "BKE_animsys.h" @@ -680,7 +679,7 @@ static float psys_render_projected_area(ParticleSystem *psys, const float center return area; } -void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[][4], float winmat[][4], int winx, int winy, int timeoffset) +void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[4][4], float winmat[4][4], int winx, int winy, int timeoffset) { ParticleRenderData *data; ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); @@ -1919,7 +1918,7 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int in /* Path Cache */ /************************************************/ -static void do_kink(ParticleKey *state, ParticleKey *par, float *par_rot, float time, float freq, float shape, float amplitude, float flat, short type, short axis, float obmat[][4], int smooth_start) +static void do_kink(ParticleKey *state, ParticleKey *par, float *par_rot, float time, float freq, float shape, float amplitude, float flat, short type, short axis, float obmat[4][4], int smooth_start) { float kink[3] = {1.f, 0.f, 0.f}, par_vec[3], q1[4] = {1.f, 0.f, 0.f, 0.f}; float t, dt = 1.f, result[3]; @@ -3351,7 +3350,7 @@ static void key_from_object(Object *ob, ParticleKey *key) } #endif -static void triatomat(float *v1, float *v2, float *v3, float (*uv)[2], float mat[][4]) +static void triatomat(float *v1, float *v2, float *v3, float (*uv)[2], float mat[4][4]) { float det, w1, w2, d1[2], d2[2]; @@ -3392,7 +3391,7 @@ static void triatomat(float *v1, float *v2, float *v3, float (*uv)[2], float mat cross_v3_v3v3(mat[0], mat[1], mat[2]); } -static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float mat[][4], int orco) +static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float mat[4][4], int orco) { float v[3][3]; MFace *mface; @@ -3425,7 +3424,7 @@ static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float m triatomat(v[0], v[1], v[2], (osface) ? osface->uv : NULL, mat); } -void psys_mat_hair_to_object(Object *UNUSED(ob), DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4]) +void psys_mat_hair_to_object(Object *UNUSED(ob), DerivedMesh *dm, short from, ParticleData *pa, float hairmat[4][4]) { float vec[3]; @@ -3440,7 +3439,7 @@ void psys_mat_hair_to_object(Object *UNUSED(ob), DerivedMesh *dm, short from, Pa copy_v3_v3(hairmat[3], vec); } -void psys_mat_hair_to_orco(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4]) +void psys_mat_hair_to_orco(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[4][4]) { float vec[3], orco[3]; @@ -3462,7 +3461,7 @@ void psys_vec_rot_to_face(DerivedMesh *dm, ParticleData *pa, float vec[3]) mul_mat3_m4_v3(mat, vec); } -void psys_mat_hair_to_global(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4]) +void psys_mat_hair_to_global(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[4][4]) { float facemat[4][4]; @@ -4502,7 +4501,7 @@ void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part, psys_particle_on_emitter(psmd, part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, loc, 0, 0, 0, orco, 0); } -void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa, ChildParticle *cpa, ParticleCacheKey *cache, float mat[][4], float *scale) +void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa, ChildParticle *cpa, ParticleCacheKey *cache, float mat[4][4], float *scale) { Object *ob = sim->ob; ParticleSystem *psys = sim->psys; diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 90889d7c09e..090082b333d 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -23,7 +23,8 @@ * Contributor(s): Raul Fernandez Hernandez (Farsthary), Stephen Swhitehorn. * * Adaptive time step - * Copyright 2011 AutoCRC + * Classical SPH + * Copyright 2011-2012 AutoCRC * * ***** END GPL LICENSE BLOCK ***** */ @@ -1889,7 +1890,6 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, bpa->data.acc[0]=bpa->data.acc[1]=bpa->data.acc[2]=0.0f; } - if (part->type == PART_HAIR) { pa->lifetime = 100.0f; } @@ -2390,33 +2390,36 @@ typedef struct SPHRangeData { SPHNeighbor neighbors[SPH_NEIGHBORS]; int tot_neighbors; - float density, near_density; - float h; + float* data; ParticleSystem *npsys; ParticleData *pa; + float h; float massfac; int use_size; } SPHRangeData; -typedef struct SPHData { - ParticleSystem *psys[10]; - ParticleData *pa; - float mass; - EdgeHash *eh; - float *gravity; - /* Average distance to neighbors (other particles in the support domain), - * for calculating the Courant number (adaptive time step). */ - int pass; - float element_size; - float flow[3]; - - /* Integrator callbacks. This allows different SPH implementations. */ - void (*force_cb) (void *sphdata_v, ParticleKey *state, float *force, float *impulse); - void (*density_cb) (void *rangedata_v, int index, float squared_dist); -} SPHData; +static void sph_evaluate_func(BVHTree *tree, ParticleSystem **psys, float co[3], SPHRangeData *pfr, float interaction_radius, BVHTree_RangeQuery callback) +{ + int i; + + pfr->tot_neighbors = 0; + + for (i=0; i < 10 && psys[i]; i++) { + pfr->npsys = psys[i]; + pfr->massfac = psys[i]->part->mass; + pfr->use_size = psys[i]->part->flag & PART_SIZEMASS; + if (tree) { + BLI_bvhtree_range_query(tree, co, interaction_radius, callback, pfr); + break; + } + else { + BLI_bvhtree_range_query(psys[i]->bvhtree, co, interaction_radius, callback, pfr); + } + } +} static void sph_density_accum_cb(void *userdata, int index, float squared_dist) { SPHRangeData *pfr = (SPHRangeData *)userdata; @@ -2446,8 +2449,8 @@ static void sph_density_accum_cb(void *userdata, int index, float squared_dist) if (pfr->use_size) q *= npa->size; - pfr->density += q*q; - pfr->near_density += q*q*q; + pfr->data[0] += q*q; + pfr->data[1] += q*q*q; } /* @@ -2500,8 +2503,10 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa float inv_mass = 1.0f/mass; float spring_constant = fluid->spring_k; - - float h = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.f*pa->size : 1.f); /* 4.0 seems to be a pretty good value */ + + /* 4.0 seems to be a pretty good value */ + float interaction_radius = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.0f * pa->size : 1.0f); + float h = interaction_radius * sphdata->hfac; float rest_density = fluid->rest_density * (fluid->flag & SPH_FAC_DENSITY ? 4.77f : 1.f); /* 4.77 is an experimentally determined density factor */ float rest_length = fluid->rest_length * (fluid->flag & SPH_FAC_REST_LENGTH ? 2.588f * pa->size : 1.f); @@ -2512,24 +2517,23 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa float vec[3]; float vel[3]; float co[3]; + float data[2]; + float density, near_density; int i, spring_index, index = pa - psys[0]->particles; - pfr.tot_neighbors = 0; - pfr.density = pfr.near_density = 0.f; + data[0] = data[1] = 0; + pfr.data = data; pfr.h = h; pfr.pa = pa; - for (i=0; i<10 && psys[i]; i++) { - pfr.npsys = psys[i]; - pfr.massfac = psys[i]->part->mass*inv_mass; - pfr.use_size = psys[i]->part->flag & PART_SIZEMASS; + sph_evaluate_func( NULL, psys, state->co, &pfr, interaction_radius, sph_density_accum_cb); - BLI_bvhtree_range_query(psys[i]->bvhtree, state->co, h, sphdata->density_cb, &pfr); - } + density = data[0]; + near_density = data[1]; - pressure = stiffness * (pfr.density - rest_density); - near_pressure = stiffness_near_fac * pfr.near_density; + pressure = stiffness * (density - rest_density); + near_pressure = stiffness_near_fac * near_density; pfn = pfr.neighbors; for (i=0; i<pfr.tot_neighbors; i++, pfn++) { @@ -2593,14 +2597,207 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa /* Artificial buoyancy force in negative gravity direction */ if (fluid->buoyancy > 0.f && gravity) - madd_v3_v3fl(force, gravity, fluid->buoyancy * (pfr.density-rest_density)); + madd_v3_v3fl(force, gravity, fluid->buoyancy * (density-rest_density)); if (sphdata->pass == 0 && psys[0]->part->time_flag & PART_TIME_AUTOSF) sph_particle_courant(sphdata, &pfr); sphdata->pass++; } -static void sph_solver_init(ParticleSimulationData *sim, SPHData *sphdata) +/* powf is really slow for raising to integer powers. */ +MINLINE float pow2(float x) +{ + return x * x; +} +MINLINE float pow3(float x) +{ + return pow2(x) * x; +} +MINLINE float pow4(float x) +{ + return pow2(pow2(x)); +} +MINLINE float pow7(float x) +{ + return pow2(pow3(x)) * x; +} + +static void sphclassical_density_accum_cb(void *userdata, int index, float UNUSED(squared_dist)) +{ + SPHRangeData *pfr = (SPHRangeData *)userdata; + ParticleData *npa = pfr->npsys->particles + index; + float q; + float qfac = 21.0f / (256.f * (float)M_PI); + float rij, rij_h; + float vec[3]; + + /* Exclude particles that are more than 2h away. Can't use squared_dist here + * because it is not accurate enough. Use current state, i.e. the output of + * basic_integrate() - z0r */ + sub_v3_v3v3(vec, npa->state.co, pfr->pa->state.co); + rij = len_v3(vec); + rij_h = rij / pfr->h; + if (rij_h > 2.0f) + return; + + /* Smoothing factor. Utilise the Wendland kernel. gnuplot: + * q1(x) = (2.0 - x)**4 * ( 1.0 + 2.0 * x) + * plot [0:2] q1(x) */ + q = qfac / pow3(pfr->h) * pow4(2.0f - rij_h) * ( 1.0f + 2.0f * rij_h); + q *= pfr->massfac; + + if (pfr->use_size) + q *= pfr->pa->size; + + pfr->data[0] += q; + pfr->data[1] += q / npa->sphdensity; +} + +static void sphclassical_neighbour_accum_cb(void *userdata, int index, float UNUSED(squared_dist)) +{ + SPHRangeData *pfr = (SPHRangeData *)userdata; + ParticleData *npa = pfr->npsys->particles + index; + float rij, rij_h; + float vec[3]; + + if (pfr->tot_neighbors >= SPH_NEIGHBORS) + return; + + /* Exclude particles that are more than 2h away. Can't use squared_dist here + * because it is not accurate enough. Use current state, i.e. the output of + * basic_integrate() - z0r */ + sub_v3_v3v3(vec, npa->state.co, pfr->pa->state.co); + rij = len_v3(vec); + rij_h = rij / pfr->h; + if (rij_h > 2.0f) + return; + + pfr->neighbors[pfr->tot_neighbors].index = index; + pfr->neighbors[pfr->tot_neighbors].psys = pfr->npsys; + pfr->tot_neighbors++; +} +static void sphclassical_force_cb(void *sphdata_v, ParticleKey *state, float *force, float *UNUSED(impulse)) +{ + SPHData *sphdata = (SPHData *)sphdata_v; + ParticleSystem **psys = sphdata->psys; + ParticleData *pa = sphdata->pa; + SPHFluidSettings *fluid = psys[0]->part->fluid; + SPHRangeData pfr; + SPHNeighbor *pfn; + float *gravity = sphdata->gravity; + + float dq, u, rij, dv[3]; + float pressure, npressure; + + float visc = fluid->viscosity_omega; + + float interaction_radius; + float h, hinv; + /* 4.77 is an experimentally determined density factor */ + float rest_density = fluid->rest_density * (fluid->flag & SPH_FAC_DENSITY ? 4.77f : 1.0f); + + float stiffness = fluid->stiffness_k; + + ParticleData *npa; + float vec[3]; + float co[3]; + float pressureTerm; + + int i; + + float qfac2 = 42.0f / (256.0f * (float)M_PI); + float rij_h; + + /* 4.0 here is to be consistent with previous formulation/interface */ + interaction_radius = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.0f * pa->size : 1.0f); + h = interaction_radius * sphdata->hfac; + hinv = 1.0f / h; + + pfr.h = h; + pfr.pa = pa; + + sph_evaluate_func(NULL, psys, state->co, &pfr, interaction_radius, sphclassical_neighbour_accum_cb); + pressure = stiffness * (pow7(pa->sphdensity / rest_density) - 1.0f); + + /* multiply by mass so that we return a force, not accel */ + qfac2 *= sphdata->mass / pow3(pfr.h); + + pfn = pfr.neighbors; + for (i = 0; i < pfr.tot_neighbors; i++, pfn++) { + npa = pfn->psys->particles + pfn->index; + if (npa == pa) { + /* we do not contribute to ourselves */ + continue; + } + + /* Find vector to neighbour. Exclude particles that are more than 2h + * away. Can't use current state here because it may have changed on + * another thread - so do own mini integration. Unlike basic_integrate, + * SPH integration depends on neighbouring particles. - z0r */ + madd_v3_v3v3fl(co, npa->prev_state.co, npa->prev_state.vel, state->time); + sub_v3_v3v3(vec, co, state->co); + rij = normalize_v3(vec); + rij_h = rij / pfr.h; + if (rij_h > 2.0f) + continue; + + npressure = stiffness * (pow7(npa->sphdensity / rest_density) - 1.0f); + + /* First derivative of smoothing factor. Utilise the Wendland kernel. + * gnuplot: + * q2(x) = 2.0 * (2.0 - x)**4 - 4.0 * (2.0 - x)**3 * (1.0 + 2.0 * x) + * plot [0:2] q2(x) + * Particles > 2h away are excluded above. */ + dq = qfac2 * (2.0f * pow4(2.0f - rij_h) - 4.0f * pow3(2.0f - rij_h) * (1.0f + 2.0f * rij_h) ); + + if (pfn->psys->part->flag & PART_SIZEMASS) + dq *= npa->size; + + pressureTerm = pressure / pow2(pa->sphdensity) + npressure / pow2(npa->sphdensity); + + /* Note that 'minus' is removed, because vec = vecBA, not vecAB. + * This applies to the viscosity calculation below, too. */ + madd_v3_v3fl(force, vec, pressureTerm * dq); + + /* Viscosity */ + if (visc > 0.0f) { + sub_v3_v3v3(dv, npa->prev_state.vel, pa->prev_state.vel); + u = dot_v3v3(vec, dv); + /* Apply parameters */ + u *= -dq * hinv * visc / (0.5f * npa->sphdensity + 0.5f * pa->sphdensity); + madd_v3_v3fl(force, vec, u); + } + } + + /* Artificial buoyancy force in negative gravity direction */ + if (fluid->buoyancy > 0.f && gravity) + madd_v3_v3fl(force, gravity, fluid->buoyancy * (pa->sphdensity - rest_density)); + + if (sphdata->pass == 0 && psys[0]->part->time_flag & PART_TIME_AUTOSF) + sph_particle_courant(sphdata, &pfr); + sphdata->pass++; +} + +static void sphclassical_calc_dens(ParticleData *pa, float UNUSED(dfra), SPHData *sphdata) +{ + ParticleSystem **psys = sphdata->psys; + SPHFluidSettings *fluid = psys[0]->part->fluid; + /* 4.0 seems to be a pretty good value */ + float interaction_radius = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.0f * psys[0]->part->size : 1.0f); + SPHRangeData pfr; + float data[2]; + + data[0] = 0; + data[1] = 0; + pfr.data = data; + pfr.h = interaction_radius * sphdata->hfac; + pfr.pa = pa; + + sph_evaluate_func( NULL, psys, pa->state.co, &pfr, interaction_radius, sphclassical_density_accum_cb); + pa->sphdensity = MIN2(MAX2(data[0], fluid->rest_density * 0.9f), fluid->rest_density * 1.1f); +} + +void psys_sph_init(ParticleSimulationData *sim, SPHData *sphdata) { ParticleTarget *pt; int i; @@ -2621,17 +2818,46 @@ static void sph_solver_init(ParticleSimulationData *sim, SPHData *sphdata) sphdata->pa = NULL; sphdata->mass = 1.0f; - sphdata->force_cb = sph_force_cb; - sphdata->density_cb = sph_density_accum_cb; + if (sim->psys->part->fluid->solver == SPH_SOLVER_DDR) { + sphdata->force_cb = sph_force_cb; + sphdata->density_cb = sph_density_accum_cb; + sphdata->hfac = 1.0f; + } + else { + /* SPH_SOLVER_CLASSICAL */ + sphdata->force_cb = sphclassical_force_cb; + sphdata->density_cb = sphclassical_density_accum_cb; + sphdata->hfac = 0.5f; + } + } -static void sph_solver_finalise(SPHData *sphdata) +void psys_sph_finalise(SPHData *sphdata) { if (sphdata->eh) { BLI_edgehash_free(sphdata->eh, NULL); sphdata->eh = NULL; } } +/* Sample the density field at a point in space. */ +void psys_sph_density(BVHTree *tree, SPHData *sphdata, float co[3], float vars[2]) +{ + ParticleSystem **psys = sphdata->psys; + SPHFluidSettings *fluid = psys[0]->part->fluid; + /* 4.0 seems to be a pretty good value */ + float interaction_radius = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.0f * psys[0]->part->size : 1.0f); + SPHRangeData pfr; + float density[2]; + + density[0] = density[1] = 0.0f; + pfr.data = density; + pfr.h = interaction_radius*sphdata->hfac; + + sph_evaluate_func(tree, psys, co, &pfr, interaction_radius, sphdata->density_cb); + + vars[0] = pfr.data[0]; + vars[1] = pfr.data[1]; +} static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float dfra, SPHData *sphdata) { @@ -3781,18 +4007,19 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra)) /* Code for an adaptive time step based on the Courant-Friedrichs-Lewy * condition. */ -#define MIN_TIMESTEP 1.0f / 101.0f +static const float MIN_TIMESTEP = 1.0f / 101.0f; /* Tolerance of 1.5 means the last subframe neither favors growing nor * shrinking (e.g if it were 1.3, the last subframe would tend to be too * small). */ -#define TIMESTEP_EXPANSION_TOLERANCE 1.5f +static const float TIMESTEP_EXPANSION_FACTOR = 0.1f; +static const float TIMESTEP_EXPANSION_TOLERANCE = 1.5f; /* Calculate the speed of the particle relative to the local scale of the * simulation. This should be called once per particle during a simulation * step, after the velocity has been updated. element_size defines the scale of * the simulation, and is typically the distance to neighboring particles. */ static void update_courant_num(ParticleSimulationData *sim, ParticleData *pa, - float dtime, SPHData *sphdata) + float dtime, SPHData *sphdata) { float relative_vel[3]; float speed; @@ -3802,14 +4029,31 @@ static void update_courant_num(ParticleSimulationData *sim, ParticleData *pa, if (sim->courant_num < speed * dtime / sphdata->element_size) sim->courant_num = speed * dtime / sphdata->element_size; } +static float get_base_time_step(ParticleSettings *part) +{ + return 1.0f / (float) (part->subframes + 1); +} /* Update time step size to suit current conditions. */ static float update_timestep(ParticleSystem *psys, ParticleSimulationData *sim, float t_frac) { + float dt_target; if (sim->courant_num == 0.0f) - psys->dt_frac = 1.0f; + dt_target = 1.0f; + else + dt_target = psys->dt_frac * (psys->part->courant_target / sim->courant_num); + + /* Make sure the time step is reasonable. For some reason, the CLAMP macro + * doesn't work here. The time step becomes too large. - z0r */ + if (dt_target < MIN_TIMESTEP) + dt_target = MIN_TIMESTEP; + else if (dt_target > get_base_time_step(psys->part)) + dt_target = get_base_time_step(psys->part); + + /* Decrease time step instantly, but increase slowly. */ + if (dt_target > psys->dt_frac) + psys->dt_frac = interpf(dt_target, psys->dt_frac, TIMESTEP_EXPANSION_FACTOR); else - psys->dt_frac *= (psys->part->courant_target / sim->courant_num); - CLAMP(psys->dt_frac, MIN_TIMESTEP, 1.0f); + psys->dt_frac = dt_target; /* Sync with frame end if it's close. */ if (t_frac == 1.0f) @@ -3973,31 +4217,72 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) case PART_PHYS_FLUID: { SPHData sphdata; - sph_solver_init(sim, &sphdata); + ParticleSettings *part = sim->psys->part; + psys_sph_init(sim, &sphdata); - #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5) - LOOP_DYNAMIC_PARTICLES { - /* do global forces & effectors */ - basic_integrate(sim, p, pa->state.time, cfra); + if (part->fluid->flag & SPH_SOLVER_DDR) { + /* Apply SPH forces using double-density relaxation algorithm + * (Clavat et. al.) */ + #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5) + LOOP_DYNAMIC_PARTICLES { + /* do global forces & effectors */ + basic_integrate(sim, p, pa->state.time, cfra); - /* actual fluids calculations */ - sph_integrate(sim, pa, pa->state.time, &sphdata); + /* actual fluids calculations */ + sph_integrate(sim, pa, pa->state.time, &sphdata); - if (sim->colliders) - collision_check(sim, p, pa->state.time, cfra); - - /* SPH particles are not physical particles, just interpolation - * particles, thus rotation has not a direct sense for them */ - basic_rotate(part, pa, pa->state.time, timestep); + if (sim->colliders) + collision_check(sim, p, pa->state.time, cfra); + + /* SPH particles are not physical particles, just interpolation + * particles, thus rotation has not a direct sense for them */ + basic_rotate(part, pa, pa->state.time, timestep); + + #pragma omp critical + if (part->time_flag & PART_TIME_AUTOSF) + update_courant_num(sim, pa, dtime, &sphdata); + } + + sph_springs_modify(psys, timestep); - #pragma omp critical - if (part->time_flag & PART_TIME_AUTOSF) - update_courant_num(sim, pa, dtime, &sphdata); } + else { + /* SPH_SOLVER_CLASSICAL */ + /* Apply SPH forces using classical algorithm (due to Gingold + * and Monaghan). Note that, unlike double-density relaxation, + * this algorthim is separated into distinct loops. */ + + #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5) + LOOP_DYNAMIC_PARTICLES { + basic_integrate(sim, p, pa->state.time, cfra); + } + + /* calculate summation density */ + #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5) + LOOP_DYNAMIC_PARTICLES { + sphclassical_calc_dens(pa, pa->state.time, &sphdata); + } + + /* do global forces & effectors */ + #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5) + LOOP_DYNAMIC_PARTICLES { + /* actual fluids calculations */ + sph_integrate(sim, pa, pa->state.time, &sphdata); + + if (sim->colliders) + collision_check(sim, p, pa->state.time, cfra); + + /* SPH particles are not physical particles, just interpolation + * particles, thus rotation has not a direct sense for them */ + basic_rotate(part, pa, pa->state.time, timestep); - sph_springs_modify(psys, timestep); + #pragma omp critical + if (part->time_flag & PART_TIME_AUTOSF) + update_courant_num(sim, pa, dtime, &sphdata); + } + } - sph_solver_finalise(&sphdata); + psys_sph_finalise(&sphdata); break; } } @@ -4309,14 +4594,14 @@ static void system_step(ParticleSimulationData *sim, float cfra) if (!(part->time_flag & PART_TIME_AUTOSF)) { /* Constant time step */ - psys->dt_frac = 1.0f / (float) (part->subframes + 1); + psys->dt_frac = get_base_time_step(part); } else if ((int)cfra == startframe) { - /* Variable time step; use a very conservative value at the start. - * If it doesn't need to be so small, it will quickly grow. */ - psys->dt_frac = 1.0; + /* Variable time step; initialise to subframes */ + psys->dt_frac = get_base_time_step(part); } else if (psys->dt_frac < MIN_TIMESTEP) { + /* Variable time step; subsequent frames */ psys->dt_frac = MIN_TIMESTEP; } diff --git a/source/blender/blenlib/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 6fa6d86589f..3a4e8afca76 100644 --- a/source/blender/blenlib/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -22,8 +22,6 @@ * \ingroup bli */ - - #include "DNA_meshdata_types.h" #include "MEM_guardedalloc.h" @@ -32,8 +30,8 @@ #include "BLI_math.h" #include "BLI_utildefines.h" #include "BLI_ghash.h" -#include "BLI_pbvh.h" +#include "BKE_pbvh.h" #include "BKE_ccg.h" #include "BKE_DerivedMesh.h" #include "BKE_mesh.h" /* for BKE_mesh_calc_normals */ diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 965a1e2b4a6..2eadfe73858 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -2782,7 +2782,8 @@ static PointCache *ptcache_copy(PointCache *cache, int copy_data) ncache->mem_cache.last = NULL; ncache->cached_frames = NULL; - ncache->flag= 0; + /* flag is a mix of user settings and simulator/baking state */ + ncache->flag= ncache->flag & (PTCACHE_DISK_CACHE|PTCACHE_EXTERNAL|PTCACHE_IGNORE_LIBPATH); ncache->simframe= 0; } else { diff --git a/source/blender/blenkernel/intern/property.c b/source/blender/blenkernel/intern/property.c index 8da4f11fed3..c4658712ecb 100644 --- a/source/blender/blenkernel/intern/property.c +++ b/source/blender/blenkernel/intern/property.c @@ -287,7 +287,7 @@ void BKE_bproperty_add(bProperty *prop, const char *str) } /* reads value of property, sets it in chars in str */ -void BKE_bproperty_set_valstr(bProperty *prop, char *str) +void BKE_bproperty_set_valstr(bProperty *prop, char str[MAX_PROPSTRING]) { // extern int Gdfra; /* sector.c */ diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c index d925d736358..185aeac5452 100644 --- a/source/blender/blenkernel/intern/report.c +++ b/source/blender/blenkernel/intern/report.c @@ -52,6 +52,8 @@ static const char *report_type_str(int type) return TIP_("Info"); case RPT_OPERATOR: return TIP_("Operator"); + case RPT_PROPERTY: + return TIP_("Property"); case RPT_WARNING: return TIP_("Warning"); case RPT_ERROR: diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 8fcd5ca56d0..5e6d7647d1d 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -145,7 +145,8 @@ Scene *BKE_scene_copy(Scene *sce, int type) if (type == SCE_COPY_EMPTY) { ListBase lb; - scen = BKE_scene_add(sce->id.name + 2); + /* XXX. main should become an arg */ + scen = BKE_scene_add(G.main, sce->id.name + 2); lb = scen->r.layers; scen->r = sce->r; @@ -379,9 +380,8 @@ void BKE_scene_free(Scene *sce) BKE_color_managed_view_settings_free(&sce->view_settings); } -Scene *BKE_scene_add(const char *name) +static Scene *scene_add(Main *bmain, const char *name) { - Main *bmain = G.main; Scene *sce; ParticleEditSettings *pset; int a; @@ -439,6 +439,7 @@ Scene *BKE_scene_add(const char *name) sce->r.bake_osa = 5; sce->r.bake_flag = R_BAKE_CLEAR; sce->r.bake_normal_space = R_BAKE_SPACE_TANGENT; + sce->r.bake_rays_number = 256; sce->r.scemode = R_DOCOMP | R_DOSEQ | R_EXTENSION; sce->r.stamp = R_STAMP_TIME | R_STAMP_FRAME | R_STAMP_DATE | R_STAMP_CAMERA | R_STAMP_SCENE | R_STAMP_FILENAME | R_STAMP_RENDERTIME; sce->r.stamp_font_id = 12; @@ -612,6 +613,11 @@ Scene *BKE_scene_add(const char *name) return sce; } +Scene *BKE_scene_add(Main *bmain, const char *name) +{ + return scene_add(bmain, name); +} + Base *BKE_scene_base_find(Scene *scene, Object *ob) { return BLI_findptr(&scene->base, ob, offsetof(Base, object)); diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index 0b7fdaa7c1d..3bff209f53c 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -1745,7 +1745,7 @@ static void transform_image(int x, int y, ImBuf *ibuf1, ImBuf *out, float scale /* interpolate */ switch (interpolation) { case 0: - neareast_interpolation(ibuf1, out, xt, yt, xi, yi); + nearest_interpolation(ibuf1, out, xt, yt, xi, yi); break; case 1: bilinear_interpolation(ibuf1, out, xt, yt, xi, yi); diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index acce3740c98..1467d24f323 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -191,7 +191,9 @@ static void BKE_sequence_free_ex(Scene *scene, Sequence *seq, const int do_cache ((ID *)seq->sound)->us--; } - /* clipboard has no scene and will never have a sound handle or be active */ + /* clipboard has no scene and will never have a sound handle or be active + * same goes to sequences copy for proxy rebuild job + */ if (scene) { Editing *ed = scene->ed; @@ -1451,7 +1453,7 @@ void BKE_sequencer_proxy_rebuild_finish(SeqIndexBuildContext *context, short sto IMB_anim_index_rebuild_finish(context->index_context, stop); } - seq_free_sequence_recurse(context->scene, context->seq); + seq_free_sequence_recurse(NULL, context->seq); MEM_freeN(context); } @@ -2409,8 +2411,9 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float /* opengl offscreen render */ BKE_scene_update_for_newframe(context.bmain, scene, scene->lay); - ibuf = sequencer_view3d_cb(scene, camera, context.rectx, context.recty, - IB_rect, context.scene->r.seq_prev_type, TRUE, FALSE, err_out); + ibuf = sequencer_view3d_cb(scene, camera, context.rectx, context.recty, IB_rect, + context.scene->r.seq_prev_type, context.scene->r.seq_flag & R_SEQ_SOLID_TEX, + TRUE, FALSE, err_out); if (ibuf == NULL) { fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out); } diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 53dfbdcfb85..c9cf5d561e5 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -924,7 +924,8 @@ static void clampBoundsInDomain(SmokeDomainSettings *sds, int min[3], int max[3] } } -static void em_allocateData(EmissionMap *em, int use_velocity) { +static void em_allocateData(EmissionMap *em, int use_velocity) +{ int i, res[3]; for (i = 0; i < 3; i++) { @@ -941,7 +942,8 @@ static void em_allocateData(EmissionMap *em, int use_velocity) { em->velocity = MEM_callocN(sizeof(float) * em->total_cells * 3, "smoke_flow_velocity"); } -static void em_freeData(EmissionMap *em) { +static void em_freeData(EmissionMap *em) +{ if (em->influence) MEM_freeN(em->influence); if (em->velocity) @@ -2509,7 +2511,8 @@ float smoke_get_velocity_at(struct Object *ob, float position[3], float velocity return -1.0f; } -int smoke_get_data_flags(SmokeDomainSettings *sds) { +int smoke_get_data_flags(SmokeDomainSettings *sds) +{ int flags = 0; if (smoke_has_heat(sds->fluid)) flags |= SM_ACTIVE_HEAT; if (smoke_has_fuel(sds->fluid)) flags |= SM_ACTIVE_FIRE; diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c index 09440591826..f6599cc9648 100644 --- a/source/blender/blenkernel/intern/speaker.c +++ b/source/blender/blenkernel/intern/speaker.c @@ -35,7 +35,6 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" #include "BKE_animsys.h" #include "BKE_global.h" diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index f76b480c423..7c58c7b21ed 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -50,8 +50,8 @@ #include "BLI_edgehash.h" #include "BLI_math.h" #include "BLI_memarena.h" -#include "BLI_pbvh.h" +#include "BKE_pbvh.h" #include "BKE_ccg.h" #include "BKE_cdderivedmesh.h" #include "BKE_global.h" diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 6d0313f6334..149842bc038 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -42,7 +42,6 @@ #include "BLI_math.h" #include "BLI_kdopbvh.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" #include "DNA_key_types.h" #include "DNA_object_types.h" diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 30b48401046..801fecc9f7c 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -3462,15 +3462,15 @@ ImBuf *BKE_tracking_stabilize_frame(MovieTracking *tracking, int framenr, ImBuf BKE_tracking_stabilization_data_to_mat4(ibuf->x, ibuf->y, aspect, tloc, tscale, tangle, mat); invert_m4(mat); - if (filter == TRACKING_FILTER_NEAREAST) - interpolation = neareast_interpolation; + if (filter == TRACKING_FILTER_NEAREST) + interpolation = nearest_interpolation; else if (filter == TRACKING_FILTER_BILINEAR) interpolation = bilinear_interpolation; else if (filter == TRACKING_FILTER_BICUBIC) interpolation = bicubic_interpolation; else /* fallback to default interpolation method */ - interpolation = neareast_interpolation; + interpolation = nearest_interpolation; for (j = 0; j < tmpibuf->y; j++) { for (i = 0; i < tmpibuf->x; i++) { diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 4bde895cf7d..ad101c41dc5 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -40,7 +40,6 @@ #include "BLI_listbase.h" #include "BLI_utildefines.h" -#include "BLI_bpath.h" #include "BKE_animsys.h" #include "BKE_global.h" diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index 0f861a7ed37..cf2a165c2b2 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -497,8 +497,15 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex c->rc_max_rate = rd->ffcodecdata.rc_max_rate * 1000; c->rc_min_rate = rd->ffcodecdata.rc_min_rate * 1000; c->rc_buffer_size = rd->ffcodecdata.rc_buffer_size * 1024; + +#if 0 + /* this options are not set in ffmpeg.c and leads to artifacts with MPEG-4 + * see #33586: Encoding to mpeg4 makes first frame(s) blocky + */ c->rc_initial_buffer_occupancy = rd->ffcodecdata.rc_buffer_size * 3 / 4; c->rc_buffer_aggressivity = 1.0; +#endif + c->me_method = ME_EPZS; codec = avcodec_find_encoder(c->codec_id); diff --git a/source/blender/blenlib/BLI_array.h b/source/blender/blenlib/BLI_array.h index a21778307c1..6d34b0d48d5 100644 --- a/source/blender/blenlib/BLI_array.h +++ b/source/blender/blenlib/BLI_array.h @@ -196,3 +196,31 @@ if (_##arr##_is_static) { \ MEM_freeN(arr); \ } (void)0 + + +/* alloca */ +#ifdef _MSC_VER +# define alloca _alloca +#endif + +#if defined(__MINGW32__) +# include <malloc.h> /* mingw needs for alloca() */ +#endif + +#if defined(__GNUC__) || defined(__clang__) +#define BLI_array_alloca(arr, realsize) \ + (typeof(arr))alloca(sizeof(*arr) * (realsize)) + +#define BLI_array_alloca_and_count(arr, realsize) \ + (typeof(arr))alloca(sizeof(*arr) * (realsize)); \ + const int _##arr##_count = (realsize) + +#else +#define BLI_array_alloca(arr, realsize) \ + alloca(sizeof(*arr) * (realsize)) + +#define BLI_array_alloca_and_count(arr, realsize) \ + alloca(sizeof(*arr) * (realsize)); \ + const int _##arr##_count = (realsize) +#endif + diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index 1330a74bea3..d06956e39de 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -41,7 +41,7 @@ extern "C" { #endif void BLI_insertlink(struct ListBase *listbase, void *vprevlink, void *vnewlink); -int BLI_findindex(const struct ListBase *listbase, void *vlink); +int BLI_findindex(const struct ListBase *listbase, const void *vlink); int BLI_findstringindex(const struct ListBase *listbase, const char *id, const int offset); /* find forwards */ @@ -79,4 +79,4 @@ struct LinkData *BLI_genericNodeN(void *data); } #endif -#endif +#endif /* __BLI_LISTBASE_H__ */ diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index cfd163d4e57..423765bad3d 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -202,7 +202,7 @@ void perspective_m4(float mat[4][4], const float left, const float right, const float bottom, const float top, const float nearClip, const float farClip); void orthographic_m4(float mat[4][4], const float left, const float right, const float bottom, const float top, const float nearClip, const float farClip); -void window_translate_m4(float winmat[][4], float perspmat[][4], +void window_translate_m4(float winmat[4][4], float perspmat[4][4], const float x, const float y); int box_clip_bounds_m4(float boundbox[2][3], diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index f51bd1cf840..c12ec62ca1b 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -144,10 +144,14 @@ float determinant_m2(float a, float b, float determinant_m3(float a, float b, float c, float d, float e, float f, float g, float h, float i); +float determinant_m3_array(float m[3][3]); float determinant_m4(float A[4][4]); +#define PSEUDOINVERSE_EPSILON 1e-8f + void svd_m4(float U[4][4], float s[4], float V[4][4], float A[4][4]); void pseudoinverse_m4_m4(float Ainv[4][4], float A[4][4], float epsilon); +void pseudoinverse_m3_m3(float Ainv[3][3], float A[3][3], float epsilon); /****************************** Transformations ******************************/ @@ -167,8 +171,8 @@ void translate_m4(float mat[4][4], float tx, float ty, float tz); void rotate_m4(float mat[4][4], const char axis, const float angle); -void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[][3]); -void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[][4]); +void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]); +void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4]); void loc_eul_size_to_mat4(float R[4][4], const float loc[3], const float eul[3], const float size[3]); diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h index 5e47adf25ef..557ecb3dd0c 100644 --- a/source/blender/blenlib/BLI_path_util.h +++ b/source/blender/blenlib/BLI_path_util.h @@ -67,6 +67,8 @@ char *BLI_get_folder_version(const int id, const int ver, const int do_check); #define BLENDER_RESOURCE_PATH_SYSTEM 2 #define BLENDER_STARTUP_FILE "startup.blend" +#define BLENDER_USERPREF_FILE "userpref.blend" +#define BLENDER_QUIT_FILE "quit.blend" #define BLENDER_BOOKMARK_FILE "bookmarks.txt" #define BLENDER_HISTORY_FILE "recent-files.txt" diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 8a3b1c9675b..6644c58611f 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -25,9 +25,7 @@ set(INC . - ../blenkernel - ../blenloader - ../gpu + # ../blenkernel # dont add this back! ../makesdna ../../../intern/ghost ../../../intern/guardedalloc @@ -50,7 +48,6 @@ set(SRC intern/BLI_mempool.c intern/DLRB_tree.c intern/boxpack2d.c - intern/bpath.c intern/callbacks.c intern/cpu.c intern/dynlib.c @@ -78,7 +75,6 @@ set(SRC intern/md5.c intern/noise.c intern/path_util.c - intern/pbvh.c intern/quadric.c intern/rand.c intern/rct.c @@ -101,7 +97,6 @@ set(SRC BLI_bitmap.h BLI_blenlib.h BLI_boxpack2d.h - BLI_bpath.h BLI_callbacks.h BLI_cpu.h BLI_dlrbTree.h @@ -137,7 +132,6 @@ set(SRC BLI_mempool.h BLI_noise.h BLI_path_util.h - BLI_pbvh.h BLI_quadric.h BLI_rand.h BLI_rect.h diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript index e53f622a5c4..2be06f7311d 100644 --- a/source/blender/blenlib/SConscript +++ b/source/blender/blenlib/SConscript @@ -1,11 +1,37 @@ -#!/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('intern/*.c') cflags='' -incs = '. ../makesdna ../blenkernel #/intern/guardedalloc #/intern/ghost ../editors/include ../gpu ../blenloader' -incs += ' ../windowmanager ../bmesh #/extern/glew/include' +# don't add ../blenkernel back! +incs = '. ../makesdna #/intern/guardedalloc #/intern/ghost' incs += ' ' + env['BF_FREETYPE_INC'] incs += ' ' + env['BF_ZLIB_INC'] diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index c4094920c2a..7d2fc38272d 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -39,7 +39,7 @@ #include "BLI_mempool.h" #include "BLI_ghash.h" -#include "BLO_sys_types.h" // for intptr_t support +#include "MEM_sys_types.h" /* for intptr_t support */ /***/ unsigned int hashsizes[] = { @@ -312,17 +312,25 @@ int BLI_ghashutil_intcmp(const void *a, const void *b) return (a < b) ? -1 : 1; } +/** + * This function implements the widely used "djb" hash apparently posted + * by Daniel Bernstein to comp.lang.c some time ago. The 32 bit + * unsigned hash value starts at 5381 and for each byte 'c' in the + * string, is updated: <literal>hash = hash * 33 + c</literal>. This + * function uses the signed value of each byte. + * + * note: this is the same hash method that glib 2.34.0 uses. + */ unsigned int BLI_ghashutil_strhash(const void *ptr) { - const char *s = ptr; - unsigned int i = 0; - unsigned char c; + const signed char *p; + unsigned int h = 5381; - while ((c = *s++)) { - i = i * 37 + c; + for (p = ptr; *p != '\0'; p++) { + h = (h << 5) + h + *p; } - return i; + return h; } int BLI_ghashutil_strcmp(const void *a, const void *b) { @@ -376,4 +384,3 @@ void BLI_ghashutil_pairfree(void *ptr) { MEM_freeN((void *)ptr); } - diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 6cf167b8823..55f67cedfc6 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -1237,7 +1237,7 @@ static void dfs_find_nearest_begin(BVHNearestData *data, BVHNode *node) #define DEFAULT_FIND_NEAREST_HEAP_SIZE 1024 -#define NodeDistance_priority(a, b) ( (a).dist < (b).dist) +#define NodeDistance_priority(a, b) ((a).dist < (b).dist) static void NodeDistance_push_heap(NodeDistance *heap, int heap_size) PUSH_HEAP_BODY(NodeDistance, NodeDistance_priority, heap, heap_size) diff --git a/source/blender/blenlib/intern/endian_switch.c b/source/blender/blenlib/intern/endian_switch.c index b9b18136863..e3ed88b6f8d 100644 --- a/source/blender/blenlib/intern/endian_switch.c +++ b/source/blender/blenlib/intern/endian_switch.c @@ -24,7 +24,7 @@ * \ingroup bli */ -#include "BLO_sys_types.h" +#include "MEM_sys_types.h" #include "BLI_utildefines.h" #include "BLI_endian_switch.h" diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index 883cdfde426..0f42fca9f12 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -63,7 +63,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" -#include "BLO_sys_types.h" // for intptr_t support +#include "MEM_sys_types.h" // for intptr_t support /* gzip the file in from and write it to "to". diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index 0a87316aa81..353b73a6403 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -52,8 +52,6 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -#include "BKE_font.h" - #include "DNA_vfont_types.h" #include "DNA_packedFile_types.h" #include "DNA_curve_types.h" diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index 9f6f409c473..c60a9ae6bfc 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -345,7 +345,7 @@ void *BLI_rfindlink(const ListBase *listbase, int number) return link; } -int BLI_findindex(const ListBase *listbase, void *vlink) +int BLI_findindex(const ListBase *listbase, const void *vlink) { Link *link = NULL; int number = 0; diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 74abd7e8c7e..931025606db 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -180,7 +180,7 @@ float dist_to_line_v2(const float p[2], const float l1[2], const float l2[2]) /* distance p to line-piece v1-v2 */ float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2]) { - float labda, rc[2], pt[2], len; + float lambda, rc[2], pt[2], len; rc[0] = l2[0] - l1[0]; rc[1] = l2[1] - l1[1]; @@ -191,18 +191,18 @@ float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const return (rc[0] * rc[0] + rc[1] * rc[1]); } - labda = (rc[0] * (p[0] - l1[0]) + rc[1] * (p[1] - l1[1])) / len; - if (labda <= 0.0f) { + lambda = (rc[0] * (p[0] - l1[0]) + rc[1] * (p[1] - l1[1])) / len; + if (lambda <= 0.0f) { pt[0] = l1[0]; pt[1] = l1[1]; } - else if (labda >= 1.0f) { + else if (lambda >= 1.0f) { pt[0] = l2[0]; pt[1] = l2[1]; } else { - pt[0] = labda * rc[0] + l1[0]; - pt[1] = labda * rc[1] + l1[1]; + pt[0] = lambda * rc[0] + l1[0]; + pt[1] = lambda * rc[1] + l1[1]; } rc[0] = pt[0] - p[0]; @@ -301,17 +301,17 @@ float dist_to_line_segment_v3(const float v1[3], const float v2[3], const float /* intersect Line-Line, shorts */ int isect_line_line_v2_int(const int v1[2], const int v2[2], const int v3[2], const int v4[2]) { - float div, labda, mu; + float div, lambda, mu; div = (float)((v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0])); if (div == 0.0f) return ISECT_LINE_LINE_COLINEAR; - labda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; + lambda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; mu = ((float)(v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div; - if (labda >= 0.0f && labda <= 1.0f && mu >= 0.0f && mu <= 1.0f) { - if (labda == 0.0f || labda == 1.0f || mu == 0.0f || mu == 1.0f) return ISECT_LINE_LINE_EXACT; + if (lambda >= 0.0f && lambda <= 1.0f && mu >= 0.0f && mu <= 1.0f) { + if (lambda == 0.0f || lambda == 1.0f || mu == 0.0f || mu == 1.0f) return ISECT_LINE_LINE_EXACT; return ISECT_LINE_LINE_CROSS; } return ISECT_LINE_LINE_NONE; @@ -335,17 +335,17 @@ int isect_line_line_v2_point(const float v1[2], const float v2[2], const float v /* intersect Line-Line, floats */ int isect_line_line_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]) { - float div, labda, mu; + float div, lambda, mu; div = (v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]); if (div == 0.0f) return ISECT_LINE_LINE_COLINEAR; - labda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; + lambda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; mu = ((float)(v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div; - if (labda >= 0.0f && labda <= 1.0f && mu >= 0.0f && mu <= 1.0f) { - if (labda == 0.0f || labda == 1.0f || mu == 0.0f || mu == 1.0f) return ISECT_LINE_LINE_EXACT; + if (lambda >= 0.0f && lambda <= 1.0f && mu >= 0.0f && mu <= 1.0f) { + if (lambda == 0.0f || lambda == 1.0f || mu == 0.0f || mu == 1.0f) return ISECT_LINE_LINE_EXACT; return ISECT_LINE_LINE_CROSS; } return ISECT_LINE_LINE_NONE; @@ -2435,7 +2435,7 @@ void interp_barycentric_tri_v3(float data[3][3], float u, float v, float res[3]) /***************************** View & Projection *****************************/ -void orthographic_m4(float matrix[][4], const float left, const float right, const float bottom, const float top, +void orthographic_m4(float matrix[4][4], const float left, const float right, const float bottom, const float top, const float nearClip, const float farClip) { float Xdelta, Ydelta, Zdelta; @@ -2481,7 +2481,7 @@ void perspective_m4(float mat[4][4], const float left, const float right, const } /* translate a matrix created by orthographic_m4 or perspective_m4 in XY coords (used to jitter the view) */ -void window_translate_m4(float winmat[][4], float perspmat[][4], const float x, const float y) +void window_translate_m4(float winmat[4][4], float perspmat[4][4], const float x, const float y) { if (winmat[2][3] == -1.0f) { /* in the case of a win-matrix, this means perspective always */ @@ -2509,7 +2509,7 @@ void window_translate_m4(float winmat[][4], float perspmat[][4], const float x, } } -static void i_multmatrix(float icand[][4], float Vm[][4]) +static void i_multmatrix(float icand[4][4], float Vm[4][4]) { int row, col; float temp[4][4]; @@ -2523,7 +2523,7 @@ static void i_multmatrix(float icand[][4], float Vm[][4]) copy_m4_m4(Vm, temp); } -void polarview_m4(float Vm[][4], float dist, float azimuth, float incidence, float twist) +void polarview_m4(float Vm[4][4], float dist, float azimuth, float incidence, float twist) { unit_m4(Vm); @@ -2534,7 +2534,7 @@ void polarview_m4(float Vm[][4], float dist, float azimuth, float incidence, flo rotate_m4(Vm, 'Z', -azimuth); } -void lookat_m4(float mat[][4], float vx, float vy, float vz, float px, float py, float pz, float twist) +void lookat_m4(float mat[4][4], float vx, float vy, float vz, float px, float py, float pz, float twist) { float sine, cosine, hyp, hyp1, dx, dy, dz; float mat1[4][4] = MAT4_UNITY; diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 38214f9c6b0..3a294769eb3 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -43,7 +43,7 @@ void zero_m4(float m[4][4]) memset(m, 0, 4 * 4 * sizeof(float)); } -void unit_m3(float m[][3]) +void unit_m3(float m[3][3]) { m[0][0] = m[1][1] = m[2][2] = 1.0; m[0][1] = m[0][2] = 0.0; @@ -51,7 +51,7 @@ void unit_m3(float m[][3]) m[2][0] = m[2][1] = 0.0; } -void unit_m4(float m[][4]) +void unit_m4(float m[4][4]) { m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0; m[0][1] = m[0][2] = m[0][3] = 0.0; @@ -60,18 +60,18 @@ void unit_m4(float m[][4]) m[3][0] = m[3][1] = m[3][2] = 0.0; } -void copy_m3_m3(float m1[][3], float m2[][3]) +void copy_m3_m3(float m1[3][3], float m2[3][3]) { /* destination comes first: */ memcpy(&m1[0], &m2[0], 9 * sizeof(float)); } -void copy_m4_m4(float m1[][4], float m2[][4]) +void copy_m4_m4(float m1[4][4], float m2[4][4]) { memcpy(m1, m2, 4 * 4 * sizeof(float)); } -void copy_m3_m4(float m1[][3], float m2[][4]) +void copy_m3_m4(float m1[3][3], float m2[4][4]) { m1[0][0] = m2[0][0]; m1[0][1] = m2[0][1]; @@ -86,7 +86,7 @@ void copy_m3_m4(float m1[][3], float m2[][4]) m1[2][2] = m2[2][2]; } -void copy_m4_m3(float m1[][4], float m2[][3]) /* no clear */ +void copy_m4_m3(float m1[4][4], float m2[3][3]) /* no clear */ { m1[0][0] = m2[0][0]; m1[0][1] = m2[0][1]; @@ -112,7 +112,7 @@ void copy_m4_m3(float m1[][4], float m2[][3]) /* no clear */ } -void swap_m3m3(float m1[][3], float m2[][3]) +void swap_m3m3(float m1[3][3], float m2[3][3]) { float t; int i, j; @@ -126,7 +126,7 @@ void swap_m3m3(float m1[][3], float m2[][3]) } } -void swap_m4m4(float m1[][4], float m2[][4]) +void swap_m4m4(float m1[4][4], float m2[4][4]) { float t; int i, j; @@ -142,7 +142,7 @@ void swap_m4m4(float m1[][4], float m2[][4]) /******************************** Arithmetic *********************************/ -void mult_m4_m4m4(float m1[][4], float m3_[][4], float m2_[][4]) +void mult_m4_m4m4(float m1[4][4], float m3_[4][4], float m2_[4][4]) { float m2[4][4], m3[4][4]; @@ -173,7 +173,7 @@ void mult_m4_m4m4(float m1[][4], float m3_[][4], float m2_[][4]) } -void mul_m3_m3m3(float m1[][3], float m3_[][3], float m2_[][3]) +void mul_m3_m3m3(float m1[3][3], float m3_[3][3], float m2_[3][3]) { float m2[3][3], m3[3][3]; @@ -195,7 +195,7 @@ void mul_m3_m3m3(float m1[][3], float m3_[][3], float m2_[][3]) m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2]; } -void mul_m4_m4m3(float m1[][4], float m3_[][4], float m2_[][3]) +void mul_m4_m4m3(float m1[4][4], float m3_[4][4], float m2_[3][3]) { float m2[3][3], m3[4][4]; @@ -215,7 +215,7 @@ void mul_m4_m4m3(float m1[][4], float m3_[][4], float m2_[][3]) } /* m1 = m2 * m3, ignore the elements on the 4th row/column of m3 */ -void mult_m3_m3m4(float m1[][3], float m3_[][4], float m2_[][3]) +void mult_m3_m3m4(float m1[3][3], float m3_[4][4], float m2_[3][3]) { float m2[3][3], m3[4][4]; @@ -237,7 +237,7 @@ void mult_m3_m3m4(float m1[][3], float m3_[][4], float m2_[][3]) m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2]; } -void mul_m4_m3m4(float m1[][4], float m3_[][3], float m2_[][4]) +void mul_m4_m3m4(float m1[4][4], float m3_[3][3], float m2_[4][4]) { float m2[4][4], m3[3][3]; @@ -256,10 +256,10 @@ void mul_m4_m3m4(float m1[][4], float m3_[][3], float m2_[][4]) m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2]; } -void mul_serie_m3(float answ[][3], - float m1[][3], float m2[][3], float m3[][3], - float m4[][3], float m5[][3], float m6[][3], - float m7[][3], float m8[][3]) +void mul_serie_m3(float answ[3][3], + float m1[3][3], float m2[3][3], float m3[3][3], + float m4[3][3], float m5[3][3], float m6[3][3], + float m7[3][3], float m8[3][3]) { float temp[3][3]; @@ -289,10 +289,10 @@ void mul_serie_m3(float answ[][3], } } -void mul_serie_m4(float answ[][4], float m1[][4], - float m2[][4], float m3[][4], float m4[][4], - float m5[][4], float m6[][4], float m7[][4], - float m8[][4]) +void mul_serie_m4(float answ[4][4], float m1[4][4], + float m2[4][4], float m3[4][4], float m4[4][4], + float m5[4][4], float m6[4][4], float m7[4][4], + float m8[4][4]) { float temp[4][4]; @@ -322,7 +322,7 @@ void mul_serie_m4(float answ[][4], float m1[][4], } } -void mul_m4_v3(float mat[][4], float vec[3]) +void mul_m4_v3(float mat[4][4], float vec[3]) { float x, y; @@ -333,7 +333,7 @@ void mul_m4_v3(float mat[][4], float vec[3]) vec[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2]; } -void mul_v3_m4v3(float in[3], float mat[][4], const float vec[3]) +void mul_v3_m4v3(float in[3], float mat[4][4], const float vec[3]) { float x, y; @@ -345,7 +345,7 @@ void mul_v3_m4v3(float in[3], float mat[][4], const float vec[3]) } /* same as mul_m4_v3() but doesnt apply translation component */ -void mul_mat3_m4_v3(float mat[][4], float vec[3]) +void mul_mat3_m4_v3(float mat[4][4], float vec[3]) { float x, y; @@ -356,7 +356,7 @@ void mul_mat3_m4_v3(float mat[][4], float vec[3]) vec[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2]; } -void mul_project_m4_v3(float mat[][4], float vec[3]) +void mul_project_m4_v3(float mat[4][4], float vec[3]) { const float w = vec[0] * mat[0][3] + vec[1] * mat[1][3] + vec[2] * mat[2][3] + mat[3][3]; mul_m4_v3(mat, vec); @@ -419,7 +419,7 @@ void mul_m3_v3(float M[3][3], float r[3]) copy_v3_v3(r, tmp); } -void mul_transposed_m3_v3(float mat[][3], float vec[3]) +void mul_transposed_m3_v3(float mat[3][3], float vec[3]) { float x, y; @@ -457,7 +457,7 @@ void mul_mat3_m4_fl(float m[4][4], float f) m[i][j] *= f; } -void mul_m3_v3_double(float mat[][3], double vec[3]) +void mul_m3_v3_double(float mat[3][3], double vec[3]) { double x, y; @@ -468,7 +468,7 @@ void mul_m3_v3_double(float mat[][3], double vec[3]) vec[2] = x * (double)mat[0][2] + y * (double)mat[1][2] + (double)mat[2][2] * vec[2]; } -void add_m3_m3m3(float m1[][3], float m2[][3], float m3[][3]) +void add_m3_m3m3(float m1[3][3], float m2[3][3], float m3[3][3]) { int i, j; @@ -477,7 +477,7 @@ void add_m3_m3m3(float m1[][3], float m2[][3], float m3[][3]) m1[i][j] = m2[i][j] + m3[i][j]; } -void add_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) +void add_m4_m4m4(float m1[4][4], float m2[4][4], float m3[4][4]) { int i, j; @@ -486,7 +486,7 @@ void add_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) m1[i][j] = m2[i][j] + m3[i][j]; } -void sub_m3_m3m3(float m1[][3], float m2[][3], float m3[][3]) +void sub_m3_m3m3(float m1[3][3], float m2[3][3], float m3[3][3]) { int i, j; @@ -495,7 +495,7 @@ void sub_m3_m3m3(float m1[][3], float m2[][3], float m3[][3]) m1[i][j] = m2[i][j] - m3[i][j]; } -void sub_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) +void sub_m4_m4m4(float m1[4][4], float m2[4][4], float m3[4][4]) { int i, j; @@ -504,8 +504,7 @@ void sub_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) m1[i][j] = m2[i][j] - m3[i][j]; } -/* why not make this a standard part of the API? */ -static float determinant_m3_local(float m[3][3]) +float determinant_m3_array(float m[3][3]) { return (m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]) - m[1][0] * (m[0][1] * m[2][2] - m[0][2] * m[2][1]) + @@ -534,7 +533,7 @@ int invert_m3_m3_ex(float m1[3][3], float m2[3][3], const float epsilon) adjoint_m3_m3(m1, m2); /* then determinant old matrix! */ - det = determinant_m3_local(m2); + det = determinant_m3_array(m2); success = (fabsf(det) > epsilon); @@ -569,7 +568,7 @@ int invert_m3_m3(float m1[3][3], float m2[3][3]) adjoint_m3_m3(m1, m2); /* then determinant old matrix! */ - det = determinant_m3_local(m2); + det = determinant_m3_array(m2); success = (det != 0.0f); @@ -613,6 +612,8 @@ int invert_m4_m4(float inverse[4][4], float mat[4][4]) float max; int maxj; + BLI_assert(inverse != mat); + /* Set inverse to identity */ for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) @@ -665,7 +666,7 @@ int invert_m4_m4(float inverse[4][4], float mat[4][4]) /****************************** Linear Algebra *******************************/ -void transpose_m3(float mat[][3]) +void transpose_m3(float mat[3][3]) { float t; @@ -680,7 +681,7 @@ void transpose_m3(float mat[][3]) mat[2][1] = t; } -void transpose_m4(float mat[][4]) +void transpose_m4(float mat[4][4]) { float t; @@ -706,7 +707,7 @@ void transpose_m4(float mat[][4]) mat[3][2] = t; } -void orthogonalize_m3(float mat[][3], int axis) +void orthogonalize_m3(float mat[3][3], int axis) { float size[3]; mat3_to_size(size, mat); @@ -784,7 +785,7 @@ void orthogonalize_m3(float mat[][3], int axis) mul_v3_fl(mat[2], size[2]); } -void orthogonalize_m4(float mat[][4], int axis) +void orthogonalize_m4(float mat[4][4], int axis) { float size[3]; mat4_to_size(size, mat); @@ -863,7 +864,7 @@ void orthogonalize_m4(float mat[][4], int axis) mul_v3_fl(mat[2], size[2]); } -int is_orthogonal_m3(float m[][3]) +int is_orthogonal_m3(float m[3][3]) { int i, j; @@ -877,7 +878,7 @@ int is_orthogonal_m3(float m[][3]) return 1; } -int is_orthogonal_m4(float m[][4]) +int is_orthogonal_m4(float m[4][4]) { int i, j; @@ -892,7 +893,7 @@ int is_orthogonal_m4(float m[][4]) return 1; } -int is_orthonormal_m3(float m[][3]) +int is_orthonormal_m3(float m[3][3]) { if (is_orthogonal_m3(m)) { int i; @@ -907,7 +908,7 @@ int is_orthonormal_m3(float m[][3]) return 0; } -int is_orthonormal_m4(float m[][4]) +int is_orthonormal_m4(float m[4][4]) { if (is_orthogonal_m4(m)) { int i; @@ -922,7 +923,7 @@ int is_orthonormal_m4(float m[][4]) return 0; } -int is_uniform_scaled_m3(float m[][3]) +int is_uniform_scaled_m3(float m[3][3]) { const float eps = 1e-7; float t[3][3]; @@ -951,21 +952,21 @@ int is_uniform_scaled_m3(float m[][3]) return 0; } -void normalize_m3(float mat[][3]) +void normalize_m3(float mat[3][3]) { normalize_v3(mat[0]); normalize_v3(mat[1]); normalize_v3(mat[2]); } -void normalize_m3_m3(float rmat[][3], float mat[][3]) +void normalize_m3_m3(float rmat[3][3], float mat[3][3]) { normalize_v3_v3(rmat[0], mat[0]); normalize_v3_v3(rmat[1], mat[1]); normalize_v3_v3(rmat[2], mat[2]); } -void normalize_m4(float mat[][4]) +void normalize_m4(float mat[4][4]) { float len; @@ -977,7 +978,7 @@ void normalize_m4(float mat[][4]) if (len != 0.0f) mat[2][3] /= len; } -void normalize_m4_m4(float rmat[][4], float mat[][4]) +void normalize_m4_m4(float rmat[4][4], float mat[4][4]) { float len; @@ -998,7 +999,7 @@ void adjoint_m2_m2(float m1[][2], float m[][2]) m1[1][1] = m[0][0]; } -void adjoint_m3_m3(float m1[][3], float m[][3]) +void adjoint_m3_m3(float m1[3][3], float m[3][3]) { BLI_assert(m1 != m); m1[0][0] = m[1][1] * m[2][2] - m[1][2] * m[2][1]; @@ -1014,7 +1015,7 @@ void adjoint_m3_m3(float m1[][3], float m[][3]) m1[2][2] = m[0][0] * m[1][1] - m[0][1] * m[1][0]; } -void adjoint_m4_m4(float out[][4], float in[][4]) /* out = ADJ(in) */ +void adjoint_m4_m4(float out[4][4], float in[4][4]) /* out = ADJ(in) */ { float a1, a2, a3, a4, b1, b2, b3, b4; float c1, c2, c3, c4, d1, d2, d3, d4; @@ -1080,7 +1081,7 @@ float determinant_m3(float a1, float a2, float a3, return ans; } -float determinant_m4(float m[][4]) +float determinant_m4(float m[4][4]) { float ans; float a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4; @@ -1115,7 +1116,7 @@ float determinant_m4(float m[][4]) /****************************** Transformations ******************************/ -void size_to_mat3(float mat[][3], const float size[3]) +void size_to_mat3(float mat[3][3], const float size[3]) { mat[0][0] = size[0]; mat[0][1] = 0.0f; @@ -1128,7 +1129,7 @@ void size_to_mat3(float mat[][3], const float size[3]) mat[2][0] = 0.0f; } -void size_to_mat4(float mat[][4], const float size[3]) +void size_to_mat4(float mat[4][4], const float size[3]) { float tmat[3][3]; @@ -1137,14 +1138,14 @@ void size_to_mat4(float mat[][4], const float size[3]) copy_m4_m3(mat, tmat); } -void mat3_to_size(float size[3], float mat[][3]) +void mat3_to_size(float size[3], float mat[3][3]) { size[0] = len_v3(mat[0]); size[1] = len_v3(mat[1]); size[2] = len_v3(mat[2]); } -void mat4_to_size(float size[3], float mat[][4]) +void mat4_to_size(float size[3], float mat[4][4]) { size[0] = len_v3(mat[0]); size[1] = len_v3(mat[1]); @@ -1154,7 +1155,7 @@ void mat4_to_size(float size[3], float mat[][4]) /* this gets the average scale of a matrix, only use when your scaling * data that has no idea of scale axis, examples are bone-envelope-radius * and curve radius */ -float mat3_to_scale(float mat[][3]) +float mat3_to_scale(float mat[3][3]) { /* unit length vector */ float unit_vec[3] = {0.577350269189626f, 0.577350269189626f, 0.577350269189626f}; @@ -1162,7 +1163,7 @@ float mat3_to_scale(float mat[][3]) return len_v3(unit_vec); } -float mat4_to_scale(float mat[][4]) +float mat4_to_scale(float mat[4][4]) { float tmat[3][3]; copy_m3_m4(tmat, mat); @@ -1200,7 +1201,7 @@ void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]) size[2] = mat3[2][2]; } -void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[][4]) +void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4]) { float mat3[3][3]; /* wmat -> 3x3 */ @@ -1211,7 +1212,7 @@ void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wm copy_v3_v3(loc, wmat[3]); } -void scale_m3_fl(float m[][3], float scale) +void scale_m3_fl(float m[3][3], float scale) { m[0][0] = m[1][1] = m[2][2] = scale; m[0][1] = m[0][2] = 0.0; @@ -1219,7 +1220,7 @@ void scale_m3_fl(float m[][3], float scale) m[2][0] = m[2][1] = 0.0; } -void scale_m4_fl(float m[][4], float scale) +void scale_m4_fl(float m[4][4], float scale) { m[0][0] = m[1][1] = m[2][2] = scale; m[3][3] = 1.0; @@ -1229,14 +1230,14 @@ void scale_m4_fl(float m[][4], float scale) m[3][0] = m[3][1] = m[3][2] = 0.0; } -void translate_m4(float mat[][4], float Tx, float Ty, float Tz) +void translate_m4(float mat[4][4], float Tx, float Ty, float Tz) { mat[3][0] += (Tx * mat[0][0] + Ty * mat[1][0] + Tz * mat[2][0]); mat[3][1] += (Tx * mat[0][1] + Ty * mat[1][1] + Tz * mat[2][1]); mat[3][2] += (Tx * mat[0][2] + Ty * mat[1][2] + Tz * mat[2][2]); } -void rotate_m4(float mat[][4], const char axis, const float angle) +void rotate_m4(float mat[4][4], const char axis, const float angle) { int col; float temp[4] = {0.0f, 0.0f, 0.0f, 0.0f}; @@ -1276,7 +1277,7 @@ void rotate_m4(float mat[][4], const char axis, const float angle) } } -void blend_m3_m3m3(float out[][3], float dst[][3], float src[][3], const float srcweight) +void blend_m3_m3m3(float out[3][3], float dst[3][3], float src[3][3], const float srcweight) { float srot[3][3], drot[3][3]; float squat[4], dquat[4], fquat[4]; @@ -1299,7 +1300,7 @@ void blend_m3_m3m3(float out[][3], float dst[][3], float src[][3], const float s mul_m3_m3m3(out, rmat, smat); } -void blend_m4_m4m4(float out[][4], float dst[][4], float src[][4], const float srcweight) +void blend_m4_m4m4(float out[4][4], float dst[4][4], float src[4][4], const float srcweight) { float sloc[3], dloc[3], floc[3]; float srot[3][3], drot[3][3]; @@ -1321,14 +1322,14 @@ void blend_m4_m4m4(float out[][4], float dst[][4], float src[][4], const float s loc_quat_size_to_mat4(out, floc, fquat, fsize); } -int is_negative_m3(float mat[][3]) +int is_negative_m3(float mat[3][3]) { float vec[3]; cross_v3_v3v3(vec, mat[0], mat[1]); return (dot_v3v3(vec, mat[2]) < 0.0f); } -int is_negative_m4(float mat[][4]) +int is_negative_m4(float mat[4][4]) { float vec[3]; cross_v3_v3v3(vec, mat[0], mat[1]); @@ -1418,7 +1419,7 @@ void loc_axisangle_size_to_mat4(float mat[4][4], const float loc[3], const float /*********************************** Other ***********************************/ -void print_m3(const char *str, float m[][3]) +void print_m3(const char *str, float m[3][3]) { printf("%s\n", str); printf("%f %f %f\n", m[0][0], m[1][0], m[2][0]); @@ -1427,7 +1428,7 @@ void print_m3(const char *str, float m[][3]) printf("\n"); } -void print_m4(const char *str, float m[][4]) +void print_m4(const char *str, float m[4][4]) { printf("%s\n", str); printf("%f %f %f %f\n", m[0][0], m[1][0], m[2][0], m[3][0]); @@ -1901,3 +1902,16 @@ void pseudoinverse_m4_m4(float Ainv[4][4], float A[4][4], float epsilon) mul_serie_m4(Ainv, U, Wm, V, NULL, NULL, NULL, NULL, NULL); } + +void pseudoinverse_m3_m3(float Ainv[3][3], float A[3][3], float epsilon) +{ + /* try regular inverse when possible, otherwise fall back to slow svd */ + if (!invert_m3_m3(Ainv, A)) { + float tmp[4][4], tmpinv[4][4]; + + copy_m4_m3(tmp, A); + pseudoinverse_m4_m4(tmpinv, tmp, epsilon); + copy_m3_m4(Ainv, tmpinv); + } +} + diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index 3069542107e..71f146e8131 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -185,7 +185,7 @@ void mul_fac_qt_fl(float q[4], const float fac) } /* skip error check, currently only needed by mat3_to_quat_is_ok */ -static void quat_to_mat3_no_error(float m[][3], const float q[4]) +static void quat_to_mat3_no_error(float m[3][3], const float q[4]) { double q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc; @@ -217,7 +217,7 @@ static void quat_to_mat3_no_error(float m[][3], const float q[4]) m[2][2] = (float)(1.0 - qaa - qbb); } -void quat_to_mat3(float m[][3], const float q[4]) +void quat_to_mat3(float m[3][3], const float q[4]) { #ifdef DEBUG float f; @@ -229,7 +229,7 @@ void quat_to_mat3(float m[][3], const float q[4]) quat_to_mat3_no_error(m, q); } -void quat_to_mat4(float m[][4], const float q[4]) +void quat_to_mat4(float m[4][4], const float q[4]) { double q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc; @@ -273,7 +273,7 @@ void quat_to_mat4(float m[][4], const float q[4]) m[3][3] = 1.0f; } -void mat3_to_quat(float q[4], float wmat[][3]) +void mat3_to_quat(float q[4], float wmat[3][3]) { double tr, s; float mat[3][3]; @@ -325,7 +325,7 @@ void mat3_to_quat(float q[4], float wmat[][3]) normalize_qt(q); } -void mat4_to_quat(float q[4], float m[][4]) +void mat4_to_quat(float q[4], float m[4][4]) { float mat[3][3]; @@ -861,7 +861,7 @@ void single_axis_angle_to_mat3(float mat[3][3], const char axis, const float ang /* TODO: the following calls should probably be deprecated sometime */ /* TODO, replace use of this function with axis_angle_to_mat3() */ -void vec_rot_to_mat3(float mat[][3], const float vec[3], const float phi) +void vec_rot_to_mat3(float mat[3][3], const float vec[3], const float phi) { /* rotation of phi radials around vec */ float vx, vx2, vy, vy2, vz, vz2, co, si; @@ -889,7 +889,7 @@ void vec_rot_to_mat3(float mat[][3], const float vec[3], const float phi) /******************************** XYZ Eulers *********************************/ /* XYZ order */ -void eul_to_mat3(float mat[][3], const float eul[3]) +void eul_to_mat3(float mat[3][3], const float eul[3]) { double ci, cj, ch, si, sj, sh, cc, cs, sc, ss; @@ -917,7 +917,7 @@ void eul_to_mat3(float mat[][3], const float eul[3]) } /* XYZ order */ -void eul_to_mat4(float mat[][4], const float eul[3]) +void eul_to_mat4(float mat[4][4], const float eul[3]) { double ci, cj, ch, si, sj, sh, cc, cs, sc, ss; @@ -950,7 +950,7 @@ void eul_to_mat4(float mat[][4], const float eul[3]) /* returns two euler calculation methods, so we can pick the best */ /* XYZ order */ -static void mat3_to_eul2(float tmat[][3], float eul1[3], float eul2[3]) +static void mat3_to_eul2(float tmat[3][3], float eul1[3], float eul2[3]) { float cy, quat[4], mat[3][3]; @@ -982,7 +982,7 @@ static void mat3_to_eul2(float tmat[][3], float eul1[3], float eul2[3]) } /* XYZ order */ -void mat3_to_eul(float *eul, float tmat[][3]) +void mat3_to_eul(float *eul, float tmat[3][3]) { float eul1[3], eul2[3]; @@ -998,7 +998,7 @@ void mat3_to_eul(float *eul, float tmat[][3]) } /* XYZ order */ -void mat4_to_eul(float *eul, float tmat[][4]) +void mat4_to_eul(float *eul, float tmat[4][4]) { float tempMat[3][3]; @@ -1107,7 +1107,7 @@ void compatible_eul(float eul[3], const float oldrot[3]) /* uses 2 methods to retrieve eulers, and picks the closest */ /* XYZ order */ -void mat3_to_compatible_eul(float eul[3], const float oldrot[3], float mat[][3]) +void mat3_to_compatible_eul(float eul[3], const float oldrot[3], float mat[3][3]) { float eul1[3], eul2[3]; float d1, d2; @@ -1388,7 +1388,7 @@ void rotate_eulO(float beul[3], const short order, char axis, float ang) } /* the matrix is written to as 3 axis vectors */ -void eulO_to_gimbal_axis(float gmat[][3], const float eul[3], const short order) +void eulO_to_gimbal_axis(float gmat[3][3], const float eul[3], const short order) { const RotOrderInfo *R = GET_ROTATIONORDER_INFO(order); @@ -1447,7 +1447,7 @@ void eulO_to_gimbal_axis(float gmat[][3], const float eul[3], const short order) * - added support for scaling */ -void mat4_to_dquat(DualQuat *dq, float basemat[][4], float mat[][4]) +void mat4_to_dquat(DualQuat *dq, float basemat[4][4], float mat[4][4]) { float *t, *q, dscale[3], scale[3], basequat[4]; float baseRS[4][4], baseinv[4][4], baseR[4][4], baseRinv[4][4]; @@ -1502,7 +1502,7 @@ void mat4_to_dquat(DualQuat *dq, float basemat[][4], float mat[][4]) dq->trans[3] = 0.5f * ( t[0] * q[2] - t[1] * q[1] + t[2] * q[0]); } -void dquat_to_mat4(float mat[][4], DualQuat *dq) +void dquat_to_mat4(float mat[4][4], DualQuat *dq) { float len, *t, q0[4]; @@ -1583,7 +1583,7 @@ void normalize_dq(DualQuat *dq, float totweight) } } -void mul_v3m3_dq(float co[3], float mat[][3], DualQuat *dq) +void mul_v3m3_dq(float co[3], float mat[3][3], DualQuat *dq) { float M[3][3], t[3], scalemat[3][3], len2; float w = dq->quat[0], x = dq->quat[1], y = dq->quat[2], z = dq->quat[3]; diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index 3ede8636aa5..04b9d574347 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -544,7 +544,7 @@ MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const f n[2] += (v_prev[0] - v_curr[0]) * (v_prev[1] + v_curr[1]); } -MINLINE void star_m3_v3(float rmat[][3], float a[3]) +MINLINE void star_m3_v3(float rmat[3][3], float a[3]) { rmat[0][0] = rmat[1][1] = rmat[2][2] = 0.0; rmat[0][1] = -a[2]; diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index 444daf8817c..7c1842b10f2 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -47,7 +47,7 @@ #include "BLI_string_utf8.h" #include "BLI_utildefines.h" -#include "BKE_blender.h" /* BLENDER_VERSION */ +#include "../blenkernel/BKE_blender.h" /* BLENDER_VERSION, bad level include (no function call) */ #include "GHOST_Path-api.h" diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c index ee073d5d309..fb767f54e55 100644 --- a/source/blender/blenlib/intern/rct.c +++ b/source/blender/blenlib/intern/rct.c @@ -109,9 +109,9 @@ static int isect_segments_i(const int v1[2], const int v2[2], const int v3[2], c return 1; /* co-linear */ } else { - const double labda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; + const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div; - return (labda >= 0.0 && labda <= 1.0 && mu >= 0.0 && mu <= 1.0); + return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0); } } static int isect_segments_fl(const float v1[2], const float v2[2], const float v3[2], const float v4[2]) @@ -121,9 +121,9 @@ static int isect_segments_fl(const float v1[2], const float v2[2], const float v return 1; /* co-linear */ } else { - const double labda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; + const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div; - return (labda >= 0.0 && labda <= 1.0 && mu >= 0.0 && mu <= 1.0); + return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0); } } diff --git a/source/blender/blenlib/intern/winstuff.c b/source/blender/blenlib/intern/winstuff.c index 68d9d74cca4..65fb490b218 100644 --- a/source/blender/blenlib/intern/winstuff.c +++ b/source/blender/blenlib/intern/winstuff.c @@ -41,7 +41,7 @@ #include "BLI_path_util.h" #include "BLI_string.h" -#include "BKE_global.h" +#include "../blenkernel/BKE_global.h" /* G.background, bad level include (no function calls) */ #define WIN32_SKIP_HKEY_PROTECTION // need to use HKEY #include "BLI_winstuff.h" diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index 16a4d8d46ec..2ee5decdfac 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -240,13 +240,32 @@ struct ID *BLO_library_append_named_part_ex(const struct bContext *C, struct Mai void BLO_library_append_end(const struct bContext *C, struct Main *mainl, BlendHandle **bh, int idcode, short flag); +void BLO_library_append_all(struct Main *mainl, BlendHandle *bh); + void *BLO_library_read_struct(struct FileData *fd, struct BHead *bh, const char *blockname); BlendFileData *blo_read_blendafterruntime(int file, const char *name, int actualsize, struct ReportList *reports); - + /* internal function but we need to expose it */ void blo_lib_link_screen_restore(struct Main *newmain, struct bScreen *curscreen, struct Scene *curscene); +/** + * BLO_expand_main() loops over all ID data in Main to mark relations. + * Set (id->flag & LIB_NEED_EXPAND) to mark expanding. Flags get cleared after expanding. + * + * \param expand_doit_func() gets called for each ID block it finds + */ +void BLO_main_expander(void (*expand_doit_func)(void *, struct Main *, void *)); + +/** + * BLO_expand_main() loops over all ID data in Main to mark relations. + * Set (id->flag & LIB_NEED_EXPAND) to mark expanding. Flags get cleared after expanding. + * + * \param fdhandle usually filedata, or own handle + * \param mainvar the Main database to expand + */ +void BLO_expand_main(void *fdhandle, struct Main *mainvar); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenloader/SConscript b/source/blender/blenloader/SConscript index 49e8869637e..8950c4f7702 100644 --- a/source/blender/blenloader/SConscript +++ b/source/blender/blenloader/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('intern/*.c') diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index ffc188c081b..5c044a0a3bd 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2982,7 +2982,7 @@ static void direct_link_text(FileData *fd, Text *text) if (text->flags & TXT_ISEXT) { BKE_text_reload(text); } - else { + /* else { */ #endif link_list(fd, &text->lines); @@ -5174,6 +5174,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) win->drawdata = NULL; win->drawmethod = -1; win->drawfail = 0; + win->active = 0; } wm->timers.first = wm->timers.last = NULL; @@ -5245,27 +5246,6 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd) /* ****************** READ SCREEN ***************** */ -static void butspace_version_132(SpaceButs *buts) -{ - buts->v2d.tot.xmin = 0.0f; - buts->v2d.tot.ymin = 0.0f; - buts->v2d.tot.xmax = 1279.0f; - buts->v2d.tot.ymax = 228.0f; - - buts->v2d.min[0] = 256.0f; - buts->v2d.min[1] = 42.0f; - - buts->v2d.max[0] = 2048.0f; - buts->v2d.max[1] = 450.0f; - - buts->v2d.minzoom = 0.5f; - buts->v2d.maxzoom = 1.21f; - - buts->v2d.scroll = 0; - buts->v2d.keepzoom = 1; - buts->v2d.keeptot = 1; -} - /* note: file read without screens option G_FILE_NO_UI; * check lib pointers in call below */ static void lib_link_screen(FileData *fd, Main *main) @@ -5319,18 +5299,9 @@ static void lib_link_screen(FileData *fd, Main *main) else if (sl->spacetype == SPACE_BUTS) { SpaceButs *sbuts = (SpaceButs *)sl; sbuts->pinid = newlibadr(fd, sc->id.lib, sbuts->pinid); - sbuts->mainbo = sbuts->mainb; - sbuts->mainbuser = sbuts->mainb; - if (main->versionfile < 132) - butspace_version_132(sbuts); } else if (sl->spacetype == SPACE_FILE) { - SpaceFile *sfile = (SpaceFile *)sl; - sfile->files = NULL; - sfile->op = NULL; - sfile->layout = NULL; - sfile->folders_prev = NULL; - sfile->folders_next = NULL; + ; } else if (sl->spacetype == SPACE_ACTION) { SpaceAction *saction = (SpaceAction *)sl; @@ -5362,12 +5333,6 @@ static void lib_link_screen(FileData *fd, Main *main) */ sseq->gpd = newlibadr_us(fd, sc->id.lib, sseq->gpd); - sseq->scopes.reference_ibuf = NULL; - sseq->scopes.zebra_ibuf = NULL; - sseq->scopes.waveform_ibuf = NULL; - sseq->scopes.sep_waveform_ibuf = NULL; - sseq->scopes.vector_ibuf = NULL; - sseq->scopes.histogram_ibuf = NULL; } else if (sl->spacetype == SPACE_NLA) { SpaceNla *snla= (SpaceNla *)sl; @@ -5382,7 +5347,6 @@ static void lib_link_screen(FileData *fd, Main *main) SpaceText *st= (SpaceText *)sl; st->text= newlibadr(fd, sc->id.lib, st->text); - st->drawcache= NULL; } else if (sl->spacetype == SPACE_SCRIPT) { SpaceScript *scpt = (SpaceScript *)sl; @@ -5399,7 +5363,6 @@ static void lib_link_screen(FileData *fd, Main *main) TreeStoreElem *tselem; int a; - so->tree.first = so->tree.last= NULL; so->search_tse.id = newlibadr(fd, NULL, so->search_tse.id); if (so->treestore) { @@ -5413,7 +5376,6 @@ static void lib_link_screen(FileData *fd, Main *main) SpaceNode *snode = (SpaceNode *)sl; snode->id = newlibadr(fd, sc->id.lib, snode->id); - snode->edittree = NULL; if (ELEM3(snode->treetype, NTREE_COMPOSIT, NTREE_SHADER, NTREE_TEXTURE)) { /* internal data, a bit patchy */ @@ -5434,19 +5396,12 @@ static void lib_link_screen(FileData *fd, Main *main) else { snode->nodetree = newlibadr_us(fd, sc->id.lib, snode->nodetree); } - - snode->linkdrag.first = snode->linkdrag.last = NULL; } else if (sl->spacetype == SPACE_CLIP) { SpaceClip *sclip = (SpaceClip *)sl; sclip->clip = newlibadr_us(fd, sc->id.lib, sclip->clip); sclip->mask_info.mask = newlibadr_us(fd, sc->id.lib, sclip->mask_info.mask); - - sclip->scopes.track_search = NULL; - sclip->scopes.track_preview = NULL; - sclip->draw_context = NULL; - sclip->scopes.ok = 0; } else if (sl->spacetype == SPACE_LOGIC) { SpaceLogic *slogic = (SpaceLogic *)sl; @@ -5473,7 +5428,14 @@ static void *restore_pointer_by_name(Main *mainp, ID *id, int user) for (; idn; idn = idn->next) { if (idn->name[2] == name[0] && strcmp(idn->name+2, name) == 0) { if (idn->lib == id->lib) { - if (user && idn->us == 0) idn->us++; + if (user == 1) { + if (idn->us == 0) { + idn->us++; + } + } + else if (user == 2) { + id_us_ensure_real(idn); + } break; } } @@ -5639,7 +5601,7 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc else if (sl->spacetype == SPACE_IMAGE) { SpaceImage *sima = (SpaceImage *)sl; - sima->image = restore_pointer_by_name(newmain, (ID *)sima->image, 1); + sima->image = restore_pointer_by_name(newmain, (ID *)sima->image, 2); /* this will be freed, not worth attempting to find same scene, * since it gets initialized later */ @@ -5655,7 +5617,7 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc * so assume that here we're doing for undo only... */ sima->gpd = restore_pointer_by_name(newmain, (ID *)sima->gpd, 1); - sima->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sima->mask_info.mask, 1); + sima->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sima->mask_info.mask, 2); } else if (sl->spacetype == SPACE_SEQ) { SpaceSeq *sseq = (SpaceSeq *)sl; @@ -5730,8 +5692,8 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc else if (sl->spacetype == SPACE_CLIP) { SpaceClip *sclip = (SpaceClip *)sl; - sclip->clip = restore_pointer_by_name(newmain, (ID *)sclip->clip, 1); - sclip->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sclip->mask_info.mask, 1); + sclip->clip = restore_pointer_by_name(newmain, (ID *)sclip->clip, 2); + sclip->mask_info.mask = restore_pointer_by_name(newmain, (ID *)sclip->mask_info.mask, 2); sclip->scopes.ok = 0; } @@ -5788,6 +5750,7 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype) ar->type = NULL; ar->swap = 0; ar->do_draw = FALSE; + ar->regiontimer = NULL; memset(&ar->drawrct, 0, sizeof(ar->drawrct)); } @@ -5932,6 +5895,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc) soops->treestore->totelem = soops->treestore->usedelem; soops->storeflag |= SO_TREESTORE_CLEANUP; // at first draw } + soops->tree.first = soops->tree.last= NULL; } else if (sl->spacetype == SPACE_IMAGE) { SpaceImage *sima = (SpaceImage *)sl; @@ -5964,6 +5928,13 @@ static void direct_link_screen(FileData *fd, bScreen *sc) snode->gpd = newdataadr(fd, snode->gpd); direct_link_gpencil(fd, snode->gpd); } + snode->edittree = NULL; + snode->linkdrag.first = snode->linkdrag.last = NULL; + } + else if (sl->spacetype == SPACE_TEXT) { + SpaceText *st= (SpaceText *)sl; + + st->drawcache= NULL; } else if (sl->spacetype == SPACE_TIME) { SpaceTime *stime = (SpaceTime *)sl; @@ -5979,6 +5950,8 @@ static void direct_link_screen(FileData *fd, bScreen *sc) } } else if (sl->spacetype == SPACE_SEQ) { + SpaceSeq *sseq = (SpaceSeq *)sl; + /* grease pencil data is not a direct data and can't be linked from direct_link* * functions, it should be linked from lib_link* functions instead * @@ -5987,17 +5960,26 @@ static void direct_link_screen(FileData *fd, bScreen *sc) * simple return NULL here (sergey) */ #if 0 - SpaceSeq *sseq = (SpaceSeq *)sl; if (sseq->gpd) { sseq->gpd = newdataadr(fd, sseq->gpd); direct_link_gpencil(fd, sseq->gpd); } #endif + sseq->scopes.reference_ibuf = NULL; + sseq->scopes.zebra_ibuf = NULL; + sseq->scopes.waveform_ibuf = NULL; + sseq->scopes.sep_waveform_ibuf = NULL; + sseq->scopes.vector_ibuf = NULL; + sseq->scopes.histogram_ibuf = NULL; + } else if (sl->spacetype == SPACE_BUTS) { SpaceButs *sbuts = (SpaceButs *)sl; + sbuts->path= NULL; sbuts->texuser= NULL; + sbuts->mainbo = sbuts->mainb; + sbuts->mainbuser = sbuts->mainb; } else if (sl->spacetype == SPACE_CONSOLE) { SpaceConsole *sconsole = (SpaceConsole *)sl; @@ -6037,6 +6019,14 @@ static void direct_link_screen(FileData *fd, bScreen *sc) sfile->op = NULL; sfile->params = newdataadr(fd, sfile->params); } + else if (sl->spacetype == SPACE_CLIP) { + SpaceClip *sclip = (SpaceClip *)sl; + + sclip->scopes.track_search = NULL; + sclip->scopes.track_preview = NULL; + sclip->draw_context = NULL; + sclip->scopes.ok = 0; + } } sa->actionzones.first = sa->actionzones.last = NULL; @@ -6816,6 +6806,10 @@ static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead) bfd->globalf = fg->globalf; BLI_strncpy(bfd->filename, fg->filename, sizeof(bfd->filename)); + /* early 2.50 version patch - filename not in FileGlobal struct */ + if (fd->fileversion <= 250) + BLI_strncpy(bfd->filename, bfd->main->name, sizeof(bfd->main->name)); + if (G.fileflags & G_FILE_RECOVER) BLI_strncpy(fd->relabase, fg->filename, sizeof(fd->relabase)); @@ -8573,6 +8567,59 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 3)) { + bScreen *sc; + for (sc = main->screen.first; sc; sc = sc->id.next) { + ScrArea *sa; + for (sa = sc->areabase.first; sa; sa = sa->next) { + SpaceLink *sl; + for (sl = sa->spacedata.first; sl; sl = sl->next) { + switch (sl->spacetype) { + case SPACE_VIEW3D: + { + View3D *v3d = (View3D *)sl; + v3d->flag2 |= V3D_SHOW_GPENCIL; + break; + } + case SPACE_SEQ: + { + SpaceSeq *sseq = (SpaceSeq *)sl; + sseq->flag |= SEQ_SHOW_GPENCIL; + break; + } + case SPACE_IMAGE: + { + SpaceImage *sima = (SpaceImage *)sl; + sima->flag |= SI_SHOW_GPENCIL; + break; + } + case SPACE_NODE: + { + SpaceNode *snode = (SpaceNode *)sl; + snode->flag |= SNODE_SHOW_GPENCIL; + break; + } + case SPACE_CLIP: + { + SpaceClip *sclip = (SpaceClip *)sl; + sclip->flag |= SC_SHOW_GPENCIL; + break; + } + } + } + } + } + } + + { + Scene *scene; + + for (scene = main->scene.first; scene; scene = scene->id.next) { + if (scene->r.bake_rays_number == 0) + scene->r.bake_rays_number = 256; + } + } + /* default values in Freestyle settings */ { Scene *sce; @@ -8625,8 +8672,11 @@ static void lib_link_all(FileData *fd, Main *main) { oldnewmap_sort(fd); + /* No load UI for undo memfiles */ + if (fd->memfile == NULL) { lib_link_windowmanager(fd, main); lib_link_screen(fd, main); + } lib_link_scene(fd, main); lib_link_object(fd, main); lib_link_curve(fd, main); @@ -8900,9 +8950,10 @@ static ID *is_yet_read(FileData *fd, Main *mainvar, BHead *bhead) return BLI_findstring(which_libbase(mainvar, GS(idname)), idname, offsetof(ID, name)); } -static void expand_doit(FileData *fd, Main *mainvar, void *old) +static void expand_doit_library(void *fdhandle, Main *mainvar, void *old) { BHead *bhead; + FileData *fd = fdhandle; ID *id; bhead = find_bhead(fd, old); @@ -8969,7 +9020,7 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old) } } - +static void (*expand_doit)(void *, Main *, void *); // XXX deprecated - old animation system static void expand_ipo(FileData *fd, Main *mainvar, Ipo *ipo) @@ -9707,14 +9758,18 @@ static void expand_linestyle(FileData *fd, Main *mainvar, FreestyleLineStyle *li } } -static void expand_main(FileData *fd, Main *mainvar) +void BLO_main_expander(void (*expand_doit_func)(void *, Main *, void *)) +{ + expand_doit = expand_doit_func; +} + +void BLO_expand_main(void *fdhandle, Main *mainvar) { ListBase *lbarray[MAX_LIBARRAY]; + FileData *fd = fdhandle; ID *id; int a, do_it = TRUE; - if (fd == NULL) return; - while (do_it) { do_it = FALSE; @@ -9808,6 +9863,9 @@ static void expand_main(FileData *fd, Main *mainvar) } } + +/* ***************************** */ + static int object_in_any_scene(Main *mainvar, Object *ob) { Scene *sce; @@ -9956,6 +10014,28 @@ static ID *append_named_part(Main *mainl, FileData *fd, const char *idname, cons return (found) ? id : NULL; } +/* simple reader for copy/paste buffers */ +void BLO_library_append_all(Main *mainl, BlendHandle *bh) +{ + FileData *fd = (FileData *)(bh); + BHead *bhead; + ID *id = NULL; + + for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) { + if (bhead->code == ENDB) + break; + if (bhead->code == ID_OB) + read_libblock(fd, mainl, bhead, LIB_TESTIND, &id); + + if (id) { + /* sort by name in list */ + ListBase *lb = which_libbase(mainl, GS(id->name)); + id_sort_by_name(lb, id); + } + } +} + + static ID *append_named_part_ex(const bContext *C, Main *mainl, FileData *fd, const char *idname, const int idcode, const int flag) { ID *id= append_named_part(mainl, fd, idname, idcode); @@ -10060,8 +10140,11 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in Main *mainvar; Library *curlib; + /* expander now is callback function */ + BLO_main_expander(expand_doit_library); + /* make main consistent */ - expand_main(*fd, mainl); + BLO_expand_main(*fd, mainl); /* do this when expand found other libs */ read_libraries(*fd, (*fd)->mainlist); @@ -10156,6 +10239,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) ListBase *lbarray[MAX_LIBARRAY]; int a, do_it = TRUE; + /* expander now is callback function */ + BLO_main_expander(expand_doit_library); + while (do_it) { do_it = FALSE; @@ -10255,7 +10341,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) } } - expand_main(fd, mainptr); + BLO_expand_main(fd, mainptr); } } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index de661cac62f..8208cca981e 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -140,7 +140,7 @@ #include "BLI_bitmap.h" #include "BLI_blenlib.h" #include "BLI_linklist.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_utildefines.h" @@ -2528,6 +2528,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase) sc= sc->id.next; } + + /* flush helps the compression for undo-save */ + mywrite(wd, MYWRITE_FLUSH, 0); } static void write_libraries(WriteData *wd, Main *main) @@ -3091,7 +3094,7 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar) /* XXX still remap G */ fg.curscreen= screen; - fg.curscene= screen->scene; + fg.curscene= screen? screen->scene : NULL; fg.displaymode= G.displaymode; fg.winpos= G.winpos; @@ -3100,7 +3103,6 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar) fg.globalf= G.f; BLI_strncpy(fg.filename, mainvar->name, sizeof(fg.filename)); - sprintf(subvstr, "%4d", BLENDER_SUBVERSION); memcpy(fg.subvstr, subvstr, 4); @@ -3152,11 +3154,8 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil write_thumb(wd, thumb); write_global(wd, write_flags, mainvar); - /* no UI save in undo */ - if (current==NULL) { - write_windowmanagers(wd, &mainvar->wm); - write_screens (wd, &mainvar->screen); - } + write_windowmanagers(wd, &mainvar->wm); + write_screens (wd, &mainvar->screen); write_movieclips (wd, &mainvar->movieclip); write_masks (wd, &mainvar->mask); write_scenes (wd, &mainvar->scene); @@ -3242,13 +3241,12 @@ static int do_history(const char *name, ReportList *reports) /* return: success (1) */ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportList *reports, const int *thumb) { - char userfilename[FILE_MAX]; char tempname[FILE_MAX+1]; int file, err, write_user_block; /* path backup/restore */ void *path_list_backup = NULL; - const int path_list_flag = (BLI_BPATH_TRAVERSE_SKIP_LIBRARY | BLI_BPATH_TRAVERSE_SKIP_MULTIFILE); + const int path_list_flag = (BKE_BPATH_TRAVERSE_SKIP_LIBRARY | BKE_BPATH_TRAVERSE_SKIP_MULTIFILE); /* open temporary file, so we preserve the original in case we crash */ BLI_snprintf(tempname, sizeof(tempname), "%s@", filepath); @@ -3261,7 +3259,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL /* check if we need to backup and restore paths */ if (UNLIKELY((write_flags & G_FILE_RELATIVE_REMAP) && (G_FILE_SAVE_COPY & write_flags))) { - path_list_backup = BLI_bpath_list_backup(mainvar, path_list_flag); + path_list_backup = BKE_bpath_list_backup(mainvar, path_list_flag); } /* remapping of relative paths to new file location */ @@ -3284,24 +3282,23 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL * we should not have any relative paths, but if there * is somehow, an invalid or empty G.main->name it will * print an error, don't try make the absolute in this case. */ - BLI_bpath_absolute_convert(mainvar, G.main->name, NULL); + BKE_bpath_absolute_convert(mainvar, G.main->name, NULL); } } } - BLI_make_file_string(G.main->name, userfilename, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE); - write_user_block= (BLI_path_cmp(filepath, userfilename) == 0); + write_user_block= write_flags & G_FILE_USERPREFS; if (write_flags & G_FILE_RELATIVE_REMAP) - BLI_bpath_relative_convert(mainvar, filepath, NULL); /* note, making relative to something OTHER then G.main->name */ + BKE_bpath_relative_convert(mainvar, filepath, NULL); /* note, making relative to something OTHER then G.main->name */ /* actual file writing */ err= write_file_handle(mainvar, file, NULL, NULL, write_user_block, write_flags, thumb); close(file); if (UNLIKELY(path_list_backup)) { - BLI_bpath_list_restore(mainvar, path_list_flag, path_list_backup); - BLI_bpath_list_free(path_list_backup); + BKE_bpath_list_restore(mainvar, path_list_flag, path_list_backup); + BKE_bpath_list_free(path_list_backup); } if (err) { @@ -3366,3 +3363,4 @@ int BLO_write_file_mem(Main *mainvar, MemFile *compare, MemFile *current, int wr if (err==0) return 1; return 0; } + diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index 2a23658f5d0..c41b0703240 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -111,6 +111,8 @@ set(SRC tools/bmesh_decimate_dissolve.c tools/bmesh_decimate_unsubdivide.c tools/bmesh_decimate.h + tools/bmesh_edgesplit.c + tools/bmesh_edgesplit.h bmesh.h bmesh_class.h diff --git a/source/blender/bmesh/SConscript b/source/blender/bmesh/SConscript index 6765d57cb3e..722b7518630 100644 --- a/source/blender/bmesh/SConscript +++ b/source/blender/bmesh/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') cflags='' diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index bcd6780b675..a2613f46bf8 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -187,8 +187,9 @@ typedef struct BMesh { /*element pools*/ struct BLI_mempool *vpool, *epool, *lpool, *fpool; - /*operator api stuff*/ - struct BLI_mempool *toolflagpool; + /*operator api stuff (must be all NULL or all alloc'd)*/ + struct BLI_mempool *vtoolflagpool, *etoolflagpool, *ftoolflagpool; + int stackdepth; struct BMOperator *currentop; @@ -277,5 +278,6 @@ enum { * but should not error on valid cases */ #define BM_LOOP_RADIAL_MAX 10000 #define BM_NGON_MAX 100000 +#define BM_OMP_LIMIT 10000 #endif /* __BMESH_CLASS_H__ */ diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index 50f02b12dca..229a7caebfd 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -173,15 +173,17 @@ void BM_face_copy_shared(BMesh *bm, BMFace *f) */ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, const int create_flag) { - BMEdge **edges2 = NULL; - BLI_array_staticdeclare(edges2, BM_DEFAULT_NGON_STACK_SIZE); - BMVert **verts = NULL; - BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE); + BMEdge **edges2 = BLI_array_alloca_and_count(edges2, len); + BMVert **verts = BLI_array_alloca_and_count(verts, len + 1); + int e2_index = 0; + int v_index = 0; + BMFace *f = NULL; BMEdge *e; BMVert *v, *ev1, *ev2; int i, /* j, */ v1found, reverse; + /* this code is hideous, yeek. I'll have to think about ways of * cleaning it up. basically, it now combines the old BM_face_create_ngon * _and_ the old bmesh_mf functions, so its kindof smashed together @@ -207,14 +209,14 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i SWAP(BMVert *, ev1, ev2); } - BLI_array_append(verts, ev1); + verts[v_index++] = ev1; v = ev2; e = edges[0]; do { BMEdge *e2 = e; - BLI_array_append(verts, v); - BLI_array_append(edges2, e); + verts[v_index++] = v; + edges2[e2_index++] = e; /* we only flag the verts to check if they are in the face more then once */ BM_ELEM_API_FLAG_ENABLE(v, _FLAG_MV); @@ -289,9 +291,6 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i BM_ELEM_API_FLAG_DISABLE(edges2[i], _FLAG_MF); } - BLI_array_free(verts); - BLI_array_free(edges2); - return f; err: @@ -303,9 +302,6 @@ err: } } - BLI_array_free(verts); - BLI_array_free(edges2); - return NULL; } diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 14fab7abdc9..ea9ab364b84 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -78,9 +78,9 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example, cons copy_v3_v3(v->co, co); } - /* allocate flag */ - if (bm->toolflagpool) { - v->oflags = BLI_mempool_calloc(bm->toolflagpool); + /* allocate flags */ + if (bm->vtoolflagpool) { + v->oflags = BLI_mempool_calloc(bm->vtoolflagpool); } if (!(create_flag & BM_CREATE_SKIP_CD)) { @@ -132,9 +132,9 @@ BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, e->head.htype = BM_EDGE; - /* allocate flag */ - if (bm->toolflagpool) { - e->oflags = BLI_mempool_calloc(bm->toolflagpool); + /* allocate flags */ + if (bm->etoolflagpool) { + e->oflags = BLI_mempool_calloc(bm->etoolflagpool); } e->v1 = v1; @@ -211,10 +211,8 @@ static BMLoop *bm_face_boundary_add(BMesh *bm, BMFace *f, BMVert *startv, BMEdge BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short copyedges) { - BMVert **verts = NULL; - BMEdge **edges = NULL; - BLI_array_fixedstack_declare(verts, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__); - BLI_array_fixedstack_declare(edges, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__); + BMVert **verts = BLI_array_alloca(verts, f->len); + BMEdge **edges = BLI_array_alloca(edges, f->len); BMLoop *l_iter; BMLoop *l_first; BMLoop *l_copy; @@ -267,9 +265,6 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co l_copy = l_copy->next; } while ((l_iter = l_iter->next) != l_first); - BLI_array_fixedstack_free(verts); - BLI_array_fixedstack_free(edges); - return f_copy; } @@ -295,9 +290,9 @@ BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm, const eBMCreateFlag creat f->head.htype = BM_FACE; - /* allocate flag */ - if (bm->toolflagpool) { - f->oflags = BLI_mempool_calloc(bm->toolflagpool); + /* allocate flags */ + if (bm->ftoolflagpool) { + f->oflags = BLI_mempool_calloc(bm->ftoolflagpool); } if (!(create_flag & BM_CREATE_SKIP_CD)) { @@ -321,7 +316,7 @@ BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, int i, overlap; if (len == 0) { - /* just return NULL for no */ + /* just return NULL for now */ return NULL; } @@ -517,8 +512,8 @@ static void bm_kill_only_vert(BMesh *bm, BMVert *v) if (v->head.data) CustomData_bmesh_free_block(&bm->vdata, &v->head.data); - if (bm->toolflagpool) { - BLI_mempool_free(bm->toolflagpool, v->oflags); + if (bm->vtoolflagpool) { + BLI_mempool_free(bm->vtoolflagpool, v->oflags); } BLI_mempool_free(bm->vpool, v); } @@ -537,8 +532,8 @@ static void bm_kill_only_edge(BMesh *bm, BMEdge *e) if (e->head.data) CustomData_bmesh_free_block(&bm->edata, &e->head.data); - if (bm->toolflagpool) { - BLI_mempool_free(bm->toolflagpool, e->oflags); + if (bm->etoolflagpool) { + BLI_mempool_free(bm->etoolflagpool, e->oflags); } BLI_mempool_free(bm->epool, e); } @@ -560,8 +555,8 @@ static void bm_kill_only_face(BMesh *bm, BMFace *f) if (f->head.data) CustomData_bmesh_free_block(&bm->pdata, &f->head.data); - if (bm->toolflagpool) { - BLI_mempool_free(bm->toolflagpool, f->oflags); + if (bm->ftoolflagpool) { + BLI_mempool_free(bm->ftoolflagpool, f->oflags); } BLI_mempool_free(bm->fpool, f); } @@ -585,22 +580,19 @@ static void bm_kill_only_loop(BMesh *bm, BMLoop *l) */ void BM_face_edges_kill(BMesh *bm, BMFace *f) { - BMEdge **edges = NULL; - BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE); + BMEdge **edges = BLI_array_alloca_and_count(edges, f->len); BMLoop *l_iter; BMLoop *l_first; - int i; + int i = 0; l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { - BLI_array_append(edges, l_iter->e); + edges[i++] = l_iter->e; } while ((l_iter = l_iter->next) != l_first); for (i = 0; i < BLI_array_count(edges); i++) { BM_edge_kill(bm, edges[i]); } - - BLI_array_free(edges); } /** @@ -609,22 +601,19 @@ void BM_face_edges_kill(BMesh *bm, BMFace *f) */ void BM_face_verts_kill(BMesh *bm, BMFace *f) { - BMVert **verts = NULL; - BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE); + BMVert **verts = BLI_array_alloca_and_count(verts, f->len); BMLoop *l_iter; BMLoop *l_first; - int i; + int i = 0; l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { - BLI_array_append(verts, l_iter->v); + verts[i++] = l_iter->v; } while ((l_iter = l_iter->next) != l_first); for (i = 0; i < BLI_array_count(verts); i++) { BM_vert_kill(bm, verts[i]); } - - BLI_array_free(verts); } /** @@ -761,8 +750,7 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f const int len = f->len; const int do_disps = CustomData_has_layer(&bm->ldata, CD_MDISPS); BMLoop *l_iter, *oldprev, *oldnext; - BMEdge **edar = NULL; - BLI_array_fixedstack_declare(edar, BM_DEFAULT_NGON_STACK_SIZE, len, __func__); + BMEdge **edar = BLI_array_alloca(edar, len); int i, j, edok; for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next) { @@ -814,11 +802,11 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f } } } - /* rebuild radia */ + /* rebuild radial */ for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next) bmesh_radial_append(l_iter->e, l_iter); - /* validate radia */ + /* validate radial */ for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next) { BM_CHECK_ELEMENT(l_iter); BM_CHECK_ELEMENT(l_iter->e); @@ -826,8 +814,6 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f BM_CHECK_ELEMENT(l_iter->f); } - BLI_array_fixedstack_free(edar); - BM_CHECK_ELEMENT(f); return 1; @@ -1068,7 +1054,7 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del } while (l2 != l_iter); if (l2 != l_iter) { - /* I think this is correct */ + /* I think this is correct? */ if (l2->v != l_iter->v) { l2 = l2->next; } @@ -1080,7 +1066,7 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del BM_elem_attrs_copy(bm, bm, faces[0], newf); #ifdef USE_BMESH_HOLES - /* add hole */ + /* add holes */ BLI_movelisttolist(&newf->loops, &holes); #endif @@ -1396,7 +1382,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) /* add ne to tv's disk cycle */ bmesh_disk_edge_append(ne, tv); - /* verify disk cycle */ + /* verify disk cycles */ edok = bmesh_disk_validate(valence1, ov->e, ov); BMESH_ASSERT(edok != FALSE); edok = bmesh_disk_validate(valence2, tv->e, tv); @@ -1483,7 +1469,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) BMESH_ASSERT(l->v != l->next->v); BMESH_ASSERT(l->e != l->next->e); - /* verify loop cycle for kloop-> */ + /* verify loop cycle for kloop->f */ BM_CHECK_ELEMENT(l); BM_CHECK_ELEMENT(l->v); BM_CHECK_ELEMENT(l->e); @@ -1564,7 +1550,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou oe = bmesh_disk_edge_next(ke, kv); tv = bmesh_edge_other_vert_get(ke, kv); ov = bmesh_edge_other_vert_get(oe, kv); - halt = bmesh_verts_in_edge(kv, tv, oe); /* check for double edge */ + halt = bmesh_verts_in_edge(kv, tv, oe); /* check for double edges */ if (halt) { return NULL; @@ -1572,7 +1558,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou else { BMEdge *e_splice; - /* For verification later, count valence of ov and t */ + /* For verification later, count valence of ov and tv */ valence1 = bmesh_disk_count(ov); valence2 = bmesh_disk_count(tv); @@ -1614,8 +1600,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou radlen = bmesh_radial_length(ke->l); if (LIKELY(radlen)) { - BMLoop **loops = NULL; - BLI_array_fixedstack_declare(loops, BM_DEFAULT_NGON_STACK_SIZE, radlen, __func__); + BMLoop **loops = BLI_array_alloca(loops, radlen); killoop = ke->l; @@ -1628,7 +1613,6 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou bm->totloop--; BLI_mempool_free(bm->lpool, loops[i]); } - BLI_array_fixedstack_free(loops); } /* Validate radial cycle of oe */ @@ -1801,8 +1785,8 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e) bmesh_disk_edge_remove(f1loop->e, f1loop->e->v2); /* deallocate edge and its two loops as well as f2 */ - if (bm->toolflagpool) { - BLI_mempool_free(bm->toolflagpool, f1loop->e->oflags); + if (bm->etoolflagpool) { + BLI_mempool_free(bm->etoolflagpool, f1loop->e->oflags); } BLI_mempool_free(bm->epool, f1loop->e); bm->totedge--; @@ -1810,8 +1794,8 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e) bm->totloop--; BLI_mempool_free(bm->lpool, f2loop); bm->totloop--; - if (bm->toolflagpool) { - BLI_mempool_free(bm->toolflagpool, f2->oflags); + if (bm->ftoolflagpool) { + BLI_mempool_free(bm->ftoolflagpool, f2->oflags); } BLI_mempool_free(bm->fpool, f2); bm->totface--; @@ -1895,7 +1879,7 @@ int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target) int bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len) { BMEdge **stack = NULL; - BLI_array_declare(stack); + BLI_array_staticdeclare(stack, BM_DEFAULT_ITER_STACK_SIZE); BMVert **verts = NULL; GHash *visithash; BMIter eiter, liter; diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index caf9f3c70d5..df58b90bc03 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -172,11 +172,9 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source) BMLoop *l_iter; BMLoop *l_first; - void **blocks = NULL; - float (*cos)[3] = NULL, *w = NULL; - BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__); - BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__); - BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__); + void **blocks = BLI_array_alloca(blocks, source->len); + float (*cos)[3] = BLI_array_alloca(cos, source->len); + float *w = BLI_array_alloca(w, source->len); int i; BM_elem_attrs_copy(bm, bm, source, target); @@ -196,10 +194,6 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source) CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, source->len, l_iter->head.data); i++; } while ((l_iter = l_iter->next) != l_first); - - BLI_array_fixedstack_free(cos); - BLI_array_fixedstack_free(w); - BLI_array_fixedstack_free(blocks); } /** @@ -609,14 +603,12 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source, { BMLoop *l_iter; BMLoop *l_first; - void **blocks = NULL; - void **vblocks = NULL; - float (*cos)[3] = NULL, co[3], *w = NULL; + void **vblocks = BLI_array_alloca(vblocks, do_vertex ? source->len : 0); + void **blocks = BLI_array_alloca(blocks, source->len); + float (*cos)[3] = BLI_array_alloca(cos, source->len); + float *w = BLI_array_alloca(w, source->len); + float co[3]; float cent[3] = {0.0f, 0.0f, 0.0f}; - BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__); - BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__); - BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__); - BLI_array_fixedstack_declare(vblocks, BM_DEFAULT_NGON_STACK_SIZE, do_vertex ? source->len : 0, __func__); int i, ax, ay; BM_elem_attrs_copy(bm, bm, source, target->f); @@ -667,13 +659,8 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source, CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, source->len, target->head.data); if (do_vertex) { CustomData_bmesh_interp(&bm->vdata, vblocks, w, NULL, source->len, target->v->head.data); - BLI_array_fixedstack_free(vblocks); } - BLI_array_fixedstack_free(cos); - BLI_array_fixedstack_free(w); - BLI_array_fixedstack_free(blocks); - if (do_multires) { if (CustomData_has_layer(&bm->ldata, CD_MDISPS)) { bm_loop_interp_mdisps(bm, target, source); @@ -686,12 +673,10 @@ void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source) { BMLoop *l_iter; BMLoop *l_first; - void **blocks = NULL; - float (*cos)[3] = NULL, *w = NULL; + void **blocks = BLI_array_alloca(blocks, source->len); + float (*cos)[3] = BLI_array_alloca(cos, source->len); + float *w = BLI_array_alloca(w, source->len); float cent[3] = {0.0f, 0.0f, 0.0f}; - BLI_array_fixedstack_declare(cos, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__); - BLI_array_fixedstack_declare(w, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__); - BLI_array_fixedstack_declare(blocks, BM_DEFAULT_NGON_STACK_SIZE, source->len, __func__); int i; i = 0; @@ -718,10 +703,6 @@ void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source) /* interpolate */ interp_weights_poly_v3(w, cos, source->len, v->co); CustomData_bmesh_interp(&bm->vdata, blocks, w, NULL, source->len, v->head.data); - - BLI_array_fixedstack_free(cos); - BLI_array_fixedstack_free(w); - BLI_array_fixedstack_free(blocks); } static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data) diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index 9af65d7dd7e..b1ec4cde44b 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -44,8 +44,6 @@ static void recount_totsels(BMesh *bm) { - BMIter iter; - BMElem *ele; const char iter_types[3] = {BM_VERTS_OF_MESH, BM_EDGES_OF_MESH, BM_FACES_OF_MESH}; @@ -58,11 +56,16 @@ static void recount_totsels(BMesh *bm) tots[1] = &bm->totedgesel; tots[2] = &bm->totfacesel; +#pragma omp parallel for schedule(dynamic) for (i = 0; i < 3; i++) { - ele = BM_iter_new(&iter, bm, iter_types[i], NULL); - for ( ; ele; ele = BM_iter_step(&iter)) { - if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) *tots[i] += 1; + BMIter iter; + BMElem *ele; + int count = 0; + + BM_ITER_MESH (ele, &iter, bm, iter_types[i]) { + if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) count += 1; } + *tots[i] = count; } } @@ -161,34 +164,45 @@ void BM_mesh_deselect_flush(BMesh *bm) int ok; - BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) { - if (!(BM_elem_flag_test(e->v1, BM_ELEM_SELECT) && - BM_elem_flag_test(e->v2, BM_ELEM_SELECT) && - !BM_elem_flag_test(e, BM_ELEM_HIDDEN))) + /* we can use 2 sections here because the second loop isnt checking edge selection */ +#pragma omp parallel sections if (bm->totedge + bm->totface >= BM_OMP_LIMIT) + { +#pragma omp section { - BM_elem_flag_disable(e, BM_ELEM_SELECT); + BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) { + if (!(BM_elem_flag_test(e->v1, BM_ELEM_SELECT) && + BM_elem_flag_test(e->v2, BM_ELEM_SELECT) && + !BM_elem_flag_test(e, BM_ELEM_HIDDEN))) + { + BM_elem_flag_disable(e, BM_ELEM_SELECT); + } + } } - } - BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { - ok = TRUE; - if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { - l_iter = l_first = BM_FACE_FIRST_LOOP(f); - do { - if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) { +#pragma omp section + { + BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { + ok = TRUE; + if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) { + ok = FALSE; + break; + } + } while ((l_iter = l_iter->next) != l_first); + } + else { ok = FALSE; - break; } - } while ((l_iter = l_iter->next) != l_first); - } - else { - ok = FALSE; - } - if (ok == FALSE) { - BM_elem_flag_disable(f, BM_ELEM_SELECT); + if (ok == FALSE) { + BM_elem_flag_disable(f, BM_ELEM_SELECT); + } + } } } + /* end sections */ /* Remove any deselected elements from the BMEditSelection */ BM_select_history_validate(bm); @@ -212,32 +226,42 @@ void BM_mesh_select_flush(BMesh *bm) int ok; - BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) && - BM_elem_flag_test(e->v2, BM_ELEM_SELECT) && - !BM_elem_flag_test(e, BM_ELEM_HIDDEN)) + /* we can use 2 sections here because the second loop isnt checking edge selection */ +#pragma omp parallel sections if (bm->totedge + bm->totface >= BM_OMP_LIMIT) + { +#pragma omp section { - BM_elem_flag_enable(e, BM_ELEM_SELECT); + BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) && + BM_elem_flag_test(e->v2, BM_ELEM_SELECT) && + !BM_elem_flag_test(e, BM_ELEM_HIDDEN)) + { + BM_elem_flag_enable(e, BM_ELEM_SELECT); + } + } } - } - BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { - ok = TRUE; - if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { - l_iter = l_first = BM_FACE_FIRST_LOOP(f); - do { - if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) { +#pragma omp section + { + BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { + ok = TRUE; + if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) { + ok = FALSE; + break; + } + } while ((l_iter = l_iter->next) != l_first); + } + else { ok = FALSE; - break; } - } while ((l_iter = l_iter->next) != l_first); - } - else { - ok = FALSE; - } - if (ok) { - BM_elem_flag_enable(f, BM_ELEM_SELECT); + if (ok) { + BM_elem_flag_enable(f, BM_ELEM_SELECT); + } + } } } @@ -810,8 +834,6 @@ void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hfl const char flag_types[3] = {BM_VERT, BM_EDGE, BM_FACE}; - BMIter iter; - BMElem *ele; int i; if (hflag & BM_ELEM_SELECT) { @@ -825,16 +847,25 @@ void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hfl { /* fast path for deselect all, avoid topology loops * since we know all will be de-selected anyway. */ + +#pragma omp parallel for schedule(dynamic) if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT) for (i = 0; i < 3; i++) { + BMIter iter; + BMElem *ele; + ele = BM_iter_new(&iter, bm, iter_types[i], NULL); for ( ; ele; ele = BM_iter_step(&iter)) { BM_elem_flag_disable(ele, BM_ELEM_SELECT); } } + bm->totvertsel = bm->totedgesel = bm->totfacesel = 0; } else { for (i = 0; i < 3; i++) { + BMIter iter; + BMElem *ele; + if (htype & flag_types[i]) { ele = BM_iter_new(&iter, bm, iter_types[i], NULL); for ( ; ele; ele = BM_iter_step(&iter)) { diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 590edc45d07..015c040dc95 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -63,40 +63,62 @@ static void bm_mempool_init(BMesh *bm, const BMAllocTemplate *allocsize) void BM_mesh_elem_toolflags_ensure(BMesh *bm) { - if (bm->toolflagpool == NULL) { - const int totflagpool_size = max_ii(512, bm->totvert + bm->totedge + bm->totface); - BLI_mempool *toolflagpool; - - BMIter iter; - BMElemF *ele; - const char iter_types[3] = {BM_VERTS_OF_MESH, - BM_EDGES_OF_MESH, - BM_FACES_OF_MESH}; - - int i; - - BLI_assert(bm->totflags == 0); - - /* allocate one flag pool that we don't get rid of. */ - toolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), totflagpool_size, 512, 0); - + if (bm->vtoolflagpool && bm->etoolflagpool && bm->ftoolflagpool) { + return; + } - for (i = 0; i < 3; i++) { - BM_ITER_MESH (ele, &iter, bm, iter_types[i]) { + bm->vtoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), max_ii(512, bm->totvert), 512, 0); + bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), max_ii(512, bm->totedge), 512, 0); + bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), max_ii(512, bm->totface), 512, 0); + +#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT) + { +#pragma omp section + { + BLI_mempool *toolflagpool = bm->vtoolflagpool; + BMIter iter; + BMElemF *ele; + BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) { + ele->oflags = BLI_mempool_calloc(toolflagpool); + } + } +#pragma omp section + { + BLI_mempool *toolflagpool = bm->etoolflagpool; + BMIter iter; + BMElemF *ele; + BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) { + ele->oflags = BLI_mempool_calloc(toolflagpool); + } + } +#pragma omp section + { + BLI_mempool *toolflagpool = bm->ftoolflagpool; + BMIter iter; + BMElemF *ele; + BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) { ele->oflags = BLI_mempool_calloc(toolflagpool); } } - - bm->toolflagpool = toolflagpool; - bm->totflags = 1; } + + + bm->totflags = 1; } void BM_mesh_elem_toolflags_clear(BMesh *bm) { - if (bm->toolflagpool) { - BLI_mempool_destroy(bm->toolflagpool); - bm->toolflagpool = NULL; + if (bm->vtoolflagpool) { + BLI_mempool_destroy(bm->vtoolflagpool); + bm->vtoolflagpool = NULL; + } + if (bm->etoolflagpool) { + BLI_mempool_destroy(bm->etoolflagpool); + bm->etoolflagpool = NULL; + } + if (bm->ftoolflagpool) { + BLI_mempool_destroy(bm->ftoolflagpool); + bm->ftoolflagpool = NULL; } } @@ -446,50 +468,58 @@ void BM_mesh_elem_index_ensure(BMesh *bm, const char hflag) BM_ELEM_INDEX_VALIDATE(bm, "Should Never Fail!", __func__); #endif - if (hflag & BM_VERT) { - if (bm->elem_index_dirty & BM_VERT) { - int index = 0; - BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) { - BM_elem_index_set(ele, index); /* set_ok */ - index++; +#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT) + { +#pragma omp section + { + if (hflag & BM_VERT) { + if (bm->elem_index_dirty & BM_VERT) { + int index; + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, index) { + BM_elem_index_set(ele, index); /* set_ok */ + } + BLI_assert(index == bm->totvert); + } + else { + // printf("%s: skipping vert index calc!\n", __func__); + } } - bm->elem_index_dirty &= ~BM_VERT; - BLI_assert(index == bm->totvert); } - else { - // printf("%s: skipping vert index calc!\n", __func__); - } - } - if (hflag & BM_EDGE) { - if (bm->elem_index_dirty & BM_EDGE) { - int index = 0; - BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) { - BM_elem_index_set(ele, index); /* set_ok */ - index++; +#pragma omp section + { + if (hflag & BM_EDGE) { + if (bm->elem_index_dirty & BM_EDGE) { + int index; + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, index) { + BM_elem_index_set(ele, index); /* set_ok */ + } + BLI_assert(index == bm->totedge); + } + else { + // printf("%s: skipping edge index calc!\n", __func__); + } } - bm->elem_index_dirty &= ~BM_EDGE; - BLI_assert(index == bm->totedge); - } - else { - // printf("%s: skipping edge index calc!\n", __func__); } - } - if (hflag & BM_FACE) { - if (bm->elem_index_dirty & BM_FACE) { - int index = 0; - BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) { - BM_elem_index_set(ele, index); /* set_ok */ - index++; +#pragma omp section + { + if (hflag & BM_FACE) { + if (bm->elem_index_dirty & BM_FACE) { + int index; + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, index) { + BM_elem_index_set(ele, index); /* set_ok */ + } + BLI_assert(index == bm->totface); + } + else { + // printf("%s: skipping face index calc!\n", __func__); + } } - bm->elem_index_dirty &= ~BM_FACE; - BLI_assert(index == bm->totface); - } - else { - // printf("%s: skipping face index calc!\n", __func__); } } + + bm->elem_index_dirty &= ~hflag; } diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index 89516061f91..9a99d5b96d1 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -152,14 +152,14 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v) return TRUE; } else if (keepedge == NULL && len == 2) { - /* collapse the verte */ + /* collapse the vertex */ e = BM_vert_collapse_faces(bm, v->e, v, 1.0, TRUE, TRUE); if (!e) { return FALSE; } - /* handle two-valenc */ + /* handle two-valence */ f = e->l->f; f2 = e->l->radial_next->f; @@ -205,12 +205,12 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v) return FALSE; } - /* get remaining two face */ + /* get remaining two faces */ f = e->l->f; f2 = e->l->radial_next->f; if (f != f2) { - /* join two remaining face */ + /* join two remaining faces */ if (!BM_faces_join_pair(bm, f, f2, e, TRUE)) { return FALSE; } @@ -343,7 +343,7 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l BLI_assert(v1 != v2); - /* do we have a multires layer */ + /* do we have a multires layer? */ if (has_mdisp) { of = BM_face_copy(bm, f, FALSE, FALSE); } @@ -641,7 +641,6 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce BMFace **oldfaces = NULL; BMEdge *e_dummy; BLI_array_staticdeclare(oldfaces, 32); - SmallHash hash; const int do_mdisp = (e->l && CustomData_has_layer(&bm->ldata, CD_MDISPS)); /* we need this for handling multi-res */ @@ -649,7 +648,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce r_e = &e_dummy; } - /* do we have a multi-res layer */ + /* do we have a multi-res layer? */ if (do_mdisp) { BMLoop *l; int i; @@ -660,12 +659,11 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce l = l->radial_next; } while (l != e->l); - /* create a hash so we can differentiate oldfaces from new face */ - BLI_smallhash_init(&hash); - + /* flag existing faces so we can differentiate oldfaces from new faces */ for (i = 0; i < BLI_array_count(oldfaces); i++) { + BM_ELEM_API_FLAG_ENABLE(oldfaces[i], _FLAG_OVERLAP); oldfaces[i] = BM_face_copy(bm, oldfaces[i], TRUE, TRUE); - BLI_smallhash_insert(&hash, (intptr_t)oldfaces[i], NULL); + BM_ELEM_API_FLAG_DISABLE(oldfaces[i], _FLAG_OVERLAP); } } @@ -689,7 +687,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce if (do_mdisp) { int i, j; - /* interpolate new/changed loop data from copied old face */ + /* interpolate new/changed loop data from copied old faces */ for (j = 0; j < 2; j++) { for (i = 0; i < BLI_array_count(oldfaces); i++) { BMEdge *e1 = j ? *r_e : e; @@ -703,7 +701,8 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce } do { - if (!BLI_smallhash_haskey(&hash, (intptr_t)l->f)) { + /* check this is an old face */ + if (BM_ELEM_API_FLAG_TEST(l->f, _FLAG_OVERLAP)) { BMLoop *l2_first; l2 = l2_first = BM_FACE_FIRST_LOOP(l->f); @@ -716,7 +715,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce } } - /* destroy the old face */ + /* destroy the old faces */ for (i = 0; i < BLI_array_count(oldfaces); i++) { BM_face_verts_kill(bm, oldfaces[i]); } @@ -741,7 +740,6 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce #endif BLI_array_free(oldfaces); - BLI_smallhash_release(&hash); } return nv; diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 58c6e051e48..3a7a1c4eaaa 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -339,7 +339,7 @@ static BMOpDefine bmo_automerge_def = { static BMOpDefine bmo_collapse_def = { "collapse", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -374,7 +374,7 @@ static BMOpDefine bmo_pointmerge_facedata_def = { static BMOpDefine bmo_average_vert_facedata_def = { "average_vert_facedata", /* slots_in */ - {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertice */ + {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -390,7 +390,7 @@ static BMOpDefine bmo_average_vert_facedata_def = { static BMOpDefine bmo_pointmerge_def = { "pointmerge", /* slots_in */ - {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertice */ + {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */ {"merge_co", BMO_OP_SLOT_VEC}, {{'\0'}}, }, @@ -407,7 +407,7 @@ static BMOpDefine bmo_pointmerge_def = { static BMOpDefine bmo_collapse_uvs_def = { "collapse_uvs", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */ {{'\0'}}, }, {{{'\0'}}}, /* no output */ @@ -513,7 +513,7 @@ static BMOpDefine bmo_contextual_create_def = { static BMOpDefine bmo_bridge_loops_def = { "bridge_loops", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */ {"use_merge", BMO_OP_SLOT_BOOL}, {"merge_factor", BMO_OP_SLOT_FLT}, {{'\0'}}, @@ -534,7 +534,7 @@ static BMOpDefine bmo_bridge_loops_def = { static BMOpDefine bmo_edgenet_fill_def = { "edgenet_fill", /* slots_in */ - {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */ + {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */ /* restricts edges to groups. maps edges to integer */ {"restrict", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_BOOL}}, {"use_restrict", BMO_OP_SLOT_BOOL}, @@ -547,7 +547,7 @@ static BMOpDefine bmo_edgenet_fill_def = { /* slots_out */ /* maps new faces to the group numbers they came from */ {{"face_groupmap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, - {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new face */ + {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */ {{'\0'}}, }, bmo_edgenet_fill_exec, @@ -962,7 +962,7 @@ static BMOpDefine bmo_subdivide_edges_def = { {/* these next three can have multiple types of elements in them */ {"geom_inner.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, {"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, - {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* contains all output geometr */ + {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* contains all output geometry */ {{'\0'}}, }, bmo_subdivide_edges_exec, diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 5e51f5a5ada..fbf51b7dfdf 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -599,6 +599,7 @@ void BMO_mesh_flag_disable_all(BMesh *bm, BMOperator *UNUSED(op), const char hty BMElemF *ele; int i; +#pragma omp parallel for schedule(dynamic) if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT) for (i = 0; i < 3; i++) { if (htype & flag_types[i]) { BM_ITER_MESH (ele, &iter, bm, iter_types[i]) { @@ -1159,100 +1160,161 @@ void BMO_slot_buffer_flag_disable(BMesh *bm, */ static void bmo_flag_layer_alloc(BMesh *bm) { - BMElemF *ele; /* set the index values since we are looping over all data anyway, * may save time later on */ - int i; - BMIter iter; - BLI_mempool *oldpool = bm->toolflagpool; /* old flag pool */ - BLI_mempool *newpool; - void *oldflags; + BLI_mempool *voldpool = bm->vtoolflagpool; /* old flag pool */ + BLI_mempool *eoldpool = bm->etoolflagpool; /* old flag pool */ + BLI_mempool *foldpool = bm->ftoolflagpool; /* old flag pool */ /* store memcpy size for reuse */ const size_t old_totflags_size = (bm->totflags * sizeof(BMFlagLayer)); - BLI_assert(oldpool != NULL); - bm->totflags++; - /* allocate new flag poo */ - bm->toolflagpool = newpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, 512, 512, 0); - - /* now go through and memcpy all the flags. Loops don't get a flag layer at this time.. */ - BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) { - oldflags = ele->oflags; - ele->oflags = BLI_mempool_calloc(newpool); - memcpy(ele->oflags, oldflags, old_totflags_size); - BM_elem_index_set(ele, i); /* set_inline */ - BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); - } - BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) { - oldflags = ele->oflags; - ele->oflags = BLI_mempool_calloc(newpool); - memcpy(ele->oflags, oldflags, old_totflags_size); - BM_elem_index_set(ele, i); /* set_inline */ - BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); - } - BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) { - oldflags = ele->oflags; - ele->oflags = BLI_mempool_calloc(newpool); - memcpy(ele->oflags, oldflags, old_totflags_size); - BM_elem_index_set(ele, i); /* set_inline */ - BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); + bm->vtoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, max_ii(512, bm->totvert), 512, 0); + bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, max_ii(512, bm->totedge), 512, 0); + bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, max_ii(512, bm->totface), 512, 0); + +#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT) + { +#pragma omp section + { + BMIter iter; + BMElemF *ele; + int i; + + BLI_mempool *newpool = bm->vtoolflagpool; + + /* now go through and memcpy all the flags. Loops don't get a flag layer at this time.. */ + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) { + void *oldflags = ele->oflags; + ele->oflags = BLI_mempool_calloc(newpool); + memcpy(ele->oflags, oldflags, old_totflags_size); + BM_elem_index_set(ele, i); /* set_inline */ + BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); + } + } +#pragma omp section + { + BMIter iter; + BMElemF *ele; + int i; + + BLI_mempool *newpool = bm->etoolflagpool; + + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) { + void *oldflags = ele->oflags; + ele->oflags = BLI_mempool_calloc(newpool); + memcpy(ele->oflags, oldflags, old_totflags_size); + BM_elem_index_set(ele, i); /* set_inline */ + BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); + } + } +#pragma omp section + { + BMIter iter; + BMElemF *ele; + int i; + + BLI_mempool *newpool = bm->ftoolflagpool; + + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) { + void *oldflags = ele->oflags; + ele->oflags = BLI_mempool_calloc(newpool); + memcpy(ele->oflags, oldflags, old_totflags_size); + BM_elem_index_set(ele, i); /* set_inline */ + BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); + } + } } + BLI_mempool_destroy(voldpool); + BLI_mempool_destroy(eoldpool); + BLI_mempool_destroy(foldpool); + bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE); - BLI_mempool_destroy(oldpool); + } static void bmo_flag_layer_free(BMesh *bm) { - BMElemF *ele; /* set the index values since we are looping over all data anyway, * may save time later on */ - int i; - BMIter iter; - BLI_mempool *oldpool = bm->toolflagpool; - BLI_mempool *newpool; - void *oldflags; - + BLI_mempool *voldpool = bm->vtoolflagpool; + BLI_mempool *eoldpool = bm->etoolflagpool; + BLI_mempool *foldpool = bm->ftoolflagpool; + /* store memcpy size for reuse */ const size_t new_totflags_size = ((bm->totflags - 1) * sizeof(BMFlagLayer)); /* de-increment the totflags first.. */ bm->totflags--; - /* allocate new flag poo */ - bm->toolflagpool = newpool = BLI_mempool_create(new_totflags_size, 512, 512, 0); - - /* now go through and memcpy all the flag */ - BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) { - oldflags = ele->oflags; - ele->oflags = BLI_mempool_calloc(newpool); - memcpy(ele->oflags, oldflags, new_totflags_size); - BM_elem_index_set(ele, i); /* set_inline */ - BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); - } - BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) { - oldflags = ele->oflags; - ele->oflags = BLI_mempool_calloc(newpool); - memcpy(ele->oflags, oldflags, new_totflags_size); - BM_elem_index_set(ele, i); /* set_inline */ - BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); - } - BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) { - oldflags = ele->oflags; - ele->oflags = BLI_mempool_calloc(newpool); - memcpy(ele->oflags, oldflags, new_totflags_size); - BM_elem_index_set(ele, i); /* set_inline */ - BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); + + bm->vtoolflagpool = BLI_mempool_create(new_totflags_size, bm->totvert, 512, 0); + bm->etoolflagpool = BLI_mempool_create(new_totflags_size, bm->totedge, 512, 0); + bm->ftoolflagpool = BLI_mempool_create(new_totflags_size, bm->totface, 512, 0); + +#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT) + { +#pragma omp section + { + BMIter iter; + BMElemF *ele; + int i; + + BLI_mempool *newpool = bm->vtoolflagpool; + + /* now go through and memcpy all the flag */ + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) { + void *oldflags = ele->oflags; + ele->oflags = BLI_mempool_calloc(newpool); + memcpy(ele->oflags, oldflags, new_totflags_size); + BM_elem_index_set(ele, i); /* set_inline */ + BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); + } + } +#pragma omp section + { + BMIter iter; + BMElemF *ele; + int i; + + BLI_mempool *newpool = bm->etoolflagpool; + + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) { + void *oldflags = ele->oflags; + ele->oflags = BLI_mempool_calloc(newpool); + memcpy(ele->oflags, oldflags, new_totflags_size); + BM_elem_index_set(ele, i); /* set_inline */ + BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); + } + } +#pragma omp section + { + BMIter iter; + BMElemF *ele; + int i; + + BLI_mempool *newpool = bm->ftoolflagpool; + + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) { + void *oldflags = ele->oflags; + ele->oflags = BLI_mempool_calloc(newpool); + memcpy(ele->oflags, oldflags, new_totflags_size); + BM_elem_index_set(ele, i); /* set_inline */ + BM_ELEM_API_FLAG_CLEAR((BMElemF *)ele); + } + } } - bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE); + BLI_mempool_destroy(voldpool); + BLI_mempool_destroy(eoldpool); + BLI_mempool_destroy(foldpool); - BLI_mempool_destroy(oldpool); + bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE); } static void bmo_flag_layer_clear(BMesh *bm) @@ -1261,22 +1323,35 @@ static void bmo_flag_layer_clear(BMesh *bm) /* set the index values since we are looping over all data anyway, * may save time later on */ int i; + const BMFlagLayer zero_flag = {0}; BMIter iter; const int totflags_offset = bm->totflags - 1; - /* now go through and memcpy all the flag */ - BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) { - memset(ele->oflags + totflags_offset, 0, sizeof(BMFlagLayer)); - BM_elem_index_set(ele, i); /* set_inline */ - } - BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) { - memset(ele->oflags + totflags_offset, 0, sizeof(BMFlagLayer)); - BM_elem_index_set(ele, i); /* set_inline */ - } - BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) { - memset(ele->oflags + totflags_offset, 0, sizeof(BMFlagLayer)); - BM_elem_index_set(ele, i); /* set_inline */ +#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT) + { + /* now go through and memcpy all the flag */ +#pragma omp section + { + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) { + ele->oflags[totflags_offset] = zero_flag; + BM_elem_index_set(ele, i); /* set_inline */ + } + } +#pragma omp section + { + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) { + ele->oflags[totflags_offset] = zero_flag; + BM_elem_index_set(ele, i); /* set_inline */ + } + } +#pragma omp section + { + BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) { + ele->oflags[totflags_offset] = zero_flag; + BM_elem_index_set(ele, i); /* set_inline */ + } + } } bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE); @@ -1364,7 +1439,7 @@ void *BMO_iter_step(BMOIter *iter) return NULL; } -/* used for iterating over mapping */ +/* used for iterating over mappings */ void *BMO_iter_map_value(BMOIter *iter) { return iter->val; @@ -1380,7 +1455,7 @@ float BMO_iter_map_value_f(BMOIter *iter) return *((float *)iter->val); } -/* error syste */ +/* error system */ typedef struct BMOpError { struct BMOpError *next, *prev; int errorcode; @@ -1562,7 +1637,7 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v goto error; \ } (void)0 - /* we muck around in here, so dup i */ + /* we muck around in here, so dup it */ fmt = ofmt = BLI_strdup(_fmt); /* find operator name */ @@ -1589,11 +1664,11 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v while (*fmt) { if (state) { - /* jump past leading whitespac */ + /* jump past leading whitespace */ i = strspn(fmt, " "); fmt += i; - /* ignore trailing whitespac */ + /* ignore trailing whitespace */ if (!fmt[i]) break; diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 2e0471863d4..953e7f4d20c 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -157,13 +157,11 @@ float BM_face_calc_area(BMFace *f) { BMLoop *l; BMIter iter; - float (*verts)[3]; + float (*verts)[3] = BLI_array_alloca(verts, f->len); float normal[3]; float area; int i; - BLI_array_fixedstack_declare(verts, BM_DEFAULT_NGON_STACK_SIZE, f->len, __func__); - BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, i) { copy_v3_v3(verts[i], l->v->co); } @@ -179,8 +177,6 @@ float BM_face_calc_area(BMFace *f) area = area_poly_v3(f->len, verts, normal); } - BLI_array_fixedstack_free(verts); - return area; } @@ -855,8 +851,8 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, float (*projectverts)[3], const s BMLoop *newl; BMLoop *l_iter; BMLoop *l_first; - float *abscoss = NULL; - BLI_array_fixedstack_declare(abscoss, 16, f->len, "BM_face_triangulate: temp absolute cosines of face corners"); + /* BM_face_triangulate: temp absolute cosines of face corners */ + float *abscoss = BLI_array_alloca(abscoss, f->len); /* copy vertex coordinates to vertspace area */ i = 0; @@ -940,11 +936,10 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, float (*projectverts)[3], const s } #endif - BLI_array_fixedstack_free(abscoss); - /* NULL-terminate */ - if (newfaces) + if (newfaces) { newfaces[nf_i] = NULL; + } } /** @@ -961,13 +956,10 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) BMLoop *l; float v1[3], v2[3], v3[3] /*, v4[3 */, no[3], mid[3], *p1, *p2, *p3, *p4; float out[3] = {-FLT_MAX, -FLT_MAX, 0.0f}; - float (*projverts)[3]; - float (*edgeverts)[3]; + float (*projverts)[3] = BLI_array_alloca(projverts, f->len); + float (*edgeverts)[3] = BLI_array_alloca(edgeverts, len * 2); float fac1 = 1.0000001f, fac2 = 0.9f; //9999f; //0.999f; int i, j, a = 0, clen; - - BLI_array_fixedstack_declare(projverts, BM_DEFAULT_NGON_STACK_SIZE, f->len, "projvertsb"); - BLI_array_fixedstack_declare(edgeverts, BM_DEFAULT_NGON_STACK_SIZE * 2, len * 2, "edgevertsb"); i = 0; l = BM_iter_new(&iter, bm, BM_LOOPS_OF_FACE, f); @@ -1042,7 +1034,7 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) } } - /* do line crossing test */ + /* do line crossing tests */ for (i = 0; i < f->len; i++) { p1 = projverts[i]; p2 = projverts[(i + 1) % f->len]; @@ -1085,7 +1077,4 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) } } } - - BLI_array_fixedstack_free(projverts); - BLI_array_fixedstack_free(edgeverts); } diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 195c60c5a9c..5f5c60dde3f 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -1113,6 +1113,40 @@ float BM_vert_calc_shell_factor(BMVert *v) return 1.0f; } } +/* alternate version of #BM_vert_calc_shell_factor which only + * uses 'hflag' faces, but falls back to all if none found. */ +float BM_vert_calc_shell_factor_ex(BMVert *v, const char hflag) +{ + BMIter iter; + BMLoop *l; + float accum_shell = 0.0f; + float accum_angle = 0.0f; + int tot_sel = 0, tot = 0; + + BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) { + if (BM_elem_flag_test(l->f, hflag)) { /* <-- main difference to BM_vert_calc_shell_factor! */ + const float face_angle = BM_loop_calc_face_angle(l); + accum_shell += shell_angle_to_dist(angle_normalized_v3v3(v->no, l->f->no)) * face_angle; + accum_angle += face_angle; + tot_sel++; + } + tot++; + } + + if (accum_angle != 0.0f) { + return accum_shell / accum_angle; + } + else { + /* other main difference from BM_vert_calc_shell_factor! */ + if (tot != 0 && tot_sel == 0) { + /* none selected, so use all */ + return BM_vert_calc_shell_factor(v); + } + else { + return 1.0f; + } + } +} /** * \note quite an obscure function. @@ -1415,8 +1449,7 @@ int BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len) /* same as 'BM_face_exists_multi' but built vert array from edges */ int BM_face_exists_multi_edge(BMEdge **earr, int len) { - BMVert **varr; - BLI_array_fixedstack_declare(varr, BM_DEFAULT_NGON_STACK_SIZE, len, __func__); + BMVert **varr = BLI_array_alloca(varr, len); int ok; int i, i_next; @@ -1432,14 +1465,11 @@ int BM_face_exists_multi_edge(BMEdge **earr, int len) if (ok == FALSE) { BMESH_ASSERT(0); - BLI_array_fixedstack_free(varr); return FALSE; } ok = BM_face_exists_multi(varr, earr, len); - BLI_array_fixedstack_free(varr); - return ok; } diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h index 7a18f69371e..9af792417bf 100644 --- a/source/blender/bmesh/intern/bmesh_queries.h +++ b/source/blender/bmesh/intern/bmesh_queries.h @@ -69,6 +69,7 @@ void BM_edge_calc_face_tangent(BMEdge *e, BMLoop *e_loop, float r_tangent[3]) float BM_vert_calc_edge_angle(BMVert *v); float BM_vert_calc_shell_factor(BMVert *v); +float BM_vert_calc_shell_factor_ex(BMVert *v, const char hflag); float BM_vert_calc_mean_tagged_edge_length(BMVert *v); BMLoop *BM_face_find_shortest_loop(BMFace *f); diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c index aa69806fb37..2ea5914ca92 100644 --- a/source/blender/bmesh/operators/bmo_create.c +++ b/source/blender/bmesh/operators/bmo_create.c @@ -578,7 +578,7 @@ static void init_rotsys(BMesh *bm, EdgeData *edata, VertData *vdata) //rotsys_fill_faces(bm, edata, vdata); #if 0 - /* create visualizing geometr */ + /* create visualizing geometry */ BMVert *lastv; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { BMVert *v2; diff --git a/source/blender/bmesh/operators/bmo_edgesplit.c b/source/blender/bmesh/operators/bmo_edgesplit.c index 9e9e4b8c962..b4b50a60877 100644 --- a/source/blender/bmesh/operators/bmo_edgesplit.c +++ b/source/blender/bmesh/operators/bmo_edgesplit.c @@ -22,152 +22,32 @@ /** \file blender/bmesh/operators/bmo_edgesplit.c * \ingroup bmesh + * + * Just a wrapper around #BM_mesh_edgesplit */ -#include "MEM_guardedalloc.h" - #include "BLI_utildefines.h" #include "bmesh.h" +#include "tools/bmesh_edgesplit.h" #include "intern/bmesh_operators_private.h" /* own include */ -enum { - EDGE_SEAM = 1 -}; - -enum { - VERT_SEAM = 2 -}; - -/** - * Remove the EDGE_SEAM flag for edges we cant split - * - * un-tag edges not connected to other tagged edges, - * unless they are on a boundary - */ -static void bm_edgesplit_validate_seams(BMesh *bm, BMOperator *op) -{ - BMOIter siter; - BMIter iter; - BMEdge *e; - - unsigned char *vtouch; - unsigned char *vt; - - BM_mesh_elem_index_ensure(bm, BM_VERT); - - vtouch = MEM_callocN(sizeof(char) * bm->totvert, __func__); - - /* tag all boundary verts so as not to untag an edge which is inbetween only 2 faces [] */ - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - - /* unrelated to flag assignment in this function - since this is the - * only place we loop over all edges, disable tag */ - BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG); - - if (e->l == NULL) { - BMO_elem_flag_disable(bm, e, EDGE_SEAM); - } - else if (BM_edge_is_boundary(e)) { - vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++; - vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++; - - /* while the boundary verts need to be tagged, - * the edge its self can't be split */ - BMO_elem_flag_disable(bm, e, EDGE_SEAM); - } - } - - /* single marked edges unconnected to any other marked edges - * are illegal, go through and unmark them */ - BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { - /* lame, but we don't want the count to exceed 255, - * so just count to 2, its all we need */ - unsigned char *vt; - vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++; - vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++; - } - BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { - if (vtouch[BM_elem_index_get(e->v1)] == 1 && - vtouch[BM_elem_index_get(e->v2)] == 1) - { - BMO_elem_flag_disable(bm, e, EDGE_SEAM); - } - } - - MEM_freeN(vtouch); -} /* keep this operator fast, its used in a modifier */ void bmo_split_edges_exec(BMesh *bm, BMOperator *op) { - BMOIter siter; - BMEdge *e; const int use_verts = BMO_slot_bool_get(op->slots_in, "use_verts"); - BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, EDGE_SEAM); + BMO_slot_buffer_hflag_enable(bm, op->slots_in, "edges", BM_EDGE, BM_ELEM_TAG, FALSE); if (use_verts) { /* this slows down the operation but its ok because the modifier doesn't use */ - BMO_slot_buffer_flag_enable(bm, op->slots_in, "verts", BM_VERT, VERT_SEAM); - - /* prevent one edge having both verts unflagged - * we could alternately disable these edges, either way its a corner case. - * - * This is needed so we don't split off the edge but then none of its verts which - * would leave a duplicate edge. - */ - BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { - if (UNLIKELY((BMO_elem_flag_test(bm, e->v1, VERT_SEAM) == FALSE && - (BMO_elem_flag_test(bm, e->v2, VERT_SEAM) == FALSE)))) - { - BMO_elem_flag_enable(bm, e->v1, VERT_SEAM); - BMO_elem_flag_enable(bm, e->v2, VERT_SEAM); - } - } + BMO_slot_buffer_hflag_enable(bm, op->slots_in, "verts", BM_VERT, BM_ELEM_TAG, FALSE); } - bm_edgesplit_validate_seams(bm, op); - - BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { - if (BMO_elem_flag_test(bm, e, EDGE_SEAM)) { - /* this flag gets copied so we can be sure duplicate edges get it too (important) */ - BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG); - - /* keep splitting until each loop has its own edge */ - do { - bmesh_edge_separate(bm, e, e->l); - } while (!BM_edge_is_boundary(e)); - - BM_elem_flag_enable(e->v1, BM_ELEM_TAG); - BM_elem_flag_enable(e->v2, BM_ELEM_TAG); - } - } - - if (use_verts) { - BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { - if (BMO_elem_flag_test(bm, e->v1, VERT_SEAM) == FALSE) { - BM_elem_flag_disable(e->v1, BM_ELEM_TAG); - } - if (BMO_elem_flag_test(bm, e->v2, VERT_SEAM) == FALSE) { - BM_elem_flag_disable(e->v2, BM_ELEM_TAG); - } - } - } - - BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { - if (BMO_elem_flag_test(bm, e, EDGE_SEAM)) { - if (BM_elem_flag_test(e->v1, BM_ELEM_TAG)) { - BM_elem_flag_disable(e->v1, BM_ELEM_TAG); - bmesh_vert_separate(bm, e->v1, NULL, NULL); - } - if (BM_elem_flag_test(e->v2, BM_ELEM_TAG)) { - BM_elem_flag_disable(e->v2, BM_ELEM_TAG); - bmesh_vert_separate(bm, e->v2, NULL, NULL); - } - } - } + /* this is where everything happens */ + BM_mesh_edgesplit(bm, use_verts, TRUE); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_INTERNAL_TAG); } diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c index 065a1b57737..bf3bafc57fb 100644 --- a/source/blender/bmesh/operators/bmo_extrude.c +++ b/source/blender/bmesh/operators/bmo_extrude.c @@ -600,39 +600,31 @@ static void solidify_add_thickness(BMesh *bm, const float dist) float *vert_accum = vert_angles + bm->totvert; int i, index; - /* array for passing verts to angle_poly_v3 */ - float **verts = NULL; - BLI_array_staticdeclare(verts, BM_DEFAULT_NGON_STACK_SIZE); - /* array for receiving angles from angle_poly_v3 */ - float *face_angles = NULL; - BLI_array_staticdeclare(face_angles, BM_DEFAULT_NGON_STACK_SIZE); - BM_mesh_elem_index_ensure(bm, BM_VERT); BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { - if (!BMO_elem_flag_test(bm, f, FACE_MARK)) { - continue; - } + if (BMO_elem_flag_test(bm, f, FACE_MARK)) { - BLI_array_grow_items(verts, f->len); - BM_ITER_ELEM_INDEX (l, &loopIter, f, BM_LOOPS_OF_FACE, i) { - verts[i] = l->v->co; - } + /* array for passing verts to angle_poly_v3 */ + float *face_angles = BLI_array_alloca(face_angles, f->len); + /* array for receiving angles from angle_poly_v3 */ + float **verts = BLI_array_alloca(verts, f->len); - BLI_array_grow_items(face_angles, f->len); - angle_poly_v3(face_angles, (const float **)verts, f->len); + BM_ITER_ELEM_INDEX (l, &loopIter, f, BM_LOOPS_OF_FACE, i) { + verts[i] = l->v->co; + } - i = 0; - BM_ITER_ELEM (l, &loopIter, f, BM_LOOPS_OF_FACE) { - v = l->v; - index = BM_elem_index_get(v); - vert_accum[index] += face_angles[i]; - vert_angles[index] += shell_angle_to_dist(angle_normalized_v3v3(v->no, f->no)) * face_angles[i]; - i++; - } + angle_poly_v3(face_angles, (const float **)verts, f->len); - BLI_array_empty(verts); - BLI_array_empty(face_angles); + i = 0; + BM_ITER_ELEM (l, &loopIter, f, BM_LOOPS_OF_FACE) { + v = l->v; + index = BM_elem_index_get(v); + vert_accum[index] += face_angles[i]; + vert_angles[index] += shell_angle_to_dist(angle_normalized_v3v3(v->no, f->no)) * face_angles[i]; + i++; + } + } } BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { @@ -643,9 +635,6 @@ static void solidify_add_thickness(BMesh *bm, const float dist) } MEM_freeN(vert_angles); - - BLI_array_free(verts); - BLI_array_free(face_angles); } void bmo_solidify_face_region_exec(BMesh *bm, BMOperator *op) diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c index 1e18a83a0a0..45ecdee014e 100644 --- a/source/blender/bmesh/operators/bmo_join_triangles.c +++ b/source/blender/bmesh/operators/bmo_join_triangles.c @@ -331,13 +331,13 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) } } - /* if l isn't NULL, we broke out of the loo */ + /* if l isn't NULL, we broke out of the loop */ if (l) { break; } } - /* if i isn't 2, we broke out of that loo */ + /* if i isn't 2, we broke out of that loop */ if (i != 2) { continue; } diff --git a/source/blender/bmesh/tools/BME_bevel.c b/source/blender/bmesh/tools/BME_bevel.c index 3f2ca21bcee..5e1d58150fa 100644 --- a/source/blender/bmesh/tools/BME_bevel.c +++ b/source/blender/bmesh/tools/BME_bevel.c @@ -965,7 +965,7 @@ static BMesh *BME_bevel_initialize(BMesh *bm, int options, BMIter iter; int /* wire, */ len; - /* tag non-manifold geometr */ + /* tag non-manifold geometry */ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { BMO_elem_flag_enable(bm, v, BME_BEVEL_ORIG); if (v->e) { diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 9125800d3e8..cc472e4a501 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -37,6 +37,7 @@ #include "BKE_customdata.h" #include "bmesh.h" +#include "./intern/bmesh_private.h" @@ -263,14 +264,12 @@ static BMFace *bev_create_ngon(BMesh *bm, BMVert **vert_arr, const int totv, BMF } else { int i; - BMEdge **ee = NULL; - BLI_array_fixedstack_declare(ee, BM_DEFAULT_NGON_STACK_SIZE, totv, __func__); + BMEdge **ee = BLI_array_alloca(ee, totv); for (i = 0; i < totv; i++) { ee[i] = BM_edge_create(bm, vert_arr[i], vert_arr[(i + 1) % totv], NULL, BM_CREATE_NO_DOUBLE); } f = BM_face_create_ngon(bm, vert_arr[0], vert_arr[1], ee, totv, 0); - BLI_array_fixedstack_free(ee); } if (facerep && f) { int has_mdisps = CustomData_has_layer(&bm->ldata, CD_MDISPS); @@ -1137,7 +1136,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv) /* Make center ngon if odd number of segments and fully beveled */ if (ns % 2 == 1 && vm->count == bv->selcount) { BMVert **vv = NULL; - BLI_array_declare(vv); + BLI_array_staticdeclare(vv, BM_DEFAULT_NGON_STACK_SIZE); v = vm->boundstart; do { @@ -1155,7 +1154,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv) if (vm->count > bv->selcount) { int j; BMVert **vv = NULL; - BLI_array_declare(vv); + BLI_array_staticdeclare(vv, BM_DEFAULT_NGON_STACK_SIZE); v = vm->boundstart; f = boundvert_rep_face(v); @@ -1217,7 +1216,7 @@ static BMFace *bevel_build_poly_ex(BMesh *bm, BevVert *bv) VMesh *vm = bv->vmesh; BoundVert *v; BMVert **vv = NULL; - BLI_array_declare(vv); + BLI_array_staticdeclare(vv, BM_DEFAULT_NGON_STACK_SIZE); v = vm->boundstart; n = 0; @@ -1477,9 +1476,9 @@ static void build_vmesh(MemArena *mem_arena, BMesh *bm, BevVert *bv) } /* take care, this flag isn't cleared before use, it just so happens that its not set */ -#define BM_BEVEL_EDGE_TAG_ENABLE(bme) BM_elem_flag_enable( (bme)->l, BM_ELEM_TAG) -#define BM_BEVEL_EDGE_TAG_DISABLE(bme) BM_elem_flag_disable( (bme)->l, BM_ELEM_TAG) -#define BM_BEVEL_EDGE_TAG_TEST(bme) BM_elem_flag_test( (bme)->l, BM_ELEM_TAG) +#define BM_BEVEL_EDGE_TAG_ENABLE(bme) BM_ELEM_API_FLAG_ENABLE( (bme), _FLAG_OVERLAP) +#define BM_BEVEL_EDGE_TAG_DISABLE(bme) BM_ELEM_API_FLAG_DISABLE( (bme), _FLAG_OVERLAP) +#define BM_BEVEL_EDGE_TAG_TEST(bme) BM_ELEM_API_FLAG_TEST( (bme), _FLAG_OVERLAP) /* * Construction around the vertex @@ -1506,6 +1505,8 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) nsel++; } ntot++; + + BM_BEVEL_EDGE_TAG_DISABLE(bme); } if (nsel == 0) { diff --git a/source/blender/bmesh/tools/bmesh_edgesplit.c b/source/blender/bmesh/tools/bmesh_edgesplit.c new file mode 100644 index 00000000000..b6a8c7985d6 --- /dev/null +++ b/source/blender/bmesh/tools/bmesh_edgesplit.c @@ -0,0 +1,170 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/bmesh/tools/bmesh_edgesplit.c + * \ingroup bmesh + * + * Edge-Split. + * + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" + +#include "bmesh.h" + +#include "bmesh_edgesplit.h" /* own include */ + + +/** + * Remove the BM_ELEM_TAG flag for edges we cant split + * + * un-tag edges not connected to other tagged edges, + * unless they are on a boundary + */ +static void bm_edgesplit_validate_seams(BMesh *bm) +{ + BMIter iter; + BMEdge *e; + + unsigned char *vtouch; + unsigned char *vt; + + BM_mesh_elem_index_ensure(bm, BM_VERT); + + vtouch = MEM_callocN(sizeof(char) * bm->totvert, __func__); + + /* tag all boundary verts so as not to untag an edge which is inbetween only 2 faces [] */ + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + + /* unrelated to flag assignment in this function - since this is the + * only place we loop over all edges, disable tag */ + BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG); + + if (e->l == NULL) { + BM_elem_flag_disable(e, BM_ELEM_TAG); + } + else if (BM_edge_is_boundary(e)) { + vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++; + vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++; + + /* while the boundary verts need to be tagged, + * the edge its self can't be split */ + BM_elem_flag_disable(e, BM_ELEM_TAG); + } + } + + /* single marked edges unconnected to any other marked edges + * are illegal, go through and unmark them */ + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + /* lame, but we don't want the count to exceed 255, + * so just count to 2, its all we need */ + unsigned char *vt; + vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++; + vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++; + } + } + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + if (vtouch[BM_elem_index_get(e->v1)] == 1 && + vtouch[BM_elem_index_get(e->v2)] == 1) + { + BM_elem_flag_disable(e, BM_ELEM_TAG); + } + } + } + + MEM_freeN(vtouch); +} + +void BM_mesh_edgesplit(BMesh *bm, const int use_verts, const int tag_only) +{ + BMIter iter; + BMEdge *e; + + + if (tag_only == FALSE) { + BM_mesh_elem_hflag_enable_all(bm, BM_EDGE | (use_verts ? BM_VERT : 0), BM_ELEM_TAG, FALSE); + } + + if (use_verts) { + /* prevent one edge having both verts unflagged + * we could alternately disable these edges, either way its a corner case. + * + * This is needed so we don't split off the edge but then none of its verts which + * would leave a duplicate edge. + */ + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + if (UNLIKELY(((BM_elem_flag_test(e->v1, BM_ELEM_TAG) == FALSE) && + (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == FALSE)))) + { + BM_elem_flag_enable(e->v1, BM_ELEM_TAG); + BM_elem_flag_enable(e->v2, BM_ELEM_TAG); + } + } + } + } + + bm_edgesplit_validate_seams(bm); + + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + /* this flag gets copied so we can be sure duplicate edges get it too (important) */ + BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG); + + /* keep splitting until each loop has its own edge */ + do { + bmesh_edge_separate(bm, e, e->l); + } while (!BM_edge_is_boundary(e)); + + BM_elem_flag_enable(e->v1, BM_ELEM_TAG); + BM_elem_flag_enable(e->v2, BM_ELEM_TAG); + } + } + + if (use_verts) { + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e->v1, BM_ELEM_TAG) == FALSE) { + BM_elem_flag_disable(e->v1, BM_ELEM_TAG); + } + if (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == FALSE) { + BM_elem_flag_disable(e->v2, BM_ELEM_TAG); + } + } + } + + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + if (BM_elem_flag_test(e->v1, BM_ELEM_TAG)) { + BM_elem_flag_disable(e->v1, BM_ELEM_TAG); + bmesh_vert_separate(bm, e->v1, NULL, NULL); + } + if (BM_elem_flag_test(e->v2, BM_ELEM_TAG)) { + BM_elem_flag_disable(e->v2, BM_ELEM_TAG); + bmesh_vert_separate(bm, e->v2, NULL, NULL); + } + } + } +} diff --git a/source/blender/bmesh/tools/bmesh_edgesplit.h b/source/blender/bmesh/tools/bmesh_edgesplit.h new file mode 100644 index 00000000000..687fdac0e00 --- /dev/null +++ b/source/blender/bmesh/tools/bmesh_edgesplit.h @@ -0,0 +1,32 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BMESH_EDGESPLIT_H__ +#define __BMESH_EDGESPLIT_H__ + +/** \file blender/bmesh/tools/bmesh_edgesplit.h + * \ingroup bmesh + */ + +void BM_mesh_edgesplit(BMesh *bm, const int use_verts, const int tag_only); + +#endif /* __BMESH_EDGESPLIT_H__ */ diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp index cd2574d055e..f1cf732e695 100644 --- a/source/blender/collada/ArmatureImporter.cpp +++ b/source/blender/collada/ArmatureImporter.cpp @@ -79,7 +79,7 @@ JointData *ArmatureImporter::get_joint_data(COLLADAFW::Node *node); } #endif void ArmatureImporter::create_unskinned_bone(COLLADAFW::Node *node, EditBone *parent, int totchild, - float parent_mat[][4], Object *ob_arm) + float parent_mat[4][4], Object *ob_arm) { std::vector<COLLADAFW::Node *>::iterator it; it = std::find(finished_joints.begin(), finished_joints.end(), node); @@ -156,7 +156,7 @@ void ArmatureImporter::create_unskinned_bone(COLLADAFW::Node *node, EditBone *pa } void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild, - float parent_mat[][4], bArmature *arm) + float parent_mat[4][4], bArmature *arm) { //Checking if bone is already made. std::vector<COLLADAFW::Node *>::iterator it; @@ -268,7 +268,7 @@ void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBo finished_joints.push_back(node); } -void ArmatureImporter::add_leaf_bone(float mat[][4], EditBone *bone, COLLADAFW::Node *node) +void ArmatureImporter::add_leaf_bone(float mat[4][4], EditBone *bone, COLLADAFW::Node *node) { LeafBone leaf; @@ -572,7 +572,7 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin) // is a child of a node (not joint), root should be true since // this is where we build armature bones from -void ArmatureImporter::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[][4]) +void ArmatureImporter::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[4][4]) { char *bone_name = (char *) bc_get_joint_name(root_node); float mat[4][4]; @@ -792,7 +792,7 @@ void ArmatureImporter::get_rna_path_for_joint(COLLADAFW::Node *node, char *joint } // gives a world-space mat -bool ArmatureImporter::get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint) +bool ArmatureImporter::get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint) { std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it; bool found = false; diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h index a6b37287479..bb710f09490 100644 --- a/source/blender/collada/ArmatureImporter.h +++ b/source/blender/collada/ArmatureImporter.h @@ -104,16 +104,16 @@ private: #endif void create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild, - float parent_mat[][4], bArmature *arm); + float parent_mat[4][4], bArmature *arm); void create_unskinned_bone(COLLADAFW::Node *node, EditBone *parent, int totchild, - float parent_mat[][4], Object * ob_arm); + float parent_mat[4][4], Object * ob_arm); - void add_leaf_bone(float mat[][4], EditBone *bone, COLLADAFW::Node * node); + void add_leaf_bone(float mat[4][4], EditBone *bone, COLLADAFW::Node * node); void fix_leaf_bones(); - void set_pose ( Object * ob_arm, COLLADAFW::Node * root_node, const char *parentname, float parent_mat[][4]); + void set_pose ( Object * ob_arm, COLLADAFW::Node * root_node, const char *parentname, float parent_mat[4][4]); #if 0 @@ -168,7 +168,7 @@ public: void get_rna_path_for_joint(COLLADAFW::Node *node, char *joint_path, size_t count); // gives a world-space mat - bool get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint); + bool get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint); void set_tags_map( TagsMap& tags_map); diff --git a/source/blender/collada/SConscript b/source/blender/collada/SConscript index 5d921681aea..1351441e41b 100644 --- a/source/blender/collada/SConscript +++ b/source/blender/collada/SConscript @@ -1,4 +1,5 @@ -#!/usr/bin/python +#!/usr/bin/env python +# # ***** BEGIN GPL LICENSE BLOCK ***** # # This program is free software; you can redistribute it and/or diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp index 9b0d59d66ea..470f663f716 100644 --- a/source/blender/collada/SkinInfo.cpp +++ b/source/blender/collada/SkinInfo.cpp @@ -168,7 +168,7 @@ Object *SkinInfo::set_armature(Object *ob_arm) return ob_arm; } -bool SkinInfo::get_joint_inv_bind_matrix(float inv_bind_mat[][4], COLLADAFW::Node *node) +bool SkinInfo::get_joint_inv_bind_matrix(float inv_bind_mat[4][4], COLLADAFW::Node *node) { const COLLADAFW::UniqueId& uid = node->getUniqueId(); std::vector<JointData>::iterator it; diff --git a/source/blender/collada/SkinInfo.h b/source/blender/collada/SkinInfo.h index 894f53f07c3..e074f59cffc 100644 --- a/source/blender/collada/SkinInfo.h +++ b/source/blender/collada/SkinInfo.h @@ -103,7 +103,7 @@ public: Object* set_armature(Object *ob_arm); - bool get_joint_inv_bind_matrix(float inv_bind_mat[][4], COLLADAFW::Node *node); + bool get_joint_inv_bind_matrix(float inv_bind_mat[4][4], COLLADAFW::Node *node); Object *BKE_armature_from_object(); diff --git a/source/blender/collada/TransformReader.cpp b/source/blender/collada/TransformReader.cpp index 61793589422..5bc135e9b67 100644 --- a/source/blender/collada/TransformReader.cpp +++ b/source/blender/collada/TransformReader.cpp @@ -34,7 +34,7 @@ TransformReader::TransformReader(UnitConverter *conv) : unit_converter(conv) /* pass */ } -void TransformReader::get_node_mat(float mat[][4], COLLADAFW::Node *node, std::map<COLLADAFW::UniqueId, Animation> *animation_map, Object *ob) +void TransformReader::get_node_mat(float mat[4][4], COLLADAFW::Node *node, std::map<COLLADAFW::UniqueId, Animation> *animation_map, Object *ob) { float cur[4][4]; float copy[4][4]; @@ -79,7 +79,7 @@ void TransformReader::get_node_mat(float mat[][4], COLLADAFW::Node *node, std::m } } -void TransformReader::dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[][4]) +void TransformReader::dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]) { COLLADAFW::Rotate *ro = (COLLADAFW::Rotate *)tm; COLLADABU::Math::Vector3& axis = ro->getRotationAxis(); @@ -91,7 +91,7 @@ void TransformReader::dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[ axis_angle_to_mat4(m, ax, angle); } -void TransformReader::dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[][4]) +void TransformReader::dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]) { COLLADAFW::Translate *tra = (COLLADAFW::Translate *)tm; COLLADABU::Math::Vector3& t = tra->getTranslation(); @@ -103,14 +103,14 @@ void TransformReader::dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[3][2] = (float)t[2]; } -void TransformReader::dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[][4]) +void TransformReader::dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]) { COLLADABU::Math::Vector3& s = ((COLLADAFW::Scale *)tm)->getScale(); float size[3] = {(float)s[0], (float)s[1], (float)s[2]}; size_to_mat4(m, size); } -void TransformReader::dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[][4]) +void TransformReader::dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]) { unit_converter->dae_matrix_to_mat4_(m, ((COLLADAFW::Matrix *)tm)->getMatrix()); } diff --git a/source/blender/collada/TransformReader.h b/source/blender/collada/TransformReader.h index 47e59a1bf52..ab974b9ba85 100644 --- a/source/blender/collada/TransformReader.h +++ b/source/blender/collada/TransformReader.h @@ -58,12 +58,12 @@ public: TransformReader(UnitConverter *conv); - void get_node_mat(float mat[][4], COLLADAFW::Node *node, std::map<COLLADAFW::UniqueId, Animation> *animation_map, Object *ob); + void get_node_mat(float mat[4][4], COLLADAFW::Node *node, std::map<COLLADAFW::UniqueId, Animation> *animation_map, Object *ob); - void dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[][4]); - void dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[][4]); - void dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[][4]); - void dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[][4]); + void dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]); + void dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]); + void dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]); + void dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]); void dae_translate_to_v3(COLLADAFW::Transformation *tm, float v[3]); void dae_scale_to_v3(COLLADAFW::Transformation *tm, float v[3]); void dae_vector3_to_v3(const COLLADABU::Math::Vector3 &v3, float v[3]); diff --git a/source/blender/collada/TransformWriter.cpp b/source/blender/collada/TransformWriter.cpp index 0d6e3831637..3fe3f620a68 100644 --- a/source/blender/collada/TransformWriter.cpp +++ b/source/blender/collada/TransformWriter.cpp @@ -32,7 +32,7 @@ #include "BLI_math.h" -void TransformWriter::add_node_transform(COLLADASW::Node& node, float mat[][4], float parent_mat[][4]) +void TransformWriter::add_node_transform(COLLADASW::Node& node, float mat[4][4], float parent_mat[4][4]) { float loc[3], rot[3], scale[3]; float local[4][4]; diff --git a/source/blender/collada/TransformWriter.h b/source/blender/collada/TransformWriter.h index 917e26dac1a..d2a4b54a570 100644 --- a/source/blender/collada/TransformWriter.h +++ b/source/blender/collada/TransformWriter.h @@ -37,7 +37,7 @@ class TransformWriter : protected TransformBase { protected: - void add_node_transform(COLLADASW::Node& node, float mat[][4], float parent_mat[][4]); + void add_node_transform(COLLADASW::Node& node, float mat[4][4], float parent_mat[4][4]); void add_node_transform_ob(COLLADASW::Node& node, Object *ob); diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp index a4969735757..51d81dc164b 100644 --- a/source/blender/collada/collada_internal.cpp +++ b/source/blender/collada/collada_internal.cpp @@ -74,7 +74,7 @@ void UnitConverter::convertVector3(COLLADABU::Math::Vector3 &vec, float *v) // TODO need also for angle conversion, time conversion... -void UnitConverter::dae_matrix_to_mat4_(float out[][4], const COLLADABU::Math::Matrix4& in) +void UnitConverter::dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math::Matrix4& in) { // in DAE, matrices use columns vectors, (see comments in COLLADABUMathMatrix4.h) // so here, to make a blender matrix, we swap columns and rows @@ -85,13 +85,13 @@ void UnitConverter::dae_matrix_to_mat4_(float out[][4], const COLLADABU::Math::M } } -void UnitConverter::mat4_to_dae(float out[][4], float in[][4]) +void UnitConverter::mat4_to_dae(float out[4][4], float in[4][4]) { copy_m4_m4(out, in); transpose_m4(out); } -void UnitConverter::mat4_to_dae_double(double out[][4], float in[][4]) +void UnitConverter::mat4_to_dae_double(double out[4][4], float in[4][4]) { float mat[4][4]; @@ -102,7 +102,7 @@ void UnitConverter::mat4_to_dae_double(double out[][4], float in[][4]) out[i][j] = mat[i][j]; } -void TransformBase::decompose(float mat[][4], float *loc, float eul[3], float quat[4], float *size) +void TransformBase::decompose(float mat[4][4], float *loc, float eul[3], float quat[4], float *size) { mat4_to_size(size, mat); if (eul) { diff --git a/source/blender/collada/collada_internal.h b/source/blender/collada/collada_internal.h index 6eec6a1675e..d92f53f714c 100644 --- a/source/blender/collada/collada_internal.h +++ b/source/blender/collada/collada_internal.h @@ -69,17 +69,17 @@ public: // TODO need also for angle conversion, time conversion... - void dae_matrix_to_mat4_(float out[][4], const COLLADABU::Math::Matrix4& in); + void dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math::Matrix4& in); - void mat4_to_dae(float out[][4], float in[][4]); + void mat4_to_dae(float out[4][4], float in[4][4]); - void mat4_to_dae_double(double out[][4], float in[][4]); + void mat4_to_dae_double(double out[4][4], float in[4][4]); }; class TransformBase { public: - void decompose(float mat[][4], float *loc, float eul[3], float quat[4], float *size); + void decompose(float mat[4][4], float *loc, float eul[3], float quat[4], float *size); }; extern void clear_global_id_map(); diff --git a/source/blender/compositor/SConscript b/source/blender/compositor/SConscript index 9f947ca7327..1872bf2afac 100644 --- a/source/blender/compositor/SConscript +++ b/source/blender/compositor/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) 2011, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Jeroen Bakker, Monique Dewanchand, Blender Developers Fund. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') defs = ['GLEW_STATIC'] diff --git a/source/blender/compositor/operations/COM_ImageOperation.cpp b/source/blender/compositor/operations/COM_ImageOperation.cpp index 84557118a1c..c8e3dbf993d 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.cpp +++ b/source/blender/compositor/operations/COM_ImageOperation.cpp @@ -120,7 +120,7 @@ void ImageOperation::executePixel(float output[4], float x, float y, PixelSample else { switch (sampler) { case COM_PS_NEAREST: - neareast_interpolation_color(this->m_buffer, NULL, output, x, y); + nearest_interpolation_color(this->m_buffer, NULL, output, x, y); break; case COM_PS_BILINEAR: bilinear_interpolation_color(this->m_buffer, NULL, output, x, y); @@ -143,7 +143,7 @@ void ImageAlphaOperation::executePixel(float output[4], float x, float y, PixelS tempcolor[3] = 1.0f; switch (sampler) { case COM_PS_NEAREST: - neareast_interpolation_color(this->m_buffer, NULL, tempcolor, x, y); + nearest_interpolation_color(this->m_buffer, NULL, tempcolor, x, y); break; case COM_PS_BILINEAR: bilinear_interpolation_color(this->m_buffer, NULL, tempcolor, x, y); diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.cpp b/source/blender/compositor/operations/COM_MovieClipOperation.cpp index 709e4b7d4b0..74761f00e1f 100644 --- a/source/blender/compositor/operations/COM_MovieClipOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieClipOperation.cpp @@ -95,7 +95,7 @@ void MovieClipOperation::executePixel(float output[4], float x, float y, PixelSa else { switch (sampler) { case COM_PS_NEAREST: - neareast_interpolation_color(this->m_movieClipBuffer, NULL, output, x, y); + nearest_interpolation_color(this->m_movieClipBuffer, NULL, output, x, y); break; case COM_PS_BILINEAR: bilinear_interpolation_color(this->m_movieClipBuffer, NULL, output, x, y); diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp index af0d5161835..1c9dd0f170e 100644 --- a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp +++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp @@ -54,7 +54,7 @@ void MultilayerColorOperation::executePixel(float output[4], float x, float y, P if (this->m_numberOfChannels == 4) { switch (sampler) { case COM_PS_NEAREST: - neareast_interpolation_color(this->m_buffer, NULL, output, x, y); + nearest_interpolation_color(this->m_buffer, NULL, output, x, y); break; case COM_PS_BILINEAR: bilinear_interpolation_color(this->m_buffer, NULL, output, x, y); diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl b/source/blender/compositor/operations/COM_OpenCLKernels.cl index 36205bb94cc..8cc25fc3360 100644 --- a/source/blender/compositor/operations/COM_OpenCLKernels.cl +++ b/source/blender/compositor/operations/COM_OpenCLKernels.cl @@ -66,7 +66,8 @@ __kernel void bokehBlurKernel(__read_only image2d_t boundingBox, __read_only ima } color /= multiplyer; - } else { + } + else { int2 imageCoordinates = realCoordinate - offsetInput; color = read_imagef(inputImage, SAMPLER_NEAREST, imageCoordinates); } diff --git a/source/blender/datatoc/datatoc.c b/source/blender/datatoc/datatoc.c index 379658bb4c4..236d9af8ef1 100644 --- a/source/blender/datatoc/datatoc.c +++ b/source/blender/datatoc/datatoc.c @@ -51,6 +51,7 @@ int main(int argc, char **argv) FILE *fpin, *fpout; long size; int i; + int argv_len; if (argc < 2) { printf("Usage: datatoc <data_file_from> <data_file_to>\n"); @@ -75,7 +76,8 @@ int main(int argc, char **argv) printf("Making C file <%s>\n", argv[2]); #endif - for (i = 0; i < (int)strlen(argv[1]); i++) + argv_len = (int)strlen(argv[1]); + for (i = 0; i < argv_len; i++) if (argv[1][i] == '.') argv[1][i] = '_'; fpout = fopen(argv[2], "w"); 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) diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp index e7f97405390..f2ce7df0f6c 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -80,7 +80,7 @@ BlenderStrokeRenderer::BlenderStrokeRenderer(Render* re, int render_count) : Str char name[22]; BLI_snprintf(name, sizeof(name), "FRS%d_%s", render_count, re->scene->id.name + 2); - freestyle_scene = BKE_scene_add(name); + freestyle_scene = BKE_scene_add(G.main, name); freestyle_scene->r.cfra = old_scene->r.cfra; freestyle_scene->r.mode = old_scene->r.mode & ~(R_EDGE_FRS | R_SHADOW | R_SSS | R_PANORAMA | R_ENVMAP | R_MBLUR | R_BORDER); diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h index b26c25558c3..974865db1c0 100644 --- a/source/blender/gpu/GPU_draw.h +++ b/source/blender/gpu/GPU_draw.h @@ -93,7 +93,7 @@ int GPU_set_tpage(struct MTFace *tface, int mipmap, int transp); int GPU_default_lights(void); int GPU_scene_object_lights(struct Scene *scene, struct Object *ob, - int lay, float viewmat[][4], int ortho); + int lay, float viewmat[4][4], int ortho); /* Text render * - based on moving uv coordinates */ diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index c46230de8bf..20791652735 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -127,7 +127,7 @@ void GPU_material_free(struct Material *ma); void GPU_materials_free(void); void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap); -void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4], float autobumpscale); +void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float viewinv[4][4], float obcol[4], float autobumpscale); void GPU_material_unbind(GPUMaterial *material); int GPU_material_bound(GPUMaterial *material); @@ -232,10 +232,10 @@ void GPU_lamp_free(struct Object *ob); int GPU_lamp_has_shadow_buffer(GPULamp *lamp); void GPU_lamp_update_buffer_mats(GPULamp *lamp); -void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4]); +void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4]); void GPU_lamp_shadow_buffer_unbind(GPULamp *lamp); -void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[][4]); +void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4]); void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float energy); void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2); void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend); diff --git a/source/blender/gpu/SConscript b/source/blender/gpu/SConscript index 9b8a86eac15..aeb7edc2c56 100644 --- a/source/blender/gpu/SConscript +++ b/source/blender/gpu/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('intern/*.c') diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 6e475ace09d..daf97c4841f 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -45,6 +45,7 @@ #include "BLI_threads.h" #include "DNA_meshdata_types.h" +#include "DNA_material_types.h" #include "BKE_ccg.h" #include "BKE_DerivedMesh.h" @@ -66,8 +67,8 @@ typedef enum { #define MAX_GPU_ATTRIB_DATA 32 -/* material number is an 16-bit short and the range of short is from -16383 to 16383 (assume material number is non-negative) */ -#define MAX_MATERIALS 16384 +/* material number is an 16-bit signed short and the range (assume material number is non-negative) */ +#define MAX_MATERIALS MAXMAT /* -1 - undefined, 0 - vertex arrays, 1 - VBOs */ static int useVBOs = -1; diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index d466e59452b..88a9122e88c 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -252,6 +252,25 @@ void GPU_set_gpu_mipmapping(int gpu_mipmap) } } +static void gpu_generate_mipmap(GLenum target) +{ + int is_ati = GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY); + int target_enabled = 0; + + /* work around bug in ATI driver, need to have GL_TEXTURE_2D enabled + * http://www.opengl.org/wiki/Common_Mistakes#Automatic_mipmap_generation */ + if (is_ati) { + target_enabled = glIsEnabled(target); + if (!target_enabled) + glEnable(target); + } + + glGenerateMipmapEXT(target); + + if (is_ati && !target_enabled) + glDisable(target); +} + void GPU_set_mipmap(int mipmap) { if (GTS.domipmap != (mipmap != 0)) { @@ -691,7 +710,7 @@ void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float * frect, int else glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, pix); - glGenerateMipmapEXT(GL_TEXTURE_2D); + gpu_generate_mipmap(GL_TEXTURE_2D); } else { if (use_high_bit_depth) @@ -934,7 +953,7 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h) /* we have already accounted for the case where GTS.gpu_mipmap is false * so we will be using GPU mipmap generation here */ if (GPU_get_mipmap()) { - glGenerateMipmapEXT(GL_TEXTURE_2D); + gpu_generate_mipmap(GL_TEXTURE_2D); } else { ima->tpageflag &= ~IMA_MIPMAP_COMPLETE; @@ -959,7 +978,7 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h) /* see comment above as to why we are using gpu mipmap generation here */ if (GPU_get_mipmap()) { - glGenerateMipmapEXT(GL_TEXTURE_2D); + gpu_generate_mipmap(GL_TEXTURE_2D); } else { ima->tpageflag &= ~IMA_MIPMAP_COMPLETE; @@ -1593,7 +1612,7 @@ int GPU_default_lights(void) return count; } -int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[][4], int ortho) +int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[4][4], int ortho) { Base *base; Lamp *la; diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 9c48f74bf5f..2039f01a740 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -282,7 +282,7 @@ void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double tim } } -void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float viewmat[][4], float viewinv[][4], float obcol[4], float autobumpscale) +void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float viewinv[4][4], float obcol[4], float autobumpscale) { if (material->pass) { GPUShader *shader = GPU_pass_shader(material->pass); @@ -1526,7 +1526,7 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma) ntreeGPUMaterialNodes(ma->nodetree, mat); } else { - if(BKE_scene_use_new_shading_nodes(scene)) { + if (BKE_scene_use_new_shading_nodes(scene)) { /* create simple diffuse material instead of nodes */ outlink = gpu_material_diffuse_bsdf(mat, ma); } @@ -1572,7 +1572,7 @@ void GPU_materials_free(void) /* Lamps and shadow buffers */ -void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[][4]) +void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[4][4]) { float mat[4][4]; @@ -1854,7 +1854,7 @@ void GPU_lamp_update_buffer_mats(GPULamp *lamp) mult_m4_m4m4(lamp->persmat, rangemat, persmat); } -void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[][4], int *winsize, float winmat[][4]) +void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4]) { GPU_lamp_update_buffer_mats(lamp); diff --git a/source/blender/ikplugin/SConscript b/source/blender/ikplugin/SConscript index 97b1cf18e0d..0d201cb423c 100644 --- a/source/blender/ikplugin/SConscript +++ b/source/blender/ikplugin/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') defs = [] sources = env.Glob('intern/*.c') + env.Glob('intern/*.cpp') diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c index ca81f4c915a..75aaa23369b 100644 --- a/source/blender/ikplugin/intern/iksolver_plugin.c +++ b/source/blender/ikplugin/intern/iksolver_plugin.c @@ -206,7 +206,7 @@ static void make_dmats(bPoseChannel *pchan) /* applies IK matrix to pchan, IK is done separated */ /* formula: pose_mat(b) = pose_mat(b-1) * diffmat(b-1, b) * ik_mat(b) */ /* to make this work, the diffmats have to be precalculated! Stored in chan_mat */ -static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[][3]) // nr = to detect if this is first bone +static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[3][3]) // nr = to detect if this is first bone { float vec[3], ikmat[4][4]; diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index d0ac71a7131..db1404813b1 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -407,11 +407,11 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf); * \attention defined in imageprocess.c */ void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout); -void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout); +void nearest_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout); void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout); void bicubic_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); -void neareast_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); +void nearest_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); void bilinear_interpolation_color(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char col[4], float col_float[4], float u, float v); diff --git a/source/blender/imbuf/SConscript b/source/blender/imbuf/SConscript index 976108cd84e..f76da8cd9d0 100644 --- a/source/blender/imbuf/SConscript +++ b/source/blender/imbuf/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 os Import ('env') diff --git a/source/blender/imbuf/intern/cineon/SConscript b/source/blender/imbuf/intern/cineon/SConscript index a07334632d7..d8fc2502081 100644 --- a/source/blender/imbuf/intern/cineon/SConscript +++ b/source/blender/imbuf/intern/cineon/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') source_files = env.Glob('*.c') diff --git a/source/blender/imbuf/intern/cineon/cineonlib.c b/source/blender/imbuf/intern/cineon/cineonlib.c index 3049a5be514..b858251a6b9 100644 --- a/source/blender/imbuf/intern/cineon/cineonlib.c +++ b/source/blender/imbuf/intern/cineon/cineonlib.c @@ -50,7 +50,8 @@ static int verbose = 0; -void cineonSetVerbose(int verbosity) { +void cineonSetVerbose(int verbosity) +{ verbose = verbosity; } diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c index 4c9b5e620dd..aeebf46a632 100644 --- a/source/blender/imbuf/intern/cineon/dpxlib.c +++ b/source/blender/imbuf/intern/cineon/dpxlib.c @@ -48,7 +48,8 @@ static int verbose = 0; -void dpxSetVerbose(int verbosity) { +void dpxSetVerbose(int verbosity) +{ verbose = verbosity; } diff --git a/source/blender/imbuf/intern/dds/SConscript b/source/blender/imbuf/intern/dds/SConscript index 475d21135aa..960e15f8e55 100644 --- a/source/blender/imbuf/intern/dds/SConscript +++ b/source/blender/imbuf/intern/dds/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') source_files = ['dds_api.cpp', 'DirectDrawSurface.cpp', 'Stream.cpp', 'BlockDXT.cpp', 'ColorBlock.cpp', 'Image.cpp', 'FlipDXT.cpp'] diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c index a185c4ee3e0..92b8dd8c724 100644 --- a/source/blender/imbuf/intern/imageprocess.c +++ b/source/blender/imbuf/intern/imageprocess.c @@ -219,7 +219,7 @@ void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, i /* function assumes out to be zero'ed, only does RGBA */ /* NEAREST INTERPOLATION */ -void neareast_interpolation_color(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v) +void nearest_interpolation_color(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v) { float *dataF; unsigned char *dataI; @@ -268,7 +268,7 @@ void neareast_interpolation_color(struct ImBuf *in, unsigned char outI[4], float } } -void neareast_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout) +void nearest_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout) { unsigned char *outI = NULL; float *outF = NULL; @@ -279,7 +279,7 @@ void neareast_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, i pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */ - neareast_interpolation_color(in, outI, outF, x, y); + nearest_interpolation_color(in, outI, outF, x, y); } /*********************** Threaded image processing *************************/ diff --git a/source/blender/imbuf/intern/openexr/SConscript b/source/blender/imbuf/intern/openexr/SConscript index a6c5ad984e2..ac38c0458d9 100644 --- a/source/blender/imbuf/intern/openexr/SConscript +++ b/source/blender/imbuf/intern/openexr/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') source_files = ['openexr_api.cpp'] diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 6f7bb5a723e..e28b8780250 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -46,7 +46,7 @@ typedef struct CustomDataLayer { int active_clone; /* number of the layer to render*/ int active_mask; /* number of the layer to render*/ int uid; /* shape keyblock unique id reference*/ - char name[64]; /* layer name, MAX_CUSTOMDATA_LAYER_AAME */ + char name[64]; /* layer name, MAX_CUSTOMDATA_LAYER_NAME */ void *data; /* layer data */ } CustomDataLayer; diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 3875a0d5799..089103c66e5 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -76,7 +76,8 @@ typedef enum ModifierType { eModifierType_Remesh = 41, eModifierType_Skin = 42, eModifierType_LaplacianSmooth = 43, - eModifierType_Triangulate = 44, + eModifierType_Triangulate = 44, + eModifierType_UVWarp = 45, NUM_MODIFIER_TYPES } ModifierType; @@ -586,7 +587,7 @@ typedef struct MeshDeformModifierData { /* runtime */ void (*bindfunc)(struct Scene *scene, struct MeshDeformModifierData *mmd, - float *vertexcos, int totvert, float cagemat[][4]); + float *vertexcos, int totvert, float cagemat[4][4]); } MeshDeformModifierData; typedef enum { @@ -1140,4 +1141,20 @@ typedef struct LaplacianSmoothModifierData { short flag, repeat; } LaplacianSmoothModifierData; -#endif +typedef struct UVWarpModifierData { + ModifierData modifier; + + char axis_u, axis_v; + char pad[6]; + float center[2]; /* used for rotate/scale */ + + struct Object *object_src; /* source */ + char bone_src[64]; /* optional name of bone target, MAX_ID_NAME-2 */ + struct Object *object_dst; /* target */ + char bone_dst[64]; /* optional name of bone target, MAX_ID_NAME-2 */ + + char vgroup_name[64]; /* optional vertexgroup name, MAX_VGROUP_NAME */ + char uvlayer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ +} UVWarpModifierData; + +#endif /* __DNA_MODIFIER_TYPES_H__ */ diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 5952aa8afb0..1cf16fb52b3 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -116,6 +116,9 @@ typedef struct ParticleData { float size; /* size and multiplier so that we can update size when ever */ + float sphdensity; /* density of sph particle */ + int pad; + int hair_index; short flag; short alive; /* the life state of a particle */ @@ -130,6 +133,8 @@ typedef struct SPHFluidSettings { float stiffness_k, stiffness_knear, rest_density; float buoyancy; int flag, spring_frames; + short solver; + short pad[3]; } SPHFluidSettings; /* fluid->flag */ @@ -141,6 +146,10 @@ typedef struct SPHFluidSettings { #define SPH_FAC_VISCOSITY 32 #define SPH_FAC_REST_LENGTH 64 +/* fluid->solver (numerical ID field, not bitfield) */ +#define SPH_SOLVER_DDR 0 +#define SPH_SOLVER_CLASSICAL 1 + typedef struct ParticleSettings { ID id; struct AnimData *adt; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 58ab4d0ea09..a2eb54bde99 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -495,7 +495,8 @@ typedef struct RenderData { /* Bake Render options */ short bake_osa, bake_filter, bake_mode, bake_flag; short bake_normal_space, bake_quad_split; - float bake_maxdist, bake_biasdist, bake_pad; + float bake_maxdist, bake_biasdist; + int bake_rays_number; /* path to render output */ char pic[1024]; /* 1024 = FILE_MAX */ @@ -643,7 +644,8 @@ typedef struct GameData { short physicsEngine; short exitkey, pad; short ticrate, maxlogicstep, physubstep, maxphystep; - short obstacleSimulation, pad1; + short obstacleSimulation; + short raster_storage; float levelHeight; float deactivationtime, lineardeactthreshold, angulardeactthreshold, pad2; } GameData; @@ -670,6 +672,12 @@ typedef struct GameData { #define OBSTSIMULATION_TOI_rays 1 #define OBSTSIMULATION_TOI_cells 2 +/* Raster storage */ +#define RAS_STORE_AUTO 0 +#define RAS_STORE_IMMEDIATE 1 +#define RAS_STORE_VA 2 +#define RAS_STORE_VBO 3 + /* GameData.flag */ #define GAME_RESTRICT_ANIM_UPDATES (1 << 0) #define GAME_ENABLE_ALL_FRAMES (1 << 1) @@ -953,7 +961,7 @@ typedef struct ToolSettings { short uvcalc_mapalign; short uvcalc_flag; short uv_flag, uv_selectmode; - short uv_subsurf_level; + short pad2; /* Grease Pencil */ short gpencil_flags; @@ -981,7 +989,7 @@ typedef struct ToolSettings { /* Multires */ char multires_subdiv_type; - char pad2[5]; + char pad3[5]; /* Skeleton generation */ short skgen_resolution; @@ -1206,6 +1214,7 @@ typedef struct Scene { /* seq_flag */ #define R_SEQ_GL_PREV 1 // #define R_SEQ_GL_REND 2 // UNUSED, opengl render has its own operator now. +#define R_SEQ_SOLID_TEX 4 /* displaymode */ diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index b1cd54950e6..de6ddb4b896 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -82,7 +82,8 @@ typedef struct bScreen { typedef struct ScrVert { struct ScrVert *next, *prev, *newv; vec2s vec; - int flag; + /* first one used internally, second one for tools */ + short flag, editflag; } ScrVert; typedef struct ScrEdge { @@ -159,7 +160,8 @@ typedef struct ARegion { short do_draw; /* private, cached notifier events */ short do_draw_overlay; /* private, cached notifier events */ short swap; /* private, indicator to survive swap-exchange */ - short pad[3]; + short overlap; /* private, set for indicate drawing overlapped */ + short pad[2]; struct ARegionType *type; /* callbacks for this region type */ @@ -167,6 +169,8 @@ typedef struct ARegion { ListBase panels; /* Panel */ ListBase handlers; /* wmEventHandler */ + struct wmTimer *regiontimer; /* blend in/out */ + char *headerstr; /* use this string to draw info */ void *regiondata; /* XXX 2.50, need spacedata equivalent? */ } ARegion; @@ -235,10 +239,6 @@ enum { #define RGN_ALIGN_VSPLIT 6 #define RGN_ALIGN_FLOAT 7 #define RGN_ALIGN_QSPLIT 8 -#define RGN_OVERLAP_TOP 9 -#define RGN_OVERLAP_BOTTOM 10 -#define RGN_OVERLAP_LEFT 11 -#define RGN_OVERLAP_RIGHT 12 #define RGN_SPLIT_PREV 32 diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 408dc17c6a0..1f665f2e0c0 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -495,7 +495,7 @@ typedef enum eSpaceSeq_Flag { SEQ_MARKER_TRANS = (1 << 1), SEQ_DRAW_COLOR_SEPARATED = (1 << 2), SEQ_DRAW_SAFE_MARGINS = (1 << 3), -/* SEQ_DRAW_GPENCIL = (1 << 4), */ /* DEPRECATED */ + SEQ_SHOW_GPENCIL = (1 << 4), SEQ_NO_DRAW_CFRANUM = (1 << 5), } eSpaceSeq_Flag; @@ -777,7 +777,7 @@ typedef enum eSpaceImage_Flag { SI_DRAW_TILE = (1 << 19), SI_SMOOTH_UV = (1 << 20), SI_DRAW_STRETCH = (1 << 21), -/* SI_DISPGP = (1 << 22), */ /* deprecated */ + SI_SHOW_GPENCIL = (1 << 22), SI_DRAW_OTHER = (1 << 23), SI_COLOR_CORRECTION = (1 << 24), @@ -798,7 +798,7 @@ typedef struct SpaceText { int top, viewlines; short flags, menunr; - short lheight; /* user preference */ + short lheight; /* user preference, is font_size! */ char cwidth, linenrs_tot; /* runtime computed, character width and the number of chars to use when showing line numbers */ int left; int showlinenrs; @@ -817,8 +817,9 @@ typedef struct SpaceText { char findstr[256]; /* ST_MAX_FIND_STR */ char replacestr[256]; /* ST_MAX_FIND_STR */ - short margin_column; /* column number to show right margin at */ - char pad[6]; + short margin_column; /* column number to show right margin at */ + short lheight_dpi; /* actual lineheight, dpi controlled */ + char pad[4]; void *drawcache; /* cache for faster drawing */ } SpaceText; @@ -887,7 +888,7 @@ typedef struct SpaceNode { struct ID *id, *from; /* context, no need to save in file? well... pinning... */ short flag, pad1; /* menunr: browse id block in header */ - float aspect, aspect_sqrt; + float aspect, pad2; /* internal state variables */ float xof, yof; /* offset for drawing the backdrop */ float zoom; /* zoom for backdrop */ @@ -907,7 +908,7 @@ typedef struct SpaceNode { /* snode->flag */ typedef enum eSpaceNode_Flag { SNODE_BACKDRAW = (1 << 1), -/* SNODE_DISPGP = (1 << 2), */ /* XXX: Grease Pencil - deprecated? */ + SNODE_SHOW_GPENCIL = (1 << 2), SNODE_USE_ALPHA = (1 << 3), SNODE_SHOW_ALPHA = (1 << 4), SNODE_SHOW_R = (1 << 7), @@ -1061,7 +1062,7 @@ typedef enum eSpaceClip_Flag { SC_SHOW_GRID = (1 << 9), SC_SHOW_STABLE = (1 << 10), SC_MANUAL_CALIBRATION = (1 << 11), -/* SC_SHOW_GPENCIL = (1 << 12),*/ /* UNUSED */ + SC_SHOW_GPENCIL = (1 << 12), SC_SHOW_FILTERS = (1 << 13), SC_SHOW_GRAPH_FRAMES = (1 << 14), SC_SHOW_GRAPH_TRACKS = (1 << 15), diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index 12819303b26..b258fbaa668 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -373,7 +373,7 @@ enum { /* MovieTrackingStrabilization->filter */ enum { - TRACKING_FILTER_NEAREAST = 0, + TRACKING_FILTER_NEAREST = 0, TRACKING_FILTER_BILINEAR = 1, TRACKING_FILTER_BICUBIC = 2 }; diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index b8bb7a5846d..2f082afb189 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -143,8 +143,10 @@ typedef struct uiWidgetStateColors { typedef struct uiPanelColors { char header[4]; + char back[4]; short show_header; - short pad; + short show_back; + int pad; } uiPanelColors; typedef struct ThemeUI { @@ -157,7 +159,7 @@ typedef struct ThemeUI { uiWidgetStateColors wcol_state; - uiPanelColors panel; + uiPanelColors panel; /* depricated, but we keep it for do_versions (2.66.1) */ char iconfile[256]; // FILE_MAXFILE length float icon_alpha; @@ -172,33 +174,36 @@ typedef struct ThemeUI { typedef struct ThemeSpace { /* main window colors */ char back[4]; - char title[4]; + char title[4]; /* panel title */ char text[4]; char text_hi[4]; /* header colors */ - char header[4]; - char header_title[4]; + char header[4]; /* region background */ + char header_title[4]; /* unused */ char header_text[4]; char header_text_hi[4]; /* button/tool regions */ - char button[4]; - char button_title[4]; + char button[4]; /* region background */ + char button_title[4]; /* panel title */ char button_text[4]; char button_text_hi[4]; /* listview regions */ - char list[4]; - char list_title[4]; + char list[4]; /* region background */ + char list_title[4]; /* panel title */ char list_text[4]; char list_text_hi[4]; /* float panel */ - char panel[4]; - char panel_title[4]; - char panel_text[4]; - char panel_text_hi[4]; +/* char panel[4]; unused */ +/* char panel_title[4]; unused */ +/* char panel_text[4]; unused */ +/* char panel_text_hi[4]; unused */ + + /* note, cannot use name 'panel' because of DNA mapping old files */ + uiPanelColors panelcolors; char shade1[4]; char shade2[4]; @@ -360,9 +365,10 @@ typedef struct UserDef { short versions; short dbl_click_time; - int gameflags; - int wheellinescroll; - int uiflag, language; + short gameflags; + short wheellinescroll; + int uiflag, uiflag2; + int language; short userpref, viewzoom; int mixbufsize; @@ -413,7 +419,7 @@ typedef struct UserDef { short scrcastfps; /* frame rate for screencast to be played back */ short scrcastwait; /* milliseconds between screencast snapshots */ - short widget_unit; /* defaults to 20 for 72 DPI setting */ + short widget_unit; /* private, defaults to 20 for 72 DPI setting */ short anisotropic_filter; short use_16bit_textures, use_gpu_mipmap; @@ -444,7 +450,7 @@ typedef struct UserDef { int compute_device_id; float fcu_inactive_alpha; /* opacity of inactive F-Curves in F-Curve Editor */ - float pad; + float pixelsize; /* private, set by GHOST, to multiply DPI with */ } UserDef; extern UserDef U; /* from blenkernel blender.c */ @@ -540,6 +546,12 @@ typedef enum eUserpref_UI_Flag { USER_HIDE_SYSTEM_BOOKMARKS = (1 << 31) } eUserpref_UI_Flag; +/* uiflag2 */ +typedef enum eUserpref_UI_Flag2 { + USER_KEEP_SESSION = (1 << 0), + USER_REGION_OVERLAP = (1 << 1) +} eUserpref_UI_Flag2; + /* Auto-Keying mode */ typedef enum eAutokey_Mode { /* AUTOKEY_ON is a bitflag */ diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index c83b0bc366f..dbe54a4fcdf 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -225,6 +225,7 @@ typedef struct View3D { #define V3D_DISPBGPICS 2 #define V3D_HIDE_HELPLINES 4 #define V3D_INVALID_BACKBUF 8 +#define V3D_INVALID_BACKBUF 8 #define V3D_ALIGN 1024 #define V3D_SELECT_OUTLINE 2048 @@ -261,7 +262,7 @@ typedef struct View3D { /* View3d->flag2 (short) */ #define V3D_RENDER_OVERRIDE 4 #define V3D_SOLID_TEX 8 -#define V3D_DISPGP 16 +#define V3D_SHOW_GPENCIL 16 #define V3D_LOCK_CAMERA 32 #define V3D_RENDER_SHADOW 64 /* This is a runtime only flag that's used to tell draw_mesh_object() that we're doing a shadow pass instead of a regular draw */ #define V3D_SHOW_RECONSTRUCTION 128 diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 2294abc0735..27aef3b8ec6 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -65,19 +65,21 @@ struct uiLayout; /* keep in sync with 'wm_report_items' in wm_rna.c */ typedef enum ReportType { - RPT_DEBUG = 1<<0, - RPT_INFO = 1<<1, - RPT_OPERATOR = 1<<2, - RPT_WARNING = 1<<3, - RPT_ERROR = 1<<4, - RPT_ERROR_INVALID_INPUT = 1<<5, - RPT_ERROR_INVALID_CONTEXT = 1<<6, - RPT_ERROR_OUT_OF_MEMORY = 1<<7 + RPT_DEBUG = 1 << 0, + RPT_INFO = 1 << 1, + RPT_OPERATOR = 1 << 2, + RPT_PROPERTY = 1 << 3, + RPT_WARNING = 1 << 4, + RPT_ERROR = 1 << 5, + RPT_ERROR_INVALID_INPUT = 1 << 6, + RPT_ERROR_INVALID_CONTEXT = 1 << 7, + RPT_ERROR_OUT_OF_MEMORY = 1 << 8 } ReportType; #define RPT_DEBUG_ALL (RPT_DEBUG) #define RPT_INFO_ALL (RPT_INFO) #define RPT_OPERATOR_ALL (RPT_OPERATOR) +#define RPT_PROPERTY_ALL (RPT_PROPERTY) #define RPT_WARNING_ALL (RPT_WARNING) #define RPT_ERROR_ALL (RPT_ERROR|RPT_ERROR_INVALID_INPUT|RPT_ERROR_INVALID_CONTEXT|RPT_ERROR_OUT_OF_MEMORY) diff --git a/source/blender/makesdna/SConscript b/source/blender/makesdna/SConscript index c3d39783b00..a6520a6c03e 100644 --- a/source/blender/makesdna/SConscript +++ b/source/blender/makesdna/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') objs = [] diff --git a/source/blender/makesdna/intern/SConscript b/source/blender/makesdna/intern/SConscript index c1e6eb5281d..add9611866d 100644 --- a/source/blender/makesdna/intern/SConscript +++ b/source/blender/makesdna/intern/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 sys import os diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index de91c17553e..12df9def368 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -210,7 +210,7 @@ static int calculate_structlens(int); /** * Construct the DNA.c file */ -void dna_write(FILE *file, void *pntr, int size); +static void dna_write(FILE *file, const void *pntr, const int size); /** * Report all structures found so far, and print their lengths. @@ -894,7 +894,7 @@ static int calculate_structlens(int firststruct) #define MAX_DNA_LINE_LENGTH 20 -void dna_write(FILE *file, void *pntr, int size) +static void dna_write(FILE *file, const void *pntr, const int size) { static int linelength = 0; int i; @@ -936,7 +936,7 @@ void printStructLengths(void) } -static int make_structDNA(char *baseDirectory, FILE *file) +static int make_structDNA(const char *baseDirectory, FILE *file) { int len, i; short *sp; @@ -986,7 +986,7 @@ static int make_structDNA(char *baseDirectory, FILE *file) /* little test first... */ /* Mind the breaking condition here! */ if (debugSDNA) printf("\tStart of header scan:\n"); - for (i = 0; strlen(includefiles[i]); i++) { + for (i = 0; *(includefiles[i]) != '\0'; i++) { sprintf(str, "%s%s", baseDirectory, includefiles[i]); if (debugSDNA) printf("\t|-- Converting %s\n", str); if (convert_include(str)) { @@ -1038,12 +1038,10 @@ static int make_structDNA(char *baseDirectory, FILE *file) /* pass */ } else { - strcpy(str, "SDNA"); - dna_write(file, str, 4); + dna_write(file, "SDNA", 4); /* write names */ - strcpy(str, "NAME"); - dna_write(file, str, 4); + dna_write(file, "NAME", 4); len = nr_names; dna_write(file, &len, 4); @@ -1055,8 +1053,7 @@ static int make_structDNA(char *baseDirectory, FILE *file) dna_write(file, names[0], len); /* write TYPES */ - strcpy(str, "TYPE"); - dna_write(file, str, 4); + dna_write(file, "TYPE", 4); len = nr_types; dna_write(file, &len, 4); @@ -1069,16 +1066,14 @@ static int make_structDNA(char *baseDirectory, FILE *file) dna_write(file, types[0], len); /* WRITE TYPELENGTHS */ - strcpy(str, "TLEN"); - dna_write(file, str, 4); + dna_write(file, "TLEN", 4); len = 2 * nr_types; if (nr_types & 1) len += 2; dna_write(file, typelens_native, len); /* WRITE STRUCTS */ - strcpy(str, "STRC"); - dna_write(file, str, 4); + dna_write(file, "STRC", 4); len = nr_structs; dna_write(file, &len, 4); @@ -1102,7 +1097,7 @@ static int make_structDNA(char *baseDirectory, FILE *file) else { /* add all include files defined in the global array */ - for (i = 0; strlen(includefiles[i]); i++) { + for (i = 0; *(includefiles[i]) != '\0'; i++) { fprintf(fp, "#include \"%s%s\"\n", baseDirectory, includefiles[i]); } @@ -1167,13 +1162,13 @@ int main(int argc, char **argv) return_status = 1; } else { - char baseDirectory[256]; + const char *baseDirectory; if (argc == 3) { - strcpy(baseDirectory, argv[2]); + baseDirectory = argv[2]; } else { - strcpy(baseDirectory, BASE_HEADER); + baseDirectory = BASE_HEADER; } fprintf(file, "const unsigned char DNAstr[] = {\n"); diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index e22bffd7db7..ad4ea0161f0 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -622,6 +622,7 @@ extern StructRNA RNA_TransformConstraint; extern StructRNA RNA_TransformSequence; extern StructRNA RNA_UILayout; extern StructRNA RNA_UIListItem; +extern StructRNA RNA_UVWarpModifier; extern StructRNA RNA_UVProjectModifier; extern StructRNA RNA_UVProjector; extern StructRNA RNA_UnitSettings; @@ -897,7 +898,12 @@ int RNA_path_resolve_full(PointerRNA *ptr, const char *path, char *RNA_path_from_ID_to_struct(PointerRNA *ptr); char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop); -char *RNA_path_from_ID_python(struct ID *id); + +char *RNA_path_full_ID_py(struct ID *id); +char *RNA_path_full_struct_py(struct PointerRNA *ptr); +char *RNA_path_full_property_py(struct PointerRNA *ptr, struct PropertyRNA *prop, int index); +char *RNA_path_struct_property_py(struct PointerRNA *ptr, struct PropertyRNA *prop, int index); +char *RNA_path_property_py(struct PointerRNA *ptr, struct PropertyRNA *prop, int index); /* Quick name based property access * @@ -1005,8 +1011,8 @@ int RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier); int RNA_property_is_idprop(PropertyRNA *prop); /* python compatible string representation of this property, (must be freed!) */ -char *RNA_property_as_string(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop); -char *RNA_pointer_as_string(struct bContext *C, PointerRNA *ptr); +char *RNA_property_as_string(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index); +char *RNA_pointer_as_string(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop_ptr, PointerRNA *ptr_prop); char *RNA_pointer_as_string_keywords_ex(struct bContext *C, PointerRNA *ptr, PointerRNA *ptr_default, const short skip_optional_value, const short all_args, PropertyRNA *iterprop); diff --git a/source/blender/makesrna/SConscript b/source/blender/makesrna/SConscript index 5379de52ca8..b012f6c96a2 100644 --- a/source/blender/makesrna/SConscript +++ b/source/blender/makesrna/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') objs = [] diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript index d26de50fae0..5d60d416cc4 100644 --- a/source/blender/makesrna/intern/SConscript +++ b/source/blender/makesrna/intern/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 sys import os diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 075dc959173..333cdeabfa4 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -91,7 +91,7 @@ static void rna_generate_static_parameter_prototypes(FILE *f, StructRNA *srna, F { \ WRITE_COMMA; \ fprintf(f, param); \ - } + } (void)0 static int replace_if_different(char *tmpfile, const char *dep_files[]) { @@ -760,7 +760,7 @@ static void rna_clamp_value(FILE *f, PropertyRNA *prop, int array) if (prop->type == PROP_INT) { IntPropertyRNA *iprop = (IntPropertyRNA *)prop; - if (iprop->hardmin != INT_MIN || iprop->hardmax != INT_MAX) { + if (iprop->hardmin != INT_MIN || iprop->hardmax != INT_MAX || iprop->range) { if (array) fprintf(f, "CLAMPIS(values[i], "); else fprintf(f, "CLAMPIS(value, "); if (iprop->range) { @@ -776,7 +776,7 @@ static void rna_clamp_value(FILE *f, PropertyRNA *prop, int array) else if (prop->type == PROP_FLOAT) { FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop; - if (fprop->hardmin != -FLT_MAX || fprop->hardmax != FLT_MAX) { + if (fprop->hardmin != -FLT_MAX || fprop->hardmax != FLT_MAX || fprop->range) { if (array) fprintf(f, "CLAMPIS(values[i], "); else fprintf(f, "CLAMPIS(value, "); if (fprop->range) { diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 488dbffc3db..23e0fa663b9 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -1197,11 +1197,16 @@ void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA RNA_property_enum_items(C, ptr, prop, item, totitem, free); #ifdef WITH_INTERNATIONAL - /* Note: keep directly using BLF_gettext here, has we have already done tests like BLF_translate_iface... */ - if (BLF_translate_iface()) { + { int i; + /* Note: Only do those tests once, and then use BLF_pgettext. */ + int do_iface = BLF_translate_iface(); + int do_tooltip = BLF_translate_tooltips(); EnumPropertyItem *nitem; + if (!(do_iface || do_tooltip)) + return; + if (*free) { nitem = *item; } @@ -1217,18 +1222,17 @@ void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA for (i = 0; (*item)[i].identifier; i++) nitem[i] = (*item)[i]; - *free = 1; + *free = TRUE; } for (i = 0; nitem[i].identifier; i++) { - if (nitem[i].name) { - if (prop->translation_context) - nitem[i].name = BLF_pgettext(prop->translation_context, nitem[i].name); - else - nitem[i].name = BLF_pgettext(NULL, nitem[i].name); + if (nitem[i].name && do_iface) { + /* note: prop->translation_context may be NULL, this just means we use the default "" context */ + nitem[i].name = BLF_pgettext(prop->translation_context, nitem[i].name); } - if (nitem[i].description) + if (nitem[i].description && do_tooltip) { nitem[i].description = BLF_pgettext(NULL, nitem[i].description); + } } *item = nitem; @@ -4168,7 +4172,7 @@ char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop) * Get the ID as a python representation, eg: * bpy.data.foo["bar"] */ -char *RNA_path_from_ID_python(ID *id) +char *RNA_path_full_ID_py(ID *id) { char id_esc[(sizeof(id->name) - 2) * 2]; @@ -4177,6 +4181,112 @@ char *RNA_path_from_ID_python(ID *id) return BLI_sprintfN("bpy.data.%s[\"%s\"]", BKE_idcode_to_name_plural(GS(id->name)), id_esc); } +/** + * Get the ID.struct as a python representation, eg: + * bpy.data.foo["bar"].some_struct + */ +char *RNA_path_full_struct_py(struct PointerRNA *ptr) +{ + char *id_path; + char *data_path; + + char *ret; + + if (!ptr->id.data) { + return NULL; + } + + /* never fails */ + id_path = RNA_path_full_ID_py(ptr->id.data); + + data_path = RNA_path_from_ID_to_struct(ptr); + + ret = BLI_sprintfN("%s.%s", + id_path, data_path); + + return ret; +} + +/** + * Get the ID.struct.property as a python representation, eg: + * bpy.data.foo["bar"].some_struct.some_prop[10] + */ +char *RNA_path_full_property_py(PointerRNA *ptr, PropertyRNA *prop, int index) +{ + char *id_path; + char *data_path; + + char *ret; + + if (!ptr->id.data) { + return NULL; + } + + /* never fails */ + id_path = RNA_path_full_ID_py(ptr->id.data); + + data_path = RNA_path_from_ID_to_property(ptr, prop); + + if ((index == -1) || (RNA_property_array_check(prop) == FALSE)) { + ret = BLI_sprintfN("%s.%s", + id_path, data_path); + } + else { + ret = BLI_sprintfN("%s.%s[%d]", + id_path, data_path, index); + } + + return ret; +} + +/** + * Get the struct.property as a python representation, eg: + * some_struct.some_prop[10] + */ +char *RNA_path_struct_property_py(PointerRNA *ptr, PropertyRNA *prop, int index) +{ + char *data_path; + + char *ret; + + if (!ptr->id.data) { + return NULL; + } + + data_path = RNA_path_from_ID_to_property(ptr, prop); + + if ((index == -1) || (RNA_property_array_check(prop) == FALSE)) { + ret = BLI_sprintfN("%s", + data_path); + } + else { + ret = BLI_sprintfN("%s[%d]", + data_path, index); + } + + return ret; +} + +/** + * Get the struct.property as a python representation, eg: + * some_prop[10] + */ +char *RNA_path_property_py(PointerRNA *UNUSED(ptr), PropertyRNA *prop, int index) +{ + char *ret; + + if ((index == -1) || (RNA_property_array_check(prop) == FALSE)) { + ret = BLI_sprintfN("%s", + RNA_property_identifier(prop)); + } + else { + ret = BLI_sprintfN("%s[%d]", + RNA_property_identifier(prop), index); + } + + return ret; +} + /* Quick name based property access */ int RNA_boolean_get(PointerRNA *ptr, const char *name) @@ -4606,7 +4716,7 @@ int RNA_property_is_idprop(PropertyRNA *prop) /* string representation of a property, python * compatible but can be used for display too, * context may be NULL */ -char *RNA_pointer_as_string(bContext *C, PointerRNA *ptr) +static char *rna_pointer_as_string__idprop(bContext *C, PointerRNA *ptr) { DynStr *dynstr = BLI_dynstr_new(); char *cstring; @@ -4627,7 +4737,7 @@ char *RNA_pointer_as_string(bContext *C, PointerRNA *ptr) BLI_dynstr_append(dynstr, ", "); first_time = 0; - cstring = RNA_property_as_string(C, ptr, prop); + cstring = RNA_property_as_string(C, ptr, prop, -1); BLI_dynstr_appendf(dynstr, "\"%s\":%s", propname, cstring); MEM_freeN(cstring); } @@ -4641,6 +4751,25 @@ char *RNA_pointer_as_string(bContext *C, PointerRNA *ptr) return cstring; } +static char *rna_pointer_as_string__bldata(PointerRNA *ptr) +{ + if (RNA_struct_is_ID(ptr->type)) { + return RNA_path_full_ID_py(ptr->id.data); + } + else { + return RNA_path_full_struct_py(ptr); + } +} + +char *RNA_pointer_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop_ptr, PointerRNA *ptr_prop) +{ + if (RNA_property_flag(prop_ptr) & PROP_IDPROPERTY) { + return rna_pointer_as_string__idprop(C, ptr_prop); + } + else { + return rna_pointer_as_string__bldata(ptr_prop); + } +} /* context and ptr_default can be NULL */ char *RNA_pointer_as_string_keywords_ex(bContext *C, PointerRNA *ptr, PointerRNA *ptr_default, @@ -4693,7 +4822,7 @@ char *RNA_pointer_as_string_keywords_ex(bContext *C, PointerRNA *ptr, PointerRNA } } else { - buf = RNA_property_as_string(C, ptr, prop); + buf = RNA_property_as_string(C, ptr, prop, -1); } ok = TRUE; @@ -4704,7 +4833,7 @@ char *RNA_pointer_as_string_keywords_ex(bContext *C, PointerRNA *ptr, PointerRNA prop_default = RNA_struct_find_property(ptr_default, arg_name); if (prop_default) { - buf_default = RNA_property_as_string(C, ptr_default, prop_default); + buf_default = RNA_property_as_string(C, ptr_default, prop_default, -1); if (strcmp(buf, buf_default) == 0) ok = FALSE; /* values match, don't bother printing */ @@ -4754,7 +4883,12 @@ char *RNA_function_as_string_keywords(bContext *C, FunctionRNA *func, PointerRNA iterprop); } -char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop) +static const char *bool_as_py_string(const int var) +{ + return var ? "True" : "False"; +} + +char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index) { int type = RNA_property_type(prop); int len = RNA_property_array_length(ptr, prop); @@ -4768,17 +4902,22 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop) switch (type) { case PROP_BOOLEAN: if (len == 0) { - BLI_dynstr_append(dynstr, RNA_property_boolean_get(ptr, prop) ? "True" : "False"); + BLI_dynstr_append(dynstr, bool_as_py_string(RNA_property_boolean_get(ptr, prop))); } else { - BLI_dynstr_append(dynstr, "("); - for (i = 0; i < len; i++) { - BLI_dynstr_appendf(dynstr, i ? ", %s" : "%s", - RNA_property_boolean_get_index(ptr, prop, i) ? "True" : "False"); + if (index != -1) { + BLI_dynstr_append(dynstr, bool_as_py_string(RNA_property_boolean_get_index(ptr, prop, index))); + } + else { + BLI_dynstr_append(dynstr, "("); + for (i = 0; i < len; i++) { + BLI_dynstr_appendf(dynstr, i ? ", %s" : "%s", + bool_as_py_string(RNA_property_boolean_get_index(ptr, prop, i))); + } + if (len == 1) + BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */ + BLI_dynstr_append(dynstr, ")"); } - if (len == 1) - BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */ - BLI_dynstr_append(dynstr, ")"); } break; case PROP_INT: @@ -4786,13 +4925,18 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop) BLI_dynstr_appendf(dynstr, "%d", RNA_property_int_get(ptr, prop)); } else { - BLI_dynstr_append(dynstr, "("); - for (i = 0; i < len; i++) { - BLI_dynstr_appendf(dynstr, i ? ", %d" : "%d", RNA_property_int_get_index(ptr, prop, i)); + if (index != -1) { + BLI_dynstr_appendf(dynstr, "%d", RNA_property_int_get_index(ptr, prop, index)); + } + else { + BLI_dynstr_append(dynstr, "("); + for (i = 0; i < len; i++) { + BLI_dynstr_appendf(dynstr, i ? ", %d" : "%d", RNA_property_int_get_index(ptr, prop, i)); + } + if (len == 1) + BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */ + BLI_dynstr_append(dynstr, ")"); } - if (len == 1) - BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */ - BLI_dynstr_append(dynstr, ")"); } break; case PROP_FLOAT: @@ -4800,13 +4944,18 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop) BLI_dynstr_appendf(dynstr, "%g", RNA_property_float_get(ptr, prop)); } else { - BLI_dynstr_append(dynstr, "("); - for (i = 0; i < len; i++) { - BLI_dynstr_appendf(dynstr, i ? ", %g" : "%g", RNA_property_float_get_index(ptr, prop, i)); + if (index != -1) { + BLI_dynstr_appendf(dynstr, "%g", RNA_property_float_get_index(ptr, prop, index)); + } + else { + BLI_dynstr_append(dynstr, "("); + for (i = 0; i < len; i++) { + BLI_dynstr_appendf(dynstr, i ? ", %g" : "%g", RNA_property_float_get_index(ptr, prop, i)); + } + if (len == 1) + BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */ + BLI_dynstr_append(dynstr, ")"); } - if (len == 1) - BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */ - BLI_dynstr_append(dynstr, ")"); } break; case PROP_STRING: @@ -4872,7 +5021,7 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop) case PROP_POINTER: { PointerRNA tptr = RNA_property_pointer_get(ptr, prop); - cstring = RNA_pointer_as_string(C, &tptr); + cstring = RNA_pointer_as_string(C, ptr, prop, &tptr); BLI_dynstr_append(dynstr, cstring); MEM_freeN(cstring); break; @@ -4893,7 +5042,7 @@ char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop) first_time = 0; /* now get every prop of the collection */ - cstring = RNA_pointer_as_string(C, &itemptr); + cstring = RNA_pointer_as_string(C, ptr, prop, &itemptr); BLI_dynstr_append(dynstr, cstring); MEM_freeN(cstring); } diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c index 92c8c9d0cea..85af3073945 100644 --- a/source/blender/makesrna/intern/rna_action.c +++ b/source/blender/makesrna/intern/rna_action.c @@ -602,7 +602,7 @@ static void rna_def_action_pose_markers(BlenderRNA *brna, PropertyRNA *cprop) "rna_Action_active_pose_marker_set", NULL, NULL); RNA_def_property_ui_text(prop, "Active Pose Marker", "Active pose marker for this action"); - prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE); + prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "active_marker"); RNA_def_property_int_funcs(prop, "rna_Action_active_pose_marker_index_get", "rna_Action_active_pose_marker_index_set", "rna_Action_active_pose_marker_index_range"); diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c index b9e86e116a2..69de86da007 100644 --- a/source/blender/makesrna/intern/rna_cloth.c +++ b/source/blender/makesrna/intern/rna_cloth.c @@ -403,8 +403,8 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "pre_roll", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "preroll"); - RNA_def_property_range(prop, 0, 200); - RNA_def_property_ui_text(prop, "Pre Roll", "Simulation starts on this frame"); + RNA_def_property_range(prop, 0, MAXFRAME); + RNA_def_property_ui_text(prop, "Pre Roll", "Start simulation a number of frames earlier to let the cloth settle in"); RNA_def_property_update(prop, 0, "rna_cloth_reset"); prop = RNA_def_property(srna, "rest_shape_key", PROP_POINTER, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index d78e4ecc0f5..48db12ce14e 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -119,9 +119,9 @@ static void rna_Main_cameras_remove(Main *bmain, ReportList *reports, PointerRNA } } -static Scene *rna_Main_scenes_new(Main *UNUSED(bmain), const char *name) +static Scene *rna_Main_scenes_new(Main *bmain, const char *name) { - return BKE_scene_add(name); + return BKE_scene_add(bmain, name); } static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports, PointerRNA *scene_ptr) { diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index d939b1073fc..bc67bf2da35 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -2368,7 +2368,7 @@ static void rna_def_tessface_vertex_colors(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_flag(parm, PROP_RNAPTR); RNA_def_function_return(func, parm); - prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED); + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MeshColorLayer"); RNA_def_property_pointer_funcs(prop, "rna_Mesh_tessface_vertex_color_active_get", "rna_Mesh_tessface_vertex_color_active_set", NULL, NULL); @@ -2412,7 +2412,7 @@ static void rna_def_loop_colors(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); #endif - prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED); + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MeshLoopColorLayer"); RNA_def_property_pointer_funcs(prop, "rna_Mesh_vertex_color_active_get", "rna_Mesh_vertex_color_active_set", NULL, NULL); @@ -2440,7 +2440,7 @@ static void rna_def_uv_layers(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_struct_sdna(srna, "Mesh"); RNA_def_struct_ui_text(srna, "UV Loop Layers", "Collection of uv loop layers"); - prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED); + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MeshUVLoopLayer"); RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_layer_active_get", "rna_Mesh_uv_layer_active_set", NULL, NULL); @@ -2545,7 +2545,7 @@ static void rna_def_tessface_uv_textures(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_return(func, parm); - prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED); + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MeshTextureFaceLayer"); RNA_def_property_pointer_funcs(prop, "rna_Mesh_tessface_uv_texture_active_get", "rna_Mesh_tessface_uv_texture_active_set", NULL, NULL); @@ -2590,7 +2590,7 @@ static void rna_def_uv_textures(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); #endif - prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED); + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MeshTexturePolyLayer"); RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_texture_active_get", "rna_Mesh_uv_texture_active_set", NULL, NULL); @@ -2708,7 +2708,7 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_ui_text(prop, "UV Loop Layers", "All UV loop layers"); rna_def_uv_layers(brna, prop); - prop = RNA_def_property(srna, "uv_layer_clone", PROP_POINTER, PROP_UNSIGNED); + prop = RNA_def_property(srna, "uv_layer_clone", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MeshUVLoopLayer"); RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_layer_clone_get", "rna_Mesh_uv_layer_clone_set", NULL, NULL); @@ -2720,7 +2720,7 @@ static void rna_def_mesh(BlenderRNA *brna) "rna_Mesh_uv_layer_clone_index_set", "rna_Mesh_uv_layer_index_range"); RNA_def_property_ui_text(prop, "Clone UV loop layer Index", "Clone UV loop layer index"); - prop = RNA_def_property(srna, "uv_layer_stencil", PROP_POINTER, PROP_UNSIGNED); + prop = RNA_def_property(srna, "uv_layer_stencil", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MeshUVLoopLayer"); RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_layer_stencil_get", "rna_Mesh_uv_layer_stencil_set", NULL, NULL); @@ -2751,7 +2751,7 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_ui_text(prop, "UV Maps", "All UV maps"); rna_def_uv_textures(brna, prop); - prop = RNA_def_property(srna, "uv_texture_clone", PROP_POINTER, PROP_UNSIGNED); + prop = RNA_def_property(srna, "uv_texture_clone", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MeshTexturePolyLayer"); RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_texture_clone_get", "rna_Mesh_uv_texture_clone_set", NULL, NULL); @@ -2763,7 +2763,7 @@ static void rna_def_mesh(BlenderRNA *brna) "rna_Mesh_uv_texture_clone_index_set", "rna_Mesh_uv_texture_index_range"); RNA_def_property_ui_text(prop, "Clone UV Map Index", "Clone UV map index"); - prop = RNA_def_property(srna, "uv_texture_stencil", PROP_POINTER, PROP_UNSIGNED); + prop = RNA_def_property(srna, "uv_texture_stencil", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "MeshTexturePolyLayer"); RNA_def_property_pointer_funcs(prop, "rna_Mesh_uv_texture_stencil_get", "rna_Mesh_uv_texture_stencil_set", NULL, NULL); diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index a2b0945fb46..e1489d821a0 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -59,6 +59,7 @@ EnumPropertyItem modifier_type_items[] = { {0, "", 0, N_("Modify"), ""}, {eModifierType_UVProject, "UV_PROJECT", ICON_MOD_UVPROJECT, "UV Project", ""}, + {eModifierType_UVWarp, "UV_WARP", ICON_MOD_UVPROJECT, "UV Warp", ""}, {eModifierType_WeightVGEdit, "VERTEX_WEIGHT_EDIT", ICON_MOD_VERTEX_WEIGHT, "Vertex Weight Edit", ""}, {eModifierType_WeightVGMix, "VERTEX_WEIGHT_MIX", ICON_MOD_VERTEX_WEIGHT, "Vertex Weight Mix", ""}, {eModifierType_WeightVGProximity, "VERTEX_WEIGHT_PROXIMITY", ICON_MOD_VERTEX_WEIGHT, @@ -129,7 +130,7 @@ static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr) { ModifierData *md = (ModifierData *)ptr->data; - switch (md->type) { + switch ((ModifierType)md->type) { case eModifierType_Subsurf: return &RNA_SubsurfModifier; case eModifierType_Lattice: @@ -216,9 +217,16 @@ static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr) return &RNA_LaplacianSmoothModifier; case eModifierType_Triangulate: return &RNA_TriangulateModifier; - default: + case eModifierType_UVWarp: + return &RNA_UVWarpModifier; + /* Default */ + case eModifierType_None: + case eModifierType_ShapeKey: + case NUM_MODIFIER_TYPES: return &RNA_Modifier; } + + return &RNA_Modifier; } static void rna_Modifier_name_set(PointerRNA *ptr, const char *value) @@ -738,6 +746,18 @@ static void rna_BevelModifier_angle_limit_set(PointerRNA *ptr, float value) md->bevel_angle = (int)value; } +static void rna_UVWarpModifier_vgroup_set(PointerRNA *ptr, const char *value) +{ + UVWarpModifierData *umd = (UVWarpModifierData*)ptr->data; + rna_object_vgroup_name_set(ptr, value, umd->vgroup_name, sizeof(umd->vgroup_name)); +} + +static void rna_UVWarpModifier_uvlayer_set(PointerRNA *ptr, const char *value) +{ + UVWarpModifierData *umd = (UVWarpModifierData*)ptr->data; + rna_object_uvlayer_name_set(ptr, value, umd->uvlayer_name, sizeof(umd->uvlayer_name)); +} + #else static PropertyRNA *rna_def_property_subdivision_common(StructRNA *srna, const char type[]) @@ -2773,6 +2793,75 @@ static void rna_def_modifier_screw(BlenderRNA *brna) #endif } +static void rna_def_modifier_uvwarp(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem uvwarp_axis[] = { + {0, "X", 0, "X", ""}, + {1, "Y", 0, "Y", ""}, + {2, "Z", 0, "Z", ""}, + {0, NULL, 0, NULL, NULL} + }; + + srna = RNA_def_struct(brna, "UVWarpModifier", "Modifier"); + RNA_def_struct_ui_text(srna, "UVWarp Modifier", "Add target position to uv coordinates"); + RNA_def_struct_sdna(srna, "UVWarpModifierData"); + RNA_def_struct_ui_icon(srna, ICON_MOD_UVPROJECT); + + prop = RNA_def_property(srna, "axis_u", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "axis_u"); + RNA_def_property_enum_items(prop, uvwarp_axis); + RNA_def_property_ui_text(prop, "U-Axis", "Pole axis for rotation"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "axis_v", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "axis_v"); + RNA_def_property_enum_items(prop, uvwarp_axis); + RNA_def_property_ui_text(prop, "V-Axis", "Pole axis for rotation"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "center", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "center"); + RNA_def_property_ui_text(prop, "UV Center", "Center point for rotate/scale"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "object_from", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "object_src"); + RNA_def_property_ui_text(prop, "Target", "Object defining offset"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); + + prop = RNA_def_property(srna, "bone_from", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "bone_src"); + RNA_def_property_ui_text(prop, "Sub-Target", "Bone defining offset"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); + + prop = RNA_def_property(srna, "object_to", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "object_dst"); + RNA_def_property_ui_text(prop, "Target", "Object defining offset"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); + + prop = RNA_def_property(srna, "bone_to", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "bone_dst"); + RNA_def_property_ui_text(prop, "Sub-Target", "Bone defining offset"); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); + + prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "vgroup_name"); + RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_UVWarpModifier_vgroup_set"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "uvlayer_name"); + RNA_def_property_ui_text(prop, "UV Layer", "UV Layer name"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_UVWarpModifier_uvlayer_set"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); +} + static void rna_def_modifier_weightvg_mask(BlenderRNA *UNUSED(brna), StructRNA *srna) { static EnumPropertyItem weightvg_mask_tex_map_items[] = { @@ -3480,6 +3569,7 @@ void RNA_def_modifier(BlenderRNA *brna) rna_def_modifier_smoke(brna); rna_def_modifier_solidify(brna); rna_def_modifier_screw(brna); + rna_def_modifier_uvwarp(brna); rna_def_modifier_weightvgedit(brna); rna_def_modifier_weightvgmix(brna); rna_def_modifier_weightvgproximity(brna); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 1da9a450c2c..93ce3b8dc07 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -271,6 +271,24 @@ static char *rna_Node_path(PointerRNA *ptr) return BLI_sprintfN("nodes[\"%s\"]", node->name); } +/* define a get_type function for each node type */ +#define DEF_NODE_GET_NODE_TYPE(name, enum_name) \ +static const char *rna_##name##_get_node_type() \ +{ \ + return enum_name; \ +} + +#define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \ +DEF_NODE_GET_NODE_TYPE(Category##StructName, EnumName) + +#include "rna_nodetree_types.h" + +/* some nodes not included in rna_nodetree_types.h */ +DEF_NODE_GET_NODE_TYPE(NodeGroup, "GROUP") +DEF_NODE_GET_NODE_TYPE(NodeFrame, "FRAME") +DEF_NODE_GET_NODE_TYPE(NodeReroute, "REROUTE") + + static StructRNA *rna_NodeSocket_refine(PointerRNA *ptr) { bNodeSocket *sock = (bNodeSocket *)ptr->data; @@ -499,6 +517,20 @@ static void rna_Node_name_set(PointerRNA *ptr, const char *value) BKE_all_animdata_fix_paths_rename(NULL, "nodes", oldname, node->name); } +static void rna_Node_width_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax) +{ + bNode *node = ptr->data; + *min = *softmin = node->typeinfo->minwidth; + *max = *softmax = node->typeinfo->maxwidth; +} + +static void rna_Node_height_range(PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax) +{ + bNode *node = ptr->data; + *min = *softmin = node->typeinfo->minheight; + *max = *softmax = node->typeinfo->maxheight; +} + static void rna_NodeSocket_update(Main *bmain, Scene *scene, PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree *)ptr->id.data; @@ -4609,6 +4641,24 @@ static void rna_def_node(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Location", ""); RNA_def_property_update(prop, NC_NODE, "rna_Node_update"); + prop = RNA_def_property(srna, "width", PROP_FLOAT, PROP_XYZ); + RNA_def_property_float_sdna(prop, NULL, "width"); + RNA_def_property_float_funcs(prop, NULL, NULL, "rna_Node_width_range"); + RNA_def_property_ui_text(prop, "Width", "Width of the node"); + RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL); + + prop = RNA_def_property(srna, "width_hidden", PROP_FLOAT, PROP_XYZ); + RNA_def_property_float_sdna(prop, NULL, "miniwidth"); + RNA_def_property_float_funcs(prop, NULL, NULL, "rna_Node_width_range"); + RNA_def_property_ui_text(prop, "Width Hidden", "Width of the node in hidden state"); + RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL); + + prop = RNA_def_property(srna, "height", PROP_FLOAT, PROP_XYZ); + RNA_def_property_float_sdna(prop, NULL, "height"); + RNA_def_property_float_funcs(prop, NULL, NULL, "rna_Node_height_range"); + RNA_def_property_ui_text(prop, "Height", "Height of the node"); + RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL); + prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Name", "Unique node identifier"); RNA_def_struct_name_property(srna, prop); @@ -4874,12 +4924,20 @@ static void rna_def_texture_nodetree(BlenderRNA *brna) rna_def_texture_nodetree_api(brna, prop); } -static void define_specific_node(BlenderRNA *brna, int id, void (*func)(StructRNA *)) +static void define_specific_node(BlenderRNA *brna, int id, void (*def_func)(StructRNA *), const char *get_node_type_func) { StructRNA *srna = def_node(brna, id); - - if (func) - func(srna); + FunctionRNA *func; + PropertyRNA *parm; + + if (def_func) + def_func(srna); + + func = RNA_def_function(srna, "get_node_type", get_node_type_func); + RNA_def_function_ui_description(func, "Get the identifier of the node type"); + RNA_def_function_flag(func, FUNC_NO_SELF); + parm = RNA_def_string(func, "result", "", 0, "Result", ""); + RNA_def_function_return(func, parm); } void RNA_def_nodetree(BlenderRNA *brna) @@ -4910,13 +4968,13 @@ void RNA_def_nodetree(BlenderRNA *brna) rna_def_shader_nodetree(brna); rna_def_texture_nodetree(brna); #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \ - define_specific_node(brna, ID, DefFunc); + define_specific_node(brna, ID, DefFunc, "rna_" STRINGIFY_ARG(Category##StructName) "_get_node_type"); #include "rna_nodetree_types.h" - define_specific_node(brna, NODE_GROUP, def_group); - define_specific_node(brna, NODE_FRAME, def_frame); - define_specific_node(brna, NODE_REROUTE, 0); + define_specific_node(brna, NODE_GROUP, def_group, "rna_NodeGroup_get_node_type"); + define_specific_node(brna, NODE_FRAME, def_frame, "rna_NodeFrame_get_node_type"); + define_specific_node(brna, NODE_REROUTE, 0, "rna_NodeReroute_get_node_type"); /* special socket types */ rna_def_cmp_output_file_slot_file(brna); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 1d08ea97b79..b218cc6a944 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -94,6 +94,7 @@ static EnumPropertyItem parent_type_items[] = { {0, NULL, 0, NULL, NULL} }; +#ifndef RNA_RUNTIME static EnumPropertyItem dupli_items[] = { {0, "NONE", 0, "None", ""}, {OB_DUPLIFRAMES, "FRAMES", 0, "Frames", "Make copy of object for every frame"}, @@ -102,6 +103,7 @@ static EnumPropertyItem dupli_items[] = { {OB_DUPLIGROUP, "GROUP", 0, "Group", "Enable group instancing"}, {0, NULL, 0, NULL, NULL} }; +#endif static EnumPropertyItem collision_bounds_items[] = { {OB_BOUND_BOX, "BOX", 0, "Box", ""}, @@ -1961,7 +1963,7 @@ static void rna_def_object_vertex_groups(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_ui_text(prop, "Active Vertex Group", "Vertex groups of the object"); RNA_def_property_update(prop, NC_GEOM | ND_DATA, "rna_Object_internal_update_data"); - prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE); + prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_int_sdna(prop, NULL, "actdef"); RNA_def_property_int_funcs(prop, "rna_Object_active_vertex_group_index_get", @@ -2080,6 +2082,7 @@ static void rna_def_object(BlenderRNA *brna) RNA_def_property_boolean_funcs(prop, NULL, "rna_Object_layer_set"); RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_layer_update"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); prop = RNA_def_property(srna, "layers_local_view", PROP_BOOLEAN, PROP_LAYER_MEMBER); RNA_def_property_boolean_sdna(prop, NULL, "lay", 0x01000000); diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 6825d3d781d..93f940b1aa3 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -1112,12 +1112,25 @@ static void rna_def_fluid_settings(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; - + + static EnumPropertyItem sph_solver_items[] = { + {SPH_SOLVER_DDR, "DDR", 0, "Double-Density", "An artistic solver with strong surface tension effects (original)"}, + {SPH_SOLVER_CLASSICAL, "CLASSICAL", 0, "Classical", "A more physically-accurate solver"}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "SPHFluidSettings", NULL); RNA_def_struct_path_func(srna, "rna_SPHFluidSettings_path"); RNA_def_struct_ui_text(srna, "SPH Fluid Settings", "Settings for particle fluids physics"); - + /* Fluid settings */ + prop = RNA_def_property(srna, "solver", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "solver"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_enum_items(prop, sph_solver_items); + RNA_def_property_ui_text(prop, "SPH Solver", "The code used to calculate internal forces on particles"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); + prop = RNA_def_property(srna, "spring_force", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "spring_k"); RNA_def_property_range(prop, 0.0f, 100.0f); @@ -1186,7 +1199,7 @@ static void rna_def_fluid_settings(BlenderRNA *brna) /* Double density relaxation */ prop = RNA_def_property(srna, "stiffness", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "stiffness_k"); - RNA_def_property_range(prop, 0.0f, 100.0f); + RNA_def_property_range(prop, 0.0f, 100000.0f); RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3); RNA_def_property_ui_text(prop, "Stiffness", "How incompressible the fluid is"); RNA_def_property_update(prop, 0, "rna_Particle_reset"); @@ -1201,7 +1214,7 @@ static void rna_def_fluid_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "rest_density", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "rest_density"); - RNA_def_property_range(prop, 0.0f, 100.0f); + RNA_def_property_range(prop, 0.0f, 10000.0f); RNA_def_property_ui_range(prop, 0.0f, 2.0f, 1, 3); RNA_def_property_ui_text(prop, "Rest Density", "Fluid rest density"); RNA_def_property_update(prop, 0, "rna_Particle_reset"); @@ -2129,11 +2142,11 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop = RNA_def_property(srna, "courant_target", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.01, 10); - RNA_def_property_float_default(prop, 0.2); + RNA_def_property_range(prop, 0.0001, 10); + RNA_def_property_float_default(prop, 0.1); RNA_def_property_ui_text(prop, "Adaptive Subframe Threshold", "The relative distance a particle can move before requiring more subframes " - "(target Courant number); 0.1-0.3 is the recommended range"); + "(target Courant number); 0.01-0.3 is the recommended range"); RNA_def_property_update(prop, 0, "rna_Particle_reset"); prop = RNA_def_property(srna, "jitter_factor", PROP_FLOAT, PROP_NONE); @@ -2281,7 +2294,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) /* physical properties */ prop = RNA_def_property(srna, "mass", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.001f, 100000.0f); + RNA_def_property_range(prop, 0.00000001f, 100000.0f); RNA_def_property_ui_range(prop, 0.01, 100, 1, 3); RNA_def_property_ui_text(prop, "Mass", "Mass of the particles"); RNA_def_property_update(prop, 0, "rna_Particle_reset"); diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 5c90fb8787c..28d1de2c601 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -1246,7 +1246,7 @@ static void rna_def_bone_groups(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_ui_text(prop, "Active Bone Group", "Active bone group for this pose"); RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); - prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE); + prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "active_group"); RNA_def_property_int_funcs(prop, "rna_Pose_active_bone_group_index_get", "rna_Pose_active_bone_group_index_set", "rna_Pose_active_bone_group_index_range"); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 7ec371c212c..a0a55c663e9 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1250,27 +1250,32 @@ static void object_simplify_update(Object *ob) } } -static void rna_Scene_use_simplify_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr)) +static void rna_Scene_use_simplify_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { + Scene *sce = ptr->id.data; Scene *sce_iter; Base *base; - for (SETLOOPER(scene, sce_iter, base)) + for (SETLOOPER(sce, sce_iter, base)) object_simplify_update(base->object); DAG_ids_flush_update(bmain, 0); WM_main_add_notifier(NC_GEOM | ND_DATA, NULL); } -static void rna_Scene_simplify_update(Main *bmain, Scene *scene, PointerRNA *ptr) +static void rna_Scene_simplify_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { - if (scene->r.mode & R_SIMPLIFY) - rna_Scene_use_simplify_update(bmain, scene, ptr); + Scene *sce = ptr->id.data; + + if (sce->r.mode & R_SIMPLIFY) + rna_Scene_use_simplify_update(bmain, sce, ptr); } -static void rna_Scene_use_persistent_data_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr)) +static void rna_Scene_use_persistent_data_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { - if (!(scene->r.mode & R_PERSISTENT_DATA)) + Scene *sce = ptr->id.data; + + if (!(sce->r.mode & R_PERSISTENT_DATA)) RE_FreePersistentData(); } @@ -2903,6 +2908,14 @@ static void rna_def_scene_game_data(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static EnumPropertyItem storage_items[] ={ + {RAS_STORE_AUTO, "AUTO", 0, "Auto Select", "Chooses the best supported mode"}, + {RAS_STORE_IMMEDIATE, "IMMEDIATE", 0, "Immediate Mode", "Slowest performance, requires OpenGL (any version)"}, + {RAS_STORE_VA, "VERTEX_ARRAY", 0, "Vertex Arrays", "Better performance, requires at least OpenGL 1.1"}, + /* VBOS are currently disabled since they cannot beat vertex array with display lists in performance. 8? + /*{RAS_STORE_VBO, "VERTEX_BUFFER_OBJECT", 0, "Vertex Buffer Objects", "Best performance, requires at least OpenGL 1.4"},*/ + {0, NULL, 0, NULL, NULL}}; + srna = RNA_def_struct(brna, "SceneGameData", NULL); RNA_def_struct_sdna(srna, "GameData"); RNA_def_struct_nested(brna, srna, "Scene"); @@ -2938,6 +2951,12 @@ static void rna_def_scene_game_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Exit Key", "The key that exits the Game Engine"); RNA_def_property_update(prop, NC_SCENE, NULL); + prop= RNA_def_property(srna, "raster_storage", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "raster_storage"); + RNA_def_property_enum_items(prop, storage_items); + RNA_def_property_ui_text(prop, "Storage", "Sets the storage mode used by the rasterizer"); + RNA_def_property_update(prop, NC_SCENE, NULL); + /* Do we need it here ? (since we already have it in World */ prop = RNA_def_property(srna, "frequency", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "freqplay"); @@ -3287,7 +3306,7 @@ static void rna_def_render_layers(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_struct_sdna(srna, "RenderData"); RNA_def_struct_ui_text(srna, "Render Layers", "Collection of render layers"); - prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE); + prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "actlay"); RNA_def_property_int_funcs(prop, "rna_RenderSettings_active_layer_index_get", "rna_RenderSettings_active_layer_index_set", @@ -3295,7 +3314,7 @@ static void rna_def_render_layers(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_ui_text(prop, "Active Layer Index", "Active index in render layer array"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); - prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED); + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "SceneRenderLayer"); RNA_def_property_pointer_funcs(prop, "rna_RenderSettings_active_layer_get", "rna_RenderSettings_active_layer_set", NULL, NULL); @@ -3546,21 +3565,18 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "video_bitrate", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "video_bitrate"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_range(prop, 1, 64000); RNA_def_property_ui_text(prop, "Bitrate", "Video bitrate (kb/s)"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); prop = RNA_def_property(srna, "minrate", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "rc_min_rate"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_range(prop, 0, 48000); RNA_def_property_ui_text(prop, "Min Rate", "Rate control: min rate (kb/s)"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); prop = RNA_def_property(srna, "maxrate", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "rc_max_rate"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_range(prop, 1, 96000); RNA_def_property_ui_text(prop, "Max Rate", "Rate control: max rate (kb/s)"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); @@ -4366,6 +4382,13 @@ static void rna_def_scene_render_data(BlenderRNA *brna) "Calculate heights against unsubdivided low resolution mesh"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + prop = RNA_def_property(srna, "bake_rays_number", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "bake_rays_number"); + RNA_def_property_range(prop, 64, 1024); + RNA_def_property_int_default(prop, 256); + RNA_def_property_ui_text(prop, "Number of Rays", "Number of rays used for ambient occlusion baking from multires"); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + /* stamp */ prop = RNA_def_property(srna, "use_stamp_time", PROP_BOOLEAN, PROP_NONE); @@ -4479,6 +4502,11 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_enum_items(prop, viewport_shade_items); RNA_def_property_ui_text(prop, "Sequencer Preview Shading", "Method to draw in the sequencer view"); + prop = RNA_def_property(srna, "use_sequencer_gl_textured_solid", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "seq_flag", R_SEQ_SOLID_TEX); + RNA_def_property_ui_text(prop, "Textured Solid", "Draw face-assigned textures in solid draw method"); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SceneSequencer_update"); + /* layers */ prop = RNA_def_property(srna, "layers", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "layers", NULL); diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index 84e76fae896..f717c83075a 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -59,8 +59,7 @@ static EnumPropertyItem particle_edit_hair_brush_items[] = { #include "BKE_pointcache.h" #include "BKE_particle.h" #include "BKE_depsgraph.h" - -#include "BLI_pbvh.h" +#include "BKE_pbvh.h" #include "ED_particle.h" diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index c928e91ea1f..83bf40f85f6 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -321,7 +321,7 @@ static void rna_View3D_CursorLocation_get(PointerRNA *ptr, float *values) View3D *v3d = (View3D *)(ptr->data); bScreen *sc = (bScreen *)ptr->id.data; Scene *scene = (Scene *)sc->scene; - float *loc = give_cursor(scene, v3d); + const float *loc = give_cursor(scene, v3d); copy_v3_v3(values, loc); } @@ -775,7 +775,7 @@ static void rna_SpaceProperties_align_set(PointerRNA *ptr, int value) static void rna_ConsoleLine_body_get(PointerRNA *ptr, char *value) { ConsoleLine *ci = (ConsoleLine *)ptr->data; - strcpy(value, ci->line); + memcpy(value, ci->line, ci->len + 1); } static int rna_ConsoleLine_body_length(PointerRNA *ptr) @@ -1659,6 +1659,12 @@ static void rna_def_space_view3d(BlenderRNA *brna) "Show dashed lines indicating parent or constraint relationships"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SHOW_GPENCIL); + RNA_def_property_ui_text(prop, "Show Grease Pencil", + "Show grease pencil for this view"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "show_textured_solid", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SOLID_TEX); RNA_def_property_ui_text(prop, "Textured Solid", "Display face-assigned textures in solid view"); @@ -2045,6 +2051,12 @@ static void rna_def_space_image(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Draw Repeated", "Draw the image repeated outside of the main view"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL); + prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_SHOW_GPENCIL); + RNA_def_property_ui_text(prop, "Show Grease Pencil", + "Show grease pencil for this view"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL); + prop = RNA_def_property(srna, "draw_channels", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); RNA_def_property_enum_items(prop, draw_channels_items); @@ -2210,6 +2222,12 @@ static void rna_def_space_sequencer(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); + prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_SHOW_GPENCIL); + RNA_def_property_ui_text(prop, "Show Grease Pencil", + "Show grease pencil for this view"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); + prop = RNA_def_property(srna, "display_channel", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "chanshown"); RNA_def_property_ui_text(prop, "Display Channel", @@ -3031,6 +3049,12 @@ static void rna_def_space_node(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Backdrop", "Use active Viewer Node output as backdrop for compositing nodes"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL); + prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_SHOW_GPENCIL); + RNA_def_property_ui_text(prop, "Show Grease Pencil", + "Show grease pencil for this view"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL); + prop = RNA_def_property(srna, "use_auto_render", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_AUTO_RENDER); RNA_def_property_ui_text(prop, "Auto Render", "Re-render and composite changed layers on 3D edits"); @@ -3303,6 +3327,13 @@ static void rna_def_space_clip(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Manual Calibration", "Use manual calibration helpers"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); + /* show grease pencil */ + prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_GPENCIL); + RNA_def_property_ui_text(prop, "Show Grease Pencil", + "Show grease pencil for this view"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, NULL); + /* show filters */ prop = RNA_def_property(srna, "show_filters", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_FILTERS); diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index bdf9fa4e436..e116e5df0de 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -71,12 +71,12 @@ EnumPropertyItem texture_type_items[] = { {TEX_MUSGRAVE, "MUSGRAVE", ICON_TEXTURE, "Musgrave", "Procedural - highly flexible fractal noise texture"}, {TEX_NOISE, "NOISE", ICON_TEXTURE, "Noise", "Procedural - random noise, gives a different result every time, for every frame, for every pixel"}, + {TEX_OCEAN, "OCEAN", ICON_TEXTURE, "Ocean", "Use a texture generated by an Ocean modifier"}, {TEX_POINTDENSITY, "POINT_DENSITY", ICON_TEXTURE, "Point Density", ""}, {TEX_STUCCI, "STUCCI", ICON_TEXTURE, "Stucci", "Procedural - create a fractal noise texture"}, {TEX_VORONOI, "VORONOI", ICON_TEXTURE, "Voronoi", "Procedural - create cell-like patterns based on Worley noise"}, {TEX_VOXELDATA, "VOXEL_DATA", ICON_TEXTURE, "Voxel Data", "Create a 3D texture based on volumetric data"}, {TEX_WOOD, "WOOD", ICON_TEXTURE, "Wood", "Procedural - wave generated bands or rings, with optional noise"}, - {TEX_OCEAN, "OCEAN", ICON_TEXTURE, "Ocean", "Use a texture generated by an Ocean modifier"}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 4aefaf991d2..f5bcab3e530 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -1161,7 +1161,7 @@ static void rna_def_trackingStabilization(BlenderRNA *brna) PropertyRNA *prop; static EnumPropertyItem filter_items[] = { - {TRACKING_FILTER_NEAREAST, "NEAREST", 0, "Nearest", ""}, + {TRACKING_FILTER_NEAREST, "NEAREST", 0, "Nearest", ""}, {TRACKING_FILTER_BILINEAR, "BILINEAR", 0, "Bilinear", ""}, {TRACKING_FILTER_BICUBIC, "BICUBIC", 0, "Bicubic", ""}, {0, NULL, 0, NULL, NULL} diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c index a0a9f6183af..de359fd6413 100644 --- a/source/blender/makesrna/intern/rna_ui.c +++ b/source/blender/makesrna/intern/rna_ui.c @@ -651,8 +651,8 @@ static void rna_def_panel(BlenderRNA *brna) static EnumPropertyItem panel_flag_items[] = { {PNL_DEFAULT_CLOSED, "DEFAULT_CLOSED", 0, "Default Closed", "Defines if the panel has to be open or collapsed at the time of its creation"}, - {PNL_NO_HEADER, "HIDE_HEADER", 0, "Show Header", - "If set to True, the panel shows a header, which contains a clickable " + {PNL_NO_HEADER, "HIDE_HEADER", 0, "Hide Header", + "If set to False, the panel shows a header, which contains a clickable " "arrow to collapse the panel and the label (see bl_label)"}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index c9614129b81..46d0744cad7 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -62,6 +62,7 @@ static EnumPropertyItem compute_device_type_items[] = { #include "DNA_object_types.h" #include "DNA_screen_types.h" +#include "BKE_blender.h" #include "BKE_DerivedMesh.h" #include "BKE_depsgraph.h" #include "BKE_global.h" @@ -83,9 +84,10 @@ static void rna_userdef_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Pointe WM_main_add_notifier(NC_WINDOW, NULL); } +/* also used by buffer swap switching */ static void rna_userdef_dpi_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) { - U.widget_unit = (U.dpi * 20 + 36) / 72; + BKE_userdef_state(); WM_main_add_notifier(NC_WINDOW, NULL); /* full redraw */ WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); /* refresh region sizes */ } @@ -502,13 +504,6 @@ static void rna_def_userdef_theme_ui_style(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Panel Zoom", "Default zoom level for panel areas"); #endif - prop = RNA_def_property(srna, "panel_title", PROP_POINTER, PROP_NONE); - RNA_def_property_flag(prop, PROP_NEVER_NULL); - RNA_def_property_pointer_sdna(prop, NULL, "paneltitle"); - RNA_def_property_struct_type(prop, "ThemeFontStyle"); - RNA_def_property_ui_text(prop, "Panel Style", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - /* (not used yet) */ #if 0 prop = RNA_def_property(srna, "group_label", PROP_POINTER, PROP_NONE); @@ -648,10 +643,18 @@ static void rna_def_userdef_theme_ui_panel(BlenderRNA *brna) prop = RNA_def_property(srna, "header", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_ui_text(prop, "Header", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - + + prop = RNA_def_property(srna, "back", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_ui_text(prop, "Background", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + prop = RNA_def_property(srna, "show_header", PROP_BOOLEAN, PROP_NONE); RNA_def_property_ui_text(prop, "Show Header", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop = RNA_def_property(srna, "show_back", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_ui_text(prop, "Show Background", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_ui(BlenderRNA *brna) @@ -757,11 +760,6 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna) RNA_def_property_ui_text(prop, "State Colors", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "panel", PROP_POINTER, PROP_NONE); - RNA_def_property_flag(prop, PROP_NEVER_NULL); - RNA_def_property_ui_text(prop, "Panel Colors", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "icon_file", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "iconfile"); RNA_def_property_ui_text(prop, "Icon File", ""); @@ -837,10 +835,16 @@ static void rna_def_userdef_theme_space_generic(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Header Text Highlight", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); + /* panel settings */ + prop = RNA_def_property(srna, "panelcolors", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_ui_text(prop, "Panel Colors", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + /* buttons */ /* if (! ELEM(spacetype, SPACE_BUTS, SPACE_OUTLINER)) { */ prop = RNA_def_property(srna, "button", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 3); + RNA_def_property_array(prop, 4); RNA_def_property_ui_text(prop, "Region Background", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); @@ -1124,11 +1128,6 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Grid", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 4); - RNA_def_property_ui_text(prop, "Panel", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "wire", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Wire", ""); @@ -1283,11 +1282,6 @@ static void rna_def_userdef_theme_space_graph(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Grid", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Panel", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "window_sliders", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "shade1"); RNA_def_property_array(prop, 3); @@ -1370,12 +1364,6 @@ static void rna_def_userdef_theme_space_file(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Selected File", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "tiles", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_float_sdna(prop, NULL, "panel"); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Tiles", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - prop = RNA_def_property(srna, "scrollbar", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_float_sdna(prop, NULL, "shade1"); RNA_def_property_array(prop, 3); @@ -1664,7 +1652,7 @@ static void rna_def_userdef_theme_space_node(BlenderRNA *brna) static void rna_def_userdef_theme_space_logic(BlenderRNA *brna) { StructRNA *srna; - PropertyRNA *prop; +// PropertyRNA *prop; /* space_logic */ @@ -1675,17 +1663,13 @@ static void rna_def_userdef_theme_space_logic(BlenderRNA *brna) rna_def_userdef_theme_spaces_main(srna); - prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Panel", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_buts(BlenderRNA *brna) { StructRNA *srna; - PropertyRNA *prop; +// PropertyRNA *prop; /* space_buts */ @@ -1696,10 +1680,6 @@ static void rna_def_userdef_theme_space_buts(BlenderRNA *brna) rna_def_userdef_theme_spaces_main(srna); - prop = RNA_def_property(srna, "panel", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Panel", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); } static void rna_def_userdef_theme_space_time(BlenderRNA *brna) @@ -3285,7 +3265,7 @@ static void rna_def_userdef_system(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "wmdrawmethod"); RNA_def_property_enum_items(prop, draw_method_items); RNA_def_property_ui_text(prop, "Window Draw Method", "Drawing method used by the window manager"); - RNA_def_property_update(prop, 0, "rna_userdef_update"); + RNA_def_property_update(prop, 0, "rna_userdef_dpi_update"); prop = RNA_def_property(srna, "audio_mixing_buffer", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "mixbufsize"); @@ -3339,6 +3319,13 @@ static void rna_def_userdef_system(BlenderRNA *brna) RNA_def_property_enum_items(prop, multi_sample_levels); RNA_def_property_ui_text(prop, "MultiSample", "Enable OpenGL multi-sampling, only for systems that support it, requires restart"); + prop = RNA_def_property(srna, "use_region_overlap", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "uiflag2", USER_REGION_OVERLAP); + RNA_def_property_ui_text(prop, "Region Overlap", + "Draw tool/property regions over the main region, when using Triple Buffer"); + RNA_def_property_update(prop, 0, "rna_userdef_dpi_update"); + + #ifdef WITH_CYCLES prop = RNA_def_property(srna, "compute_device_type", PROP_ENUM, PROP_NONE); RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT); @@ -3674,6 +3661,11 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna) "The time (in minutes) to wait between automatic temporary saves"); RNA_def_property_update(prop, 0, "rna_userdef_autosave_update"); + prop = RNA_def_property(srna, "use_keep_session", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "uiflag2", USER_KEEP_SESSION); + RNA_def_property_ui_text(prop, "Keep Session", + "Always load session recovery and save it after quitting Blender"); + prop = RNA_def_property(srna, "recent_files", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 0, 30); RNA_def_property_ui_text(prop, "Recent Files", "Maximum number of recently opened files to remember"); diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index f83410e7cc1..f123b564f8d 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -416,6 +416,7 @@ EnumPropertyItem wm_report_items[] = { {RPT_DEBUG, "DEBUG", 0, "Debug", ""}, {RPT_INFO, "INFO", 0, "Info", ""}, {RPT_OPERATOR, "OPERATOR", 0, "Operator", ""}, + {RPT_PROPERTY, "PROPERTY", 0, "Property", ""}, {RPT_WARNING, "WARNING", 0, "Warning", ""}, {RPT_ERROR, "ERROR", 0, "Error", ""}, {RPT_ERROR_INVALID_INPUT, "ERROR_INVALID_INPUT", 0, "Invalid Input", ""}, @@ -1617,6 +1618,26 @@ static void rna_def_window(BlenderRNA *brna) RNA_def_property_pointer_funcs(prop, NULL, "rna_Window_screen_set", NULL, NULL); RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); RNA_def_property_update(prop, 0, "rna_Window_screen_update"); + + prop = RNA_def_property(srna, "x", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "posx"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "X Position", "Vertical location of the window"); + + prop = RNA_def_property(srna, "y", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "posy"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Y Position", "Horizontal location of the window"); + + prop = RNA_def_property(srna, "width", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_sdna(prop, NULL, "sizex"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Width", "Window width"); + + prop = RNA_def_property(srna, "height", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_sdna(prop, NULL, "sizey"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Height", "Window height"); } /* curve.splines */ diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt index cf3bb05849a..33209095164 100644 --- a/source/blender/modifiers/CMakeLists.txt +++ b/source/blender/modifiers/CMakeLists.txt @@ -64,8 +64,8 @@ set(SRC intern/MOD_fluidsim.c intern/MOD_fluidsim_util.c intern/MOD_hook.c - intern/MOD_lattice.c intern/MOD_laplaciansmooth.c + intern/MOD_lattice.c intern/MOD_mask.c intern/MOD_meshdeform.c intern/MOD_mirror.c @@ -86,7 +86,9 @@ set(SRC intern/MOD_solidify.c intern/MOD_subsurf.c intern/MOD_surface.c + intern/MOD_triangulate.c intern/MOD_util.c + intern/MOD_uvwarp.c intern/MOD_uvproject.c intern/MOD_warp.c intern/MOD_wave.c @@ -94,7 +96,6 @@ set(SRC intern/MOD_weightvgedit.c intern/MOD_weightvgmix.c intern/MOD_weightvgproximity.c - intern/MOD_triangulate.c MOD_modifiertypes.h intern/MOD_boolean_util.h diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h index 290ba193567..17e903e9ebb 100644 --- a/source/blender/modifiers/MOD_modifiertypes.h +++ b/source/blender/modifiers/MOD_modifiertypes.h @@ -77,6 +77,7 @@ extern ModifierTypeInfo modifierType_Remesh; extern ModifierTypeInfo modifierType_Skin; extern ModifierTypeInfo modifierType_LaplacianSmooth; extern ModifierTypeInfo modifierType_Triangulate; +extern ModifierTypeInfo modifierType_UVWarp; /* MOD_util.c */ void modifier_type_init(ModifierTypeInfo *types[]); diff --git a/source/blender/modifiers/SConscript b/source/blender/modifiers/SConscript index 62fd9ba2de1..d3430c6a4d5 100644 --- a/source/blender/modifiers/SConscript +++ b/source/blender/modifiers/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('intern/*.c') diff --git a/source/blender/modifiers/intern/MOD_boolean_util.c b/source/blender/modifiers/intern/MOD_boolean_util.c index 2ff93532d14..0cf4f6a008f 100644 --- a/source/blender/modifiers/intern/MOD_boolean_util.c +++ b/source/blender/modifiers/intern/MOD_boolean_util.c @@ -305,7 +305,7 @@ static Object *AddNewBlenderMesh(Scene *scene, Base *base) static void InterpCSGFace( DerivedMesh *dm, DerivedMesh *orig_dm, int index, int orig_index, int nr, - float mapmat[][4]) + float mapmat[4][4]) { float obco[3], *co[4], *orig_co[4], w[4][4]; MFace *mface, *orig_mface; @@ -344,8 +344,8 @@ static void InterpCSGFace( static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh( CSG_FaceIteratorDescriptor *face_it, CSG_VertexIteratorDescriptor *vertex_it, - float parinv[][4], - float mapmat[][4], + float parinv[4][4], + float mapmat[4][4], Material **mat, int *totmat, DerivedMesh *dm1, diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index 28cdfa810fa..a23b677f8e6 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -188,7 +188,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* update for display only */ dmd->face_count = bm->totface; result = CDDM_from_bmesh(bm, FALSE); - BLI_assert(bm->toolflagpool == NULL); /* make sure we never alloc'd this */ + BLI_assert(bm->vtoolflagpool == NULL); /* make sure we never alloc'd this */ + BLI_assert(bm->etoolflagpool == NULL); + BLI_assert(bm->ftoolflagpool == NULL); BM_mesh_free(bm); #ifdef USE_TIMEIT diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c index ec81c5ce699..5c786626c94 100644 --- a/source/blender/modifiers/intern/MOD_edgesplit.c +++ b/source/blender/modifiers/intern/MOD_edgesplit.c @@ -30,32 +30,24 @@ /** \file blender/modifiers/intern/MOD_edgesplit.c * \ingroup modifiers + * + * EdgeSplit modifier + * + * Splits edges in the mesh according to sharpness flag + * or edge angle (can be used to achieve autosmoothing) */ - -/* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag - * or edge angle (can be used to achieve autosmoothing) */ - #include "BLI_utildefines.h" #include "BLI_math.h" -#include "MEM_guardedalloc.h" - #include "BKE_cdderivedmesh.h" #include "BKE_modifier.h" -#include "BKE_mesh.h" #include "bmesh.h" +#include "tools/bmesh_edgesplit.h" #include "DNA_object_types.h" -/* EdgeSplit */ -/* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag - * or edge angle (can be used to achieve autosmoothing) - * - * note: this code is very close to MOD_bevel.c - */ - #define EDGE_MARK 1 static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Object *UNUSED(ob)) @@ -67,7 +59,6 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj float threshold = cosf((emd->split_angle + 0.00001f) * (float)M_PI / 180.0f); bm = DM_to_bmesh(dm); - BM_mesh_elem_toolflags_ensure(bm); if (emd->flags & MOD_EDGESPLIT_FROMANGLE) { BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { @@ -81,7 +72,7 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj /* 2 face edge - check angle*/ (dot_v3v3(l1->f->no, l2->f->no) < threshold)) { - BMO_elem_flag_enable(bm, e, EDGE_MARK); + BM_elem_flag_enable(e, BM_ELEM_TAG); } } } @@ -94,14 +85,13 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj (e->l->next != e->l)) { if (!BM_elem_flag_test(e, BM_ELEM_SMOOTH)) { - BMO_elem_flag_enable(bm, e, EDGE_MARK); + BM_elem_flag_enable(e, BM_ELEM_TAG); } } } } - BMO_op_callf(bm, BMO_FLAG_DEFAULTS, - "split_edges edges=%fe", EDGE_MARK); + BM_mesh_edgesplit(bm, FALSE, TRUE); /* BM_mesh_validate(bm); */ /* for troubleshooting */ diff --git a/source/blender/modifiers/intern/MOD_fluidsim_util.c b/source/blender/modifiers/intern/MOD_fluidsim_util.c index 13d409dc941..b39ddf62c55 100644 --- a/source/blender/modifiers/intern/MOD_fluidsim_util.c +++ b/source/blender/modifiers/intern/MOD_fluidsim_util.c @@ -301,7 +301,7 @@ static DerivedMesh *fluidsim_read_obj(const char *filename, const MPoly *mp_exam } -void fluid_get_bb(MVert *mvert, int totvert, float obmat[][4], +void fluid_get_bb(MVert *mvert, int totvert, float obmat[4][4], /*RET*/ float start[3], /*RET*/ float size[3]) { float bbsx = 0.0, bbsy = 0.0, bbsz = 0.0; diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index a27d5e5e03b..6c2f68891af 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -279,5 +279,6 @@ void modifier_type_init(ModifierTypeInfo *types[]) INIT_TYPE(Skin); INIT_TYPE(LaplacianSmooth); INIT_TYPE(Triangulate); + INIT_TYPE(UVWarp); #undef INIT_TYPE } diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c new file mode 100644 index 00000000000..249c3c89d5f --- /dev/null +++ b/source/blender/modifiers/intern/MOD_uvwarp.c @@ -0,0 +1,268 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Pawel Kowal, Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/modifiers/intern/MOD_uvwarp.c + * \ingroup modifiers + */ + +#include <string.h> + +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" + +#include "BLI_math.h" +#include "BLI_string.h" +#include "BLI_utildefines.h" + +#include "BKE_action.h" /* BKE_pose_channel_find_name */ +#include "BKE_cdderivedmesh.h" +#include "BKE_deform.h" +#include "BKE_modifier.h" + +#include "depsgraph_private.h" + +#include "MOD_util.h" + + +static void uv_warp_from_mat4_pair(float uv_dst[2], const float uv_src[2], float warp_mat[4][4], + int axis_u, int axis_v) +{ + float tuv[3] = {0.0f}; + + tuv[axis_u] = uv_src[0]; + tuv[axis_v] = uv_src[1]; + + mul_m4_v3(warp_mat, tuv); + + uv_dst[0] = tuv[axis_u]; + uv_dst[1] = tuv[axis_v]; +} + +static void initData(ModifierData *md) +{ + UVWarpModifierData *umd = (UVWarpModifierData *) md; + umd->axis_u = 0; + umd->axis_v = 1; + copy_v2_fl(umd->center, 0.5f); +} + +static void copyData(ModifierData *md, ModifierData *target) +{ + UVWarpModifierData *umd = (UVWarpModifierData *)md; + UVWarpModifierData *tumd = (UVWarpModifierData *)target; + + tumd->axis_u = umd->axis_u; + tumd->axis_v = umd->axis_v; + copy_v2_v2(tumd->center, umd->center); + tumd->object_src = umd->object_src; + BLI_strncpy(tumd->bone_src, umd->bone_src, sizeof(tumd->bone_src)); + tumd->object_dst = umd->object_dst; + BLI_strncpy(tumd->bone_dst, umd->bone_dst, sizeof(tumd->bone_dst)); + BLI_strncpy(tumd->vgroup_name, umd->vgroup_name, sizeof(tumd->vgroup_name)); + BLI_strncpy(tumd->uvlayer_name, umd->uvlayer_name, sizeof(umd->uvlayer_name)); +} + +static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) +{ + UVWarpModifierData *umd = (UVWarpModifierData *)md; + CustomDataMask dataMask = 0; + + /* ask for vertexgroups if we need them */ + if (umd->vgroup_name[0]) + dataMask |= CD_MASK_MDEFORMVERT; + + return dataMask; +} + +static void matrix_from_obj_pchan(float mat[4][4], Object *ob, const char *bonename) +{ + bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bonename); + if (pchan) { + mult_m4_m4m4(mat, ob->obmat, pchan->pose_mat); + } + else { + copy_m4_m4(mat, ob->obmat); + } +} + +#define OMP_LIMIT 1000 +static DerivedMesh *applyModifier(ModifierData *md, Object *ob, + DerivedMesh *dm, + ModifierApplyFlag UNUSED(flag)) +{ + UVWarpModifierData *umd = (UVWarpModifierData *) md; + int i, numPolys, numLoops; + MPoly *mpoly; + MLoop *mloop; + MLoopUV *mloopuv; + MDeformVert *dvert; + int defgrp_index; + char uvname[MAX_CUSTOMDATA_LAYER_NAME]; + float mat_src[4][4]; + float mat_dst[4][4]; + float imat_dst[4][4]; + float warp_mat[4][4]; + const int axis_u = umd->axis_u; + const int axis_v = umd->axis_v; + + /* make sure there are UV Maps available */ + if (!CustomData_has_layer(&dm->loopData, CD_MLOOPUV)) { + return dm; + } + else if (ELEM(NULL, umd->object_src, umd->object_dst)) { + modifier_setError(md, "From/To objects must be set"); + return dm; + } + + /* make sure anything moving UVs is available */ + matrix_from_obj_pchan(mat_src, umd->object_src, umd->bone_src); + matrix_from_obj_pchan(mat_dst, umd->object_dst, umd->bone_dst); + + invert_m4_m4(imat_dst, mat_dst); + mult_m4_m4m4(warp_mat, imat_dst, mat_src); + + /* apply warp */ + if (!is_zero_v2(umd->center)) { + float mat_cent[4][4]; + float imat_cent[4][4]; + + unit_m4(mat_cent); + mat_cent[3][axis_u] = umd->center[0]; + mat_cent[3][axis_v] = umd->center[1]; + + invert_m4_m4(imat_cent, mat_cent); + + mult_m4_m4m4(warp_mat, warp_mat, imat_cent); + mult_m4_m4m4(warp_mat, mat_cent, warp_mat); + } + + /* make sure we're using an existing layer */ + CustomData_validate_layer_name(&dm->loopData, CD_MLOOPUV, umd->uvlayer_name, uvname); + + numPolys = dm->getNumPolys(dm); + numLoops = dm->getNumLoops(dm); + + mpoly = dm->getPolyArray(dm); + mloop = dm->getLoopArray(dm); + /* make sure we are not modifying the original UV map */ + mloopuv = CustomData_duplicate_referenced_layer_named(&dm->loopData, CD_MLOOPUV, uvname, numLoops); + modifier_get_vgroup(ob, dm, umd->vgroup_name, &dvert, &defgrp_index); + + if (dvert) { +#pragma omp parallel for if (numPolys > OMP_LIMIT) + for (i = 0; i < numPolys; i++) { + float uv[2]; + MPoly *mp = &mpoly[i]; + MLoop *ml = &mloop[mp->loopstart]; + MLoopUV *mluv = &mloopuv[mp->loopstart]; + int l; + for (l = 0; l < mp->totloop; l++, ml++, mluv++) { + const float weight = defvert_find_weight(&dvert[ml->v], defgrp_index); + uv_warp_from_mat4_pair(uv, mluv->uv, warp_mat, axis_u, axis_v); + interp_v2_v2v2(mluv->uv, mluv->uv, uv, weight); + } + } + } + else { +#pragma omp parallel for if (numPolys > OMP_LIMIT) + for (i = 0; i < numPolys; i++) { + MPoly *mp = &mpoly[i]; + // MLoop *ml = &mloop[mp->loopstart]; + MLoopUV *mluv = &mloopuv[mp->loopstart]; + int l; + for (l = 0; l < mp->totloop; l++, /* ml++, */ mluv++) { + uv_warp_from_mat4_pair(mluv->uv, mluv->uv, warp_mat, axis_u, axis_v); + } + } + } + + dm->dirty |= DM_DIRTY_TESS_CDLAYERS; + + return dm; +} + +static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, + struct BMEditMesh *UNUSED(editData), + DerivedMesh *derivedData) +{ + return applyModifier(md, ob, derivedData, MOD_APPLY_USECACHE); +} + +static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData) +{ + UVWarpModifierData *umd = (UVWarpModifierData *) md; + + walk(userData, ob, &umd->object_dst); + walk(userData, ob, &umd->object_src); +} + +static void uv_warp_deps_object_bone(DagForest *forest, DagNode *obNode, + Object *obj, const char *bonename) +{ + if (obj) { + DagNode *curNode = dag_get_node(forest, obj); + + if (bonename[0]) + dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "UVWarp Modifier"); + else + dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA, "UVWarp Modifier"); + } +} + +static void updateDepgraph(ModifierData *md, DagForest *forest, + struct Scene *UNUSED(scene), + Object *UNUSED(ob), + DagNode *obNode) +{ + UVWarpModifierData *umd = (UVWarpModifierData *) md; + + uv_warp_deps_object_bone(forest, obNode, umd->object_src, umd->bone_src); + uv_warp_deps_object_bone(forest, obNode, umd->object_dst, umd->bone_dst); +} + +ModifierTypeInfo modifierType_UVWarp = { + /* name */ "UVWarp", + /* structName */ "UVWarpModifierData", + /* structSize */ sizeof(UVWarpModifierData), + /* type */ eModifierTypeType_NonGeometrical, + /* flags */ eModifierTypeFlag_AcceptsMesh | + eModifierTypeFlag_SupportsEditmode | + eModifierTypeFlag_EnableInEditmode, + /* copyData */ copyData, + /* deformVerts */ NULL, + /* deformMatrices */ NULL, + /* deformVertsEM */ NULL, + /* deformMatricesEM */ NULL, + /* applyModifier */ applyModifier, + /* applyModifierEM */ applyModifierEM, + /* initData */ initData, + /* requiredDataMask */ requiredDataMask, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepgraph */ updateDepgraph, + /* dependsOnTime */ NULL, + /* dependsOnNormals */ NULL, + /* foreachObjectLink */ foreachObjectLink, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, +}; diff --git a/source/blender/nodes/SConscript b/source/blender/nodes/SConscript index ec4f00a199a..cc735902934 100644 --- a/source/blender/nodes/SConscript +++ b/source/blender/nodes/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('intern/*.c') diff --git a/source/blender/nodes/composite/nodes/node_composite_rotate.c b/source/blender/nodes/composite/nodes/node_composite_rotate.c index 9a76764b97e..50c8b2a78c1 100644 --- a/source/blender/nodes/composite/nodes/node_composite_rotate.c +++ b/source/blender/nodes/composite/nodes/node_composite_rotate.c @@ -91,7 +91,7 @@ static void node_composit_exec_rotate(void *UNUSED(data), bNode *node, bNodeStac switch (node->custom1) { case 0: - neareast_interpolation(ibuf, obuf, u, v, xo, yo); + nearest_interpolation(ibuf, obuf, u, v, xo, yo); break; case 1: bilinear_interpolation(ibuf, obuf, u, v, xo, yo); diff --git a/source/blender/nodes/composite/nodes/node_composite_transform.c b/source/blender/nodes/composite/nodes/node_composite_transform.c index a8ef0286f2f..d6bb545cd5c 100644 --- a/source/blender/nodes/composite/nodes/node_composite_transform.c +++ b/source/blender/nodes/composite/nodes/node_composite_transform.c @@ -93,7 +93,7 @@ CompBuf* node_composit_transform(CompBuf *cbuf, float x, float y, float angle, f switch (filter_type) { case 0: - neareast_interpolation(ibuf, obuf, vec[0], vec[1], i, j); + nearest_interpolation(ibuf, obuf, vec[0], vec[1], i, j); break; case 1: bilinear_interpolation(ibuf, obuf, vec[0], vec[1], i, j); diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.c index 9fa654c9740..216e10a7e9a 100644 --- a/source/blender/nodes/shader/nodes/node_shader_curves.c +++ b/source/blender/nodes/shader/nodes/node_shader_curves.c @@ -74,7 +74,7 @@ void register_node_type_sh_curve_vec(bNodeTreeType *ttype) static bNodeType ntype; node_type_base(ttype, &ntype, SH_NODE_CURVE_VEC, "Vector Curves", NODE_CLASS_OP_VECTOR, NODE_OPTIONS); - node_type_compatibility(&ntype, NODE_OLD_SHADING); + node_type_compatibility(&ntype, NODE_OLD_SHADING|NODE_NEW_SHADING); node_type_socket_templates(&ntype, sh_node_curve_vec_in, sh_node_curve_vec_out); node_type_size(&ntype, 200, 140, 320); node_type_init(&ntype, node_shader_init_curve_vec); @@ -132,7 +132,7 @@ void register_node_type_sh_curve_rgb(bNodeTreeType *ttype) static bNodeType ntype; node_type_base(ttype, &ntype, SH_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR, NODE_OPTIONS); - node_type_compatibility(&ntype, NODE_OLD_SHADING); + node_type_compatibility(&ntype, NODE_OLD_SHADING|NODE_NEW_SHADING); node_type_socket_templates(&ntype, sh_node_curve_rgb_in, sh_node_curve_rgb_out); node_type_size(&ntype, 200, 140, 320); node_type_init(&ntype, node_shader_init_curve_rgb); diff --git a/source/blender/nodes/shader/nodes/node_shader_material.c b/source/blender/nodes/shader/nodes/node_shader_material.c index 2902bf143c8..a36f35c646d 100644 --- a/source/blender/nodes/shader/nodes/node_shader_material.c +++ b/source/blender/nodes/shader/nodes/node_shader_material.c @@ -145,7 +145,7 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in, /* make alpha output give results even if transparency is only enabled on * the material linked in this not and not on the parent material */ mode = shi->mode; - if(shi->mat->mode & MA_TRANSP) + if (shi->mat->mode & MA_TRANSP) shi->mode |= MA_TRANSP; shi->nodes= 1; /* temp hack to prevent trashadow recursion */ diff --git a/source/blender/opencl/SConscript b/source/blender/opencl/SConscript index e91a99d5075..388789a5b50 100644 --- a/source/blender/opencl/SConscript +++ b/source/blender/opencl/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('intern/*.c') diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript index b0164d24852..21af50dbf10 100644 --- a/source/blender/python/SConscript +++ b/source/blender/python/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 ***** # TODO, split into 3 files. @@ -47,16 +72,100 @@ if env['WITH_BF_PYTHON_SAFETY']: if env['BF_BUILDINFO']: defs.append('BUILD_DATE') -if env['WITH_BF_INTERNATIONAL']: - defs.append('WITH_INTERNATIONAL') -if env['WITH_BF_CYCLES']: - defs.append('WITH_CYCLES') +# Audaspace is always on currently + +if env['WITH_BF_BULLET']: + defs.append('WITH_BULLET') + +# AVI is always on currently if env['WITH_BF_FFMPEG']: defs.append('WITH_FFMPEG') incs += ' ' + env['BF_FFMPEG_INC'] - + +if env['WITH_BF_QUICKTIME']: + defs.append('WITH_QUICKTIME') + +if env['WITH_BF_SNDFILE']: + defs.append('WITH_SNDFILE') + +if env['WITH_BF_COMPOSITOR']: + defs.append('WITH_COMPOSITOR') + +if env['WITH_BF_CYCLES']: + defs.append('WITH_CYCLES') + +if env['WITH_BF_CYCLES']: + defs.append('WITH_CYCLES') + +if env['WITH_BF_CYCLES_OSL']: + defs.append('WITH_CYCLES_OSL') + +if env['WITH_BF_GAMEENGINE']: + defs.append('WITH_GAMEENGINE') + +if env['WITH_BF_CINEON']: + defs.append('WITH_CINEON') + +if env['WITH_BF_DDS']: + defs.append('WITH_DDS') + +if env['WITH_BF_FRAMESERVER']: + defs.append('WITH_FRAMESERVER') + +if env['WITH_BF_HDR']: + defs.append('WITH_HDR') + +if env['WITH_BF_OPENEXR']: + defs.append('WITH_OPENEXR') + +if env['WITH_BF_OPENJPEG']: + defs.append('WITH_OPENJPEG') + +if env['WITH_BF_REDCODE']: + defs.append('WITH_REDCODE') + +if env['WITH_BF_TIFF']: + defs.append('WITH_TIFF') + +# NDof is always on currently + +if env['WITH_BF_INTERNATIONAL']: + defs.append('WITH_INTERNATIONAL') + +if env['WITH_BF_JACK']: + defs.append('WITH_JACK') + +if env['WITH_BF_LIBMV']: + defs.append('WITH_LIBMV') + +if env['WITH_BF_BOOLEAN']: + defs.append('WITH_MOD_BOOLEAN') + +if env['WITH_BF_FLUID']: + defs.append('WITH_MOD_FLUID') + +if env['WITH_BF_OCEANSIM']: + defs.append('WITH_OCEANSIM') + +if env['WITH_BF_REMESH']: + defs.append('WITH_MOD_REMESH') + +if env['WITH_BF_SMOKE']: + defs.append('WITH_SMOKE') + +if env['WITH_BF_OPENAL']: + defs.append('WITH_OPENAL') + +if env['WITH_BF_COLLADA']: + defs.append('WITH_COLLADA') + +if env['WITH_BF_PLAYER']: + defs.append('WITH_PLAYER') + + + if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] diff --git a/source/blender/python/bmesh/bmesh_py_api.c b/source/blender/python/bmesh/bmesh_py_api.c index 18f5d895132..9abb13731af 100644 --- a/source/blender/python/bmesh/bmesh_py_api.c +++ b/source/blender/python/bmesh/bmesh_py_api.c @@ -98,7 +98,7 @@ static PyObject *bpy_bm_from_edit_mesh(PyObject *UNUSED(self), PyObject *value) } PyDoc_STRVAR(bpy_bm_update_edit_mesh_doc, -".. method:: update_edit_mesh(mesh, tessface=True)\n" +".. method:: update_edit_mesh(mesh, tessface=True, destructive=True)\n" "\n" " Update the mesh after changes to the BMesh in editmode, \n" " optionally recalculating n-gon tessellation.\n" @@ -107,14 +107,17 @@ PyDoc_STRVAR(bpy_bm_update_edit_mesh_doc, " :type mesh: :class:`bpy.types.Mesh`\n" " :arg tessface: Option to recalculate n-gon tessellation.\n" " :type tessface: boolean\n" +" :arg destructive: Use when grometry has been added or removed.\n" +" :type destructive: boolean\n" ); static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args) { PyObject *py_me; Mesh *me; int do_tessface = TRUE; + int is_destructive = TRUE; - if (!PyArg_ParseTuple(args, "O|i:update_edit_mesh", &py_me, &do_tessface)) { + if (!PyArg_ParseTuple(args, "O|ii:update_edit_mesh", &py_me, &do_tessface, &is_destructive)) { return NULL; } @@ -131,13 +134,8 @@ static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args) } { - /* XXX, not great - infact this function could just not use the context at all - * postpone that change until after release: BMESH_TODO - campbell */ - extern struct bContext *BPy_GetContext(void); - extern void EDBM_update_generic(struct bContext *C, BMEditMesh *em, const short do_tessface); - - struct bContext *C = BPy_GetContext(); - EDBM_update_generic(C, me->edit_btmesh, do_tessface); + extern void EDBM_update_generic(BMEditMesh *em, const short do_tessface, const short is_destructive); + EDBM_update_generic(me->edit_btmesh, do_tessface, is_destructive); } Py_RETURN_NONE; diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt index bd660b94321..b2ce33b08c7 100644 --- a/source/blender/python/intern/CMakeLists.txt +++ b/source/blender/python/intern/CMakeLists.txt @@ -48,6 +48,7 @@ set(SRC bpy.c bpy_app.c bpy_app_ffmpeg.c + bpy_app_build_options.c bpy_app_handlers.c bpy_driver.c bpy_interface.c @@ -69,6 +70,7 @@ set(SRC bpy.h bpy_app.h bpy_app_ffmpeg.h + bpy_app_build_options.h bpy_app_handlers.h bpy_driver.h bpy_intern_string.h @@ -97,24 +99,136 @@ if(WITH_PYTHON_SAFETY) add_definitions(-DWITH_PYTHON_SAFETY) endif() + + if(WITH_AUDASPACE) add_definitions(-DWITH_AUDASPACE) endif() -if(WITH_CYCLES) - add_definitions(-DWITH_CYCLES) +if(WITH_BULLET) + add_definitions(-DWITH_BULLET) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) +if(WITH_CODEC_AVI) + add_definitions(-DWITH_AVI) endif() if(WITH_CODEC_FFMPEG) list(APPEND INC_SYS ${FFMPEG_INCLUDE_DIRS} ) - add_definitions(-DWITH_FFMPEG) endif() +if(WITH_CODEC_QUICKTIME) + add_definitions(-DWITH_QUICKTIME) +endif() + +if(WITH_CODEC_SNDFILE) + add_definitions(-DWITH_SNDFILE) +endif() + +if(WITH_COMPOSITOR) + add_definitions(-DWITH_COMPOSITOR) +endif() + +if(WITH_CYCLES) + add_definitions(-DWITH_CYCLES) +endif() + +if(WITH_CYCLES_OSL) + add_definitions(-DWITH_CYCLES_OSL) +endif() + +if(WITH_GAMEENGINE) + add_definitions(-DWITH_GAMEENGINE) +endif() + +if(WITH_IMAGE_CINEON) + add_definitions(-DWITH_CINEON) +endif() + +if(WITH_IMAGE_DDS) + add_definitions(-DWITH_DDS) +endif() + +if(WITH_IMAGE_FRAMESERVER) + add_definitions(-DWITH_FRAMESERVER) +endif() + +if(WITH_IMAGE_HDR) + add_definitions(-DWITH_HDR) +endif() + +if(WITH_IMAGE_OPENEXR) + add_definitions(-DWITH_OPENEXR) +endif() + +if(WITH_IMAGE_OPENJPEG) + add_definitions(-DWITH_OPENJPEG) +endif() + +if(WITH_IMAGE_REDCODE) + add_definitions(-DWITH_REDCODE) +endif() + +if(WITH_IMAGE_TIFF) + add_definitions(-DWITH_TIFF) +endif() + +if(WITH_INPUT_NDOF) + add_definitions(-DWITH_INPUT_NDOF) +endif() + +if(WITH_INTERNATIONAL) + add_definitions(-DWITH_INTERNATIONAL) +endif() + +if(WITH_JACK) + add_definitions(-DWITH_JACK) +endif() + +if(WITH_LIBMV) + add_definitions(-DWITH_LIBMV) +endif() + +if(WITH_LIBMV) + add_definitions(-DWITH_LIBMV) +endif() + +if(WITH_MOD_BOOLEAN) + add_definitions(-DWITH_MOD_BOOLEAN) +endif() + +if(WITH_MOD_FLUID) + add_definitions(-DWITH_MOD_FLUID) +endif() + +if(WITH_MOD_OCEANSIM) + add_definitions(-DWITH_OCEANSIM) +endif() + +if(WITH_MOD_REMESH) + add_definitions(-DWITH_MOD_REMESH) +endif() + +if(WITH_MOD_SMOKE) + add_definitions(-DWITH_SMOKE) +endif() + +if(WITH_OPENAL) + add_definitions(-DWITH_OPENAL) +endif() + +if(WITH_OPENCOLLADA) + add_definitions(-DWITH_COLLADA) +endif() + +if(WITH_PLAYER) + add_definitions(-DWITH_PLAYER) +endif() + + + + blender_add_lib(bf_python "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c index 6897a8591b0..b0dd8a29fbe 100644 --- a/source/blender/python/intern/bpy.c +++ b/source/blender/python/intern/bpy.c @@ -45,7 +45,7 @@ #include "BLI_path_util.h" #include "BLI_string.h" -#include "BLI_bpath.h" +#include "BKE_bpath.h" #include "BLI_utildefines.h" #include "BKE_main.h" @@ -129,13 +129,13 @@ static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObjec return NULL; } - if (absolute) flag |= BLI_BPATH_TRAVERSE_ABS; - if (!packed) flag |= BLI_BPATH_TRAVERSE_SKIP_PACKED; - if (local) flag |= BLI_BPATH_TRAVERSE_SKIP_LIBRARY; + if (absolute) flag |= BKE_BPATH_TRAVERSE_ABS; + if (!packed) flag |= BKE_BPATH_TRAVERSE_SKIP_PACKED; + if (local) flag |= BKE_BPATH_TRAVERSE_SKIP_LIBRARY; list = PyList_New(0); - BLI_bpath_traverse_main(G.main, bpy_blend_paths_visit_cb, flag, (void *)list); + BKE_bpath_traverse_main(G.main, bpy_blend_paths_visit_cb, flag, (void *)list); return list; } diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c index b1eeff8b3ae..bea63d2b6e8 100644 --- a/source/blender/python/intern/bpy_app.c +++ b/source/blender/python/intern/bpy_app.c @@ -34,6 +34,7 @@ #include "bpy_app.h" #include "bpy_app_ffmpeg.h" +#include "bpy_app_build_options.h" #include "bpy_app_handlers.h" #include "bpy_driver.h" @@ -83,6 +84,7 @@ static PyStructSequence_Field app_info_fields[] = { /* submodules */ {(char *)"ffmpeg", (char *)"FFmpeg library information backend"}, + {(char *)"build_options", (char *)"A set containing most important enabled optional build features"}, {(char *)"handlers", (char *)"Application handler callbacks"}, {NULL} }; @@ -148,6 +150,7 @@ static PyObject *make_app_info(void) #endif SetObjItem(BPY_app_ffmpeg_struct()); + SetObjItem(BPY_app_build_options_struct()); SetObjItem(BPY_app_handlers_struct()); #undef SetIntItem diff --git a/source/blender/python/intern/bpy_app_build_options.c b/source/blender/python/intern/bpy_app_build_options.c new file mode 100644 index 00000000000..607613b592c --- /dev/null +++ b/source/blender/python/intern/bpy_app_build_options.c @@ -0,0 +1,176 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Bastien Montagne + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/python/intern/bpy_app_build_options.c + * \ingroup pythonintern + */ + +#include <Python.h> +#include "BLI_utildefines.h" + +#include "bpy_app_build_options.h" + +static PyObject *make_build_options(void) +{ + PyObject *build_options = PyFrozenSet_New(NULL); + +#define SetStrItem(str) \ + PySet_Add(build_options, PyUnicode_FromString(str)); + +#ifdef WITH_AUDASPACE + SetStrItem("AUDASPACE"); +#endif + +#ifdef WITH_BULLET + SetStrItem("BULLET"); +#endif + +#ifdef WITH_AVI + SetStrItem("CODEC_AVI"); +#endif + +#ifdef WITH_FFMPEG + SetStrItem("CODEC_FFMPEG"); +#endif + +#ifdef WITH_QUICKTIME + SetStrItem("CODEC_QUICKTIME"); +#endif + +#ifdef WITH_SNDFILE + SetStrItem("CODEC_SNDFILE"); +#endif + +#ifdef WITH_COMPOSITOR + SetStrItem("COMPOSITOR"); +#endif + +#ifdef WITH_CYCLES + SetStrItem("CYCLES"); +#endif + +#ifdef WITH_CYCLES_OSL + SetStrItem("CYCLES_OSL"); +#endif + +#ifdef WITH_GAMEENGINE + SetStrItem("GAMEENGINE"); +#endif + +#ifdef WITH_CINEON + SetStrItem("IMAGE_CINEON"); +#endif + +#ifdef WITH_DDS + SetStrItem("IMAGE_DDS"); +#endif + +#ifdef WITH_FRAMESERVER + SetStrItem("IMAGE_FRAMESERVER"); +#endif + +#ifdef WITH_HDR + SetStrItem("IMAGE_HDR"); +#endif + +#ifdef WITH_OPENEXR + SetStrItem("IMAGE_OPENEXR"); +#endif + +#ifdef WITH_OPENJPEG + SetStrItem("IMAGE_OPENJPEG"); +#endif + +#ifdef WITH_REDCODE + SetStrItem("IMAGE_REDCODE"); +#endif + +#ifdef WITH_TIFF + SetStrItem("IMAGE_TIFF"); +#endif + +#ifdef WITH_INPUT_NDOF + SetStrItem("INPUT_NDOF"); +#endif + +#ifdef WITH_INTERNATIONAL + SetStrItem("INTERNATIONAL"); +#endif + +#ifdef WITH_JACK + SetStrItem("JACK"); +#endif + +#ifdef WITH_LIBMV + SetStrItem("LIBMV"); +#endif + +#ifdef WITH_MOD_BOOLEAN + SetStrItem("MOD_BOOLEAN"); +#endif + +#ifdef WITH_MOD_FLUID + SetStrItem("MOD_FLUID"); +#endif + +#ifdef WITH_OCEANSIM + SetStrItem("MOD_OCEANSIM"); +#endif + +#ifdef WITH_MOD_REMESH + SetStrItem("MOD_REMESH"); +#endif + +#ifdef WITH_SMOKE + SetStrItem("MOD_SMOKE"); +#endif + +#ifdef WITH_OPENAL + SetStrItem("OPENAL"); +#endif + +#ifdef WITH_COLLADA + SetStrItem("COLLADA"); +#endif + +#ifdef WITH_PLAYER + SetStrItem("PLAYER"); +#endif + +#undef SetStrItem + + if (PyErr_Occurred()) { + Py_CLEAR(build_options); + return NULL; + } + + return build_options; +} + +PyObject *BPY_app_build_options_struct(void) +{ + PyObject *ret; + + ret = make_build_options(); + + return ret; +} diff --git a/source/blender/python/intern/bpy_app_build_options.h b/source/blender/python/intern/bpy_app_build_options.h new file mode 100644 index 00000000000..82a1417ea2c --- /dev/null +++ b/source/blender/python/intern/bpy_app_build_options.h @@ -0,0 +1,32 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Bastien Montagne + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/python/intern/bpy_app_build_options.h + * \ingroup pythonintern + */ + +#ifndef __BPY_APP_BUILD_OPTIONS_H__ +#define __BPY_APP_BUILD_OPTIONS_H__ + +PyObject *BPY_app_build_options_struct(void); + +#endif /* __BPY_APP_BUILD_OPTIONS_H__ */ diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index a0df8988068..55983c73895 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1478,7 +1478,7 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const cha } -static PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func) +static PyObject *pyrna_func_to_py(const PointerRNA *ptr, FunctionRNA *func) { BPy_FunctionRNA *pyfunc = (BPy_FunctionRNA *) PyObject_NEW(BPy_FunctionRNA, &pyrna_func_Type); pyfunc->ptr = *ptr; @@ -6029,6 +6029,27 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna) PyObject_SetAttr(newclass, bpy_intern_str_bl_rna, item); Py_DECREF(item); + /* add classmethods */ + { + const PointerRNA func_ptr = {{NULL}, srna, NULL}; + const ListBase *lb; + Link *link; + + lb = RNA_struct_type_functions(srna); + for (link = lb->first; link; link = link->next) { + FunctionRNA *func = (FunctionRNA *)link; + const int flag = RNA_function_flag(func); + if ((flag & FUNC_NO_SELF) && /* is classmethod */ + (flag & FUNC_REGISTER) == FALSE) /* is not for registration */ + { + /* we may went to set the type of this later */ + PyObject *func_py = pyrna_func_to_py(&func_ptr, func); + PyObject_SetAttrString(newclass, RNA_function_identifier(func), func_py); + Py_DECREF(func_py); + } + } + } + /* done with rna instance */ } diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c index 05306f230d1..da2888045d0 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.c +++ b/source/blender/python/mathutils/mathutils_Matrix.c @@ -1025,13 +1025,13 @@ static PyObject *Matrix_resize_4x4(MatrixObject *self) int col; if (self->wrapped == Py_WRAP) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.resize_4x4(): " "cannot resize wrapped data - make a copy and resize that"); return NULL; } if (self->cb_user) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.resize_4x4(): " "cannot resize owned data - make a copy and resize that"); return NULL; @@ -1080,7 +1080,7 @@ static PyObject *Matrix_to_4x4(MatrixObject *self) } /* TODO, 2x2 matrix */ - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.to_4x4(): " "inappropriate matrix size"); return NULL; @@ -1102,7 +1102,7 @@ static PyObject *Matrix_to_3x3(MatrixObject *self) return NULL; if ((self->num_row < 3) || (self->num_col < 3)) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.to_3x3(): inappropriate matrix size"); return NULL; } @@ -1126,7 +1126,7 @@ static PyObject *Matrix_to_translation(MatrixObject *self) return NULL; if ((self->num_row < 3) || self->num_col < 4) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.to_translation(): " "inappropriate matrix size"); return NULL; @@ -1156,7 +1156,7 @@ static PyObject *Matrix_to_scale(MatrixObject *self) /*must be 3-4 cols, 3-4 rows, square matrix */ if ((self->num_row < 3) || (self->num_col < 3)) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.to_scale(): " "inappropriate matrix size, 3x3 minimum size"); return NULL; @@ -1194,7 +1194,7 @@ static PyObject *Matrix_invert(MatrixObject *self) return NULL; if (self->num_col != self->num_row) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.invert(ed): " "only square matrices are supported"); return NULL; @@ -1222,7 +1222,7 @@ static PyObject *Matrix_invert(MatrixObject *self) break; } default: - PyErr_Format(PyExc_TypeError, + PyErr_Format(PyExc_ValueError, "Matrix invert(ed): size (%d) unsupported", (int)self->num_col); return NULL; @@ -1281,7 +1281,7 @@ static PyObject *Matrix_adjugate(MatrixObject *self) return NULL; if (self->num_col != self->num_row) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.adjugate(d): " "only square matrices are supported"); return NULL; @@ -1311,7 +1311,7 @@ static PyObject *Matrix_adjugate(MatrixObject *self) break; } default: - PyErr_Format(PyExc_TypeError, + PyErr_Format(PyExc_ValueError, "Matrix adjugate(d): size (%d) unsupported", (int)self->num_col); return NULL; @@ -1357,7 +1357,7 @@ static PyObject *Matrix_rotate(MatrixObject *self, PyObject *value) return NULL; if (self->num_row != 3 || self->num_col != 3) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.rotate(): " "must have 3x3 dimensions"); return NULL; @@ -1390,7 +1390,7 @@ static PyObject *Matrix_decompose(MatrixObject *self) float size[3]; if (self->num_row != 4 || self->num_col != 4) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.decompose(): " "inappropriate matrix size - expects 4x4 matrix"); return NULL; @@ -1476,7 +1476,7 @@ static PyObject *Matrix_determinant(MatrixObject *self) return NULL; if (self->num_col != self->num_row) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.determinant(): " "only square matrices are supported"); return NULL; @@ -1498,7 +1498,7 @@ static PyObject *Matrix_transpose(MatrixObject *self) return NULL; if (self->num_col != self->num_row) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.transpose(d): " "only square matrices are supported"); return NULL; @@ -1533,6 +1533,53 @@ static PyObject *Matrix_transposed(MatrixObject *self) return matrix__apply_to_copy((PyNoArgsFunction)Matrix_transpose, self); } +/*---------------------------matrix.normalize() ------------------*/ +PyDoc_STRVAR(Matrix_normalize_doc, +".. method:: normalize()\n" +"\n" +" Normalize each of the matrix columns.\n" +); +static PyObject *Matrix_normalize(MatrixObject *self) +{ + if (BaseMath_ReadCallback(self) == -1) + return NULL; + + if (self->num_col != self->num_row) { + PyErr_SetString(PyExc_ValueError, + "Matrix.normalize(): " + "only square matrices are supported"); + return NULL; + } + + if (self->num_col == 3) { + normalize_m3((float (*)[3])self->matrix); + } + else if (self->num_col == 4) { + normalize_m4((float (*)[4])self->matrix); + } + else { + PyErr_SetString(PyExc_ValueError, + "Matrix.normalize(): " + "can only use a 3x3 or 4x4 matrix"); + } + + (void)BaseMath_WriteCallback(self); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(Matrix_normalized_doc, +".. method:: normalized()\n" +"\n" +" Return a column normalized matrix\n" +"\n" +" :return: a column normalized matrix\n" +" :rtype: :class:`Matrix`\n" +); +static PyObject *Matrix_normalized(MatrixObject *self) +{ + return matrix__apply_to_copy((PyNoArgsFunction)Matrix_normalize, self); +} + /*---------------------------matrix.zero() -----------------------*/ PyDoc_STRVAR(Matrix_zero_doc, ".. method:: zero()\n" @@ -1568,7 +1615,7 @@ static PyObject *Matrix_identity(MatrixObject *self) return NULL; if (self->num_col != self->num_row) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix.identity(): " "only square matrices are supported"); return NULL; @@ -1924,7 +1971,7 @@ static PyObject *Matrix_add(PyObject *m1, PyObject *m2) return NULL; if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix addition: " "matrices must have the same dimensions for this operation"); return NULL; @@ -1956,7 +2003,7 @@ static PyObject *Matrix_sub(PyObject *m1, PyObject *m2) return NULL; if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) { - PyErr_SetString(PyExc_TypeError, + PyErr_SetString(PyExc_ValueError, "Matrix addition: " "matrices must have the same dimensions for this operation"); return NULL; @@ -2371,6 +2418,8 @@ static struct PyMethodDef Matrix_methods[] = { /* operate on original or copy */ {"transpose", (PyCFunction) Matrix_transpose, METH_NOARGS, Matrix_transpose_doc}, {"transposed", (PyCFunction) Matrix_transposed, METH_NOARGS, Matrix_transposed_doc}, + {"normalize", (PyCFunction) Matrix_normalize, METH_NOARGS, Matrix_normalize_doc}, + {"normalized", (PyCFunction) Matrix_normalized, METH_NOARGS, Matrix_normalized_doc}, {"invert", (PyCFunction) Matrix_invert, METH_NOARGS, Matrix_invert_doc}, {"inverted", (PyCFunction) Matrix_inverted, METH_NOARGS, Matrix_inverted_doc}, {"adjugate", (PyCFunction) Matrix_adjugate, METH_NOARGS, Matrix_adjugate_doc}, diff --git a/source/blender/quicktime/SConscript b/source/blender/quicktime/SConscript index db1d4a4f1ab..a32f325de24 100644 --- a/source/blender/quicktime/SConscript +++ b/source/blender/quicktime/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/quicktime/apple/qtkit_export.m b/source/blender/quicktime/apple/qtkit_export.m index e0858cd5ec2..6935c908ee4 100644 --- a/source/blender/quicktime/apple/qtkit_export.m +++ b/source/blender/quicktime/apple/qtkit_export.m @@ -61,7 +61,7 @@ #import <QTKit/QTKit.h> #include <AudioToolbox/AudioToolbox.h> -#if (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4) || !__LP64__ +#if (MAC_OS_X_VERSION_MIN_REQUIRED <= 1040) || !__LP64__ #error 64 bit build & OSX 10.5 minimum are needed for QTKit #endif diff --git a/source/blender/quicktime/quicktime_export.h b/source/blender/quicktime/quicktime_export.h index a3469ddafde..d773cdc8f3a 100644 --- a/source/blender/quicktime/quicktime_export.h +++ b/source/blender/quicktime/quicktime_export.h @@ -87,7 +87,7 @@ void makeqtstring(struct RenderData *rd, char *string); //for playanim.c -#if (defined(USE_QTKIT) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 && __LP64__) +#if (defined(USE_QTKIT) && MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 && __LP64__) //Include the quicktime codec types constants that are missing in QTKitDefines.h enum { kRawCodecType = 'raw ', diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt index 5be10f56d7a..291ee8e44bd 100644 --- a/source/blender/render/CMakeLists.txt +++ b/source/blender/render/CMakeLists.txt @@ -61,6 +61,7 @@ set(SRC intern/source/gammaCorrectionTables.c intern/source/imagetexture.c intern/source/initrender.c + intern/source/multires_bake.c intern/source/occlusion.c intern/source/pipeline.c intern/source/pixelblending.c @@ -84,6 +85,7 @@ set(SRC intern/source/zbuf.c extern/include/RE_engine.h + extern/include/RE_multires_bake.h extern/include/RE_pipeline.h extern/include/RE_render_ext.h extern/include/RE_shader_ext.h diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript index 5addc45571d..0fd180fed65 100644 --- a/source/blender/render/SConscript +++ b/source/blender/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('intern/source/*.c') diff --git a/source/blender/render/extern/include/RE_multires_bake.h b/source/blender/render/extern/include/RE_multires_bake.h new file mode 100644 index 00000000000..5e8ebdd8a18 --- /dev/null +++ b/source/blender/render/extern/include/RE_multires_bake.h @@ -0,0 +1,61 @@ +/* + * ***** 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) 2010 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Morten Mikkelsen, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file RE_multires_bake.h + * \ingroup render + */ + +#ifndef __RE_MULTIRES_BAKE_H__ +#define __RE_MULTIRES_BAKE_H__ + +struct MultiresBakeRender; + +typedef struct MultiresBakeRender { + DerivedMesh *lores_dm, *hires_dm; + int simple, lvl, tot_lvl, bake_filter; + short mode, use_lores_mesh; + + int number_of_rays; + float bias; + + int tot_obj, tot_image; + ListBase image; + + int baked_objects, baked_faces; + + int raytrace_structure; + int octree_resolution; + + short *stop; + short *do_update; + float *progress; +} MultiresBakeRender; + +void RE_multires_bake_images(struct MultiresBakeRender *bkr); + +#endif diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 9d1e2b8e620..56cc0ad9a1c 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -198,7 +198,7 @@ void RE_SetOrtho (struct Render *re, rctf *viewplane, float clipsta, float clipe void RE_SetPixelSize(struct Render *re, float pixsize); /* option to set viewmatrix before making dbase */ -void RE_SetView (struct Render *re, float mat[][4]); +void RE_SetView (struct Render *re, float mat[4][4]); /* make or free the dbase */ void RE_Database_FromScene(struct Render *re, struct Main *bmain, struct Scene *scene, unsigned int lay, int use_camera_view); @@ -274,8 +274,8 @@ int RE_seq_render_active(struct Scene *scene, struct RenderData *rd); void RE_Database_Baking(struct Render *re, struct Main *bmain, struct Scene *scene, unsigned int lay, const int type, struct Object *actob); -void RE_DataBase_GetView(struct Render *re, float mat[][4]); -void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[][4]); +void RE_DataBase_GetView(struct Render *re, float mat[4][4]); +void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4]); struct Scene *RE_GetScene(struct Render *re); int RE_is_rendering_allowed(struct Scene *scene, struct Object *camera_override, struct ReportList *reports); diff --git a/source/blender/render/intern/include/pixelblending.h b/source/blender/render/intern/include/pixelblending.h index bb2e7e7f9f9..19759bf3e97 100644 --- a/source/blender/render/intern/include/pixelblending.h +++ b/source/blender/render/intern/include/pixelblending.h @@ -38,8 +38,8 @@ */ void add_filt_fmask(unsigned int mask, const float col[4], float *rowbuf, int row_w); void add_filt_fmask_pixsize(unsigned int mask, float *in, float *rowbuf, int row_w, int pixsize); -void add_filt_fmask_coord(float filt[][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y); -void mask_array(unsigned int mask, float filt[][3]); +void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y); +void mask_array(unsigned int mask, float filt[3][3]); /** * Alpha-over blending for floats. diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index 07fc7d7a6ed..e9514b8585e 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -56,7 +56,7 @@ int RE_rayobject_raycast(RayObject *r, struct Isect *i); /* Acceleration Structures */ RayObject *RE_rayobject_octree_create(int ocres, int size); -RayObject *RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob); +RayObject *RE_rayobject_instance_create(RayObject *target, float transform[4][4], void *ob, void *target_ob); RayObject *RE_rayobject_empty_create(void); RayObject *RE_rayobject_blibvh_create(int size); /* BLI_kdopbvh.c */ @@ -87,6 +87,8 @@ typedef struct RayFace { RayObject *RE_rayface_from_vlak(RayFace *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr); +RayObject *RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4); + /* RayObject representing faces directly from a given VlakRen structure. Thus * allowing to save memory, but making code triangle intersection dependent on * render structures. */ diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index f7a5a930ac6..45080de3148 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -198,7 +198,6 @@ struct Render ListBase strandsurface; /* use this instead of R.r.cfra */ - float cfra; float mblur_offs, field_offs; /* render database */ diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h index 30712250440..88b639c4ba9 100644 --- a/source/blender/render/intern/include/rendercore.h +++ b/source/blender/render/intern/include/rendercore.h @@ -83,6 +83,8 @@ int get_sample_layers(struct RenderPart *pa, struct RenderLayer *rl, struct Rend /* -------- ray.c ------- */ +struct RayObject *RE_rayobject_create(int type, int size, int octree_resolution); + extern void freeraytree(Render *re); extern void makeraytree(Render *re); struct RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi); diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h index 5213f14d773..24989b13c48 100644 --- a/source/blender/render/intern/include/renderdatabase.h +++ b/source/blender/render/intern/include/renderdatabase.h @@ -87,8 +87,8 @@ void free_renderdata_tables(struct Render *re); void free_renderdata_vertnodes(struct VertTableNode *vertnodes); void free_renderdata_vlaknodes(struct VlakTableNode *vlaknodes); -void project_renderdata(struct Render *re, void (*projectfunc)(const float *, float mat[][4], float *), int do_pano, float xoffs, int do_buckets); -int clip_render_object(float boundbox[][3], float bounds[4], float mat[][4]); +void project_renderdata(struct Render *re, void (*projectfunc)(const float *, float mat[4][4], float *), int do_pano, float xoffs, int do_buckets); +int clip_render_object(float boundbox[2][3], float bounds[4], float mat[4][4]); /* functions are not exported... so wrong names */ @@ -106,7 +106,7 @@ struct HaloRen *RE_inithalo_particle(struct Render *re, struct ObjectRen *obr, s struct StrandBuffer *RE_addStrandBuffer(struct ObjectRen *obr, int totvert); struct ObjectRen *RE_addRenderObject(struct Render *re, struct Object *ob, struct Object *par, int index, int psysindex, int lay); -struct ObjectInstanceRen *RE_addRenderInstance(struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, int index, int psysindex, float mat[][4], int lay); +struct ObjectInstanceRen *RE_addRenderInstance(struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, int index, int psysindex, float mat[4][4], int lay); void RE_makeRenderInstances(struct Render *re); float *RE_vertren_get_stress(struct ObjectRen *obr, struct VertRen *ver, int verify); diff --git a/source/blender/render/intern/include/strand.h b/source/blender/render/intern/include/strand.h index 720354219e9..d9594864bff 100644 --- a/source/blender/render/intern/include/strand.h +++ b/source/blender/render/intern/include/strand.h @@ -92,10 +92,10 @@ struct StrandShadeCache; typedef struct StrandShadeCache StrandShadeCache; void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint); -void render_strand_segment(struct Render *re, float winmat[][4], struct StrandPart *spart, struct ZSpan *zspan, int totzspan, StrandSegment *sseg); +void render_strand_segment(struct Render *re, float winmat[4][4], struct StrandPart *spart, struct ZSpan *zspan, int totzspan, StrandSegment *sseg); void strand_minmax(struct StrandRen *strand, float min[3], float max[3], const float width); -struct StrandSurface *cache_strand_surface(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, float mat[][4], int timeoffset); +struct StrandSurface *cache_strand_surface(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, float mat[4][4], int timeoffset); void free_strand_surface(struct Render *re); struct StrandShadeCache *strand_shade_cache_create(void); diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h index e873111e6bf..162fa3b7e88 100644 --- a/source/blender/render/intern/include/zbuf.h +++ b/source/blender/render/intern/include/zbuf.h @@ -49,17 +49,17 @@ void fillrect(int *rect, int x, int y, int val); * Converts a world coordinate into a homogeneous coordinate in view * coordinates. */ -void projectvert(const float v1[3], float winmat[][4], float adr[4]); -void projectverto(const float v1[3], float winmat[][4], float adr[4]); +void projectvert(const float v1[3], float winmat[4][4], float adr[4]); +void projectverto(const float v1[3], float winmat[4][4], float adr[4]); int testclip(const float v[3]); -void zbuffer_shadow(struct Render *re, float winmat[][4], struct LampRen *lar, int *rectz, int size, float jitx, float jity); -void zbuffer_abuf_shadow(struct Render *re, struct LampRen *lar, float winmat[][4], struct APixstr *APixbuf, struct APixstrand *apixbuf, struct ListBase *apsmbase, int size, int samples, float (*jit)[2]); +void zbuffer_shadow(struct Render *re, float winmat[4][4], struct LampRen *lar, int *rectz, int size, float jitx, float jity); +void zbuffer_abuf_shadow(struct Render *re, struct LampRen *lar, float winmat[4][4], struct APixstr *APixbuf, struct APixstrand *apixbuf, struct ListBase *apsmbase, int size, int samples, float (*jit)[2]); void zbuffer_solid(struct RenderPart *pa, struct RenderLayer *rl, void (*fillfunc)(struct RenderPart *, struct ZSpan *, int, void*), void *data); unsigned short *zbuffer_transp_shade(struct RenderPart *pa, struct RenderLayer *rl, float *pass, struct ListBase *psmlist); void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(void*, int, int, int, int, int)); -int zbuffer_strands_abuf(struct Render *re, struct RenderPart *pa, struct APixstrand *apixbuf, struct ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[][4], int winx, int winy, int sample, float (*jit)[2], float clipcrop, int shadow, struct StrandShadeCache *cache); +int zbuffer_strands_abuf(struct Render *re, struct RenderPart *pa, struct APixstrand *apixbuf, struct ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[4][4], int winx, int winy, int sample, float (*jit)[2], float clipcrop, int shadow, struct StrandShadeCache *cache); typedef struct APixstr { unsigned short mask[4]; /* jitter mask */ @@ -136,8 +136,8 @@ void zbufclipwire(struct ZSpan *zspan, int obi, int zvlnr, int ec, float *ho1, float *ho2, float *ho3, float *ho4, int c1, int c2, int c3, int c4); /* exported to shadeinput.c */ -void zbuf_make_winmat(Render *re, float winmat[][4]); -void zbuf_render_project(float winmat[][4], const float co[3], float ho[4]); +void zbuf_make_winmat(Render *re, float winmat[4][4]); +void zbuf_render_project(float winmat[4][4], const float co[3], float ho[4]); /* sould not really be exposed, bad! */ void hoco_to_zco(ZSpan *zspan, float zco[3], const float hoco[4]); diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp index c3babf99d51..b31aff82777 100644 --- a/source/blender/render/intern/raytrace/rayobject.cpp +++ b/source/blender/render/intern/raytrace/rayobject.cpp @@ -90,6 +90,11 @@ RayObject *RE_rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRe return rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : 0); } +RayObject *RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4) +{ + return rayface_from_coords(rayface, ob, face, v1, v2, v3, v4); +} + /* VlakPrimitive */ RayObject *RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstanceRen *obi, struct VlakRen *vlr) diff --git a/source/blender/render/intern/raytrace/rayobject_instance.cpp b/source/blender/render/intern/raytrace/rayobject_instance.cpp index f797f7a4311..f9ed012b117 100644 --- a/source/blender/render/intern/raytrace/rayobject_instance.cpp +++ b/source/blender/render/intern/raytrace/rayobject_instance.cpp @@ -75,7 +75,7 @@ typedef struct InstanceRayObject { } InstanceRayObject; -RayObject *RE_rayobject_instance_create(RayObject *target, float transform[][4], void *ob, void *target_ob) +RayObject *RE_rayobject_instance_create(RayObject *target, float transform[4][4], void *ob, void *target_ob) { InstanceRayObject *obj = (InstanceRayObject *)MEM_callocN(sizeof(InstanceRayObject), "InstanceRayObject"); assert(RE_rayobject_isAligned(obj) ); /* RayObject API assumes real data to be 4-byte aligned */ diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp index afb8fe6c3b5..dad7fe5fd60 100644 --- a/source/blender/render/intern/raytrace/rayobject_octree.cpp +++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp @@ -223,7 +223,7 @@ static Node *addnode(Octree *oc) return oc->adrnode[index] + (oc->nodecount & 4095); } -static int face_in_node(RayFace *face, short x, short y, short z, float rtf[][3]) +static int face_in_node(RayFace *face, short x, short y, short z, float rtf[4][3]) { static float nor[3], d; float fx, fy, fz; @@ -321,12 +321,12 @@ static void ocwrite(Octree *oc, RayFace *face, int quad, short x, short y, short calc_ocval_face(rtf[0], rtf[1], rtf[2], NULL, x >> 2, y >> 1, z, &no->ov[a]); } -static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocface, short rts[][3], float rtf[][3]) +static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocface, short rts[4][3], float rtf[4][3]) { int ocx1, ocx2, ocy1, ocy2; int x, y, dx = 0, dy = 0; float ox1, ox2, oy1, oy2; - float labda, labdao, labdax, labday, ldx, ldy; + float lambda, lambda_o, lambda_x, lambda_y, ldx, ldy; ocx1 = rts[b1][c1]; ocy1 = rts[b1][c2]; @@ -345,40 +345,40 @@ static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocfa if (ox1 != ox2) { if (ox2 - ox1 > 0.0f) { - labdax = (ox1 - ocx1 - 1.0f) / (ox1 - ox2); + lambda_x = (ox1 - ocx1 - 1.0f) / (ox1 - ox2); ldx = -1.0f / (ox1 - ox2); dx = 1; } else { - labdax = (ox1 - ocx1) / (ox1 - ox2); + lambda_x = (ox1 - ocx1) / (ox1 - ox2); ldx = 1.0f / (ox1 - ox2); dx = -1; } } else { - labdax = 1.0f; + lambda_x = 1.0f; ldx = 0; } if (oy1 != oy2) { if (oy2 - oy1 > 0.0f) { - labday = (oy1 - ocy1 - 1.0f) / (oy1 - oy2); + lambda_y = (oy1 - ocy1 - 1.0f) / (oy1 - oy2); ldy = -1.0f / (oy1 - oy2); dy = 1; } else { - labday = (oy1 - ocy1) / (oy1 - oy2); + lambda_y = (oy1 - ocy1) / (oy1 - oy2); ldy = 1.0f / (oy1 - oy2); dy = -1; } } else { - labday = 1.0f; + lambda_y = 1.0f; ldy = 0; } x = ocx1; y = ocy1; - labda = MIN2(labdax, labday); + lambda = MIN2(lambda_x, lambda_y); while (TRUE) { @@ -389,26 +389,26 @@ static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocfa ocface[oc->ocres * x + y] = 1; } - labdao = labda; - if (labdax == labday) { - labdax += ldx; + lambda_o = lambda; + if (lambda_x == lambda_y) { + lambda_x += ldx; x += dx; - labday += ldy; + lambda_y += ldy; y += dy; } else { - if (labdax < labday) { - labdax += ldx; + if (lambda_x < lambda_y) { + lambda_x += ldx; x += dx; } else { - labday += ldy; + lambda_y += ldy; y += dy; } } - labda = MIN2(labdax, labday); - if (labda == labdao) break; - if (labda >= 1.0f) break; + lambda = MIN2(lambda_x, lambda_y); + if (lambda == lambda_o) break; + if (lambda >= 1.0f) break; } ocface[oc->ocres * ocx2 + ocy2] = 1; } @@ -851,8 +851,8 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is) OcVal ocval; float vec1[3], vec2[3], start[3], end[3]; float u1, u2, ox1, ox2, oy1, oy2, oz1, oz2; - float labdao, labdax, ldx, labday, ldy, labdaz, ldz, ddalabda; - float olabda = 0; + float lambda_o, lambda_x, ldx, lambda_y, ldy, lambda_z, ldz, dda_lambda; + float o_lambda = 0; int dx, dy, dz; int xo, yo, zo, c1 = 0; int ocx1, ocx2, ocy1, ocy2, ocz1, ocz2; @@ -871,7 +871,7 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is) copy_v3_v3(start, is->start); madd_v3_v3v3fl(end, is->start, is->dir, is->dist); ldx = is->dir[0] * is->dist; - olabda = is->dist; + o_lambda = is->dist; u1 = 0.0f; u2 = 1.0f; @@ -939,68 +939,68 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is) float dox, doy, doz; int eqval; - /* calc labda en ld */ + /* calc lambda en ld */ dox = ox1 - ox2; doy = oy1 - oy2; doz = oz1 - oz2; if (dox < -FLT_EPSILON) { ldx = -1.0f / dox; - labdax = (ocx1 - ox1 + 1.0f) * ldx; + lambda_x = (ocx1 - ox1 + 1.0f) * ldx; dx = 1; } else if (dox > FLT_EPSILON) { ldx = 1.0f / dox; - labdax = (ox1 - ocx1) * ldx; + lambda_x = (ox1 - ocx1) * ldx; dx = -1; } else { - labdax = 1.0f; + lambda_x = 1.0f; ldx = 0; dx = 0; } if (doy < -FLT_EPSILON) { ldy = -1.0f / doy; - labday = (ocy1 - oy1 + 1.0f) * ldy; + lambda_y = (ocy1 - oy1 + 1.0f) * ldy; dy = 1; } else if (doy > FLT_EPSILON) { ldy = 1.0f / doy; - labday = (oy1 - ocy1) * ldy; + lambda_y = (oy1 - ocy1) * ldy; dy = -1; } else { - labday = 1.0f; + lambda_y = 1.0f; ldy = 0; dy = 0; } if (doz < -FLT_EPSILON) { ldz = -1.0f / doz; - labdaz = (ocz1 - oz1 + 1.0f) * ldz; + lambda_z = (ocz1 - oz1 + 1.0f) * ldz; dz = 1; } else if (doz > FLT_EPSILON) { ldz = 1.0f / doz; - labdaz = (oz1 - ocz1) * ldz; + lambda_z = (oz1 - ocz1) * ldz; dz = -1; } else { - labdaz = 1.0f; + lambda_z = 1.0f; ldz = 0; dz = 0; } xo = ocx1; yo = ocy1; zo = ocz1; - ddalabda = MIN3(labdax, labday, labdaz); + dda_lambda = MIN3(lambda_x, lambda_y, lambda_z); vec2[0] = ox1; vec2[1] = oy1; vec2[2] = oz1; /* this loop has been constructed to make sure the first and last node of ray - * are always included, even when ddalabda==1.0f or larger */ + * are always included, even when dda_lambda==1.0f or larger */ while (TRUE) { @@ -1010,83 +1010,83 @@ static int RE_rayobject_octree_intersect(RayObject *tree, Isect *is) /* calculate ray intersection with octree node */ copy_v3_v3(vec1, vec2); // dox, y, z is negative - vec2[0] = ox1 - ddalabda * dox; - vec2[1] = oy1 - ddalabda * doy; - vec2[2] = oz1 - ddalabda * doz; + vec2[0] = ox1 - dda_lambda * dox; + vec2[1] = oy1 - dda_lambda * doy; + vec2[2] = oz1 - dda_lambda * doz; calc_ocval_ray(&ocval, (float)xo, (float)yo, (float)zo, vec1, vec2); - //is->dist = (u1+ddalabda*(u2-u1))*olabda; + //is->dist = (u1+dda_lambda*(u2-u1))*o_lambda; if (testnode(oc, is, no, ocval) ) found = 1; - if (is->dist < (u1 + ddalabda * (u2 - u1)) * olabda) + if (is->dist < (u1 + dda_lambda * (u2 - u1)) * o_lambda) return found; } - labdao = ddalabda; + lambda_o = dda_lambda; /* traversing octree nodes need careful detection of smallest values, with proper - * exceptions for equal labdas */ - eqval = (labdax == labday); - if (labday == labdaz) eqval += 2; - if (labdax == labdaz) eqval += 4; + * exceptions for equal lambdas */ + eqval = (lambda_x == lambda_y); + if (lambda_y == lambda_z) eqval += 2; + if (lambda_x == lambda_z) eqval += 4; if (eqval) { // only 4 cases exist! if (eqval == 7) { // x=y=z - xo += dx; labdax += ldx; - yo += dy; labday += ldy; - zo += dz; labdaz += ldz; + xo += dx; lambda_x += ldx; + yo += dy; lambda_y += ldy; + zo += dz; lambda_z += ldz; } else if (eqval == 1) { // x=y - if (labday < labdaz) { - xo += dx; labdax += ldx; - yo += dy; labday += ldy; + if (lambda_y < lambda_z) { + xo += dx; lambda_x += ldx; + yo += dy; lambda_y += ldy; } else { - zo += dz; labdaz += ldz; + zo += dz; lambda_z += ldz; } } else if (eqval == 2) { // y=z - if (labdax < labday) { - xo += dx; labdax += ldx; + if (lambda_x < lambda_y) { + xo += dx; lambda_x += ldx; } else { - yo += dy; labday += ldy; - zo += dz; labdaz += ldz; + yo += dy; lambda_y += ldy; + zo += dz; lambda_z += ldz; } } else { // x=z - if (labday < labdax) { - yo += dy; labday += ldy; + if (lambda_y < lambda_x) { + yo += dy; lambda_y += ldy; } else { - xo += dx; labdax += ldx; - zo += dz; labdaz += ldz; + xo += dx; lambda_x += ldx; + zo += dz; lambda_z += ldz; } } } else { // all three different, just three cases exist - eqval = (labdax < labday); - if (labday < labdaz) eqval += 2; - if (labdax < labdaz) eqval += 4; + eqval = (lambda_x < lambda_y); + if (lambda_y < lambda_z) eqval += 2; + if (lambda_x < lambda_z) eqval += 4; if (eqval == 7 || eqval == 5) { // x smallest - xo += dx; labdax += ldx; + xo += dx; lambda_x += ldx; } else if (eqval == 2 || eqval == 6) { // y smallest - yo += dy; labday += ldy; + yo += dy; lambda_y += ldy; } else { // z smallest - zo += dz; labdaz += ldz; + zo += dz; lambda_z += ldz; } } - ddalabda = MIN3(labdax, labday, labdaz); - if (ddalabda == labdao) break; + dda_lambda = MIN3(lambda_x, lambda_y, lambda_z); + if (dda_lambda == lambda_o) break; /* to make sure the last node is always checked */ - if (labdao >= 1.0f) break; + if (lambda_o >= 1.0f) break; } } diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index f87478bb663..bc84661698f 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -760,7 +760,7 @@ static VertRen *as_findvertex(VlakRen *vlr, VertRen *UNUSED(ver), ASvert *asv, f /* note; autosmooth happens in object space still, after applying autosmooth we rotate */ /* note2; actually, when original mesh and displist are equal sized, face normals are from original mesh */ -static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[][4], int degr) +static void autosmooth(Render *UNUSED(re), ObjectRen *obr, float mat[4][4], int degr) { ASvert *asv, *asverts; ASface *asf; @@ -2187,7 +2187,7 @@ static short test_for_displace(Render *re, Object *ob) return 0; } -static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, VertRen *vr, int vindex, float *scale, float mat[][4], float imat[][3]) +static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, VertRen *vr, int vindex, float *scale, float mat[4][4], float imat[3][3]) { MTFace *tface; short texco= shi->mat->texco; @@ -2286,7 +2286,7 @@ static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, Ve return; } -static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float *scale, float mat[][4], float imat[][3]) +static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float *scale, float mat[4][4], float imat[3][3]) { ShadeInput shi; @@ -2341,7 +2341,7 @@ static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float } } -static void do_displacement(Render *re, ObjectRen *obr, float mat[][4], float imat[][3]) +static void do_displacement(Render *re, ObjectRen *obr, float mat[4][4], float imat[3][3]) { VertRen *vr; VlakRen *vlr; @@ -2821,7 +2821,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) ListBase disp={NULL, NULL}; Material **matar; float *data, *fp, *orco=NULL; - float n[3], mat[4][4]; + float n[3], mat[4][4], nmat[4][4]; int nr, startvert, a, b; int need_orco=0, totmat; @@ -2836,6 +2836,11 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) mult_m4_m4m4(mat, re->viewmat, ob->obmat); invert_m4_m4(ob->imat, mat); + /* local object -> world space transform for normals */ + copy_m4_m4(nmat, mat); + transpose_m4(nmat); + invert_m4(nmat); + /* material array */ totmat= ob->totcol+1; matar= MEM_callocN(sizeof(Material*)*totmat, "init_render_surf matar"); @@ -2892,13 +2897,20 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) zero_v3(n); index= dl->index; for (a=0; a<dl->parts; a++, index+=3) { + int v1 = index[0], v2 = index[1], v3 = index[2]; + float *co1 = &dl->verts[v1 * 3], + *co2 = &dl->verts[v2 * 3], + *co3 = &dl->verts[v3 * 3]; + vlr= RE_findOrAddVlak(obr, obr->totvlak++); - vlr->v1= RE_findOrAddVert(obr, startvert+index[0]); - vlr->v2= RE_findOrAddVert(obr, startvert+index[1]); - vlr->v3= RE_findOrAddVert(obr, startvert+index[2]); + vlr->v1= RE_findOrAddVert(obr, startvert + v1); + vlr->v2= RE_findOrAddVert(obr, startvert + v2); + vlr->v3= RE_findOrAddVert(obr, startvert + v3); vlr->v4= NULL; - if (area_tri_v3(vlr->v3->co, vlr->v2->co, vlr->v1->co)>FLT_EPSILON10) { - normal_tri_v3(tmp, vlr->v3->co, vlr->v2->co, vlr->v1->co); + + /* to prevent float accuracy issues, we calculate normal in local object space (not world) */ + if (area_tri_v3(co3, co2, co1)>FLT_EPSILON10) { + normal_tri_v3(tmp, co3, co2, co1); add_v3_v3(n, tmp); } @@ -2907,6 +2919,8 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) vlr->ec= 0; } + /* transform normal to world space */ + mul_m4_v3(nmat, n); normalize_v3(n); /* vertex normals */ @@ -3159,7 +3173,12 @@ static void init_camera_inside_volumes(Render *re) { ObjectInstanceRen *obi; VolumeOb *vo; - float co[3] = {0.f, 0.f, 0.f}; + /* coordinates are all in camera space, so camera coordinate is zero. we also + * add an offset for the clip start, however note that with clip start it's + * actually impossible to do a single 'inside' test, since there will not be + * a single point where all camera rays start from, though for small clip start + * they will be close together. */ + float co[3] = {0.f, 0.f, -re->clipsta}; for (vo= re->volumes.first; vo; vo= vo->next) { for (obi= re->instancetable.first; obi; obi= obi->next) { @@ -3563,7 +3582,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) /* Lamps and Shadowbuffers */ /* ------------------------------------------------------------------------- */ -static void initshadowbuf(Render *re, LampRen *lar, float mat[][4]) +static void initshadowbuf(Render *re, LampRen *lar, float mat[4][4]) { struct ShadBuf *shb; float viewinv[4][4]; @@ -5196,7 +5215,7 @@ void RE_DataBase_ApplyWindow(Render *re) project_renderdata(re, projectverto, 0, 0, 0); } -void RE_DataBase_GetView(Render *re, float mat[][4]) +void RE_DataBase_GetView(Render *re, float mat[4][4]) { copy_m4_m4(mat, re->viewmat); } diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index c3126e57b53..be8b7f6c357 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -210,7 +210,7 @@ static void envmap_free_render_copy(Render *envre) /* ------------------------------------------------------------------------- */ -static void envmap_transmatrix(float mat[][4], int part) +static void envmap_transmatrix(float mat[4][4], int part) { float tmat[4][4], eul[3], rotmat[4][4]; @@ -247,7 +247,7 @@ static void envmap_transmatrix(float mat[][4], int part) /* ------------------------------------------------------------------------- */ -static void env_rotate_scene(Render *re, float mat[][4], int mode) +static void env_rotate_scene(Render *re, float mat[4][4], int mode) { GroupObject *go; ObjectRen *obr; @@ -587,53 +587,53 @@ void make_envmaps(Render *re) static int envcube_isect(EnvMap *env, const float vec[3], float answ[2]) { - float labda; + float lambda; int face; if (env->type == ENV_PLANE) { face = 1; - labda = 1.0f / vec[2]; - answ[0] = env->viewscale * labda * vec[0]; - answ[1] = -env->viewscale * labda * vec[1]; + lambda = 1.0f / vec[2]; + answ[0] = env->viewscale * lambda * vec[0]; + answ[1] = -env->viewscale * lambda * vec[1]; } else { /* which face */ if (vec[2] <= -fabsf(vec[0]) && vec[2] <= -fabsf(vec[1]) ) { face = 0; - labda = -1.0f / vec[2]; - answ[0] = labda * vec[0]; - answ[1] = labda * vec[1]; + lambda = -1.0f / vec[2]; + answ[0] = lambda * vec[0]; + answ[1] = lambda * vec[1]; } else if (vec[2] >= fabsf(vec[0]) && vec[2] >= fabsf(vec[1])) { face = 1; - labda = 1.0f / vec[2]; - answ[0] = labda * vec[0]; - answ[1] = -labda * vec[1]; + lambda = 1.0f / vec[2]; + answ[0] = lambda * vec[0]; + answ[1] = -lambda * vec[1]; } else if (vec[1] >= fabsf(vec[0])) { face = 2; - labda = 1.0f / vec[1]; - answ[0] = labda * vec[0]; - answ[1] = labda * vec[2]; + lambda = 1.0f / vec[1]; + answ[0] = lambda * vec[0]; + answ[1] = lambda * vec[2]; } else if (vec[0] <= -fabsf(vec[1])) { face = 3; - labda = -1.0f / vec[0]; - answ[0] = labda * vec[1]; - answ[1] = labda * vec[2]; + lambda = -1.0f / vec[0]; + answ[0] = lambda * vec[1]; + answ[1] = lambda * vec[2]; } else if (vec[1] <= -fabsf(vec[0])) { face = 4; - labda = -1.0f / vec[1]; - answ[0] = -labda * vec[0]; - answ[1] = labda * vec[2]; + lambda = -1.0f / vec[1]; + answ[0] = -lambda * vec[0]; + answ[1] = lambda * vec[2]; } else { face = 5; - labda = 1.0f / vec[0]; - answ[0] = -labda * vec[1]; - answ[1] = labda * vec[2]; + lambda = 1.0f / vec[0]; + answ[0] = -lambda * vec[1]; + answ[1] = lambda * vec[2]; } } diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 3ea74abbcc2..0d957f8019f 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -515,7 +515,7 @@ void RE_SetPixelSize(Render *re, float pixsize) re->viewdy = re->ycor * pixsize; } -void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[][4]) +void RE_GetCameraWindow(struct Render *re, struct Object *camera, int frame, float mat[4][4]) { re->r.cfra = frame; RE_SetCamera(re, camera); diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c new file mode 100644 index 00000000000..0eb0c9a51c3 --- /dev/null +++ b/source/blender/render/intern/source/multires_bake.c @@ -0,0 +1,1182 @@ +/* + * ***** 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 by Blender Foundation + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Morten Mikkelsen, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/render/intern/source/multires_bake.c + * \ingroup render + */ + +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_object_types.h" +#include "DNA_mesh_types.h" + +#include "BLI_math.h" +#include "BLI_listbase.h" + +#include "BKE_ccg.h" +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_image.h" +#include "BKE_multires.h" +#include "BKE_modifier.h" +#include "BKE_subsurf.h" + +#include "RE_multires_bake.h" +#include "RE_pipeline.h" +#include "RE_shader_ext.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "rayintersection.h" +#include "rayobject.h" +#include "rendercore.h" + +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; + +typedef struct { + int number_of_rays; + float bias; + + unsigned short *permutation_table_1; + unsigned short *permutation_table_2; + + RayObject *raytree; + RayFace *rayfaces; + + const int *orig_index_mf_to_mpoly; + const int *orig_index_mp_to_orig; +} MAOBakeData; + +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]; + + 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; + + if (data->pvtangent) { + 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; + + /* 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); + } + else { + zero_m3(to_tang); + } + + 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, int require_tangent, 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 (require_tangent) { + 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]); + + if (ibuf->rect_float) + ibuf->userflags |= IB_RECT_INVALID; + + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; + } + + 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); +} + +/* **************** Displacement Baker **************** */ + +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 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); + } + } + } + + if (ibuf->rect_float) + ibuf->userflags |= IB_RECT_INVALID; + + ibuf->userflags |= 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; + } + else { + char *rrgb = (char *)ibuf->rect + pixel * 4; + rrgb[3] = 255; + } +} + +/* **************** Normal Maps Baker **************** */ + +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); +} + +/* 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; + } + else { + unsigned char *rrgb = (unsigned char *)ibuf->rect + pixel * 4; + rgb_float_to_uchar(rrgb, vec); + rrgb[3] = 255; + } +} + +/* **************** Ambient Occlusion Baker **************** */ + +#define MAX_NUMBER_OF_AO_RAYS 1024 + +static unsigned short ao_random_table_1[MAX_NUMBER_OF_AO_RAYS]; +static unsigned short ao_random_table_2[MAX_NUMBER_OF_AO_RAYS]; + +static void init_ao_random(void) +{ + int i; + + for (i = 0; i < MAX_NUMBER_OF_AO_RAYS; i++) { + ao_random_table_1[i] = rand() & 0xffff; + ao_random_table_2[i] = rand() & 0xffff; + } +} + +static unsigned short get_ao_random1(const int i) +{ + return ao_random_table_1[i & (MAX_NUMBER_OF_AO_RAYS - 1)]; +} + +static unsigned short get_ao_random2(const int i) +{ + return ao_random_table_2[i & (MAX_NUMBER_OF_AO_RAYS - 1)]; +} + +static void build_permutation_table(unsigned short permutation[], unsigned short temp_permutation[], + const int number_of_rays, const int is_first_perm_table) +{ + int i, k; + + for (i = 0; i < number_of_rays; i++) + temp_permutation[i] = i; + + for (i = 0; i < number_of_rays; i++) { + const unsigned int nr_entries_left = number_of_rays - i; + unsigned short rnd = is_first_perm_table != FALSE ? get_ao_random1(i) : get_ao_random2(i); + const unsigned short entry = rnd % nr_entries_left; + + /* pull entry */ + permutation[i] = temp_permutation[entry]; + + /* delete entry */ + for(k = entry; k < nr_entries_left - 1; k++) + temp_permutation[k] = temp_permutation[k + 1]; + } + + /* verify permutation table + * every entry must appear exactly once + */ +#if 0 + for(i = 0; i < number_of_rays; i++) temp_permutation[i] = 0; + for(i = 0; i < number_of_rays; i++) ++temp_permutation[permutation[i]]; + for(i = 0; i < number_of_rays; i++) BLI_assert(temp_permutation[i] == 1); +#endif +} + +static void create_ao_raytree(MultiresBakeRender *bkr, MAOBakeData *ao_data) +{ + DerivedMesh *hidm = bkr->hires_dm; + RayObject *raytree; + RayFace *face; + CCGElem **grid_data; + CCGKey key; + int num_grids, grid_size, face_side, num_faces; + int i; + + num_grids = hidm->getNumGrids(hidm); + grid_size = hidm->getGridSize(hidm); + grid_data = hidm->getGridData(hidm); + hidm->getGridKey(hidm, &key); + + face_side = (grid_size << 1) - 1; + num_faces = num_grids * (grid_size - 1) * (grid_size - 1); + + raytree = ao_data->raytree = RE_rayobject_create(bkr->raytrace_structure, num_faces, bkr->octree_resolution); + face = ao_data->rayfaces = (RayFace *) MEM_callocN(num_faces * sizeof(RayFace), "ObjectRen faces"); + + for (i = 0; i < num_grids; i++) { + int x, y; + for (x = 0; x < grid_size - 1; x++) { + for (y = 0; y < grid_size - 1; y++) { + float co[4][3]; + + copy_v3_v3(co[0], CCG_grid_elem_co(&key, grid_data[i], x, y)); + copy_v3_v3(co[1], CCG_grid_elem_co(&key, grid_data[i], x, y + 1)); + copy_v3_v3(co[2], CCG_grid_elem_co(&key, grid_data[i], x + 1, y + 1)); + copy_v3_v3(co[3], CCG_grid_elem_co(&key, grid_data[i], x + 1, y)); + + RE_rayface_from_coords(face, ao_data, face, co[0], co[1], co[2], co[3]); + RE_rayobject_add(raytree, RE_rayobject_unalignRayFace(face)); + + face++; + } + } + } + + RE_rayobject_done(raytree); +} + +static void *init_ao_data(MultiresBakeRender *bkr, Image *UNUSED(ima)) +{ + MAOBakeData *ao_data; + DerivedMesh *lodm = bkr->lores_dm; + unsigned short *temp_permutation_table; + size_t permutation_size; + + init_ao_random(); + + ao_data = MEM_callocN(sizeof(MAOBakeData), "MultiresBake aoData"); + + ao_data->number_of_rays = bkr->number_of_rays; + ao_data->bias = bkr->bias; + + ao_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX); + ao_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX); + + create_ao_raytree(bkr, ao_data); + + /* initialize permutation tables */ + permutation_size = sizeof(unsigned short) * bkr->number_of_rays; + ao_data->permutation_table_1 = MEM_callocN(permutation_size, "multires AO baker perm1"); + ao_data->permutation_table_2 = MEM_callocN(permutation_size, "multires AO baker perm2"); + temp_permutation_table = MEM_callocN(permutation_size, "multires AO baker temp perm"); + + build_permutation_table(ao_data->permutation_table_1, temp_permutation_table, bkr->number_of_rays, 1); + build_permutation_table(ao_data->permutation_table_2, temp_permutation_table, bkr->number_of_rays, 0); + + MEM_freeN(temp_permutation_table); + + return (void *)ao_data; +} + +static void free_ao_data(void *bake_data) +{ + MAOBakeData *ao_data = (MAOBakeData *) bake_data; + + RE_rayobject_free(ao_data->raytree); + MEM_freeN(ao_data->rayfaces); + + MEM_freeN(ao_data->permutation_table_1); + MEM_freeN(ao_data->permutation_table_2); + + MEM_freeN(ao_data); +} + +/* builds an X and a Y axis from the given Z axis */ +static void build_coordinate_frame(float axisX[3], float axisY[3], const float axisZ[3]) +{ + const float faX = fabsf(axisZ[0]); + const float faY = fabsf(axisZ[1]); + const float faZ = fabsf(axisZ[2]); + + if (faX <= faY && faX <= faZ) { + const float len = sqrtf(axisZ[1] * axisZ[1] + axisZ[2] * axisZ[2]); + axisY[0] = 0; axisY[1] = axisZ[2] / len; axisY[2] = -axisZ[1] / len; + cross_v3_v3v3(axisX, axisY, axisZ); + } + else if (faY <= faZ) { + const float len = sqrtf(axisZ[0] * axisZ[0] + axisZ[2] * axisZ[2]); + axisX[0] = axisZ[2] / len; axisX[1] = 0; axisX[2] = -axisZ[0] / len; + cross_v3_v3v3(axisY, axisZ, axisX); + } + else { + const float len = sqrtf(axisZ[0] * axisZ[0] + axisZ[1] * axisZ[1]); + axisX[0] = axisZ[1] / len; axisX[1] = -axisZ[0] / len; axisX[2] = 0; + cross_v3_v3v3(axisY, axisZ, axisX); + } +} + +/* return FALSE if nothing was hit and TRUE otherwise */ +static int trace_ao_ray(MAOBakeData *ao_data, float ray_start[3], float ray_direction[3]) +{ + Isect isect = {{0}}; + + isect.dist = RE_RAYTRACE_MAXDIST; + copy_v3_v3(isect.start, ray_start); + copy_v3_v3(isect.dir, ray_direction); + isect.lay = -1; + + normalize_v3(isect.dir); + + return RE_rayobject_raycast(ao_data->raytree, &isect); +} + +static void apply_ao_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) +{ + MAOBakeData *ao_data = (MAOBakeData *) bake_data; + MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE); + MFace mface; + + int i, k, perm_offs; + float pos[3], nrm[3]; + float cen[3]; + float axisX[3], axisY[3], axisZ[3]; + float shadow = 0; + float value; + int pixel = ibuf->x * y + x; + float uv[2], *st0, *st1, *st2, *st3; + + 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, + ao_data->orig_index_mf_to_mpoly, ao_data->orig_index_mp_to_orig, + lvl, face_index, uv[0], uv[1], pos, nrm); + + /* offset ray origin by user bias along normal */ + for (i = 0; i < 3; i++) + cen[i] = pos[i] + ao_data->bias * nrm[i]; + + /* build tangent frame */ + for (i = 0; i < 3; i++) + axisZ[i] = nrm[i]; + + build_coordinate_frame(axisX, axisY, axisZ); + + /* static noise */ + perm_offs = (get_ao_random2(get_ao_random1(x) + y)) & (MAX_NUMBER_OF_AO_RAYS - 1); + + /* importance sample shadow rays (cosine weighted) */ + for (i = 0; i < ao_data->number_of_rays; i++) { + int hit_something; + + /* use N-Rooks to distribute our N ray samples across + * a multi-dimensional domain (2D) + */ + const unsigned short I = ao_random_table_1[(i + perm_offs) % ao_data->number_of_rays]; + const unsigned short J = ao_random_table_2[i]; + + const float JitPh = (get_ao_random2(I + perm_offs) & (MAX_NUMBER_OF_AO_RAYS-1))/((float) MAX_NUMBER_OF_AO_RAYS); + const float JitTh = (get_ao_random1(J + perm_offs) & (MAX_NUMBER_OF_AO_RAYS-1))/((float) MAX_NUMBER_OF_AO_RAYS); + const float SiSqPhi = (I + JitPh) / ao_data->number_of_rays; + const float Theta = 2 * M_PI * ((J + JitTh) / ao_data->number_of_rays); + + /* this gives results identical to the so-called cosine + * weighted distribution relative to the north pole. + */ + float SiPhi = sqrt(SiSqPhi); + float CoPhi = SiSqPhi < 1.0f ? sqrt(1.0f - SiSqPhi) : 1.0f - SiSqPhi; + float CoThe = cos(Theta); + float SiThe = sin(Theta); + + const float dx = CoThe * CoPhi; + const float dy = SiThe * CoPhi; + const float dz = SiPhi; + + /* transform ray direction out of tangent frame */ + float dv[3]; + for (k = 0; k < 3; k++) + dv[k] = axisX[k] * dx + axisY[k] * dy + axisZ[k] * dz; + + hit_something = trace_ao_ray(ao_data, cen, dv); + + if (hit_something != 0) + shadow += 1; + } + + value = 1.0f - (shadow / ao_data->number_of_rays); + + if (ibuf->rect_float) { + float *rrgbf = ibuf->rect_float + pixel * 4; + rrgbf[0] = rrgbf[1] = rrgbf[2] = value; + rrgbf[3] = 1.0f; + } + else { + unsigned char *rrgb = (unsigned char *) ibuf->rect + pixel * 4; + rrgb[0] = rrgb[1] = rrgb[2] = FTOCHAR(value); + rrgb[3] = 255; + } +} + +/* **************** Common functions public API relates on **************** */ + +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, TRUE, apply_tangmat_callback, init_normal_data, NULL, free_normal_data); + break; + case RE_BAKE_DISPLACEMENT: + do_multires_bake(bkr, ima, FALSE, apply_heights_callback, init_heights_data, + apply_heights_data, free_heights_data); + break; + case RE_BAKE_AO: + do_multires_bake(bkr, ima, FALSE, apply_ao_callback, init_ao_data, NULL, free_ao_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); + } +} + +void RE_multires_bake_images(MultiresBakeRender *bkr) +{ + count_images(bkr); + bake_images(bkr); + finish_images(bkr); +} diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 24b0830e651..39df6a01f61 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -585,7 +585,7 @@ void RE_SetOrtho(Render *re, rctf *viewplane, float clipsta, float clipend) re->viewplane.ymin, re->viewplane.ymax, re->clipsta, re->clipend); } -void RE_SetView(Render *re, float mat[][4]) +void RE_SetView(Render *re, float mat[4][4]) { /* re->ok flag? */ copy_m4_m4(re->viewmat, mat); @@ -947,6 +947,9 @@ static void add_freestyle(Render *re); static void do_render_3d(Render *re) { + float cfra; + int cfra_backup; + /* try external */ if (RE_engine_render(re, 0)) return; @@ -954,9 +957,13 @@ static void do_render_3d(Render *re) /* internal */ RE_parts_clamp(re); -// re->cfra= cfra; /* <- unused! */ - re->scene->r.subframe = re->mblur_offs + re->field_offs; - + /* add motion blur and fields offset to frames */ + cfra_backup = re->scene->r.cfra; + + cfra = re->scene->r.cfra + re->mblur_offs + re->field_offs; + re->scene->r.cfra = floorf(cfra); + re->scene->r.subframe = cfra - floorf(cfra); + /* lock drawing in UI during data phase */ if (re->draw_lock) re->draw_lock(re->dlh, 1); @@ -986,6 +993,7 @@ static void do_render_3d(Render *re) /* free all render verts etc */ RE_Database_Free(re); + re->scene->r.cfra = cfra_backup; re->scene->r.subframe = 0.f; } diff --git a/source/blender/render/intern/source/pixelblending.c b/source/blender/render/intern/source/pixelblending.c index 74de8a1291f..21ff1151cfb 100644 --- a/source/blender/render/intern/source/pixelblending.c +++ b/source/blender/render/intern/source/pixelblending.c @@ -206,7 +206,7 @@ void add_filt_fmask(unsigned int mask, const float col[4], float *rowbuf, int ro } -void mask_array(unsigned int mask, float filt[][3]) +void mask_array(unsigned int mask, float filt[3][3]) { float **fmask1 = R.samples->fmask1, **fmask2 = R.samples->fmask2; unsigned int maskand = (mask & 255); @@ -244,7 +244,7 @@ void mask_array(unsigned int mask, float filt[][3]) * </pre> */ -void add_filt_fmask_coord(float filt[][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y) +void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y) { float *fpoin[3][3]; float val, r, g, b, al, lfilt[3][3]; diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index a540cdb85d5..3ca4015ff7b 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -447,7 +447,7 @@ int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres) turb = BLI_gTurbulence(pd->noise_size, texvec[0]+age, texvec[1]+age, texvec[2]+age, pd->noise_depth, 0, pd->noise_basis); } else if (pd->noise_influence == TEX_PD_NOISE_TIME) { - time = R.cfra / (float)R.r.efra; + time = R.r.cfra / (float)R.r.efra; turb = BLI_gTurbulence(pd->noise_size, texvec[0]+time, texvec[1]+time, texvec[2]+time, pd->noise_depth, 0, pd->noise_basis); //turb = BLI_turbulence(pd->noise_size, texvec[0]+time, texvec[1]+time, texvec[2]+time, pd->noise_depth); } diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 127e0bc07b9..fb9eb59cbbf 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -94,7 +94,7 @@ static void RE_rayobject_config_control(RayObject *r, Render *re) } } -static RayObject* RE_rayobject_create(Render *re, int type, int size) +RayObject *RE_rayobject_create(int type, int size, int octree_resolution) { RayObject * res = NULL; @@ -117,7 +117,7 @@ static RayObject* RE_rayobject_create(Render *re, int type, int size) if (type == R_RAYSTRUCTURE_OCTREE) //TODO dynamic ocres - res = RE_rayobject_octree_create(re->r.ocres, size); + res = RE_rayobject_octree_create(octree_resolution, size); else if (type == R_RAYSTRUCTURE_BLIBVH) res = RE_rayobject_blibvh_create(size); else if (type == R_RAYSTRUCTURE_VBVH) @@ -129,10 +129,18 @@ static RayObject* RE_rayobject_create(Render *re, int type, int size) else res = RE_rayobject_vbvh_create(size); //Fallback + return res; +} + +static RayObject* rayobject_create(Render *re, int type, int size) +{ + RayObject * res = NULL; + + res = RE_rayobject_create(type, size, re->r.ocres); if (res) RE_rayobject_config_control(res, re); - + return res; } @@ -240,7 +248,7 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi) return NULL; //Create Ray cast accelaration structure - raytree = RE_rayobject_create( re, re->r.raytrace_structure, faces ); + raytree = rayobject_create( re, re->r.raytrace_structure, faces ); if ( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) ) vlakprimitive = obr->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "ObjectRen primitives"); else @@ -334,7 +342,7 @@ static void makeraytree_single(Render *re) } //Create raytree - raytree = re->raytree = RE_rayobject_create( re, re->r.raytrace_structure, faces+special ); + raytree = re->raytree = rayobject_create( re, re->r.raytrace_structure, faces+special ); if ( (re->r.raytrace_options & R_RAYTRACE_USE_LOCAL_COORDS) ) { vlakprimitive = re->rayprimitives = (VlakPrimitive*)MEM_callocN(faces*sizeof(VlakPrimitive), "Raytrace vlak-primitives"); diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 3431c3ff5de..bd0061c0e68 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -2795,4 +2795,3 @@ struct Image *RE_bake_shade_get_image(void) { return R.bakebuf; } - diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 44daaf516e1..e189d8bdaea 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -1221,7 +1221,9 @@ static int panotestclip(Render *re, int do_pano, float v[4]) * - shadow buffering (shadbuf.c) */ -void project_renderdata(Render *re, void (*projectfunc)(const float *, float mat[][4], float *), int do_pano, float xoffs, int UNUSED(do_buckets)) +void project_renderdata(Render *re, + void (*projectfunc)(const float *, float mat[4][4], float *), + int do_pano, float xoffs, int UNUSED(do_buckets)) { ObjectRen *obr; HaloRen *har = NULL; @@ -1308,7 +1310,7 @@ void project_renderdata(Render *re, void (*projectfunc)(const float *, float mat /* ------------------------------------------------------------------------- */ -ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[][4], int lay) +ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[4][4], int lay) { ObjectInstanceRen *obi; float mat3[3][3]; @@ -1363,7 +1365,7 @@ void RE_makeRenderInstances(Render *re) re->instancetable= newlist; } -int clip_render_object(float boundbox[][3], float bounds[4], float winmat[][4]) +int clip_render_object(float boundbox[2][3], float bounds[4], float winmat[4][4]) { float mat[4][4], vec[4]; int a, fl, flag = -1; diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index a7f6b40981d..078c11a2061 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -1302,7 +1302,7 @@ float shadow_halo(LampRen *lar, const float p1[3], const float p2[3]) ShadBuf *shb= lar->shb; ShadSampleBuf *shsample; float co[4], siz; - float labda, labdao, labdax, labday, ldx, ldy; + float lambda, lambda_o, lambda_x, lambda_y, ldx, ldy; float zf, xf1, yf1, zf1, xf2, yf2, zf2; float count, lightcount; int x, y, z, xs1, ys1; @@ -1336,68 +1336,68 @@ float shadow_halo(LampRen *lar, const float p1[3], const float p2[3]) if (xf1 != xf2) { if (xf2-xf1 > 0.0f) { - labdax= (xf1-xs1-1.0f)/(xf1-xf2); + lambda_x= (xf1-xs1-1.0f)/(xf1-xf2); ldx= -shb->shadhalostep/(xf1-xf2); dx= shb->shadhalostep; } else { - labdax= (xf1-xs1)/(xf1-xf2); + lambda_x= (xf1-xs1)/(xf1-xf2); ldx= shb->shadhalostep/(xf1-xf2); dx= -shb->shadhalostep; } } else { - labdax= 1.0; + lambda_x= 1.0; ldx= 0.0; } if (yf1 != yf2) { if (yf2-yf1 > 0.0f) { - labday= (yf1-ys1-1.0f)/(yf1-yf2); + lambda_y= (yf1-ys1-1.0f)/(yf1-yf2); ldy= -shb->shadhalostep/(yf1-yf2); dy= shb->shadhalostep; } else { - labday= (yf1-ys1)/(yf1-yf2); + lambda_y= (yf1-ys1)/(yf1-yf2); ldy= shb->shadhalostep/(yf1-yf2); dy= -shb->shadhalostep; } } else { - labday= 1.0; + lambda_y= 1.0; ldy= 0.0; } x= xs1; y= ys1; - labda= count= lightcount= 0.0; + lambda= count= lightcount= 0.0; /* printf("start %x %x \n", (int)(0x7FFFFFFF*zf1), (int)(0x7FFFFFFF*zf2)); */ while (1) { - labdao= labda; + lambda_o= lambda; - if (labdax==labday) { - labdax+= ldx; + if (lambda_x==lambda_y) { + lambda_x+= ldx; x+= dx; - labday+= ldy; + lambda_y+= ldy; y+= dy; } else { - if (labdax<labday) { - labdax+= ldx; + if (lambda_x<lambda_y) { + lambda_x+= ldx; x+= dx; } else { - labday+= ldy; + lambda_y+= ldy; y+= dy; } } - labda = min_ff(labdax, labday); - if (labda==labdao || labda>=1.0f) break; + lambda = min_ff(lambda_x, lambda_y); + if (lambda==lambda_o || lambda>=1.0f) break; - zf= zf1 + labda*(zf2-zf1); + zf= zf1 + lambda*(zf2-zf1); count+= (float)shb->totbuf; if (zf<= -1.0f) lightcount += 1.0f; /* close to the spot */ @@ -1686,21 +1686,21 @@ static int point_behind_strand(const float p[3], BSPFace *face) return 1; } else { - float labda= ( face->rc[0]*(p[0]-face->vec1[0]) + face->rc[1]*(p[1]-face->vec1[1]) )*face->len; + float lambda= ( face->rc[0]*(p[0]-face->vec1[0]) + face->rc[1]*(p[1]-face->vec1[1]) )*face->len; - if (labda > -face->radline_end && labda < 1.0f+face->radline_end) { + if (lambda > -face->radline_end && lambda < 1.0f+face->radline_end) { /* hesse for dist: */ //dist= (float)(fabs( (p[0]-vec2[0])*rc[1] + (p[1]-vec2[1])*rc[0])/len); - pt[0]= labda*face->rc[0]+face->vec1[0]; - pt[1]= labda*face->rc[1]+face->vec1[1]; + pt[0]= lambda*face->rc[0]+face->vec1[0]; + pt[1]= lambda*face->rc[1]+face->vec1[1]; rc[0]= pt[0]-p[0]; rc[1]= pt[1]-p[1]; dist= (float)sqrt(rc[0]*rc[0]+ rc[1]*rc[1]); if (dist < face->radline) { - float zval= face->vec1[2] + labda*face->rc[2]; + float zval= face->vec1[2] + lambda*face->rc[2]; if (p[2] > zval) return 1; } diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c index 2fe8adaa1ee..569bac29205 100644 --- a/source/blender/render/intern/source/strand.c +++ b/source/blender/render/intern/source/strand.c @@ -476,13 +476,13 @@ static int compare_strand_segment(const void *poin1, const void *poin2) return 1; } -static void do_strand_point_project(float winmat[][4], ZSpan *zspan, float *co, float *hoco, float *zco) +static void do_strand_point_project(float winmat[4][4], ZSpan *zspan, float *co, float *hoco, float *zco) { projectvert(co, winmat, hoco); hoco_to_zco(zspan, zco, hoco); } -static void strand_project_point(float winmat[][4], float winx, float winy, StrandPoint *spoint) +static void strand_project_point(float winmat[4][4], float winx, float winy, StrandPoint *spoint) { float div; @@ -603,7 +603,7 @@ static void do_strand_fillac(void *handle, int x, int y, float u, float v, float } /* width is calculated in hoco space, to ensure strands are visible */ -static int strand_test_clip(float winmat[][4], ZSpan *UNUSED(zspan), float *bounds, float *co, float *zcomp, float widthx, float widthy) +static int strand_test_clip(float winmat[4][4], ZSpan *UNUSED(zspan), float *bounds, float *co, float *zcomp, float widthx, float widthy) { float hoco[4]; int clipflag= 0; @@ -663,7 +663,7 @@ static void do_scanconvert_strand(Render *UNUSED(re), StrandPart *spart, ZSpan * zspan_scanconvert_strand(zspan, spart, jco1, jco3, jco4, do_strand_fillac); } -static void strand_render(Render *re, StrandSegment *sseg, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandPoint *p1, StrandPoint *p2) +static void strand_render(Render *re, StrandSegment *sseg, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandPoint *p1, StrandPoint *p2) { if (spart) { float t= p2->t; @@ -696,7 +696,7 @@ static void strand_render(Render *re, StrandSegment *sseg, float winmat[][4], St } } -static int strand_segment_recursive(Render *re, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg, StrandPoint *p1, StrandPoint *p2, int depth) +static int strand_segment_recursive(Render *re, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg, StrandPoint *p1, StrandPoint *p2, int depth) { StrandPoint p; StrandBuffer *buffer= sseg->buffer; @@ -745,7 +745,7 @@ static int strand_segment_recursive(Render *re, float winmat[][4], StrandPart *s return 1; } -void render_strand_segment(Render *re, float winmat[][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg) +void render_strand_segment(Render *re, float winmat[4][4], StrandPart *spart, ZSpan *zspan, int totzspan, StrandSegment *sseg) { StrandBuffer *buffer= sseg->buffer; StrandPoint *p1= &sseg->point1; @@ -783,7 +783,7 @@ void render_strand_segment(Render *re, float winmat[][4], StrandPart *spart, ZSp } /* render call to fill in strands */ -int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBase *apsmbase, unsigned int lay, int UNUSED(negzmask), float winmat[][4], int winx, int winy, int samples, float (*jit)[2], float clipcrop, int shadow, StrandShadeCache *cache) +int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBase *apsmbase, unsigned int lay, int UNUSED(negzmask), float winmat[4][4], int winx, int winy, int samples, float (*jit)[2], float clipcrop, int shadow, StrandShadeCache *cache) { ObjectRen *obr; ObjectInstanceRen *obi; @@ -976,7 +976,7 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBa /* *************** */ -StrandSurface *cache_strand_surface(Render *re, ObjectRen *obr, DerivedMesh *dm, float mat[][4], int timeoffset) +StrandSurface *cache_strand_surface(Render *re, ObjectRen *obr, DerivedMesh *dm, float mat[4][4], int timeoffset) { StrandSurface *mesh; MFace *mface; diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index c52fb84a7f8..2e1b23435e5 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -1600,8 +1600,8 @@ void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float * /** * (clip pyramid) - * Sets labda: flag, and parametrize the clipping of vertices in - * viewspace coordinates. labda = -1 means no clipping, labda in [0, 1] means a clipping. + * Sets lambda: flag, and parametrize the clipping of vertices in + * viewspace coordinates. lambda = -1 means no clipping, lambda in [0, 1] means a clipping. * Note: uses globals. * \param v1 start coordinate s * \param v2 target coordinate t @@ -1611,13 +1611,13 @@ void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float * * \param a index for coordinate (x, y, or z) */ -static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a, float clipcrop) +static void clippyra(float *lambda, float *v1, float *v2, int *b2, int *b3, int a, float clipcrop) { float da, dw, u1=0.0, u2=1.0; float v13; - labda[0]= -1.0; - labda[1]= -1.0; + lambda[0]= -1.0; + lambda[1]= -1.0; da= v2[a]-v1[a]; /* prob; we clip slightly larger, osa renders add 2 pixels on edges, should become variable? */ @@ -1641,16 +1641,16 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a if (cliptestf(da, -dw, v13, -v1[a], &u1, &u2)) { *b3=1; if (u2<1.0f) { - labda[1]= u2; + lambda[1]= u2; *b2=1; } - else labda[1]=1.0; /* u2 */ + else lambda[1]=1.0; /* u2 */ if (u1>0.0f) { - labda[0] = u1; + lambda[0] = u1; *b2 = 1; } else { - labda[0] = 0.0; + lambda[0] = 0.0; } } } @@ -1658,8 +1658,8 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a /** * (make vertex pyramide clip) - * Checks labda and uses this to make decision about clipping the line - * segment from v1 to v2. labda is the factor by which the vector is + * Checks lambda and uses this to make decision about clipping the line + * segment from v1 to v2. lambda is the factor by which the vector is * cut. ( calculate s + l * ( t - s )). The result is appended to the * vertex list of this face. * @@ -1671,12 +1671,12 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a * \param clve vertex vector. */ -static void makevertpyra(float *vez, float *labda, float **trias, float *v1, float *v2, int *b1, int *clve) +static void makevertpyra(float *vez, float *lambda, float **trias, float *v1, float *v2, int *b1, int *clve) { float l1, l2, *adr; - l1= labda[0]; - l2= labda[1]; + l1= lambda[0]; + l2= lambda[1]; if (l1!= -1.0f) { if (l1!= 0.0f) { @@ -1708,7 +1708,7 @@ static void makevertpyra(float *vez, float *labda, float **trias, float *v1, flo /* ------------------------------------------------------------------------- */ -void projectverto(const float v1[3], float winmat[][4], float adr[4]) +void projectverto(const float v1[3], float winmat[4][4], float adr[4]) { /* calcs homogenic coord of vertex v1 */ float x, y, z; @@ -1726,7 +1726,7 @@ void projectverto(const float v1[3], float winmat[][4], float adr[4]) /* ------------------------------------------------------------------------- */ -void projectvert(const float v1[3], float winmat[][4], float adr[4]) +void projectvert(const float v1[3], float winmat[4][4], float adr[4]) { /* calcs homogenic coord of vertex v1 */ float x, y, z; @@ -1761,7 +1761,7 @@ static void zbuf_project_cache_clear(ZbufProjectCache *cache, int size) cache[i].index= -1; } -static int zbuf_shadow_project(ZbufProjectCache *cache, int index, float winmat[][4], float *co, float *ho) +static int zbuf_shadow_project(ZbufProjectCache *cache, int index, float winmat[4][4], float *co, float *ho) { int cindex= index & 255; @@ -1790,7 +1790,7 @@ static void zbuffer_part_bounds(int winx, int winy, RenderPart *pa, float *bound bounds[3]= (2*pa->disprect.ymax - winy+1)/(float)winy; } -static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[][4], float *bounds, float *co, float *ho) +static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[4][4], float *bounds, float *co, float *ho) { float vec[3]; int cindex= index & 255; @@ -1819,7 +1819,7 @@ static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[][ } } -void zbuf_render_project(float winmat[][4], const float co[3], float ho[4]) +void zbuf_render_project(float winmat[4][4], const float co[3], float ho[4]) { float vec[3]; @@ -1827,7 +1827,7 @@ void zbuf_render_project(float winmat[][4], const float co[3], float ho[4]) projectvert(vec, winmat, ho); } -void zbuf_make_winmat(Render *re, float winmat[][4]) +void zbuf_make_winmat(Render *re, float winmat[4][4]) { if (re->r.mode & R_PANORAMA) { float panomat[4][4]= MAT4_UNITY; @@ -1847,7 +1847,7 @@ void zbuf_make_winmat(Render *re, float winmat[][4]) void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3) { - float *vlzp[32][3], labda[3][2]; + float *vlzp[32][3], lambda[3][2]; float vez[400], *trias[40]; if (c1 | c2 | c3) { /* not in middle */ @@ -1887,9 +1887,9 @@ void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, else if (b==1) arg= 0; else arg= 1; - clippyra(labda[0], vlzp[v][0], vlzp[v][1], &b2, &b3, arg, zspan->clipcrop); - clippyra(labda[1], vlzp[v][1], vlzp[v][2], &b2, &b3, arg, zspan->clipcrop); - clippyra(labda[2], vlzp[v][2], vlzp[v][0], &b2, &b3, arg, zspan->clipcrop); + clippyra(lambda[0], vlzp[v][0], vlzp[v][1], &b2, &b3, arg, zspan->clipcrop); + clippyra(lambda[1], vlzp[v][1], vlzp[v][2], &b2, &b3, arg, zspan->clipcrop); + clippyra(lambda[2], vlzp[v][2], vlzp[v][0], &b2, &b3, arg, zspan->clipcrop); if (b2==0 && b3==1) { /* completely 'in', but we copy because of last for () loop in this section */; @@ -1905,9 +1905,9 @@ void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, } else { b1=0; - makevertpyra(vez, labda[0], trias, vlzp[v][0], vlzp[v][1], &b1, &clve); - makevertpyra(vez, labda[1], trias, vlzp[v][1], vlzp[v][2], &b1, &clve); - makevertpyra(vez, labda[2], trias, vlzp[v][2], vlzp[v][0], &b1, &clve); + makevertpyra(vez, lambda[0], trias, vlzp[v][0], vlzp[v][1], &b1, &clve); + makevertpyra(vez, lambda[1], trias, vlzp[v][1], vlzp[v][2], &b1, &clve); + makevertpyra(vez, lambda[2], trias, vlzp[v][2], vlzp[v][0], &b1, &clve); /* after front clip done: now set clip flags */ if (b==0) { @@ -2296,7 +2296,7 @@ void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart*, } } -void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int size, float jitx, float jity) +void zbuffer_shadow(Render *re, float winmat[4][4], LampRen *lar, int *rectz, int size, float jitx, float jity) { ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE]; ZSpan zspan; @@ -3261,7 +3261,7 @@ static void copyto_abufz(RenderPart *pa, int *arectz, int *rectmask, int sample) * Do accumulation z buffering. */ -static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[][4], int winx, int winy, int samples, float (*jit)[2], float UNUSED(clipcrop), int shadow) +static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, unsigned int lay, int negzmask, float winmat[4][4], int winx, int winy, int samples, float (*jit)[2], float UNUSED(clipcrop), int shadow) { ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE]; ZSpan zspans[16], *zspan; /* MAX_OSA */ @@ -3459,7 +3459,7 @@ static int zbuffer_abuf_render(RenderPart *pa, APixstr *APixbuf, APixstrand *APi return doztra; } -void zbuffer_abuf_shadow(Render *re, LampRen *lar, float winmat[][4], APixstr *APixbuf, APixstrand *APixbufstrand, ListBase *apsmbase, int size, int samples, float (*jit)[2]) +void zbuffer_abuf_shadow(Render *re, LampRen *lar, float winmat[4][4], APixstr *APixbuf, APixstrand *APixbufstrand, ListBase *apsmbase, int size, int samples, float (*jit)[2]) { RenderPart pa; int lay= -1; diff --git a/source/blender/windowmanager/SConscript b/source/blender/windowmanager/SConscript index de340ec4c9a..3702a2d909c 100644 --- a/source/blender/windowmanager/SConscript +++ b/source/blender/windowmanager/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') import os diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 8d885bf6d6f..b0b020f3d97 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -56,6 +56,7 @@ struct wmOperatorType; struct wmOperator; struct rcti; struct PointerRNA; +struct PropertyRNA; struct EnumPropertyItem; struct MenuType; struct wmDropBox; @@ -68,6 +69,7 @@ typedef struct wmJob wmJob; void WM_init_state_size_set (int stax, int stay, int sizx, int sizy); void WM_init_state_fullscreen_set(void); void WM_init_state_normal_set(void); +void WM_init_native_pixels(int do_it); void WM_init (struct bContext *C, int argc, const char **argv); void WM_exit_ext (struct bContext *C, const short do_python); @@ -92,21 +94,23 @@ void WM_check (struct bContext *C); struct wmWindow *WM_window_open (struct bContext *C, struct rcti *rect); +int WM_window_pixels_x (struct wmWindow *win); +int WM_window_pixels_y (struct wmWindow *win); + /* defines for 'type' WM_window_open_temp */ #define WM_WINDOW_RENDER 0 #define WM_WINDOW_USERPREFS 1 #define WM_WINDOW_FILESEL 2 void WM_window_open_temp (struct bContext *C, struct rcti *position, int type); + + /* returns true if draw method is triple buffer */ +int WM_is_draw_triple(struct wmWindow *win); /* files */ -int WM_homefile_read_exec(struct bContext *C, struct wmOperator *op); -int WM_homefile_read(struct bContext *C, struct ReportList *reports, short from_memory); -int WM_homefile_write_exec(struct bContext *C, struct wmOperator *op); void WM_file_read(struct bContext *C, const char *filepath, struct ReportList *reports); -int WM_file_write(struct bContext *C, const char *target, int fileflags, struct ReportList *reports); void WM_autosave_init(struct wmWindowManager *wm); /* mouse cursors */ @@ -144,8 +148,9 @@ struct wmEventHandler *WM_event_add_ui_handler(const struct bContext *C, ListBas int (*func)(struct bContext *C, struct wmEvent *event, void *userdata), void (*remove)(struct bContext *C, void *userdata), void *userdata); void WM_event_remove_ui_handler(ListBase *handlers, - int (*func)(struct bContext *C, struct wmEvent *event, void *userdata), - void (*remove)(struct bContext *C, void *userdata), void *userdata, int postpone); + int (*func)(struct bContext *C, struct wmEvent *event, void *userdata), + void (*remove)(struct bContext *C, void *userdata), + void *userdata, int postpone); void WM_event_remove_area_handler(struct ListBase *handlers, void *area); struct wmEventHandler *WM_event_add_modal_handler(struct bContext *C, struct wmOperator *op); @@ -253,6 +258,7 @@ int WM_operator_last_properties_store(struct wmOperator *op); /* operator as a python command (resultuing string must be freed) */ char *WM_operator_pystring(struct bContext *C, struct wmOperatorType *ot, struct PointerRNA *opptr, int all_args); +char *WM_prop_pystring_assign(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, int index); void WM_operator_bl_idname(char *to, const char *from); void WM_operator_py_idname(char *to, const char *from); @@ -298,7 +304,7 @@ struct wmDrag *WM_event_start_drag(struct bContext *C, int icon, int type, void void WM_event_drag_image(struct wmDrag *, struct ImBuf *, float scale, int sx, int sy); struct wmDropBox *WM_dropbox_add(ListBase *lb, const char *idname, int (*poll)(struct bContext *, struct wmDrag *, struct wmEvent *event), - void (*copy)(struct wmDrag *, struct wmDropBox *)); + void (*copy)(struct wmDrag *, struct wmDropBox *)); ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid); /* Set a subwindow active in pixelspace view, with optional scissor subset */ diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index a92ed65392c..11cf1088280 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -49,6 +49,7 @@ #include "BKE_context.h" #include "BKE_global.h" +#include "BKE_screen.h" #include "GHOST_C-api.h" @@ -431,22 +432,22 @@ static int wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple) triple->target = GL_TEXTURE_RECTANGLE_ARB; triple->nx = 1; triple->ny = 1; - triple->x[0] = win->sizex; - triple->y[0] = win->sizey; + triple->x[0] = WM_window_pixels_x(win); + triple->y[0] = WM_window_pixels_y(win); } else if (GPU_non_power_of_two_support()) { triple->target = GL_TEXTURE_2D; triple->nx = 1; triple->ny = 1; - triple->x[0] = win->sizex; - triple->y[0] = win->sizey; + triple->x[0] = WM_window_pixels_x(win); + triple->y[0] = WM_window_pixels_y(win); } else { triple->target = GL_TEXTURE_2D; triple->nx = 0; triple->ny = 0; - split_width(win->sizex, MAX_N_TEX, triple->x, &triple->nx); - split_width(win->sizey, MAX_N_TEX, triple->y, &triple->ny); + split_width(WM_window_pixels_x(win), MAX_N_TEX, triple->x, &triple->nx); + split_width(WM_window_pixels_y(win), MAX_N_TEX, triple->y, &triple->ny); } /* generate texture names */ @@ -491,7 +492,7 @@ static int wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple) return 1; } -static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple) +static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple, float alpha) { float halfx, halfy, ratiox, ratioy; int x, y, sizex, sizey, offx, offy; @@ -500,8 +501,8 @@ static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple) for (y = 0, offy = 0; y < triple->ny; offy += triple->y[y], y++) { for (x = 0, offx = 0; x < triple->nx; offx += triple->x[x], x++) { - sizex = (x == triple->nx - 1) ? win->sizex - offx : triple->x[x]; - sizey = (y == triple->ny - 1) ? win->sizey - offy : triple->y[y]; + sizex = (x == triple->nx - 1) ? WM_window_pixels_x(win) - offx : triple->x[x]; + sizey = (y == triple->ny - 1) ? WM_window_pixels_y(win) - offy : triple->y[y]; /* wmOrtho for the screen has this same offset */ ratiox = sizex; @@ -519,7 +520,7 @@ static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple) glBindTexture(triple->target, triple->bind[x + y * triple->nx]); - glColor3f(1.0f, 1.0f, 1.0f); + glColor4f(1.0f, 1.0f, 1.0f, alpha); glBegin(GL_QUADS); glTexCoord2f(halfx, halfy); glVertex2f(offx, offy); @@ -546,8 +547,8 @@ static void wm_triple_copy_textures(wmWindow *win, wmDrawTriple *triple) for (y = 0, offy = 0; y < triple->ny; offy += triple->y[y], y++) { for (x = 0, offx = 0; x < triple->nx; offx += triple->x[x], x++) { - sizex = (x == triple->nx - 1) ? win->sizex - offx : triple->x[x]; - sizey = (y == triple->ny - 1) ? win->sizey - offy : triple->y[y]; + sizex = (x == triple->nx - 1) ? WM_window_pixels_x(win) - offx : triple->x[x]; + sizey = (y == triple->ny - 1) ? WM_window_pixels_y(win) - offy : triple->y[y]; glBindTexture(triple->target, triple->bind[x + y * triple->nx]); glCopyTexSubImage2D(triple->target, 0, 0, 0, offx, offy, sizex, sizey); @@ -557,6 +558,20 @@ static void wm_triple_copy_textures(wmWindow *win, wmDrawTriple *triple) glBindTexture(triple->target, 0); } +static void wm_draw_region_blend(wmWindow *win, ARegion *ar) +{ + float fac = ED_region_blend_factor(ar); + + /* region blend always is 1, except when blend timer is running */ + if (fac < 1.0f) { + wmSubWindowScissorSet(win, win->screen->mainwin, &ar->winrct); + + glEnable(GL_BLEND); + wm_triple_draw_textures(win, win->drawdata, 1.0f - fac); + glDisable(GL_BLEND); + } +} + static void wm_method_draw_triple(bContext *C, wmWindow *win) { wmWindowManager *wm = CTX_wm_manager(C); @@ -572,7 +587,7 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) wmSubWindowSet(win, screen->mainwin); - wm_triple_draw_textures(win, win->drawdata); + wm_triple_draw_textures(win, win->drawdata, 1.0f); } else { win->drawdata = MEM_callocN(sizeof(wmDrawTriple), "wmDrawTriple"); @@ -591,11 +606,13 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) for (ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->swinid && ar->do_draw) { - CTX_wm_region_set(C, ar); - ED_region_do_draw(C, ar); - ED_area_overdraw_flush(sa, ar); - CTX_wm_region_set(C, NULL); - copytex = 1; + if (ar->overlap == 0) { + CTX_wm_region_set(C, ar); + ED_region_do_draw(C, ar); + ED_area_overdraw_flush(sa, ar); + CTX_wm_region_set(C, NULL); + copytex = 1; + } } } @@ -610,10 +627,28 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) wm_triple_copy_textures(win, triple); } + /* draw overlapping area regions (always like popups) */ + for (sa = screen->areabase.first; sa; sa = sa->next) { + CTX_wm_area_set(C, sa); + + for (ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->swinid && ar->overlap) { + CTX_wm_region_set(C, ar); + ED_region_do_draw(C, ar); + ED_area_overdraw_flush(sa, ar); + CTX_wm_region_set(C, NULL); + + wm_draw_region_blend(win, ar); + } + } + + CTX_wm_area_set(C, NULL); + } + /* after area regions so we can do area 'overlay' drawing */ ED_screen_draw(win); - /* draw overlapping regions */ + /* draw floating regions (menus) */ for (ar = screen->regionbase.first; ar; ar = ar->next) { if (ar->swinid) { CTX_wm_menu_set(C, ar); @@ -652,9 +687,9 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) if (wm->drags.first) { wm_drags_draw(C, win, NULL); } - } + /****************** main update call **********************/ /* quick test to prevent changing window drawable */ @@ -734,6 +769,14 @@ static int wm_automatic_draw_method(wmWindow *win) return win->drawmethod; } +int WM_is_draw_triple(wmWindow *win) +{ + /* function can get called before this variable is set in drawing code below */ + if (win->drawmethod != U.wmdrawmethod) + win->drawmethod = U.wmdrawmethod; + return USER_DRAW_TRIPLE == wm_automatic_draw_method(win); +} + void wm_tag_redraw_overlay(wmWindow *win, ARegion *ar) { /* for draw triple gestures, paint cursors don't need region redraw */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index c0e3b19c716..d8dd0ac04c4 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1640,9 +1640,9 @@ static int wm_action_not_handled(int action) static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers) { #ifndef NDEBUG - const int do_debug_handler = (G.debug & G_DEBUG_HANDLERS) + const int do_debug_handler = (G.debug & G_DEBUG_HANDLERS) && /* comment this out to flood the console! (if you really want to test) */ - && !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) + !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) ; #endif wmWindowManager *wm = CTX_wm_manager(C); @@ -2738,11 +2738,9 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U { GHOST_TEventCursorData *cd = customdata; wmEvent *lastevent = win->queue.last; - int cx, cy; - GHOST_ScreenToClient(win->ghostwin, cd->x, cd->y, &cx, &cy); - evt->x = cx; - evt->y = (win->sizey - 1) - cy; + evt->x = cd->x; + evt->y = cd->y; event.x = evt->x; event.y = evt->y; @@ -2790,13 +2788,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U break; } - { - int cx, cy; - GHOST_ScreenToClient(win->ghostwin, pd->x, pd->y, &cx, &cy); - event.x = evt->x = cx; - event.y = evt->y = (win->sizey - 1) - cy; - } - + event.x = evt->x = pd->x; + event.y = evt->y = pd->y; event.val = 0; /* Use prevx/prevy so we can calculate the delta later */ diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 1c168bc5ac5..20b205a642a 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -285,7 +285,9 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist) /* in case UserDef was read, we re-initialize all, and do versioning */ static void wm_init_userdef(bContext *C) { + /* versioning is here */ UI_init_userdef(); + MEM_CacheLimiter_set_maximum(((size_t)U.memcachelimit) * 1024 * 1024); sound_init(CTX_data_main(C)); @@ -302,6 +304,13 @@ static void wm_init_userdef(bContext *C) /* update tempdir from user preferences */ BLI_init_temporary_dir(U.tempdir); + + /* displays with larger native pixels, like Macbook. Used to scale dpi with */ + if (G.background == FALSE) + U.pixelsize = GHOST_GetNativePixelSize(); + if (U.pixelsize == 0) U.pixelsize = 1; + + BKE_userdef_state(); } @@ -390,6 +399,8 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports) /* also exit screens and editors */ wm_window_match_init(C, &wmbase); + /* confusing this global... */ + G.relbase_valid = 1; retval = BKE_read_file(C, filepath, reports); G.save_over = 1; @@ -410,7 +421,6 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports) } if (retval != BKE_READ_FILE_FAIL) { - G.relbase_valid = 1; if (do_history) { write_history(); } @@ -488,11 +498,12 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports) /* called on startup, (context entirely filled with NULLs) */ /* or called for 'New File' */ -/* op can be NULL */ -int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory) +/* both startup.blend and userpref.blend are checked */ +int wm_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory) { ListBase wmbase; - char tstr[FILE_MAX]; + char startstr[FILE_MAX]; + char prefstr[FILE_MAX]; int success = 0; BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE); @@ -501,10 +512,12 @@ int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory if (!from_memory) { char *cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL); if (cfgdir) { - BLI_make_file_string(G.main->name, tstr, cfgdir, BLENDER_STARTUP_FILE); + BLI_make_file_string(G.main->name, startstr, cfgdir, BLENDER_STARTUP_FILE); + BLI_make_file_string(G.main->name, prefstr, cfgdir, BLENDER_USERPREF_FILE); } else { - tstr[0] = '\0'; + startstr[0] = '\0'; + prefstr[0] = '\0'; from_memory = 1; } } @@ -515,14 +528,16 @@ int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory /* put aside screens to match with persistent windows later */ wm_window_match_init(C, &wmbase); - if (!from_memory && BLI_exists(tstr)) { - success = (BKE_read_file(C, tstr, NULL) != BKE_READ_FILE_FAIL); + if (!from_memory && BLI_exists(startstr)) { + success = (BKE_read_file(C, startstr, NULL) != BKE_READ_FILE_FAIL); - if (U.themes.first == NULL) { - printf("\nError: No valid "STRINGIFY (BLENDER_STARTUP_FILE)", fall back to built-in default.\n\n"); - success = 0; - } } + + if (U.themes.first == NULL) { + printf("\nError: No valid "STRINGIFY (BLENDER_STARTUP_FILE)", fall back to built-in default.\n\n"); + success = 0; + } + if (success == 0) { success = BKE_read_file_from_memory(C, datatoc_startup_blend, datatoc_startup_blend_size, NULL); if (wmbase.first == NULL) wm_clear_default_size(C); @@ -534,6 +549,12 @@ int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory #endif } + /* check new prefs only after startup.blend was finished */ + if (!from_memory && BLI_exists(prefstr)) { + int done = BKE_read_file_userdef(prefstr, NULL); + if (done) printf("read new prefs: %s\n", prefstr); + } + /* prevent buggy files that had G_FILE_RELATIVE_REMAP written out by mistake. Screws up autosaves otherwise * can remove this eventually, only in a 2.53 and older, now its not written */ G.fileflags &= ~G_FILE_RELATIVE_REMAP; @@ -587,13 +608,13 @@ int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory return TRUE; } -int WM_homefile_read_exec(bContext *C, wmOperator *op) +int wm_homefile_read_exec(bContext *C, wmOperator *op) { int from_memory = strcmp(op->type->idname, "WM_OT_read_factory_settings") == 0; - return WM_homefile_read(C, op->reports, from_memory) ? OPERATOR_FINISHED : OPERATOR_CANCELLED; + return wm_homefile_read(C, op->reports, from_memory) ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } -void WM_read_history(void) +void wm_read_history(void) { char name[FILE_MAX]; LinkNode *l, *lines; @@ -633,6 +654,10 @@ static void write_history(void) FILE *fp; int i; + /* no write history for recovered startup files */ + if (G.main->name[0] == 0) + return; + /* will be NULL in background mode */ user_config_dir = BLI_get_folder_create(BLENDER_USER_CONFIG, NULL); if (!user_config_dir) @@ -711,7 +736,7 @@ static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, int **thumb_pt) if (scene->camera) { ibuf = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, - IB_rect, OB_SOLID, FALSE, FALSE, err_out); + IB_rect, OB_SOLID, FALSE, FALSE, FALSE, err_out); } else { ibuf = ED_view3d_draw_offscreen_imbuf(scene, v3d, ar, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, @@ -765,12 +790,11 @@ int write_crash_blend(void) } } -int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *reports) +int wm_file_write(bContext *C, const char *target, int fileflags, ReportList *reports) { Library *li; int len; char filepath[FILE_MAX]; - int *thumb = NULL; ImBuf *ibuf_thumb = NULL; @@ -820,6 +844,14 @@ int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *re fileflags |= G_FILE_HISTORY; /* write file history */ + /* first time saving */ + /* XXX temp solution to solve bug, real fix coming (ton) */ + if (G.main->name[0] == 0) + BLI_strncpy(G.main->name, filepath, sizeof(G.main->name)); + + /* XXX temp solution to solve bug, real fix coming (ton) */ + G.main->recovered = 0; + if (BLO_write_file(CTX_data_main(C), filepath, fileflags, reports, thumb)) { if (!(fileflags & G_FILE_SAVE_COPY)) { G.relbase_valid = 1; @@ -864,7 +896,7 @@ int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *re } /* operator entry */ -int WM_homefile_write_exec(bContext *C, wmOperator *op) +int wm_homefile_write_exec(bContext *C, wmOperator *op) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); @@ -884,7 +916,7 @@ int WM_homefile_write_exec(bContext *C, wmOperator *op) /* force save as regular blend file */ fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY); - if (BLO_write_file(CTX_data_main(C), filepath, fileflags, op->reports, NULL) == 0) { + if (BLO_write_file(CTX_data_main(C), filepath, fileflags | G_FILE_USERPREFS, op->reports, NULL) == 0) { printf("fail\n"); return OPERATOR_CANCELLED; } @@ -896,6 +928,28 @@ int WM_homefile_write_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +/* Only save the prefs block. operator entry */ +int wm_userpref_write_exec(bContext *C, wmOperator *op) +{ + wmWindowManager *wm = CTX_wm_manager(C); + char filepath[FILE_MAX]; + + /* update keymaps in user preferences */ + WM_keyconfig_update(wm); + + BLI_make_file_string("/", filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_USERPREF_FILE); + printf("trying to save userpref at %s ", filepath); + + if (BKE_write_file_userdef(filepath, op->reports) == 0) { + printf("fail\n"); + return OPERATOR_CANCELLED; + } + + printf("ok\n"); + + return OPERATOR_FINISHED; +} + /************************ autosave ****************************/ void wm_autosave_location(char *filepath) @@ -939,7 +993,7 @@ void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(w wmWindow *win; wmEventHandler *handler; char filepath[FILE_MAX]; - int fileflags; + Scene *scene = CTX_data_scene(C); WM_event_remove_timer(wm, NULL, wm->autosavetimer); @@ -963,12 +1017,17 @@ void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(w wm_autosave_location(filepath); - /* force save as regular blend file */ - fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY); - - /* no error reporting to console */ - BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL); + if (U.uiflag & USER_GLOBALUNDO) { + /* fast save of last undobuffer, now with UI */ + BKE_undo_save_file(filepath); + } + else { + /* save as regular blend file */ + int fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY); + /* no error reporting to console */ + BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL); + } /* do timer after file write, just in case file write takes a long time */ wm->autosavetimer = WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, U.savetime * 60.0); } @@ -989,7 +1048,7 @@ void wm_autosave_delete(void) if (BLI_exists(filename)) { char str[FILE_MAX]; - BLI_make_file_string("/", str, BLI_temporary_dir(), "quit.blend"); + BLI_make_file_string("/", str, BLI_temporary_dir(), BLENDER_QUIT_FILE); /* if global undo; remove tempsave, otherwise rename */ if (U.uiflag & USER_GLOBALUNDO) BLI_delete(filename, 0, 0); @@ -1005,3 +1064,6 @@ void wm_autosave_read(bContext *C, ReportList *reports) WM_file_read(C, filename, reports); } + + + diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index c9f0bbffc63..3cffa143ebc 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -48,6 +48,7 @@ #include "DNA_windowmanager_types.h" #include "BLI_listbase.h" +#include "BLI_path_util.h" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -128,6 +129,7 @@ int wm_start_with_console = 0; /* used in creator.c */ /* only called once, for startup */ void WM_init(bContext *C, int argc, const char **argv) { + if (!G.background) { wm_ghost_init(C); /* note: it assigns C to ghost! */ wm_init_cursor_data(); @@ -149,8 +151,8 @@ void WM_init(bContext *C, int argc, const char **argv) BLF_lang_init(); /* get the default database, plus a wm */ - WM_homefile_read(C, NULL, G.factory_startup); - + wm_homefile_read(C, NULL, G.factory_startup); + BLF_lang_set(NULL); /* note: there is a bug where python needs initializing before loading the @@ -158,7 +160,7 @@ void WM_init(bContext *C, int argc, const char **argv) * initializing space types and other internal data. * * However cant redo this at the moment. Solution is to load python - * before WM_homefile_read() or make py-drivers check if python is running. + * before wm_homefile_read() or make py-drivers check if python is running. * Will try fix when the crash can be repeated. - campbell. */ #ifdef WITH_PYTHON @@ -195,7 +197,7 @@ void WM_init(bContext *C, int argc, const char **argv) ED_preview_init_dbase(); - WM_read_history(); + wm_read_history(); /* allow a path of "", this is what happens when making a new file */ #if 0 @@ -211,6 +213,10 @@ void WM_init(bContext *C, int argc, const char **argv) COM_linker_hack = COM_execute; } #endif + + /* load last session, uses regular file reading so it has to be in end (after init py etc) */ + if (U.uiflag2 & USER_KEEP_SESSION) + wm_recover_last_session(C, NULL); } void WM_init_splash(bContext *C) @@ -372,6 +378,18 @@ void WM_exit_ext(bContext *C, const short do_python) if (C && wm) { wmWindow *win; + if (!G.background) { + if ((U.uiflag2 & USER_KEEP_SESSION) || BKE_undo_valid(NULL)) { + /* save the undo state as quit.blend */ + char filename[FILE_MAX]; + + BLI_make_file_string("/", filename, BLI_temporary_dir(), BLENDER_QUIT_FILE); + + if (BKE_undo_save_file(filename)) + printf("Saved session recovery to '%s'\n", filename); + } + } + WM_jobs_kill_all(wm); for (win = wm->windows.first; win; win = win->next) { @@ -454,9 +472,6 @@ void WM_exit_ext(bContext *C, const short do_python) GPU_free_unused_buffers(); GPU_extensions_exit(); - if (!G.background) { - BKE_undo_save_quit(); /* saves quit.blend if global undo is on */ - } BKE_reset_undo(); ED_file_exit(); /* for fsmenu */ diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 8a0701b1063..cd3d5c97f99 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -103,6 +103,7 @@ #include "wm_draw.h" #include "wm_event_system.h" #include "wm_event_types.h" +#include "wm_files.h" #include "wm_subwindow.h" #include "wm_window.h" @@ -559,6 +560,106 @@ char *WM_operator_pystring(bContext *C, wmOperatorType *ot, PointerRNA *opptr, i return cstring; } +/* return NULL if no match is found */ +static char *wm_prop_pystring_from_context(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index) +{ + + /* loop over all context items and do 2 checks + * + * - see if the pointer is in the context. + * - see if the pointers ID is in the context. + */ + + ListBase lb = CTX_data_dir_get(C); + LinkData *link; + + const char *member_found = NULL; + const char *member_id = NULL; + + char *prop_str = NULL; + char *ret = NULL; + + + for (link = lb.first; link; link = link->next) { + const char *identifier = link->data; + PointerRNA ctx_ptr = CTX_data_pointer_get(C, identifier); + + if (ctx_ptr.type == NULL) { + continue; + } + + if (ptr->id.data == ctx_ptr.id.data) { + if ((ptr->data == ctx_ptr.data) && + (ptr->type == ctx_ptr.type)) + { + /* found! */ + member_found = identifier; + break; + } + else if (RNA_struct_is_ID(ctx_ptr.type)) { + /* we found a reference to this ID, + * so fallback to it if there is no direct reference */ + member_id = identifier; + } + } + } + + /* grr, CTX_data_dir_get skips scene */ + if ((member_id == NULL) && + (ptr->id.data != NULL) && + (GS(((ID *)ptr->id.data)->name) == ID_SCE) && + (CTX_data_scene(C) == ptr->id.data)) + { + member_id = "scene"; + } + + if (member_found) { + prop_str = RNA_path_property_py(ptr, prop, index); + if (prop_str) { + ret = BLI_sprintfN("bpy.context.%s.%s", member_found, prop_str); + MEM_freeN(prop_str); + } + } + else if (member_id) { + prop_str = RNA_path_struct_property_py(ptr, prop, index); + if (prop_str) { + ret = BLI_sprintfN("bpy.context.%s.%s", member_id, prop_str); + MEM_freeN(prop_str); + } + } + + BLI_freelistN(&lb); + + return ret; +} + +char *WM_prop_pystring_assign(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index) +{ + char *lhs, *rhs, *ret; + + lhs = C ? wm_prop_pystring_from_context(C, ptr, prop, index) : NULL; + + if (lhs == NULL) { + /* fallback to bpy.data.foo[id] if we dont find in the context */ + lhs = RNA_path_full_property_py(ptr, prop, index); + } + + if (!lhs) { + return NULL; + } + + rhs = RNA_property_as_string(C, ptr, prop, index); + if (!rhs) { + MEM_freeN(lhs); + return NULL; + } + + ret = BLI_sprintfN("%s = %s", lhs, rhs); + MEM_freeN(lhs); + MEM_freeN(rhs); + return ret; +} + void WM_operator_properties_create_ptr(PointerRNA *ptr, wmOperatorType *ot) { RNA_pointer_create(NULL, ot->srna, NULL, ptr); @@ -1078,7 +1179,7 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) uiBlock *block; uiLayout *layout; uiStyle *style = UI_GetStyle(); - int width = 300; + int width = 15 * UI_UNIT_X; block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); uiBlockClearFlag(block, UI_BLOCK_LOOP); @@ -1262,7 +1363,7 @@ static int wm_operator_props_popup_ex(bContext *C, wmOperator *op, const int do_ /* if we don't have global undo, we can't do undo push for automatic redo, * so we require manual OK clicking in this popup */ if (!(U.uiflag & USER_GLOBALUNDO)) - return WM_operator_props_dialog_popup(C, op, 300, UI_UNIT_Y); + return WM_operator_props_dialog_popup(C, op, 15 * UI_UNIT_X, UI_UNIT_Y); uiPupBlock(C, wm_block_create_redo, op); @@ -1429,7 +1530,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar int i; MenuType *mt = WM_menutype_find("USERPREF_MT_splash", TRUE); char url[96]; - char file [FILE_MAX]; + char file[FILE_MAX]; #ifndef WITH_HEADLESS extern char datatoc_splash_png[]; @@ -1452,9 +1553,9 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar "%d.%02d.%d", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION); BLI_snprintf(revision_buf, sizeof(revision_buf), "r%s", build_rev); - BLF_size(style->widgetlabel.uifont_id, style->widgetlabel.points, U.dpi); - ver_width = (int)BLF_width(style->widgetlabel.uifont_id, version_buf) + 5; - rev_width = (int)BLF_width(style->widgetlabel.uifont_id, revision_buf) + 5; + BLF_size(style->widgetlabel.uifont_id, style->widgetlabel.points, U.pixelsize * U.dpi); + ver_width = (int)BLF_width(style->widgetlabel.uifont_id, version_buf) + 0.5f * U.widget_unit; + rev_width = (int)BLF_width(style->widgetlabel.uifont_id, revision_buf) + 0.5f * U.widget_unit; #endif /* WITH_BUILDINFO */ block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS); @@ -1464,16 +1565,17 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar * ugly results and clipping the splash isn't useful anyway, just disable it [#32938] */ uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_NO_WIN_CLIP); - but = uiDefBut(block, BUT_IMAGE, 0, "", 0, 10, 501, 282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */ + /* XXX splash scales with pixelsize, should become widget-units */ + but = uiDefBut(block, BUT_IMAGE, 0, "", 0, 0.5f * U.widget_unit, U.pixelsize * 501, U.pixelsize *282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */ uiButSetFunc(but, wm_block_splash_close, block, NULL); uiBlockSetFunc(block, wm_block_splash_refreshmenu, block, NULL); #ifdef WITH_BUILDINFO - uiDefBut(block, LABEL, 0, version_buf, 494 - ver_width, 282 - 24, ver_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); - uiDefBut(block, LABEL, 0, revision_buf, 494 - rev_width, 282 - 36, rev_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, LABEL, 0, version_buf, U.pixelsize * 494 - ver_width, U.pixelsize * 258, ver_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, LABEL, 0, revision_buf, U.pixelsize * 494 - rev_width, U.pixelsize * 246, rev_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); #endif /* WITH_BUILDINFO */ - layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, 480, 110, style); + layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, U.pixelsize * 480, U.pixelsize * 110, style); uiBlockSetEmboss(block, UI_EMBOSS); /* show the splash menu (containing interaction presets), using python */ @@ -1675,12 +1777,23 @@ static void WM_OT_window_duplicate(wmOperatorType *ot) static void WM_OT_save_homefile(wmOperatorType *ot) { - ot->name = "Save User Settings"; + ot->name = "Save Startup File"; ot->idname = "WM_OT_save_homefile"; - ot->description = "Make the current file the default .blend file"; + ot->description = "Make the current file the default .blend file, includes preferences"; ot->invoke = WM_operator_confirm; - ot->exec = WM_homefile_write_exec; + ot->exec = wm_homefile_write_exec; + ot->poll = WM_operator_winactive; +} + +static void WM_OT_save_userpref(wmOperatorType *ot) +{ + ot->name = "Save User Settings"; + ot->idname = "WM_OT_save_userpref"; + ot->description = "Save user preferences separately, overrides startup file preferences"; + + ot->invoke = WM_operator_confirm; + ot->exec = wm_userpref_write_exec; ot->poll = WM_operator_winactive; } @@ -1691,7 +1804,7 @@ static void WM_OT_read_homefile(wmOperatorType *ot) ot->description = "Open the default file (doesn't save the current file)"; ot->invoke = WM_operator_confirm; - ot->exec = WM_homefile_read_exec; + ot->exec = wm_homefile_read_exec; /* ommit poll to run in background mode */ } @@ -1702,7 +1815,7 @@ static void WM_OT_read_factory_settings(wmOperatorType *ot) ot->description = "Load default file and user preferences"; ot->invoke = WM_operator_confirm; - ot->exec = WM_homefile_read_exec; + ot->exec = wm_homefile_read_exec; /* ommit poll to run in background mode */ } @@ -2003,21 +2116,35 @@ static void WM_OT_link_append(wmOperatorType *ot) /* *************** recover last session **************** */ -static int wm_recover_last_session_exec(bContext *C, wmOperator *op) +void wm_recover_last_session(bContext *C, ReportList *reports) { char filename[FILE_MAX]; + + BLI_make_file_string("/", filename, BLI_temporary_dir(), BLENDER_QUIT_FILE); + /* if reports==NULL, it's called directly without operator, we add a quick check here */ + if (reports || BLI_exists(filename)) { + G.fileflags |= G_FILE_RECOVER; + + /* XXX wm in context is not set correctly after WM_file_read -> crash */ + /* do it before for now, but is this correct with multiple windows? */ + WM_event_add_notifier(C, NC_WINDOW, NULL); + + /* load file */ + WM_file_read(C, filename, reports); + + G.fileflags &= ~G_FILE_RECOVER; + + /* XXX bad global... fixme */ + if (G.main->name[0]) + G.file_loaded = 1; /* prevents splash to show */ + else + G.relbase_valid = 0; + } +} - G.fileflags |= G_FILE_RECOVER; - - /* XXX wm in context is not set correctly after WM_file_read -> crash */ - /* do it before for now, but is this correct with multiple windows? */ - WM_event_add_notifier(C, NC_WINDOW, NULL); - - /* load file */ - BLI_make_file_string("/", filename, BLI_temporary_dir(), "quit.blend"); - WM_file_read(C, filename, op->reports); - - G.fileflags &= ~G_FILE_RECOVER; +static int wm_recover_last_session_exec(bContext *C, wmOperator *op) +{ + wm_recover_last_session(C, op->reports); return OPERATOR_FINISHED; } @@ -2025,7 +2152,7 @@ static void WM_OT_recover_last_session(wmOperatorType *ot) { ot->name = "Recover Last Session"; ot->idname = "WM_OT_recover_last_session"; - ot->description = "Open the last closed file (\"quit.blend\")"; + ot->description = "Open the last closed file (\"" BLENDER_QUIT_FILE "\")"; ot->exec = wm_recover_last_session_exec; ot->poll = WM_operator_winactive; @@ -2139,7 +2266,7 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op) untitled(path); } - fileflags = G.fileflags; + fileflags = G.fileflags & ~G_FILE_USERPREFS; /* set compression flag */ BKE_BIT_TEST_SET(fileflags, RNA_boolean_get(op->ptr, "compress"), @@ -2158,7 +2285,7 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op) G_FILE_MESH_COMPAT); #endif - if (WM_file_write(C, path, fileflags, op->reports) != 0) + if (wm_file_write(C, path, fileflags, op->reports) != 0) return OPERATOR_CANCELLED; WM_event_add_notifier(C, NC_WM | ND_FILESAVE, NULL); @@ -3787,6 +3914,7 @@ void wm_operatortype_init(void) WM_operatortype_append(WM_OT_read_homefile); WM_operatortype_append(WM_OT_read_factory_settings); WM_operatortype_append(WM_OT_save_homefile); + WM_operatortype_append(WM_OT_save_userpref); WM_operatortype_append(WM_OT_window_fullscreen_toggle); WM_operatortype_append(WM_OT_quit_blender); WM_operatortype_append(WM_OT_open_mainfile); diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c index 8533494ae96..1ed9ffb3b6c 100644 --- a/source/blender/windowmanager/intern/wm_subwindow.c +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -131,7 +131,7 @@ void wm_subwindow_getorigin(wmWindow *win, int swinid, int *x, int *y) } } -void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[][4]) +void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[4][4]) { wmSubWindow *swin = swin_from_swinid(win, swinid); @@ -217,10 +217,10 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct) * fixed it). - zr (2001!) */ - if (swin->winrct.xmax > win->sizex) - swin->winrct.xmax = win->sizex; - if (swin->winrct.ymax > win->sizey) - swin->winrct.ymax = win->sizey; + if (swin->winrct.xmax > WM_window_pixels_x(win)) + swin->winrct.xmax = WM_window_pixels_x(win); + if (swin->winrct.ymax > WM_window_pixels_y(win)) + swin->winrct.ymax = WM_window_pixels_y(win); /* extra service */ wmSubWindowSet(win, swinid); @@ -257,8 +257,8 @@ void wmSubWindowScissorSet(wmWindow *win, int swinid, rcti *srct) glViewport(_curswin->winrct.xmin, _curswin->winrct.ymin, width, height); if (srct) { - width = BLI_rcti_size_x(srct) + 1; - height = BLI_rcti_size_y(srct) + 1; + int width = BLI_rcti_size_x(srct) + 1; /* only here */ + int height = BLI_rcti_size_y(srct) + 1; glScissor(srct->xmin, srct->ymin, width, height); } else diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 09f7e1692d9..be202a23d33 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -91,7 +91,9 @@ static struct WMInitStruct { int windowstate; WinOverrideFlag override_flag; -} wm_init_state = {0, 0, 0, 0, GHOST_kWindowStateNormal, 0}; + + int native_pixels; +} wm_init_state = {0, 0, 0, 0, GHOST_kWindowStateNormal, 0, 1}; /* ******** win open & close ************ */ @@ -241,7 +243,7 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig) win->screen->do_refresh = TRUE; win->screen->do_draw = TRUE; - win->drawmethod = -1; + win->drawmethod = U.wmdrawmethod; win->drawdata = NULL; return win; @@ -251,51 +253,50 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig) void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win) { wmWindow *tmpwin; - bScreen *screen = win->screen; + int do_exit = 0; + + /* first check if we have to quit (there are non-temp remaining windows) */ + for (tmpwin = wm->windows.first; tmpwin; tmpwin = tmpwin->next) { + if (tmpwin == win) + continue; + if (tmpwin->screen->temp == 0) + break; + } + + if (tmpwin == NULL) + do_exit = 1; - /* first check if we have any non-temp remaining windows */ if ((U.uiflag & USER_QUIT_PROMPT) && !wm->file_saved) { - if (wm->windows.first) { - for (tmpwin = wm->windows.first; tmpwin; tmpwin = tmpwin->next) { - if (tmpwin == win) - continue; - if (tmpwin->screen->temp == 0) - break; - } - if (tmpwin == NULL) { - if (!GHOST_confirmQuit(win->ghostwin)) - return; - } + if (do_exit) { + if (!GHOST_confirmQuit(win->ghostwin)) + return; } } - BLI_remlink(&wm->windows, win); - - wm_draw_window_clear(win); - CTX_wm_window_set(C, win); /* needed by handlers */ - WM_event_remove_handlers(C, &win->handlers); - WM_event_remove_handlers(C, &win->modalhandlers); - ED_screen_exit(C, win, win->screen); - - wm_window_free(C, wm, win); - - /* if temp screen, delete it after window free (it stops jobs that can access it) */ - if (screen->temp) { - Main *bmain = CTX_data_main(C); - BKE_libblock_free(&bmain->screen, screen); + /* let WM_exit do all freeing, for correct quit.blend save */ + if (do_exit) { + WM_exit(C); } + else { + bScreen *screen = win->screen; + + BLI_remlink(&wm->windows, win); + + wm_draw_window_clear(win); + + CTX_wm_window_set(C, win); /* needed by handlers */ + WM_event_remove_handlers(C, &win->handlers); + WM_event_remove_handlers(C, &win->modalhandlers); + ED_screen_exit(C, win, win->screen); + + wm_window_free(C, wm, win); - /* check remaining windows */ - if (wm->windows.first) { - for (win = wm->windows.first; win; win = win->next) - if (win->screen->temp == 0) - break; - /* in this case we close all */ - if (win == NULL) - WM_exit(C); - } - else - WM_exit(C); + /* if temp screen, delete it after window free (it stops jobs that can access it) */ + if (screen->temp) { + Main *bmain = CTX_data_main(C); + BKE_libblock_free(&bmain->screen, screen); + } + } } void wm_window_title(wmWindowManager *wm, wmWindow *win) @@ -308,8 +309,9 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win) /* this is set to 1 if you don't have startup.blend open */ if (G.save_over && G.main->name[0]) { - char str[sizeof(G.main->name) + 12]; - BLI_snprintf(str, sizeof(str), "Blender%s [%s]", wm->file_saved ? "" : "*", G.main->name); + char str[sizeof(G.main->name) + 24]; + BLI_snprintf(str, sizeof(str), "Blender%s [%s%s]", wm->file_saved ? "" : "*", G.main->name, + G.main->recovered ? " (Recovered)" : ""); GHOST_SetTitle(win->ghostwin, str); } else @@ -344,8 +346,6 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win) wm_get_screensize(&scr_w, &scr_h); posy = (scr_h - win->posy - win->sizey); - /* Disable AA for now, as GL_SELECT (used for border, lasso, ... select) - * doesn't work well when AA is initialized, even if not used. */ ghostwin = GHOST_CreateWindow(g_system, title, win->posx, posy, win->sizex, win->sizey, (GHOST_TWindowState)win->windowstate, @@ -354,6 +354,8 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win) multisamples /* AA */); if (ghostwin) { + GHOST_RectangleHandle bounds; + /* needed so we can detect the graphics card below */ GPU_extensions_init(); @@ -372,7 +374,19 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win) if (!GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE)) { glClear(GL_COLOR_BUFFER_BIT); } + + /* displays with larger native pixels, like Macbook. Used to scale dpi with */ + /* needed here, because it's used before it reads userdef */ + U.pixelsize = GHOST_GetNativePixelSize(); + BKE_userdef_state(); + + /* store actual window size in blender window */ + bounds = GHOST_GetClientBounds(win->ghostwin); + win->sizex = GHOST_GetWidthRectangle(bounds); + win->sizey = GHOST_GetHeightRectangle(bounds); + GHOST_DisposeRectangle(bounds); + wm_window_swap_buffers(win); //GHOST_SetWindowState(ghostwin, GHOST_kWindowStateModified); @@ -468,7 +482,7 @@ wmWindow *WM_window_open(bContext *C, rcti *rect) win->sizex = BLI_rcti_size_x(rect); win->sizey = BLI_rcti_size_y(rect); - win->drawmethod = -1; + win->drawmethod = U.wmdrawmethod; win->drawdata = NULL; WM_check(C); @@ -578,6 +592,23 @@ int wm_window_fullscreen_toggle_exec(bContext *C, wmOperator *UNUSED(op)) /* ************ events *************** */ +static void wm_convert_cursor_position(wmWindow *win, int *x, int *y) +{ + + GHOST_ScreenToClient(win->ghostwin, *x, *y, x, y); + *x *= GHOST_GetNativePixelSize(); + + *y = (win->sizey - 1) - *y; + *y *= GHOST_GetNativePixelSize(); +} + + +void wm_get_cursor_position(wmWindow *win, int *x, int *y) +{ + GHOST_GetCursorPosition(g_system, x, y); + wm_convert_cursor_position(win, x, y); +} + typedef enum { SHIFT = 's', CONTROL = 'c', @@ -633,6 +664,7 @@ void wm_window_make_drawable(bContext *C, wmWindow *win) } /* called by ghost, here we handle events for windows themselves or send to event system */ +/* mouse coordinate converversion happens here */ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr) { bContext *C = C_void_ptr; @@ -673,7 +705,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr { GHOST_TEventKeyData kdata; wmEvent event; - int cx, cy, wx, wy; + int wx, wy; wm->winactive = win; /* no context change! c->wm->windrawable is drawable, or for area queues */ @@ -703,11 +735,10 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr win->eventstate->keymodifier = 0; /* entering window, update mouse pos. but no event */ - GHOST_GetCursorPosition(g_system, &wx, &wy); - - GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy); - win->eventstate->x = cx; - win->eventstate->y = (win->sizey - 1) - cy; + wm_get_cursor_position(win, &wx, &wy); + + win->eventstate->x = wx; + win->eventstate->y = wy; win->addmousemove = 1; /* enables highlighted buttons */ @@ -857,14 +888,12 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr { wmEvent event; GHOST_TEventDragnDropData *ddd = GHOST_GetEventData(evt); - int cx, cy, wx, wy; + int wx, wy; /* entering window, update mouse pos */ - GHOST_GetCursorPosition(g_system, &wx, &wy); - - GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy); - win->eventstate->x = cx; - win->eventstate->y = (win->sizey - 1) - cy; + wm_get_cursor_position(win, &wx, &wy); + win->eventstate->x = wx; + win->eventstate->y = wy; event = *(win->eventstate); /* copy last state, like mouse coords */ @@ -907,11 +936,24 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr } } + break; + } + case GHOST_kEventTrackpad: + { + GHOST_TEventTrackpadData *pd = data; + wm_convert_cursor_position(win, &pd->x, &pd->y); + wm_event_add_ghostevent(wm, win, type, time, data); + break; + } + case GHOST_kEventCursorMove: + { + GHOST_TEventCursorData *cd = data; + wm_convert_cursor_position(win, &cd->x, &cd->y); + wm_event_add_ghostevent(wm, win, type, time, data); break; } - default: wm_event_add_ghostevent(wm, win, type, time, data); break; @@ -1017,6 +1059,10 @@ void wm_ghost_init(bContext *C) g_system = GHOST_CreateSystem(); GHOST_AddEventConsumer(g_system, consumer); + + if (wm_init_state.native_pixels) { + GHOST_UseNativePixels(); + } } } @@ -1068,6 +1114,8 @@ void WM_event_remove_timer(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer * if (wt == timer) break; if (wt) { + wmWindow *win; + if (wm->reports.reporttimer == wt) wm->reports.reporttimer = NULL; @@ -1075,6 +1123,17 @@ void WM_event_remove_timer(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer * if (wt->customdata) MEM_freeN(wt->customdata); MEM_freeN(wt); + + /* there might be events in queue with this timer as customdata */ + for (win = wm->windows.first; win; win = win->next) { + wmEvent *event; + for (event = win->queue.first; event; event = event->next) { + if (event->customdata == wt) { + event->customdata = NULL; + event->type = EVENT_NONE; /* timer users customdata, dont want NULL == NULL */ + } + } + } } } @@ -1158,23 +1217,6 @@ void wm_window_get_position(wmWindow *win, int *posx_r, int *posy_r) *posy_r = win->posy; } -void wm_window_get_size(wmWindow *win, int *width_r, int *height_r) -{ - *width_r = win->sizex; - *height_r = win->sizey; -} - -/* exceptional case: - splash is called before events are processed - * this means we don't actually know the window size so get this from GHOST */ -void wm_window_get_size_ghost(wmWindow *win, int *width_r, int *height_r) -{ - GHOST_RectangleHandle bounds = GHOST_GetClientBounds(win->ghostwin); - *width_r = GHOST_GetWidthRectangle(bounds); - *height_r = GHOST_GetHeightRectangle(bounds); - - GHOST_DisposeRectangle(bounds); -} - void wm_window_set_size(wmWindow *win, int width, int height) { GHOST_SetClientSize(win->ghostwin, width, height); @@ -1202,12 +1244,6 @@ void wm_window_swap_buffers(wmWindow *win) #endif } -void wm_get_cursor_position(wmWindow *win, int *x, int *y) -{ - GHOST_GetCursorPosition(g_system, x, y); - GHOST_ScreenToClient(win->ghostwin, *x, *y, x, y); - *y = (win->sizey - 1) - *y; -} /* ******************* exported api ***************** */ @@ -1217,8 +1253,8 @@ void WM_init_state_size_set(int stax, int stay, int sizx, int sizy) { wm_init_state.start_x = stax; /* left hand pos */ wm_init_state.start_y = stay; /* bottom pos */ - wm_init_state.size_x = sizx; - wm_init_state.size_y = sizy; + wm_init_state.size_x = sizx < 640 ? 640 : sizx; + wm_init_state.size_y = sizy < 480 ? 480 : sizy; wm_init_state.override_flag |= WIN_OVERRIDE_GEOM; } @@ -1235,12 +1271,20 @@ void WM_init_state_normal_set(void) wm_init_state.override_flag |= WIN_OVERRIDE_WINSTATE; } +void WM_init_native_pixels(int do_it) +{ + wm_init_state.native_pixels = do_it; +} + /* This function requires access to the GHOST_SystemHandle (g_system) */ void WM_cursor_warp(wmWindow *win, int x, int y) { if (win && win->ghostwin) { + float f = GHOST_GetNativePixelSize(); int oldx = x, oldy = y; + x = x / f; + y = y / f; y = win->sizey - y - 1; GHOST_ClientToScreen(win->ghostwin, x, y, &x, &y); @@ -1251,3 +1295,19 @@ void WM_cursor_warp(wmWindow *win, int x, int y) } } +/* support for native pixel size */ +/* mac retina opens window in size X, but it has up to 2 x more pixels */ +int WM_window_pixels_x(wmWindow *win) +{ + float f = GHOST_GetNativePixelSize(); + + return (int)(f * (float)win->sizex); +} + +int WM_window_pixels_y(wmWindow *win) +{ + float f = GHOST_GetNativePixelSize(); + + return (int)(f * (float)win->sizey); + +} diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h index 2d0dd2ef911..2fbfdc41bce 100644 --- a/source/blender/windowmanager/wm_event_system.h +++ b/source/blender/windowmanager/wm_event_system.h @@ -107,5 +107,8 @@ void wm_dropbox_free(void); void wm_drags_check_ops(bContext *C, wmEvent *event); void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect); +/* wm_operators.c */ +void wm_recover_last_session(bContext *C, ReportList *reports); + #endif /* __WM_EVENT_SYSTEM_H__ */ diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index 4d3d6ef89d9..c90bbaf8d6c 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -53,6 +53,8 @@ #define MOUSEX 4 #define MOUSEY 5 +/* non-event, for example disabled timer */ +#define EVENT_NONE 0 /* MOUSE : 0x00x */ #define LEFTMOUSE 1 #define MIDDLEMOUSE 2 @@ -148,6 +150,7 @@ enum { #define TIMERJOBS 0x0114 /* timer event, jobs system */ #define TIMERAUTOSAVE 0x0115 /* timer event, autosave */ #define TIMERREPORT 0x0116 /* timer event, reports */ +#define TIMERREGION 0x0117 /* timer event, region slide in/out */ #define TIMERF 0x011F /* last timer */ /* test whether the event is timer event */ diff --git a/source/blender/windowmanager/wm_files.h b/source/blender/windowmanager/wm_files.h index f373530b5e6..fe007e7f52f 100644 --- a/source/blender/windowmanager/wm_files.h +++ b/source/blender/windowmanager/wm_files.h @@ -31,7 +31,13 @@ #ifndef __WM_FILES_H__ #define __WM_FILES_H__ -void WM_read_history(void); +void wm_read_history(void); +int wm_file_write(struct bContext *C, const char *target, int fileflags, struct ReportList *reports); +int wm_homefile_read_exec(struct bContext *C, struct wmOperator *op); +int wm_homefile_read(struct bContext *C, struct ReportList *reports, short from_memory); +int wm_homefile_write_exec(struct bContext *C, struct wmOperator *op); +int wm_userpref_write_exec(struct bContext *C, struct wmOperator *op); + #endif /* __WM_FILES_H__ */ diff --git a/source/blender/windowmanager/wm_subwindow.h b/source/blender/windowmanager/wm_subwindow.h index 5017977952b..b584d0127a5 100644 --- a/source/blender/windowmanager/wm_subwindow.h +++ b/source/blender/windowmanager/wm_subwindow.h @@ -46,7 +46,7 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct); void wm_subwindow_getsize(wmWindow *win, int swinid, int *x, int *y); void wm_subwindow_getorigin(wmWindow *win, int swinid, int *x, int *y); -void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[][4]); +void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[4][4]); unsigned int index_to_framebuffer(int index); diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h index 6360cfd4802..ce360f5ef56 100644 --- a/source/blender/windowmanager/wm_window.h +++ b/source/blender/windowmanager/wm_window.h @@ -55,8 +55,6 @@ void wm_window_make_drawable(bContext *C, wmWindow *win); void wm_window_raise (wmWindow *win); void wm_window_lower (wmWindow *win); void wm_window_set_size (wmWindow *win, int width, int height); -void wm_window_get_size (wmWindow *win, int *width_r, int *height_r); -void wm_window_get_size_ghost(wmWindow *win, int *width_r, int *height_r); void wm_window_get_position (wmWindow *win, int *posx_r, int *posy_r); void wm_window_swap_buffers (wmWindow *win); diff --git a/source/blenderplayer/bad_level_call_stubs/SConscript b/source/blenderplayer/bad_level_call_stubs/SConscript index 5efe9aa5761..f26f4dfea6b 100644 --- a/source/blenderplayer/bad_level_call_stubs/SConscript +++ b/source/blenderplayer/bad_level_call_stubs/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 = 'stubs.c' diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 8274585cdb1..014fefb8219 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -179,7 +179,7 @@ int RE_RenderInProgress(struct Render *re) {return 0;} struct Scene *RE_GetScene(struct Render *re) {return (struct Scene *) NULL;} void RE_Database_Free(struct Render *re) {} void RE_FreeRender(struct Render *re) {} -void RE_DataBase_GetView(struct Render *re, float mat[][4]) {} +void RE_DataBase_GetView(struct Render *re, float mat[4][4]) {} int externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta) {return 0;} float texture_value_blend(float tex, float out, float fact, float facg, int blendtype, int flip) {return 0.0f;} void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg, int blendtype) {} @@ -302,13 +302,13 @@ void ED_node_tree_update(struct SpaceNode *snode, struct Scene *scene) {} void ED_view3d_scene_layers_update(struct Main *bmain, struct Scene *scene) {} int ED_view3d_scene_layer_set(int lay, const int *values) {return 0;} void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar) {} -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) {} struct BGpic *ED_view3D_background_image_new(struct View3D *v3d) {return (struct BGpic *) NULL;} void ED_view3D_background_image_remove(struct View3D *v3d, struct BGpic *bgpic) {} void ED_view3D_background_image_clear(struct View3D *v3d) {} -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]) {} float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit) {return 0.0f;} -void view3d_apply_mat4(float mat[][4], float *ofs, float *quat, float *dist) {} +void view3d_apply_mat4(float mat[4][4], float *ofs, float *quat, float *dist) {} int text_file_modified(struct Text *text) {return 0;} void ED_node_shader_default(struct Material *ma) {} void ED_screen_animation_timer_update(struct bContext *C, int redraws) {} diff --git a/source/creator/creator.c b/source/creator/creator.c index b0eff2770ba..3bf02298ddf 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -483,6 +483,12 @@ static int prefsize(int argc, const char **argv, void *UNUSED(data)) return 4; } +static int native_pixels(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data)) +{ + WM_init_native_pixels(0); + return 0; +} + static int with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data)) { WM_init_state_normal_set(); @@ -1161,6 +1167,7 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle) BLI_argsAdd(ba, 2, "-con", "--start-console", "\n\tStart with the console window open (ignored if -b is set)", start_with_console, NULL); BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension, then exit (Windows only)", register_extension, NULL); BLI_argsAdd(ba, 2, "-r", NULL, "\n\tSilently register .blend extension, then exit (Windows only)", register_extension, ba); + BLI_argsAdd(ba, 2, NULL, "--no-native-pixels", "\n\tDo not use native pixel size, for high resolution displays (MacBook 'Retina')", native_pixels, ba); /* third pass: disabling things and forcing settings */ BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle); diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 6807f531f0a..9f788b29ac6 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -58,7 +58,6 @@ #include "RAS_GLExtensionManager.h" #include "RAS_OpenGLRasterizer.h" -#include "RAS_VAOpenGLRasterizer.h" #include "RAS_ListRasterizer.h" #include "NG_LoopBackNetworkDeviceInterface.h" @@ -287,16 +286,12 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c RAS_IRenderTools* rendertools = new KX_BlenderRenderTools(); RAS_IRasterizer* rasterizer = NULL; - if (displaylists) { - if (GLEW_VERSION_1_1 && !novertexarrays) - rasterizer = new RAS_ListRasterizer(canvas, true, true); - else - rasterizer = new RAS_ListRasterizer(canvas); - } - else if (GLEW_VERSION_1_1 && !novertexarrays) - rasterizer = new RAS_VAOpenGLRasterizer(canvas, false); + //Don't use displaylists with VBOs + //If auto starts using VBOs, make sure to check for that here + if (displaylists && startscene->gm.raster_storage != RAS_STORE_VBO) + rasterizer = new RAS_ListRasterizer(canvas, true, startscene->gm.raster_storage); else - rasterizer = new RAS_OpenGLRasterizer(canvas); + rasterizer = new RAS_OpenGLRasterizer(canvas, startscene->gm.raster_storage); // create the inputdevices KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice(); diff --git a/source/gameengine/BlenderRoutines/SConscript b/source/gameengine/BlenderRoutines/SConscript index 04dbe27337f..e2417d70b58 100644 --- a/source/gameengine/BlenderRoutines/SConscript +++ b/source/gameengine/BlenderRoutines/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('*.cpp') diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index eb695e624e4..15fc5ba76c7 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -423,55 +423,61 @@ static void SetDefaultLightMode(Scene* scene) // -- -static void GetRGB( - const bool use_mcol, - MFace *mface, - MCol *mmcol, - Material *mat, - unsigned int &c0, - unsigned int &c1, - unsigned int &c2, - unsigned int &c3) +static void GetRGB(short type, + MFace* mface, + MCol* mmcol, + Material *mat, + unsigned int c[4]) { unsigned int color = 0xFFFFFFFFL; - if (use_mcol) { - // vertex colors - - if (mmcol) { - c0 = KX_Mcol2uint_new(mmcol[0]); - c1 = KX_Mcol2uint_new(mmcol[1]); - c2 = KX_Mcol2uint_new(mmcol[2]); + switch (type) { + case 0: // vertex colors + { + if (mmcol) { + c[0] = KX_Mcol2uint_new(mmcol[0]); + c[1] = KX_Mcol2uint_new(mmcol[1]); + c[2] = KX_Mcol2uint_new(mmcol[2]); + if (mface->v4) + c[3] = KX_Mcol2uint_new(mmcol[3]); + } + else { // backup white + c[0] = KX_rgbaint2uint_new(color); + c[1] = KX_rgbaint2uint_new(color); + c[2] = KX_rgbaint2uint_new(color); + if (mface->v4) + c[3] = KX_rgbaint2uint_new( color ); + } + } break; + + + case 1: // material rgba + { + if (mat) { + union { + unsigned char cp[4]; + unsigned int integer; + } col_converter; + col_converter.cp[3] = (unsigned char) (mat->r * 255.0f); + col_converter.cp[2] = (unsigned char) (mat->g * 255.0f); + col_converter.cp[1] = (unsigned char) (mat->b * 255.0f); + col_converter.cp[0] = (unsigned char) (mat->alpha * 255.0f); + color = col_converter.integer; + } + c[0] = KX_rgbaint2uint_new(color); + c[1] = KX_rgbaint2uint_new(color); + c[2] = KX_rgbaint2uint_new(color); if (mface->v4) - c3 = KX_Mcol2uint_new(mmcol[3]); - } - else { // backup white - c0 = KX_rgbaint2uint_new(color); - c1 = KX_rgbaint2uint_new(color); - c2 = KX_rgbaint2uint_new(color); + c[3] = KX_rgbaint2uint_new(color); + } break; + + default: // white + { + c[0] = KX_rgbaint2uint_new(color); + c[1] = KX_rgbaint2uint_new(color); + c[2] = KX_rgbaint2uint_new(color); if (mface->v4) - c3 = KX_rgbaint2uint_new( color ); - } - } - else { - // material rgba - if (mat) { - union { - unsigned char cp[4]; - unsigned int integer; - } col_converter; - col_converter.cp[3] = (unsigned char) (mat->r * 255.0f); - col_converter.cp[2] = (unsigned char) (mat->g * 255.0f); - col_converter.cp[1] = (unsigned char) (mat->b * 255.0f); - col_converter.cp[0] = (unsigned char) (mat->alpha * 255.0f); - color = col_converter.integer; - } - // backup white is fallback - - c0 = KX_rgbaint2uint_new(color); - c1 = KX_rgbaint2uint_new(color); - c2 = KX_rgbaint2uint_new(color); - if (mface->v4) - c3 = KX_rgbaint2uint_new(color); + c[3] = KX_rgbaint2uint_new(color); + } break; } } @@ -480,42 +486,67 @@ typedef struct MTF_localLayer { const char *name; } MTF_localLayer; -static void tface_to_uv_bge(const MFace *mface, const MTFace *tface, MT_Point2 uv[4]) +static void GetUVs(BL_Material *material, MTF_localLayer *layers, MFace *mface, MTFace *tface, MT_Point2 uvs[4][MAXTEX]) { - uv[0].setValue(tface->uv[0]); - uv[1].setValue(tface->uv[1]); - uv[2].setValue(tface->uv[2]); - if (mface->v4) { - uv[3].setValue(tface->uv[3]); + int unit = 0; + if (tface) + { + + uvs[0][0].setValue(tface->uv[0]); + uvs[1][0].setValue(tface->uv[1]); + uvs[2][0].setValue(tface->uv[2]); + + if (mface->v4) + uvs[3][0].setValue(tface->uv[3]); } -} + else + { + uvs[0][0] = uvs[1][0] = uvs[2][0] = uvs[3][0] = MT_Point2(0.f, 0.f); + } + + for (int vind = 0; vind<MAXTEX; vind++) + { + BL_Mapping &map = material->mapping[vind]; -static void GetUV( - MFace *mface, - MTFace *tface, - MTF_localLayer *layers, - const int layer_uv[2], - MT_Point2 uv[4], - MT_Point2 uv2[4]) -{ - bool validface = (tface != NULL); + if (!(map.mapping & USEUV)) continue; - uv2[0] = uv2[1] = uv2[2] = uv2[3] = MT_Point2(0.0f, 0.0f); + //If no UVSet is specified, try grabbing one from the UV/Image editor + if (map.uvCoName.IsEmpty() && tface) + { + uvs[0][unit].setValue(tface->uv[0]); + uvs[1][unit].setValue(tface->uv[1]); + uvs[2][unit].setValue(tface->uv[2]); - /* No material, what to do? let's see what is in the UV and set the material accordingly - * light and visible is always on */ - if (layer_uv[0] != -1) { - tface_to_uv_bge(mface, layers[layer_uv[0]].face, uv); - if (layer_uv[1] != -1) { - tface_to_uv_bge(mface, layers[layer_uv[1]].face, uv2); + if (mface->v4) + uvs[3][unit].setValue(tface->uv[3]); + + ++unit; + continue; + } + + + for (int lay=0; lay<MAX_MTFACE; lay++) + { + MTF_localLayer& layer = layers[lay]; + if (layer.face == 0) break; + + if (map.uvCoName.IsEmpty() || strcmp(map.uvCoName.ReadPtr(), layer.name)==0) + { + MT_Point2 uvSet[4]; + + uvs[0][unit].setValue(layer.face->uv[0]); + uvs[1][unit].setValue(layer.face->uv[1]); + uvs[2][unit].setValue(layer.face->uv[2]); + + if (mface->v4) + uvs[3][unit].setValue(layer.face->uv[3]); + else + uvs[3][unit].setValue(0.0f, 0.0f); + + ++unit; + break; + } } - } - else if (validface) { - tface_to_uv_bge(mface, tface, uv); - } - else { - // nothing at all - uv[0] = uv[1] = uv[2] = uv[3] = MT_Point2(0.0f, 0.0f); } } @@ -526,25 +557,29 @@ static bool ConvertMaterial( MTFace* tface, const char *tfaceName, MFace* mface, - MCol* mmcol, /* only for text, use first mcol, weak */ - MTF_localLayer *layers, - int layer_uv[2], - const bool glslmat) + MCol* mmcol, + bool glslmat) { material->Initialize(); - int numchan = -1, texalpha = 0; + int texalpha = 0; bool validmat = (mat!=0); bool validface = (tface!=0); + short type = 0; + if ( validmat ) + type = 1; // material color + material->IdMode = DEFAULT_BLENDER; material->glslmat = (validmat)? glslmat: false; material->materialindex = mface->mat_nr; - /* default value for being unset */ - layer_uv[0] = layer_uv[1] = -1; - // -------------------------------- if (validmat) { + + // use vertex colors by explicitly setting + if (mat->mode &MA_VERTEXCOLP || glslmat) + type = 0; + // use lighting? material->ras_mode |= ( mat->mode & MA_SHLESS )?0:USE_LIGHT; material->ras_mode |= ( mat->game.flag & GEMAT_BACKCULL )?0:TWOSIDED; @@ -552,7 +587,6 @@ static bool ConvertMaterial( // cast shadows? material->ras_mode |= ( mat->mode & MA_SHADBUF )?CAST_SHADOW:0; MTex *mttmp = 0; - numchan = getNumTexChannels(mat); int valid_index = 0; /* In Multitexture use the face texture if and only if @@ -561,12 +595,9 @@ static bool ConvertMaterial( bool facetex = false; if (validface && mat->mode &MA_FACETEXTURE) facetex = true; - - numchan = numchan>MAXTEX?MAXTEX:numchan; - if (facetex && numchan == 0) numchan = 1; // foreach MTex - for (int i=0; i<numchan; i++) { + for (int i=0; i<MAXTEX; i++) { // use face tex if (i==0 && facetex ) { @@ -798,14 +829,11 @@ static bool ConvertMaterial( material->ras_mode |= USE_LIGHT; } - const char *uvName = "", *uv2Name = ""; - /* No material, what to do? let's see what is in the UV and set the material accordingly * light and visible is always on */ if ( validface ) { material->tile = tface->tile; - uvName = tfaceName; - } + } else { // nothing at all material->alphablend = GEMAT_SOLID; @@ -826,45 +854,19 @@ static bool ConvertMaterial( material->ras_mode |= (mat && (mat->game.alpha_blend & GEMAT_ALPHA_SORT))? ZSORT: 0; } - // get uv sets - if (validmat) { - bool isFirstSet = true; - - // only two sets implemented, but any of the eight - // sets can make up the two layers - for (int vind = 0; vind<material->num_enabled; vind++) { - BL_Mapping &map = material->mapping[vind]; - - if (map.uvCoName.IsEmpty()) { - isFirstSet = false; - } - else { - for (int lay=0; lay<MAX_MTFACE; lay++) { - MTF_localLayer& layer = layers[lay]; - if (layer.face == 0) break; - - if (strcmp(map.uvCoName.ReadPtr(), layer.name)==0) { - if (isFirstSet) { - layer_uv[0] = lay; - isFirstSet = false; - uvName = layer.name; - } - else if (strcmp(layer.name, uvName) != 0) { - layer_uv[1] = lay; - map.mapping |= USECUSTOMUV; - uv2Name = layer.name; - } - } - } - } - } - } + // XXX The RGB values here were meant to be temporary storage for the conversion process, + // but fonts now make use of them too, so we leave them in for now. + unsigned int rgb[4]; + GetRGB(type,mface,mmcol,mat,rgb); - if (validmat && mmcol) { /* color is only for text */ - material->m_mcol = *(unsigned int *)mmcol; + // swap the material color, so MCol on bitmap font works + if (validmat && type==1 && (mat->game.flag & GEMAT_TEXT)) + { + rgb[0] = KX_rgbaint2uint_new(rgb[0]); + rgb[1] = KX_rgbaint2uint_new(rgb[1]); + rgb[2] = KX_rgbaint2uint_new(rgb[2]); + rgb[3] = KX_rgbaint2uint_new(rgb[3]); } - material->SetUVLayerName(uvName); - material->SetUVLayerName2(uv2Name); if (validmat) material->matname =(mat->id.name); @@ -879,8 +881,189 @@ static bool ConvertMaterial( return true; } +RAS_MaterialBucket* material_from_mesh(Material *ma, MFace *mface, MTFace *tface, MCol *mcol, MTF_localLayer *layers, int lightlayer, unsigned int *rgb, MT_Point2 uvs[4][RAS_TexVert::MAX_UNIT], const char *tfaceName, KX_Scene* scene, KX_BlenderSceneConverter *converter) +{ + RAS_IPolyMaterial* polymat = converter->FindCachedPolyMaterial(ma); + BL_Material* bl_mat = converter->FindCachedBlenderMaterial(ma); + KX_BlenderMaterial* kx_blmat = NULL; + KX_PolygonMaterial* kx_polymat = NULL; + + if (converter->GetMaterials()) { + /* do Blender Multitexture and Blender GLSL materials */ + + /* first is the BL_Material */ + if (!bl_mat) + { + bl_mat = new BL_Material(); + + ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol, + converter->GetGLSLMaterials()); + + converter->CacheBlenderMaterial(ma, bl_mat); + } + + + short type = (ma) ? ((ma->mode & MA_VERTEXCOLP || bl_mat->glslmat) ? 0 : 1) : 0; + GetRGB(type,mface,mcol,ma,rgb); + + GetUVs(bl_mat, layers, mface, tface, uvs); + + /* then the KX_BlenderMaterial */ + if (polymat == NULL) + { + kx_blmat = new KX_BlenderMaterial(); + + kx_blmat->Initialize(scene, bl_mat, (ma?&ma->game:NULL), lightlayer); + polymat = static_cast<RAS_IPolyMaterial*>(kx_blmat); + converter->CachePolyMaterial(ma, polymat); + } + } + else { + /* do Texture Face materials */ + Image* bima = (tface)? (Image*)tface->tpage: NULL; + STR_String imastr = (tface)? (bima? (bima)->id.name : "" ) : ""; + + char alpha_blend=0; + short tile=0; + int tilexrep=4,tileyrep = 4; + + /* set material properties - old TexFace */ + if (ma) { + alpha_blend = ma->game.alpha_blend; + /* Commented out for now. If we ever get rid of + * "Texture Face/Singletexture" we can then think about it */ + + /* Texture Face mode ignores texture but requires "Face Textures to be True "*/ + #if 0 + if ((ma->mode &MA_FACETEXTURE)==0 && (ma->game.flag &GEMAT_TEXT)==0) { + bima = NULL; + imastr = ""; + alpha_blend = GEMAT_SOLID; + } + else { + alpha_blend = ma->game.alpha_blend; + } + #endif + } + /* check for tface tex to fallback on */ + else { + if (bima) { + /* see if depth of the image is 32 */ + if (BKE_image_has_alpha(bima)) + alpha_blend = GEMAT_ALPHA; + else + alpha_blend = GEMAT_SOLID; + } + else { + alpha_blend = GEMAT_SOLID; + } + } + + if (bima) { + tilexrep = bima->xrep; + tileyrep = bima->yrep; + } + + /* set UV properties */ + if (tface) { + uvs[0][0].setValue(tface->uv[0]); + uvs[1][0].setValue(tface->uv[1]); + uvs[2][0].setValue(tface->uv[2]); + + if (mface->v4) + uvs[3][0].setValue(tface->uv[3]); + + tile = tface->tile; + } + else { + /* no texfaces */ + tile = 0; + } + + /* get vertex colors */ + if (mcol) { + /* we have vertex colors */ + rgb[0] = KX_Mcol2uint_new(mcol[0]); + rgb[1] = KX_Mcol2uint_new(mcol[1]); + rgb[2] = KX_Mcol2uint_new(mcol[2]); + + if (mface->v4) + rgb[3] = KX_Mcol2uint_new(mcol[3]); + } + else { + /* no vertex colors, take from material, otherwise white */ + unsigned int color = 0xFFFFFFFFL; + + if (ma) + { + union + { + unsigned char cp[4]; + unsigned int integer; + } col_converter; + + col_converter.cp[3] = (unsigned char) (ma->r*255.0); + col_converter.cp[2] = (unsigned char) (ma->g*255.0); + col_converter.cp[1] = (unsigned char) (ma->b*255.0); + col_converter.cp[0] = (unsigned char) (ma->alpha*255.0); + + color = col_converter.integer; + } + + rgb[0] = KX_rgbaint2uint_new(color); + rgb[1] = KX_rgbaint2uint_new(color); + rgb[2] = KX_rgbaint2uint_new(color); + + if (mface->v4) + rgb[3] = KX_rgbaint2uint_new(color); + } + + // only zsort alpha + add + bool alpha = ELEM3(alpha_blend, GEMAT_ALPHA, GEMAT_ADD, GEMAT_ALPHA_SORT); + bool zsort = (alpha_blend == GEMAT_ALPHA_SORT); + bool light = (ma)?(ma->mode & MA_SHLESS)==0:default_light_mode; + + // don't need zort anymore, deal as if it it's alpha blend + if (alpha_blend == GEMAT_ALPHA_SORT) alpha_blend = GEMAT_ALPHA; + + if (polymat == NULL) + { + kx_polymat = new KX_PolygonMaterial(); + kx_polymat->Initialize(imastr, ma, (int)mface->mat_nr, + tile, tilexrep, tileyrep, + alpha_blend, alpha, zsort, light, lightlayer, tface, (unsigned int*)mcol); + polymat = static_cast<RAS_IPolyMaterial*>(kx_polymat); + + if (ma) { + polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec; + polymat->m_shininess = (float)ma->har/4.0f; // 0 < ma->har <= 512 + polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref); + } + else { + polymat->m_specular.setValue(0.0f,0.0f,0.0f); + polymat->m_shininess = 35.0; + } + + converter->CachePolyMaterial(ma, polymat); + } + } + + // see if a bucket was reused or a new one was created + // this way only one KX_BlenderMaterial object has to exist per bucket + bool bucketCreated; + RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated); + if (bucketCreated) { + // this is needed to free up memory afterwards + converter->RegisterPolyMaterial(polymat); + if (converter->GetMaterials()) + converter->RegisterBlenderMaterial(bl_mat); + } + + return bucket; +} + /* blenderobj can be NULL, make sure its checked for */ -RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, KX_BlenderSceneConverter *converter) +RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, KX_BlenderSceneConverter *converter, bool libloading) { RAS_MeshObject *meshobj; int lightlayer = blenderobj ? blenderobj->lay:(1<<20)-1; // all layers if no object. @@ -910,7 +1093,6 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, // Extract avaiable layers MTF_localLayer *layers = new MTF_localLayer[MAX_MTFACE]; - int layer_uv[2]; /* store uv1, uv2 layers */ for (int lay=0; lay<MAX_MTFACE; lay++) { layers[lay].face = 0; layers[lay].name = ""; @@ -933,31 +1115,23 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, meshobj->SetName(mesh->id.name + 2); meshobj->m_sharedvertex_map.resize(totvert); - RAS_IPolyMaterial* polymat = NULL; - STR_String imastr; - // These pointers will hold persistent material structure during the conversion - // to avoid countless allocation/deallocation of memory. - BL_Material* bl_mat = NULL; - KX_BlenderMaterial* kx_blmat = NULL; - KX_PolygonMaterial* kx_polymat = NULL; - for (int f=0;f<totface;f++,mface++) - { - Material* ma = 0; - bool collider = true; - MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0); - MT_Point2 uv20(0.0,0.0),uv21(0.0,0.0),uv22(0.0,0.0),uv23(0.0,0.0); - unsigned int rgb0,rgb1,rgb2,rgb3 = 0; + Material* ma = 0; + bool collider = true; + MT_Point2 uvs[4][RAS_TexVert::MAX_UNIT]; + unsigned int rgb[4] = {0}; - MT_Point3 pt0, pt1, pt2, pt3; - MT_Vector3 no0(0,0,0), no1(0,0,0), no2(0,0,0), no3(0,0,0); - MT_Vector4 tan0(0,0,0,0), tan1(0,0,0,0), tan2(0,0,0,0), tan3(0,0,0,0); + MT_Point3 pt[4]; + MT_Vector3 no[4]; + MT_Vector4 tan[4]; + for (int f=0;f<totface;f++,mface++) + { /* get coordinates, normals and tangents */ - pt0.setValue(mvert[mface->v1].co); - pt1.setValue(mvert[mface->v2].co); - pt2.setValue(mvert[mface->v3].co); - if (mface->v4) pt3.setValue(mvert[mface->v4].co); + pt[0].setValue(mvert[mface->v1].co); + pt[1].setValue(mvert[mface->v2].co); + pt[2].setValue(mvert[mface->v3].co); + if (mface->v4) pt[3].setValue(mvert[mface->v4].co); if (mface->flag & ME_SMOOTH) { float n0[3], n1[3], n2[3], n3[3]; @@ -965,13 +1139,13 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, normal_short_to_float_v3(n0, mvert[mface->v1].no); normal_short_to_float_v3(n1, mvert[mface->v2].no); normal_short_to_float_v3(n2, mvert[mface->v3].no); - no0 = n0; - no1 = n1; - no2 = n2; + no[0] = n0; + no[1] = n1; + no[2] = n2; if (mface->v4) { normal_short_to_float_v3(n3, mvert[mface->v4].no); - no3 = n3; + no[3] = n3; } } else { @@ -982,16 +1156,16 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, else normal_tri_v3(fno,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co); - no0 = no1 = no2 = no3 = MT_Vector3(fno); + no[0] = no[1] = no[2] = no[3] = MT_Vector3(fno); } if (tangent) { - tan0 = tangent[f*4 + 0]; - tan1 = tangent[f*4 + 1]; - tan2 = tangent[f*4 + 2]; + tan[0] = tangent[f*4 + 0]; + tan[1] = tangent[f*4 + 1]; + tan[2] = tangent[f*4 + 2]; if (mface->v4) - tan3 = tangent[f*4 + 3]; + tan[3] = tangent[f*4 + 3]; } if (blenderobj) ma = give_current_material(blenderobj, mface->mat_nr+1); @@ -1007,171 +1181,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, bool visible = true; bool twoside = false; - if (converter->GetMaterials()) { - const bool is_bl_mat_new = (bl_mat == NULL); - //const bool is_kx_blmat_new = (kx_blmat == NULL); - const bool glslmat = converter->GetGLSLMaterials(); - const bool use_mcol = ma ? (ma->mode & MA_VERTEXCOLP || glslmat) : true; - /* do Blender Multitexture and Blender GLSL materials */ - MT_Point2 uv_1[4]; - MT_Point2 uv_2[4]; - - /* first is the BL_Material */ - if (!bl_mat) { - bl_mat = new BL_Material(); - } - - /* only */ - if (is_bl_mat_new || (bl_mat->material != ma)) { - ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol, - layers, layer_uv, glslmat); - } - - /* vertex colors and uv's from the faces */ - GetRGB(use_mcol, mface, mcol, ma, rgb0, rgb1, rgb2, rgb3); - GetUV(mface, tface, layers, layer_uv, uv_1, uv_2); - - uv0 = uv_1[0]; uv1 = uv_1[1]; - uv2 = uv_1[2]; uv3 = uv_1[3]; - - uv20 = uv_2[0]; uv21 = uv_2[1]; - uv22 = uv_2[2]; uv23 = uv_2[3]; - - /* then the KX_BlenderMaterial */ - if (kx_blmat == NULL) - kx_blmat = new KX_BlenderMaterial(); - - //if (is_kx_blmat_new || !kx_blmat->IsMaterial(bl_mat)) { - kx_blmat->Initialize(scene, bl_mat, (ma ? &ma->game : NULL)); - //} - - polymat = static_cast<RAS_IPolyMaterial*>(kx_blmat); - } - else { - /* do Texture Face materials */ - Image* bima = (tface)? (Image*)tface->tpage: NULL; - imastr = (tface)? (bima? (bima)->id.name : "" ) : ""; - - char alpha_blend=0; - short tile=0; - int tilexrep=4,tileyrep = 4; - - /* set material properties - old TexFace */ - if (ma) { - alpha_blend = ma->game.alpha_blend; - /* Commented out for now. If we ever get rid of - * "Texture Face/Singletexture" we can then think about it */ - - /* Texture Face mode ignores texture but requires "Face Textures to be True "*/ -#if 0 - if ((ma->mode &MA_FACETEXTURE)==0 && (ma->game.flag &GEMAT_TEXT)==0) { - bima = NULL; - imastr = ""; - alpha_blend = GEMAT_SOLID; - } - else { - alpha_blend = ma->game.alpha_blend; - } -#endif - } - /* check for tface tex to fallback on */ - else { - if (bima) { - /* see if depth of the image is 32 */ - if (BKE_image_has_alpha(bima)) - alpha_blend = GEMAT_ALPHA; - else - alpha_blend = GEMAT_SOLID; - } - else { - alpha_blend = GEMAT_SOLID; - } - } - - if (bima) { - tilexrep = bima->xrep; - tileyrep = bima->yrep; - } - - /* set UV properties */ - if (tface) { - uv0.setValue(tface->uv[0]); - uv1.setValue(tface->uv[1]); - uv2.setValue(tface->uv[2]); - - if (mface->v4) - uv3.setValue(tface->uv[3]); - - tile = tface->tile; - } - else { - /* no texfaces */ - tile = 0; - } - - /* get vertex colors */ - if (mcol) { - /* we have vertex colors */ - rgb0 = KX_Mcol2uint_new(mcol[0]); - rgb1 = KX_Mcol2uint_new(mcol[1]); - rgb2 = KX_Mcol2uint_new(mcol[2]); - - if (mface->v4) - rgb3 = KX_Mcol2uint_new(mcol[3]); - } - else { - /* no vertex colors, take from material, otherwise white */ - unsigned int color = 0xFFFFFFFFL; - - if (ma) - { - union - { - unsigned char cp[4]; - unsigned int integer; - } col_converter; - - col_converter.cp[3] = (unsigned char) (ma->r * 255.0f); - col_converter.cp[2] = (unsigned char) (ma->g * 255.0f); - col_converter.cp[1] = (unsigned char) (ma->b * 255.0f); - col_converter.cp[0] = (unsigned char) (ma->alpha * 255.0f); - - color = col_converter.integer; - } - - rgb0 = KX_rgbaint2uint_new(color); - rgb1 = KX_rgbaint2uint_new(color); - rgb2 = KX_rgbaint2uint_new(color); - - if (mface->v4) - rgb3 = KX_rgbaint2uint_new(color); - } - - // only zsort alpha + add - bool alpha = ELEM3(alpha_blend, GEMAT_ALPHA, GEMAT_ADD, GEMAT_ALPHA_SORT); - bool zsort = (alpha_blend == GEMAT_ALPHA_SORT); - bool light = (ma)?(ma->mode & MA_SHLESS)==0:default_light_mode; - - // don't need zort anymore, deal as if it it's alpha blend - if (alpha_blend == GEMAT_ALPHA_SORT) alpha_blend = GEMAT_ALPHA; - - if (kx_polymat == NULL) - kx_polymat = new KX_PolygonMaterial(); - kx_polymat->Initialize(imastr, ma, (int)mface->mat_nr, - tile, tilexrep, tileyrep, - alpha_blend, alpha, zsort, light, lightlayer, tface, (unsigned int*)mcol); - polymat = static_cast<RAS_IPolyMaterial*>(kx_polymat); - - if (ma) { - polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec; - polymat->m_shininess = (float)ma->har/4.0f; // 0 < ma->har <= 512 - polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref); - } - else { - polymat->m_specular.setValue(0.0f,0.0f,0.0f); - polymat->m_shininess = 35.0; - } - } + RAS_MaterialBucket* bucket = material_from_mesh(ma, mface, tface, mcol, layers, lightlayer, rgb, uvs, tfaceName, scene, converter); // set render flags if (ma) @@ -1188,30 +1198,9 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, /* mark face as flat, so vertices are split */ bool flat = (mface->flag & ME_SMOOTH) == 0; - - // see if a bucket was reused or a new one was created - // this way only one KX_BlenderMaterial object has to exist per bucket - bool bucketCreated; - RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated); - if (bucketCreated) { - // this is needed to free up memory afterwards - converter->RegisterPolyMaterial(polymat); - if (converter->GetMaterials()) { - converter->RegisterBlenderMaterial(bl_mat); - // the poly material has been stored in the bucket, next time we must create a new one - bl_mat = NULL; - kx_blmat = NULL; - } else { - // the poly material has been stored in the bucket, next time we must create a new one - kx_polymat = NULL; - } - } else { - // from now on, use the polygon material from the material bucket - polymat = bucket->GetPolyMaterial(); - // keep the material pointers, they will be reused for next face - } - + int nverts = (mface->v4)? 4: 3; + RAS_Polygon *poly = meshobj->AddPolygon(bucket, nverts); poly->SetVisible(visible); @@ -1219,12 +1208,12 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, poly->SetTwoside(twoside); //poly->SetEdgeCode(mface->edcode); - meshobj->AddVertex(poly,0,pt0,uv0,uv20,tan0,rgb0,no0,flat,mface->v1); - meshobj->AddVertex(poly,1,pt1,uv1,uv21,tan1,rgb1,no1,flat,mface->v2); - meshobj->AddVertex(poly,2,pt2,uv2,uv22,tan2,rgb2,no2,flat,mface->v3); + meshobj->AddVertex(poly,0,pt[0],uvs[0],tan[0],rgb[0],no[0],flat,mface->v1); + meshobj->AddVertex(poly,1,pt[1],uvs[1],tan[1],rgb[1],no[1],flat,mface->v2); + meshobj->AddVertex(poly,2,pt[2],uvs[2],tan[2],rgb[2],no[2],flat,mface->v3); if (nverts==4) - meshobj->AddVertex(poly,3,pt3,uv3,uv23,tan3,rgb3,no3,flat,mface->v4); + meshobj->AddVertex(poly,3,pt[3],uvs[3],tan[3],rgb[3],no[3],flat,mface->v4); } if (tface) @@ -1246,22 +1235,19 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, meshobj->EndConversion(); // pre calculate texture generation - for (list<RAS_MeshMaterial>::iterator mit = meshobj->GetFirstMaterial(); - mit != meshobj->GetLastMaterial(); ++ mit) { - mit->m_bucket->GetPolyMaterial()->OnConstruction(lightlayer); + // However, we want to delay this if we're libloading so we can make sure we have the right scene. + if (!libloading) { + for (list<RAS_MeshMaterial>::iterator mit = meshobj->GetFirstMaterial(); + mit != meshobj->GetLastMaterial(); ++ mit) { + mit->m_bucket->GetPolyMaterial()->OnConstruction(); + } } if (layers) delete []layers; dm->release(dm); - // cleanup material - if (bl_mat) - delete bl_mat; - if (kx_blmat) - delete kx_blmat; - if (kx_polymat) - delete kx_polymat; + converter->RegisterGameMesh(meshobj, mesh); return meshobj; } @@ -1921,7 +1907,8 @@ static KX_GameObject *gameobject_from_blenderobject( Object *ob, KX_Scene *kxscene, RAS_IRenderTools *rendertools, - KX_BlenderSceneConverter *converter) + KX_BlenderSceneConverter *converter, + bool libloading) { KX_GameObject *gameobj = NULL; Scene *blenderscene = kxscene->GetBlenderScene(); @@ -1958,7 +1945,7 @@ static KX_GameObject *gameobject_from_blenderobject( Mesh* mesh = static_cast<Mesh*>(ob->data); float center[3], extents[3]; float radius = my_boundbox_mesh((Mesh*) ob->data, center, extents); - RAS_MeshObject* meshobj = BL_ConvertMesh(mesh,ob,kxscene,converter); + RAS_MeshObject* meshobj = BL_ConvertMesh(mesh,ob,kxscene,converter, libloading); // needed for python scripting kxscene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj); @@ -2187,26 +2174,37 @@ static void bl_ConvertBlenderObject_Single( blenderobject->loc[1]+blenderobject->dloc[1], blenderobject->loc[2]+blenderobject->dloc[2] ); - MT_Vector3 eulxyz(blenderobject->rot); + + MT_Matrix3x3 rotation; + float rotmat[3][3]; + BKE_object_rot_to_mat3(blenderobject, rotmat, FALSE); + rotation.setValue3x3((float*)rotmat); + MT_Vector3 scale(blenderobject->size); + if (converter->addInitFromFrame) {//rcruiz - float eulxyzPrev[3]; blenderscene->r.cfra=blenderscene->r.sfra-1; //XXX update_for_newframe(); MT_Vector3 tmp=pos-MT_Point3(blenderobject->loc[0]+blenderobject->dloc[0], blenderobject->loc[1]+blenderobject->dloc[1], blenderobject->loc[2]+blenderobject->dloc[2] ); - eulxyzPrev[0]=blenderobject->rot[0]; - eulxyzPrev[1]=blenderobject->rot[1]; - eulxyzPrev[2]=blenderobject->rot[2]; + + float rotmatPrev[3][3]; + BKE_object_rot_to_mat3(blenderobject, rotmatPrev, FALSE); + + float eulxyz[3], eulxyzPrev[3]; + mat3_to_eul(eulxyz, rotmat); + mat3_to_eul(eulxyzPrev, rotmatPrev); double fps = (double) blenderscene->r.frs_sec/ (double) blenderscene->r.frs_sec_base; tmp.scale(fps, fps, fps); inivel.push_back(tmp); - tmp=eulxyz-eulxyzPrev; + tmp[0]=eulxyz[0]-eulxyzPrev[0]; + tmp[1]=eulxyz[1]-eulxyzPrev[1]; + tmp[2]=eulxyz[2]-eulxyzPrev[2]; tmp.scale(fps, fps, fps); iniang.push_back(tmp); blenderscene->r.cfra=blenderscene->r.sfra; @@ -2214,7 +2212,7 @@ static void bl_ConvertBlenderObject_Single( } gameobj->NodeSetLocalPosition(pos); - gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz)); + gameobj->NodeSetLocalOrientation(rotation); gameobj->NodeSetLocalScale(scale); gameobj->NodeUpdateGS(0); @@ -2321,7 +2319,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, RAS_IRenderTools* rendertools, RAS_ICanvas* canvas, KX_BlenderSceneConverter* converter, - bool alwaysUseExpandFraming + bool alwaysUseExpandFraming, + bool libloading ) { @@ -2431,7 +2430,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, base->object, kxscene, rendertools, - converter); + converter, + libloading); bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo) !=0; bool addobj=true; @@ -2490,7 +2490,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, blenderobject, kxscene, rendertools, - converter); + converter, + libloading); // this code is copied from above except that // object from groups are never in active layer diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.h b/source/gameengine/Converter/BL_BlenderDataConversion.h index 2a7efaac898..f3a680929fb 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.h +++ b/source/gameengine/Converter/BL_BlenderDataConversion.h @@ -38,7 +38,7 @@ #include "KX_PhysicsEngineEnums.h" #include "SCA_IInputDevice.h" -class RAS_MeshObject* BL_ConvertMesh(struct Mesh* mesh,struct Object* lightobj,class KX_Scene* scene, class KX_BlenderSceneConverter *converter); +class RAS_MeshObject* BL_ConvertMesh(struct Mesh* mesh,struct Object* lightobj,class KX_Scene* scene, class KX_BlenderSceneConverter *converter, bool libloading); void BL_ConvertBlenderObjects(struct Main* maggie, class KX_Scene* kxscene, @@ -47,7 +47,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, class RAS_IRenderTools* rendertools, class RAS_ICanvas* canvas, class KX_BlenderSceneConverter* sceneconverter, - bool alwaysUseExpandFraming + bool alwaysUseExpandFraming, + bool libloading=false ); SCA_IInputDevice::KX_EnumInputs ConvertKeyCode(int key_code); diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index d1684db0f5a..260ca9ede96 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -151,6 +151,7 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter() vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator itp = m_polymaterials.begin(); while (itp != m_polymaterials.end()) { + m_polymat_cache.erase((*itp).second->GetBlenderMaterial()); delete (*itp).second; itp++; } @@ -158,6 +159,7 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter() // delete after RAS_IPolyMaterial vector<pair<KX_Scene*,BL_Material *> >::iterator itmat = m_materials.begin(); while (itmat != m_materials.end()) { + m_mat_cache.erase((*itmat).second->material); delete (*itmat).second; itmat++; } @@ -286,7 +288,8 @@ struct BlenderDebugDraw : public btIDebugDraw void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene, class RAS_IRenderTools* rendertools, - class RAS_ICanvas* canvas) + class RAS_ICanvas* canvas, + bool libloading) { //find out which physics engine Scene *blenderscene = destinationscene->GetBlenderScene(); @@ -355,7 +358,8 @@ void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene, rendertools, canvas, this, - m_alwaysUseExpandFraming + m_alwaysUseExpandFraming, + libloading ); //These lookup are not needed during game @@ -406,6 +410,7 @@ void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene) size = m_polymaterials.size(); for (i=0, polymit=m_polymaterials.begin(); i<size; ) { if ((*polymit).first == scene) { + m_polymat_cache.erase((*polymit).second->GetBlenderMaterial()); delete (*polymit).second; *polymit = m_polymaterials.back(); m_polymaterials.pop_back(); @@ -420,6 +425,7 @@ void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene) size = m_materials.size(); for (i=0, matit=m_materials.begin(); i<size; ) { if ((*matit).first == scene) { + m_mat_cache.erase((*matit).second->material); delete (*matit).second; *matit = m_materials.back(); m_materials.pop_back(); @@ -470,6 +476,12 @@ bool KX_BlenderSceneConverter::GetGLSLMaterials() void KX_BlenderSceneConverter::RegisterBlenderMaterial(BL_Material *mat) { + // First make sure we don't register the material twice + vector<pair<KX_Scene*,BL_Material*> >::iterator it; + for (it = m_materials.begin(); it != m_materials.end(); ++it) + if (it->second == mat) + return; + m_materials.push_back(pair<KX_Scene*,BL_Material *>(m_currentScene,mat)); } @@ -540,19 +552,37 @@ RAS_MeshObject *KX_BlenderSceneConverter::FindGameMesh( } else { return NULL; } -} - - - - - +} void KX_BlenderSceneConverter::RegisterPolyMaterial(RAS_IPolyMaterial *polymat) { + // First make sure we don't register the material twice + vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator it; + for (it = m_polymaterials.begin(); it != m_polymaterials.end(); ++it) + if (it->second == polymat) + return; m_polymaterials.push_back(pair<KX_Scene*,RAS_IPolyMaterial*>(m_currentScene,polymat)); } +void KX_BlenderSceneConverter::CachePolyMaterial(struct Material *mat, RAS_IPolyMaterial *polymat) +{ + m_polymat_cache[mat] = polymat; +} + +RAS_IPolyMaterial *KX_BlenderSceneConverter::FindCachedPolyMaterial(struct Material *mat) +{ + return m_polymat_cache[mat]; +} +void KX_BlenderSceneConverter::CacheBlenderMaterial(struct Material *mat, BL_Material *blmat) +{ + m_mat_cache[mat] = blmat; +} + +BL_Material *KX_BlenderSceneConverter::FindCachedBlenderMaterial(struct Material *mat) +{ + return m_mat_cache[mat]; +} void KX_BlenderSceneConverter::RegisterInterpolatorList( BL_InterpolatorList *actList, @@ -1016,7 +1046,7 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha for (mesh= (ID *)main_newlib->mesh.first; mesh; mesh= (ID *)mesh->next ) { if (options & LIB_LOAD_VERBOSE) printf("MeshName: %s\n", mesh->name+2); - RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)mesh, NULL, scene_merge, this); + RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)mesh, NULL, scene_merge, this, false); // For now only use the libloading option for scenes, which need to handle materials/shaders scene_merge->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj); } } @@ -1038,7 +1068,7 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha printf("SceneName: %s\n", scene->name+2); /* merge into the base scene */ - KX_Scene* other= m_ketsjiEngine->CreateScene((Scene *)scene); + KX_Scene* other= m_ketsjiEngine->CreateScene((Scene *)scene, true); scene_merge->MergeScene(other); // RemoveScene(other); // Don't run this, it frees the entire scene converter data, just delete the scene @@ -1302,7 +1332,7 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie) } if (IS_TAGGED(bmat)) { - + m_polymat_cache.erase((*polymit).second->GetBlenderMaterial()); delete (*polymit).second; *polymit = m_polymaterials.back(); m_polymaterials.pop_back(); @@ -1320,6 +1350,7 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie) for (i=0, matit=m_materials.begin(); i<size; ) { BL_Material *mat= (*matit).second; if (IS_TAGGED(mat->material)) { + m_mat_cache.erase((*matit).second->material); delete (*matit).second; *matit = m_materials.back(); m_materials.pop_back(); @@ -1469,7 +1500,7 @@ RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene* kx_scene, } } - RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)me, NULL, kx_scene, this); + RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)me, NULL, kx_scene, this, false); kx_scene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj); m_map_mesh_to_gamemesh.clear(); /* This is at runtime so no need to keep this, BL_ConvertMesh adds */ return meshobj; diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h index 34a1117a0eb..eddb377dbc7 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.h +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h @@ -39,6 +39,8 @@ #include "KX_ISceneConverter.h" #include "KX_IpoConvert.h" +#include <map> + using namespace std; class KX_WorldInfo; @@ -58,6 +60,11 @@ class KX_BlenderSceneConverter : public KX_ISceneConverter vector<pair<KX_Scene*,RAS_IPolyMaterial*> > m_polymaterials; vector<pair<KX_Scene*,RAS_MeshObject*> > m_meshobjects; vector<pair<KX_Scene*,BL_Material *> > m_materials; + + // Cached material conversions + map<struct Material*, BL_Material*> m_mat_cache; + map<struct Material*, RAS_IPolyMaterial*> m_polymat_cache; + // Should also have a list of collision shapes. // For the time being this is held in KX_Scene::m_shapes @@ -93,7 +100,8 @@ public: virtual void ConvertScene( class KX_Scene* destinationscene, class RAS_IRenderTools* rendertools, - class RAS_ICanvas* canvas + class RAS_ICanvas* canvas, + bool libloading=false ); virtual void RemoveScene(class KX_Scene *scene); @@ -110,8 +118,12 @@ public: RAS_MeshObject *FindGameMesh(struct Mesh *for_blendermesh/*, unsigned int onlayer*/); void RegisterPolyMaterial(RAS_IPolyMaterial *polymat); + void CachePolyMaterial(struct Material *mat, RAS_IPolyMaterial *polymat); + RAS_IPolyMaterial *FindCachedPolyMaterial(struct Material *mat); void RegisterBlenderMaterial(BL_Material *mat); + void CacheBlenderMaterial(struct Material *mat, BL_Material *blmat); + BL_Material *FindCachedBlenderMaterial(struct Material *mat); void RegisterInterpolatorList(BL_InterpolatorList *actList, struct bAction *for_act); BL_InterpolatorList *FindInterpolatorList(struct bAction *for_act); diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index 06399642edd..695bf0c4dc8 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -523,7 +523,8 @@ void BL_ConvertActuators(const char* maggiename, editobact->me, blenderobject, scene, - converter + converter, + false ); KX_SCA_ReplaceMeshActuator* tmpreplaceact = new KX_SCA_ReplaceMeshActuator( diff --git a/source/gameengine/Converter/SConscript b/source/gameengine/Converter/SConscript index b9c70910283..28ad742545e 100644 --- a/source/gameengine/Converter/SConscript +++ b/source/gameengine/Converter/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('*.cpp') diff --git a/source/gameengine/Expressions/SConscript b/source/gameengine/Expressions/SConscript index 4dc165a7696..a6d82a4f2da 100644 --- a/source/gameengine/Expressions/SConscript +++ b/source/gameengine/Expressions/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('*.cpp') diff --git a/source/gameengine/GameLogic/SConscript b/source/gameengine/GameLogic/SConscript index da3c0fadb51..b274e518015 100644 --- a/source/gameengine/GameLogic/SConscript +++ b/source/gameengine/GameLogic/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('*.cpp') + env.Glob('Joystick/*.cpp') diff --git a/source/gameengine/GamePlayer/SConscript b/source/gameengine/GamePlayer/SConscript index 0b140bba8e7..d1930aca26d 100644 --- a/source/gameengine/GamePlayer/SConscript +++ b/source/gameengine/GamePlayer/SConscript @@ -1,3 +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 ***** + SConscript(['common/SConscript', 'ghost/SConscript']) diff --git a/source/gameengine/GamePlayer/common/SConscript b/source/gameengine/GamePlayer/common/SConscript index 6a1f47c51af..1648d8af78c 100644 --- a/source/gameengine/GamePlayer/common/SConscript +++ b/source/gameengine/GamePlayer/common/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 sys Import ('env') diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index 92db1fe790e..1dcc68c8e75 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -76,7 +76,6 @@ extern "C" #include "SCA_IActuator.h" #include "RAS_MeshObject.h" #include "RAS_OpenGLRasterizer.h" -#include "RAS_VAOpenGLRasterizer.h" #include "RAS_ListRasterizer.h" #include "RAS_GLExtensionManager.h" #include "KX_PythonInit.h" @@ -582,16 +581,12 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode) if (!m_rendertools) goto initFailed; - if (useLists) { - if (GLEW_VERSION_1_1) - m_rasterizer = new RAS_ListRasterizer(m_canvas, true); - else - m_rasterizer = new RAS_ListRasterizer(m_canvas); - } - else if (GLEW_VERSION_1_1) - m_rasterizer = new RAS_VAOpenGLRasterizer(m_canvas); + //Don't use displaylists with VBOs + //If auto starts using VBOs, make sure to check for that here + if (useLists && gm->raster_storage != RAS_STORE_VBO) + m_rasterizer = new RAS_ListRasterizer(m_canvas, false, gm->raster_storage); else - m_rasterizer = new RAS_OpenGLRasterizer(m_canvas); + m_rasterizer = new RAS_OpenGLRasterizer(m_canvas, gm->raster_storage); /* Stereo parameters - Eye Separation from the UI - stereomode from the command-line/UI */ m_rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) stereoMode); diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index a82f9ce1779..ba7d3135a10 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -492,6 +492,8 @@ int main(int argc, char** argv) // XXX this one too U.anisotropic_filter = 2; + // enable fast mipmap generation + U.use_gpu_mipmap = 1; sound_init_once(); diff --git a/source/gameengine/GamePlayer/ghost/SConscript b/source/gameengine/GamePlayer/ghost/SConscript index fb046d0fdf8..64bd58aa784 100644 --- a/source/gameengine/GamePlayer/ghost/SConscript +++ b/source/gameengine/GamePlayer/ghost/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 sys Import ('env') diff --git a/source/gameengine/Ketsji/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp index 23bfd7a111b..64e191fe960 100644 --- a/source/gameengine/Ketsji/BL_BlenderShader.cpp +++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp @@ -95,21 +95,15 @@ void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat) ras->SetTexCoordNum(0); ras->SetAttribNum(attrib_num); - for (i=0; i<attrib_num; i++) + for (i = 0; i < attrib_num; i++) ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, i); for (i = 0; i < attribs.totlayer; i++) { if (attribs.layer[i].glindex > attrib_num) continue; - if (attribs.layer[i].type == CD_MTFACE) { - if (!mat->uvName.IsEmpty() && strcmp(mat->uvName.ReadPtr(), attribs.layer[i].name) == 0) - ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex); - else if (!mat->uv2Name.IsEmpty() && strcmp(mat->uv2Name.ReadPtr(), attribs.layer[i].name) == 0) - ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV2, attribs.layer[i].glindex); - else - ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex); - } + if (attribs.layer[i].type == CD_MTFACE) + ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV, attribs.layer[i].glindex); else if (attribs.layer[i].type == CD_TANGENT) ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, attribs.layer[i].glindex); else if (attribs.layer[i].type == CD_ORCO) diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp index 0954aa0f7ab..461a8c51a52 100644 --- a/source/gameengine/Ketsji/BL_Material.cpp +++ b/source/gameengine/Ketsji/BL_Material.cpp @@ -20,15 +20,6 @@ MTex* getImageFromMaterial(Material *mat, int index) return m?m:0; } -int getNumTexChannels( Material *mat ) -{ - int count = -1; - if (!mat) return -1; - - for (count =0; (count < 10) && mat->mtex[count] != 0; count++) {} - return count; -} - BL_Material::BL_Material() { Initialize(); @@ -36,7 +27,10 @@ BL_Material::BL_Material() void BL_Material::Initialize() { - m_mcol = 0xFFFFFFFFL; + rgb[0] = 0; + rgb[1] = 0; + rgb[2] = 0; + rgb[3] = 0; IdMode = 0; ras_mode = 0; glslmat = 0; @@ -64,7 +58,7 @@ void BL_Material::Initialize() int i; - for (i=0; i<MAXTEX; i++) // :( + for (i = 0; i < MAXTEX; i++) // :( { mapping[i].mapping = 0; mapping[i].offsets[0] = 0.f; @@ -90,15 +84,6 @@ void BL_Material::Initialize() } } -void BL_Material::SetUVLayerName(const STR_String& name) -{ - uvName = name; -} -void BL_Material::SetUVLayerName2(const STR_String& name) -{ - uv2Name = name; -} - void BL_Material::SetSharedMaterial(bool v) { if ((v && num_users == -1) || num_users > 1 ) diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h index ef180ed2126..0383c0891b6 100644 --- a/source/gameengine/Ketsji/BL_Material.h +++ b/source/gameengine/Ketsji/BL_Material.h @@ -87,13 +87,8 @@ public: MTFace tface; /* copy of the derived meshes tface */ Image* img[MAXTEX]; EnvMap* cubemap[MAXTEX]; - unsigned int m_mcol; /* for text color (only) */ - STR_String uvName; - STR_String uv2Name; - - void SetUVLayerName(const STR_String &name); - void SetUVLayerName2(const STR_String &name); + unsigned int rgb[4]; void SetSharedMaterial(bool v); bool IsShared(); @@ -180,7 +175,6 @@ enum BL_MappingProj // ------------------------------------ //extern void initBL_Material(BL_Material* mat); extern MTex* getImageFromMaterial(Material *mat, int index); -extern int getNumTexChannels( Material *mat ); // ------------------------------------ #endif diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp index 66423ed820e..98fff5c8b65 100644 --- a/source/gameengine/Ketsji/BL_Texture.cpp +++ b/source/gameengine/Ketsji/BL_Texture.cpp @@ -60,6 +60,7 @@ public: typedef std::map<char*, BL_TextureObject> BL_TextureMap; static BL_TextureMap g_textureManager; +static GLint g_max_units = -1; BL_Texture::BL_Texture() @@ -379,14 +380,17 @@ unsigned int BL_Texture::GetTextureType() const int BL_Texture::GetMaxUnits() { - GLint unit=0; - - if (GLEW_ARB_multitexture) { - glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &unit); - return (MAXTEX>=unit?unit:MAXTEX); + if (g_max_units < 0) { + GLint unit; + if (GLEW_ARB_multitexture) { + glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &unit); + g_max_units = (MAXTEX>=unit)?unit:MAXTEX; + } else { + g_max_units = 0; + } } - return 0; + return g_max_units; } void BL_Texture::ActivateFirst() diff --git a/source/gameengine/Ketsji/KXNetwork/SConscript b/source/gameengine/Ketsji/KXNetwork/SConscript index 3d696501203..40a1ec10df3 100644 --- a/source/gameengine/Ketsji/KXNetwork/SConscript +++ b/source/gameengine/Ketsji/KXNetwork/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('*.cpp') diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 20c36c2cc44..a55dd701826 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -60,7 +60,8 @@ KX_BlenderMaterial::KX_BlenderMaterial() void KX_BlenderMaterial::Initialize( KX_Scene *scene, BL_Material *data, - GameSettings *game) + GameSettings *game, + int lightlayer) { RAS_IPolyMaterial::Initialize( data->texname[0], @@ -84,6 +85,7 @@ void KX_BlenderMaterial::Initialize( mModified = 0; mConstructed = false; mPass = 0; + mLightLayer = lightlayer; // -------------------------------- // RAS_IPolyMaterial variables... m_flag |= RAS_BLENDERMAT; @@ -92,16 +94,11 @@ void KX_BlenderMaterial::Initialize( m_flag |= (mMaterial->glslmat)? RAS_BLENDERGLSL: 0; m_flag |= ((mMaterial->ras_mode & CAST_SHADOW)!=0)? RAS_CASTSHADOW: 0; - // figure max - int enabled = mMaterial->num_enabled; - int max = BL_Texture::GetMaxUnits(); - mMaterial->num_enabled = enabled>=max?max:enabled; - // test the sum of the various modes for equality // so we can ether accept or reject this material // as being equal, this is rather important to // prevent material bleeding - for (int i=0; i<mMaterial->num_enabled; i++) { + for (int i=0; i<BL_Texture::GetMaxUnits(); i++) { m_multimode += (mMaterial->flag[i] + mMaterial->blend_mode[i]); } m_multimode += mMaterial->IdMode+ (mMaterial->ras_mode & ~(USE_LIGHT)); @@ -124,7 +121,7 @@ MTFace* KX_BlenderMaterial::GetMTFace(void) const unsigned int* KX_BlenderMaterial::GetMCol(void) const { // fonts on polys - return &mMaterial->m_mcol; + return mMaterial->rgb; } void KX_BlenderMaterial::GetMaterialRGBAColor(unsigned char *rgba) const @@ -138,11 +135,6 @@ void KX_BlenderMaterial::GetMaterialRGBAColor(unsigned char *rgba) const RAS_IPolyMaterial::GetMaterialRGBAColor(rgba); } -bool KX_BlenderMaterial::IsMaterial(const BL_Material *bl_mat) const -{ - return (mMaterial == bl_mat); -} - Material *KX_BlenderMaterial::GetBlenderMaterial() const { return mMaterial->material; @@ -163,7 +155,7 @@ void KX_BlenderMaterial::InitTextures() { // for each unique material... int i; - for (i=0; i<mMaterial->num_enabled; i++) { + for (i=0; i<BL_Texture::GetMaxUnits(); i++) { if ( mMaterial->mapping[i].mapping & USEENV ) { if (!GLEW_ARB_texture_cube_map) { spit("CubeMap textures not supported"); @@ -185,14 +177,14 @@ void KX_BlenderMaterial::InitTextures() } } -void KX_BlenderMaterial::OnConstruction(int layer) +void KX_BlenderMaterial::OnConstruction() { if (mConstructed) // when material are reused between objects return; if (mMaterial->glslmat) - SetBlenderGLSLShader(layer); + SetBlenderGLSLShader(); InitTextures(); @@ -239,7 +231,8 @@ void KX_BlenderMaterial::OnExit() } BL_Texture::ActivateFirst(); - for (int i=0; i<mMaterial->num_enabled; i++) { + for (int i=0; i<BL_Texture::GetMaxUnits(); i++) { + if (!mTextures[i].Ok()) continue; BL_Texture::ActivateUnit(i); mTextures[i].DeleteTex(); mTextures[i].DisableUnit(); @@ -278,7 +271,7 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras) mShader->ApplyShader(); // for each enabled unit - for (i=0; i<mMaterial->num_enabled; i++) { + for (i=0; i<BL_Texture::GetMaxUnits(); i++) { if (!mTextures[i].Ok()) continue; mTextures[i].ActivateTexture(); mTextures[0].SetMapping(mMaterial->mapping[i].mapping); @@ -354,7 +347,7 @@ void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras) } int mode = 0,i=0; - for (i=0; (i<mMaterial->num_enabled && i<MAXTEX); i++) { + for (i=0; i<BL_Texture::GetMaxUnits(); i++) { if ( !mTextures[i].Ok() ) continue; mTextures[i].ActivateTexture(); @@ -647,16 +640,9 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const ras->SetTexCoordNum(mMaterial->num_enabled); - for (int i=0; i<mMaterial->num_enabled; i++) { + for (int i=0; i<BL_Texture::GetMaxUnits(); i++) { int mode = mMaterial->mapping[i].mapping; - if (mode &USECUSTOMUV) - { - if (!mMaterial->mapping[i].uvCoName.IsEmpty()) - ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV2, i); - continue; - } - if ( mode &(USEREFL|USEOBJ)) ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_GEN, i); else if (mode &USEORCO) @@ -664,7 +650,7 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const else if (mode &USENORM) ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_NORM, i); else if (mode &USEUV) - ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV1, i); + ras->SetTexCoord(RAS_IRasterizer::RAS_TEXCO_UV, i); else if (mode &USETANG) ras->SetTexCoord(RAS_IRasterizer::RAS_TEXTANGENT, i); else @@ -790,10 +776,19 @@ void KX_BlenderMaterial::UpdateIPO( mMaterial->ref = (float)(ref); } -void KX_BlenderMaterial::SetBlenderGLSLShader(int layer) +void KX_BlenderMaterial::Replace_IScene(SCA_IScene *val) +{ + mScene= static_cast<KX_Scene *>(val); + if (mBlenderShader) + mBlenderShader->SetScene(mScene); + + OnConstruction(); +} + +void KX_BlenderMaterial::SetBlenderGLSLShader() { if (!mBlenderShader) - mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, layer); + mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, mLightLayer); if (!mBlenderShader->Ok()) { delete mBlenderShader; diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index 7bc9c7c3863..c34a49e1bde 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -39,7 +39,8 @@ public: void Initialize( class KX_Scene* scene, BL_Material* mat, - GameSettings* game + GameSettings* game, + int lightlayer ); virtual ~KX_BlenderMaterial(); @@ -76,8 +77,6 @@ public: TCachingInfo& cachingInfo )const; - /* mMaterial is private, but need this for conversion */ - bool IsMaterial(const BL_Material *bl_mat) const; Material* GetBlenderMaterial() const; MTFace* GetMTFace(void) const; unsigned int* GetMCol(void) const; @@ -97,14 +96,7 @@ public: MT_Scalar ref, MT_Scalar emit, MT_Scalar alpha ); - virtual void Replace_IScene(SCA_IScene *val) - { - mScene= static_cast<KX_Scene *>(val); - if (mBlenderShader) - { - mBlenderShader->SetScene(mScene); - } - }; + virtual void Replace_IScene(SCA_IScene *val); #ifdef WITH_PYTHON // -------------------------------- @@ -125,7 +117,7 @@ public: // -------------------------------- // pre calculate to avoid pops/lag at startup - virtual void OnConstruction(int layer); + virtual void OnConstruction(); static void EndFrame(); @@ -139,10 +131,11 @@ private: unsigned int mBlendFunc[2]; bool mModified; bool mConstructed; // if false, don't clean on exit + int mLightLayer; void InitTextures(); - void SetBlenderGLSLShader(int layer); + void SetBlenderGLSLShader(); void ActivatGLMaterials( RAS_IRasterizer* rasty )const; void ActivateTexGen( RAS_IRasterizer *ras ) const; diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp index 59ca0d8d326..792a0759b59 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.cpp +++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp @@ -115,7 +115,7 @@ void KX_CameraActuator::Relink(CTR_Map<CTR_HashedPtr, void*> *obj_map) /* copied from blender BLI_math ... don't know if there's an equivalent */ -static void Kx_VecUpMat3(float vec[3], float mat[][3], short axis) +static void Kx_VecUpMat3(float vec[3], float mat[3][3], short axis) { // Construct a camera matrix s.t. the specified axis diff --git a/source/gameengine/Ketsji/KX_ISceneConverter.h b/source/gameengine/Ketsji/KX_ISceneConverter.h index 18fb336dbe0..0dbfd7de2c6 100644 --- a/source/gameengine/Ketsji/KX_ISceneConverter.h +++ b/source/gameengine/Ketsji/KX_ISceneConverter.h @@ -57,7 +57,8 @@ public: virtual void ConvertScene( class KX_Scene* destinationscene, class RAS_IRenderTools* rendertools, - class RAS_ICanvas* canvas)=0; + class RAS_ICanvas* canvas, + bool libloading=false)=0; virtual void RemoveScene(class KX_Scene *scene)=0; diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index a12e12ccef2..890b9d4c472 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -1686,7 +1686,7 @@ void KX_KetsjiEngine::RemoveScheduledScenes() } } -KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene) +KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene, bool libloading) { KX_Scene* tmpscene = new KX_Scene(m_keyboarddevice, m_mousedevice, @@ -1697,7 +1697,8 @@ KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene) m_sceneconverter->ConvertScene(tmpscene, m_rendertools, - m_canvas); + m_canvas, + libloading); return tmpscene; } diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 972594bd90f..92ffaf47aa4 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -413,7 +413,7 @@ public: void GetOverrideFrameColor(float& r, float& g, float& b) const; KX_Scene* CreateScene(const STR_String& scenename); - KX_Scene* CreateScene(Scene *scene); + KX_Scene* CreateScene(Scene *scene, bool libloading=false); GlobalSettings* GetGlobalSettings(void); void SetGlobalSettings(GlobalSettings* gs); diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp index d83e98d4712..57695df2782 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.cpp +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -338,20 +338,20 @@ PyObject *KX_MeshProxy::PyTransformUV(PyObject *args, PyObject *kwds) for (i = it.startvertex; i < it.endvertex; i++) { RAS_TexVert *vert = &it.vertex[i]; if (uvindex_from != -1) { - if (uvindex_from == 0) vert->SetUV2(vert->getUV1()); - else vert->SetUV1(vert->getUV2()); + if (uvindex_from == 0) vert->SetUV(1, vert->getUV(0)); + else vert->SetUV(0, vert->getUV(1)); } switch (uvindex) { case 0: - vert->TransformUV1(transform); + vert->TransformUV(0, transform); break; case 1: - vert->TransformUV2(transform); + vert->TransformUV(1, transform); break; case -1: - vert->TransformUV1(transform); - vert->TransformUV2(transform); + vert->TransformUV(0, transform); + vert->TransformUV(1, transform); break; } } diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp index f157d9ed20a..5ce370ccdfe 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp @@ -109,7 +109,7 @@ void KX_PolygonMaterial::Initialize( m_mcol = *mcol; } else { - m_mcol = 0; + memset(&m_mcol, 0, sizeof(m_mcol)); } m_material = ma; diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h index 2ce8f480c1c..89bfb4ff9fb 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.h +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h @@ -60,7 +60,7 @@ class KX_PolygonMaterial : public PyObjectPlus, public RAS_IPolyMaterial private: /** Blender texture face structure. */ mutable MTFace m_tface; - mutable unsigned int m_mcol; /* for text color (only) */ + mutable unsigned int m_mcol; Material* m_material; #ifdef WITH_PYTHON diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp index 2354359af18..ab73ba1902a 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.cpp +++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp @@ -94,6 +94,7 @@ PyAttributeDef KX_VertexProxy::Attributes[] = { KX_PYATTRIBUTE_RW_FUNCTION("XYZ", KX_VertexProxy, pyattr_get_XYZ, pyattr_set_XYZ), KX_PYATTRIBUTE_RW_FUNCTION("UV", KX_VertexProxy, pyattr_get_UV, pyattr_set_UV), + KX_PYATTRIBUTE_RW_FUNCTION("uvs", KX_VertexProxy, pyattr_get_uvs, pyattr_set_uvs), KX_PYATTRIBUTE_RW_FUNCTION("color", KX_VertexProxy, pyattr_get_color, pyattr_set_color), KX_PYATTRIBUTE_RW_FUNCTION("normal", KX_VertexProxy, pyattr_get_normal, pyattr_set_normal), @@ -146,25 +147,25 @@ PyObject *KX_VertexProxy::pyattr_get_a(void *self_v, const KX_PYATTRIBUTE_DEF *a PyObject *KX_VertexProxy::pyattr_get_u(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v); - return PyFloat_FromDouble(self->m_vertex->getUV1()[0]); + return PyFloat_FromDouble(self->m_vertex->getUV(0)[0]); } PyObject *KX_VertexProxy::pyattr_get_v(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v); - return PyFloat_FromDouble(self->m_vertex->getUV1()[1]); + return PyFloat_FromDouble(self->m_vertex->getUV(0)[1]); } PyObject *KX_VertexProxy::pyattr_get_u2(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v); - return PyFloat_FromDouble(self->m_vertex->getUV2()[0]); + return PyFloat_FromDouble(self->m_vertex->getUV(1)[0]); } PyObject *KX_VertexProxy::pyattr_get_v2(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v); - return PyFloat_FromDouble(self->m_vertex->getUV2()[1]); + return PyFloat_FromDouble(self->m_vertex->getUV(1)[1]); } PyObject *KX_VertexProxy::pyattr_get_XYZ(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -176,7 +177,20 @@ PyObject *KX_VertexProxy::pyattr_get_XYZ(void *self_v, const KX_PYATTRIBUTE_DEF PyObject *KX_VertexProxy::pyattr_get_UV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v); - return PyObjectFrom(MT_Point2(self->m_vertex->getUV1())); + return PyObjectFrom(MT_Point2(self->m_vertex->getUV(0))); +} + +PyObject *KX_VertexProxy::pyattr_get_uvs(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_VertexProxy* self= static_cast<KX_VertexProxy*>(self_v); + + PyObject* uvlist = PyList_New(RAS_TexVert::MAX_UNIT); + for (int i=0; i<RAS_TexVert::MAX_UNIT; ++i) + { + PyList_SET_ITEM(uvlist, i, PyObjectFrom(MT_Point2(self->m_vertex->getUV(i)))); + } + + return uvlist; } PyObject *KX_VertexProxy::pyattr_get_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -245,9 +259,9 @@ int KX_VertexProxy::pyattr_set_u(void *self_v, const struct KX_PYATTRIBUTE_DEF * if (PyFloat_Check(value)) { float val = PyFloat_AsDouble(value); - MT_Point2 uv = self->m_vertex->getUV1(); + MT_Point2 uv = self->m_vertex->getUV(0); uv[0] = val; - self->m_vertex->SetUV1(uv); + self->m_vertex->SetUV(0, uv); self->m_mesh->SetMeshModified(true); return PY_SET_ATTR_SUCCESS; } @@ -260,9 +274,9 @@ int KX_VertexProxy::pyattr_set_v(void *self_v, const struct KX_PYATTRIBUTE_DEF * if (PyFloat_Check(value)) { float val = PyFloat_AsDouble(value); - MT_Point2 uv = self->m_vertex->getUV1(); + MT_Point2 uv = self->m_vertex->getUV(0); uv[1] = val; - self->m_vertex->SetUV1(uv); + self->m_vertex->SetUV(0, uv); self->m_mesh->SetMeshModified(true); return PY_SET_ATTR_SUCCESS; } @@ -275,9 +289,9 @@ int KX_VertexProxy::pyattr_set_u2(void *self_v, const struct KX_PYATTRIBUTE_DEF if (PyFloat_Check(value)) { float val = PyFloat_AsDouble(value); - MT_Point2 uv = self->m_vertex->getUV2(); + MT_Point2 uv = self->m_vertex->getUV(1); uv[0] = val; - self->m_vertex->SetUV2(uv); + self->m_vertex->SetUV(1, uv); self->m_mesh->SetMeshModified(true); return PY_SET_ATTR_SUCCESS; } @@ -290,9 +304,9 @@ int KX_VertexProxy::pyattr_set_v2(void *self_v, const struct KX_PYATTRIBUTE_DEF if (PyFloat_Check(value)) { float val = PyFloat_AsDouble(value); - MT_Point2 uv = self->m_vertex->getUV2(); + MT_Point2 uv = self->m_vertex->getUV(1); uv[1] = val; - self->m_vertex->SetUV2(uv); + self->m_vertex->SetUV(1, uv); self->m_mesh->SetMeshModified(true); return PY_SET_ATTR_SUCCESS; } @@ -390,7 +404,7 @@ int KX_VertexProxy::pyattr_set_UV(void *self_v, const struct KX_PYATTRIBUTE_DEF { MT_Point2 vec; if (PyVecTo(value, vec)) { - self->m_vertex->SetUV1(vec); + self->m_vertex->SetUV(0, vec); self->m_mesh->SetMeshModified(true); return PY_SET_ATTR_SUCCESS; } @@ -398,6 +412,32 @@ int KX_VertexProxy::pyattr_set_UV(void *self_v, const struct KX_PYATTRIBUTE_DEF return PY_SET_ATTR_FAIL; } +int KX_VertexProxy::pyattr_set_uvs(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_VertexProxy* self= static_cast<KX_VertexProxy*>(self_v); + if (PySequence_Check(value)) + { + MT_Point2 vec; + for (int i=0; i<PySequence_Size(value) && i<RAS_TexVert::MAX_UNIT; ++i) + { + if (PyVecTo(PySequence_GetItem(value, i), vec)) + { + self->m_vertex->SetUV(i, vec); + self->m_mesh->SetMeshModified(true); + } + else + { + PyErr_SetString(PyExc_AttributeError, STR_String().Format("list[%d] was not a vector", i).ReadPtr()); + return PY_SET_ATTR_FAIL; + } + } + + self->m_mesh->SetMeshModified(true); + return PY_SET_ATTR_SUCCESS; + } + return PY_SET_ATTR_FAIL; +} + int KX_VertexProxy::pyattr_set_color(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) { KX_VertexProxy* self = static_cast<KX_VertexProxy*>(self_v); @@ -522,7 +562,7 @@ PyObject *KX_VertexProxy::PySetRGBA(PyObject *value) PyObject *KX_VertexProxy::PyGetUV1() { - return PyObjectFrom(MT_Vector2(m_vertex->getUV1())); + return PyObjectFrom(MT_Vector2(m_vertex->getUV(0))); } PyObject *KX_VertexProxy::PySetUV1(PyObject *value) @@ -531,31 +571,23 @@ PyObject *KX_VertexProxy::PySetUV1(PyObject *value) if (!PyVecTo(value, vec)) return NULL; - m_vertex->SetUV1(vec); + m_vertex->SetUV(0, vec); m_mesh->SetMeshModified(true); Py_RETURN_NONE; } PyObject *KX_VertexProxy::PyGetUV2() { - return PyObjectFrom(MT_Vector2(m_vertex->getUV2())); + return PyObjectFrom(MT_Vector2(m_vertex->getUV(1))); } PyObject *KX_VertexProxy::PySetUV2(PyObject *args) { MT_Point2 vec; - unsigned int unit= RAS_TexVert::SECOND_UV; - - PyObject *list = NULL; - if (!PyArg_ParseTuple(args, "O|i:setUV2", &list, &unit)) - return NULL; - - if (!PyVecTo(list, vec)) + if (!PyVecTo(args, vec)) return NULL; - m_vertex->SetFlag((m_vertex->getFlag()|RAS_TexVert::SECOND_UV)); - m_vertex->SetUnit(unit); - m_vertex->SetUV2(vec); + m_vertex->SetUV(1, vec); m_mesh->SetMeshModified(true); Py_RETURN_NONE; } diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h index 4247d138a66..8070825ad11 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.h +++ b/source/gameengine/Ketsji/KX_VertexProxy.h @@ -74,6 +74,7 @@ public: static PyObject *pyattr_get_UV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject *pyattr_get_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject *pyattr_get_normal(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject *pyattr_get_uvs(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_x(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static int pyattr_set_y(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static int pyattr_set_z(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); @@ -89,6 +90,7 @@ public: static int pyattr_set_UV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static int pyattr_set_color(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static int pyattr_set_normal(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + static int pyattr_set_uvs(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); KX_PYMETHOD_NOARGS(KX_VertexProxy,GetXYZ); KX_PYMETHOD_O(KX_VertexProxy,SetXYZ); diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript index 88689a5a736..da1a72b4758 100644 --- a/source/gameengine/Ketsji/SConscript +++ b/source/gameengine/Ketsji/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 sys Import ('env') diff --git a/source/gameengine/Network/LoopBackNetwork/SConscript b/source/gameengine/Network/LoopBackNetwork/SConscript index 7ca0a64f774..b183634d224 100644 --- a/source/gameengine/Network/LoopBackNetwork/SConscript +++ b/source/gameengine/Network/LoopBackNetwork/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 = 'NG_LoopBackNetworkDeviceInterface.cpp' diff --git a/source/gameengine/Network/SConscript b/source/gameengine/Network/SConscript index bbf714383b7..7365db5ba99 100644 --- a/source/gameengine/Network/SConscript +++ b/source/gameengine/Network/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('*.cpp') #'NG_NetworkMessage.cpp NG_NetworkObject.cpp NG_NetworkScene.cpp' diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 6c6ce94d8d5..a1b30ccb001 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -24,7 +24,7 @@ subject to the following restrictions: #include "btBulletDynamicsCommon.h" #include "BulletCollision/CollisionDispatch/btGhostObject.h" #include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h" - +#include "BulletCollision/Gimpact/btCompoundFromGimpact.h" #include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h" #include "PHY_IMotionState.h" @@ -2169,9 +2169,16 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape(btScalar margin, b ); btGImpactMeshShape* gimpactShape = new btGImpactMeshShape(indexVertexArrays); gimpactShape->setMargin(margin); - collisionShape = gimpactShape; gimpactShape->updateBound(); + //the depth value is how far along the triangle normal, the centroid is moved inwards + //to create surface tetrahedra for the btCompoundShape + //would be nice to expose this in the Blender user interfaceb + btScalar depth=btScalar(0.2); + collisionShape = btCreateCompoundFromGimpactShape(gimpactShape,depth); + delete gimpactShape; + + } else { if (!m_unscaledShape || m_forceReInstance) diff --git a/source/gameengine/Physics/Bullet/SConscript b/source/gameengine/Physics/Bullet/SConscript index ba4db001533..83239cf979a 100644 --- a/source/gameengine/Physics/Bullet/SConscript +++ b/source/gameengine/Physics/Bullet/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 = 'CcdPhysicsEnvironment.cpp CcdPhysicsController.cpp CcdGraphicController.cpp' diff --git a/source/gameengine/Physics/Dummy/SConscript b/source/gameengine/Physics/Dummy/SConscript index 13d1a893823..95b777b61be 100644 --- a/source/gameengine/Physics/Dummy/SConscript +++ b/source/gameengine/Physics/Dummy/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 = 'DummyPhysicsEnvironment.cpp' diff --git a/source/gameengine/Physics/common/SConscript b/source/gameengine/Physics/common/SConscript index abff3e33121..aee5e444079 100644 --- a/source/gameengine/Physics/common/SConscript +++ b/source/gameengine/Physics/common/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 = 'PHY_IMotionState.cpp PHY_IController.cpp PHY_IPhysicsController.cpp PHY_IGraphicController.cpp PHY_IPhysicsEnvironment.cpp PHY_IVehicle.cpp' diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.cpp b/source/gameengine/Rasterizer/RAS_BucketManager.cpp index f24e3397801..2b5b0aeac2a 100644 --- a/source/gameengine/Rasterizer/RAS_BucketManager.cpp +++ b/source/gameengine/Rasterizer/RAS_BucketManager.cpp @@ -232,6 +232,24 @@ void RAS_BucketManager::Renderbuckets( RenderSolidBuckets(cameratrans, rasty, rendertools); RenderAlphaBuckets(cameratrans, rasty, rendertools); + /* All meshes should be up to date now */ + /* Don't do this while processing buckets because some meshes are split between buckets */ + BucketList::iterator bit; + list<RAS_MeshSlot>::iterator mit; + for (bit = m_SolidBuckets.begin(); bit != m_SolidBuckets.end(); ++bit) { + RAS_MaterialBucket* bucket = *bit; + for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) { + mit->m_mesh->SetMeshModified(false); + } + } + for (bit = m_AlphaBuckets.begin(); bit != m_AlphaBuckets.end(); ++bit) { + RAS_MaterialBucket* bucket = *bit; + for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) { + mit->m_mesh->SetMeshModified(false); + } + } + + rendertools->SetClientObject(rasty, NULL); } diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index 9fffc8bebc9..b267879611e 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -184,7 +184,7 @@ public: /* * PreCalculate texture gen */ - virtual void OnConstruction(int layer) {} + virtual void OnConstruction() {} #ifdef WITH_CXX_GUARDEDALLOC diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index e6948025999..5a720857d50 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -52,6 +52,7 @@ using namespace std; class RAS_ICanvas; class RAS_IPolyMaterial; +class RAS_MeshSlot; typedef vector<unsigned short> KX_IndexArray; typedef vector<RAS_TexVert> KX_VertexArray; @@ -129,7 +130,7 @@ public: RAS_TEXCO_GEN, //< GPU will generate texture coordinates RAS_TEXCO_ORCO, //< Vertex coordinates (object space) RAS_TEXCO_GLOB, //< Vertex coordinates (world space) - RAS_TEXCO_UV1, //< UV coordinates + RAS_TEXCO_UV, //< UV coordinates RAS_TEXCO_OBJECT, //< Use another object's position as coordinates RAS_TEXCO_LAVECTOR, //< Light vector as coordinates RAS_TEXCO_VIEW, //< View vector as coordinates @@ -137,7 +138,6 @@ public: RAS_TEXCO_WINDOW, //< Window coordinates RAS_TEXCO_NORM, //< Normal coordinates RAS_TEXTANGENT, //< - RAS_TEXCO_UV2, //< RAS_TEXCO_VCOL, //< Vertex Color RAS_TEXCO_DISABLE //< Disable this texture unit (cached) }; diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp index 9fb47117f1d..54fe19a291f 100644 --- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp +++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp @@ -605,7 +605,8 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa if (ms.m_pDeformer) { - ms.m_pDeformer->Apply(m_material); + if (ms.m_pDeformer->Apply(m_material)); + ms.m_mesh->SetMeshModified(true); // KX_ReInstanceShapeFromMesh(ms.m_mesh); // Recompute the physics mesh. (Can't call KX_* from RAS_) } @@ -648,10 +649,6 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa else rasty->IndexPrimitives(ms); - if (rasty->QueryLists()) - if (ms.m_DisplayList) - ms.m_mesh->SetMeshModified(false); - rendertools->PopMatrix(); } diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp index 2ccb9453b3d..49b74895302 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp +++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp @@ -324,15 +324,14 @@ void RAS_MeshObject::SetVertexColor(RAS_IPolyMaterial* mat,MT_Vector4 rgba) void RAS_MeshObject::AddVertex(RAS_Polygon *poly, int i, const MT_Point3& xyz, - const MT_Point2& uv, - const MT_Point2& uv2, + const MT_Point2 uvs[RAS_TexVert::MAX_UNIT], const MT_Vector4& tangent, const unsigned int rgba, const MT_Vector3& normal, bool flat, int origindex) { - RAS_TexVert texvert(xyz, uv, uv2, tangent, rgba, normal, flat, origindex); + RAS_TexVert texvert(xyz, uvs, tangent, rgba, normal, flat, origindex); RAS_MeshMaterial *mmat; RAS_DisplayArray *darray; RAS_MeshSlot *slot; diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h index 281eae8734a..d77d0483024 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.h +++ b/source/gameengine/Rasterizer/RAS_MeshObject.h @@ -116,8 +116,7 @@ public: virtual RAS_Polygon* AddPolygon(RAS_MaterialBucket *bucket, int numverts); virtual void AddVertex(RAS_Polygon *poly, int i, const MT_Point3& xyz, - const MT_Point2& uv, - const MT_Point2& uv2, + const MT_Point2 uvs[RAS_TexVert::MAX_UNIT], const MT_Vector4& tangent, const unsigned int rgbacolor, const MT_Vector3& normal, diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt index 189c4f78f77..11cb4b1d9f9 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt @@ -46,12 +46,17 @@ set(SRC RAS_GLExtensionManager.cpp RAS_ListRasterizer.cpp RAS_OpenGLRasterizer.cpp - RAS_VAOpenGLRasterizer.cpp + RAS_StorageIM.cpp + RAS_StorageVA.cpp + RAS_StorageVBO.cpp RAS_GLExtensionManager.h + RAS_IStorage.h RAS_ListRasterizer.h RAS_OpenGLRasterizer.h - RAS_VAOpenGLRasterizer.h + RAS_StorageIM.h + RAS_StorageVA.h + RAS_StorageVBO.h ) add_definitions(-DGLEW_STATIC) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_IStorage.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_IStorage.h new file mode 100644 index 00000000000..f5c16bc8cd8 --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_IStorage.h @@ -0,0 +1,62 @@ +/* + * ***** 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) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __KX_STORAGE +#define __KX_STORAGE + +#include "RAS_MaterialBucket.h" + +enum RAS_STORAGE_TYPE { + RAS_AUTO_STORAGE, + RAS_IMMEDIATE, + RAS_VA, + RAS_VBO +}; + +class RAS_IStorage +{ + +public: + virtual ~RAS_IStorage() {}; + + virtual bool Init()=0; + virtual void Exit()=0; + + virtual void IndexPrimitives(RAS_MeshSlot& ms)=0; + virtual void IndexPrimitivesMulti(class RAS_MeshSlot& ms)=0; + + virtual void SetDrawingMode(int drawingmode)=0; + + +#ifdef WITH_CXX_GUARDEDALLOC +public: + void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_IStorage"); } + void operator delete( void *mem ) { MEM_freeN(mem); } +#endif +}; + +#endif //__KX_STORAGE diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp index d74aa134779..3a60643e9e7 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp @@ -106,9 +106,8 @@ bool RAS_ListSlot::End() -RAS_ListRasterizer::RAS_ListRasterizer(RAS_ICanvas* canvas, bool useVertexArrays, bool lock) -: RAS_VAOpenGLRasterizer(canvas, lock), - mUseVertexArrays(useVertexArrays), +RAS_ListRasterizer::RAS_ListRasterizer(RAS_ICanvas* canvas, bool lock, int storage) +: RAS_OpenGLRasterizer(canvas, storage), mATI(false) { if (!strcmp((const char*)glGetString(GL_VENDOR), "ATI Technologies Inc.")) @@ -238,11 +237,8 @@ void RAS_ListRasterizer::IndexPrimitives(RAS_MeshSlot& ms) return; } } - // derived mesh cannot use vertex array - if (mUseVertexArrays && !ms.m_pDerivedMesh) - RAS_VAOpenGLRasterizer::IndexPrimitives(ms); - else - RAS_OpenGLRasterizer::IndexPrimitives(ms); + + RAS_OpenGLRasterizer::IndexPrimitives(ms); if (ms.m_bDisplayList) { localSlot->EndList(); @@ -267,13 +263,7 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms) } } - // workaround: note how we do not use vertex arrays for making display - // lists, since glVertexAttribPointerARB doesn't seem to work correct - // in display lists on ATI? either a bug in the driver or in Blender .. - if (mUseVertexArrays && !mATI && !ms.m_pDerivedMesh) - RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(ms); - else - RAS_OpenGLRasterizer::IndexPrimitivesMulti(ms); + RAS_OpenGLRasterizer::IndexPrimitivesMulti(ms); if (ms.m_bDisplayList) { localSlot->EndList(); @@ -283,29 +273,17 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms) bool RAS_ListRasterizer::Init(void) { - if (mUseVertexArrays) { - return RAS_VAOpenGLRasterizer::Init(); - } else { - return RAS_OpenGLRasterizer::Init(); - } + return RAS_OpenGLRasterizer::Init(); } void RAS_ListRasterizer::SetDrawingMode(int drawingmode) { - if (mUseVertexArrays) { - RAS_VAOpenGLRasterizer::SetDrawingMode(drawingmode); - } else { - RAS_OpenGLRasterizer::SetDrawingMode(drawingmode); - } + RAS_OpenGLRasterizer::SetDrawingMode(drawingmode); } void RAS_ListRasterizer::Exit() { - if (mUseVertexArrays) { - RAS_VAOpenGLRasterizer::Exit(); - } else { - RAS_OpenGLRasterizer::Exit(); - } + RAS_OpenGLRasterizer::Exit(); } // eof diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h index a8eb2d5ffdf..0eddde7c203 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h @@ -7,7 +7,7 @@ #define __RAS_LISTRASTERIZER_H__ #include "RAS_MaterialBucket.h" -#include "RAS_VAOpenGLRasterizer.h" +#include "RAS_OpenGLRasterizer.h" #include <vector> #include <map> @@ -49,7 +49,7 @@ typedef std::map<RAS_DisplayArrayList, RAS_ListSlot*> RAS_ArrayLists; typedef std::vector<RAS_ListSlot*> RAS_ListSlots; // indexed by material slot number typedef std::map<DerivedMesh*, RAS_ListSlots*> RAS_DerivedMeshLists; -class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer +class RAS_ListRasterizer : public RAS_OpenGLRasterizer { bool mUseVertexArrays; bool mATI; @@ -61,7 +61,7 @@ class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer public: void RemoveListSlot(RAS_ListSlot* list); - RAS_ListRasterizer(RAS_ICanvas* canvas, bool useVertexArrays=false, bool lock=false); + RAS_ListRasterizer(RAS_ICanvas* canvas, bool lock=false, int storage=RAS_AUTO_STORAGE); virtual ~RAS_ListRasterizer(); virtual void IndexPrimitives(class RAS_MeshSlot& ms); diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 22a700c7d2b..1328a5521b4 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -43,6 +43,10 @@ #include "MT_CmMatrix4x4.h" #include "RAS_IRenderTools.h" // rendering text +#include "RAS_StorageIM.h" +#include "RAS_StorageVA.h" +#include "RAS_StorageVBO.h" + #include "GPU_draw.h" #include "GPU_material.h" #include "GPU_extensions.h" @@ -74,7 +78,7 @@ static GLuint right_eye_vinterlace_mask[32]; */ static GLuint hinterlace_mask[33]; -RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas) +RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas, int storage) :RAS_IRasterizer(canvas), m_2DCanvas(canvas), m_fogenabled(false), @@ -93,7 +97,8 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas) m_attrib_num(0), //m_last_alphablend(GPU_BLEND_SOLID), m_last_frontface(true), - m_materialCachingInfo(0) + m_materialCachingInfo(0), + m_storage_type(storage) { m_viewmatrix.setIdentity(); m_viewinvmatrix.setIdentity(); @@ -107,6 +112,24 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas) hinterlace_mask[32] = 0; m_prevafvalue = GPU_get_anisotropic(); + + if (m_storage_type == RAS_VBO /*|| m_storage_type == RAS_AUTO_STORAGE && GLEW_ARB_vertex_buffer_object*/) + { + m_storage = new RAS_StorageVBO(&m_texco_num, m_texco, &m_attrib_num, m_attrib); + m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib); + m_storage_type = RAS_VBO; + } + else if (m_storage_type == RAS_VA || m_storage_type == RAS_AUTO_STORAGE && GLEW_VERSION_1_1) + { + m_storage = new RAS_StorageVA(&m_texco_num, m_texco, &m_attrib_num, m_attrib); + m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib); + m_storage_type = RAS_VA; + } + else + { + m_storage = m_failsafe_storage = new RAS_StorageIM(&m_texco_num, m_texco, &m_attrib_num, m_attrib); + m_storage_type = RAS_IMMEDIATE; + } } @@ -115,10 +138,16 @@ RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer() { // Restore the previous AF value GPU_set_anisotropic(m_prevafvalue); + if (m_failsafe_storage && m_failsafe_storage != m_storage) + delete m_failsafe_storage; + + if (m_storage) + delete m_storage; } bool RAS_OpenGLRasterizer::Init() { + bool storage_init; GPU_state_init(); @@ -146,7 +175,9 @@ bool RAS_OpenGLRasterizer::Init() glShadeModel(GL_SMOOTH); - return true; + storage_init = m_storage->Init(); + + return true && storage_init; } @@ -267,6 +298,8 @@ bool RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat) void RAS_OpenGLRasterizer::Exit() { + m_storage->Exit(); + glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glClearDepth(1.0); @@ -289,7 +322,7 @@ void RAS_OpenGLRasterizer::Exit() bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time) { m_time = time; - m_drawingmode = drawingmode; + SetDrawingMode(drawingmode); // Blender camera routine destroys the settings if (m_drawingmode < KX_SOLID) @@ -328,6 +361,8 @@ void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode) if (m_drawingmode == KX_WIREFRAME) glDisable(GL_CULL_FACE); + + m_storage->SetDrawingMode(drawingmode); } int RAS_OpenGLRasterizer::GetDrawingMode() @@ -666,7 +701,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(RAS_MeshSlot& ms, glattrib = -1; if (GLEW_ARB_vertex_program) for (unit=0; unit<m_attrib_num; unit++) - if (m_attrib[unit] == RAS_TEXCO_UV1) + if (m_attrib[unit] == RAS_TEXCO_UV) glattrib = unit; rendertools->RenderText(polymat->GetDrawingMode(), polymat, @@ -708,257 +743,20 @@ void RAS_OpenGLRasterizer::SetAttrib(TexCoGen coords, int unit) m_attrib[unit] = coords; } -void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv) -{ - int unit; - - if (GLEW_ARB_multitexture) { - for (unit=0; unit<m_texco_num; unit++) { - if (tv.getFlag() & RAS_TexVert::SECOND_UV && (int)tv.getUnit() == unit) { - glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2()); - continue; - } - switch (m_texco[unit]) { - case RAS_TEXCO_ORCO: - case RAS_TEXCO_GLOB: - glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getXYZ()); - break; - case RAS_TEXCO_UV1: - glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV1()); - break; - case RAS_TEXCO_NORM: - glMultiTexCoord3fvARB(GL_TEXTURE0_ARB+unit, tv.getNormal()); - break; - case RAS_TEXTANGENT: - glMultiTexCoord4fvARB(GL_TEXTURE0_ARB+unit, tv.getTangent()); - break; - case RAS_TEXCO_UV2: - glMultiTexCoord2fvARB(GL_TEXTURE0_ARB+unit, tv.getUV2()); - break; - default: - break; - } - } - } - - if (GLEW_ARB_vertex_program) { - for (unit=0; unit<m_attrib_num; unit++) { - switch (m_attrib[unit]) { - case RAS_TEXCO_ORCO: - case RAS_TEXCO_GLOB: - glVertexAttrib3fvARB(unit, tv.getXYZ()); - break; - case RAS_TEXCO_UV1: - glVertexAttrib2fvARB(unit, tv.getUV1()); - break; - case RAS_TEXCO_NORM: - glVertexAttrib3fvARB(unit, tv.getNormal()); - break; - case RAS_TEXTANGENT: - glVertexAttrib4fvARB(unit, tv.getTangent()); - break; - case RAS_TEXCO_UV2: - glVertexAttrib2fvARB(unit, tv.getUV2()); - break; - case RAS_TEXCO_VCOL: - glVertexAttrib4ubvARB(unit, tv.getRGBA()); - break; - default: - break; - } - } - } - -} - void RAS_OpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms) { - IndexPrimitivesInternal(ms, false); + if (ms.m_pDerivedMesh) + m_failsafe_storage->IndexPrimitives(ms); + else + m_storage->IndexPrimitives(ms); } void RAS_OpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms) { - IndexPrimitivesInternal(ms, true); -} - -static bool current_wireframe; -static RAS_MaterialBucket *current_bucket; -static RAS_IPolyMaterial *current_polymat; -static RAS_MeshSlot *current_ms; -static RAS_MeshObject *current_mesh; -static int current_blmat_nr; -static GPUVertexAttribs current_gpu_attribs; -static Image *current_image; -static int CheckMaterialDM(int matnr, void *attribs) -{ - // only draw the current material - if (matnr != current_blmat_nr) - return 0; - GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs; - if (gattribs) - memcpy(gattribs, ¤t_gpu_attribs, sizeof(GPUVertexAttribs)); - return 1; -} - -/* -static int CheckTexfaceDM(void *mcol, int index) -{ - - // index is the original face index, retrieve the polygon - RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ? - current_mesh->GetPolygon(index) : NULL; - if (polygon && polygon->GetMaterial() == current_bucket) { - // must handle color. - if (current_wireframe) - return 2; - if (current_ms->m_bObjectColor) { - MT_Vector4& rgba = current_ms->m_RGBAcolor; - glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); - // don't use mcol - return 2; - } - if (!mcol) { - // we have to set the color from the material - unsigned char rgba[4]; - current_polymat->GetMaterialRGBAColor(rgba); - glColor4ubv((const GLubyte *)rgba); - return 2; - } - return 1; - } - return 0; -} -*/ - -static DMDrawOption CheckTexDM(MTFace *tface, int has_mcol, int matnr) -{ - - // index is the original face index, retrieve the polygon - if (matnr == current_blmat_nr && - (tface == NULL || tface->tpage == current_image)) { - // must handle color. - if (current_wireframe) - return DM_DRAW_OPTION_NO_MCOL; - if (current_ms->m_bObjectColor) { - MT_Vector4& rgba = current_ms->m_RGBAcolor; - glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); - // don't use mcol - return DM_DRAW_OPTION_NO_MCOL; - } - if (!has_mcol) { - // we have to set the color from the material - unsigned char rgba[4]; - current_polymat->GetMaterialRGBAColor(rgba); - glColor4ubv((const GLubyte *)rgba); - return DM_DRAW_OPTION_NO_MCOL; - } - return DM_DRAW_OPTION_NORMAL; - } - return DM_DRAW_OPTION_SKIP; -} - -void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi) -{ - bool obcolor = ms.m_bObjectColor; - bool wireframe = m_drawingmode <= KX_WIREFRAME; - MT_Vector4& rgba = ms.m_RGBAcolor; - RAS_MeshSlot::iterator it; - - if (ms.m_pDerivedMesh) { - // mesh data is in derived mesh, - current_bucket = ms.m_bucket; - current_polymat = current_bucket->GetPolyMaterial(); - current_ms = &ms; - current_mesh = ms.m_mesh; - current_wireframe = wireframe; - // MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */ - - // handle two-side - if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_BACKCULL) - this->SetCullFace(true); - else - this->SetCullFace(false); - - if (current_polymat->GetFlag() & RAS_BLENDERGLSL) { - // GetMaterialIndex return the original mface material index, - // increment by 1 to match what derived mesh is doing - current_blmat_nr = current_polymat->GetMaterialIndex()+1; - // For GLSL we need to retrieve the GPU material attribute - Material* blmat = current_polymat->GetBlenderMaterial(); - Scene* blscene = current_polymat->GetBlenderScene(); - if (!wireframe && blscene && blmat) - GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), ¤t_gpu_attribs); - else - memset(¤t_gpu_attribs, 0, sizeof(current_gpu_attribs)); - // DM draw can mess up blending mode, restore at the end - int current_blend_mode = GPU_get_material_alpha_blend(); - ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM); - GPU_set_material_alpha_blend(current_blend_mode); - } - else { - //ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol); - current_blmat_nr = current_polymat->GetMaterialIndex(); - current_image = current_polymat->GetBlenderImage(); - ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM, NULL, NULL); - } - return; - } - // iterate over display arrays, each containing an index + vertex array - for (ms.begin(it); !ms.end(it); ms.next(it)) { - RAS_TexVert *vertex; - size_t i, j, numvert; - - numvert = it.array->m_type; - - if (it.array->m_type == RAS_DisplayArray::LINE) { - // line drawing - glBegin(GL_LINES); - - for (i=0; i<it.totindex; i+=2) - { - vertex = &it.vertex[it.index[i]]; - glVertex3fv(vertex->getXYZ()); - - vertex = &it.vertex[it.index[i+1]]; - glVertex3fv(vertex->getXYZ()); - } - - glEnd(); - } - else { - // triangle and quad drawing - if (it.array->m_type == RAS_DisplayArray::TRIANGLE) - glBegin(GL_TRIANGLES); - else - glBegin(GL_QUADS); - - for (i=0; i<it.totindex; i+=numvert) - { - if (obcolor) - glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); - - for (j=0; j<numvert; j++) { - vertex = &it.vertex[it.index[i+j]]; - - if (!wireframe) { - if (!obcolor) - glColor4ubv((const GLubyte *)(vertex->getRGBA())); - - glNormal3fv(vertex->getNormal()); - - if (multi) - TexCoord(*vertex); - else - glTexCoord2fv(vertex->getUV1()); - } - - glVertex3fv(vertex->getXYZ()); - } - } - - glEnd(); - } - } + if (ms.m_pDerivedMesh) + m_failsafe_storage->IndexPrimitivesMulti(ms); + else + m_storage->IndexPrimitivesMulti(ms); } void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index 88bb0be531b..c156ee53ed3 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -41,6 +41,7 @@ using namespace std; #include "RAS_IRasterizer.h" +#include "RAS_IStorage.h" #include "RAS_MaterialBucket.h" #include "RAS_ICanvas.h" @@ -83,7 +84,6 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer float m_ambr; float m_ambg; float m_ambb; - double m_time; MT_Matrix4x4 m_viewmatrix; MT_Matrix4x4 m_viewinvmatrix; @@ -115,9 +115,15 @@ protected: /** Stores the caching information for the last material activated. */ RAS_IPolyMaterial::TCachingInfo m_materialCachingInfo; + /** Making use of a Strategy desing pattern for storage behavior. + Examples of concrete strategies: Vertex Arrays, VBOs, Immediate Mode*/ + int m_storage_type; + RAS_IStorage* m_storage; + RAS_IStorage* m_failsafe_storage; //So derived mesh can use immediate mode + public: double GetTime(); - RAS_OpenGLRasterizer(RAS_ICanvas* canv); + RAS_OpenGLRasterizer(RAS_ICanvas* canv, int storage=RAS_AUTO_STORAGE); virtual ~RAS_OpenGLRasterizer(); /*enum DrawType @@ -166,8 +172,6 @@ public: class RAS_IPolyMaterial* polymat, class RAS_IRenderTools* rendertools); - void IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi); - virtual void SetProjectionMatrix(MT_CmMatrix4x4 & mat); virtual void SetProjectionMatrix(const MT_Matrix4x4 & mat); virtual void SetViewMatrix( diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp new file mode 100644 index 00000000000..7b38b3b42f3 --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.cpp @@ -0,0 +1,310 @@ +/* + * ***** 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) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "RAS_StorageIM.h" + +#include "GL/glew.h" +#include "GPU_draw.h" +#include "GPU_extensions.h" +#include "GPU_material.h" + +#include "DNA_meshdata_types.h" + +extern "C"{ + #include "BLI_utildefines.h" + #include "BKE_DerivedMesh.h" +} + +RAS_StorageIM::RAS_StorageIM(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib) : + m_texco_num(texco_num), + m_texco(texco), + m_attrib_num(attrib_num), + m_attrib(attrib) +{ +} +RAS_StorageIM::~RAS_StorageIM() +{ +} + +bool RAS_StorageIM::Init() +{ + return true; +} +void RAS_StorageIM::Exit() +{ +} + +void RAS_StorageIM::IndexPrimitives(RAS_MeshSlot& ms) +{ + IndexPrimitivesInternal(ms, false); +} + +void RAS_StorageIM::IndexPrimitivesMulti(class RAS_MeshSlot& ms) +{ + IndexPrimitivesInternal(ms, true); +} + +void RAS_StorageIM::TexCoord(const RAS_TexVert &tv) +{ + int unit; + + if (GLEW_ARB_multitexture) { + for (unit = 0; unit < *m_texco_num; unit++) { + switch(m_texco[unit]) { + case RAS_IRasterizer::RAS_TEXCO_ORCO: + case RAS_IRasterizer::RAS_TEXCO_GLOB: + glMultiTexCoord3fvARB(GL_TEXTURE0_ARB + unit, tv.getXYZ()); + break; + case RAS_IRasterizer::RAS_TEXCO_UV: + glMultiTexCoord2fvARB(GL_TEXTURE0_ARB + unit, tv.getUV(unit)); + break; + case RAS_IRasterizer::RAS_TEXCO_NORM: + glMultiTexCoord3fvARB(GL_TEXTURE0_ARB + unit, tv.getNormal()); + break; + case RAS_IRasterizer::RAS_TEXTANGENT: + glMultiTexCoord4fvARB(GL_TEXTURE0_ARB + unit, tv.getTangent()); + break; + default: + break; + } + } + } + + if (GLEW_ARB_vertex_program) { + int uv = 0; + for (unit = 0; unit < *m_attrib_num; unit++) { + switch(m_attrib[unit]) { + case RAS_IRasterizer::RAS_TEXCO_ORCO: + case RAS_IRasterizer::RAS_TEXCO_GLOB: + glVertexAttrib3fvARB(unit, tv.getXYZ()); + break; + case RAS_IRasterizer::RAS_TEXCO_UV: + glVertexAttrib2fvARB(unit, tv.getUV(uv++)); + break; + case RAS_IRasterizer::RAS_TEXCO_NORM: + glVertexAttrib3fvARB(unit, tv.getNormal()); + break; + case RAS_IRasterizer::RAS_TEXTANGENT: + glVertexAttrib4fvARB(unit, tv.getTangent()); + break; + case RAS_IRasterizer::RAS_TEXCO_VCOL: + glVertexAttrib4ubvARB(unit, tv.getRGBA()); + break; + default: + break; + } + } + } + +} + +void RAS_StorageIM::SetCullFace(bool enable) +{ + if (enable) + glEnable(GL_CULL_FACE); + else + glDisable(GL_CULL_FACE); +} + +static bool current_wireframe; +static RAS_MaterialBucket *current_bucket; +static RAS_IPolyMaterial *current_polymat; +static RAS_MeshSlot *current_ms; +static RAS_MeshObject *current_mesh; +static int current_blmat_nr; +static GPUVertexAttribs current_gpu_attribs; +static Image *current_image; +static int CheckMaterialDM(int matnr, void *attribs) +{ + // only draw the current material + if (matnr != current_blmat_nr) + return 0; + GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs; + if (gattribs) + memcpy(gattribs, ¤t_gpu_attribs, sizeof(GPUVertexAttribs)); + return 1; +} + +/* +static int CheckTexfaceDM(void *mcol, int index) +{ + + // index is the original face index, retrieve the polygon + RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ? + current_mesh->GetPolygon(index) : NULL; + if (polygon && polygon->GetMaterial() == current_bucket) { + // must handle color. + if (current_wireframe) + return 2; + if (current_ms->m_bObjectColor) { + MT_Vector4& rgba = current_ms->m_RGBAcolor; + glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); + // don't use mcol + return 2; + } + if (!mcol) { + // we have to set the color from the material + unsigned char rgba[4]; + current_polymat->GetMaterialRGBAColor(rgba); + glColor4ubv((const GLubyte *)rgba); + return 2; + } + return 1; + } + return 0; +} +*/ + +static DMDrawOption CheckTexDM(MTFace *tface, int has_mcol, int matnr) +{ + + // index is the original face index, retrieve the polygon + if (matnr == current_blmat_nr && + (tface == NULL || tface->tpage == current_image)) { + // must handle color. + if (current_wireframe) + return DM_DRAW_OPTION_NO_MCOL; + if (current_ms->m_bObjectColor) { + MT_Vector4& rgba = current_ms->m_RGBAcolor; + glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); + // don't use mcol + return DM_DRAW_OPTION_NO_MCOL; + } + if (!has_mcol) { + // we have to set the color from the material + unsigned char rgba[4]; + current_polymat->GetMaterialRGBAColor(rgba); + glColor4ubv((const GLubyte *)rgba); + return DM_DRAW_OPTION_NO_MCOL; + } + return DM_DRAW_OPTION_NORMAL; + } + return DM_DRAW_OPTION_SKIP; +} + +void RAS_StorageIM::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi) +{ + bool obcolor = ms.m_bObjectColor; + bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME; + MT_Vector4& rgba = ms.m_RGBAcolor; + RAS_MeshSlot::iterator it; + + if (ms.m_pDerivedMesh) { + // mesh data is in derived mesh, + current_bucket = ms.m_bucket; + current_polymat = current_bucket->GetPolyMaterial(); + current_ms = &ms; + current_mesh = ms.m_mesh; + current_wireframe = wireframe; + // MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */ + + // handle two-side + if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_BACKCULL) + this->SetCullFace(true); + else + this->SetCullFace(false); + + if (current_polymat->GetFlag() & RAS_BLENDERGLSL) { + // GetMaterialIndex return the original mface material index, + // increment by 1 to match what derived mesh is doing + current_blmat_nr = current_polymat->GetMaterialIndex()+1; + // For GLSL we need to retrieve the GPU material attribute + Material* blmat = current_polymat->GetBlenderMaterial(); + Scene* blscene = current_polymat->GetBlenderScene(); + if (!wireframe && blscene && blmat) + GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), ¤t_gpu_attribs); + else + memset(¤t_gpu_attribs, 0, sizeof(current_gpu_attribs)); + // DM draw can mess up blending mode, restore at the end + int current_blend_mode = GPU_get_material_alpha_blend(); + ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM); + GPU_set_material_alpha_blend(current_blend_mode); + } else { + //ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol); + current_blmat_nr = current_polymat->GetMaterialIndex(); + current_image = current_polymat->GetBlenderImage(); + ms.m_pDerivedMesh->drawFacesTex(ms.m_pDerivedMesh, CheckTexDM, NULL, NULL); + } + return; + } + // iterate over display arrays, each containing an index + vertex array + for (ms.begin(it); !ms.end(it); ms.next(it)) { + RAS_TexVert *vertex; + size_t i, j, numvert; + + numvert = it.array->m_type; + + if (it.array->m_type == RAS_DisplayArray::LINE) { + // line drawing + glBegin(GL_LINES); + + for (i = 0; i < it.totindex; i += 2) + { + vertex = &it.vertex[it.index[i]]; + glVertex3fv(vertex->getXYZ()); + + vertex = &it.vertex[it.index[i+1]]; + glVertex3fv(vertex->getXYZ()); + } + + glEnd(); + } + else { + // triangle and quad drawing + if (it.array->m_type == RAS_DisplayArray::TRIANGLE) + glBegin(GL_TRIANGLES); + else + glBegin(GL_QUADS); + + for (i = 0; i < it.totindex; i += numvert) + { + if (obcolor) + glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); + + for (j = 0; j < numvert; j++) { + vertex = &it.vertex[it.index[i+j]]; + + if (!wireframe) { + if (!obcolor) + glColor4ubv((const GLubyte *)(vertex->getRGBA())); + + glNormal3fv(vertex->getNormal()); + + if (multi) + TexCoord(*vertex); + else + glTexCoord2fv(vertex->getUV(0)); + } + + glVertex3fv(vertex->getXYZ()); + } + } + + glEnd(); + } + } +} diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h new file mode 100644 index 00000000000..de4ff30d394 --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageIM.h @@ -0,0 +1,68 @@ +/* + * ***** 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) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __KX_IMMEDIATEMODESTORAGE +#define __KX_IMMEDIATEMODESTORAGE + +#include "RAS_IStorage.h" +#include "RAS_IRasterizer.h" + +class RAS_StorageIM : public RAS_IStorage +{ +public: + RAS_StorageIM(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib); + virtual ~RAS_StorageIM(); + + virtual bool Init(); + virtual void Exit(); + + virtual void IndexPrimitives(RAS_MeshSlot& ms); + virtual void IndexPrimitivesMulti(class RAS_MeshSlot& ms); + + virtual void SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;}; + +protected: + int m_drawingmode; + int* m_texco_num; + int* m_attrib_num; + RAS_IRasterizer::TexCoGen* m_texco; + RAS_IRasterizer::TexCoGen* m_attrib; + + void TexCoord(const RAS_TexVert &tv); + void SetCullFace(bool enable); + + void IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi); + + +#ifdef WITH_CXX_GUARDEDALLOC +public: + void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageIM"); } + void operator delete( void *mem ) { MEM_freeN(mem); } +#endif +}; + +#endif //__KX_IMMEDIATEMODESTORAGE diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp new file mode 100644 index 00000000000..e0d580eff11 --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.cpp @@ -0,0 +1,320 @@ +/* + * ***** 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) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "RAS_StorageVA.h" + +#include "GL/glew.h" + +RAS_StorageVA::RAS_StorageVA(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib) : + m_texco_num(texco_num), + m_texco(texco), + m_attrib_num(attrib_num), + m_attrib(attrib), + m_last_texco_num(0), + m_last_attrib_num(0) +{ +} + +RAS_StorageVA::~RAS_StorageVA() +{ +} + +bool RAS_StorageVA::Init() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + return true; +} + +void RAS_StorageVA::Exit() +{ +} + +void RAS_StorageVA::IndexPrimitives(RAS_MeshSlot& ms) +{ + static const GLsizei stride = sizeof(RAS_TexVert); + bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME; + RAS_MeshSlot::iterator it; + GLenum drawmode; + + if (!wireframe) + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + + // use glDrawElements to draw each vertexarray + for (ms.begin(it); !ms.end(it); ms.next(it)) { + if (it.totindex == 0) + continue; + + // drawing mode + if (it.array->m_type == RAS_DisplayArray::TRIANGLE) + drawmode = GL_TRIANGLES; + else if (it.array->m_type == RAS_DisplayArray::QUAD) + drawmode = GL_QUADS; + else + drawmode = GL_LINES; + + // colors + if (drawmode != GL_LINES && !wireframe) { + if (ms.m_bObjectColor) { + const MT_Vector4& rgba = ms.m_RGBAcolor; + + glDisableClientState(GL_COLOR_ARRAY); + glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); + } + else { + glColor4f(0.0f, 0.0f, 0.0f, 1.0f); + glEnableClientState(GL_COLOR_ARRAY); + } + } + else + glColor4f(0.0f, 0.0f, 0.0f, 1.0f); + + glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ()); + glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal()); + if (!wireframe) { + glTexCoordPointer(2, GL_FLOAT, stride, it.vertex->getUV(0)); + if (glIsEnabled(GL_COLOR_ARRAY)) + glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA()); + } + + // here the actual drawing takes places + glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index); + } + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + if (!wireframe) { + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + } +} + +void RAS_StorageVA::IndexPrimitivesMulti(class RAS_MeshSlot& ms) +{ + static const GLsizei stride = sizeof(RAS_TexVert); + bool wireframe = m_drawingmode <= RAS_IRasterizer::KX_WIREFRAME, use_color_array; + RAS_MeshSlot::iterator it; + GLenum drawmode; + + if (!wireframe) + EnableTextures(true); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + + // use glDrawElements to draw each vertexarray + for (ms.begin(it); !ms.end(it); ms.next(it)) { + if (it.totindex == 0) + continue; + + // drawing mode + if (it.array->m_type == RAS_DisplayArray::TRIANGLE) + drawmode = GL_TRIANGLES; + else if (it.array->m_type == RAS_DisplayArray::QUAD) + drawmode = GL_QUADS; + else + drawmode = GL_LINES; + + // colors + if (drawmode != GL_LINES && !wireframe) { + if (ms.m_bObjectColor) { + const MT_Vector4& rgba = ms.m_RGBAcolor; + + glDisableClientState(GL_COLOR_ARRAY); + glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); + use_color_array = false; + } + else { + glColor4f(0.0f, 0.0f, 0.0f, 1.0f); + glEnableClientState(GL_COLOR_ARRAY); + use_color_array = true; + } + } + else + glColor4f(0.0f, 0.0f, 0.0f, 1.0f); + + glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ()); + glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal()); + + if (!wireframe) { + TexCoordPtr(it.vertex); + if (use_color_array) + glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA()); + } + + // here the actual drawing takes places + glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index); + } + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + if (!wireframe) { + glDisableClientState(GL_COLOR_ARRAY); + EnableTextures(false); + } +} + +void RAS_StorageVA::TexCoordPtr(const RAS_TexVert *tv) +{ + /* note: this function must closely match EnableTextures to enable/disable + * the right arrays, otherwise coordinate and attribute pointers from other + * materials can still be used and cause crashes */ + int unit; + + if (GLEW_ARB_multitexture) + { + for (unit = 0; unit < *m_texco_num; unit++) + { + glClientActiveTextureARB(GL_TEXTURE0_ARB+unit); + switch (m_texco[unit]) { + case RAS_IRasterizer::RAS_TEXCO_ORCO: + case RAS_IRasterizer::RAS_TEXCO_GLOB: + glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getXYZ()); + break; + case RAS_IRasterizer::RAS_TEXCO_UV: + glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV(unit)); + break; + case RAS_IRasterizer::RAS_TEXCO_NORM: + glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getNormal()); + break; + case RAS_IRasterizer::RAS_TEXTANGENT: + glTexCoordPointer(4, GL_FLOAT, sizeof(RAS_TexVert),tv->getTangent()); + break; + default: + break; + } + } + + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + + if (GLEW_ARB_vertex_program) { + int uv = 0; + for (unit = 0; unit < *m_attrib_num; unit++) { + switch (m_attrib[unit]) { + case RAS_IRasterizer::RAS_TEXCO_ORCO: + case RAS_IRasterizer::RAS_TEXCO_GLOB: + glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getXYZ()); + break; + case RAS_IRasterizer::RAS_TEXCO_UV: + glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV(uv++)); + break; + case RAS_IRasterizer::RAS_TEXCO_NORM: + glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal()); + break; + case RAS_IRasterizer::RAS_TEXTANGENT: + glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent()); + break; + case RAS_IRasterizer::RAS_TEXCO_VCOL: + glVertexAttribPointerARB(unit, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(RAS_TexVert), tv->getRGBA()); + break; + default: + break; + } + } + } +} + +void RAS_StorageVA::EnableTextures(bool enable) +{ + RAS_IRasterizer::TexCoGen *texco, *attrib; + int unit, texco_num, attrib_num; + + /* we cache last texcoords and attribs to ensure we disable the ones that + * were actually last set */ + if (enable) { + texco = m_texco; + texco_num = *m_texco_num; + attrib = m_attrib; + attrib_num = *m_attrib_num; + + memcpy(m_last_texco, m_texco, sizeof(RAS_IRasterizer::TexCoGen)*(*m_texco_num)); + m_last_texco_num = *m_texco_num; + memcpy(m_last_attrib, m_attrib, sizeof(RAS_IRasterizer::TexCoGen)*(*m_attrib_num)); + m_last_attrib_num = *m_attrib_num; + } + else { + texco = m_last_texco; + texco_num = m_last_texco_num; + attrib = m_last_attrib; + attrib_num = m_last_attrib_num; + } + + if (GLEW_ARB_multitexture) { + for (unit = 0; unit < texco_num; unit++) { + glClientActiveTextureARB(GL_TEXTURE0_ARB + unit); + + switch (texco[unit]) { + case RAS_IRasterizer::RAS_TEXCO_ORCO: + case RAS_IRasterizer::RAS_TEXCO_GLOB: + case RAS_IRasterizer::RAS_TEXCO_UV: + case RAS_IRasterizer::RAS_TEXCO_NORM: + case RAS_IRasterizer::RAS_TEXTANGENT: + if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY); + else glDisableClientState(GL_TEXTURE_COORD_ARRAY); + break; + default: + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + break; + } + } + + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + else { + if (texco_num) { + if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY); + else glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + } + + if (GLEW_ARB_vertex_program) { + for (unit = 0; unit < attrib_num; unit++) { + switch (attrib[unit]) { + case RAS_IRasterizer::RAS_TEXCO_ORCO: + case RAS_IRasterizer::RAS_TEXCO_GLOB: + case RAS_IRasterizer::RAS_TEXCO_UV: + case RAS_IRasterizer::RAS_TEXCO_NORM: + case RAS_IRasterizer::RAS_TEXTANGENT: + case RAS_IRasterizer::RAS_TEXCO_VCOL: + if (enable) glEnableVertexAttribArrayARB(unit); + else glDisableVertexAttribArrayARB(unit); + break; + default: + glDisableVertexAttribArrayARB(unit); + break; + } + } + } + + if (!enable) { + m_last_texco_num = 0; + m_last_attrib_num = 0; + } +} + diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h index 6b159db05ed..da7766ec5ca 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVA.h @@ -25,46 +25,53 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file RAS_VAOpenGLRasterizer.h - * \ingroup bgerastogl - */ +#ifndef __KX_VERTEXARRAYSTORAGE +#define __KX_VERTEXARRAYSTORAGE -#ifndef __RAS_VAOPENGLRASTERIZER_H__ -#define __RAS_VAOPENGLRASTERIZER_H__ +#include "RAS_IStorage.h" +#include "RAS_IRasterizer.h" #include "RAS_OpenGLRasterizer.h" -class RAS_VAOpenGLRasterizer : public RAS_OpenGLRasterizer +class RAS_StorageVA : public RAS_IStorage { - void TexCoordPtr(const RAS_TexVert *tv); - /* bool m_Lock; */ /* UNUSED */ - - TexCoGen m_last_texco[RAS_MAX_TEXCO]; - TexCoGen m_last_attrib[RAS_MAX_ATTRIB]; - int m_last_texco_num; - int m_last_attrib_num; public: - RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas, bool lock=false); - virtual ~RAS_VAOpenGLRasterizer(); + RAS_StorageVA(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib); + virtual ~RAS_StorageVA(); virtual bool Init(); virtual void Exit(); - virtual void SetDrawingMode(int drawingmode); - - virtual void IndexPrimitives(class RAS_MeshSlot& ms); + virtual void IndexPrimitives(RAS_MeshSlot& ms); virtual void IndexPrimitivesMulti(class RAS_MeshSlot& ms); -private: + virtual void SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;}; + +protected: + int m_drawingmode; + + int* m_texco_num; + int* m_attrib_num; + + int m_last_texco_num; + int m_last_attrib_num; + + RAS_IRasterizer::TexCoGen* m_texco; + RAS_IRasterizer::TexCoGen* m_attrib; + + RAS_IRasterizer::TexCoGen m_last_texco[RAS_MAX_TEXCO]; + RAS_IRasterizer::TexCoGen m_last_attrib[RAS_MAX_ATTRIB]; + virtual void EnableTextures(bool enable); - //virtual bool QueryArrays() {return true;} - //virtual bool QueryLists() {return m_Lock;} + virtual void TexCoordPtr(const RAS_TexVert *tv); #ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GE:RAS_VAOpenGLRasterizer") +public: + void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageVA"); } + void operator delete( void *mem ) { MEM_freeN(mem); } #endif }; -#endif /* __RAS_VAOPENGLRASTERIZER_H__ */ +#endif //__KX_VERTEXARRAYSTORAGE diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp new file mode 100644 index 00000000000..d40aa98295b --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp @@ -0,0 +1,259 @@ +/* + * ***** 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) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "RAS_StorageVBO.h" +#include "RAS_MeshObject.h" + +#include "GL/glew.h" + +VBO::VBO(RAS_DisplayArray *data, unsigned int indices) +{ + this->data = data; + this->size = data->m_vertex.size(); + this->indices = indices; + this->stride = 32*sizeof(GLfloat); // ATI cards really like 32byte aligned VBOs, so we add a little padding + + // Determine drawmode + if (data->m_type == data->QUAD) + this->mode = GL_QUADS; + else if (data->m_type == data->TRIANGLE) + this->mode = GL_TRIANGLES; + else + this->mode = GL_LINE; + + // Generate Buffers + glGenBuffersARB(1, &this->ibo); + glGenBuffersARB(1, &this->vbo_id); + + // Fill the buffers with initial data + UpdateIndices(); + UpdateData(); + + // Establish offsets + this->vertex_offset = 0; + this->normal_offset = (void*)(3*sizeof(GLfloat)); + this->tangent_offset = (void*)(6*sizeof(GLfloat)); + this->color_offset = (void*)(10*sizeof(GLfloat)); + this->uv_offset = (void*)(11*sizeof(GLfloat)); +} + +VBO::~VBO() +{ + glDeleteBuffersARB(1, &this->ibo); + glDeleteBuffersARB(1, &this->vbo_id); +} + +void VBO::UpdateData() +{ + unsigned int i, j, k; + + glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vbo_id); + glBufferData(GL_ARRAY_BUFFER, this->stride*this->size, NULL, GL_STATIC_DRAW); + + // Map the buffer + GLfloat *vbo_map = (GLfloat*)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + + // Gather data + for (i = 0, j = 0; i < data->m_vertex.size(); i++, j += this->stride/sizeof(GLfloat)) + { + memcpy(&vbo_map[j], data->m_vertex[i].getXYZ(), sizeof(float)*3); + memcpy(&vbo_map[j+3], data->m_vertex[i].getNormal(), sizeof(float)*3); + memcpy(&vbo_map[j+6], data->m_vertex[i].getTangent(), sizeof(float)*4); + memcpy(&vbo_map[j+10], data->m_vertex[i].getRGBA(), sizeof(char)*4); + + for (k = 0; k < RAS_TexVert::MAX_UNIT; k++) + memcpy(&vbo_map[j+11+(k*2)], data->m_vertex[i].getUV(k), sizeof(float)*2); + } + + glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); +} + +void VBO::UpdateIndices() +{ + int space = data->m_index.size() * sizeof(GLushort); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, this->ibo); + + // Upload Data to VBO + glBufferData(GL_ELEMENT_ARRAY_BUFFER, space, &data->m_index[0], GL_STATIC_DRAW); +} + +void VBO::Draw(int texco_num, RAS_IRasterizer::TexCoGen* texco, int attrib_num, RAS_IRasterizer::TexCoGen* attrib, bool multi) +{ + int unit; + + // Bind buffers + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, this->ibo); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vbo_id); + + // Vertexes + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, this->stride, this->vertex_offset); + + // Normals + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, this->stride, this->normal_offset); + + // Colors + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_UNSIGNED_BYTE, this->stride, this->color_offset); + + if (multi) + { + for (unit = 0; unit < texco_num; ++unit) + { + glClientActiveTexture(GL_TEXTURE0_ARB + unit); + switch (texco[unit]) { + case RAS_IRasterizer::RAS_TEXCO_ORCO: + case RAS_IRasterizer::RAS_TEXCO_GLOB: + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(3, GL_FLOAT, this->stride, this->vertex_offset); + break; + case RAS_IRasterizer::RAS_TEXCO_UV: + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, this->stride, (void*)((intptr_t)this->uv_offset+(sizeof(GLfloat)*2*unit))); + break; + case RAS_IRasterizer::RAS_TEXCO_NORM: + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(3, GL_FLOAT, this->stride, this->normal_offset); + break; + case RAS_IRasterizer::RAS_TEXTANGENT: + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(4, GL_FLOAT, this->stride, this->tangent_offset); + break; + default: + break; + } + } + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + else //TexFace + { + glClientActiveTextureARB(GL_TEXTURE0_ARB); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, this->stride, this->uv_offset); + } + + if (GLEW_ARB_vertex_program) + { + int uv = 0; + for (unit = 0; unit < attrib_num; ++unit) + { + switch (attrib[unit]) { + case RAS_IRasterizer::RAS_TEXCO_ORCO: + case RAS_IRasterizer::RAS_TEXCO_GLOB: + glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, this->stride, this->vertex_offset); + glEnableVertexAttribArrayARB(unit); + break; + case RAS_IRasterizer::RAS_TEXCO_UV: + glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, this->stride, (void*)((intptr_t)this->uv_offset+uv)); + uv += sizeof(GLfloat)*2; + glEnableVertexAttribArrayARB(unit); + break; + case RAS_IRasterizer::RAS_TEXCO_NORM: + glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, stride, this->normal_offset); + glEnableVertexAttribArrayARB(unit); + break; + case RAS_IRasterizer::RAS_TEXTANGENT: + glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, this->stride, this->tangent_offset); + glEnableVertexAttribArrayARB(unit); + break; + default: + break; + } + } + } + + glDrawElements(this->mode, this->indices, GL_UNSIGNED_SHORT, 0); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + if (GLEW_ARB_vertex_program) + { + for (int i = 0; i < attrib_num; ++i) + glDisableVertexAttribArrayARB(i); + } + + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + } + +RAS_StorageVBO::RAS_StorageVBO(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib): + m_texco_num(texco_num), + m_texco(texco), + m_attrib_num(attrib_num), + m_attrib(attrib) +{ +} + +RAS_StorageVBO::~RAS_StorageVBO() +{ +} + +bool RAS_StorageVBO::Init() +{ + return true; +} + +void RAS_StorageVBO::Exit() +{ + m_vbo_lookup.clear(); +} + +void RAS_StorageVBO::IndexPrimitives(RAS_MeshSlot& ms) +{ + IndexPrimitivesInternal(ms, false); +} + +void RAS_StorageVBO::IndexPrimitivesMulti(RAS_MeshSlot& ms) +{ + IndexPrimitivesInternal(ms, true); +} + +void RAS_StorageVBO::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi) +{ + RAS_MeshSlot::iterator it; + VBO *vbo; + + for (ms.begin(it); !ms.end(it); ms.next(it)) + { + vbo = m_vbo_lookup[it.array]; + + if (vbo == 0) + m_vbo_lookup[it.array] = vbo = new VBO(it.array, it.totindex); + + // Update the vbo + if (ms.m_mesh->MeshModified()) + { + vbo->UpdateData(); + } + + vbo->Draw(*m_texco_num, m_texco, *m_attrib_num, m_attrib, multi); + } +} diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h new file mode 100644 index 00000000000..d8d8192e482 --- /dev/null +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.h @@ -0,0 +1,100 @@ +/* + * ***** 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) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __KX_VERTEXBUFFEROBJECTSTORAGE +#define __KX_VERTEXBUFFEROBJECTSTORAGE + +#include <map> +#include "GL/glew.h" + +#include "RAS_IStorage.h" +#include "RAS_IRasterizer.h" + +#include "RAS_OpenGLRasterizer.h" + +class VBO +{ +public: + VBO(RAS_DisplayArray *data, unsigned int indices); + ~VBO(); + + void Draw(int texco_num, RAS_IRasterizer::TexCoGen* texco, int attrib_num, RAS_IRasterizer::TexCoGen* attrib, bool multi); + + void UpdateData(); + void UpdateIndices(); +private: + RAS_DisplayArray* data; + GLuint size; + GLuint stride; + GLuint indices; + GLenum mode; + GLuint ibo; + GLuint vbo_id; + + void* vertex_offset; + void* normal_offset; + void* color_offset; + void* tangent_offset; + void* uv_offset; +}; + +class RAS_StorageVBO : public RAS_IStorage +{ + +public: + RAS_StorageVBO(int *texco_num, RAS_IRasterizer::TexCoGen *texco, int *attrib_num, RAS_IRasterizer::TexCoGen *attrib); + virtual ~RAS_StorageVBO(); + + virtual bool Init(); + virtual void Exit(); + + virtual void IndexPrimitives(RAS_MeshSlot& ms); + virtual void IndexPrimitivesMulti(RAS_MeshSlot& ms); + + virtual void SetDrawingMode(int drawingmode){m_drawingmode=drawingmode;}; + +protected: + int m_drawingmode; + + int* m_texco_num; + int* m_attrib_num; + + RAS_IRasterizer::TexCoGen* m_texco; + RAS_IRasterizer::TexCoGen* m_attrib; + + std::map<RAS_DisplayArray*, class VBO*> m_vbo_lookup; + + virtual void IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi); + +#ifdef WITH_CXX_GUARDEDALLOC +public: + void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:RAS_StorageVA"); } + void operator delete( void *mem ) { MEM_freeN(mem); } +#endif +}; + +#endif //__KX_VERTEXBUFFEROBJECTSTORAGE diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp deleted file mode 100644 index 076acb0d153..00000000000 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp +++ /dev/null @@ -1,382 +0,0 @@ -/* - * ***** 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) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp - * \ingroup bgerastogl - */ - -#include "RAS_VAOpenGLRasterizer.h" -#include <stdlib.h> - -#include "GL/glew.h" -#include "GPU_extensions.h" - -#include "STR_String.h" -#include "RAS_TexVert.h" -#include "MT_CmMatrix4x4.h" -#include "RAS_IRenderTools.h" // rendering text - -RAS_VAOpenGLRasterizer::RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas, bool lock) -: RAS_OpenGLRasterizer(canvas), - /* m_Lock(lock && GLEW_EXT_compiled_vertex_array), */ /* UNUSED */ - m_last_texco_num(0), - m_last_attrib_num(0) -{ -} - -RAS_VAOpenGLRasterizer::~RAS_VAOpenGLRasterizer() -{ -} - -bool RAS_VAOpenGLRasterizer::Init(void) -{ - - bool result = RAS_OpenGLRasterizer::Init(); - - if (result) - { - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - } - - return result; -} - -void RAS_VAOpenGLRasterizer::SetDrawingMode(int drawingmode) -{ - m_drawingmode = drawingmode; - - switch (m_drawingmode) - { - case KX_BOUNDINGBOX: - case KX_WIREFRAME: - //glDisableClientState(GL_COLOR_ARRAY); - //glDisable(GL_CULL_FACE); - break; - case KX_SOLID: - //glDisableClientState(GL_COLOR_ARRAY); - break; - case KX_TEXTURED: - case KX_SHADED: - case KX_SHADOW: - //glEnableClientState(GL_COLOR_ARRAY); - default: - break; - } -} - -void RAS_VAOpenGLRasterizer::Exit() -{ - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - - RAS_OpenGLRasterizer::Exit(); -} - -void RAS_VAOpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms) -{ - static const GLsizei stride = sizeof(RAS_TexVert); - bool wireframe = m_drawingmode <= KX_WIREFRAME; - RAS_MeshSlot::iterator it; - GLenum drawmode; - - if (ms.m_pDerivedMesh) { - // cannot be handled here, pass to RAS_OpenGLRasterizer - RAS_OpenGLRasterizer::IndexPrimitivesInternal(ms, false); - return; - } - - if (!wireframe) - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - // use glDrawElements to draw each vertexarray - for (ms.begin(it); !ms.end(it); ms.next(it)) { - if (it.totindex == 0) - continue; - - // drawing mode - if (it.array->m_type == RAS_DisplayArray::TRIANGLE) - drawmode = GL_TRIANGLES; - else if (it.array->m_type == RAS_DisplayArray::QUAD) - drawmode = GL_QUADS; - else - drawmode = GL_LINES; - - // colors - if (drawmode != GL_LINES && !wireframe) { - if (ms.m_bObjectColor) { - const MT_Vector4& rgba = ms.m_RGBAcolor; - - glDisableClientState(GL_COLOR_ARRAY); - glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); - } - else { - glColor4f(0.0f, 0.0f, 0.0f, 1.0f); - glEnableClientState(GL_COLOR_ARRAY); - } - } - else - glColor4f(0.0f, 0.0f, 0.0f, 1.0f); - - glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ()); - glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal()); - if (!wireframe) { - glTexCoordPointer(2, GL_FLOAT, stride, it.vertex->getUV1()); - if (glIsEnabled(GL_COLOR_ARRAY)) - glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA()); - } - - // here the actual drawing takes places - glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index); - } - - if (!wireframe) { - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - } -} - -void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms) -{ - static const GLsizei stride = sizeof(RAS_TexVert); - bool wireframe = m_drawingmode <= KX_WIREFRAME; - RAS_MeshSlot::iterator it; - GLenum drawmode; - - if (ms.m_pDerivedMesh) { - // cannot be handled here, pass to RAS_OpenGLRasterizer - RAS_OpenGLRasterizer::IndexPrimitivesInternal(ms, true); - return; - } - - if (!wireframe) - EnableTextures(true); - - // use glDrawElements to draw each vertexarray - for (ms.begin(it); !ms.end(it); ms.next(it)) { - if (it.totindex == 0) - continue; - - // drawing mode - if (it.array->m_type == RAS_DisplayArray::TRIANGLE) - drawmode = GL_TRIANGLES; - else if (it.array->m_type == RAS_DisplayArray::QUAD) - drawmode = GL_QUADS; - else - drawmode = GL_LINES; - - // colors - if (drawmode != GL_LINES && !wireframe) { - if (ms.m_bObjectColor) { - const MT_Vector4& rgba = ms.m_RGBAcolor; - - glDisableClientState(GL_COLOR_ARRAY); - glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); - } - else { - glColor4f(0.0f, 0.0f, 0.0f, 1.0f); - glEnableClientState(GL_COLOR_ARRAY); - } - } - else - glColor4f(0.0f, 0.0f, 0.0f, 1.0f); - - glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ()); - glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal()); - if (!wireframe) { - TexCoordPtr(it.vertex); - if (glIsEnabled(GL_COLOR_ARRAY)) - glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA()); - } - - // here the actual drawing takes places - glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index); - } - - if (!wireframe) { - glDisableClientState(GL_COLOR_ARRAY); - EnableTextures(false); - } -} - -void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv) -{ - /* note: this function must closely match EnableTextures to enable/disable - * the right arrays, otherwise coordinate and attribute pointers from other - * materials can still be used and cause crashes */ - int unit; - - if (GLEW_ARB_multitexture) - { - for (unit=0; unit<m_texco_num; unit++) - { - glClientActiveTextureARB(GL_TEXTURE0_ARB+unit); - if (tv->getFlag() & RAS_TexVert::SECOND_UV && (int)tv->getUnit() == unit) { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert), tv->getUV2()); - continue; - } - switch (m_texco[unit]) { - case RAS_TEXCO_ORCO: - case RAS_TEXCO_GLOB: - glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getXYZ()); - break; - case RAS_TEXCO_UV1: - glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV1()); - break; - case RAS_TEXCO_NORM: - glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getNormal()); - break; - case RAS_TEXTANGENT: - glTexCoordPointer(4, GL_FLOAT, sizeof(RAS_TexVert),tv->getTangent()); - break; - case RAS_TEXCO_UV2: - glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV2()); - break; - default: - break; - } - } - - glClientActiveTextureARB(GL_TEXTURE0_ARB); - } - - if (GLEW_ARB_vertex_program) { - for (unit=0; unit<m_attrib_num; unit++) { - switch (m_attrib[unit]) { - case RAS_TEXCO_ORCO: - case RAS_TEXCO_GLOB: - glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getXYZ()); - break; - case RAS_TEXCO_UV1: - glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV1()); - break; - case RAS_TEXCO_NORM: - glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal()); - break; - case RAS_TEXTANGENT: - glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent()); - break; - case RAS_TEXCO_UV2: - glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV2()); - break; - case RAS_TEXCO_VCOL: - glVertexAttribPointerARB(unit, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(RAS_TexVert), tv->getRGBA()); - break; - default: - break; - } - } - } -} - -void RAS_VAOpenGLRasterizer::EnableTextures(bool enable) -{ - TexCoGen *texco, *attrib; - int unit, texco_num, attrib_num; - - /* we cache last texcoords and attribs to ensure we disable the ones that - * were actually last set */ - if (enable) { - texco = m_texco; - texco_num = m_texco_num; - attrib = m_attrib; - attrib_num = m_attrib_num; - - memcpy(m_last_texco, m_texco, sizeof(TexCoGen)*m_texco_num); - m_last_texco_num = m_texco_num; - memcpy(m_last_attrib, m_attrib, sizeof(TexCoGen)*m_attrib_num); - m_last_attrib_num = m_attrib_num; - } - else { - texco = m_last_texco; - texco_num = m_last_texco_num; - attrib = m_last_attrib; - attrib_num = m_last_attrib_num; - } - - if (GLEW_ARB_multitexture) { - for (unit=0; unit<texco_num; unit++) { - glClientActiveTextureARB(GL_TEXTURE0_ARB+unit); - - switch (texco[unit]) { - case RAS_TEXCO_ORCO: - case RAS_TEXCO_GLOB: - case RAS_TEXCO_UV1: - case RAS_TEXCO_NORM: - case RAS_TEXTANGENT: - case RAS_TEXCO_UV2: - if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY); - else glDisableClientState(GL_TEXTURE_COORD_ARRAY); - break; - default: - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - break; - } - } - - glClientActiveTextureARB(GL_TEXTURE0_ARB); - } - else { - if (texco_num) { - if (enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY); - else glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - } - - if (GLEW_ARB_vertex_program) { - for (unit=0; unit<attrib_num; unit++) { - switch (attrib[unit]) { - case RAS_TEXCO_ORCO: - case RAS_TEXCO_GLOB: - case RAS_TEXCO_UV1: - case RAS_TEXCO_NORM: - case RAS_TEXTANGENT: - case RAS_TEXCO_UV2: - case RAS_TEXCO_VCOL: - if (enable) glEnableVertexAttribArrayARB(unit); - else glDisableVertexAttribArrayARB(unit); - break; - default: - glDisableVertexAttribArrayARB(unit); - break; - } - } - } - - if (!enable) { - m_last_texco_num = 0; - m_last_attrib_num = 0; - } -} - diff --git a/source/gameengine/Rasterizer/RAS_TexVert.cpp b/source/gameengine/Rasterizer/RAS_TexVert.cpp index 945644ff3e6..0a90054275b 100644 --- a/source/gameengine/Rasterizer/RAS_TexVert.cpp +++ b/source/gameengine/Rasterizer/RAS_TexVert.cpp @@ -34,8 +34,7 @@ #include "MT_Matrix4x4.h" RAS_TexVert::RAS_TexVert(const MT_Point3& xyz, - const MT_Point2& uv, - const MT_Point2& uv2, + const MT_Point2 uvs[MAX_UNIT], const MT_Vector4& tangent, const unsigned int rgba, const MT_Vector3& normal, @@ -43,8 +42,6 @@ RAS_TexVert::RAS_TexVert(const MT_Point3& xyz, const unsigned int origindex) { xyz.getValue(m_localxyz); - uv.getValue(m_uv1); - uv2.getValue(m_uv2); SetRGBA(rgba); SetNormal(normal); tangent.getValue(m_tangent); @@ -52,6 +49,11 @@ RAS_TexVert::RAS_TexVert(const MT_Point3& xyz, m_origindex = origindex; m_unit = 2; m_softBodyIndex = -1; + + for (int i = 0; i < MAX_UNIT; ++i) + { + uvs[i].getValue(m_uvs[i]); + } } const MT_Point3& RAS_TexVert::xyz() @@ -80,26 +82,15 @@ void RAS_TexVert::SetXYZ(const float xyz[3]) m_localxyz[0] = xyz[0]; m_localxyz[1] = xyz[1]; m_localxyz[2] = xyz[2]; } -void RAS_TexVert::SetUV1(const MT_Point2& uv) -{ - uv.getValue(m_uv1); -} - -void RAS_TexVert::SetUV1(const float uv[3]) +void RAS_TexVert::SetUV(int index, const MT_Point2& uv) { - m_uv1[0] = uv[0]; - m_uv1[1] = uv[1]; + uv.getValue(m_uvs[index]); } -void RAS_TexVert::SetUV2(const MT_Point2& uv) +void RAS_TexVert::SetUV(int index, const float uv[2]) { - uv.getValue(m_uv2); -} - -void RAS_TexVert::SetUV2(const float uv[3]) -{ - m_uv2[0] = uv[0]; - m_uv2[1] = uv[1]; + m_uvs[index][0] = uv[0]; + m_uvs[index][1] = uv[1]; } void RAS_TexVert::SetRGBA(const unsigned int rgba) @@ -132,14 +123,17 @@ void RAS_TexVert::SetTangent(const MT_Vector3& tangent) // compare two vertices, and return TRUE if both are almost identical (they can be shared) bool RAS_TexVert::closeTo(const RAS_TexVert* other) { + bool uv_match = true; + for (int i=0; i<MAX_UNIT; i++) + uv_match = uv_match && MT_fuzzyEqual(MT_Vector2(m_uvs[i]), MT_Vector2(other->m_uvs[i])); + return ( /* m_flag == other->m_flag && */ /* at the moment the face only stores the smooth/flat setting so don't bother comparing it */ m_rgba == other->m_rgba && MT_fuzzyEqual(MT_Vector3(m_normal), MT_Vector3(other->m_normal)) && MT_fuzzyEqual(MT_Vector3(m_tangent), MT_Vector3(other->m_tangent)) && - MT_fuzzyEqual(MT_Vector2(m_uv1), MT_Vector2(other->m_uv1)) && - MT_fuzzyEqual(MT_Vector2(m_uv2), MT_Vector2(other->m_uv2)) /* && + uv_match /* && MT_fuzzyEqual(MT_Vector3(m_localxyz), MT_Vector3(other->m_localxyz))*/); /* don't bother comparing m_localxyz since we know there from the same vert */ } @@ -162,12 +156,7 @@ void RAS_TexVert::Transform(const MT_Matrix4x4& mat, const MT_Matrix4x4& nmat) SetTangent((nmat*MT_Vector4(m_tangent[0], m_tangent[1], m_tangent[2], 1.0)).getValue()); } -void RAS_TexVert::TransformUV1(const MT_Matrix4x4& mat) -{ - SetUV1((mat * MT_Vector4(m_uv1[0], m_uv1[1], 0.0, 1.0)).getValue()); -} - -void RAS_TexVert::TransformUV2(const MT_Matrix4x4& mat) +void RAS_TexVert::TransformUV(int index, const MT_Matrix4x4& mat) { - SetUV2((mat * MT_Vector4(m_uv2[0], m_uv2[1], 0.0, 1.0)).getValue()); + SetUV(index, (mat * MT_Vector4(m_uvs[index][0], m_uvs[index][1], 0.0, 1.0)).getValue()); } diff --git a/source/gameengine/Rasterizer/RAS_TexVert.h b/source/gameengine/Rasterizer/RAS_TexVert.h index 98ea4dd60aa..a91d2c7f848 100644 --- a/source/gameengine/Rasterizer/RAS_TexVert.h +++ b/source/gameengine/Rasterizer/RAS_TexVert.h @@ -48,23 +48,21 @@ class RAS_TexVert { float m_localxyz[3]; // 3*4 = 12 - float m_uv1[2]; // 2*4 = 8 - float m_uv2[2]; // 2*4 = 8 + float m_uvs[8][2]; // 8*2*4=64 //8 = MAX_UNIT unsigned int m_rgba; // 4 - float m_tangent[4]; // 4*4 = 16 - float m_normal[3]; // 3*4 = 12 + float m_tangent[4]; // 4*4 = 16 + float m_normal[3]; // 3*4 = 12 short m_flag; // 2 short m_softBodyIndex; //2 unsigned int m_unit; // 4 unsigned int m_origindex; // 4 //--------- - // 56+6+8+2=72 - // 32 bytes total size, fits nice = 56 = not fit nice. + // 120 + // 32 bytes total size, fits nice = 120 = not fit nice. public: enum { FLAT = 1, - SECOND_UV = 2, MAX_UNIT = 8 }; @@ -74,8 +72,7 @@ public: RAS_TexVert()// :m_xyz(0,0,0),m_uv(0,0),m_rgba(0) {} RAS_TexVert(const MT_Point3& xyz, - const MT_Point2& uv, - const MT_Point2& uv2, + const MT_Point2 uvs[MAX_UNIT], const MT_Vector4& tangent, const unsigned int rgba, const MT_Vector3& normal, @@ -83,12 +80,8 @@ public: const unsigned int origindex); ~RAS_TexVert() {}; - const float* getUV1 () const { - return m_uv1; - }; - - const float* getUV2 () const { - return m_uv2; + const float* getUV (int unit) const { + return m_uvs[unit]; }; const float* getXYZ() const { @@ -123,10 +116,8 @@ public: void SetXYZ(const MT_Point3& xyz); void SetXYZ(const float xyz[3]); - void SetUV1(const MT_Point2& uv); - void SetUV2(const MT_Point2& uv); - void SetUV1(const float uv[2]); - void SetUV2(const float uv[2]); + void SetUV(int index, const MT_Point2& uv); + void SetUV(int index, const float uv[2]); void SetRGBA(const unsigned int rgba); void SetNormal(const MT_Vector3& normal); @@ -139,8 +130,7 @@ public: void Transform(const class MT_Matrix4x4& mat, const class MT_Matrix4x4& nmat); - void TransformUV1(const MT_Matrix4x4& mat); - void TransformUV2(const MT_Matrix4x4& mat); + void TransformUV(int index, const MT_Matrix4x4& mat); // compare two vertices, to test if they can be shared, used for // splitting up based on uv's, colors, etc diff --git a/source/gameengine/Rasterizer/RAS_texmatrix.cpp b/source/gameengine/Rasterizer/RAS_texmatrix.cpp index d335a38171f..3203fcf9d6b 100644 --- a/source/gameengine/Rasterizer/RAS_texmatrix.cpp +++ b/source/gameengine/Rasterizer/RAS_texmatrix.cpp @@ -52,9 +52,9 @@ void RAS_CalcTexMatrix(RAS_TexVert p[3],MT_Point3& origin,MT_Vector3& udir,MT_Ve MT_Scalar d = -p[0].xyz().dot(normal); - MT_Matrix3x3 mat3( p[0].getUV1()[0],p[0].getUV1()[1], 1, - p[1].getUV1()[0],p[1].getUV1()[1], 1, - p[2].getUV1()[0],p[2].getUV1()[1], 1); + MT_Matrix3x3 mat3( p[0].getUV(0)[0],p[0].getUV(0)[1], 1, + p[1].getUV(0)[0],p[1].getUV(0)[1], 1, + p[2].getUV(0)[0],p[2].getUV(0)[1], 1); MT_Matrix3x3 mat3inv = mat3.inverse(); diff --git a/source/gameengine/Rasterizer/SConscript b/source/gameengine/Rasterizer/SConscript index 4164271ba9b..438e95391bb 100644 --- a/source/gameengine/Rasterizer/SConscript +++ b/source/gameengine/Rasterizer/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('*.cpp') diff --git a/source/gameengine/SConscript b/source/gameengine/SConscript index aebbf4d9fcf..3db973d9406 100644 --- a/source/gameengine/SConscript +++ b/source/gameengine/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') SConscript(['BlenderRoutines/SConscript', diff --git a/source/gameengine/SceneGraph/SConscript b/source/gameengine/SceneGraph/SConscript index 9270169199e..c88a2d6280b 100644 --- a/source/gameengine/SceneGraph/SConscript +++ b/source/gameengine/SceneGraph/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/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript index e66284948ed..ac8082e0d09 100644 --- a/source/gameengine/VideoTexture/SConscript +++ b/source/gameengine/VideoTexture/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 sys Import ('env') diff --git a/source/icons/SConscript b/source/icons/SConscript index 4bb27a7d4fb..443f6454417 100644 --- a/source/icons/SConscript +++ b/source/icons/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') import btools |