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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h3
-rw-r--r--source/blender/blenkernel/BKE_animsys.h2
-rw-r--r--source/blender/blenkernel/BKE_appdir.h80
-rw-r--r--source/blender/blenkernel/BKE_blender.h2
-rw-r--r--source/blender/blenkernel/BKE_context.h11
-rw-r--r--source/blender/blenkernel/BKE_curve.h5
-rw-r--r--source/blender/blenkernel/BKE_customdata.h2
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h5
-rw-r--r--source/blender/blenkernel/BKE_gpencil.h9
-rw-r--r--source/blender/blenkernel/BKE_idprop.h12
-rw-r--r--source/blender/blenkernel/BKE_image.h1
-rw-r--r--source/blender/blenkernel/BKE_key.h32
-rw-r--r--source/blender/blenkernel/BKE_movieclip.h1
-rw-r--r--source/blender/blenkernel/BKE_object_deform.h43
-rw-r--r--source/blender/blenkernel/BKE_particle.h2
-rw-r--r--source/blender/blenkernel/BKE_scene.h4
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h23
-rw-r--r--source/blender/blenkernel/BKE_sound.h4
-rw-r--r--source/blender/blenkernel/BKE_tracking.h21
-rw-r--r--source/blender/blenkernel/CMakeLists.txt17
-rw-r--r--source/blender/blenkernel/SConscript5
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c42
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.h22
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c22
-rw-r--r--source/blender/blenkernel/intern/action.c6
-rw-r--r--source/blender/blenkernel/intern/addon.c6
-rw-r--r--source/blender/blenkernel/intern/anim.c3
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c38
-rw-r--r--source/blender/blenkernel/intern/appdir.c808
-rw-r--r--source/blender/blenkernel/intern/armature.c14
-rw-r--r--source/blender/blenkernel/intern/autoexec.c5
-rw-r--r--source/blender/blenkernel/intern/blender.c23
-rw-r--r--source/blender/blenkernel/intern/boids.c2
-rw-r--r--source/blender/blenkernel/intern/brush.c4
-rw-r--r--source/blender/blenkernel/intern/camera.c2
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c1040
-rw-r--r--source/blender/blenkernel/intern/cloth.c2
-rw-r--r--source/blender/blenkernel/intern/collision.c2
-rw-r--r--source/blender/blenkernel/intern/colortools.c1
-rw-r--r--source/blender/blenkernel/intern/constraint.c83
-rw-r--r--source/blender/blenkernel/intern/context.c36
-rw-r--r--source/blender/blenkernel/intern/curve.c6
-rw-r--r--source/blender/blenkernel/intern/customdata.c119
-rw-r--r--source/blender/blenkernel/intern/deform.c4
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c9
-rw-r--r--source/blender/blenkernel/intern/displist.c6
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c43
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c19
-rw-r--r--source/blender/blenkernel/intern/fcurve.c55
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c14
-rw-r--r--source/blender/blenkernel/intern/freestyle.c2
-rw-r--r--source/blender/blenkernel/intern/gpencil.c60
-rw-r--r--source/blender/blenkernel/intern/idprop.c173
-rw-r--r--source/blender/blenkernel/intern/image.c30
-rw-r--r--source/blender/blenkernel/intern/implicit.c214
-rw-r--r--source/blender/blenkernel/intern/ipo.c2
-rw-r--r--source/blender/blenkernel/intern/key.c481
-rw-r--r--source/blender/blenkernel/intern/lamp.c1
-rw-r--r--source/blender/blenkernel/intern/lattice.c18
-rw-r--r--source/blender/blenkernel/intern/linestyle.c2
-rw-r--r--source/blender/blenkernel/intern/mask.c13
-rw-r--r--source/blender/blenkernel/intern/mask_evaluate.c2
-rw-r--r--source/blender/blenkernel/intern/mask_rasterize.c6
-rw-r--r--source/blender/blenkernel/intern/material.c16
-rw-r--r--source/blender/blenkernel/intern/mball.c4
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c2
-rw-r--r--source/blender/blenkernel/intern/modifier.c6
-rw-r--r--source/blender/blenkernel/intern/movieclip.c23
-rw-r--r--source/blender/blenkernel/intern/multires.c18
-rw-r--r--source/blender/blenkernel/intern/nla.c74
-rw-r--r--source/blender/blenkernel/intern/node.c8
-rw-r--r--source/blender/blenkernel/intern/object.c130
-rw-r--r--source/blender/blenkernel/intern/object_deform.c548
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c2
-rw-r--r--source/blender/blenkernel/intern/paint.c20
-rw-r--r--source/blender/blenkernel/intern/particle.c18
-rw-r--r--source/blender/blenkernel/intern/particle_system.c32
-rw-r--r--source/blender/blenkernel/intern/pbvh.c6
-rw-r--r--source/blender/blenkernel/intern/pointcache.c35
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c10
-rw-r--r--source/blender/blenkernel/intern/scene.c83
-rw-r--r--source/blender/blenkernel/intern/sequencer.c171
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c1
-rw-r--r--source/blender/blenkernel/intern/smoke.c13
-rw-r--r--source/blender/blenkernel/intern/softbody.c4
-rw-r--r--source/blender/blenkernel/intern/sound.c49
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c167
-rw-r--r--source/blender/blenkernel/intern/text.c62
-rw-r--r--source/blender/blenkernel/intern/texture.c15
-rw-r--r--source/blender/blenkernel/intern/tracking.c47
-rw-r--r--source/blender/blenkernel/intern/tracking_auto.c568
-rw-r--r--source/blender/blenkernel/intern/tracking_detect.c1
-rw-r--r--source/blender/blenkernel/intern/tracking_region_tracker.c481
-rw-r--r--source/blender/blenkernel/intern/tracking_solver.c9
-rw-r--r--source/blender/blenkernel/intern/tracking_util.c446
-rw-r--r--source/blender/blenkernel/intern/world.c11
-rw-r--r--source/blender/blenkernel/intern/writeavi.c4
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c10
-rw-r--r--source/blender/blenkernel/tracking_private.h28
99 files changed, 4437 insertions, 2409 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 229d2fc17cd..da4fcb4eca4 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -147,6 +147,7 @@ typedef int (*DMSetMaterial)(int mat_nr, void *attribs);
typedef int (*DMCompareDrawOptions)(void *userData, int cur_index, int next_index);
typedef void (*DMSetDrawInterpOptions)(void *userData, int index, float t);
typedef DMDrawOption (*DMSetDrawOptions)(void *userData, int index);
+typedef DMDrawOption (*DMSetDrawOptionsMappedTex)(void *userData, int origindex, int mat_nr);
typedef DMDrawOption (*DMSetDrawOptionsTex)(struct MTFace *tface, const bool has_vcol, int matnr);
typedef enum DMDrawFlag {
@@ -423,7 +424,7 @@ struct DerivedMesh {
* - Drawing options too complicated to enumerate, look at code.
*/
void (*drawMappedFacesTex)(DerivedMesh *dm,
- DMSetDrawOptions setDrawOptions,
+ DMSetDrawOptionsMappedTex setDrawOptions,
DMCompareDrawOptions compareDrawOptions,
void *userData, DMDrawFlag uvflag);
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index e79822daa4d..a5109acfa56 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -106,7 +106,7 @@ void BKE_keyingsets_free(struct ListBase *list);
/* ************************************* */
/* Path Fixing API */
-/* Fix all the paths for the the given ID + Action */
+/* Fix all the paths for the given ID + Action */
void BKE_action_fix_paths_rename(struct ID *owner_id, struct bAction *act, const char *prefix, const char *oldName,
const char *newName, int oldSubscript, int newSubscript, bool verify_paths);
diff --git a/source/blender/blenkernel/BKE_appdir.h b/source/blender/blenkernel/BKE_appdir.h
new file mode 100644
index 00000000000..5e42f17be03
--- /dev/null
+++ b/source/blender/blenkernel/BKE_appdir.h
@@ -0,0 +1,80 @@
+/*
+ * ***** 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __BKE_APPDIR_H__
+#define __BKE_APPDIR_H__
+
+/** \file BKE_appdir.h
+ * \ingroup bli
+ */
+
+/* note on naming: typical _get() suffix is omitted here,
+ * since its the main purpose of the API. */
+const char *BKE_appdir_folder_default(void);
+const char *BKE_appdir_folder_id(const int folder_id, const char *subfolder);
+const char *BKE_appdir_folder_id_create(const int folder_id, const char *subfolder);
+const char *BKE_appdir_folder_id_user_notest(const int folder_id, const char *subfolder);
+const char *BKE_appdir_folder_id_version(const int folder_id, const int ver, const bool do_check);
+
+/* Initialize path to program executable */
+void BKE_appdir_program_path_init(const char *argv0);
+
+const char *BKE_appdir_program_path(void);
+const char *BKE_appdir_program_dir(void);
+
+/* Initialize path to temporary directory. */
+void BKE_tempdir_init(char *userdir);
+void BKE_tempdir_system_init(char *dir);
+
+const char *BKE_tempdir_base(void);
+const char *BKE_tempdir_session(void);
+void BKE_tempdir_session_purge(void);
+
+
+/* folder_id */
+enum {
+ /* general, will find based on user/local/system priority */
+ BLENDER_DATAFILES = 2,
+
+ /* user-specific */
+ BLENDER_USER_CONFIG = 31,
+ BLENDER_USER_DATAFILES = 32,
+ BLENDER_USER_SCRIPTS = 33,
+ BLENDER_USER_AUTOSAVE = 34,
+
+ /* system */
+ BLENDER_SYSTEM_DATAFILES = 52,
+ BLENDER_SYSTEM_SCRIPTS = 53,
+ BLENDER_SYSTEM_PYTHON = 54,
+};
+
+/* for BKE_appdir_folder_id_version only */
+enum {
+ BLENDER_RESOURCE_PATH_USER = 0,
+ BLENDER_RESOURCE_PATH_LOCAL = 1,
+ 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"
+
+#endif /* __BKE_APPDIR_H__ */
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 6c8f90c60ae..8cd4e2584c6 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 272
-#define BLENDER_SUBVERSION 1
+#define BLENDER_SUBVERSION 3
/* 262 was the last editmesh release but it has compatibility code for bmesh data */
#define BLENDER_MINVERSION 270
#define BLENDER_MINSUBVERSION 5
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index 877e376b343..ae0ef9ce314 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -56,6 +56,9 @@ struct Text;
struct ImBuf;
struct EditBone;
struct bPoseChannel;
+struct bGPdata;
+struct bGPDlayer;
+struct bGPDframe;
struct wmWindow;
struct wmWindowManager;
struct SpaceText;
@@ -275,6 +278,14 @@ struct bPoseChannel *CTX_data_active_pose_bone(const bContext *C);
int CTX_data_selected_pose_bones(const bContext *C, ListBase *list);
int CTX_data_visible_pose_bones(const bContext *C, ListBase *list);
+struct bGPdata *CTX_data_gpencil_data(const bContext *C);
+struct bGPDlayer *CTX_data_active_gpencil_layer(const bContext *C);
+struct bGPDframe *CTX_data_active_gpencil_frame(const bContext *C);
+int CTX_data_visible_gpencil_layers(const bContext *C, ListBase *list);
+int CTX_data_editable_gpencil_layers(const bContext *C, ListBase *list);
+int CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 5de7d9936e6..13a1468aee8 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -49,6 +49,7 @@ struct rctf;
typedef struct CurveCache {
ListBase disp;
ListBase bev;
+ ListBase deformed_nurbs;
struct Path *path;
} CurveCache;
@@ -84,8 +85,8 @@ void BKE_curve_texspace_get(struct Curve *cu, float r_loc[3], float r_rot[3], fl
bool BKE_curve_minmax(struct Curve *cu, bool use_radius, float min[3], float max[3]);
bool BKE_curve_center_median(struct Curve *cu, float cent[3]);
bool BKE_curve_center_bounds(struct Curve *cu, float cent[3]);
-void BKE_curve_transform_ex(struct Curve *cu, float mat[4][4], bool do_keys, const float unit_scale);
-void BKE_curve_transform(struct Curve *cu, float mat[4][4], bool do_keys);
+void BKE_curve_transform_ex(struct Curve *cu, float mat[4][4], const bool do_keys, const float unit_scale);
+void BKE_curve_transform(struct Curve *cu, float mat[4][4], const bool do_keys);
void BKE_curve_translate(struct Curve *cu, float offset[3], const bool do_keys);
void BKE_curve_material_index_remove(struct Curve *cu, int index);
void BKE_curve_material_index_clear(struct Curve *cu);
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 9a6524cc9ab..30a58891bda 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -173,6 +173,7 @@ int CustomData_number_of_layers_typemask(const struct CustomData *data, CustomDa
/* duplicate data of a layer with flag NOFREE, and remove that flag.
* returns the layer data */
void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int type, const int totelem);
+void *CustomData_duplicate_referenced_layer_n(struct CustomData *data, const int type, const int n, const int totelem);
void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
const int type, const char *name, const int totelem);
bool CustomData_is_referenced_layer(struct CustomData *data, int type);
@@ -327,6 +328,7 @@ int CustomData_sizeof(int type);
/* get the name of a layer type */
const char *CustomData_layertype_name(int type);
bool CustomData_layertype_is_singleton(int type);
+int CustomData_layertype_layers_max(const int type);
/* make sure the name of layer at index is unique */
void CustomData_set_layer_unique_name(struct CustomData *data, int index);
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index c377769b271..83783946d4f 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -44,6 +44,7 @@ struct DriverTarget;
struct FCM_EnvelopeData;
struct bContext;
+struct AnimData;
struct bAction;
struct BezTriple;
struct StructRNA;
@@ -224,10 +225,10 @@ int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix,
/* find an f-curve based on an rna property. */
struct FCurve *rna_get_fcurve(struct PointerRNA *ptr, struct PropertyRNA *prop, int rnaindex,
- struct bAction **action, bool *r_driven);
+ struct AnimData **adt, struct bAction **action, bool *r_driven);
/* Same as above, but takes a context data, temp hack needed for complex paths like texture ones. */
struct FCurve *rna_get_fcurve_context_ui(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop,
- int rnaindex, struct bAction **action, bool *r_driven);
+ int rnaindex, struct AnimData **adt, struct bAction **action, bool *r_driven);
/* Binary search algorithm for finding where to 'insert' BezTriple with given frame number.
* Returns the index to insert at (data already at that index will be offset if replace is 0)
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index 86c111653d1..084c5527f21 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -35,6 +35,7 @@ struct ListBase;
struct bGPdata;
struct bGPDlayer;
struct bGPDframe;
+struct bGPDstroke;
/* ------------ Grease-Pencil API ------------------ */
@@ -43,17 +44,15 @@ void free_gpencil_frames(struct bGPDlayer *gpl);
void free_gpencil_layers(struct ListBase *list);
void BKE_gpencil_free(struct bGPdata *gpd);
+void gpencil_stroke_sync_selection(struct bGPDstroke *gps);
+
struct bGPDframe *gpencil_frame_addnew(struct bGPDlayer *gpl, int cframe);
struct bGPDlayer *gpencil_layer_addnew(struct bGPdata *gpd, const char *name, int setactive);
struct bGPdata *gpencil_data_addnew(const char name[]);
struct bGPDframe *gpencil_frame_duplicate(struct bGPDframe *src);
struct bGPDlayer *gpencil_layer_duplicate(struct bGPDlayer *src);
-struct bGPdata *gpencil_data_duplicate(struct bGPdata *gpd);
-
-//struct bGPdata *gpencil_data_getactive(struct ScrArea *sa);
-//short gpencil_data_setactive(struct ScrArea *sa, struct bGPdata *gpd);
-//struct ScrArea *gpencil_data_findowner(struct bGPdata *gpd);
+struct bGPdata *gpencil_data_duplicate(struct bGPdata *gpd, bool internal_copy);
void gpencil_frame_delete_laststroke(struct bGPDlayer *gpl, struct bGPDframe *gpf);
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index 2ab3d84dea5..f33f3eba590 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -41,13 +41,13 @@ typedef union IDPropertyTemplate {
double d;
struct {
char *str;
- short len;
+ int len;
char subtype;
} string;
struct ID *id;
struct {
- short type;
- short len;
+ int len;
+ char type;
} array;
struct {
int matvec_size;
@@ -91,6 +91,7 @@ void IDP_SyncGroupValues(struct IDProperty *dest, const struct IDProperty *src)
void IDP_SyncGroupTypes(struct IDProperty *dest, const struct IDProperty *src, const bool do_arraylen) ATTR_NONNULL();
void IDP_ReplaceGroupInGroup(struct IDProperty *dest, const struct IDProperty *src) ATTR_NONNULL();
void IDP_ReplaceInGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL();
+void IDP_ReplaceInGroup_ex(struct IDProperty *group, struct IDProperty *prop, struct IDProperty *prop_exist);
void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overwrite) ATTR_NONNULL();
bool IDP_AddToGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL();
bool IDP_InsertToGroup(struct IDProperty *group, struct IDProperty *previous,
@@ -100,9 +101,6 @@ void IDP_FreeFromGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_N
IDProperty *IDP_GetPropertyFromGroup(struct IDProperty *prop, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
IDProperty *IDP_GetPropertyTypeFromGroup(struct IDProperty *prop, const char *name, const char type) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-void *IDP_GetGroupIterator(struct IDProperty *prop) ATTR_WARN_UNUSED_RESULT;
-IDProperty *IDP_GroupIterNext(void *vself) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-void IDP_FreeIterBeforeEnd(void *vself) ATTR_NONNULL();
/*-------- Main Functions --------*/
struct IDProperty *IDP_GetProperties(struct ID *id, const bool create_if_needed) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
@@ -112,7 +110,7 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is
bool IDP_EqualsProperties(struct IDProperty *prop1, struct IDProperty *prop2) ATTR_WARN_UNUSED_RESULT;
-struct IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+struct IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
void IDP_FreeProperty(struct IDProperty *prop);
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index dc3d9f38b21..a225a27a00b 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -162,6 +162,7 @@ void BKE_image_alpha_mode_from_extension(struct Image *image);
/* returns a new image or NULL if it can't load */
struct Image *BKE_image_load(struct Main *bmain, const char *filepath);
/* returns existing Image when filename/type is same (frame optional) */
+struct Image *BKE_image_load_exists_ex(const char *filepath, bool *r_exists);
struct Image *BKE_image_load_exists(const char *filepath);
/* adds image, adds ibuf, generates color or pattern */
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index 6183df8666d..31b2c7dc2b9 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -87,15 +87,29 @@ void BKE_key_evaluate_relative(const int start, int end, const int tot, char *ba
float **per_keyblock_weights, const int mode);
/* conversion functions */
-void BKE_key_convert_to_mesh(struct KeyBlock *kb, struct Mesh *me);
-void BKE_key_convert_from_mesh(struct Mesh *me, struct KeyBlock *kb);
-void BKE_key_convert_to_lattice(struct KeyBlock *kb, struct Lattice *lt);
-void BKE_key_convert_from_lattice(struct Lattice *lt, struct KeyBlock *kb);
-void BKE_key_convert_to_curve(struct KeyBlock *kb, struct Curve *cu, struct ListBase *nurb);
-void BKE_key_convert_from_curve(struct Curve *cu, struct KeyBlock *kb, struct ListBase *nurb);
-float (*BKE_key_convert_to_vertcos(struct Object *ob, struct KeyBlock *kb))[3];
-void BKE_key_convert_from_vertcos(struct Object *ob, struct KeyBlock *kb, float (*vertCos)[3]);
-void BKE_key_convert_from_offset(struct Object *ob, struct KeyBlock *kb, float (*ofs)[3]);
+/* Note: 'update_from' versions do not (re)allocate mem in kb, while 'convert_from' do. */
+void BKE_keyblock_update_from_lattice(struct Lattice *lt, struct KeyBlock *kb);
+void BKE_keyblock_convert_from_lattice(struct Lattice *lt, struct KeyBlock *kb);
+void BKE_keyblock_convert_to_lattice(struct KeyBlock *kb, struct Lattice *lt);
+
+void BKE_keyblock_update_from_curve(struct Curve *cu, struct KeyBlock *kb, struct ListBase *nurb);
+void BKE_keyblock_convert_from_curve(struct Curve *cu, struct KeyBlock *kb, struct ListBase *nurb);
+void BKE_keyblock_convert_to_curve(struct KeyBlock *kb, struct Curve *cu, struct ListBase *nurb);
+
+void BKE_keyblock_update_from_mesh(struct Mesh *me, struct KeyBlock *kb);
+void BKE_keyblock_convert_from_mesh(struct Mesh *me, struct KeyBlock *kb);
+void BKE_keyblock_convert_to_mesh(struct KeyBlock *kb, struct Mesh *me);
+
+void BKE_keyblock_update_from_vertcos(struct Object *ob, struct KeyBlock *kb, float (*vertCos)[3]);
+void BKE_keyblock_convert_from_vertcos(struct Object *ob, struct KeyBlock *kb, float (*vertCos)[3]);
+float (*BKE_keyblock_convert_to_vertcos(struct Object *ob, struct KeyBlock *kb))[3];
+
+void BKE_keyblock_update_from_offset(struct Object *ob, struct KeyBlock *kb, float (*ofs)[3]);
+
+/* other management */
+bool BKE_keyblock_move(struct Object *ob, int org_index, int new_index);
+
+bool BKE_keyblock_is_basis(struct Key *key, const int index);
/* key.c */
extern int slurph_opt;
diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h
index 341105cfdf7..a4aa58e22f1 100644
--- a/source/blender/blenkernel/BKE_movieclip.h
+++ b/source/blender/blenkernel/BKE_movieclip.h
@@ -46,6 +46,7 @@ void BKE_movieclip_unlink(struct Main *bmain, struct MovieClip *clip);
struct MovieClip *BKE_movieclip_file_add(struct Main *bmain, const char *name);
void BKE_movieclip_reload(struct MovieClip *clip);
void BKE_movieclip_clear_cache(struct MovieClip *clip);
+void BKE_movieclip_clear_proxy_cache(struct MovieClip *clip);
struct ImBuf *BKE_movieclip_get_ibuf(struct MovieClip *clip, struct MovieClipUser *user);
struct ImBuf *BKE_movieclip_get_postprocessed_ibuf(struct MovieClip *clip, struct MovieClipUser *user, int postprocess_flag);
diff --git a/source/blender/blenkernel/BKE_object_deform.h b/source/blender/blenkernel/BKE_object_deform.h
index 6de7ff9bc1c..0e5ad2d51c8 100644
--- a/source/blender/blenkernel/BKE_object_deform.h
+++ b/source/blender/blenkernel/BKE_object_deform.h
@@ -29,10 +29,47 @@
* used by painting and tools.
*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct Object;
+struct ID;
+struct MDeformVert;
+struct bDeformGroup;
+
+/* General vgroup operations */
+void BKE_object_defgroup_remap_update_users(struct Object *ob, int *map);
+
+bool BKE_object_defgroup_array_get(struct ID *id, struct MDeformVert **dvert_arr, int *dvert_tot);
+
+struct bDeformGroup *BKE_object_defgroup_add(struct Object *ob);
+struct bDeformGroup *BKE_object_defgroup_add_name(struct Object *ob, const char *name);
+struct MDeformVert *BKE_object_defgroup_data_create(struct ID *id);
+
+bool BKE_object_defgroup_clear(struct Object *ob, struct bDeformGroup *dg, const bool use_selection);
+bool BKE_object_defgroup_clear_all(struct Object *ob, const bool use_selection);
+
+void BKE_object_defgroup_remove(struct Object *ob, struct bDeformGroup *defgroup);
+void BKE_object_defgroup_remove_all(struct Object *ob);
+
+
+/* Select helpers */
+enum eVGroupSelect;
+bool *BKE_object_defgroup_subset_from_select_type(
+ struct Object *ob, enum eVGroupSelect subset_type, int *r_defgroup_tot, int *r_subset_count);
+void BKE_object_defgroup_subset_to_index_array(
+ const bool *defgroup_validmap, const int defgroup_tot, int *r_defgroup_subset_map);
+
+
+/* ********** */
+
+bool *BKE_object_defgroup_lock_flags_get(struct Object *ob, const int defbase_tot);
+bool *BKE_object_defgroup_validmap_get(struct Object *ob, const int defbase_tot);
+bool *BKE_object_defgroup_selected_get(struct Object *ob, int defbase_tot, int *r_dg_flags_sel_tot);
-bool *BKE_objdef_lock_flags_get(struct Object *ob, const int defbase_tot);
-bool *BKE_objdef_validmap_get(struct Object *ob, const int defbase_tot);
-bool *BKE_objdef_selected_get(struct Object *ob, int defbase_tot, int *r_dg_flags_sel_tot);
+#ifdef __cplusplus
+}
+#endif
#endif /* __BKE_OBJECT_DEFORM_H__ */
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index f84a6378fb3..204fbbf5bfc 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -378,7 +378,7 @@ void free_keyed_keys(struct ParticleSystem *psys);
void psys_free_particles(struct ParticleSystem *psys);
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_interpolate_particle(short type, struct ParticleKey keys[4], float dt, struct ParticleKey *result, bool 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][4]);
void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[4][4]);
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 1bfe0eeea0b..eac4f6a56a5 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -110,7 +110,7 @@ char *BKE_scene_find_marker_name(struct Scene *scene, int frame);
char *BKE_scene_find_last_marker_name(struct Scene *scene, int frame);
/* checks for cycle, returns 1 if it's all OK */
-int BKE_scene_validate_setscene(struct Main *bmain, struct Scene *sce);
+bool BKE_scene_validate_setscene(struct Main *bmain, struct Scene *sce);
float BKE_scene_frame_get(struct Scene *scene);
float BKE_scene_frame_get_from_ctime(struct Scene *scene, const float frame);
@@ -131,7 +131,9 @@ int get_render_shadow_samples(struct RenderData *r, int samples);
float get_render_aosss_error(struct RenderData *r, float error);
bool BKE_scene_use_new_shading_nodes(struct Scene *scene);
+
bool BKE_scene_uses_blender_internal(struct Scene *scene);
+bool BKE_scene_uses_blender_game(struct Scene *scene);
void BKE_scene_disable_color_management(struct Scene *scene);
bool BKE_scene_check_color_management_enabled(const struct Scene *scene);
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index 13cc5d2e84f..5a0c7ac1ce1 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -217,6 +217,10 @@ void BKE_sequence_clipboard_pointers_free(struct Sequence *seq);
void BKE_sequence_clipboard_pointers_store(struct Sequence *seq);
void BKE_sequence_clipboard_pointers_restore(struct Sequence *seq, struct Main *bmain);
+void BKE_sequencer_base_clipboard_pointers_free(struct ListBase *seqbase);
+void BKE_sequencer_base_clipboard_pointers_store(struct ListBase *seqbase);
+void BKE_sequencer_base_clipboard_pointers_restore(struct ListBase *seqbase, struct Main *bmain);
+
void BKE_sequence_free(struct Scene *scene, struct Sequence *seq);
const char *BKE_sequence_give_name(struct Sequence *seq);
void BKE_sequence_calc(struct Scene *scene, struct Sequence *seq);
@@ -308,7 +312,7 @@ void BKE_sequencer_offset_animdata(struct Scene *scene, struct Sequence *seq, in
void BKE_sequencer_dupe_animdata(struct Scene *scene, const char *name_src, const char *name_dst);
bool BKE_sequence_base_shuffle(struct ListBase *seqbasep, struct Sequence *test, struct Scene *evil_scene);
bool BKE_sequence_base_shuffle_time(ListBase *seqbasep, struct Scene *evil_scene);
-bool BKE_sequence_base_isolated_sel_check(struct ListBase *seqbase, bool one_only);
+bool BKE_sequence_base_isolated_sel_check(struct ListBase *seqbase);
void BKE_sequencer_free_imbuf(struct Scene *scene, struct ListBase *seqbasep, bool for_render);
struct Sequence *BKE_sequence_dupli_recursive(struct Scene *scene, struct Scene *scene_to, struct Sequence *seq, int dupe_flag);
int BKE_sequence_swap(struct Sequence *seq_a, struct Sequence *seq_b, const char **error_str);
@@ -326,7 +330,9 @@ void BKE_sequencer_update_sound(struct Scene *scene, struct bSound *sound);
void BKE_sequencer_refresh_sound_length(struct Scene *scene);
void BKE_sequence_base_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq);
-void BKE_sequence_base_dupli_recursive(struct Scene *scene, struct Scene *scene_to, ListBase *nseqbase, ListBase *seqbase, int dupe_flag);
+void BKE_sequence_base_dupli_recursive(
+ struct Scene *scene, struct Scene *scene_to, ListBase *nseqbase, ListBase *seqbase,
+ int dupe_flag);
bool BKE_sequence_is_valid_check(struct Sequence *seq);
void BKE_sequencer_clear_scene_in_allseqs(struct Main *bmain, struct Scene *sce);
@@ -371,12 +377,23 @@ struct Sequence *BKE_sequence_alloc(ListBase *lb, int cfra, int machine);
void BKE_sequence_alpha_mode_from_extension(struct Sequence *seq);
void BKE_sequence_init_colorspace(struct Sequence *seq);
+/* RNA enums, just to be more readable */
+enum {
+ SEQ_SIDE_NONE = 0,
+ SEQ_SIDE_LEFT,
+ SEQ_SIDE_RIGHT,
+ SEQ_SIDE_BOTH
+};
+int BKE_sequencer_find_next_prev_edit(
+ struct Scene *scene, int cfra, const short side,
+ const bool do_skip_mute, const bool do_center, const bool do_unselected);
+
struct Sequence *BKE_sequencer_add_image_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load);
struct Sequence *BKE_sequencer_add_sound_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load);
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, bool, bool, int, char[256]);
+typedef struct ImBuf *(*SequencerDrawView)(struct Scene *, struct Object *, int, int, unsigned int, int, bool, bool, bool, int, char[256]);
extern SequencerDrawView sequencer_view3d_cb;
/* copy/paste */
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index 50ca5fcdf7b..f318c74258b 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -71,8 +71,6 @@ void sound_delete(struct Main *bmain, struct bSound *sound);
void sound_cache(struct bSound *sound);
-void sound_cache_notifying(struct Main *main, struct bSound *sound);
-
void sound_delete_cache(struct bSound *sound);
void sound_load(struct Main *main, struct bSound *sound);
@@ -132,7 +130,7 @@ int sound_scene_playing(struct Scene *scene);
void sound_free_waveform(struct bSound *sound);
-void sound_read_waveform(struct bSound *sound);
+void sound_read_waveform(struct bSound *sound, bool locked, short *stop);
void sound_update_scene(struct Main *bmain, struct Scene *scene);
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
index 8bc619c1b27..e5fb60cf1b5 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -145,6 +145,9 @@ void BKE_tracking_plane_marker_delete(struct MovieTrackingPlaneTrack *plane_trac
struct MovieTrackingPlaneMarker *BKE_tracking_plane_marker_get(struct MovieTrackingPlaneTrack *plane_track, int framenr);
struct MovieTrackingPlaneMarker *BKE_tracking_plane_marker_get_exact(struct MovieTrackingPlaneTrack *plane_track, int framenr);
struct MovieTrackingPlaneMarker *BKE_tracking_plane_marker_ensure(struct MovieTrackingPlaneTrack *plane_track, int framenr);
+void BKE_tracking_plane_marker_get_subframe_corners(struct MovieTrackingPlaneTrack *plane_track,
+ float framenr,
+ float corners[4][2]);
/* **** Object **** */
struct MovieTrackingObject *BKE_tracking_object_add(struct MovieTracking *tracking, const char *name);
@@ -210,16 +213,18 @@ void BKE_tracking_disable_channels(struct ImBuf *ibuf, bool disable_red, bool di
bool disable_blue, bool grayscale);
/* **** 2D tracking **** */
-struct MovieTrackingContext *BKE_tracking_context_new(struct MovieClip *clip, struct MovieClipUser *user,
- const bool backwards, const bool sequence);
-void BKE_tracking_context_free(struct MovieTrackingContext *context);
-void BKE_tracking_context_sync(struct MovieTrackingContext *context);
-void BKE_tracking_context_sync_user(const struct MovieTrackingContext *context, struct MovieClipUser *user);
-bool BKE_tracking_context_step(struct MovieTrackingContext *context);
-void BKE_tracking_context_finish(struct MovieTrackingContext *context);
-
void BKE_tracking_refine_marker(struct MovieClip *clip, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, bool backwards);
+/* *** 2D auto track *** */
+
+struct AutoTrackContext *BKE_autotrack_context_new(struct MovieClip *clip, struct MovieClipUser *user,
+ const bool backwards, const bool sequence);
+bool BKE_autotrack_context_step(struct AutoTrackContext *context);
+void BKE_autotrack_context_sync(struct AutoTrackContext *context);
+void BKE_autotrack_context_sync_user(struct AutoTrackContext *context, struct MovieClipUser *user);
+void BKE_autotrack_context_finish(struct AutoTrackContext *context);
+void BKE_autotrack_context_free(struct AutoTrackContext *context);
+
/* **** Plane tracking **** */
void BKE_tracking_track_plane_from_existing_motion(struct MovieTrackingPlaneTrack *plane_track, int start_frame);
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index f4a3a0c10dd..5850b1614e7 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -37,6 +37,7 @@ set(INC
../modifiers
../nodes
../render/extern/include
+ ../../../intern/ghost
../../../intern/guardedalloc
../../../intern/glew-mx
../../../intern/iksolver/extern
@@ -63,6 +64,7 @@ set(SRC
intern/addon.c
intern/anim.c
intern/anim_sys.c
+ intern/appdir.c
intern/armature.c
intern/autoexec.c
intern/blender.c
@@ -158,6 +160,7 @@ set(SRC
intern/text.c
intern/texture.c
intern/tracking.c
+ intern/tracking_auto.c
intern/tracking_detect.c
intern/tracking_plane_tracker.c
intern/tracking_region_tracker.c
@@ -175,6 +178,7 @@ set(SRC
BKE_addon.h
BKE_anim.h
BKE_animsys.h
+ BKE_appdir.h
BKE_armature.h
BKE_autoexec.h
BKE_blender.h
@@ -273,8 +277,21 @@ set(SRC
intern/pbvh_intern.h
)
+if(WITH_BINRELOC)
+ list(APPEND INC_SYS
+ ${BINRELOC_INCLUDE_DIRS}
+ )
+ add_definitions(-DWITH_BINRELOC)
+endif()
+
add_definitions(${GL_DEFINITIONS})
+if(WIN32)
+ list(APPEND INC
+ ../../../intern/utfconv
+ )
+endif()
+
if(WITH_AUDASPACE)
list(APPEND INC
../../../intern/audaspace/intern
diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript
index 9243c85167b..3da3d647275 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -46,6 +46,7 @@ incs = [
'#/intern/rigidbody',
'#/extern/bullet2/src',
env['BF_GLEW_INC'],
+ '#/intern/ghost',
'#/intern/glew-mx',
'#/intern/audaspace/intern',
'#/intern/elbeem/extern',
@@ -167,7 +168,11 @@ if env['WITH_BF_FREESTYLE']:
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
incs += ' ' + env['BF_PTHREADS_INC']
+ incs += ' ../../../intern/utfconv'
+if env['WITH_BF_BINRELOC']:
+ incs += ' #extern/binreloc/include'
+ defs.append('WITH_BINRELOC')
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
env.BlenderLib ( libname = 'bf_blenkernel', sources = sources, includes = Split(incs), defines = defs, libtype=['core','player'], priority = [166,25]) #, cc_compileflags = env['CCFLAGS'].append('/WX') )
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index 623fb50b62c..9e5d4afffe2 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -172,29 +172,19 @@ static void *_ehash_lookup(EHash *eh, void *key)
/**/
-typedef struct _EHashIterator {
- EHash *eh;
- int curBucket;
- EHEntry *curEntry;
-} EHashIterator;
-
-static EHashIterator *_ehashIterator_new(EHash *eh)
+static void _ehashIterator_init(EHash *eh, EHashIterator *ehi)
{
- EHashIterator *ehi = EHASH_alloc(eh, sizeof(*ehi));
+ /* fill all members */
ehi->eh = eh;
- ehi->curEntry = NULL;
ehi->curBucket = -1;
+ ehi->curEntry = NULL;
+
while (!ehi->curEntry) {
ehi->curBucket++;
if (ehi->curBucket == ehi->eh->curSize)
break;
ehi->curEntry = ehi->eh->buckets[ehi->curBucket];
}
- return ehi;
-}
-static void _ehashIterator_free(EHashIterator *ehi)
-{
- EHASH_free(ehi->eh, ehi);
}
static void *_ehashIterator_getCurrent(EHashIterator *ehi)
@@ -3051,17 +3041,17 @@ void *ccgSubSurf_getFaceGridData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int
/*** External API iterator functions ***/
-CCGVertIterator *ccgSubSurf_getVertIterator(CCGSubSurf *ss)
+void ccgSubSurf_initVertIterator(CCGSubSurf *ss, CCGVertIterator *viter)
{
- return (CCGVertIterator *) _ehashIterator_new(ss->vMap);
+ _ehashIterator_init(ss->vMap, viter);
}
-CCGEdgeIterator *ccgSubSurf_getEdgeIterator(CCGSubSurf *ss)
+void ccgSubSurf_initEdgeIterator(CCGSubSurf *ss, CCGEdgeIterator *eiter)
{
- return (CCGEdgeIterator *) _ehashIterator_new(ss->eMap);
+ _ehashIterator_init(ss->eMap, eiter);
}
-CCGFaceIterator *ccgSubSurf_getFaceIterator(CCGSubSurf *ss)
+void ccgSubSurf_initFaceIterator(CCGSubSurf *ss, CCGFaceIterator *fiter)
{
- return (CCGFaceIterator *) _ehashIterator_new(ss->fMap);
+ _ehashIterator_init(ss->fMap, fiter);
}
CCGVert *ccgVertIterator_getCurrent(CCGVertIterator *vi)
@@ -3076,10 +3066,6 @@ void ccgVertIterator_next(CCGVertIterator *vi)
{
_ehashIterator_next((EHashIterator *) vi);
}
-void ccgVertIterator_free(CCGVertIterator *vi)
-{
- _ehashIterator_free((EHashIterator *) vi);
-}
CCGEdge *ccgEdgeIterator_getCurrent(CCGEdgeIterator *vi)
{
@@ -3093,10 +3079,6 @@ void ccgEdgeIterator_next(CCGEdgeIterator *vi)
{
_ehashIterator_next((EHashIterator *) vi);
}
-void ccgEdgeIterator_free(CCGEdgeIterator *vi)
-{
- _ehashIterator_free((EHashIterator *) vi);
-}
CCGFace *ccgFaceIterator_getCurrent(CCGFaceIterator *vi)
{
@@ -3110,10 +3092,6 @@ void ccgFaceIterator_next(CCGFaceIterator *vi)
{
_ehashIterator_next((EHashIterator *) vi);
}
-void ccgFaceIterator_free(CCGFaceIterator *vi)
-{
- _ehashIterator_free((EHashIterator *) vi);
-}
/*** Extern API final vert/edge/face interface ***/
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h
index fdf6d2df99f..2b86a2a66b2 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf.h
@@ -53,6 +53,13 @@ typedef struct CCGAllocatorIFC {
void (*release) (CCGAllocatorHDL a);
} CCGAllocatorIFC;
+/* private, so we can allocate on the stack */
+typedef struct _EHashIterator {
+ struct _EHash *eh;
+ int curBucket;
+ struct _EHEntry *curEntry;
+} EHashIterator;
+
/***/
typedef enum {
@@ -163,27 +170,24 @@ int ccgSubSurf_getNumFinalFaces (const CCGSubSurf *ss);
/***/
-typedef struct CCGVertIterator CCGVertIterator;
-typedef struct CCGEdgeIterator CCGEdgeIterator;
-typedef struct CCGFaceIterator CCGFaceIterator;
+typedef struct _EHashIterator CCGVertIterator;
+typedef struct _EHashIterator CCGEdgeIterator;
+typedef struct _EHashIterator CCGFaceIterator;
-CCGVertIterator* ccgSubSurf_getVertIterator (CCGSubSurf *ss);
-CCGEdgeIterator* ccgSubSurf_getEdgeIterator (CCGSubSurf *ss);
-CCGFaceIterator* ccgSubSurf_getFaceIterator (CCGSubSurf *ss);
+void ccgSubSurf_initVertIterator(CCGSubSurf *ss, CCGVertIterator *viter);
+void ccgSubSurf_initEdgeIterator(CCGSubSurf *ss, CCGEdgeIterator *eiter);
+void ccgSubSurf_initFaceIterator(CCGSubSurf *ss, CCGFaceIterator *fiter);
CCGVert* ccgVertIterator_getCurrent (CCGVertIterator *vi);
int ccgVertIterator_isStopped (CCGVertIterator *vi);
void ccgVertIterator_next (CCGVertIterator *vi);
-void ccgVertIterator_free (CCGVertIterator *vi);
CCGEdge* ccgEdgeIterator_getCurrent (CCGEdgeIterator *ei);
int ccgEdgeIterator_isStopped (CCGEdgeIterator *ei);
void ccgEdgeIterator_next (CCGEdgeIterator *ei);
-void ccgEdgeIterator_free (CCGEdgeIterator *ei);
CCGFace* ccgFaceIterator_getCurrent (CCGFaceIterator *fi);
int ccgFaceIterator_isStopped (CCGFaceIterator *fi);
void ccgFaceIterator_next (CCGFaceIterator *fi);
-void ccgFaceIterator_free (CCGFaceIterator *fi);
#endif /* __CCGSUBSURF_H__ */
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 81c03d8081b..e8000a09d82 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -73,13 +73,11 @@ static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm);
#include "BLI_sys_types.h" /* for intptr_t support */
#include "GPU_buffers.h"
-#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_glew.h"
-#include "GPU_material.h"
/* very slow! enable for testing only! */
-// #define USE_MODIFIER_VALIDATE
+//#define USE_MODIFIER_VALIDATE
#ifdef USE_MODIFIER_VALIDATE
# define ASSERT_IS_VALID_DM(dm) (BLI_assert((dm == NULL) || (DM_is_valid(dm) == true)))
@@ -914,7 +912,7 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob,
if (mti->isDisabled && mti->isDisabled(md, 0)) return NULL;
if (build_shapekey_layers && me->key && (kb = BLI_findlink(&me->key->block, ob->shapenr - 1))) {
- BKE_key_convert_to_mesh(kb, me);
+ BKE_keyblock_convert_to_mesh(kb, me);
}
if (mti->type == eModifierTypeType_OnlyDeform) {
@@ -1221,14 +1219,14 @@ static void calc_weightpaint_vert_array(Object *ob, DerivedMesh *dm, int const d
unsigned int i;
/* variables for multipaint */
- const int defbase_tot = BLI_countlist(&ob->defbase);
+ const int defbase_tot = BLI_listbase_count(&ob->defbase);
const int defbase_act = ob->actdef - 1;
int defbase_sel_tot = 0;
bool *defbase_sel = NULL;
if (draw_flag & CALC_WP_MULTIPAINT) {
- defbase_sel = BKE_objdef_selected_get(ob, defbase_tot, &defbase_sel_tot);
+ defbase_sel = BKE_object_defgroup_selected_get(ob, defbase_tot, &defbase_sel_tot);
}
for (i = numVerts; i != 0; i--, wc++, dv++) {
@@ -1486,8 +1484,8 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
const bool has_multires = (mmd && mmd->sculptlvl != 0);
bool multires_applied = false;
- const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt;
- const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm);
+ const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt && !useRenderParams;
+ const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm) && !useRenderParams;
const int draw_flag = dm_drawflag_calc(scene->toolsettings);
/* Generic preview only in object mode! */
@@ -1977,10 +1975,10 @@ bool editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh *
if (!modifier_isEnabled(scene, md, required_mode)) return 0;
if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
modifier_setError(md, "Modifier requires original data, bad stack position");
- return 0;
+ return false;
}
- return 1;
+ return true;
}
static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, DerivedMesh **cage_r,
@@ -2960,7 +2958,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
a = attribs->tottface++;
if (layer != -1) {
- attribs->tface[a].array = tfdata->layers[layer].data;
+ attribs->tface[a].array = NULL;
attribs->tface[a].em_offset = ldata->layers[layer].offset;
}
else {
@@ -3007,7 +3005,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
a = attribs->totmcol++;
if (layer != -1) {
- attribs->mcol[a].array = tfdata->layers[layer].data;
+ attribs->mcol[a].array = NULL;
/* odd, store the offset for a different layer type here, but editmode draw code expects it */
attribs->mcol[a].em_offset = ldata->layers[layer].offset;
}
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index c6dcca576fb..c1173cb2391 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -966,7 +966,7 @@ bActionGroup *BKE_pose_add_group(bPose *pose, const char *name)
BLI_addtail(&pose->agroups, grp);
BLI_uniquename(&pose->agroups, grp, name, '.', offsetof(bActionGroup, name), sizeof(grp->name));
- pose->active_group = BLI_countlist(&pose->agroups);
+ pose->active_group = BLI_listbase_count(&pose->agroups);
return grp;
}
@@ -1028,12 +1028,12 @@ bool action_has_motion(const bAction *act)
if (act) {
for (fcu = act->curves.first; fcu; fcu = fcu->next) {
if (fcu->totvert)
- return 1;
+ return true;
}
}
/* nothing found */
- return 0;
+ return false;
}
/* Calculate the extents of given action */
diff --git a/source/blender/blenkernel/intern/addon.c b/source/blender/blenkernel/intern/addon.c
index 119fa266908..28667d458b8 100644
--- a/source/blender/blenkernel/intern/addon.c
+++ b/source/blender/blenkernel/intern/addon.c
@@ -29,15 +29,9 @@
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
-#include "BLI_string.h"
#include "BKE_addon.h" /* own include */
-#include "RNA_access.h"
-#include "RNA_define.h"
-
-#include "BLF_translation.h"
-
#include "MEM_guardedalloc.h"
static GHash *global_addonpreftype_hash = NULL;
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index aff99d3e1bf..b878dbe1f39 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -627,6 +627,9 @@ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float qua
if (!bl->nr) return 0;
if (bl->poly > -1) cycl = 1;
+ /* values below zero for non-cyclic curves give strange results */
+ BLI_assert(cycl || ctime >= 0.0f);
+
ctime *= (path->len - 1);
s1 = (int)floor(ctime);
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 2fb832dc72d..8e36449f214 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -83,7 +83,7 @@ bool id_type_can_have_animdata(ID *id)
{
/* sanity check */
if (id == NULL)
- return 0;
+ return false;
/* Only some ID-blocks have this info for now */
/* TODO: finish adding this for the other blocktypes */
@@ -100,13 +100,14 @@ bool id_type_can_have_animdata(ID *id)
case ID_SCE:
case ID_MC:
case ID_MSK:
+ case ID_GD:
{
- return 1;
+ return true;
}
/* no AnimData */
default:
- return 0;
+ return false;
}
}
@@ -193,20 +194,20 @@ bool BKE_animdata_set_action(ReportList *reports, ID *id, bAction *act)
/* can set */
adt->action = act;
id_us_plus((ID *)adt->action);
- ok = 1;
+ ok = true;
}
else {
/* cannot set */
BKE_reportf(reports, RPT_ERROR,
"Could not set action '%s' onto ID '%s', as it does not have suitably rooted paths "
"for this purpose", act->id.name + 2, id->name);
- /* ok = 0; */
+ /* ok = false; */
}
}
else {
/* just clearing the action... */
adt->action = NULL;
- ok = 1;
+ ok = true;
}
return ok;
@@ -289,7 +290,7 @@ bool BKE_copy_animdata_id(ID *id_to, ID *id_from, const bool do_action)
AnimData *adt;
if ((id_to && id_from) && (GS(id_to->name) != GS(id_from->name)))
- return 0;
+ return false;
BKE_free_animdata(id_to);
@@ -299,7 +300,7 @@ bool BKE_copy_animdata_id(ID *id_to, ID *id_from, const bool do_action)
iat->adt = BKE_copy_animdata(adt, do_action);
}
- return 1;
+ return true;
}
void BKE_copy_animdata_id_action(ID *id)
@@ -1031,6 +1032,9 @@ void BKE_animdata_main_cb(Main *mainptr, ID_AnimData_Edit_Callback func, void *u
/* line styles */
ANIMDATA_IDS_CB(mainptr->linestyle.first);
+
+ /* grease pencil */
+ ANIMDATA_IDS_CB(mainptr->gpencil.first);
}
/* Fix all RNA-Paths throughout the database (directly access the Global.main version)
@@ -1119,6 +1123,9 @@ void BKE_all_animdata_fix_paths_rename(ID *ref_id, const char *prefix, const cha
/* linestyles */
RENAMEFIX_ANIM_IDS(mainptr->linestyle.first);
+ /* grease pencil */
+ RENAMEFIX_ANIM_IDS(mainptr->gpencil.first);
+
/* scenes */
RENAMEFIX_ANIM_NODETREE_IDS(mainptr->scene.first, Scene);
}
@@ -1346,11 +1353,11 @@ static bool animsys_remap_path(AnimMapper *UNUSED(remap), char *path, char **dst
/* nothing suitable found, so just set dst to look at path (i.e. no alloc/free needed) */
*dst = path;
- return 0;
+ return false;
}
-/* less then 1.0 evaluates to false, use epsilon to avoid float error */
+/* less than 1.0 evaluates to false, use epsilon to avoid float error */
#define ANIMSYS_FLOAT_AS_BOOL(value) ((value) > ((1.0f - FLT_EPSILON)))
/* Write the given value to a setting using RNA, and return success */
@@ -1375,7 +1382,7 @@ static bool animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_ind
path, array_index, array_len - 1);
}
- return 0;
+ return false;
}
switch (RNA_property_type(prop)) {
@@ -1429,7 +1436,7 @@ static bool animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_ind
break;
default:
/* nothing can be done here... so it is unsuccessful? */
- return 0;
+ return false;
}
/* RNA property update disabled for now - [#28525] [#28690] [#28774] [#28777] */
@@ -1468,7 +1475,7 @@ static bool animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_ind
}
/* successful */
- return 1;
+ return true;
}
else {
/* failed to get path */
@@ -1479,7 +1486,7 @@ static bool animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_ind
(ptr->id.data) ? (((ID *)ptr->id.data)->name + 2) : "<No ID>",
path, array_index);
}
- return 0;
+ return false;
}
}
@@ -2680,6 +2687,9 @@ void BKE_animsys_evaluate_all_animation(Main *main, Scene *scene, float ctime)
/* linestyles */
EVAL_ANIM_IDS(main->linestyle.first, ADT_RECALC_ANIM);
+ /* grease pencil */
+ EVAL_ANIM_IDS(main->gpencil.first, ADT_RECALC_ANIM);
+
/* objects */
/* ADT_RECALC_ANIM doesn't need to be supplied here, since object AnimData gets
* this tagged by Depsgraph on framechange. This optimization means that objects
diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c
new file mode 100644
index 00000000000..e2e6e828335
--- /dev/null
+++ b/source/blender/blenkernel/intern/appdir.c
@@ -0,0 +1,808 @@
+/*
+ * ***** 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.
+ *
+ */
+
+/** \file blender/blenlib/intern/appdir.c
+ * \ingroup bke
+ *
+ * Access to application level directories.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "BLI_utildefines.h"
+#include "BLI_string.h"
+#include "BLI_fileops.h"
+#include "BLI_path_util.h"
+
+#include "BKE_appdir.h" /* own include */
+
+#include "GHOST_Path-api.h"
+
+#include "../blenkernel/BKE_blender.h" /* BLENDER_VERSION, bad level include (no function call) */
+
+#include "MEM_guardedalloc.h"
+
+#ifdef WIN32
+# include "utf_winfunc.h"
+# include "utfconv.h"
+# include <io.h>
+# ifdef _WIN32_IE
+# undef _WIN32_IE
+# endif
+# define _WIN32_IE 0x0501
+# include <windows.h>
+# include <shlobj.h>
+# include "BLI_winstuff.h"
+#else /* non windows */
+# ifdef WITH_BINRELOC
+# include "binreloc.h"
+# endif
+# include <unistd.h> /* mkdtemp on OSX (and probably all *BSD?), not worth making specific check for this OS. */
+#endif /* WIN32 */
+
+/* local */
+static char bprogname[FILE_MAX]; /* full path to program executable */
+static char bprogdir[FILE_MAX]; /* full path to directory in which executable is located */
+static char btempdir_base[FILE_MAX]; /* persistent temporary directory */
+static char btempdir_session[FILE_MAX] = ""; /* volatile temporary directory */
+
+/* This is now only used to really get the user's default document folder */
+/* On Windows I chose the 'Users/<MyUserName>/Documents' since it's used
+ * as default location to save documents */
+const char *BKE_appdir_folder_default(void)
+{
+#ifndef WIN32
+ const char * const xdg_documents_dir = getenv("XDG_DOCUMENTS_DIR");
+
+ if (xdg_documents_dir)
+ return xdg_documents_dir;
+
+ return getenv("HOME");
+#else /* Windows */
+ static char documentfolder[MAXPATHLEN];
+ HRESULT hResult;
+
+ /* Check for %HOME% env var */
+ if (uput_getenv("HOME", documentfolder, MAXPATHLEN)) {
+ if (BLI_is_dir(documentfolder)) return documentfolder;
+ }
+
+ /* add user profile support for WIN 2K / NT.
+ * This is %APPDATA%, which translates to either
+ * %USERPROFILE%\Application Data or since Vista
+ * to %USERPROFILE%\AppData\Roaming
+ */
+ hResult = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, documentfolder);
+
+ if (hResult == S_OK) {
+ if (BLI_is_dir(documentfolder)) return documentfolder;
+ }
+
+ return NULL;
+#endif /* WIN32 */
+}
+
+
+// #define PATH_DEBUG
+
+/* returns a formatted representation of the specified version number. Non-reentrant! */
+static char *blender_version_decimal(const int ver)
+{
+ static char version_str[5];
+ sprintf(version_str, "%d.%02d", ver / 100, ver % 100);
+ return version_str;
+}
+
+/**
+ * Concatenates path_base, (optional) path_sep and (optional) folder_name into targetpath,
+ * returning true if result points to a directory.
+ */
+static bool test_path(char *targetpath, const char *path_base, const char *path_sep, const char *folder_name)
+{
+ char tmppath[FILE_MAX];
+
+ if (path_sep) BLI_join_dirfile(tmppath, sizeof(tmppath), path_base, path_sep);
+ else BLI_strncpy(tmppath, path_base, sizeof(tmppath));
+
+ /* rare cases folder_name is omitted (when looking for ~/.blender/2.xx dir only) */
+ if (folder_name)
+ BLI_make_file_string("/", targetpath, tmppath, folder_name);
+ else
+ BLI_strncpy(targetpath, tmppath, sizeof(tmppath));
+ /* FIXME: why is "//" on front of tmppath expanded to "/" (by BLI_join_dirfile)
+ * if folder_name is specified but not otherwise? */
+
+ if (BLI_is_dir(targetpath)) {
+#ifdef PATH_DEBUG
+ printf("\t%s found: %s\n", __func__, targetpath);
+#endif
+ return true;
+ }
+ else {
+#ifdef PATH_DEBUG
+ printf("\t%s missing: %s\n", __func__, targetpath);
+#endif
+ //targetpath[0] = '\0';
+ return false;
+ }
+}
+
+/**
+ * Puts the value of the specified environment variable into *path if it exists
+ * and points at a directory. Returns true if this was done.
+ */
+static bool test_env_path(char *path, const char *envvar)
+{
+ const char *env = envvar ? getenv(envvar) : NULL;
+ if (!env) return false;
+
+ if (BLI_is_dir(env)) {
+ BLI_strncpy(path, env, FILE_MAX);
+#ifdef PATH_DEBUG
+ printf("\t%s env %s found: %s\n", __func__, envvar, env);
+#endif
+ return true;
+ }
+ else {
+ path[0] = '\0';
+#ifdef PATH_DEBUG
+ printf("\t%s env %s missing: %s\n", __func__, envvar, env);
+#endif
+ return false;
+ }
+}
+
+/**
+ * Constructs in \a targetpath the name of a directory relative to a version-specific
+ * subdirectory in the parent directory of the Blender executable.
+ *
+ * \param targetpath String to return path
+ * \param folder_name Optional folder name within version-specific directory
+ * \param subfolder_name Optional subfolder name within folder_name
+ * \param ver To construct name of version-specific directory within bprogdir
+ * \return true if such a directory exists.
+ */
+static bool get_path_local(char *targetpath, const char *folder_name, const char *subfolder_name, const int ver)
+{
+ char relfolder[FILE_MAX];
+
+#ifdef PATH_DEBUG
+ printf("%s...\n", __func__);
+#endif
+
+ if (folder_name) {
+ if (subfolder_name) {
+ BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name);
+ }
+ else {
+ BLI_strncpy(relfolder, folder_name, sizeof(relfolder));
+ }
+ }
+ else {
+ relfolder[0] = '\0';
+ }
+
+ /* try EXECUTABLE_DIR/2.5x/folder_name - new default directory for local blender installed files */
+#ifdef __APPLE__
+ static char osx_resourses[FILE_MAX]; /* due new codesign situation in OSX > 10.9.5 we must move the blender_version dir with contents to Resources */
+ sprintf(osx_resourses, "%s../Resources", bprogdir);
+ return test_path(targetpath, osx_resourses, blender_version_decimal(ver), relfolder);
+#else
+ return test_path(targetpath, bprogdir, blender_version_decimal(ver), relfolder);
+#endif
+}
+
+/**
+ * Is this an install with user files kept together with the Blender executable and its
+ * installation files.
+ */
+static bool is_portable_install(void)
+{
+ /* detect portable install by the existence of config folder */
+ const int ver = BLENDER_VERSION;
+ char path[FILE_MAX];
+
+ return get_path_local(path, "config", NULL, ver);
+}
+
+/**
+ * Returns the path of a folder within the user-files area.
+ *
+ *
+ * \param targetpath String to return path
+ * \param folder_name default name of folder within user area
+ * \param subfolder_name optional name of subfolder within folder
+ * \param envvar name of environment variable which, if defined, overrides folder_name
+ * \param ver Blender version, used to construct a subdirectory name
+ * \return true if it was able to construct such a path.
+ */
+static bool get_path_user(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver)
+{
+ char user_path[FILE_MAX];
+ const char *user_base_path;
+
+ /* for portable install, user path is always local */
+ if (is_portable_install())
+ return get_path_local(targetpath, folder_name, subfolder_name, ver);
+
+ user_path[0] = '\0';
+
+ if (test_env_path(user_path, envvar)) {
+ if (subfolder_name) {
+ return test_path(targetpath, user_path, NULL, subfolder_name);
+ }
+ else {
+ BLI_strncpy(targetpath, user_path, FILE_MAX);
+ return true;
+ }
+ }
+
+ user_base_path = (const char *)GHOST_getUserDir(ver, blender_version_decimal(ver));
+ if (user_base_path)
+ BLI_strncpy(user_path, user_base_path, FILE_MAX);
+
+ if (!user_path[0])
+ return false;
+
+#ifdef PATH_DEBUG
+ printf("%s: %s\n", __func__, user_path);
+#endif
+
+ if (subfolder_name) {
+ return test_path(targetpath, user_path, folder_name, subfolder_name);
+ }
+ else {
+ return test_path(targetpath, user_path, NULL, folder_name);
+ }
+}
+
+/**
+ * Returns the path of a folder within the Blender installation directory.
+ *
+ * \param targetpath String to return path
+ * \param folder_name default name of folder within installation area
+ * \param subfolder_name optional name of subfolder within folder
+ * \param envvar name of environment variable which, if defined, overrides folder_name
+ * \param ver Blender version, used to construct a subdirectory name
+ * \return true if it was able to construct such a path.
+ */
+static bool get_path_system(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver)
+{
+ char system_path[FILE_MAX];
+ const char *system_base_path;
+ char cwd[FILE_MAX];
+ char relfolder[FILE_MAX];
+
+ if (folder_name) {
+ if (subfolder_name) {
+ BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name);
+ }
+ else {
+ BLI_strncpy(relfolder, folder_name, sizeof(relfolder));
+ }
+ }
+ else {
+ relfolder[0] = '\0';
+ }
+
+ /* first allow developer only overrides to the system path
+ * these are only used when running blender from source */
+
+ /* try CWD/release/folder_name */
+ if (BLI_current_working_dir(cwd, sizeof(cwd))) {
+ if (test_path(targetpath, cwd, "release", relfolder)) {
+ return true;
+ }
+ }
+
+ /* try EXECUTABLE_DIR/release/folder_name */
+ if (test_path(targetpath, bprogdir, "release", relfolder))
+ return true;
+
+ /* end developer overrides */
+
+
+
+ system_path[0] = '\0';
+
+ if (test_env_path(system_path, envvar)) {
+ if (subfolder_name) {
+ return test_path(targetpath, system_path, NULL, subfolder_name);
+ }
+ else {
+ BLI_strncpy(targetpath, system_path, FILE_MAX);
+ return true;
+ }
+ }
+
+ system_base_path = (const char *)GHOST_getSystemDir(ver, blender_version_decimal(ver));
+ if (system_base_path)
+ BLI_strncpy(system_path, system_base_path, FILE_MAX);
+
+ if (!system_path[0])
+ return false;
+
+#ifdef PATH_DEBUG
+ printf("%s: %s\n", __func__, system_path);
+#endif
+
+ if (subfolder_name) {
+ /* try $BLENDERPATH/folder_name/subfolder_name */
+ return test_path(targetpath, system_path, folder_name, subfolder_name);
+ }
+ else {
+ /* try $BLENDERPATH/folder_name */
+ return test_path(targetpath, system_path, NULL, folder_name);
+ }
+}
+
+/* get a folder out of the 'folder_id' presets for paths */
+/* returns the path if found, NULL string if not */
+const char *BKE_appdir_folder_id(const int folder_id, const char *subfolder)
+{
+ const int ver = BLENDER_VERSION;
+ static char path[FILE_MAX] = "";
+
+ switch (folder_id) {
+ case BLENDER_DATAFILES: /* general case */
+ if (get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver)) break;
+ if (get_path_local(path, "datafiles", subfolder, ver)) break;
+ if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES", ver)) break;
+ return NULL;
+
+ case BLENDER_USER_DATAFILES:
+ if (get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver)) break;
+ return NULL;
+
+ case BLENDER_SYSTEM_DATAFILES:
+ if (get_path_local(path, "datafiles", subfolder, ver)) break;
+ if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES", ver)) break;
+ return NULL;
+
+ case BLENDER_USER_AUTOSAVE:
+ if (get_path_user(path, "autosave", subfolder, "BLENDER_USER_DATAFILES", ver)) break;
+ return NULL;
+
+ case BLENDER_USER_CONFIG:
+ if (get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG", ver)) break;
+ return NULL;
+
+ case BLENDER_USER_SCRIPTS:
+ if (get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS", ver)) break;
+ return NULL;
+
+ case BLENDER_SYSTEM_SCRIPTS:
+ if (get_path_local(path, "scripts", subfolder, ver)) break;
+ if (get_path_system(path, "scripts", subfolder, "BLENDER_SYSTEM_SCRIPTS", ver)) break;
+ return NULL;
+
+ case BLENDER_SYSTEM_PYTHON:
+ if (get_path_local(path, "python", subfolder, ver)) break;
+ if (get_path_system(path, "python", subfolder, "BLENDER_SYSTEM_PYTHON", ver)) break;
+ return NULL;
+
+ default:
+ BLI_assert(0);
+ break;
+ }
+
+ return path;
+}
+
+/**
+ * Returns the path to a folder in the user area without checking that it actually exists first.
+ */
+const char *BKE_appdir_folder_id_user_notest(const int folder_id, const char *subfolder)
+{
+ const int ver = BLENDER_VERSION;
+ static char path[FILE_MAX] = "";
+
+ switch (folder_id) {
+ case BLENDER_USER_DATAFILES:
+ get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver);
+ break;
+ case BLENDER_USER_CONFIG:
+ get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG", ver);
+ break;
+ case BLENDER_USER_AUTOSAVE:
+ get_path_user(path, "autosave", subfolder, "BLENDER_USER_AUTOSAVE", ver);
+ break;
+ case BLENDER_USER_SCRIPTS:
+ get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS", ver);
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+
+ if ('\0' == path[0]) {
+ return NULL;
+ }
+ return path;
+}
+
+/**
+ * Returns the path to a folder in the user area, creating it if it doesn't exist.
+ */
+const char *BKE_appdir_folder_id_create(int folder_id, const char *subfolder)
+{
+ const char *path;
+
+ /* only for user folders */
+ if (!ELEM(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_SCRIPTS, BLENDER_USER_AUTOSAVE))
+ return NULL;
+
+ path = BKE_appdir_folder_id(folder_id, subfolder);
+
+ if (!path) {
+ path = BKE_appdir_folder_id_user_notest(folder_id, subfolder);
+ if (path) BLI_dir_create_recursive(path);
+ }
+
+ return path;
+}
+
+/**
+ * Returns the path of the top-level version-specific local, user or system directory.
+ * If do_check, then the result will be NULL if the directory doesn't exist.
+ */
+const char *BKE_appdir_folder_id_version(const int folder_id, const int ver, const bool do_check)
+{
+ static char path[FILE_MAX] = "";
+ bool ok;
+ switch (folder_id) {
+ case BLENDER_RESOURCE_PATH_USER:
+ ok = get_path_user(path, NULL, NULL, NULL, ver);
+ break;
+ case BLENDER_RESOURCE_PATH_LOCAL:
+ ok = get_path_local(path, NULL, NULL, ver);
+ break;
+ case BLENDER_RESOURCE_PATH_SYSTEM:
+ ok = get_path_system(path, NULL, NULL, NULL, ver);
+ break;
+ default:
+ path[0] = '\0'; /* in case do_check is false */
+ ok = false;
+ BLI_assert(!"incorrect ID");
+ break;
+ }
+
+ if (!ok && do_check) {
+ return NULL;
+ }
+
+ return path;
+}
+
+#ifdef PATH_DEBUG
+# undef PATH_DEBUG
+#endif
+
+
+/* -------------------------------------------------------------------- */
+/* Preset paths */
+
+/**
+ * Tries appending each of the semicolon-separated extensions in the PATHEXT
+ * environment variable (Windows-only) onto *name in turn until such a file is found.
+ * Returns success/failure.
+ */
+static int add_win32_extension(char *name)
+{
+ int retval = 0;
+ int type;
+
+ type = BLI_exists(name);
+ if ((type == 0) || S_ISDIR(type)) {
+#ifdef _WIN32
+ char filename[FILE_MAX];
+ char ext[FILE_MAX];
+ const char *extensions = getenv("PATHEXT");
+ if (extensions) {
+ char *temp;
+ do {
+ strcpy(filename, name);
+ temp = strstr(extensions, ";");
+ if (temp) {
+ strncpy(ext, extensions, temp - extensions);
+ ext[temp - extensions] = 0;
+ extensions = temp + 1;
+ strcat(filename, ext);
+ }
+ else {
+ strcat(filename, extensions);
+ }
+
+ type = BLI_exists(filename);
+ if (type && (!S_ISDIR(type))) {
+ retval = 1;
+ strcpy(name, filename);
+ break;
+ }
+ } while (temp);
+ }
+#endif
+ }
+ else {
+ retval = 1;
+ }
+
+ return (retval);
+}
+
+/**
+ * Checks if name is a fully qualified filename to an executable.
+ * If not it searches $PATH for the file. On Windows it also
+ * adds the correct extension (.com .exe etc) from
+ * $PATHEXT if necessary. Also on Windows it translates
+ * the name to its 8.3 version to prevent problems with
+ * spaces and stuff. Final result is returned in fullname.
+ *
+ * \param fullname The full path and full name of the executable
+ * (must be FILE_MAX minimum)
+ * \param name The name of the executable (usually argv[0]) to be checked
+ */
+static void bli_where_am_i(char *fullname, const size_t maxlen, const char *name)
+{
+ char filename[FILE_MAX];
+ const char *path = NULL, *temp;
+
+#ifdef _WIN32
+ const char *separator = ";";
+#else
+ const char *separator = ":";
+#endif
+
+
+#ifdef WITH_BINRELOC
+ /* linux uses binreloc since argv[0] is not reliable, call br_init( NULL ) first */
+ path = br_find_exe(NULL);
+ if (path) {
+ BLI_strncpy(fullname, path, maxlen);
+ free((void *)path);
+ return;
+ }
+#endif
+
+#ifdef _WIN32
+ wchar_t *fullname_16 = MEM_mallocN(maxlen * sizeof(wchar_t), "ProgramPath");
+ if (GetModuleFileNameW(0, fullname_16, maxlen)) {
+ conv_utf_16_to_8(fullname_16, fullname, maxlen);
+ if (!BLI_exists(fullname)) {
+ printf("path can't be found: \"%.*s\"\n", (int)maxlen, fullname);
+ MessageBox(NULL, "path contains invalid characters or is too long (see console)", "Error", MB_OK);
+ }
+ MEM_freeN(fullname_16);
+ return;
+ }
+
+ MEM_freeN(fullname_16);
+#endif
+
+ /* unix and non linux */
+ if (name && name[0]) {
+
+ BLI_strncpy(fullname, name, maxlen);
+ if (name[0] == '.') {
+ char wdir[FILE_MAX] = "";
+ BLI_current_working_dir(wdir, sizeof(wdir)); /* backup cwd to restore after */
+
+ // not needed but avoids annoying /./ in name
+ if (name[1] == SEP)
+ BLI_join_dirfile(fullname, maxlen, wdir, name + 2);
+ else
+ BLI_join_dirfile(fullname, maxlen, wdir, name);
+
+ add_win32_extension(fullname); /* XXX, doesnt respect length */
+ }
+ else if (BLI_last_slash(name)) {
+ // full path
+ BLI_strncpy(fullname, name, maxlen);
+ add_win32_extension(fullname);
+ }
+ else {
+ // search for binary in $PATH
+ path = getenv("PATH");
+ if (path) {
+ do {
+ temp = strstr(path, separator);
+ if (temp) {
+ strncpy(filename, path, temp - path);
+ filename[temp - path] = 0;
+ path = temp + 1;
+ }
+ else {
+ strncpy(filename, path, sizeof(filename));
+ }
+ BLI_path_append(fullname, maxlen, name);
+ if (add_win32_extension(filename)) {
+ BLI_strncpy(fullname, filename, maxlen);
+ break;
+ }
+ } while (temp);
+ }
+ }
+#if defined(DEBUG)
+ if (strcmp(name, fullname)) {
+ printf("guessing '%s' == '%s'\n", name, fullname);
+ }
+#endif
+ }
+}
+
+void BKE_appdir_program_path_init(const char *argv0)
+{
+ bli_where_am_i(bprogname, sizeof(bprogname), argv0);
+ BLI_split_dir_part(bprogname, bprogdir, sizeof(bprogdir));
+}
+
+/**
+ * Path to executable
+ */
+const char *BKE_appdir_program_path(void)
+{
+ return bprogname;
+}
+
+/**
+ * Path to directory of executable
+ */
+const char *BKE_appdir_program_dir(void)
+{
+ return bprogdir;
+}
+
+/**
+ * Gets the temp directory when blender first runs.
+ * If the default path is not found, use try $TEMP
+ *
+ * Also make sure the temp dir has a trailing slash
+ *
+ * \param fullname The full path to the temporary temp directory
+ * \param basename The full path to the persistent temp directory (may be NULL)
+ * \param maxlen The size of the fullname buffer
+ * \param userdir Directory specified in user preferences
+ */
+static void BLI_where_is_temp(char *fullname, char *basename, const size_t maxlen, char *userdir)
+{
+ /* Clear existing temp dir, if needed. */
+ BKE_tempdir_session_purge();
+
+ fullname[0] = '\0';
+ if (basename) {
+ basename[0] = '\0';
+ }
+
+ if (userdir && BLI_is_dir(userdir)) {
+ BLI_strncpy(fullname, userdir, maxlen);
+ }
+
+
+#ifdef WIN32
+ if (fullname[0] == '\0') {
+ const char *tmp = getenv("TEMP"); /* Windows */
+ if (tmp && BLI_is_dir(tmp)) {
+ BLI_strncpy(fullname, tmp, maxlen);
+ }
+ }
+#else
+ /* Other OS's - Try TMP and TMPDIR */
+ if (fullname[0] == '\0') {
+ const char *tmp = getenv("TMP");
+ if (tmp && BLI_is_dir(tmp)) {
+ BLI_strncpy(fullname, tmp, maxlen);
+ }
+ }
+
+ if (fullname[0] == '\0') {
+ const char *tmp = getenv("TMPDIR");
+ if (tmp && BLI_is_dir(tmp)) {
+ BLI_strncpy(fullname, tmp, maxlen);
+ }
+ }
+#endif
+
+ if (fullname[0] == '\0') {
+ BLI_strncpy(fullname, "/tmp/", maxlen);
+ }
+ else {
+ /* add a trailing slash if needed */
+ BLI_add_slash(fullname);
+#ifdef WIN32
+ if (userdir && userdir != fullname) {
+ BLI_strncpy(userdir, fullname, maxlen); /* also set user pref to show %TEMP%. /tmp/ is just plain confusing for Windows users. */
+ }
+#endif
+ }
+
+ /* Now that we have a valid temp dir, add system-generated unique sub-dir. */
+ if (basename) {
+ /* 'XXXXXX' is kind of tag to be replaced by mktemp-familly by an uuid. */
+ char *tmp_name = BLI_strdupcat(fullname, "blender_XXXXXX");
+ const size_t ln = strlen(tmp_name) + 1;
+ if (ln <= maxlen) {
+#ifdef WIN32
+ if (_mktemp_s(tmp_name, ln) == 0) {
+ BLI_dir_create_recursive(tmp_name);
+ }
+#else
+ mkdtemp(tmp_name);
+#endif
+ }
+ if (BLI_is_dir(tmp_name)) {
+ BLI_strncpy(basename, fullname, maxlen);
+ BLI_strncpy(fullname, tmp_name, maxlen);
+ BLI_add_slash(fullname);
+ }
+ else {
+ printf("Warning! Could not generate a temp file name for '%s', falling back to '%s'\n", tmp_name, fullname);
+ }
+
+ MEM_freeN(tmp_name);
+ }
+}
+
+/**
+ * Sets btempdir_base to userdir if specified and is a valid directory, otherwise
+ * chooses a suitable OS-specific temporary directory.
+ * Sets btempdir_session to a mkdtemp-generated sub-dir of btempdir_base.
+ *
+ * \note On Window userdir will be set to the temporary directory!
+ */
+void BKE_tempdir_init(char *userdir)
+{
+ BLI_where_is_temp(btempdir_session, btempdir_base, FILE_MAX, userdir);
+;
+}
+
+/**
+ * Path to temporary directory (with trailing slash)
+ */
+const char *BKE_tempdir_session(void)
+{
+ return btempdir_session[0] ? btempdir_session : BKE_tempdir_base();
+}
+
+/**
+ * Path to persistent temporary directory (with trailing slash)
+ */
+const char *BKE_tempdir_base(void)
+{
+ return btempdir_base;
+}
+
+/**
+ * Path to the system temporary directory (with trailing slash)
+ */
+void BKE_tempdir_system_init(char *dir)
+{
+ BLI_where_is_temp(dir, NULL, FILE_MAX, NULL);
+}
+
+/**
+ * Delete content of this instance's temp dir.
+ */
+void BKE_tempdir_session_purge(void)
+{
+ if (btempdir_session[0] && BLI_is_dir(btempdir_session)) {
+ BLI_delete(btempdir_session, true, true);
+ }
+}
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index bb05b5de8a6..f4a5d33854a 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -840,7 +840,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float
/* bone defmats are already in the channels, chan_mat */
/* initialize B_bone matrices and dual quaternions */
- totchan = BLI_countlist(&armOb->pose->chanbase);
+ totchan = BLI_listbase_count(&armOb->pose->chanbase);
if (use_quaternion) {
dualquats = MEM_callocN(sizeof(DualQuat) * totchan, "dualquats");
@@ -866,7 +866,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float
armature_def_nr = defgroup_name_index(target, defgrp_name);
if (ELEM(target->type, OB_MESH, OB_LATTICE)) {
- defbase_tot = BLI_countlist(&target->defbase);
+ defbase_tot = BLI_listbase_count(&target->defbase);
if (target->type == OB_MESH) {
Mesh *me = target->data;
@@ -1654,6 +1654,7 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
pchanw.next = pchan->next;
pchanw.parent = pchan->parent;
pchanw.child = pchan->child;
+ pchanw.custom_tx = pchan->custom_tx;
pchanw.mpath = pchan->mpath;
pchan->mpath = NULL;
@@ -1662,7 +1663,7 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
if (pchanw.prop) {
pchanw.prop = IDP_CopyProperty(pchanw.prop);
- /* use the values from the the existing props */
+ /* use the values from the existing props */
if (pchan->prop) {
IDP_SyncGroupValues(pchanw.prop, pchan->prop);
}
@@ -1916,7 +1917,7 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos
if (ikData->points)
MEM_freeN(ikData->points);
ikData->numpoints = ikData->chainlen + 1;
- ikData->points = MEM_callocN(sizeof(float) * ikData->numpoints, "Spline IK Binding");
+ ikData->points = MEM_mallocN(sizeof(float) * ikData->numpoints, "Spline IK Binding");
/* bind 'tip' of chain (i.e. first joint = tip of bone with the Spline IK Constraint) */
ikData->points[0] = 1.0f;
@@ -1944,6 +1945,9 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos
ikData->flag |= CONSTRAINT_SPLINEIK_BOUND;
}
+ /* disallow negative values (happens with float precision) */
+ CLAMP_MIN(ikData->points[segcount], 0.0f);
+
/* apply corrections for sensitivity to scaling on a copy of the bind points,
* since it's easier to determine the positions of all the joints beforehand this way
*/
@@ -1989,7 +1993,7 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos
tree->chainlen = segcount;
/* copy over the array of links to bones in the chain (from tip to root) */
- tree->chain = MEM_callocN(sizeof(bPoseChannel *) * segcount, "SplineIK Chain");
+ tree->chain = MEM_mallocN(sizeof(bPoseChannel *) * segcount, "SplineIK Chain");
memcpy(tree->chain, pchanChain, sizeof(bPoseChannel *) * segcount);
/* store reference to joint position array */
diff --git a/source/blender/blenkernel/intern/autoexec.c b/source/blender/blenkernel/intern/autoexec.c
index 872780bd50a..d9462cd0262 100644
--- a/source/blender/blenkernel/intern/autoexec.c
+++ b/source/blender/blenkernel/intern/autoexec.c
@@ -34,9 +34,12 @@
#include "BLI_utildefines.h"
#include "BLI_fnmatch.h"
-#include "BLI_string.h"
#include "BLI_path_util.h"
+#ifdef WIN32
+# include "BLI_string.h"
+#endif
+
#include "BKE_autoexec.h" /* own include */
/**
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index adfe43cb2a3..96f769587d9 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -61,6 +61,7 @@
#include "IMB_imbuf.h"
#include "IMB_moviecache.h"
+#include "BKE_appdir.h"
#include "BKE_blender.h"
#include "BKE_bpath.h"
#include "BKE_brush.h"
@@ -493,10 +494,11 @@ bool BKE_read_file_from_memory(
BLO_update_defaults_startup_blend(bfd->main);
setup_app_data(C, bfd, "<memory2>");
}
- else
+ else {
BKE_reports_prepend(reports, "Loading failed: ");
+ }
- return (bfd ? 1 : 0);
+ return (bfd != NULL);
}
/* memfile is the undo buffer */
@@ -516,10 +518,11 @@ bool BKE_read_file_from_memfile(
setup_app_data(C, bfd, "<memory1>");
}
- else
+ else {
BKE_reports_prepend(reports, "Loading failed: ");
+ }
- return (bfd ? 1 : 0);
+ return (bfd != NULL);
}
/* only read the userdef from a .blend */
@@ -687,7 +690,7 @@ void BKE_write_undo(bContext *C, const char *name)
counter = counter % U.undosteps;
BLI_snprintf(numstr, sizeof(numstr), "%d.blend", counter);
- BLI_make_file_string("/", filepath, BLI_temp_dir_session(), numstr);
+ BLI_make_file_string("/", filepath, BKE_tempdir_session(), numstr);
/* success = */ /* UNUSED */ BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL);
@@ -834,13 +837,13 @@ bool BKE_undo_save_file(const char *filename)
int file, oflags;
if ((U.uiflag & USER_GLOBALUNDO) == 0) {
- return 0;
+ return false;
}
uel = curundo;
if (uel == NULL) {
fprintf(stderr, "No undo buffer to save recovery file\n");
- return 0;
+ return false;
}
/* note: This is currently used for autosave and 'quit.blend', where _not_ following symlinks is OK,
@@ -862,7 +865,7 @@ bool BKE_undo_save_file(const char *filename)
if (file == -1) {
fprintf(stderr, "Unable to save '%s': %s\n",
filename, errno ? strerror(errno) : "Unknown error opening file");
- return 0;
+ return false;
}
for (chunk = uel->memfile.chunks.first; chunk; chunk = chunk->next) {
@@ -876,9 +879,9 @@ bool BKE_undo_save_file(const char *filename)
if (chunk) {
fprintf(stderr, "Unable to save '%s': %s\n",
filename, errno ? strerror(errno) : "Unknown error writing file");
- return 0;
+ return false;
}
- return 1;
+ return true;
}
/* sets curscene */
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index 5731455fc01..4a564614ff3 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -995,7 +995,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
case eBoidRulesetType_Random:
{
/* use random rule for each particle (allways same for same particle though) */
- rule = BLI_findlink(&state->rules, rand % BLI_countlist(&state->rules));
+ rule = BLI_findlink(&state->rules, rand % BLI_listbase_count(&state->rules));
apply_boid_rule(bbd, rule, &val, pa, -1.0);
break;
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index ae6ae6087af..92f66cdde76 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -33,7 +33,6 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_rand.h"
-#include "BLI_rect.h"
#include "BKE_brush.h"
#include "BKE_colortools.h"
@@ -49,7 +48,6 @@
#include "IMB_imbuf_types.h"
#include "RE_render_ext.h" /* externtex */
-#include "RE_shader_ext.h"
static RNG *brush_rng;
@@ -1048,7 +1046,7 @@ struct ImBuf *BKE_brush_gen_radial_control_imbuf(Brush *br, bool secondary)
for (i = 0; i < side; ++i) {
for (j = 0; j < side; ++j) {
- float magn = sqrtf(powf(i - half, 2) + powf(j - half, 2));
+ float magn = sqrtf(pow2f(i - half) + pow2f(j - half));
im->rect_float[i * side + j] = BKE_brush_curve_strength_clamp(br, magn, half);
}
}
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 1402f62291f..5454062ad1f 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -454,7 +454,7 @@ void BKE_camera_view_frame(Scene *scene, Camera *camera, float r_vec[4][3])
float dummy_drawsize;
const float dummy_scale[3] = {1.0f, 1.0f, 1.0f};
- BKE_camera_view_frame_ex(scene, camera, false, 1.0, dummy_scale,
+ BKE_camera_view_frame_ex(scene, camera, 0.0, true, dummy_scale,
dummy_asp, dummy_shift, &dummy_drawsize, r_vec);
}
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index bfc70c91181..6ac85695570 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -35,7 +35,6 @@
*/
#include "BLI_math.h"
-#include "BLI_blenlib.h"
#include "BLI_edgehash.h"
#include "BLI_utildefines.h"
#include "BLI_stackdefines.h"
@@ -49,7 +48,6 @@
#include "BKE_editmesh.h"
#include "BKE_curve.h"
-#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -61,7 +59,6 @@
#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_glew.h"
-#include "GPU_material.h"
#include <string.h>
#include <limits.h>
@@ -343,106 +340,64 @@ static void cdDM_update_normals_from_pbvh(DerivedMesh *dm)
static void cdDM_drawVerts(DerivedMesh *dm)
{
- CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
- MVert *mv = cddm->mvert;
- int i;
-
- if (GPU_buffer_legacy(dm)) {
- glBegin(GL_POINTS);
- for (i = 0; i < dm->numVertData; i++, mv++)
- glVertex3fv(mv->co);
- glEnd();
- }
- else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
- GPU_vertex_setup(dm);
- if (!GPU_buffer_legacy(dm)) {
- if (dm->drawObject->tot_triangle_point)
- glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_triangle_point);
- else
- glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_loose_point);
- }
- GPU_buffer_unbind();
- }
+ GPU_vertex_setup(dm);
+ if (dm->drawObject->tot_triangle_point)
+ glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_triangle_point);
+ else
+ glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_loose_point);
+ GPU_buffer_unbind();
}
static void cdDM_drawUVEdges(DerivedMesh *dm)
{
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
MFace *mf = cddm->mface;
- MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
int i;
if (mf) {
- if (GPU_buffer_legacy(dm)) {
- glBegin(GL_LINES);
- for (i = 0; i < dm->numTessFaceData; i++, mf++, tf++) {
- if (!(mf->flag & ME_HIDE)) {
- glVertex2fv(tf->uv[0]);
- glVertex2fv(tf->uv[1]);
-
- glVertex2fv(tf->uv[1]);
- glVertex2fv(tf->uv[2]);
-
- if (!mf->v4) {
- glVertex2fv(tf->uv[2]);
- glVertex2fv(tf->uv[0]);
- }
- else {
- glVertex2fv(tf->uv[2]);
- glVertex2fv(tf->uv[3]);
-
- glVertex2fv(tf->uv[3]);
- glVertex2fv(tf->uv[0]);
- }
- }
+ int prevstart = 0;
+ int prevdraw = 1;
+ int draw = 1;
+ int curpos = 0;
+
+ GPU_uvedge_setup(dm);
+ for (i = 0; i < dm->numTessFaceData; i++, mf++) {
+ if (!(mf->flag & ME_HIDE)) {
+ draw = 1;
}
- glEnd();
- }
- else {
- int prevstart = 0;
- int prevdraw = 1;
- int draw = 1;
- int curpos = 0;
-
- GPU_uvedge_setup(dm);
- if (!GPU_buffer_legacy(dm)) {
- for (i = 0; i < dm->numTessFaceData; i++, mf++) {
- if (!(mf->flag & ME_HIDE)) {
- draw = 1;
- }
- else {
- draw = 0;
- }
- if (prevdraw != draw) {
- if (prevdraw > 0 && (curpos - prevstart) > 0) {
- glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
- }
- prevstart = curpos;
- }
- if (mf->v4) {
- curpos += 8;
- }
- else {
- curpos += 6;
- }
- prevdraw = draw;
- }
+ else {
+ draw = 0;
+ }
+ if (prevdraw != draw) {
if (prevdraw > 0 && (curpos - prevstart) > 0) {
glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
}
+ prevstart = curpos;
+ }
+ if (mf->v4) {
+ curpos += 8;
}
- GPU_buffer_unbind();
+ else {
+ curpos += 6;
+ }
+ prevdraw = draw;
+ }
+ if (prevdraw > 0 && (curpos - prevstart) > 0) {
+ glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
}
+ GPU_buffer_unbind();
}
}
static void cdDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdges)
{
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
- MVert *mvert = cddm->mvert;
MEdge *medge = cddm->medge;
int i;
-
+ int prevstart = 0;
+ int prevdraw = 1;
+ bool draw = true;
+
if (cddm->pbvh && cddm->pbvh_draw &&
BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH)
{
@@ -451,97 +406,60 @@ static void cdDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdg
return;
}
- if (GPU_buffer_legacy(dm)) {
- DEBUG_VBO("Using legacy code. cdDM_drawEdges\n");
- glBegin(GL_LINES);
- for (i = 0; i < dm->numEdgeData; i++, medge++) {
- if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)) &&
- (drawLooseEdges || !(medge->flag & ME_LOOSEEDGE)))
- {
- glVertex3fv(mvert[medge->v1].co);
- glVertex3fv(mvert[medge->v2].co);
- }
+ GPU_edge_setup(dm);
+ for (i = 0; i < dm->numEdgeData; i++, medge++) {
+ if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)) &&
+ (drawLooseEdges || !(medge->flag & ME_LOOSEEDGE)))
+ {
+ draw = true;
}
- glEnd();
- }
- else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
- int prevstart = 0;
- int prevdraw = 1;
- bool draw = true;
-
- GPU_edge_setup(dm);
- if (!GPU_buffer_legacy(dm)) {
- for (i = 0; i < dm->numEdgeData; i++, medge++) {
- if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)) &&
- (drawLooseEdges || !(medge->flag & ME_LOOSEEDGE)))
- {
- draw = true;
- }
- else {
- draw = false;
- }
- if (prevdraw != draw) {
- if (prevdraw > 0 && (i - prevstart) > 0) {
- GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
- }
- prevstart = i;
- }
- prevdraw = draw;
- }
+ else {
+ draw = false;
+ }
+ if (prevdraw != draw) {
if (prevdraw > 0 && (i - prevstart) > 0) {
GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
}
+ prevstart = i;
}
- GPU_buffer_unbind();
+ prevdraw = draw;
}
+ if (prevdraw > 0 && (i - prevstart) > 0) {
+ GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
+ }
+ GPU_buffer_unbind();
}
static void cdDM_drawLooseEdges(DerivedMesh *dm)
{
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
- MVert *mvert = cddm->mvert;
MEdge *medge = cddm->medge;
int i;
-
- if (GPU_buffer_legacy(dm)) {
- DEBUG_VBO("Using legacy code. cdDM_drawLooseEdges\n");
- glBegin(GL_LINES);
- for (i = 0; i < dm->numEdgeData; i++, medge++) {
- if (medge->flag & ME_LOOSEEDGE) {
- glVertex3fv(mvert[medge->v1].co);
- glVertex3fv(mvert[medge->v2].co);
- }
+
+ int prevstart = 0;
+ int prevdraw = 1;
+ int draw = 1;
+
+ GPU_edge_setup(dm);
+ for (i = 0; i < dm->numEdgeData; i++, medge++) {
+ if (medge->flag & ME_LOOSEEDGE) {
+ draw = 1;
}
- glEnd();
- }
- else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
- int prevstart = 0;
- int prevdraw = 1;
- int draw = 1;
-
- GPU_edge_setup(dm);
- if (!GPU_buffer_legacy(dm)) {
- for (i = 0; i < dm->numEdgeData; i++, medge++) {
- if (medge->flag & ME_LOOSEEDGE) {
- draw = 1;
- }
- else {
- draw = 0;
- }
- if (prevdraw != draw) {
- if (prevdraw > 0 && (i - prevstart) > 0) {
- GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
- }
- prevstart = i;
- }
- prevdraw = draw;
- }
+ else {
+ draw = 0;
+ }
+ if (prevdraw != draw) {
if (prevdraw > 0 && (i - prevstart) > 0) {
GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
}
+ prevstart = i;
}
- GPU_buffer_unbind();
+ prevdraw = draw;
+ }
+ if (prevdraw > 0 && (i - prevstart) > 0) {
+ GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
}
+ GPU_buffer_unbind();
}
static void cdDM_drawFacesSolid(DerivedMesh *dm,
@@ -549,11 +467,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
bool UNUSED(fast), DMSetMaterial setMaterial)
{
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
- MVert *mvert = cddm->mvert;
- MFace *mface = cddm->mface;
- const float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
- const short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
- int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
+ int a;
if (cddm->pbvh && cddm->pbvh_draw) {
if (dm->numTessFaceData) {
@@ -566,121 +480,37 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
return;
}
-
- if (GPU_buffer_legacy(dm)) {
- DEBUG_VBO("Using legacy code. cdDM_drawFacesSolid\n");
- glBegin(glmode = GL_QUADS);
- for (a = 0; a < dm->numTessFaceData; a++, mface++) {
- int new_glmode, new_matnr, new_shademodel;
-
- new_glmode = mface->v4 ? GL_QUADS : GL_TRIANGLES;
- new_matnr = mface->mat_nr + 1;
- new_shademodel = (lnors || (mface->flag & ME_SMOOTH)) ? GL_SMOOTH : GL_FLAT;
-
-
- if ((new_glmode != glmode) || (new_shademodel != shademodel) ||
- (setMaterial && (new_matnr != matnr)))
- {
- glEnd();
-
- if (setMaterial) {
- drawCurrentMat = setMaterial(matnr = new_matnr, NULL);
- }
-
- glShadeModel(shademodel = new_shademodel);
- glBegin(glmode = new_glmode);
- }
-
- if (drawCurrentMat) {
- if (lnors) {
- glNormal3sv((const GLshort *)lnors[0][0]);
- glVertex3fv(mvert[mface->v1].co);
- glNormal3sv((const GLshort *)lnors[0][1]);
- glVertex3fv(mvert[mface->v2].co);
- glNormal3sv((const GLshort *)lnors[0][2]);
- glVertex3fv(mvert[mface->v3].co);
- if (mface->v4) {
- glNormal3sv((const GLshort *)lnors[0][3]);
- glVertex3fv(mvert[mface->v4].co);
- }
- }
- else if (shademodel == GL_FLAT) {
- if (nors) {
- glNormal3fv(nors);
- }
- else {
- /* TODO make this better (cache facenormals as layer?) */
- float nor[3];
- if (mface->v4) {
- normal_quad_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
- }
- else {
- normal_tri_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
- }
- glNormal3fv(nor);
- }
- glVertex3fv(mvert[mface->v1].co);
- glVertex3fv(mvert[mface->v2].co);
- glVertex3fv(mvert[mface->v3].co);
- if (mface->v4) {
- glVertex3fv(mvert[mface->v4].co);
- }
- }
- else { /* shademodel == GL_SMOOTH */
- glNormal3sv(mvert[mface->v1].no);
- glVertex3fv(mvert[mface->v1].co);
- glNormal3sv(mvert[mface->v2].no);
- glVertex3fv(mvert[mface->v2].co);
- glNormal3sv(mvert[mface->v3].no);
- glVertex3fv(mvert[mface->v3].co);
- if (mface->v4) {
- glNormal3sv(mvert[mface->v4].no);
- glVertex3fv(mvert[mface->v4].co);
- }
- }
- }
-
- if (nors)
- nors += 3;
- if (lnors)
- lnors++;
- }
- glEnd();
- }
- else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
- GPU_vertex_setup(dm);
- GPU_normal_setup(dm);
- if (!GPU_buffer_legacy(dm)) {
- glShadeModel(GL_SMOOTH);
- for (a = 0; a < dm->drawObject->totmaterial; a++) {
- if (!setMaterial || setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) {
- glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start,
- dm->drawObject->materials[a].totpoint);
- }
- }
+
+ GPU_vertex_setup(dm);
+ GPU_normal_setup(dm);
+ glShadeModel(GL_SMOOTH);
+ for (a = 0; a < dm->drawObject->totmaterial; a++) {
+ if (!setMaterial || setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) {
+ glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start,
+ dm->drawObject->materials[a].totpoint);
}
- GPU_buffer_unbind();
}
+ GPU_buffer_unbind();
glShadeModel(GL_FLAT);
}
static void cdDM_drawFacesTex_common(DerivedMesh *dm,
DMSetDrawOptionsTex drawParams,
- DMSetDrawOptions drawParamsMapped,
+ DMSetDrawOptionsMappedTex drawParamsMapped,
DMCompareDrawOptions compareDrawOptions,
void *userData, DMDrawFlag uvflag)
{
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
- MVert *mv = cddm->mvert;
const MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE);
- const float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
- const short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
MCol *mcol;
int i, orig;
int colType, startFace = 0;
bool use_tface = (uvflag & DM_DRAW_USE_ACTIVE_UV) != 0;
+ int tottri;
+ int next_actualFace;
+
/* double lookup */
const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
@@ -717,208 +547,81 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
}
cdDM_update_normals_from_pbvh(dm);
-
- if (GPU_buffer_legacy(dm)) {
- int mat_nr_cache = -1;
- MTFace *tf_base = DM_get_tessface_data_layer(dm, CD_MTFACE);
- MTFace *tf_stencil_base = NULL;
- MTFace *tf_stencil = NULL;
-
- if (uvflag & DM_DRAW_USE_TEXPAINT_UV) {
- int stencil = CustomData_get_stencil_layer(&dm->faceData, CD_MTFACE);
- tf_stencil_base = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, stencil);
+
+ GPU_vertex_setup(dm);
+ GPU_normal_setup(dm);
+ if (uvflag & DM_DRAW_USE_TEXPAINT_UV)
+ GPU_texpaint_uv_setup(dm);
+ else
+ GPU_uv_setup(dm);
+ if (mcol) {
+ GPU_color_setup(dm, colType);
+ }
+
+ tottri = dm->drawObject->tot_triangle_point / 3;
+ next_actualFace = dm->drawObject->triangle_to_mface[0];
+
+ glShadeModel(GL_SMOOTH);
+ /* lastFlag = 0; */ /* UNUSED */
+ for (i = 0; i < tottri; i++) {
+ int actualFace = next_actualFace;
+ DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
+ int flush = 0;
+
+ if (i != tottri - 1)
+ next_actualFace = dm->drawObject->triangle_to_mface[i + 1];
+
+ if (drawParams) {
+ draw_option = drawParams(use_tface && tf ? &tf[actualFace] : NULL, (mcol != NULL), mf[actualFace].mat_nr);
}
-
- DEBUG_VBO("Using legacy code. cdDM_drawFacesTex_common\n");
- for (i = 0; i < dm->numTessFaceData; i++, mf++) {
- MVert *mvert;
- DMDrawOption draw_option;
- unsigned char *cp = NULL;
-
- if (uvflag & DM_DRAW_USE_TEXPAINT_UV) {
- if (mf->mat_nr != mat_nr_cache) {
- tf_base = DM_paint_uvlayer_active_get(dm, mf->mat_nr);
-
- mat_nr_cache = mf->mat_nr;
- }
- }
-
- tf = tf_base ? tf_base + i : NULL;
- tf_stencil = tf_stencil_base ? tf_stencil_base + i : NULL;
-
- if (drawParams) {
- draw_option = drawParams(use_tface ? tf : NULL, (mcol != NULL), mf->mat_nr);
- }
- else {
- if (index_mf_to_mpoly) {
- orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i);
- if (orig == ORIGINDEX_NONE) {
- /* XXX, this is not really correct
- * it will draw the previous faces context for this one when we don't know its settings.
- * but better then skipping it altogether. - campbell */
- draw_option = DM_DRAW_OPTION_NORMAL;
- }
- else if (drawParamsMapped) {
- draw_option = drawParamsMapped(userData, orig);
- }
- else {
- if (nors) {
- nors += 3;
- }
- continue;
- }
+ else {
+ if (index_mf_to_mpoly) {
+ orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace);
+ if (orig == ORIGINDEX_NONE) {
+ /* XXX, this is not really correct
+ * it will draw the previous faces context for this one when we don't know its settings.
+ * but better then skipping it altogether. - campbell */
+ draw_option = DM_DRAW_OPTION_NORMAL;
}
else if (drawParamsMapped) {
- draw_option = drawParamsMapped(userData, i);
- }
- else {
- if (nors) {
- nors += 3;
- }
- continue;
+ draw_option = drawParamsMapped(userData, orig, mf[actualFace].mat_nr);
}
}
-
- if (draw_option != DM_DRAW_OPTION_SKIP) {
- if (draw_option != DM_DRAW_OPTION_NO_MCOL && mcol)
- cp = (unsigned char *) &mcol[i * 4];
-
- if (!(lnors || (mf->flag & ME_SMOOTH))) {
- if (nors) {
- glNormal3fv(nors);
- }
- else {
- float nor[3];
- if (mf->v4) {
- normal_quad_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
- }
- else {
- normal_tri_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
- }
- glNormal3fv(nor);
- }
- }
-
- glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES);
- if (tf) glTexCoord2fv(tf->uv[0]);
- if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf->uv[0]);
- if (cp) glColor3ub(cp[3], cp[2], cp[1]);
- mvert = &mv[mf->v1];
- if (lnors) glNormal3sv((const GLshort *)lnors[0][0]);
- else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
- glVertex3fv(mvert->co);
-
- if (tf) glTexCoord2fv(tf->uv[1]);
- if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf->uv[1]);
- if (cp) glColor3ub(cp[7], cp[6], cp[5]);
- mvert = &mv[mf->v2];
- if (lnors) glNormal3sv((const GLshort *)lnors[0][1]);
- else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
- glVertex3fv(mvert->co);
-
- if (tf) glTexCoord2fv(tf->uv[2]);
- if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf->uv[2]);
- if (cp) glColor3ub(cp[11], cp[10], cp[9]);
- mvert = &mv[mf->v3];
- if (lnors) glNormal3sv((const GLshort *)lnors[0][2]);
- else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
- glVertex3fv(mvert->co);
-
- if (mf->v4) {
- if (tf) glTexCoord2fv(tf->uv[3]);
- if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf->uv[3]);
- if (cp) glColor3ub(cp[15], cp[14], cp[13]);
- mvert = &mv[mf->v4];
- if (lnors) glNormal3sv((const GLshort *)lnors[0][3]);
- else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
- glVertex3fv(mvert->co);
- }
- glEnd();
+ else if (drawParamsMapped) {
+ draw_option = drawParamsMapped(userData, actualFace, mf[actualFace].mat_nr);
}
-
- if (nors)
- nors += 3;
- if (lnors)
- lnors++;
- }
- }
- else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
- GPU_vertex_setup(dm);
- GPU_normal_setup(dm);
- if (uvflag & DM_DRAW_USE_TEXPAINT_UV)
- GPU_texpaint_uv_setup(dm);
- else
- GPU_uv_setup(dm);
- if (mcol) {
- GPU_color_setup(dm, colType);
}
-
- if (!GPU_buffer_legacy(dm)) {
- int tottri = dm->drawObject->tot_triangle_point / 3;
- int next_actualFace = dm->drawObject->triangle_to_mface[0];
-
- glShadeModel(GL_SMOOTH);
- /* lastFlag = 0; */ /* UNUSED */
- for (i = 0; i < tottri; i++) {
- int actualFace = next_actualFace;
- DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
- int flush = 0;
-
- if (i != tottri - 1)
- next_actualFace = dm->drawObject->triangle_to_mface[i + 1];
-
- if (drawParams) {
- draw_option = drawParams(use_tface && tf ? &tf[actualFace] : NULL, (mcol != NULL), mf[actualFace].mat_nr);
- }
- else {
- if (index_mf_to_mpoly) {
- orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace);
- if (orig == ORIGINDEX_NONE) {
- /* XXX, this is not really correct
- * it will draw the previous faces context for this one when we don't know its settings.
- * but better then skipping it altogether. - campbell */
- draw_option = DM_DRAW_OPTION_NORMAL;
- }
- else if (drawParamsMapped) {
- draw_option = drawParamsMapped(userData, orig);
- }
- }
- else if (drawParamsMapped) {
- draw_option = drawParamsMapped(userData, actualFace);
- }
- }
-
- /* flush buffer if current triangle isn't drawable or it's last triangle */
- flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1);
-
- if (!flush && compareDrawOptions) {
- /* also compare draw options and flush buffer if they're different
+
+ /* flush buffer if current triangle isn't drawable or it's last triangle */
+ flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1);
+
+ if (!flush && compareDrawOptions) {
+ /* also compare draw options and flush buffer if they're different
* need for face selection highlight in edit mode */
- flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
- }
-
- if (flush) {
- int first = startFace * 3;
- /* Add one to the length if we're drawing at the end of the array */
- int count = (i - startFace + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3;
-
- if (count) {
- if (mcol && draw_option != DM_DRAW_OPTION_NO_MCOL)
- GPU_color_switch(1);
- else
- GPU_color_switch(0);
-
- glDrawArrays(GL_TRIANGLES, first, count);
- }
-
- startFace = i + 1;
- }
+ flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
+ }
+
+ if (flush) {
+ int first = startFace * 3;
+ /* Add one to the length if we're drawing at the end of the array */
+ int count = (i - startFace + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3;
+
+ if (count) {
+ if (mcol && draw_option != DM_DRAW_OPTION_NO_MCOL)
+ GPU_color_switch(1);
+ else
+ GPU_color_switch(0);
+
+ glDrawArrays(GL_TRIANGLES, first, count);
}
+
+ startFace = i + 1;
}
-
- GPU_buffer_unbind();
- glShadeModel(GL_FLAT);
}
+
+ GPU_buffer_unbind();
+ glShadeModel(GL_FLAT);
+
}
static void cdDM_drawFacesTex(DerivedMesh *dm,
@@ -968,7 +671,7 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm,
/* back-buffer always uses legacy since VBO's would need the
* color array temporarily overwritten for drawing, then reset. */
- if (GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) {
+ if (G.f & G_BACKBUFSEL) {
DEBUG_VBO("Using legacy code. cdDM_drawMappedFaces\n");
for (i = 0; i < dm->numTessFaceData; i++, mf++) {
int drawSmooth = ((flag & DM_DRAW_ALWAYS_SMOOTH) || lnors) ? 1 : (mf->flag & ME_SMOOTH);
@@ -1070,79 +773,85 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm,
}
else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
int prevstart = 0;
+ int tottri;
+
GPU_vertex_setup(dm);
GPU_normal_setup(dm);
if (useColors && mcol) {
GPU_color_setup(dm, colType);
}
- if (!GPU_buffer_legacy(dm)) {
- int tottri = dm->drawObject->tot_triangle_point / 3;
- glShadeModel(GL_SMOOTH);
+ tottri = dm->drawObject->tot_triangle_point / 3;
+ glShadeModel(GL_SMOOTH);
+
+ if (tottri == 0) {
+ /* avoid buffer problems in following code */
+ }
+ if (setDrawOptions == NULL) {
+ /* just draw the entire face array */
+ glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3);
+ }
+ else {
+ /* we need to check if the next material changes */
+ int next_actualFace = dm->drawObject->triangle_to_mface[0];
+ int prev_mat_nr = -1;
- if (tottri == 0) {
- /* avoid buffer problems in following code */
- }
- if (setDrawOptions == NULL) {
- /* just draw the entire face array */
- glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3);
- }
- else {
- /* we need to check if the next material changes */
- int next_actualFace = dm->drawObject->triangle_to_mface[0];
+ for (i = 0; i < tottri; i++) {
+ //int actualFace = dm->drawObject->triangle_to_mface[i];
+ int actualFace = next_actualFace;
+ MFace *mface = mf + actualFace;
+ /*int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mface->flag & ME_SMOOTH);*/ /* UNUSED */
+ DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
+ int flush = 0;
- for (i = 0; i < tottri; i++) {
- //int actualFace = dm->drawObject->triangle_to_mface[i];
- int actualFace = next_actualFace;
- MFace *mface = mf + actualFace;
- /*int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mface->flag & ME_SMOOTH);*/ /* UNUSED */
- DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
- int flush = 0;
-
- if (i != tottri - 1)
- next_actualFace = dm->drawObject->triangle_to_mface[i + 1];
-
- orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace;
-
- if (orig == ORIGINDEX_NONE)
+ if (i != tottri - 1)
+ next_actualFace = dm->drawObject->triangle_to_mface[i + 1];
+
+ orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace;
+
+ if (mface->mat_nr != prev_mat_nr) {
+ if (setMaterial)
draw_option = setMaterial(mface->mat_nr + 1, NULL);
- else if (setDrawOptions != NULL)
- draw_option = setDrawOptions(userData, orig);
-
- if (draw_option == DM_DRAW_OPTION_STIPPLE) {
- glEnable(GL_POLYGON_STIPPLE);
- glPolygonStipple(stipple_quarttone);
- }
-
- /* Goal is to draw as long of a contiguous triangle
+
+ prev_mat_nr = mface->mat_nr;
+ }
+
+ if (setDrawOptions != NULL && (orig != ORIGINDEX_NONE))
+ draw_option = setDrawOptions(userData, orig);
+
+ if (draw_option == DM_DRAW_OPTION_STIPPLE) {
+ glEnable(GL_POLYGON_STIPPLE);
+ glPolygonStipple(stipple_quarttone);
+ }
+
+ /* Goal is to draw as long of a contiguous triangle
* array as possible, so draw when we hit either an
* invisible triangle or at the end of the array */
-
- /* flush buffer if current triangle isn't drawable or it's last triangle... */
- flush = (ELEM(draw_option, DM_DRAW_OPTION_SKIP, DM_DRAW_OPTION_STIPPLE)) || (i == tottri - 1);
-
- /* ... or when material setting is dissferent */
- flush |= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr;
-
- if (!flush && compareDrawOptions) {
- flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
- }
-
- if (flush) {
- int first = prevstart * 3;
- /* Add one to the length if we're drawing at the end of the array */
- int count = (i - prevstart + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3;
-
- if (count)
- glDrawArrays(GL_TRIANGLES, first, count);
-
- prevstart = i + 1;
-
- if (draw_option == DM_DRAW_OPTION_STIPPLE)
- glDisable(GL_POLYGON_STIPPLE);
- }
+
+ /* flush buffer if current triangle isn't drawable or it's last triangle... */
+ flush = (ELEM(draw_option, DM_DRAW_OPTION_SKIP, DM_DRAW_OPTION_STIPPLE)) || (i == tottri - 1);
+
+ /* ... or when material setting is dissferent */
+ flush |= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr;
+
+ if (!flush && compareDrawOptions) {
+ flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
+ }
+
+ if (flush) {
+ int first = prevstart * 3;
+ /* Add one to the length if we're drawing at the end of the array */
+ int count = (i - prevstart + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3;
+
+ if (count)
+ glDrawArrays(GL_TRIANGLES, first, count);
+
+ prevstart = i + 1;
+
+ if (draw_option == DM_DRAW_OPTION_STIPPLE)
+ glDisable(GL_POLYGON_STIPPLE);
}
}
-
+
glShadeModel(GL_FLAT);
}
GPU_buffer_unbind();
@@ -1150,7 +859,7 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm,
}
static void cdDM_drawMappedFacesTex(DerivedMesh *dm,
- DMSetDrawOptions setDrawOptions,
+ DMSetDrawOptionsMappedTex setDrawOptions,
DMCompareDrawOptions compareDrawOptions,
void *userData, DMDrawFlag flag)
{
@@ -1270,7 +979,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
glShadeModel(GL_SMOOTH);
- if (GPU_buffer_legacy(dm) || setDrawOptions != NULL) {
+ if (setDrawOptions != NULL) {
DEBUG_VBO("Using legacy code. cdDM_drawMappedFacesGLSL\n");
memset(&attribs, 0, sizeof(attribs));
@@ -1329,11 +1038,11 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
ln3 = &lnors[a][2];
ln4 = &lnors[a][3];
}
-
+
cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, ln1, smoothnormal);
cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, ln2, smoothnormal);
cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, ln3, smoothnormal);
-
+
if (mface->v4)
cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, ln4, smoothnormal);
else
@@ -1347,214 +1056,213 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
int numdata = 0, elementsize = 0, offset;
int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0;
int i;
-
+
const MFace *mf = mface;
GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/
memset(&attribs, 0, sizeof(attribs));
-
+
GPU_vertex_setup(dm);
GPU_normal_setup(dm);
-
- if (!GPU_buffer_legacy(dm)) {
- for (i = 0; i < dm->drawObject->tot_triangle_point / 3; i++) {
-
- a = dm->drawObject->triangle_to_mface[i];
-
- mface = mf + a;
- new_matnr = mface->mat_nr + 1;
-
- if (new_matnr != matnr) {
- numfaces = curface - start;
- if (numfaces > 0) {
-
- if (do_draw) {
-
- if (numdata != 0) {
-
- GPU_buffer_unlock(buffer);
-
- GPU_interleaved_attrib_setup(buffer, datatypes, numdata);
- }
-
- glDrawArrays(GL_TRIANGLES, start * 3, numfaces * 3);
-
- if (numdata != 0) {
-
- GPU_buffer_free(buffer);
-
- buffer = NULL;
- }
-
+
+ for (i = 0; i < dm->drawObject->tot_triangle_point / 3; i++) {
+
+ a = dm->drawObject->triangle_to_mface[i];
+
+ mface = mf + a;
+ new_matnr = mface->mat_nr + 1;
+
+ if (new_matnr != matnr) {
+ numfaces = curface - start;
+ if (numfaces > 0) {
+
+ if (do_draw) {
+
+ if (numdata != 0) {
+
+ GPU_buffer_unlock(buffer);
+
+ GPU_interleaved_attrib_setup(buffer, datatypes, numdata);
+ }
+
+ glDrawArrays(GL_TRIANGLES, start * 3, numfaces * 3);
+
+ if (numdata != 0) {
+
+ GPU_buffer_free(buffer);
+
+ buffer = NULL;
}
+
}
- numdata = 0;
- start = curface;
- /* prevdraw = do_draw; */ /* UNUSED */
- do_draw = setMaterial(matnr = new_matnr, &gattribs);
- if (do_draw) {
- DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
-
- if (attribs.totorco && attribs.orco.array) {
- datatypes[numdata].index = attribs.orco.gl_index;
- datatypes[numdata].size = 3;
+ }
+ numdata = 0;
+ start = curface;
+ /* prevdraw = do_draw; */ /* UNUSED */
+ do_draw = setMaterial(matnr = new_matnr, &gattribs);
+ if (do_draw) {
+ DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
+
+ if (attribs.totorco && attribs.orco.array) {
+ datatypes[numdata].index = attribs.orco.gl_index;
+ datatypes[numdata].size = 3;
+ datatypes[numdata].type = GL_FLOAT;
+ numdata++;
+ }
+ for (b = 0; b < attribs.tottface; b++) {
+ if (attribs.tface[b].array) {
+ datatypes[numdata].index = attribs.tface[b].gl_index;
+ datatypes[numdata].size = 2;
datatypes[numdata].type = GL_FLOAT;
numdata++;
}
- for (b = 0; b < attribs.tottface; b++) {
- if (attribs.tface[b].array) {
- datatypes[numdata].index = attribs.tface[b].gl_index;
- datatypes[numdata].size = 2;
- datatypes[numdata].type = GL_FLOAT;
- numdata++;
- }
- }
- for (b = 0; b < attribs.totmcol; b++) {
- if (attribs.mcol[b].array) {
- datatypes[numdata].index = attribs.mcol[b].gl_index;
- datatypes[numdata].size = 4;
- datatypes[numdata].type = GL_UNSIGNED_BYTE;
- numdata++;
- }
- }
- if (attribs.tottang && attribs.tang.array) {
- datatypes[numdata].index = attribs.tang.gl_index;
+ }
+ for (b = 0; b < attribs.totmcol; b++) {
+ if (attribs.mcol[b].array) {
+ datatypes[numdata].index = attribs.mcol[b].gl_index;
datatypes[numdata].size = 4;
- datatypes[numdata].type = GL_FLOAT;
+ datatypes[numdata].type = GL_UNSIGNED_BYTE;
numdata++;
}
- if (numdata != 0) {
- elementsize = GPU_attrib_element_size(datatypes, numdata);
- buffer = GPU_buffer_alloc(elementsize * dm->drawObject->tot_triangle_point);
- if (buffer == NULL) {
- GPU_buffer_unbind();
- dm->drawObject->legacy = 1;
- return;
- }
- varray = GPU_buffer_lock_stream(buffer);
- if (varray == NULL) {
- GPU_buffer_unbind();
- GPU_buffer_free(buffer);
- dm->drawObject->legacy = 1;
- return;
- }
+ }
+ if (attribs.tottang && attribs.tang.array) {
+ datatypes[numdata].index = attribs.tang.gl_index;
+ datatypes[numdata].size = 4;
+ datatypes[numdata].type = GL_FLOAT;
+ numdata++;
+ }
+ if (numdata != 0) {
+ elementsize = GPU_attrib_element_size(datatypes, numdata);
+ buffer = GPU_buffer_alloc(elementsize * dm->drawObject->tot_triangle_point, false);
+ if (buffer == NULL) {
+ GPU_buffer_unbind();
+ buffer = GPU_buffer_alloc(elementsize * dm->drawObject->tot_triangle_point, true);
+ return;
}
- else {
- /* if the buffer was set, don't use it again.
- * prevdraw was assumed true but didnt run so set to false - [#21036] */
- /* prevdraw = 0; */ /* UNUSED */
- buffer = NULL;
+ varray = GPU_buffer_lock_stream(buffer);
+ if (varray == NULL) {
+ GPU_buffer_unbind();
+ GPU_buffer_free(buffer);
+ fprintf(stderr, "Out of memory, can't draw object\n");
+ return;
}
}
+ else {
+ /* if the buffer was set, don't use it again.
+ * prevdraw was assumed true but didnt run so set to false - [#21036] */
+ /* prevdraw = 0; */ /* UNUSED */
+ buffer = NULL;
+ }
}
-
+ }
+
+ if (do_draw && numdata != 0) {
+ offset = 0;
+ if (attribs.totorco && attribs.orco.array) {
+ copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v1]);
+ copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v2]);
+ copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v3]);
+ offset += sizeof(float) * 3;
+ }
+ for (b = 0; b < attribs.tottface; b++) {
+ if (attribs.tface[b].array) {
+ MTFace *tf = &attribs.tface[b].array[a];
+ copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[0]);
+ copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[1]);
+
+ copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[2]);
+ offset += sizeof(float) * 2;
+ }
+ }
+ for (b = 0; b < attribs.totmcol; b++) {
+ if (attribs.mcol[b].array) {
+ MCol *cp = &attribs.mcol[b].array[a * 4 + 0];
+ GLubyte col[4];
+ col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
+ copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col);
+ cp = &attribs.mcol[b].array[a * 4 + 1];
+ col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
+ copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col);
+ cp = &attribs.mcol[b].array[a * 4 + 2];
+ col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
+ copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col);
+ offset += sizeof(unsigned char) * 4;
+ }
+ }
+ if (attribs.tottang && attribs.tang.array) {
+ const float *tang = attribs.tang.array[a * 4 + 0];
+ copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang);
+ tang = attribs.tang.array[a * 4 + 1];
+ copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang);
+ tang = attribs.tang.array[a * 4 + 2];
+ copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang);
+ offset += sizeof(float) * 4;
+ }
+ (void)offset;
+ }
+ curface++;
+ if (mface->v4) {
if (do_draw && numdata != 0) {
offset = 0;
if (attribs.totorco && attribs.orco.array) {
- copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v1]);
- copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v2]);
- copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v3]);
+ copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v3]);
+ copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v4]);
+ copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v1]);
offset += sizeof(float) * 3;
}
for (b = 0; b < attribs.tottface; b++) {
if (attribs.tface[b].array) {
MTFace *tf = &attribs.tface[b].array[a];
- copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[0]);
- copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[1]);
-
- copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[2]);
+ copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[2]);
+ copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[3]);
+ copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[0]);
offset += sizeof(float) * 2;
}
}
for (b = 0; b < attribs.totmcol; b++) {
if (attribs.mcol[b].array) {
- MCol *cp = &attribs.mcol[b].array[a * 4 + 0];
+ MCol *cp = &attribs.mcol[b].array[a * 4 + 2];
GLubyte col[4];
col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col);
- cp = &attribs.mcol[b].array[a * 4 + 1];
+ cp = &attribs.mcol[b].array[a * 4 + 3];
col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col);
- cp = &attribs.mcol[b].array[a * 4 + 2];
+ cp = &attribs.mcol[b].array[a * 4 + 0];
col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col);
offset += sizeof(unsigned char) * 4;
}
}
if (attribs.tottang && attribs.tang.array) {
- const float *tang = attribs.tang.array[a * 4 + 0];
+ const float *tang = attribs.tang.array[a * 4 + 2];
copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang);
- tang = attribs.tang.array[a * 4 + 1];
+ tang = attribs.tang.array[a * 4 + 3];
copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang);
- tang = attribs.tang.array[a * 4 + 2];
+ tang = attribs.tang.array[a * 4 + 0];
copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang);
offset += sizeof(float) * 4;
}
(void)offset;
}
curface++;
- if (mface->v4) {
- if (do_draw && numdata != 0) {
- offset = 0;
- if (attribs.totorco && attribs.orco.array) {
- copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v3]);
- copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v4]);
- copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v1]);
- offset += sizeof(float) * 3;
- }
- for (b = 0; b < attribs.tottface; b++) {
- if (attribs.tface[b].array) {
- MTFace *tf = &attribs.tface[b].array[a];
- copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[2]);
- copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[3]);
- copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[0]);
- offset += sizeof(float) * 2;
- }
- }
- for (b = 0; b < attribs.totmcol; b++) {
- if (attribs.mcol[b].array) {
- MCol *cp = &attribs.mcol[b].array[a * 4 + 2];
- GLubyte col[4];
- col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
- copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col);
- cp = &attribs.mcol[b].array[a * 4 + 3];
- col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
- copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col);
- cp = &attribs.mcol[b].array[a * 4 + 0];
- col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
- copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col);
- offset += sizeof(unsigned char) * 4;
- }
- }
- if (attribs.tottang && attribs.tang.array) {
- const float *tang = attribs.tang.array[a * 4 + 2];
- copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang);
- tang = attribs.tang.array[a * 4 + 3];
- copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang);
- tang = attribs.tang.array[a * 4 + 0];
- copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang);
- offset += sizeof(float) * 4;
- }
- (void)offset;
- }
- curface++;
- i++;
- }
+ i++;
}
- numfaces = curface - start;
- if (numfaces > 0) {
- if (do_draw) {
- if (numdata != 0) {
- GPU_buffer_unlock(buffer);
- GPU_interleaved_attrib_setup(buffer, datatypes, numdata);
- }
- glDrawArrays(GL_TRIANGLES, start * 3, (curface - start) * 3);
+ }
+ numfaces = curface - start;
+ if (numfaces > 0) {
+ if (do_draw) {
+ if (numdata != 0) {
+ GPU_buffer_unlock(buffer);
+ GPU_interleaved_attrib_setup(buffer, datatypes, numdata);
}
+ glDrawArrays(GL_TRIANGLES, start * 3, (curface - start) * 3);
}
- GPU_buffer_unbind();
}
+ GPU_buffer_unbind();
+
GPU_buffer_free(buffer);
}
-
+
glShadeModel(GL_FLAT);
}
@@ -2725,10 +2433,10 @@ static bool poly_gset_compare_fn(const void *k1, const void *k2)
(pk1->totloops == pk2->totloops))
{
/* Equality - note that this does not mean equality of polys */
- return 0;
+ return false;
}
else {
- return 1;
+ return true;
}
}
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index aacf02555d4..3932a8ead2f 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -789,7 +789,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm )
// Kicking goal factor to simplify things...who uses that anyway?
// ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal );
- verts->goal = powf(verts->goal, 4.0f);
+ verts->goal = pow4f(verts->goal);
if ( verts->goal >= SOFTGOALSNAP )
verts->flags |= CLOTH_VERT_FLAG_PINNED;
}
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index 2f600935b1e..3030ee4b4a4 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -648,7 +648,7 @@ static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, Collis
{
int i;
- *collisions = (CollPair *) MEM_mallocN(sizeof(CollPair) * numresult * 64, "collision array" ); // * 4 since cloth_collision_static can return more than 1 collision
+ *collisions = (CollPair *) MEM_mallocN(sizeof(CollPair) * numresult * 4, "collision array" ); // * 4 since cloth_collision_static can return more than 1 collision
*collisions_index = *collisions;
for ( i = 0; i < numresult; i++ ) {
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index a63e06c7cb8..89c3e4b0cfc 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -50,7 +50,6 @@
#include "IMB_colormanagement.h"
-#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
/* ********************************* color curve ********************* */
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index e4b60c12d64..8fedf37fb95 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -185,6 +185,10 @@ void BKE_constraints_clear_evalob(bConstraintOb *cob)
/* calculate delta of constraints evaluation */
invert_m4_m4(imat, cob->startmat);
+ /* XXX This would seem to be in wrong order. However, it does not work in 'right' order - would be nice to
+ * understand why premul is needed here instead of usual postmul?
+ * In any case, we **do not get a delta** here (e.g. startmat & matrix having same location, still gives
+ * a 'delta' with non-null translation component :/ ).*/
mul_m4_m4m4(delta, cob->matrix, imat);
/* copy matrices back to source */
@@ -1967,7 +1971,7 @@ static void pycon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTa
static void pycon_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
{
#ifndef WITH_PYTHON
- (void)con; (void)cob; (void)targets; /* unused */
+ UNUSED_VARS(con, cob, targets);
return;
#else
bPythonConstraint *data = con->data;
@@ -2613,6 +2617,8 @@ static void stretchto_new_data(void *cdata)
data->plane = 0;
data->orglength = 0.0;
data->bulge = 1.0;
+ data->bulge_max = 1.0f;
+ data->bulge_min = 1.0f;
}
static void stretchto_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
@@ -2689,39 +2695,28 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
bulge = powf(data->orglength / dist, data->bulge);
- if (data->flag & STRETCHTOCON_USE_BULGE_MAX) {
- const float bulge_median = ((data->flag & STRETCHTOCON_USE_BULGE_MIN) ?
- 0.5f * (data->bulge_min + data->bulge_max) : 0.0f);
- const float bulge_range = data->bulge_max - bulge_median;
- float x, bulge_smoothed;
-
- x = bulge_range != 0.0f ? (bulge - bulge_median) / bulge_range : 0.0f;
- CLAMP(x, -1.0f, 1.0f);
- bulge_smoothed = bulge_median + bulge_range * sinf(0.5f*M_PI * x);
-
- if (data->flag & STRETCHTOCON_USE_BULGE_MIN) {
- CLAMP_MIN(bulge, data->bulge_min);
+ if (bulge > 1.0f) {
+ if (data->flag & STRETCHTOCON_USE_BULGE_MAX) {
+ float bulge_max = max_ff(data->bulge_max, 1.0f);
+ float hard = min_ff(bulge, bulge_max);
+
+ float range = bulge_max - 1.0f;
+ float scale = (range > 0.0f) ? 1.0f / range : 0.0f;
+ float soft = 1.0f + range * atanf((bulge - 1.0f) * scale) / (0.5f * M_PI);
+
+ bulge = interpf(soft, hard, data->bulge_smooth);
}
- CLAMP_MAX(bulge, data->bulge_max);
-
- bulge = interpf(bulge_smoothed, bulge, data->bulge_smooth);
}
- else if (data->flag & STRETCHTOCON_USE_BULGE_MIN) {
- /* The quadratic formula below creates a smooth asymptote
- * of the clamped bulge value. By scaling x with the inverse smooth factor
- * the smoothed area becomes smaller ("less smoothing").
- * For very small smoothing factor below epsilon it is replaced
- * by the clamped version to avoid floating point precision issues.
- */
- const float epsilon = 0.000001f;
- if (data->bulge_smooth < epsilon) {
- CLAMP_MIN(bulge, data->bulge_min);
- }
- else {
- float scale = data->bulge_smooth;
- float inv_scale = 1.0f / scale;
- float x = (bulge - data->bulge_min) * 0.5f * inv_scale;
- bulge = scale * (x + sqrtf((x * x) + 1.0f)) + data->bulge_min;
+ if (bulge < 1.0f) {
+ if (data->flag & STRETCHTOCON_USE_BULGE_MIN) {
+ float bulge_min = CLAMPIS(data->bulge_max, 0.0f, 1.0f);
+ float hard = max_ff(bulge, bulge_min);
+
+ float range = 1.0f - bulge_min;
+ float scale = (range > 0.0f) ? 1.0f / range : 0.0f;
+ float soft = 1.0f - range * atanf((1.0f - bulge) * scale) / (0.5f * M_PI);
+
+ bulge = interpf(soft, hard, data->bulge_smooth);
}
}
@@ -3466,10 +3461,16 @@ static void shrinkwrap_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra
}
/* transform normal into requested space */
- unit_m4(mat);
- BKE_constraint_mat_convertspace(cob->ob, cob->pchan, mat, CONSTRAINT_SPACE_LOCAL, scon->projAxisSpace);
- invert_m4(mat);
- mul_mat3_m4_v3(mat, no);
+ /* We cannot use BKE_constraint_mat_convertspace here, it does not take into account scaling...
+ * In theory we would not need it, but in this case we'd have to tweak SpaceTransform to also
+ * optionally ignore scaling when handling normals - simpler to directly call BKE_object_to_mat4
+ * if needed! See T42447. */
+ if (scon->projAxisSpace == CONSTRAINT_SPACE_WORLD) {
+ BKE_object_to_mat4(cob->ob, mat);
+ invert_m4(mat);
+ mul_mat3_m4_v3(mat, no);
+ }
+ /* Else, we remain in local space, nothing to do. */
if (normalize_v3(no) < FLT_EPSILON) {
fail = true;
@@ -4394,10 +4395,10 @@ bool BKE_constraint_remove(ListBase *list, bConstraint *con)
if (con) {
BKE_constraint_free_data(con);
BLI_freelinkN(list, con);
- return 1;
+ return true;
}
else
- return 0;
+ return false;
}
/* ......... */
@@ -4661,15 +4662,15 @@ bool BKE_constraints_proxylocked_owner(Object *ob, bPoseChannel *pchan)
/* On bone-level, check if bone is on proxy-protected layer */
if ((pchan->bone) && (pchan->bone->layer & arm->layer_protected))
- return 1;
+ return true;
}
else {
/* FIXME: constraints on object-level are not handled well yet */
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
/* -------- Target-Matrix Stuff ------- */
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index de285f87444..8f6c9735aaf 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -37,6 +37,7 @@
#include "DNA_windowmanager_types.h"
#include "DNA_object_types.h"
#include "DNA_linestyle_types.h"
+#include "DNA_gpencil_types.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
@@ -257,7 +258,7 @@ static void *ctx_wm_python_context_get(
}
}
#else
- (void)C, (void)member, (void)member_type;
+ UNUSED_VARS(C, member, member_type);
#endif
/* don't allow UI context access from non-main threads */
@@ -588,7 +589,7 @@ int ctx_data_list_count(const bContext *C, int (*func)(const bContext *, ListBas
ListBase list;
if (func(C, &list)) {
- int tot = BLI_countlist(&list);
+ int tot = BLI_listbase_count(&list);
BLI_freelistN(&list);
return tot;
}
@@ -1090,3 +1091,34 @@ int CTX_data_visible_pose_bones(const bContext *C, ListBase *list)
{
return ctx_data_collection_get(C, "visible_pose_bones", list);
}
+
+bGPdata *CTX_data_gpencil_data(const bContext *C)
+{
+ return ctx_data_pointer_get(C, "gpencil_data");
+}
+
+bGPDlayer *CTX_data_active_gpencil_layer(const bContext *C)
+{
+ return ctx_data_pointer_get(C, "active_gpencil_layer");
+}
+
+bGPDframe *CTX_data_active_gpencil_frame(const bContext *C)
+{
+ return ctx_data_pointer_get(C, "active_gpencil_frame");
+}
+
+int CTX_data_visible_gpencil_layers(const bContext *C, ListBase *list)
+{
+ return ctx_data_collection_get(C, "visible_gpencil_layers", list);
+}
+
+int CTX_data_editable_gpencil_layers(const bContext *C, ListBase *list)
+{
+ return ctx_data_collection_get(C, "editable_gpencil_layers", list);
+}
+
+int CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list)
+{
+ return ctx_data_collection_get(C, "editable_gpencil_strokes", list);
+}
+
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index ca58035d638..937ceffc765 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -4312,7 +4312,7 @@ bool BKE_curve_center_bounds(Curve *cu, float cent[3])
}
-void BKE_curve_transform_ex(Curve *cu, float mat[4][4], bool do_keys, float unit_scale)
+void BKE_curve_transform_ex(Curve *cu, float mat[4][4], const bool do_keys, const float unit_scale)
{
Nurb *nu;
BPoint *bp;
@@ -4348,13 +4348,13 @@ void BKE_curve_transform_ex(Curve *cu, float mat[4][4], bool do_keys, float unit
}
}
-void BKE_curve_transform(Curve *cu, float mat[4][4], bool do_keys)
+void BKE_curve_transform(Curve *cu, float mat[4][4], const bool do_keys)
{
float unit_scale = mat4_to_scale(mat);
BKE_curve_transform_ex(cu, mat, do_keys, unit_scale);
}
-void BKE_curve_translate(Curve *cu, float offset[3], bool do_keys)
+void BKE_curve_translate(Curve *cu, float offset[3], const bool do_keys)
{
ListBase *nurb_lb = BKE_curve_nurbs_get(cu);
Nurb *nu;
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 63eb3b397b0..5e86ca596cf 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -144,6 +144,9 @@ typedef struct LayerTypeInfo {
/** a function to determine file size */
size_t (*filesize)(CDataFile *cdf, const void *data, int count);
+
+ /** a function to determine max allowed number of layers, should be NULL or return -1 if no limit */
+ int (*layers_max)(void);
} LayerTypeInfo;
static void layerCopy_mdeformvert(const void *source, void *dest,
@@ -379,6 +382,11 @@ static void layerDefault_tface(void *data, int count)
tf[i] = default_tf;
}
+static int layerMaxNum_tface(void)
+{
+ return MAX_MTFACE;
+}
+
static void layerCopy_propFloat(const void *source, void *dest,
int count)
{
@@ -745,6 +753,11 @@ static void layerInterp_mloopcol(void **sources, const float *weights,
mc->a = (int)col.a;
}
+static int layerMaxNum_mloopcol(void)
+{
+ return MAX_MCOL;
+}
+
static void layerCopyValue_mloopuv(const void *source, void *dest)
{
const MLoopUV *luv1 = source;
@@ -1093,12 +1106,12 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
/* 4: CD_MFACE */
{sizeof(MFace), "MFace", 1, NULL, NULL, NULL, NULL, NULL, NULL},
/* 5: CD_MTFACE */
- {sizeof(MTFace), "MTFace", 1, N_("UVMap"), layerCopy_tface, NULL,
- layerInterp_tface, layerSwap_tface, layerDefault_tface},
+ {sizeof(MTFace), "MTFace", 1, N_("UVMap"), layerCopy_tface, NULL, layerInterp_tface, layerSwap_tface,
+ layerDefault_tface, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, layerMaxNum_tface},
/* 6: CD_MCOL */
/* 4 MCol structs per face */
{sizeof(MCol) * 4, "MCol", 4, N_("Col"), NULL, NULL, layerInterp_mcol,
- layerSwap_mcol, layerDefault_mcol},
+ layerSwap_mcol, layerDefault_mcol, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, layerMaxNum_mloopcol},
/* 7: CD_ORIGINDEX */
{sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, layerDefault_origindex},
/* 8: CD_NORMAL */
@@ -1119,15 +1132,16 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(float) * 3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
/* 15: CD_MTEXPOLY */
/* note, when we expose the UV Map / TexFace split to the user, change this back to face Texture */
- {sizeof(MTexPoly), "MTexPoly", 1, N_("UVMap") /* "Face Texture" */, NULL, NULL, NULL, NULL, NULL},
+ {sizeof(MTexPoly), "MTexPoly", 1, N_("UVMap") /* "Face Texture" */, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, layerMaxNum_tface},
/* 16: CD_MLOOPUV */
{sizeof(MLoopUV), "MLoopUV", 1, N_("UVMap"), NULL, NULL, layerInterp_mloopuv, NULL, NULL,
layerEqual_mloopuv, layerMultiply_mloopuv, layerInitMinMax_mloopuv,
- layerAdd_mloopuv, layerDoMinMax_mloopuv, layerCopyValue_mloopuv},
+ layerAdd_mloopuv, layerDoMinMax_mloopuv, layerCopyValue_mloopuv, NULL, NULL, NULL, layerMaxNum_tface},
/* 17: CD_MLOOPCOL */
{sizeof(MLoopCol), "MLoopCol", 1, N_("Col"), NULL, NULL, layerInterp_mloopcol, NULL,
layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol,
- layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol},
+ layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol, NULL, NULL, NULL, layerMaxNum_mloopcol},
/* 18: CD_TANGENT */
{sizeof(float) * 4 * 4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
/* 19: CD_MDISPS */
@@ -1319,7 +1333,8 @@ bool CustomData_merge(const struct CustomData *source, struct CustomData *dest,
/*const LayerTypeInfo *typeInfo;*/
CustomDataLayer *layer, *newlayer;
void *data;
- int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0, lastflag = 0;
+ int i, type, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0, lastflag = 0;
+ int number = 0, maxnumber = -1;
bool changed = false;
for (i = 0; i < source->totlayer; ++i) {
@@ -1330,6 +1345,7 @@ bool CustomData_merge(const struct CustomData *source, struct CustomData *dest,
if (type != lasttype) {
number = 0;
+ maxnumber = CustomData_layertype_layers_max(type);
lastactive = layer->active;
lastrender = layer->active_rnd;
lastclone = layer->active_clone;
@@ -1342,6 +1358,7 @@ bool CustomData_merge(const struct CustomData *source, struct CustomData *dest,
if (lastflag & CD_FLAG_NOCOPY) continue;
else if (!(mask & CD_TYPE_AS_MASK(type))) continue;
+ else if ((maxnumber != -1) && (number >= maxnumber)) continue;
else if (CustomData_get_layer_named(dest, type, layer->name)) continue;
switch (alloctype) {
@@ -1781,7 +1798,8 @@ bool CustomData_free_layer(CustomData *data, int type, int totelem, int index)
const int n = index - CustomData_get_layer_index(data, type);
int i;
- if (index < 0) return 0;
+ if (index < 0)
+ return false;
customData_free_layer__internal(&data->layers[index], totelem);
@@ -1811,14 +1829,15 @@ bool CustomData_free_layer(CustomData *data, int type, int totelem, int index)
customData_update_offsets(data);
- return 1;
+ return true;
}
bool CustomData_free_layer_active(CustomData *data, int type, int totelem)
{
int index = 0;
index = CustomData_get_active_layer_index(data, type);
- if (index == -1) return 0;
+ if (index == -1)
+ return false;
return CustomData_free_layer(data, type, totelem, index);
}
@@ -1856,14 +1875,13 @@ int CustomData_number_of_layers_typemask(const CustomData *data, CustomDataMask
return number;
}
-void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int type, const int totelem)
+static void *customData_duplicate_referenced_layer_index(CustomData *data, const int layer_index, const int totelem)
{
CustomDataLayer *layer;
- int layer_index;
- /* get the layer index of the first layer of type */
- layer_index = CustomData_get_active_layer_index(data, type);
- if (layer_index == -1) return NULL;
+ if (layer_index == -1) {
+ return NULL;
+ }
layer = &data->layers[layer_index];
@@ -1879,8 +1897,9 @@ void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int t
typeInfo->copy(layer->data, dest_data, totelem);
layer->data = dest_data;
}
- else
+ else {
layer->data = MEM_dupallocN(layer->data);
+ }
layer->flag &= ~CD_FLAG_NOFREE;
}
@@ -1888,37 +1907,34 @@ void *CustomData_duplicate_referenced_layer(struct CustomData *data, const int t
return layer->data;
}
-void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
- const int type, const char *name, const int totelem)
+void *CustomData_duplicate_referenced_layer(CustomData *data, const int type, const int totelem)
{
- CustomDataLayer *layer;
int layer_index;
- /* get the layer index of the desired layer */
- layer_index = CustomData_get_named_layer_index(data, type, name);
- if (layer_index == -1) return NULL;
+ /* get the layer index of the first layer of type */
+ layer_index = CustomData_get_active_layer_index(data, type);
- layer = &data->layers[layer_index];
+ return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
+}
- if (layer->flag & CD_FLAG_NOFREE) {
- /* MEM_dupallocN won't work in case of complex layers, like e.g.
- * CD_MDEFORMVERT, which has pointers to allocated data...
- * So in case a custom copy function is defined, use it!
- */
- const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
+void *CustomData_duplicate_referenced_layer_n(CustomData *data, const int type, const int n, const int totelem)
+{
+ int layer_index;
- if (typeInfo->copy) {
- char *dest_data = MEM_mallocN(typeInfo->size * totelem, "CD duplicate ref layer");
- typeInfo->copy(layer->data, dest_data, totelem);
- layer->data = dest_data;
- }
- else
- layer->data = MEM_dupallocN(layer->data);
+ /* get the layer index of the desired layer */
+ layer_index = CustomData_get_layer_index_n(data, type, n);
- layer->flag &= ~CD_FLAG_NOFREE;
- }
+ return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
+}
- return layer->data;
+void *CustomData_duplicate_referenced_layer_named(CustomData *data, const int type, const char *name, const int totelem)
+{
+ int layer_index;
+
+ /* get the layer index of the desired layer */
+ layer_index = CustomData_get_named_layer_index(data, type, name);
+
+ return customData_duplicate_referenced_layer_index(data, layer_index, totelem);
}
bool CustomData_is_referenced_layer(struct CustomData *data, int type)
@@ -1928,7 +1944,8 @@ bool CustomData_is_referenced_layer(struct CustomData *data, int type)
/* get the layer index of the first layer of type */
layer_index = CustomData_get_active_layer_index(data, type);
- if (layer_index == -1) return 0;
+ if (layer_index == -1)
+ return false;
layer = &data->layers[layer_index];
@@ -2246,8 +2263,8 @@ bool CustomData_set_layer_name(const CustomData *data, int type, int n, const ch
/* get the layer index of the first layer of type */
int layer_index = CustomData_get_layer_index_n(data, type, n);
- if (layer_index == -1) return false;
- if (!name) return false;
+ if ((layer_index == -1) || !name)
+ return false;
BLI_strncpy(data->layers[layer_index].name, name, sizeof(data->layers[layer_index].name));
@@ -3039,6 +3056,24 @@ bool CustomData_layertype_is_singleton(int type)
return typeInfo->defaultname == NULL;
}
+/**
+ * \return Maximum number of layers of given \a type, -1 means 'no limit'.
+ */
+int CustomData_layertype_layers_max(const int type)
+{
+ const LayerTypeInfo *typeInfo = layerType_getInfo(type);
+
+ /* Same test as for singleton above. */
+ if (typeInfo->defaultname == NULL) {
+ return 1;
+ }
+ else if (typeInfo->layers_max == NULL) {
+ return -1;
+ }
+
+ return typeInfo->layers_max();
+}
+
static bool CustomData_is_property_layer(int type)
{
if ((type == CD_PROP_FLT) || (type == CD_PROP_INT) || (type == CD_PROP_STR))
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 528ff2d7b19..d3148dbc8e9 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -441,7 +441,7 @@ int defgroup_name_index(Object *ob, const char *name)
/* note, must be freed */
int *defgroup_flip_map(Object *ob, int *flip_map_len, const bool use_default)
{
- int defbase_tot = *flip_map_len = BLI_countlist(&ob->defbase);
+ int defbase_tot = *flip_map_len = BLI_listbase_count(&ob->defbase);
if (defbase_tot == 0) {
return NULL;
@@ -480,7 +480,7 @@ int *defgroup_flip_map(Object *ob, int *flip_map_len, const bool use_default)
/* note, must be freed */
int *defgroup_flip_map_single(Object *ob, int *flip_map_len, const bool use_default, int defgroup)
{
- int defbase_tot = *flip_map_len = BLI_countlist(&ob->defbase);
+ int defbase_tot = *flip_map_len = BLI_listbase_count(&ob->defbase);
if (defbase_tot == 0) {
return NULL;
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 44a0b93fc01..566aa6657b9 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -2357,6 +2357,15 @@ void DAG_on_visible_update(Main *bmain, const bool do_time)
ob->recalc |= OB_RECALC_DATA;
lib_id_recalc_tag(bmain, &ob->id);
}
+ /* This should not be needed here, but in some cases, like after a redo, we can end up with
+ * a wrong final matrix (see T42472).
+ * Quoting Sergey, this comes from BKE_object_handle_update_ex, which is calling
+ * BKE_object_where_is_calc_ex when it shouldn't, but that issue is not easily fixable.
+ */
+ else {
+ ob->recalc |= OB_RECALC_OB;
+ lib_id_recalc_tag(bmain, &ob->id);
+ }
if (ob->proxy && (ob->proxy_group == NULL)) {
ob->proxy->recalc |= OB_RECALC_DATA;
lib_id_recalc_tag(bmain, &ob->id);
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 98f0025921d..80a8d373220 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -37,7 +37,6 @@
#include "MEM_guardedalloc.h"
#include "DNA_curve_types.h"
-#include "DNA_meshdata_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
#include "DNA_vfont_types.h"
@@ -1271,6 +1270,7 @@ void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase,
}
if (!for_orco) {
+ BKE_nurbList_duplicate(&ob->curve_cache->deformed_nurbs, &nubase);
curve_calc_modifiers_post(scene, ob, &nubase, dispbase, r_dm_final,
for_render, use_render_resolution);
}
@@ -1729,8 +1729,10 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
}
}
- if (!for_orco)
+ if (!for_orco) {
+ BKE_nurbList_duplicate(&ob->curve_cache->deformed_nurbs, &nubase);
curve_calc_modifiers_post(scene, ob, &nubase, dispbase, r_dm_final, for_render, use_render_resolution);
+ }
if (cu->flag & CU_DEFORM_FILL && !ob->derivedFinal) {
curve_to_filledpoly(cu, &nubase, dispbase);
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 4719013e2f8..e3fa4733e6c 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -71,10 +71,6 @@
#include "BKE_scene.h"
#include "BKE_texture.h"
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
/* for image output */
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -257,20 +253,20 @@ static int dynamicPaint_surfaceNumOfPoints(DynamicPaintSurface *surface)
bool dynamicPaint_surfaceHasColorPreview(DynamicPaintSurface *surface)
{
if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
- return 0;
+ return false;
}
else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE ||
surface->type == MOD_DPAINT_SURFACE_T_WAVE)
{
- return 0;
+ return false;
}
else {
- return 1;
+ return true;
}
}
else {
- return 1;
+ return true;
}
}
@@ -325,7 +321,7 @@ bool dynamicPaint_outputLayerExists(struct DynamicPaintSurface *surface, Object
else if (output == 1)
name = surface->output_name2;
else
- return 0;
+ return false;
if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
@@ -336,7 +332,7 @@ bool dynamicPaint_outputLayerExists(struct DynamicPaintSurface *surface, Object
return (defgroup_name_index(ob, surface->output_name) != -1);
}
- return 0;
+ return false;
}
static bool surface_duplicateOutputExists(void *arg, const char *name)
@@ -1106,13 +1102,13 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str
canvas = pmd->canvas = MEM_callocN(sizeof(DynamicPaintCanvasSettings), "DynamicPaint Canvas");
if (!canvas)
- return 0;
+ return false;
canvas->pmd = pmd;
canvas->dm = NULL;
/* Create one surface */
if (!dynamicPaint_createNewSurface(canvas, scene))
- return 0;
+ return false;
}
else if (type == MOD_DYNAMICPAINT_TYPE_BRUSH) {
@@ -1122,7 +1118,7 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str
brush = pmd->brush = MEM_callocN(sizeof(DynamicPaintBrushSettings), "DynamicPaint Paint");
if (!brush)
- return 0;
+ return false;
brush->pmd = pmd;
brush->psys = NULL;
@@ -1157,7 +1153,7 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str
brush->paint_ramp = add_colorband(false);
if (!brush->paint_ramp)
- return 0;
+ return false;
ramp = brush->paint_ramp->data;
/* Add default smooth-falloff ramp. */
ramp[0].r = ramp[0].g = ramp[0].b = ramp[0].a = 1.0f;
@@ -1173,7 +1169,7 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str
brush->vel_ramp = add_colorband(false);
if (!brush->vel_ramp)
- return 0;
+ return false;
ramp = brush->vel_ramp->data;
ramp[0].r = ramp[0].g = ramp[0].b = ramp[0].a = ramp[0].pos = 0.0f;
ramp[1].r = ramp[1].g = ramp[1].b = ramp[1].a = ramp[1].pos = 1.0f;
@@ -1181,10 +1177,11 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str
}
}
}
- else
- return 0;
+ else {
+ return false;
+ }
- return 1;
+ return true;
}
void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct DynamicPaintModifierData *tpmd)
@@ -1630,12 +1627,12 @@ bool dynamicPaint_resetSurface(Scene *scene, DynamicPaintSurface *surface)
if (surface->data) dynamicPaint_freeSurfaceData(surface);
/* don't reallocate for image sequence types. they get handled only on bake */
- if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) return 1;
- if (numOfPoints < 1) return 0;
+ if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) return true;
+ if (numOfPoints < 1) return false;
/* allocate memory */
surface->data = MEM_callocN(sizeof(PaintSurfaceData), "PaintSurfaceData");
- if (!surface->data) return 0;
+ if (!surface->data) return false;
/* allocate data depending on surface type and format */
surface->data->total_points = numOfPoints;
@@ -1646,7 +1643,7 @@ bool dynamicPaint_resetSurface(Scene *scene, DynamicPaintSurface *surface)
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT)
dynamicPaint_setInitialColor(scene, surface);
- return 1;
+ return true;
}
/* make sure allocated surface size matches current requirements */
@@ -1655,7 +1652,7 @@ static bool dynamicPaint_checkSurfaceData(Scene *scene, DynamicPaintSurface *sur
if (!surface->data || ((dynamicPaint_surfaceNumOfPoints(surface) != surface->data->total_points))) {
return dynamicPaint_resetSurface(scene, surface);
}
- return 1;
+ return true;
}
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index ce7804d9878..559eefc834e 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -56,6 +56,7 @@
#include "MEM_guardedalloc.h"
#include "GPU_extensions.h"
+#include "GPU_draw.h"
#include "GPU_glew.h"
extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */
@@ -607,13 +608,17 @@ static void emDM_drawMappedFaces(DerivedMesh *dm,
int drawSmooth;
efa = ltri[0]->f;
- drawSmooth = lnors || ((flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH));
-
+ drawSmooth = lnors || ((flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH));
+
draw_option = (!setDrawOptions ?
DM_DRAW_OPTION_NORMAL :
setDrawOptions(userData, BM_elem_index_get(efa)));
+
if (draw_option != DM_DRAW_OPTION_SKIP) {
const GLenum poly_type = GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */
+
+ GPU_enable_material(efa->mat_nr + 1, NULL);
+
if (draw_option == DM_DRAW_OPTION_STIPPLE) { /* enabled with stipple */
if (poly_prev != GL_ZERO) glEnd();
@@ -717,7 +722,7 @@ static void bmdm_get_tri_colpreview(BMLoop *ls[3], MLoopCol *lcol[3], unsigned c
static void emDM_drawFacesTex_common(DerivedMesh *dm,
DMSetDrawOptionsTex drawParams,
- DMSetDrawOptions drawParamsMapped,
+ DMSetDrawOptionsMappedTex drawParamsMapped,
DMCompareDrawOptions compareDrawOptions,
void *userData)
{
@@ -785,7 +790,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
if (drawParams)
draw_option = drawParams(&mtf, has_vcol, efa->mat_nr);
else if (drawParamsMapped)
- draw_option = drawParamsMapped(userData, BM_elem_index_get(efa));
+ draw_option = drawParamsMapped(userData, BM_elem_index_get(efa), BM_elem_index_get(efa));
else
draw_option = DM_DRAW_OPTION_NORMAL;
@@ -854,7 +859,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
if (drawParams)
draw_option = drawParams(&mtf, has_vcol, efa->mat_nr);
else if (drawParamsMapped)
- draw_option = drawParamsMapped(userData, BM_elem_index_get(efa));
+ draw_option = drawParamsMapped(userData, BM_elem_index_get(efa), BM_elem_index_get(efa));
else
draw_option = DM_DRAW_OPTION_NORMAL;
@@ -916,7 +921,7 @@ static void emDM_drawFacesTex(DerivedMesh *dm,
}
static void emDM_drawMappedFacesTex(DerivedMesh *dm,
- DMSetDrawOptions setDrawOptions,
+ DMSetDrawOptionsMappedTex setDrawOptions,
DMCompareDrawOptions compareDrawOptions,
void *userData, DMDrawFlag UNUSED(flag))
{
@@ -970,7 +975,7 @@ static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const B
GLubyte col[4];
if (attribs->mcol[i].em_offset != -1) {
const MLoopCol *cp = BM_ELEM_CD_GET_VOID_P(loop, attribs->mcol[i].em_offset);
- col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
+ copy_v4_v4_char((char *)col, &cp->r);
}
else {
col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0;
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index e90a0891436..64300ad6f52 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -309,17 +309,18 @@ int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix,
return matches;
}
-FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction **action, bool *r_driven)
+FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, AnimData **adt, bAction **action, bool *r_driven)
{
- return rna_get_fcurve_context_ui(NULL, ptr, prop, rnaindex, action, r_driven);
+ return rna_get_fcurve_context_ui(NULL, ptr, prop, rnaindex, adt, action, r_driven);
}
FCurve *rna_get_fcurve_context_ui(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int rnaindex,
- bAction **action, bool *r_driven)
+ AnimData **animdata, bAction **action, bool *r_driven)
{
FCurve *fcu = NULL;
PointerRNA tptr = *ptr;
+ if (animdata) *animdata = NULL;
*r_driven = false;
/* there must be some RNA-pointer + property combon */
@@ -350,11 +351,14 @@ FCurve *rna_get_fcurve_context_ui(bContext *C, PointerRNA *ptr, PropertyRNA *pro
if (!fcu && (adt->drivers.first)) {
fcu = list_find_fcurve(&adt->drivers, path, rnaindex);
- if (fcu)
+ if (fcu) {
+ if (animdata) *animdata = adt;
*r_driven = true;
+ }
}
if (fcu && action) {
+ if (animdata) *animdata = adt;
*action = adt->action;
break;
}
@@ -683,11 +687,11 @@ bool fcurve_are_keyframes_usable(FCurve *fcu)
{
/* F-Curve must exist */
if (fcu == NULL)
- return 0;
+ return false;
/* F-Curve must not have samples - samples are mutually exclusive of keyframes */
if (fcu->fpt)
- return 0;
+ return false;
/* if it has modifiers, none of these should "drastically" alter the curve */
if (fcu->modifiers.first) {
@@ -714,7 +718,7 @@ bool fcurve_are_keyframes_usable(FCurve *fcu)
FMod_Generator *data = (FMod_Generator *)fcm->data;
if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0)
- return 0;
+ return false;
break;
}
case FMODIFIER_TYPE_FN_GENERATOR:
@@ -722,18 +726,18 @@ bool fcurve_are_keyframes_usable(FCurve *fcu)
FMod_FunctionGenerator *data = (FMod_FunctionGenerator *)fcm->data;
if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0)
- return 0;
+ return false;
break;
}
/* always harmful - cannot allow */
default:
- return 0;
+ return false;
}
}
}
/* keyframes are usable */
- return 1;
+ return true;
}
bool BKE_fcurve_is_protected(FCurve *fcu)
@@ -2153,18 +2157,29 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime
v4[0] = bezt->vec[1][0];
v4[1] = bezt->vec[1][1];
- /* adjust handles so that they don't overlap (forming a loop) */
- correct_bezpart(v1, v2, v3, v4);
-
- /* try to get a value for this position - if failure, try another set of points */
- b = findzero(evaltime, v1[0], v2[0], v3[0], v4[0], opl);
- if (b) {
- berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1);
- cvalue = opl[0];
- /* break; */
+ if (fabsf(v1[1] - v4[1]) < FLT_EPSILON &&
+ fabsf(v2[1] - v3[1]) < FLT_EPSILON &&
+ fabsf(v3[1] - v4[1]) < FLT_EPSILON)
+ {
+ /* Optimisation: If all the handles are flat/at the same values,
+ * the value is simply the shared value (see T40372 -> F91346)
+ */
+ cvalue = v1[1];
}
else {
- if (G.debug & G_DEBUG) printf(" ERROR: findzero() failed at %f with %f %f %f %f\n", evaltime, v1[0], v2[0], v3[0], v4[0]);
+ /* adjust handles so that they don't overlap (forming a loop) */
+ correct_bezpart(v1, v2, v3, v4);
+
+ /* try to get a value for this position - if failure, try another set of points */
+ b = findzero(evaltime, v1[0], v2[0], v3[0], v4[0], opl);
+ if (b) {
+ berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1);
+ cvalue = opl[0];
+ /* break; */
+ }
+ else {
+ if (G.debug & G_DEBUG) printf(" ERROR: findzero() failed at %f with %f %f %f %f\n", evaltime, v1[0], v2[0], v3[0], v4[0]);
+ }
}
break;
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index 56b087e7eb6..af0db5e1c47 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -27,8 +27,6 @@
* \ingroup bke
*/
-
-
#include <math.h>
#include <stdio.h>
#include <stddef.h>
@@ -1173,7 +1171,7 @@ bool remove_fmodifier(ListBase *modifiers, FModifier *fcm)
/* sanity check */
if (fcm == NULL)
- return 0;
+ return false;
/* free modifier's special data (stored inside fcm->data) */
if (fcm->data) {
@@ -1187,13 +1185,13 @@ bool remove_fmodifier(ListBase *modifiers, FModifier *fcm)
/* remove modifier from stack */
if (modifiers) {
BLI_freelinkN(modifiers, fcm);
- return 1;
+ return true;
}
else {
/* XXX this case can probably be removed some day, as it shouldn't happen... */
printf("remove_fmodifier() - no modifier stack given\n");
MEM_freeN(fcm);
- return 0;
+ return false;
}
}
@@ -1264,7 +1262,7 @@ bool list_has_suitable_fmodifier(ListBase *modifiers, int mtype, short acttype)
/* sanity checks */
if (ELEM(NULL, modifiers, modifiers->first))
- return 0;
+ return false;
/* find the first mdifier fitting these criteria */
for (fcm = modifiers->first; fcm; fcm = fcm->next) {
@@ -1279,11 +1277,11 @@ bool list_has_suitable_fmodifier(ListBase *modifiers, int mtype, short acttype)
/* if both are ok, we've found a hit */
if (mOk && aOk)
- return 1;
+ return true;
}
/* no matches */
- return 0;
+ return false;
}
/* Evaluation API --------------------------- */
diff --git a/source/blender/blenkernel/intern/freestyle.c b/source/blender/blenkernel/intern/freestyle.c
index 4aa1b49ea13..cc9ad63d451 100644
--- a/source/blender/blenkernel/intern/freestyle.c
+++ b/source/blender/blenkernel/intern/freestyle.c
@@ -181,7 +181,7 @@ static FreestyleLineSet *alloc_lineset(void)
FreestyleLineSet *BKE_freestyle_lineset_add(FreestyleConfig *config, const char *name)
{
- int lineset_index = BLI_countlist(&config->linesets);
+ int lineset_index = BLI_listbase_count(&config->linesets);
FreestyleLineSet *lineset = alloc_lineset();
BLI_addtail(&config->linesets, (void *)lineset);
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index e226e9d9797..dd2155505fb 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -45,6 +45,7 @@
#include "DNA_gpencil_types.h"
#include "DNA_userdef_types.h"
+#include "BKE_animsys.h"
#include "BKE_global.h"
#include "BKE_gpencil.h"
#include "BKE_library.h"
@@ -115,6 +116,12 @@ void BKE_gpencil_free(bGPdata *gpd)
{
/* free layers */
free_gpencil_layers(&gpd->layers);
+
+ /* free animation data */
+ if (gpd->adt) {
+ BKE_free_animdata(&gpd->id);
+ gpd->adt = NULL;
+ }
}
/* -------- Container Creation ---------- */
@@ -276,7 +283,7 @@ bGPDlayer *gpencil_layer_duplicate(bGPDlayer *src)
}
/* make a copy of a given gpencil datablock */
-bGPdata *gpencil_data_duplicate(bGPdata *src)
+bGPdata *gpencil_data_duplicate(bGPdata *src, bool internal_copy)
{
bGPDlayer *gpl, *gpld;
bGPdata *dst;
@@ -286,7 +293,14 @@ bGPdata *gpencil_data_duplicate(bGPdata *src)
return NULL;
/* make a copy of the base-data */
- dst = MEM_dupallocN(src);
+ if (internal_copy) {
+ /* make a straight copy for undo buffers used during stroke drawing */
+ dst = MEM_dupallocN(src);
+ }
+ else {
+ /* make a copy when others use this */
+ dst = BKE_libblock_copy(&src->id);
+ }
/* copy layers */
BLI_listbase_clear(&dst->layers);
@@ -300,6 +314,31 @@ bGPdata *gpencil_data_duplicate(bGPdata *src)
return dst;
}
+/* -------- GP-Stroke API --------- */
+
+/* ensure selection status of stroke is in sync with its points */
+void gpencil_stroke_sync_selection(bGPDstroke *gps)
+{
+ bGPDspoint *pt;
+ int i;
+
+ /* error checking */
+ if (gps == NULL)
+ return;
+
+ /* we'll stop when we find the first selected point,
+ * so initially, we must deselect
+ */
+ gps->flag &= ~GP_STROKE_SELECT;
+
+ for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
+ if (pt->flag & GP_SPOINT_SELECT) {
+ gps->flag |= GP_STROKE_SELECT;
+ break;
+ }
+ }
+}
+
/* -------- GP-Frame API ---------- */
/* delete the last stroke of the given frame */
@@ -359,7 +398,7 @@ bGPDframe *gpencil_layer_getframe(bGPDlayer *gpl, int cframe, short addnew)
/* do not allow any changes to layer's active frame if layer is locked from changes
* or if the layer has been set to stay on the current frame
*/
- if (gpl->flag & (GP_LAYER_LOCKED | GP_LAYER_FRAMELOCK))
+ if (gpl->flag & GP_LAYER_FRAMELOCK)
return gpf;
/* do not allow any changes to actframe if frame has painting tag attached to it */
if (gpf->flag & GP_FRAME_PAINT)
@@ -468,16 +507,23 @@ bGPDframe *gpencil_layer_getframe(bGPDlayer *gpl, int cframe, short addnew)
bool gpencil_layer_delframe(bGPDlayer *gpl, bGPDframe *gpf)
{
bool changed = false;
-
+
/* error checking */
if (ELEM(NULL, gpl, gpf))
return false;
-
+
+ /* if this frame was active, make the previous frame active instead
+ * since it's tricky to set active frame otherwise
+ */
+ if (gpl->actframe == gpf)
+ gpl->actframe = gpf->prev;
+ else
+ gpl->actframe = NULL;
+
/* free the frame and its data */
changed = free_gpencil_strokes(gpf);
BLI_freelinkN(&gpl->frames, gpf);
- gpl->actframe = NULL;
-
+
return changed;
}
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 4dbd15a3774..2b99b5f4620 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -42,10 +42,18 @@
#include "MEM_guardedalloc.h"
+#include "BLI_strict_flags.h"
+
/* IDPropertyTemplate is a union in DNA_ID.h */
+/**
+ * if the new is 'IDP_ARRAY_REALLOC_LIMIT' items less,
+ * than #IDProperty.totallen, reallocate anyway.
+ */
+#define IDP_ARRAY_REALLOC_LIMIT 200
+
/*local size table.*/
-static char idp_size_table[] = {
+static size_t idp_size_table[] = {
1, /*strings*/
sizeof(int),
sizeof(float),
@@ -158,9 +166,8 @@ void IDP_ResizeIDPArray(IDProperty *prop, int newlen)
BLI_assert(prop->type == IDP_IDPARRAY);
/* first check if the array buffer size has room */
- /* if newlen is 200 items less then totallen, reallocate anyway */
if (newlen <= prop->totallen) {
- if (newlen < prop->len && prop->totallen - newlen < 200) {
+ if (newlen < prop->len && prop->totallen - newlen < IDP_ARRAY_REALLOC_LIMIT) {
int i;
for (i = newlen; i < prop->len; i++)
@@ -194,7 +201,7 @@ void IDP_ResizeIDPArray(IDProperty *prop, int newlen)
*/
newsize = newlen;
newsize = (newsize >> 3) + (newsize < 9 ? 3 : 6) + newsize;
- prop->data.pointer = MEM_recallocN(prop->data.pointer, sizeof(IDProperty) * newsize);
+ prop->data.pointer = MEM_recallocN(prop->data.pointer, sizeof(IDProperty) * (size_t)newsize);
prop->len = newlen;
prop->totallen = newsize;
}
@@ -235,8 +242,7 @@ void IDP_ResizeArray(IDProperty *prop, int newlen)
const bool is_grow = newlen >= prop->len;
/* first check if the array buffer size has room */
- /* if newlen is 200 chars less then totallen, reallocate anyway */
- if (newlen <= prop->totallen && prop->totallen - newlen < 200) {
+ if (newlen <= prop->totallen && prop->totallen - newlen < IDP_ARRAY_REALLOC_LIMIT) {
idp_resize_group_array(prop, newlen, prop->data.pointer);
prop->len = newlen;
return;
@@ -256,7 +262,8 @@ void IDP_ResizeArray(IDProperty *prop, int newlen)
if (is_grow == false)
idp_resize_group_array(prop, newlen, prop->data.pointer);
- prop->data.pointer = MEM_recallocN(prop->data.pointer, idp_size_table[(int)prop->subtype] * newsize);
+ prop->data.pointer = MEM_recallocN(
+ prop->data.pointer, idp_size_table[(int)prop->subtype] * (size_t)newsize);
if (is_grow == true)
idp_resize_group_array(prop, newlen, prop->data.pointer);
@@ -321,8 +328,8 @@ static IDProperty *IDP_CopyArray(const IDProperty *prop)
*
* \param st The string to assign.
* \param name The property name.
- * \param maxlen The size of the new string (including the \0 terminator)
- * \return
+ * \param maxlen The size of the new string (including the \0 terminator).
+ * \return The new string property.
*/
IDProperty *IDP_NewString(const char *st, const char *name, int maxlen)
{
@@ -336,14 +343,14 @@ IDProperty *IDP_NewString(const char *st, const char *name, int maxlen)
}
else {
/* include null terminator '\0' */
- int stlen = strlen(st) + 1;
+ int stlen = (int)strlen(st) + 1;
if (maxlen > 0 && maxlen < stlen)
stlen = maxlen;
- prop->data.pointer = MEM_mallocN(stlen, "id property string 2");
+ prop->data.pointer = MEM_mallocN((size_t)stlen, "id property string 2");
prop->len = prop->totallen = stlen;
- BLI_strncpy(prop->data.pointer, st, stlen);
+ BLI_strncpy(prop->data.pointer, st, (size_t)stlen);
}
prop->type = IDP_STRING;
@@ -374,18 +381,18 @@ void IDP_AssignString(IDProperty *prop, const char *st, int maxlen)
int stlen;
BLI_assert(prop->type == IDP_STRING);
- stlen = strlen(st);
+ stlen = (int)strlen(st);
if (maxlen > 0 && maxlen < stlen)
stlen = maxlen;
if (prop->subtype == IDP_STRING_SUB_BYTE) {
IDP_ResizeArray(prop, stlen);
- memcpy(prop->data.pointer, st, stlen);
+ memcpy(prop->data.pointer, st, (size_t)stlen);
}
else {
stlen++;
IDP_ResizeArray(prop, stlen);
- BLI_strncpy(prop->data.pointer, st, stlen);
+ BLI_strncpy(prop->data.pointer, st, (size_t)stlen);
}
}
@@ -395,7 +402,7 @@ void IDP_ConcatStringC(IDProperty *prop, const char *st)
BLI_assert(prop->type == IDP_STRING);
- newlen = prop->len + strlen(st);
+ newlen = prop->len + (int)strlen(st);
/* we have to remember that prop->len includes the null byte for strings.
* so there's no need to add +1 to the resize function.*/
IDP_ResizeArray(prop, newlen);
@@ -571,18 +578,18 @@ void IDP_ReplaceGroupInGroup(IDProperty *dest, const IDProperty *src)
* Checks if a property with the same name as prop exists, and if so replaces it.
* Use this to preserve order!
*/
-void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop)
+void IDP_ReplaceInGroup_ex(IDProperty *group, IDProperty *prop, IDProperty *prop_exist)
{
- IDProperty *loop;
-
BLI_assert(group->type == IDP_GROUP);
- if ((loop = IDP_GetPropertyFromGroup(group, prop->name))) {
- BLI_insertlinkafter(&group->data.group, loop, prop);
+ BLI_assert(prop_exist == IDP_GetPropertyFromGroup(group, prop->name));
+
+ if ((prop_exist = IDP_GetPropertyFromGroup(group, prop->name))) {
+ BLI_insertlinkafter(&group->data.group, prop_exist, prop);
- BLI_remlink(&group->data.group, loop);
- IDP_FreeProperty(loop);
- MEM_freeN(loop);
+ BLI_remlink(&group->data.group, prop_exist);
+ IDP_FreeProperty(prop_exist);
+ MEM_freeN(prop_exist);
}
else {
group->len++;
@@ -590,6 +597,13 @@ void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop)
}
}
+void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop)
+{
+ IDProperty *prop_exist = IDP_GetPropertyFromGroup(group, prop->name);
+
+ IDP_ReplaceInGroup_ex(group, prop, prop_exist);
+}
+
/**
* If a property is missing in \a dest, add it.
*/
@@ -623,8 +637,8 @@ void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overw
*
* The sanity check just means the property is not added to the group if another property
* exists with the same name; the client code using ID properties then needs to detect this
- * (the function that adds new properties to groups, IDP_AddToGroup,returns 0 if a property can't
- * be added to the group, and 1 if it can) and free the property.
+ * (the function that adds new properties to groups, IDP_AddToGroup, returns false if a property can't
+ * be added to the group, and true if it can) and free the property.
*
* Currently the code to free ID properties is designed to leave the actual struct
* you pass it un-freed, this is needed for how the system works. This means
@@ -639,10 +653,10 @@ bool IDP_AddToGroup(IDProperty *group, IDProperty *prop)
if (IDP_GetPropertyFromGroup(group, prop->name) == NULL) {
group->len++;
BLI_addtail(&group->data.group, prop);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/**
@@ -656,10 +670,10 @@ bool IDP_InsertToGroup(IDProperty *group, IDProperty *previous, IDProperty *pnew
if (IDP_GetPropertyFromGroup(group, pnew->name) == NULL) {
group->len++;
BLI_insertlinkafter(&group->data.group, previous, pnew);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/**
@@ -700,56 +714,6 @@ IDProperty *IDP_GetPropertyTypeFromGroup(IDProperty *prop, const char *name, con
return (idprop && idprop->type == type) ? idprop : NULL;
}
-typedef struct IDPIter {
- void *next;
- IDProperty *parent;
-} IDPIter;
-
-/**
- * Get an iterator to iterate over the members of an id property group.
- * Note that this will automatically free the iterator once iteration is complete;
- * if you stop the iteration before hitting the end, make sure to call
- * IDP_FreeIterBeforeEnd().
- */
-void *IDP_GetGroupIterator(IDProperty *prop)
-{
- IDPIter *iter;
-
- BLI_assert(prop->type == IDP_GROUP);
- iter = MEM_mallocN(sizeof(IDPIter), "IDPIter");
- iter->next = prop->data.group.first;
- iter->parent = prop;
- return (void *) iter;
-}
-
-/**
- * Returns the next item in the iteration. To use, simple for a loop like the following:
- * while (IDP_GroupIterNext(iter) != NULL) {
- * ...
- * }
- */
-IDProperty *IDP_GroupIterNext(void *vself)
-{
- IDPIter *self = (IDPIter *) vself;
- Link *next = (Link *) self->next;
- if (self->next == NULL) {
- MEM_freeN(self);
- return NULL;
- }
-
- self->next = next->next;
- return (void *) next;
-}
-
-/**
- * Frees the iterator pointed to at vself, only use this if iteration is stopped early;
- * when the iterator hits the end of the list it'll automatically free itself.\
- */
-void IDP_FreeIterBeforeEnd(void *vself)
-{
- MEM_freeN(vself);
-}
-
/* Ok, the way things work, Groups free the ID Property structs of their children.
* This is because all ID Property freeing functions free only direct data (not the ID Property
* struct itself), but for Groups the child properties *are* considered
@@ -811,11 +775,11 @@ IDProperty *IDP_GetProperties(ID *id, const bool create_if_needed)
bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is_strict)
{
if (prop1 == NULL && prop2 == NULL)
- return 1;
+ return true;
else if (prop1 == NULL || prop2 == NULL)
- return is_strict ? 0 : 1;
+ return is_strict ? false : true;
else if (prop1->type != prop2->type)
- return 0;
+ return false;
switch (prop1->type) {
case IDP_INT:
@@ -838,27 +802,32 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is
case IDP_DOUBLE:
return (IDP_Double(prop1) == IDP_Double(prop2));
case IDP_STRING:
- return ((prop1->len == prop2->len) && strncmp(IDP_String(prop1), IDP_String(prop2), prop1->len) == 0);
+ {
+ return (((prop1->len == prop2->len) &&
+ strncmp(IDP_String(prop1), IDP_String(prop2), (size_t)prop1->len) == 0));
+ }
case IDP_ARRAY:
if (prop1->len == prop2->len && prop1->subtype == prop2->subtype) {
- return memcmp(IDP_Array(prop1), IDP_Array(prop2), idp_size_table[(int)prop1->subtype] * prop1->len);
+ return (memcmp(IDP_Array(prop1),
+ IDP_Array(prop2),
+ idp_size_table[(int)prop1->subtype] * (size_t)prop1->len) == 0);
}
- return 0;
+ return false;
case IDP_GROUP:
{
IDProperty *link1, *link2;
if (is_strict && prop1->len != prop2->len)
- return 0;
+ return false;
for (link1 = prop1->data.group.first; link1; link1 = link1->next) {
link2 = IDP_GetPropertyFromGroup(prop2, link1->name);
if (!IDP_EqualsProperties_ex(link1, link2, is_strict))
- return 0;
+ return false;
}
- return 1;
+ return true;
}
case IDP_IDPARRAY:
{
@@ -867,12 +836,12 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is
int i;
if (prop1->len != prop2->len)
- return 0;
+ return false;
for (i = 0; i < prop1->len; i++)
if (!IDP_EqualsProperties(&array1[i], &array2[i]))
- return 0;
- return 1;
+ return false;
+ return true;
}
default:
/* should never get here */
@@ -880,7 +849,7 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is
break;
}
- return 1;
+ return true;
}
bool IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2)
@@ -913,7 +882,7 @@ bool IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2)
* IDP_AddToGroup or MEM_freeN the property, doing anything else might result in
* a memory leak.
*/
-IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *name)
+IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *name)
{
IDProperty *prop = NULL;
@@ -940,8 +909,10 @@ IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *n
{
prop = MEM_callocN(sizeof(IDProperty), "IDProperty array");
prop->subtype = val->array.type;
- if (val->array.len)
- prop->data.pointer = MEM_callocN(idp_size_table[val->array.type] * val->array.len, "id property array");
+ if (val->array.len) {
+ prop->data.pointer = MEM_callocN(
+ idp_size_table[val->array.type] * (size_t)val->array.len, "id property array");
+ }
prop->len = prop->totallen = val->array.len;
break;
}
@@ -961,9 +932,9 @@ IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *n
prop->len = 0;
}
else {
- prop->data.pointer = MEM_mallocN(val->string.len, "id property string 2");
+ prop->data.pointer = MEM_mallocN((size_t)val->string.len, "id property string 2");
prop->len = prop->totallen = val->string.len;
- memcpy(prop->data.pointer, st, val->string.len);
+ memcpy(prop->data.pointer, st, (size_t)val->string.len);
}
prop->subtype = IDP_STRING_SUB_BYTE;
}
@@ -975,10 +946,10 @@ IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *n
prop->len = 1; /*NULL string, has len of 1 to account for null byte.*/
}
else {
- int stlen = strlen(st) + 1;
- prop->data.pointer = MEM_mallocN(stlen, "id property string 3");
+ int stlen = (int)strlen(st) + 1;
+ prop->data.pointer = MEM_mallocN((size_t)stlen, "id property string 3");
prop->len = prop->totallen = stlen;
- memcpy(prop->data.pointer, st, stlen);
+ memcpy(prop->data.pointer, st, (size_t)stlen);
}
prop->subtype = IDP_STRING_SUB_UTF8;
}
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 5c673eeef3f..36cd7e69601 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -249,7 +249,7 @@ void BKE_image_de_interlace(Image *ima, int odd)
/* ***************** ALLOC & FREE, DATA MANAGING *************** */
-static void image_free_cahced_frames(Image *image)
+static void image_free_cached_frames(Image *image)
{
if (image->cache) {
IMB_moviecache_free(image->cache);
@@ -263,7 +263,7 @@ static void image_free_cahced_frames(Image *image)
*/
void BKE_image_free_buffers(Image *ima)
{
- image_free_cahced_frames(ima);
+ image_free_cached_frames(ima);
if (ima->anim) IMB_free_anim(ima->anim);
ima->anim = NULL;
@@ -273,7 +273,13 @@ void BKE_image_free_buffers(Image *ima)
ima->rr = NULL;
}
- GPU_free_image(ima);
+ if (!G.background) {
+ /* Background mode doesn't use opnegl,
+ * so we can avoid freeing GPU images and save some
+ * time by skipping mutex lock.
+ */
+ GPU_free_image(ima);
+ }
ima->ok = IMA_OK;
}
@@ -661,7 +667,7 @@ Image *BKE_image_load(Main *bmain, const char *filepath)
/* otherwise creates new. */
/* does not load ibuf itself */
/* pass on optional frame for #name images */
-Image *BKE_image_load_exists(const char *filepath)
+Image *BKE_image_load_exists_ex(const char *filepath, bool *r_exists)
{
Image *ima;
char str[FILE_MAX], strtest[FILE_MAX];
@@ -681,16 +687,24 @@ Image *BKE_image_load_exists(const char *filepath)
ima->id.us++; /* officially should not, it doesn't link here! */
if (ima->ok == 0)
ima->ok = IMA_OK;
- /* RETURN! */
+ if (r_exists)
+ *r_exists = true;
return ima;
}
}
}
}
+ if (r_exists)
+ *r_exists = false;
return BKE_image_load(G.main, filepath);
}
+Image *BKE_image_load_exists(const char *filepath)
+{
+ return BKE_image_load_exists_ex(filepath, NULL);
+}
+
static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type,
const float color[4], ColorManagedColorspaceSettings *colorspace_settings)
{
@@ -2529,7 +2543,7 @@ static ImBuf *image_load_sequence_multilayer(Image *ima, ImageUser *iuser, int f
* need to ensure there's no image buffers are hanging around
* with dead links after freeing the render result.
*/
- image_free_cahced_frames(ima);
+ image_free_cached_frames(ima);
RE_FreeRenderResult(ima->rr);
ima->rr = NULL;
}
@@ -3393,9 +3407,9 @@ bool BKE_image_has_alpha(struct Image *image)
BKE_image_release_ibuf(image, ibuf, lock);
if (planes == 32)
- return 1;
+ return true;
else
- return 0;
+ return false;
}
void BKE_image_get_size(Image *image, ImageUser *iuser, int *width, int *height)
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index 4cf9d52989f..fe64af184a9 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -144,14 +144,6 @@ DO_INLINE void mul_fvector_S(float to[3], float from[3], float scalar)
to[1] = from[1] * scalar;
to[2] = from[2] * scalar;
}
-/* simple cross product */
-/* STATUS: verified */
-DO_INLINE void cross_fvector(float to[3], float vectorA[3], float vectorB[3])
-{
- to[0] = vectorA[1] * vectorB[2] - vectorA[2] * vectorB[1];
- to[1] = vectorA[2] * vectorB[0] - vectorA[0] * vectorB[2];
- to[2] = vectorA[0] * vectorB[1] - vectorA[1] * vectorB[0];
-}
/* simple v^T * v product ("outer product") */
/* STATUS: HAS TO BE verified (*should* work) */
DO_INLINE void mul_fvectorT_fvector(float to[3][3], float vectorA[3], float vectorB[3])
@@ -337,6 +329,7 @@ DO_INLINE void initdiag_fmatrixS(float to[3][3], float aS)
to[2][2] = aS;
}
+#if 0
/* calculate determinant of 3x3 matrix */
DO_INLINE float det_fmatrix(float m[3][3])
{
@@ -371,6 +364,7 @@ DO_INLINE void inverse_fmatrix(float to[3][3], float from[3][3])
}
}
+#endif
/* 3x3 matrix multiplied by a scalar */
/* STATUS: verified */
@@ -398,14 +392,6 @@ DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][3], float from[3])
to[1] = dot_v3v3(matrix[1], from);
to[2] = dot_v3v3(matrix[2], from);
}
-/* 3x3 matrix multiplied by a 3x3 matrix */
-/* STATUS: verified */
-DO_INLINE void mul_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
-{
- mul_fvector_fmatrix(to[0], matrixA[0], matrixB);
- mul_fvector_fmatrix(to[1], matrixA[1], matrixB);
- mul_fvector_fmatrix(to[2], matrixA[2], matrixB);
-}
/* 3x3 matrix addition with 3x3 matrix */
DO_INLINE void add_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
{
@@ -413,27 +399,6 @@ DO_INLINE void add_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float ma
VECADD(to[1], matrixA[1], matrixB[1]);
VECADD(to[2], matrixA[2], matrixB[2]);
}
-/* 3x3 matrix add-addition with 3x3 matrix */
-DO_INLINE void addadd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
-{
- VECADDADD(to[0], matrixA[0], matrixB[0]);
- VECADDADD(to[1], matrixA[1], matrixB[1]);
- VECADDADD(to[2], matrixA[2], matrixB[2]);
-}
-/* 3x3 matrix sub-addition with 3x3 matrix */
-DO_INLINE void addsub_fmatrixS_fmatrixS(float to[3][3], float matrixA[3][3], float aS, float matrixB[3][3], float bS)
-{
- VECADDSUBSS(to[0], matrixA[0], aS, matrixB[0], bS);
- VECADDSUBSS(to[1], matrixA[1], aS, matrixB[1], bS);
- VECADDSUBSS(to[2], matrixA[2], aS, matrixB[2], bS);
-}
-/* A -= B + C (3x3 matrix sub-addition with 3x3 matrix) */
-DO_INLINE void subadd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
-{
- VECSUBADD(to[0], matrixA[0], matrixB[0]);
- VECSUBADD(to[1], matrixA[1], matrixB[1]);
- VECSUBADD(to[2], matrixA[2], matrixB[2]);
-}
/* A -= B*x + C*y (3x3 matrix sub-addition with 3x3 matrix) */
DO_INLINE void subadd_fmatrixS_fmatrixS(float to[3][3], float matrixA[3][3], float aS, float matrixB[3][3], float bS)
{
@@ -448,44 +413,9 @@ DO_INLINE void sub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float ma
sub_v3_v3v3(to[1], matrixA[1], matrixB[1]);
sub_v3_v3v3(to[2], matrixA[2], matrixB[2]);
}
-/* A += B - C (3x3 matrix add-subtraction with 3x3 matrix) */
-DO_INLINE void addsub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
-{
- VECADDSUB(to[0], matrixA[0], matrixB[0]);
- VECADDSUB(to[1], matrixA[1], matrixB[1]);
- VECADDSUB(to[2], matrixA[2], matrixB[2]);
-}
/////////////////////////////////////////////////////////////////
// special functions
/////////////////////////////////////////////////////////////////
-/* a vector multiplied and added to/by a 3x3 matrix */
-DO_INLINE void muladd_fvector_fmatrix(float to[3], float from[3], float matrix[3][3])
-{
- to[0] += matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2];
- to[1] += matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2];
- to[2] += matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2];
-}
-/* 3x3 matrix multiplied and added to/by a 3x3 matrix and added to another 3x3 matrix */
-DO_INLINE void muladd_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
-{
- muladd_fvector_fmatrix(to[0], matrixA[0], matrixB);
- muladd_fvector_fmatrix(to[1], matrixA[1], matrixB);
- muladd_fvector_fmatrix(to[2], matrixA[2], matrixB);
-}
-/* a vector multiplied and sub'd to/by a 3x3 matrix */
-DO_INLINE void mulsub_fvector_fmatrix(float to[3], float from[3], float matrix[3][3])
-{
- to[0] -= matrix[0][0]*from[0] + matrix[1][0]*from[1] + matrix[2][0]*from[2];
- to[1] -= matrix[0][1]*from[0] + matrix[1][1]*from[1] + matrix[2][1]*from[2];
- to[2] -= matrix[0][2]*from[0] + matrix[1][2]*from[1] + matrix[2][2]*from[2];
-}
-/* 3x3 matrix multiplied and sub'd to/by a 3x3 matrix and added to another 3x3 matrix */
-DO_INLINE void mulsub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
-{
- mulsub_fvector_fmatrix(to[0], matrixA[0], matrixB);
- mulsub_fvector_fmatrix(to[1], matrixA[1], matrixB);
- mulsub_fvector_fmatrix(to[2], matrixA[2], matrixB);
-}
/* 3x3 matrix multiplied+added by a vector */
/* STATUS: verified */
DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][3], float from[3])
@@ -494,13 +424,6 @@ DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][3], float fro
to[1] += dot_v3v3(matrix[1], from);
to[2] += dot_v3v3(matrix[2], from);
}
-/* 3x3 matrix multiplied+sub'ed by a vector */
-DO_INLINE void mulsub_fmatrix_fvector(float to[3], float matrix[3][3], float from[3])
-{
- to[0] -= dot_v3v3(matrix[0], from);
- to[1] -= dot_v3v3(matrix[1], from);
- to[2] -= dot_v3v3(matrix[2], from);
-}
/////////////////////////////////////////////////////////////////
///////////////////////////
@@ -569,15 +492,6 @@ DO_INLINE void initdiag_bfmatrix(fmatrix3x3 *matrix, float m3[3][3])
}
}
-/* multiply big matrix with scalar*/
-DO_INLINE void mul_bfmatrix_S(fmatrix3x3 *matrix, float scalar)
-{
- unsigned int i = 0;
- for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) {
- mul_fmatrix_S(matrix[i].m, scalar);
- }
-}
-
/* SPARSE SYMMETRIC multiply big matrix with long vector*/
/* STATUS: verified */
DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector)
@@ -610,83 +524,6 @@ DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector
}
-/* SPARSE SYMMETRIC multiply big matrix with long vector (for diagonal preconditioner) */
-/* STATUS: verified */
-DO_INLINE void mul_prevfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector)
-{
- unsigned int i = 0;
-
- for (i = 0; i < from[0].vcount; i++) {
- mul_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]);
- }
-}
-
-/* SPARSE SYMMETRIC add big matrix with big matrix: A = B + C*/
-DO_INLINE void add_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix)
-{
- unsigned int i = 0;
-
- /* process diagonal elements */
- for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) {
- add_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m);
- }
-
-}
-/* SPARSE SYMMETRIC add big matrix with big matrix: A += B + C */
-DO_INLINE void addadd_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix)
-{
- unsigned int i = 0;
-
- /* process diagonal elements */
- for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) {
- addadd_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m);
- }
-
-}
-/* SPARSE SYMMETRIC subadd big matrix with big matrix: A -= B + C */
-DO_INLINE void subadd_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix)
-{
- unsigned int i = 0;
-
- /* process diagonal elements */
- for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) {
- subadd_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m);
- }
-
-}
-/* A = B - C (SPARSE SYMMETRIC sub big matrix with big matrix) */
-DO_INLINE void sub_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix)
-{
- unsigned int i = 0;
-
- /* process diagonal elements */
- for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) {
- sub_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m);
- }
-
-}
-/* SPARSE SYMMETRIC sub big matrix with big matrix S (special constraint matrix with limited entries) */
-DO_INLINE void sub_bfmatrix_Smatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix)
-{
- unsigned int i = 0;
-
- /* process diagonal elements */
- for (i = 0; i < matrix[0].vcount; i++) {
- sub_fmatrix_fmatrix(to[matrix[i].c].m, from[matrix[i].c].m, matrix[i].m);
- }
-
-}
-/* A += B - C (SPARSE SYMMETRIC addsub big matrix with big matrix) */
-DO_INLINE void addsub_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from, fmatrix3x3 *matrix)
-{
- unsigned int i = 0;
-
- /* process diagonal elements */
- for (i = 0; i < matrix[0].vcount+matrix[0].scount; i++) {
- addsub_fmatrix_fmatrix(to[i].m, from[i].m, matrix[i].m);
- }
-
-}
/* SPARSE SYMMETRIC sub big matrix with big matrix*/
/* A -= B * float + C * float --> for big matrix */
/* VERIFIED */
@@ -849,14 +686,18 @@ int implicit_free(ClothModifierData *clmd)
DO_INLINE float fb(float length, float L)
{
float x = length / L;
- return (-11.541f * powf(x, 4) + 34.193f * powf(x, 3) - 39.083f * powf(x, 2) + 23.116f * x - 9.713f);
+ float xx = x * x;
+ float xxx = xx * x;
+ float xxxx = xxx * x;
+ return (-11.541f * xxxx + 34.193f * xxx - 39.083f * xx + 23.116f * x - 9.713f);
}
DO_INLINE float fbderiv(float length, float L)
{
float x = length/L;
-
- return (-46.164f * powf(x, 3) + 102.579f * powf(x, 2) - 78.166f * x + 23.116f);
+ float xx = x * x;
+ float xxx = xx * x;
+ return (-46.164f * xxx + 102.579f * xx - 78.166f * x + 23.116f);
}
DO_INLINE float fbstar(float length, float L, float kb, float cb)
@@ -958,6 +799,7 @@ static int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z
return conjgrad_loopcount<conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable
}
+#if 0
// block diagonalizer
DO_INLINE void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv)
{
@@ -972,7 +814,6 @@ DO_INLINE void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv)
}
}
-#if 0
/*
// version 1.3
static int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fmatrix3x3 *S, fmatrix3x3 *P, fmatrix3x3 *Pinv)
@@ -1146,30 +987,6 @@ static int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector
}
#endif
-// outer product is NOT cross product!!!
-DO_INLINE void dfdx_spring_type1(float to[3][3], float extent[3], float length, float L, float dot, float k)
-{
- // dir is unit length direction, rest is spring's restlength, k is spring constant.
- // return (outerprod(dir, dir)*k + (I - outerprod(dir, dir))*(k - ((k*L)/length)));
- float temp[3][3];
- float temp1 = k * (1.0f - (L / length));
-
- mul_fvectorT_fvectorS(temp, extent, extent, 1.0f / dot);
- sub_fmatrix_fmatrix(to, I, temp);
- mul_fmatrix_S(to, temp1);
-
- mul_fvectorT_fvectorS(temp, extent, extent, k/ dot);
- add_fmatrix_fmatrix(to, to, temp);
-
- /*
- mul_fvectorT_fvector(temp, dir, dir);
- sub_fmatrix_fmatrix(to, I, temp);
- mul_fmatrix_S(to, k* (1.0f-(L/length)));
- mul_fmatrix_S(temp, k);
- add_fmatrix_fmatrix(to, temp, to);
- */
-}
-
DO_INLINE void dfdx_spring_type2(float to[3][3], float dir[3], float length, float L, float k, float cb)
{
// return outerprod(dir, dir)*fbstar_jacobi(length, L, k, cb);
@@ -1195,17 +1012,6 @@ DO_INLINE void dfdx_spring(float to[3][3], float dir[3], float length, float L,
mul_fmatrix_S(to, -k);
}
-// unused atm
-DO_INLINE void dfdx_damp(float to[3][3], float dir[3], float length, const float vel[3], float rest, float damping)
-{
- // inner spring damping vel is the relative velocity of the endpoints.
- // return (I-outerprod(dir, dir)) * (-damping * -(dot(dir, vel)/Max(length, rest)));
- mul_fvectorT_fvector(to, dir, dir);
- sub_fmatrix_fmatrix(to, I, to);
- mul_fmatrix_S(to, (-damping * -(dot_v3v3(dir, vel)/MAX2(length, rest))));
-
-}
-
DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s, lfVector *UNUSED(lF), lfVector *X, lfVector *V, fmatrix3x3 *UNUSED(dFdV), fmatrix3x3 *UNUSED(dFdX), float time)
{
Cloth *cloth = clmd->clothObject;
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 51cf26063c7..34877c7559c 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -1523,7 +1523,7 @@ static void ipo_to_animdata(ID *id, Ipo *ipo, char actname[], char constname[],
if (G.debug & G_DEBUG) {
printf("ipo to animdata - ID:%s, IPO:%s, actname:%s constname:%s seqname:%s curves:%d\n",
id->name + 2, ipo->id.name + 2, (actname) ? actname : "<None>", (constname) ? constname : "<None>", (seq) ? (seq->name + 2) : "<None>",
- BLI_countlist(&ipo->curve));
+ BLI_listbase_count(&ipo->curve));
}
/* Convert curves to animato system (separated into separate lists of F-Curves for animation and drivers),
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 2dc615c19f9..3ba0c6e5ffa 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -1086,7 +1086,7 @@ static float *get_weights_array(Object *ob, char *vgroup, WeightsArrayCache *cac
if (cache) {
if (cache->defgroup_weights == NULL) {
- int num_defgroup = BLI_countlist(&ob->defbase);
+ int num_defgroup = BLI_listbase_count(&ob->defbase);
cache->defgroup_weights =
MEM_callocN(sizeof(*cache->defgroup_weights) * num_defgroup,
"cached defgroup weights");
@@ -1518,7 +1518,7 @@ KeyBlock *BKE_keyblock_add(Key *key, const char *name)
BLI_addtail(&key->block, kb);
kb->type = KEY_CARDINAL;
- tot = BLI_countlist(&key->block);
+ tot = BLI_listbase_count(&key->block);
if (name) {
BLI_strncpy(kb->name, name, sizeof(kb->name));
}
@@ -1669,31 +1669,43 @@ char *BKE_keyblock_curval_rnapath_get(Key *key, KeyBlock *kb)
/* conversion functions */
/************************* Lattice ************************/
-void BKE_key_convert_from_lattice(Lattice *lt, KeyBlock *kb)
+void BKE_keyblock_update_from_lattice(Lattice *lt, KeyBlock *kb)
{
BPoint *bp;
- float *fp;
+ float (*fp)[3];
int a, tot;
+ BLI_assert(kb->totelem == lt->pntsu * lt->pntsv * lt->pntsw);
+
+ tot = kb->totelem;
+ if (tot == 0) return;
+
+ bp = lt->def;
+ fp = kb->data;
+ for (a = 0; a < kb->totelem; a++, fp++, bp++) {
+ copy_v3_v3(*fp, bp->vec);
+ }
+}
+
+void BKE_keyblock_convert_from_lattice(Lattice *lt, KeyBlock *kb)
+{
+ int tot;
+
tot = lt->pntsu * lt->pntsv * lt->pntsw;
if (tot == 0) return;
- if (kb->data) MEM_freeN(kb->data);
+ MEM_SAFE_FREE(kb->data);
- kb->data = MEM_mallocN(lt->key->elemsize * tot, "kb->data");
+ kb->data = MEM_mallocN(lt->key->elemsize * tot, __func__);
kb->totelem = tot;
- bp = lt->def;
- fp = kb->data;
- for (a = 0; a < kb->totelem; a++, fp += 3, bp++) {
- copy_v3_v3(fp, bp->vec);
- }
+ BKE_keyblock_update_from_lattice(lt, kb);
}
-void BKE_key_convert_to_lattice(KeyBlock *kb, Lattice *lt)
+void BKE_keyblock_convert_to_lattice(KeyBlock *kb, Lattice *lt)
{
BPoint *bp;
- const float *fp;
+ const float (*fp)[3];
int a, tot;
bp = lt->def;
@@ -1702,13 +1714,13 @@ void BKE_key_convert_to_lattice(KeyBlock *kb, Lattice *lt)
tot = lt->pntsu * lt->pntsv * lt->pntsw;
tot = min_ii(kb->totelem, tot);
- for (a = 0; a < tot; a++, fp += 3, bp++) {
- copy_v3_v3(bp->vec, fp);
+ for (a = 0; a < tot; a++, fp++, bp++) {
+ copy_v3_v3(bp->vec, *fp);
}
}
/************************* Curve ************************/
-void BKE_key_convert_from_curve(Curve *cu, KeyBlock *kb, ListBase *nurb)
+void BKE_keyblock_update_from_curve(Curve *UNUSED(cu), KeyBlock *kb, ListBase *nurb)
{
Nurb *nu;
BezTriple *bezt;
@@ -1717,49 +1729,52 @@ void BKE_key_convert_from_curve(Curve *cu, KeyBlock *kb, ListBase *nurb)
int a, tot;
/* count */
- tot = BKE_nurbList_verts_count(nurb);
- if (tot == 0) return;
-
- if (kb->data) MEM_freeN(kb->data);
+ BLI_assert(BKE_nurbList_verts_count(nurb) == kb->totelem);
- kb->data = MEM_mallocN(cu->key->elemsize * tot, "kb->data");
- kb->totelem = tot;
+ tot = kb->totelem;
+ if (tot == 0) return;
- nu = nurb->first;
fp = kb->data;
- while (nu) {
-
+ for (nu = nurb->first; nu; nu = nu->next) {
if (nu->bezt) {
- bezt = nu->bezt;
- a = nu->pntsu;
- while (a--) {
- copy_v3_v3(fp, bezt->vec[0]);
- fp += 3;
- copy_v3_v3(fp, bezt->vec[1]);
- fp += 3;
- copy_v3_v3(fp, bezt->vec[2]);
- fp += 3;
+ for (a = nu->pntsu, bezt = nu->bezt; a; a--, bezt++) {
+ int i;
+
+ for (i = 0; i < 3; i++, fp += 3) {
+ copy_v3_v3(fp, bezt->vec[i]);
+ }
fp[0] = bezt->alfa;
fp += 3; /* alphas */
- bezt++;
}
}
else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- while (a--) {
+
+ ;
+ for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a; a--, fp += 4, bp++) {
copy_v3_v3(fp, bp->vec);
fp[3] = bp->alfa;
-
- fp += 4;
- bp++;
}
}
- nu = nu->next;
}
}
-void BKE_key_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb)
+void BKE_keyblock_convert_from_curve(Curve *cu, KeyBlock *kb, ListBase *nurb)
+{
+ int tot;
+
+ /* count */
+ tot = BKE_nurbList_verts_count(nurb);
+ if (tot == 0) return;
+
+ MEM_SAFE_FREE(kb->data);
+
+ kb->data = MEM_mallocN(cu->key->elemsize * tot, __func__);
+ kb->totelem = tot;
+
+ BKE_keyblock_update_from_curve(cu, kb, nurb);
+}
+
+void BKE_keyblock_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb)
{
Nurb *nu;
BezTriple *bezt;
@@ -1767,74 +1782,68 @@ void BKE_key_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb)
const float *fp;
int a, tot;
- nu = nurb->first;
- fp = kb->data;
-
tot = BKE_nurbList_verts_count(nurb);
-
tot = min_ii(kb->totelem, tot);
- while (nu && tot > 0) {
-
+ fp = kb->data;
+ for (nu = nurb->first; nu && tot > 0; nu = nu->next) {
if (nu->bezt) {
- bezt = nu->bezt;
- a = nu->pntsu;
- while (a-- && tot > 0) {
- copy_v3_v3(bezt->vec[0], fp);
- fp += 3;
- copy_v3_v3(bezt->vec[1], fp);
- fp += 3;
- copy_v3_v3(bezt->vec[2], fp);
- fp += 3;
+ for (a = nu->pntsu, bezt = nu->bezt; a && tot > 0; a--, tot -= 3, bezt++) {
+ int i;
+
+ for (i = 0; i < 3; i++, fp += 3) {
+ copy_v3_v3(bezt->vec[i], fp);
+ }
bezt->alfa = fp[0];
fp += 3; /* alphas */
-
- tot -= 3;
- bezt++;
}
}
else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- while (a-- && tot > 0) {
+ for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a && tot; a--, tot--, fp += 4, bp++) {
copy_v3_v3(bp->vec, fp);
bp->alfa = fp[3];
-
- fp += 4;
- tot--;
- bp++;
}
}
- nu = nu->next;
}
}
/************************* Mesh ************************/
-void BKE_key_convert_from_mesh(Mesh *me, KeyBlock *kb)
+void BKE_keyblock_update_from_mesh(Mesh *me, KeyBlock *kb)
{
MVert *mvert;
- float *fp;
- int a;
-
- if (me->totvert == 0) return;
+ float (*fp)[3];
+ int a, tot;
- if (kb->data) MEM_freeN(kb->data);
+ BLI_assert(me->totvert == kb->totelem);
- kb->data = MEM_mallocN(me->key->elemsize * me->totvert, "kb->data");
- kb->totelem = me->totvert;
+ tot = me->totvert;
+ if (tot == 0) return;
mvert = me->mvert;
fp = kb->data;
- for (a = 0; a < kb->totelem; a++, fp += 3, mvert++) {
- copy_v3_v3(fp, mvert->co);
-
+ for (a = 0; a < tot; a++, fp++, mvert++) {
+ copy_v3_v3(*fp, mvert->co);
}
}
-void BKE_key_convert_to_mesh(KeyBlock *kb, Mesh *me)
+void BKE_keyblock_convert_from_mesh(Mesh *me, KeyBlock *kb)
+{
+ int tot = me->totvert;
+
+ if (me->totvert == 0) return;
+
+ MEM_SAFE_FREE(kb->data);
+
+ kb->data = MEM_mallocN(me->key->elemsize * tot, __func__);
+ kb->totelem = tot;
+
+ BKE_keyblock_update_from_mesh(me, kb);
+}
+
+void BKE_keyblock_convert_to_mesh(KeyBlock *kb, Mesh *me)
{
MVert *mvert;
- const float *fp;
+ const float (*fp)[3];
int a, tot;
mvert = me->mvert;
@@ -1842,94 +1851,76 @@ void BKE_key_convert_to_mesh(KeyBlock *kb, Mesh *me)
tot = min_ii(kb->totelem, me->totvert);
- for (a = 0; a < tot; a++, fp += 3, mvert++) {
- copy_v3_v3(mvert->co, fp);
+ for (a = 0; a < tot; a++, fp++, mvert++) {
+ copy_v3_v3(mvert->co, *fp);
}
}
-/************************* vert coords ************************/
-float (*BKE_key_convert_to_vertcos(Object *ob, KeyBlock *kb))[3]
+/************************* raw coords ************************/
+void BKE_keyblock_update_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3])
{
- float (*vertCos)[3], *co;
- const float *fp = kb->data;
- int tot = 0, a;
+ float (*co)[3] = vertCos;
+ float *fp = kb->data;
+ int tot, a;
- /* Count of vertex coords in array */
- if (ob->type == OB_MESH) {
- Mesh *me = (Mesh *)ob->data;
- tot = me->totvert;
- }
- else if (ob->type == OB_LATTICE) {
- Lattice *lt = (Lattice *)ob->data;
- tot = lt->pntsu * lt->pntsv * lt->pntsw;
+#ifndef NDEBUG
+ if (ob->type == OB_LATTICE) {
+ Lattice *lt = ob->data;
+ BLI_assert((lt->pntsu * lt->pntsv * lt->pntsw) == kb->totelem);
}
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
- Curve *cu = (Curve *)ob->data;
- tot = BKE_nurbList_verts_count(&cu->nurb);
+ Curve *cu = ob->data;
+ BLI_assert(BKE_nurbList_verts_count(&cu->nurb) == kb->totelem);
}
+ else if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+ BLI_assert(me->totvert == kb->totelem);
+ }
+ else {
+ BLI_assert(0 == kb->totelem);
+ }
+#endif
- if (tot == 0) return NULL;
-
- vertCos = MEM_mallocN(tot * sizeof(*vertCos), "BKE_key_convert_to_vertcos vertCos");
-
- /* Copy coords to array */
- co = (float *)vertCos;
+ tot = kb->totelem;
+ if (tot == 0) return;
+ /* Copy coords to keyblock */
if (ELEM(ob->type, OB_MESH, OB_LATTICE)) {
- for (a = 0; a < tot; a++, fp += 3, co += 3) {
- copy_v3_v3(co, fp);
+ for (a = 0; a < tot; a++, fp += 3, co++) {
+ copy_v3_v3(fp, *co);
}
}
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
Curve *cu = (Curve *)ob->data;
- Nurb *nu = cu->nurb.first;
+ Nurb *nu;
BezTriple *bezt;
BPoint *bp;
- while (nu) {
+ for (nu = cu->nurb.first; nu; nu = nu->next) {
if (nu->bezt) {
- int i;
- bezt = nu->bezt;
- a = nu->pntsu;
+ for (a = nu->pntsu, bezt = nu->bezt; a; a--, bezt++) {
+ int i;
- while (a--) {
- for (i = 0; i < 3; i++) {
- copy_v3_v3(co, fp);
- fp += 3; co += 3;
+ for (i = 0; i < 3; i++, fp += 3, co++) {
+ copy_v3_v3(fp, *co);
}
-
fp += 3; /* skip alphas */
-
- bezt++;
}
}
else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
-
- while (a--) {
- copy_v3_v3(co, fp);
-
- fp += 4;
- co += 3;
-
- bp++;
+ for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a; a--, bp++, fp += 4, co++) {
+ copy_v3_v3(fp, *co);
}
}
-
- nu = nu->next;
}
}
-
- return vertCos;
}
-void BKE_key_convert_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3])
+void BKE_keyblock_convert_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3])
{
- float *co = (float *)vertCos, *fp;
- int tot = 0, a, elemsize;
+ int tot = 0, elemsize;
- if (kb->data) MEM_freeN(kb->data);
+ MEM_SAFE_FREE(kb->data);
/* Count of vertex coords in array */
if (ob->type == OB_MESH) {
@@ -1948,110 +1939,212 @@ void BKE_key_convert_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3])
tot = BKE_nurbList_verts_count(&cu->nurb);
}
- if (tot == 0) {
- kb->data = NULL;
- return;
- }
+ if (tot == 0) return;
- fp = kb->data = MEM_mallocN(tot * elemsize, "BKE_key_convert_to_vertcos vertCos");
+ kb->data = MEM_mallocN(tot * elemsize, __func__);
/* Copy coords to keyblock */
+ BKE_keyblock_update_from_vertcos(ob, kb, vertCos);
+}
+
+float (*BKE_keyblock_convert_to_vertcos(Object *ob, KeyBlock *kb))[3]
+{
+ float (*vertCos)[3], (*co)[3];
+ const float *fp = kb->data;
+ int tot = 0, a;
+
+ /* Count of vertex coords in array */
+ if (ob->type == OB_MESH) {
+ Mesh *me = (Mesh *)ob->data;
+ tot = me->totvert;
+ }
+ else if (ob->type == OB_LATTICE) {
+ Lattice *lt = (Lattice *)ob->data;
+ tot = lt->pntsu * lt->pntsv * lt->pntsw;
+ }
+ else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ Curve *cu = (Curve *)ob->data;
+ tot = BKE_nurbList_verts_count(&cu->nurb);
+ }
+
+ if (tot == 0) return NULL;
+
+ co = vertCos = MEM_mallocN(tot * sizeof(*vertCos), __func__);
+ /* Copy coords to array */
if (ELEM(ob->type, OB_MESH, OB_LATTICE)) {
- for (a = 0; a < tot; a++, fp += 3, co += 3) {
- copy_v3_v3(fp, co);
+ for (a = 0; a < tot; a++, fp += 3, co++) {
+ copy_v3_v3(*co, fp);
}
}
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
Curve *cu = (Curve *)ob->data;
- Nurb *nu = cu->nurb.first;
+ Nurb *nu;
BezTriple *bezt;
BPoint *bp;
- while (nu) {
+ for (nu = cu->nurb.first; nu; nu = nu->next) {
if (nu->bezt) {
- int i;
- bezt = nu->bezt;
- a = nu->pntsu;
+ for (a = nu->pntsu, bezt = nu->bezt; a; a--, bezt++) {
+ int i;
- while (a--) {
- for (i = 0; i < 3; i++) {
- copy_v3_v3(fp, co);
- fp += 3; co += 3;
+ for (i = 0; i < 3; i++, fp += 3, co++) {
+ copy_v3_v3(*co, fp);
}
-
fp += 3; /* skip alphas */
-
- bezt++;
}
}
else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
-
- while (a--) {
- copy_v3_v3(fp, co);
-
- fp += 4;
- co += 3;
-
- bp++;
+ for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a; a--, bp++, fp += 4, co++) {
+ copy_v3_v3(*co, fp);
}
}
-
- nu = nu->next;
}
}
+
+ return vertCos;
}
-void BKE_key_convert_from_offset(Object *ob, KeyBlock *kb, float (*ofs)[3])
+/************************* raw coord offsets ************************/
+void BKE_keyblock_update_from_offset(Object *ob, KeyBlock *kb, float (*ofs)[3])
{
int a;
- float *co = (float *)ofs, *fp = kb->data;
+ float *fp = kb->data;
if (ELEM(ob->type, OB_MESH, OB_LATTICE)) {
- for (a = 0; a < kb->totelem; a++, fp += 3, co += 3) {
- add_v3_v3(fp, co);
+ for (a = 0; a < kb->totelem; a++, fp += 3, ofs++) {
+ add_v3_v3(fp, *ofs);
}
}
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
Curve *cu = (Curve *)ob->data;
- Nurb *nu = cu->nurb.first;
+ Nurb *nu;
BezTriple *bezt;
BPoint *bp;
- while (nu) {
+ for (nu = cu->nurb.first; nu; nu = nu->next) {
if (nu->bezt) {
- int i;
- bezt = nu->bezt;
- a = nu->pntsu;
+ for (a = nu->pntsu, bezt = nu->bezt; a; a--, bezt++) {
+ int i;
- while (a--) {
- for (i = 0; i < 3; i++) {
- add_v3_v3(fp, co);
- fp += 3; co += 3;
+ for (i = 0; i < 3; i++, fp += 3, ofs++) {
+ add_v3_v3(fp, *ofs);
}
-
fp += 3; /* skip alphas */
-
- bezt++;
}
}
else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
+ for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a; a--, bp++, fp += 4, ofs++) {
+ add_v3_v3(fp, *ofs);
+ }
+ }
+ }
+ }
+}
- while (a--) {
- add_v3_v3(fp, co);
+/* ==========================================================*/
- fp += 4;
- co += 3;
+/** Move shape key from org_index to new_index. Safe, clamps index to valid range, updates reference keys,
+ * the object's active shape index, the 'frame' value in case of absolute keys, etc.
+ * Note indices are expected in real values (not 'fake' shapenr +1 ones).
+ *
+ * \param org_index if < 0, current object's active shape will be used as skey to move.
+ * \return true if something was done, else false.
+ */
+bool BKE_keyblock_move(Object *ob, int org_index, int new_index)
+{
+ Key *key = BKE_key_from_object(ob);
+ KeyBlock *kb;
+ const int act_index = ob->shapenr - 1;
+ const int totkey = key->totkey;
+ int i;
+ bool rev, in_range = false;
- bp++;
- }
- }
+ if (org_index < 0) {
+ org_index = act_index;
+ }
+
+ CLAMP(new_index, 0, key->totkey - 1);
+ CLAMP(org_index, 0, key->totkey - 1);
+
+ if (new_index == org_index) {
+ return false;
+ }
+
+ rev = ((new_index - org_index) < 0) ? true : false;
+
+ /* We swap 'org' element with its previous/next neighbor (depending on direction of the move) repeatedly,
+ * until we reach final position.
+ * This allows us to only loop on the list once! */
+ for (kb = (rev ? key->block.last : key->block.first), i = (rev ? totkey - 1 : 0);
+ kb;
+ kb = (rev ? kb->prev : kb->next), rev ? i-- : i++)
+ {
+ if (i == org_index) {
+ in_range = true; /* Start list items swapping... */
+ }
+ else if (i == new_index) {
+ in_range = false; /* End list items swapping. */
+ }
+
+ if (in_range) {
+ KeyBlock *other_kb = rev ? kb->prev : kb->next;
+
+ /* Swap with previous/next list item. */
+ BLI_listbase_swaplinks(&key->block, kb, other_kb);
+
+ /* Swap absolute positions. */
+ SWAP(float, kb->pos, other_kb->pos);
- nu = nu->next;
+ kb = other_kb;
+ }
+
+ /* Adjust relative indices, this has to be done on the whole list! */
+ if (kb->relative == org_index) {
+ kb->relative = new_index;
+ }
+ else if (kb->relative < org_index && kb->relative >= new_index) {
+ /* remove after, insert before this index */
+ kb->relative++;
+ }
+ else if (kb->relative > org_index && kb->relative <= new_index) {
+ /* remove before, insert after this index */
+ kb->relative--;
+ }
+ }
+
+ /* Need to update active shape number if it's affected, same principle as for relative indices above. */
+ if (org_index == act_index) {
+ ob->shapenr = new_index + 1;
+ }
+ else if (act_index < org_index && act_index >= new_index) {
+ ob->shapenr++;
+ }
+ else if (act_index > org_index && act_index <= new_index) {
+ ob->shapenr--;
+ }
+
+ /* First key is always refkey, matches interface and BKE_key_sort */
+ key->refkey = key->block.first;
+
+ return true;
+}
+
+/**
+ * Check if given keyblock (as index) is used as basis by others in given key.
+ */
+bool BKE_keyblock_is_basis(Key *key, const int index)
+{
+ KeyBlock *kb;
+ int i;
+
+ if (key->type == KEY_RELATIVE) {
+ for (i = 0, kb = key->block.first; kb; i++, kb = kb->next) {
+ if ((i != index) && (kb->relative == index)) {
+ return true;
+ }
}
}
+
+ return false;
}
diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c
index 4a413850ec0..e738b16c8cc 100644
--- a/source/blender/blenkernel/intern/lamp.c
+++ b/source/blender/blenkernel/intern/lamp.c
@@ -41,7 +41,6 @@
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
-#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 3f12e3efcc7..7732d592da6 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -575,7 +575,7 @@ static bool where_on_path_deform(Object *ob, float ctime, float vec[4], float di
/* test for cyclic */
bl = ob->curve_cache->bev.first;
- if (!bl->nr) return 0;
+ if (!bl->nr) return false;
if (bl->poly > -1) cycl = 1;
if (cycl == 0) {
@@ -608,9 +608,9 @@ static bool where_on_path_deform(Object *ob, float ctime, float vec[4], float di
/* weight - not used but could be added */
}
}
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/* for each point, rotate & translate to curve */
@@ -634,9 +634,7 @@ static bool calc_curve_deform(Scene *scene, Object *par, float co[3],
#endif
if (par->curve_cache->path == NULL) {
- return 0; /* happens on append, cyclic dependencies
- * and empty curves
- */
+ return false; /* happens on append, cyclic dependencies and empty curves */
}
/* options */
@@ -718,9 +716,9 @@ static bool calc_curve_deform(Scene *scene, Object *par, float co[3],
if (r_quat)
copy_qt_qt(r_quat, quat);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
void curve_deform_verts(Scene *scene, Object *cuOb, Object *target, DerivedMesh *dm, float (*vertexCos)[3],
@@ -939,10 +937,10 @@ bool object_deform_mball(Object *ob, ListBase *dispbase)
(float(*)[3])dl->verts, dl->nr, NULL, 1.0f);
}
- return 1;
+ return true;
}
else {
- return 0;
+ return false;
}
}
diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c
index bcdaf9b7af0..5bee93349d8 100644
--- a/source/blender/blenkernel/intern/linestyle.c
+++ b/source/blender/blenkernel/intern/linestyle.c
@@ -53,8 +53,6 @@
#include "BKE_colortools.h"
#include "BKE_animsys.h"
-#include "RNA_access.h"
-
static const char *modifier_name[LS_MODIFIER_NUM] = {
NULL,
"Along Stroke",
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 83ad2f1b2d2..b8c78ce912c 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -59,8 +59,6 @@
#include "BKE_movieclip.h"
#include "BKE_image.h"
-#include "NOD_composite.h"
-
static struct {
ListBase splines;
struct GHash *id_hash;
@@ -1187,11 +1185,12 @@ void BKE_mask_point_parent_matrix_get(MaskSplinePoint *point, float ctime, float
MovieTrackingPlaneTrack *plane_track = BKE_tracking_plane_track_get_named(tracking, ob, parent->sub_parent);
if (plane_track) {
- MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, clip_framenr);
+ float corners[4][2];
float aspx, aspy;
float frame_size[2], H[3][3], mask_from_clip_matrix[3][3], mask_to_clip_matrix[3][3];
- BKE_tracking_homography_between_two_quads(parent->parent_corners_orig, plane_marker->corners, H);
+ BKE_tracking_plane_marker_get_subframe_corners(plane_track, ctime, corners);
+ BKE_tracking_homography_between_two_quads(parent->parent_corners_orig, corners, H);
unit_m3(mask_from_clip_matrix);
@@ -1457,7 +1456,7 @@ void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const bool d
{
if (found == 1) {
#if 0
- printf("%s: exact %d %d (%d)\n", __func__, (int)ctime, BLI_countlist(&masklay->splines_shapes),
+ printf("%s: exact %d %d (%d)\n", __func__, (int)ctime, BLI_listbase_count(&masklay->splines_shapes),
masklay_shape_a->frame);
#endif
@@ -1466,7 +1465,7 @@ void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const bool d
else if (found == 2) {
float w = masklay_shape_b->frame - masklay_shape_a->frame;
#if 0
- printf("%s: tween %d %d (%d %d)\n", __func__, (int)ctime, BLI_countlist(&masklay->splines_shapes),
+ printf("%s: tween %d %d (%d %d)\n", __func__, (int)ctime, BLI_listbase_count(&masklay->splines_shapes),
masklay_shape_a->frame, masklay_shape_b->frame);
#endif
BKE_mask_layer_shape_to_mask_interp(masklay, masklay_shape_a, masklay_shape_b,
@@ -1833,7 +1832,7 @@ static int mask_layer_shape_sort_cb(const void *masklay_shape_a_ptr, const void
void BKE_mask_layer_shape_sort(MaskLayer *masklay)
{
- BLI_sortlist(&masklay->splines_shapes, mask_layer_shape_sort_cb);
+ BLI_listbase_sort(&masklay->splines_shapes, mask_layer_shape_sort_cb);
}
bool BKE_mask_layer_shape_spline_from_index(MaskLayer *masklay, int index,
diff --git a/source/blender/blenkernel/intern/mask_evaluate.c b/source/blender/blenkernel/intern/mask_evaluate.c
index 3ed6148054c..5517fc36bc1 100644
--- a/source/blender/blenkernel/intern/mask_evaluate.c
+++ b/source/blender/blenkernel/intern/mask_evaluate.c
@@ -40,8 +40,6 @@
#include "BLI_math.h"
#include "DNA_mask_types.h"
-#include "DNA_node_types.h"
-#include "DNA_scene_types.h"
#include "BKE_curve.h"
#include "BKE_mask.h"
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 4dc8ed21463..387d093051e 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -572,7 +572,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
unsigned int masklay_index;
MemArena *sf_arena;
- mr_handle->layers_tot = (unsigned int)BLI_countlist(&mask->masklayers);
+ mr_handle->layers_tot = (unsigned int)BLI_listbase_count(&mask->masklayers);
mr_handle->layers = MEM_mallocN(sizeof(MaskRasterLayer) * mr_handle->layers_tot, "MaskRasterLayer");
BLI_rctf_init_minmax(&mr_handle->bounds);
@@ -608,7 +608,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
continue;
}
- tot_splines = (unsigned int)BLI_countlist(&masklay->splines);
+ tot_splines = (unsigned int)BLI_listbase_count(&masklay->splines);
open_spline_ranges = MEM_callocN(sizeof(*open_spline_ranges) * tot_splines, __func__);
BLI_scanfill_begin_arena(&sf_ctx, sf_arena);
@@ -956,7 +956,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
&isect_remvertbase,
&isect_remedgebase)))
{
- unsigned int sf_vert_tot_isect = (unsigned int)BLI_countlist(&sf_ctx.fillvertbase);
+ unsigned int sf_vert_tot_isect = (unsigned int)BLI_listbase_count(&sf_ctx.fillvertbase);
unsigned int i = sf_vert_tot;
face_coords = MEM_reallocN(face_coords, sizeof(float[3]) * (sf_vert_tot + sf_vert_tot_isect));
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 29f700cf242..ad1692eadf3 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -116,7 +116,7 @@ void BKE_material_free_ex(Material *ma, bool do_id_user)
MEM_freeN(ma->texpaintslot);
if (ma->gpumaterial.first)
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
}
void init_material(Material *ma)
@@ -1153,28 +1153,28 @@ static bool material_in_nodetree(bNodeTree *ntree, Material *mat)
if (node->id) {
if (GS(node->id->name) == ID_MA) {
if (node->id == (ID *)mat) {
- return 1;
+ return true;
}
}
else if (node->type == NODE_GROUP) {
if (material_in_nodetree((bNodeTree *)node->id, mat)) {
- return 1;
+ return true;
}
}
}
}
- return 0;
+ return false;
}
bool material_in_material(Material *parmat, Material *mat)
{
if (parmat == mat)
- return 1;
+ return true;
else if (parmat->nodetree && parmat->use_nodes)
return material_in_nodetree(parmat->nodetree, mat);
else
- return 0;
+ return false;
}
@@ -1336,7 +1336,7 @@ void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma)
short index = 0, i;
bool use_nodes = BKE_scene_use_new_shading_nodes(scene);
- bool is_bi = BKE_scene_uses_blender_internal(scene);
+ bool is_bi = BKE_scene_uses_blender_internal(scene) || BKE_scene_uses_blender_game(scene);
if (!ma)
return;
@@ -1740,7 +1740,7 @@ void paste_matcopybuf(Material *ma)
MEM_freeN(ma->nodetree);
}
- GPU_material_free(ma);
+ GPU_material_free(&ma->gpumaterial);
id = (ma->id);
memcpy(ma, &matcopybuf, sizeof(Material));
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 453c6df6e3b..4c45269cb0b 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -2436,10 +2436,10 @@ bool BKE_mball_center_bounds(MetaBall *mb, float r_cent[3])
if (BKE_mball_minmax(mb, min, max)) {
mid_v3_v3v3(r_cent, min, max);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
void BKE_mball_transform(MetaBall *mb, float mat[4][4])
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index f3a9e894eb3..3a6c949fe9c 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -755,7 +755,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
MDeformWeight *dw;
for (j = 0, dw = dv->dw; j < dv->totweight; j++, dw++) {
- /* note, greater then max defgroups is accounted for in our code, but not < 0 */
+ /* note, greater than max defgroups is accounted for in our code, but not < 0 */
if (!finite(dw->weight)) {
PRINT_ERR("\tVertex deform %u, group %d has weight: %f\n", i, dw->def_nr, dw->weight);
if (do_fixes) {
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index a9e853c873e..54ab5a8aca7 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -47,7 +47,6 @@
#include "DNA_armature_types.h"
#include "DNA_object_types.h"
-#include "DNA_meshdata_types.h"
#include "BLI_utildefines.h"
#include "BLI_path_util.h"
@@ -57,6 +56,7 @@
#include "BLF_translation.h"
+#include "BKE_appdir.h"
#include "BKE_key.h"
#include "BKE_multires.h"
#include "BKE_DerivedMesh.h"
@@ -713,7 +713,7 @@ const char *modifier_path_relbase(Object *ob)
else {
/* last resort, better then using "" which resolves to the current
* working directory */
- return BLI_temp_dir_session();
+ return BKE_tempdir_session();
}
}
@@ -723,7 +723,7 @@ void modifier_path_init(char *path, int path_maxlen, const char *name)
/* elubie: changed this to default to the same dir as the render output
* to prevent saving to C:\ on Windows */
BLI_join_dirfile(path, path_maxlen,
- G.relbase_valid ? "//" : BLI_temp_dir_session(),
+ G.relbase_valid ? "//" : BKE_tempdir_session(),
name);
}
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index e28adb7c0e0..0e9a7ce45cf 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -69,7 +69,6 @@
#include "BKE_image.h" /* openanim */
#include "BKE_tracking.h"
-#include "IMB_colormanagement.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "IMB_moviecache.h"
@@ -78,8 +77,6 @@
# include "intern/openexr/openexr_multi.h"
#endif
-#include "NOD_composite.h"
-
/*********************** movieclip buffer loaders *************************/
static int sequence_guess_offset(const char *full_name, int head_len, unsigned short numlen)
@@ -528,6 +525,15 @@ static bool put_imbuf_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, i
}
}
+static bool moviecache_check_free_proxy(ImBuf *UNUSED(ibuf),
+ void *userkey,
+ void *UNUSED(userdata))
+{
+ MovieClipImBufCacheKey *key = (MovieClipImBufCacheKey *)userkey;
+
+ return !(key->proxy == IMB_PROXY_NONE && key->render_flag == 0);
+}
+
/*********************** common functions *************************/
/* only image block itself */
@@ -1170,6 +1176,15 @@ void BKE_movieclip_clear_cache(MovieClip *clip)
free_buffers(clip);
}
+void BKE_movieclip_clear_proxy_cache(MovieClip *clip)
+{
+ if (clip->cache && clip->cache->moviecache) {
+ IMB_moviecache_cleanup(clip->cache->moviecache,
+ moviecache_check_free_proxy,
+ NULL);
+ }
+}
+
void BKE_movieclip_reload(MovieClip *clip)
{
/* clear cache */
@@ -1261,7 +1276,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
scopes->frame_width = ibuf->x;
scopes->frame_height = ibuf->y;
- scopes->use_track_mask = track->flag & TRACK_PREVIEW_ALPHA;
+ scopes->use_track_mask = (track->flag & TRACK_PREVIEW_ALPHA) != 0;
}
IMB_freeImBuf(ibuf);
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index df992cc9aed..0adc65bd806 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -126,7 +126,7 @@ static BLI_bitmap *multires_mdisps_upsample_hidden(BLI_bitmap *lo_hidden,
if (lo_level == hi_level)
return MEM_dupallocN(lo_hidden);
- subd = BLI_BITMAP_NEW(hi_gridsize * hi_gridsize, "MDisps.hidden upsample");
+ subd = BLI_BITMAP_NEW(SQUARE(hi_gridsize), "MDisps.hidden upsample");
factor = BKE_ccg_factor(lo_level, hi_level);
offset = 1 << (hi_level - lo_level - 1);
@@ -182,9 +182,7 @@ static BLI_bitmap *multires_mdisps_downsample_hidden(BLI_bitmap *old_hidden,
BLI_assert(new_level <= old_level);
factor = BKE_ccg_factor(new_level, old_level);
- new_hidden = BLI_BITMAP_NEW(new_gridsize * new_gridsize,
- "downsample hidden");
-
+ new_hidden = BLI_BITMAP_NEW(SQUARE(new_gridsize), "downsample hidden");
for (y = 0; y < new_gridsize; y++) {
@@ -250,15 +248,15 @@ static MDisps *multires_mdisps_initialize_hidden(Mesh *me, int level)
MDisps *mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS,
CD_CALLOC, NULL, me->totloop);
int gridsize = BKE_ccg_gridsize(level);
- int gridarea = gridsize * gridsize;
- int i, j, k;
+ int gridarea = SQUARE(gridsize);
+ int i, j;
for (i = 0; i < me->totpoly; i++) {
- int hide = 0;
+ bool hide = false;
for (j = 0; j < me->mpoly[i].totloop; j++) {
if (me->mvert[me->mloop[me->mpoly[i].loopstart + j].v].flag & ME_HIDE) {
- hide = 1;
+ hide = true;
break;
}
}
@@ -599,7 +597,7 @@ static void multires_grid_paint_mask_downsample(GridPaintMask *gpm, int level)
{
if (level < gpm->level) {
int gridsize = BKE_ccg_gridsize(level);
- float *data = MEM_callocN(sizeof(float) * gridsize * gridsize,
+ float *data = MEM_callocN(sizeof(float) * SQUARE(gridsize),
"multires_grid_paint_mask_downsample");
int x, y;
@@ -1602,7 +1600,7 @@ void multires_load_old_250(Mesh *me)
int nvert = mf->v4 ? 4 : 3;
int totdisp = mdisps[i].totdisp / nvert;
- for (j = 0; j < mf->v4 ? 4 : 3; j++, k++) {
+ for (j = 0; j < nvert; j++, k++) {
mdisps2[k].disps = MEM_callocN(sizeof(float) * 3 * totdisp, "multires disp in conversion");
mdisps2[k].totdisp = totdisp;
mdisps2[k].level = mdisps[i].level;
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index 19e45142960..b4d63f8053b 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -268,7 +268,7 @@ NlaTrack *add_nlatrack(AnimData *adt, NlaTrack *prev)
/* set settings requiring the track to not be part of the stack yet */
nlt->flag = NLATRACK_SELECTED;
- nlt->index = BLI_countlist(&adt->nla_tracks);
+ nlt->index = BLI_listbase_count(&adt->nla_tracks);
/* add track to stack, and make it the active one */
if (prev)
@@ -567,7 +567,7 @@ bool BKE_nlastrips_has_space(ListBase *strips, float start, float end)
/* sanity checks */
if ((strips == NULL) || IS_EQF(start, end))
- return 0;
+ return false;
if (start > end) {
puts("BKE_nlastrips_has_space() error... start and end arguments swapped");
SWAP(float, start, end);
@@ -579,17 +579,17 @@ bool BKE_nlastrips_has_space(ListBase *strips, float start, float end)
* we've gone past the window we need to check for, so things are fine
*/
if (strip->start >= end)
- return 1;
+ return true;
/* if the end of the strip is greater than either of the boundaries, the range
* must fall within the extents of the strip
*/
if ((strip->end > start) || (strip->end > end))
- return 0;
+ return false;
}
/* if we are still here, we haven't encountered any overlapping strips */
- return 1;
+ return true;
}
/* Rearrange the strips in the track so that they are always in order
@@ -646,11 +646,11 @@ bool BKE_nlastrips_add_strip(ListBase *strips, NlaStrip *strip)
/* sanity checks */
if (ELEM(NULL, strips, strip))
- return 0;
+ return false;
/* check if any space to add */
if (BKE_nlastrips_has_space(strips, strip->start, strip->end) == 0)
- return 0;
+ return false;
/* find the right place to add the strip to the nominated track */
for (ns = strips->first; ns; ns = ns->next) {
@@ -667,7 +667,7 @@ bool BKE_nlastrips_add_strip(ListBase *strips, NlaStrip *strip)
}
/* added... */
- return 1;
+ return true;
}
@@ -785,11 +785,11 @@ bool BKE_nlameta_add_strip(NlaStrip *mstrip, NlaStrip *strip)
{
/* sanity checks */
if (ELEM(NULL, mstrip, strip))
- return 0;
+ return false;
/* firstly, check if the meta-strip has space for this */
if (BKE_nlastrips_has_space(&mstrip->strips, strip->start, strip->end) == 0)
- return 0;
+ return false;
/* check if this would need to be added to the ends of the meta,
* and subsequently, if the neighboring strips allow us enough room
@@ -803,10 +803,10 @@ bool BKE_nlameta_add_strip(NlaStrip *mstrip, NlaStrip *strip)
BLI_addhead(&mstrip->strips, strip);
mstrip->start = strip->start;
- return 1;
+ return true;
}
else /* failed... no room before */
- return 0;
+ return false;
}
else if (strip->end > mstrip->end) {
/* check if strip to the right (if it exists) starts before the
@@ -817,10 +817,10 @@ bool BKE_nlameta_add_strip(NlaStrip *mstrip, NlaStrip *strip)
BLI_addtail(&mstrip->strips, strip);
mstrip->end = strip->end;
- return 1;
+ return true;
}
else /* failed... no room after */
- return 0;
+ return false;
}
else {
/* just try to add to the meta-strip (no dimension changes needed) */
@@ -988,7 +988,7 @@ bool BKE_nlatrack_has_space(NlaTrack *nlt, float start, float end)
* - bounds cannot be equal (0-length is nasty)
*/
if ((nlt == NULL) || (nlt->flag & NLATRACK_PROTECTED) || IS_EQF(start, end))
- return 0;
+ return false;
if (start > end) {
puts("BKE_nlatrack_has_space() error... start and end arguments swapped");
@@ -1019,7 +1019,7 @@ bool BKE_nlatrack_add_strip(NlaTrack *nlt, NlaStrip *strip)
{
/* sanity checks */
if (ELEM(NULL, nlt, strip))
- return 0;
+ return false;
/* try to add the strip to the track using a more generic function */
return BKE_nlastrips_add_strip(&nlt->strips, strip);
@@ -1036,11 +1036,11 @@ bool BKE_nlatrack_get_bounds(NlaTrack *nlt, float bounds[2])
if (bounds)
bounds[0] = bounds[1] = 0.0f;
else
- return 0;
+ return false;
/* sanity checks */
if (ELEM(NULL, nlt, nlt->strips.first))
- return 0;
+ return false;
/* lower bound is first strip's start frame */
strip = nlt->strips.first;
@@ -1051,7 +1051,7 @@ bool BKE_nlatrack_get_bounds(NlaTrack *nlt, float bounds[2])
bounds[1] = strip->end;
/* done */
- return 1;
+ return true;
}
/* NLA Strips -------------------------------------- */
@@ -1105,7 +1105,7 @@ bool BKE_nlastrip_within_bounds(NlaStrip *strip, float min, float max)
/* sanity checks */
if ((strip == NULL) || IS_EQF(stripLen, 0.0f) || IS_EQF(boundsLen, 0.0f))
- return 0;
+ return false;
/* only ok if at least part of the strip is within the bounding window
* - first 2 cases cover when the strip length is less than the bounding area
@@ -1115,17 +1115,17 @@ bool BKE_nlastrip_within_bounds(NlaStrip *strip, float min, float max)
!(IN_RANGE(strip->start, min, max) ||
IN_RANGE(strip->end, min, max)))
{
- return 0;
+ return false;
}
if ((stripLen > boundsLen) &&
!(IN_RANGE(min, strip->start, strip->end) ||
IN_RANGE(max, strip->start, strip->end)) )
{
- return 0;
+ return false;
}
/* should be ok! */
- return 1;
+ return true;
}
@@ -1209,11 +1209,11 @@ static bool nlastrip_is_first(AnimData *adt, NlaStrip *strip)
/* sanity checks */
if (ELEM(NULL, adt, strip))
- return 0;
+ return false;
/* check if strip has any strips before it */
if (strip->prev)
- return 0;
+ return false;
/* check other tracks to see if they have a strip that's earlier */
/* TODO: or should we check that the strip's track is also the first? */
@@ -1222,12 +1222,12 @@ static bool nlastrip_is_first(AnimData *adt, NlaStrip *strip)
ns = nlt->strips.first;
if (ns) {
if (ns->start < strip->start)
- return 0;
+ return false;
}
}
/* should be first now */
- return 1;
+ return true;
}
/* Animated Strips ------------------------------------------- */
@@ -1239,16 +1239,16 @@ bool BKE_nlatrack_has_animated_strips(NlaTrack *nlt)
/* sanity checks */
if (ELEM(NULL, nlt, nlt->strips.first))
- return 0;
+ return false;
/* check each strip for F-Curves only (don't care about whether the flags are set) */
for (strip = nlt->strips.first; strip; strip = strip->next) {
if (strip->fcurves.first)
- return 1;
+ return true;
}
/* none found */
- return 0;
+ return false;
}
/* Check if given NLA-Tracks have any strips with own F-Curves */
@@ -1258,16 +1258,16 @@ bool BKE_nlatracks_have_animated_strips(ListBase *tracks)
/* sanity checks */
if (ELEM(NULL, tracks, tracks->first))
- return 0;
+ return false;
/* check each track, stopping on the first hit */
for (nlt = tracks->first; nlt; nlt = nlt->next) {
if (BKE_nlatrack_has_animated_strips(nlt))
- return 1;
+ return true;
}
/* none found */
- return 0;
+ return false;
}
/* Validate the NLA-Strips 'control' F-Curves based on the flags set*/
@@ -1587,13 +1587,13 @@ bool BKE_nla_tweakmode_enter(AnimData *adt)
/* verify that data is valid */
if (ELEM(NULL, adt, adt->nla_tracks.first))
- return 0;
+ return false;
/* if block is already in tweakmode, just leave, but we should report
* that this block is in tweakmode (as our returncode)
*/
if (adt->flag & ADT_NLA_EDIT_ON)
- return 1;
+ return true;
/* go over the tracks, finding the active one, and its active strip
* - if we cannot find both, then there's nothing to do
@@ -1642,7 +1642,7 @@ bool BKE_nla_tweakmode_enter(AnimData *adt)
printf("NLA tweakmode enter - neither active requirement found\n");
printf("\tactiveTrack = %p, activeStrip = %p\n", (void *)activeTrack, (void *)activeStrip);
}
- return 0;
+ return false;
}
/* go over all the tracks up to the active one, tagging each strip that uses the same
@@ -1677,7 +1677,7 @@ bool BKE_nla_tweakmode_enter(AnimData *adt)
adt->flag |= ADT_NLA_EDIT_ON;
/* done! */
- return 1;
+ return true;
}
/* Exit tweakmode for this AnimData block */
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 7ab1479905a..b6c9e9309b8 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -2268,8 +2268,8 @@ bool ntreeHasType(const bNodeTree *ntree, int type)
if (ntree)
for (node = ntree->nodes.first; node; node = node->next)
if (node->type == type)
- return 1;
- return 0;
+ return true;
+ return false;
}
bool ntreeHasTree(const bNodeTree *ntree, const bNodeTree *lookup)
@@ -2534,8 +2534,8 @@ bool BKE_node_clipboard_validate(void)
/* lists must be aligned */
- BLI_assert(BLI_countlist(&node_clipboard.nodes) ==
- BLI_countlist(&node_clipboard.nodes_extra_info));
+ BLI_assert(BLI_listbase_count(&node_clipboard.nodes) ==
+ BLI_listbase_count(&node_clipboard.nodes_extra_info));
for (node = node_clipboard.nodes.first, node_info = node_clipboard.nodes_extra_info.first;
node;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 7a8843f3308..a0d1b25a103 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -96,6 +96,7 @@
#include "BKE_editmesh.h"
#include "BKE_mball.h"
#include "BKE_modifier.h"
+#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_particle.h"
@@ -107,6 +108,7 @@
#include "BKE_sequencer.h"
#include "BKE_speaker.h"
#include "BKE_softbody.h"
+#include "BKE_subsurf.h"
#include "BKE_material.h"
#include "BKE_camera.h"
#include "BKE_image.h"
@@ -119,6 +121,8 @@
#include "BPY_extern.h"
#endif
+#include "CCGSubSurf.h"
+
#include "GPU_material.h"
/* Vertex parent modifies original BMesh which is not safe for threading.
@@ -185,6 +189,7 @@ void BKE_object_free_curve_cache(Object *ob)
if (ob->curve_cache->path) {
free_path(ob->curve_cache->path);
}
+ BKE_nurbList_free(&ob->curve_cache->deformed_nurbs);
MEM_freeN(ob->curve_cache);
ob->curve_cache = NULL;
}
@@ -321,18 +326,7 @@ void BKE_object_free_derived_caches(Object *ob)
ob->derivedDeform = NULL;
}
- if (ob->curve_cache) {
- BKE_displist_free(&ob->curve_cache->disp);
- BKE_curve_bevelList_free(&ob->curve_cache->bev);
- if (ob->curve_cache->path) {
- free_path(ob->curve_cache->path);
- ob->curve_cache->path = NULL;
- }
-
- /* Signal for viewport to run DAG workarounds. */
- MEM_freeN(ob->curve_cache);
- ob->curve_cache = NULL;
- }
+ BKE_object_free_curve_cache(ob);
}
/* do not free object itself */
@@ -442,6 +436,7 @@ void BKE_object_unlink(Object *ob)
Scene *sce;
SceneRenderLayer *srl;
FreestyleLineSet *lineset;
+ bNodeTree *ntree;
Curve *cu;
Tex *tex;
Group *group;
@@ -643,17 +638,22 @@ void BKE_object_unlink(Object *ob)
}
/* materials */
- mat = bmain->mat.first;
- while (mat) {
-
+ for (mat = bmain->mat.first; mat; mat = mat->id.next) {
+ if (mat->nodetree) {
+ ntreeSwitchID(mat->nodetree, &ob->id, NULL);
+ }
for (a = 0; a < MAX_MTEX; a++) {
if (mat->mtex[a] && ob == mat->mtex[a]->object) {
/* actually, test for lib here... to do */
mat->mtex[a]->object = NULL;
}
}
+ }
- mat = mat->id.next;
+ /* node trees */
+ for (ntree = bmain->nodetree.first; ntree; ntree = ntree->id.next) {
+ if (ntree->type == NTREE_SHADER)
+ ntreeSwitchID(ntree, &ob->id, NULL);
}
/* textures */
@@ -1078,14 +1078,14 @@ static int lod_cmp(const void *a, const void *b)
void BKE_object_lod_sort(Object *ob)
{
- BLI_sortlist(&ob->lodlevels, lod_cmp);
+ BLI_listbase_sort(&ob->lodlevels, lod_cmp);
}
bool BKE_object_lod_remove(Object *ob, int level)
{
LodLevel *rem;
- if (level < 1 || level > BLI_countlist(&ob->lodlevels) - 1)
+ if (level < 1 || level > BLI_listbase_count(&ob->lodlevels) - 1)
return false;
rem = BLI_findlink(&ob->lodlevels, level);
@@ -1098,7 +1098,7 @@ bool BKE_object_lod_remove(Object *ob, int level)
MEM_freeN(rem);
/* If there are no user defined lods, remove the base lod as well */
- if (BLI_countlist(&ob->lodlevels) == 1) {
+ if (BLI_listbase_is_single(&ob->lodlevels)) {
LodLevel *base = ob->lodlevels.first;
BLI_remlink(&ob->lodlevels, base);
MEM_freeN(base);
@@ -1136,7 +1136,7 @@ static LodLevel *lod_level_select(Object *ob, const float camera_position[3])
bool BKE_object_lod_is_usable(Object *ob, Scene *scene)
{
- bool active = (scene) ? ob == OBACT : 0;
+ bool active = (scene) ? ob == OBACT : false;
return (ob->mode == OB_MODE_OBJECT || !active);
}
@@ -1402,10 +1402,10 @@ bool BKE_object_pose_context_check(Object *ob)
(ob->pose) &&
(ob->mode & OB_MODE_POSE))
{
- return 1;
+ return true;
}
else {
- return 0;
+ return false;
}
}
@@ -2161,26 +2161,60 @@ static void give_parvert(Object *par, int nr, float vec[3])
int numVerts = dm->getNumVerts(dm);
if (nr < numVerts) {
- /* avoid dm->getVertDataArray() since it allocates arrays in the dm (not thread safe) */
- int i;
+ bool use_special_ss_case = false;
+
+ if (dm->type == DM_TYPE_CCGDM) {
+ ModifierData *md;
+ VirtualModifierData virtualModifierData;
+ use_special_ss_case = true;
+ for (md = modifiers_getVirtualModifierList(par, &virtualModifierData);
+ md != NULL;
+ md = md->next)
+ {
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ /* TODO(sergey): Check for disabled modifiers. */
+ if (mti->type != eModifierTypeType_OnlyDeform && md->next != NULL) {
+ use_special_ss_case = false;
+ break;
+ }
+ }
+ }
- if (em && dm->type == DM_TYPE_EDITBMESH) {
- if (em->bm->elem_table_dirty & BM_VERT) {
-#ifdef VPARENT_THREADING_HACK
- BLI_mutex_lock(&vparent_lock);
+ if (!use_special_ss_case) {
+ /* avoid dm->getVertDataArray() since it allocates arrays in the dm (not thread safe) */
+ if (em && dm->type == DM_TYPE_EDITBMESH) {
if (em->bm->elem_table_dirty & BM_VERT) {
- BM_mesh_elem_table_ensure(em->bm, BM_VERT);
- }
- BLI_mutex_unlock(&vparent_lock);
+#ifdef VPARENT_THREADING_HACK
+ BLI_mutex_lock(&vparent_lock);
+ if (em->bm->elem_table_dirty & BM_VERT) {
+ BM_mesh_elem_table_ensure(em->bm, BM_VERT);
+ }
+ BLI_mutex_unlock(&vparent_lock);
#else
- BLI_assert(!"Not safe for threading");
- BM_mesh_elem_table_ensure(em->bm, BM_VERT);
+ BLI_assert(!"Not safe for threading");
+ BM_mesh_elem_table_ensure(em->bm, BM_VERT);
#endif
+ }
+ }
+ }
+
+ if (use_special_ss_case) {
+ /* Special case if the last modifier is SS and no constructive modifier are in front of it. */
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
+ CCGVert *ccg_vert = ccgSubSurf_getVert(ccgdm->ss, SET_INT_IN_POINTER(nr));
+ /* In case we deleted some verts, nr may refer to inexistent one now, see T42557. */
+ if (ccg_vert) {
+ float *co = ccgSubSurf_getVertData(ccgdm->ss, ccg_vert);
+ add_v3_v3(vec, co);
+ count++;
}
}
+ else if (CustomData_has_layer(&dm->vertData, CD_ORIGINDEX) &&
+ !(em && dm->type == DM_TYPE_EDITBMESH))
+ {
+ int i;
- /* get the average of all verts with (original index == nr) */
- if (CustomData_has_layer(&dm->vertData, CD_ORIGINDEX)) {
+ /* Get the average of all verts with (original index == nr). */
for (i = 0; i < numVerts; i++) {
const int *index = dm->getVertData(dm, i, CD_ORIGINDEX);
if (*index == nr) {
@@ -2219,8 +2253,18 @@ static void give_parvert(Object *par, int nr, float vec[3])
}
}
else if (ELEM(par->type, OB_CURVE, OB_SURF)) {
- Curve *cu = par->data;
- ListBase *nurb = BKE_curve_nurbs_get(cu);
+ ListBase *nurb;
+
+ /* Unless there's some weird depsgraph failure the cache should exist. */
+ BLI_assert(par->curve_cache != NULL);
+
+ if (par->curve_cache->deformed_nurbs.first != NULL) {
+ nurb = &par->curve_cache->deformed_nurbs;
+ }
+ else {
+ Curve *cu = par->data;
+ nurb = BKE_curve_nurbs_get(cu);
+ }
BKE_nurbList_index_get_co(nurb, nr, vec);
}
@@ -2357,7 +2401,7 @@ static bool where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat
/* include framerate */
fac1 = (1.0f / (1.0f + fabsf(ob->sf)));
- if (fac1 >= 1.0f) return 0;
+ if (fac1 >= 1.0f) return false;
fac2 = 1.0f - fac1;
fp1 = obmat[0];
@@ -2366,7 +2410,7 @@ static bool where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat
fp1[0] = fac1 * fp1[0] + fac2 * fp2[0];
}
- return 1;
+ return true;
}
/* note, scene is the active scene while actual_scene is the scene the object resides in */
@@ -3255,7 +3299,7 @@ int BKE_object_insert_ptcache(Object *ob)
LinkData *link = NULL;
int i = 0;
- BLI_sortlist(&ob->pc_ids, pc_cmp);
+ BLI_listbase_sort(&ob->pc_ids, pc_cmp);
for (link = ob->pc_ids.first, i = 0; link; link = link->next, i++) {
int index = GET_INT_FROM_POINTER(link->data);
@@ -3316,7 +3360,7 @@ static KeyBlock *insert_meshkey(Scene *scene, Object *ob, const char *name, cons
if (newkey || from_mix == false) {
/* create from mesh */
kb = BKE_keyblock_add_ctime(key, name, false);
- BKE_key_convert_from_mesh(me, kb);
+ BKE_keyblock_convert_from_mesh(me, kb);
}
else {
/* copy from current values */
@@ -3353,7 +3397,7 @@ static KeyBlock *insert_lattkey(Scene *scene, Object *ob, const char *name, cons
kb->totelem = basekb->totelem;
}
else {
- BKE_key_convert_from_lattice(lt, kb);
+ BKE_keyblock_convert_from_lattice(lt, kb);
}
}
else {
@@ -3393,7 +3437,7 @@ static KeyBlock *insert_curvekey(Scene *scene, Object *ob, const char *name, con
kb->totelem = basekb->totelem;
}
else {
- BKE_key_convert_from_curve(cu, kb, lb);
+ BKE_keyblock_convert_from_curve(cu, kb, lb);
}
}
else {
diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c
index e53bd26b9a2..e46929dde4a 100644
--- a/source/blender/blenkernel/intern/object_deform.c
+++ b/source/blender/blenkernel/intern/object_deform.c
@@ -27,18 +27,457 @@
#include "MEM_guardedalloc.h"
+#include "BLF_translation.h"
+
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "BLI_listbase.h"
+#include "DNA_armature_types.h"
+#include "DNA_cloth_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_lattice_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+#include "DNA_object_force.h"
+#include "DNA_particle_types.h"
+#include "DNA_scene_types.h"
+
#include "BKE_action.h"
+#include "BKE_deform.h"
+#include "BKE_editmesh.h"
#include "BKE_object_deform.h" /* own include */
#include "BKE_object.h"
#include "BKE_modifier.h"
-#include "DNA_armature_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_object_types.h"
+/** \name Misc helpers
+ * \{ */
+
+static Lattice *object_defgroup_lattice_get(ID *id)
+{
+ Lattice *lt = (Lattice *)id;
+ BLI_assert(GS(id->name) == ID_LT);
+ return (lt->editlatt) ? lt->editlatt->latt : lt;
+}
+
+/**
+ * Update users of vgroups from this object, according to given map.
+ *
+ * Use it when you remove or reorder vgroups in the object.
+ *
+ * \param map an array mapping old indices to new indices.
+ */
+void BKE_object_defgroup_remap_update_users(Object *ob, int *map)
+{
+ ModifierData *md;
+ ParticleSystem *psys;
+ int a;
+
+ /* these cases don't use names to refer to vertex groups, so when
+ * they get removed the numbers get out of sync, this corrects that */
+
+ if (ob->soft) {
+ ob->soft->vertgroup = map[ob->soft->vertgroup];
+ }
+
+ for (md = ob->modifiers.first; md; md = md->next) {
+ if (md->type == eModifierType_Explode) {
+ ExplodeModifierData *emd = (ExplodeModifierData *)md;
+ emd->vgroup = map[emd->vgroup];
+ }
+ else if (md->type == eModifierType_Cloth) {
+ ClothModifierData *clmd = (ClothModifierData *)md;
+ ClothSimSettings *clsim = clmd->sim_parms;
+
+ if (clsim) {
+ clsim->vgroup_mass = map[clsim->vgroup_mass];
+ clsim->vgroup_bend = map[clsim->vgroup_bend];
+ clsim->vgroup_struct = map[clsim->vgroup_struct];
+ }
+ }
+ }
+
+ for (psys = ob->particlesystem.first; psys; psys = psys->next) {
+ for (a = 0; a < PSYS_TOT_VG; a++) {
+ psys->vgroup[a] = map[psys->vgroup[a]];
+ }
+ }
+}
+/** \} */
+
+
+/** \name Group creation
+ * \{ */
+
+/**
+ * Add a vgroup of given name to object. *Does not* handle MDeformVert data at all!
+ */
+bDeformGroup *BKE_object_defgroup_add_name(Object *ob, const char *name)
+{
+ bDeformGroup *defgroup;
+
+ if (!ob || !OB_TYPE_SUPPORT_VGROUP(ob->type))
+ return NULL;
+
+ defgroup = BKE_defgroup_new(ob, name);
+
+ ob->actdef = BLI_listbase_count(&ob->defbase);
+
+ return defgroup;
+}
+
+/**
+ * Add a vgroup of default name to object. *Does not* handle MDeformVert data at all!
+ */
+bDeformGroup *BKE_object_defgroup_add(Object *ob)
+{
+ return BKE_object_defgroup_add_name(ob, DATA_("Group"));
+}
+
+/**
+ * Create MDeformVert data for given ID. Work in Object mode only.
+ */
+MDeformVert *BKE_object_defgroup_data_create(ID *id)
+{
+ if (GS(id->name) == ID_ME) {
+ Mesh *me = (Mesh *)id;
+ me->dvert = CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert);
+ return me->dvert;
+ }
+ else if (GS(id->name) == ID_LT) {
+ Lattice *lt = (Lattice *)id;
+ lt->dvert = MEM_callocN(sizeof(MDeformVert) * lt->pntsu * lt->pntsv * lt->pntsw, "lattice deformVert");
+ return lt->dvert;
+ }
+
+ return NULL;
+}
+/** \} */
+
+
+/** \name Group clearing
+ * \{ */
+
+/**
+ * Remove all verts (or only selected ones) from given vgroup. Work in Object and Edit modes.
+ *
+ * \param allverts If true, remove all vertices, else only selected ones.
+ * \return True if any vertex was removed, false otherwise.
+ */
+bool BKE_object_defgroup_clear(Object *ob, bDeformGroup *dg, const bool use_selection)
+{
+ MDeformVert *dv;
+ const int def_nr = BLI_findindex(&ob->defbase, dg);
+ bool changed = false;
+
+ if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+
+ if (me->edit_btmesh) {
+ BMEditMesh *em = me->edit_btmesh;
+ const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
+
+ if (cd_dvert_offset != -1) {
+ BMVert *eve;
+ BMIter iter;
+
+ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
+ dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
+
+ if (dv && dv->dw && (!use_selection || BM_elem_flag_test(eve, BM_ELEM_SELECT))) {
+ MDeformWeight *dw = defvert_find_index(dv, def_nr);
+ defvert_remove_group(dv, dw); /* dw can be NULL */
+ changed = true;
+ }
+ }
+ }
+ }
+ else {
+ if (me->dvert) {
+ MVert *mv;
+ int i;
+
+ mv = me->mvert;
+ dv = me->dvert;
+
+ for (i = 0; i < me->totvert; i++, mv++, dv++) {
+ if (mv->flag & SELECT) {
+ if (dv->dw && (!use_selection || (mv->flag & SELECT))) {
+ MDeformWeight *dw = defvert_find_index(dv, def_nr);
+ defvert_remove_group(dv, dw); /* dw can be NULL */
+ changed = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (ob->type == OB_LATTICE) {
+ Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data));
+
+ if (lt->dvert) {
+ BPoint *bp;
+ int i, tot = lt->pntsu * lt->pntsv * lt->pntsw;
+
+ for (i = 0, bp = lt->def; i < tot; i++, bp++) {
+ if (!use_selection || (bp->f1 & SELECT)) {
+ MDeformWeight *dw;
+
+ dv = &lt->dvert[i];
+
+ dw = defvert_find_index(dv, def_nr);
+ defvert_remove_group(dv, dw); /* dw can be NULL */
+ changed = true;
+ }
+ }
+ }
+ }
+
+ return changed;
+}
+
+/**
+ * Remove all verts (or only selected ones) from all vgroups. Work in Object and Edit modes.
+ *
+ * \param allverts If true, remove all vertices, else only selected ones.
+ * \return True if any vertex was removed, false otherwise.
+ */
+bool BKE_object_defgroup_clear_all(Object *ob, const bool use_selection)
+{
+ bDeformGroup *dg;
+ bool changed = false;
+
+ for (dg = ob->defbase.first; dg; dg = dg->next) {
+ if (BKE_object_defgroup_clear(ob, dg, use_selection)) {
+ changed = true;
+ }
+ }
+
+ return changed;
+}
+/** \} */
+
+
+/** \name Group removal
+ * \{ */
+
+static void object_defgroup_remove_update_users(Object *ob, const int idx)
+{
+ int i, defbase_tot = BLI_listbase_count(&ob->defbase) + 1;
+ int *map = MEM_mallocN(sizeof(int) * defbase_tot, "vgroup del");
+
+ map[idx] = map[0] = 0;
+ for (i = 1; i < idx; i++) {
+ map[i] = i;
+ }
+ for (i = idx + 1; i < defbase_tot; i++) {
+ map[i] = i - 1;
+ }
+
+ BKE_object_defgroup_remap_update_users(ob, map);
+ MEM_freeN(map);
+}
+
+static void object_defgroup_remove_common(Object *ob, bDeformGroup *dg, const int def_nr)
+{
+ object_defgroup_remove_update_users(ob, def_nr + 1);
+
+ /* Remove the group */
+ BLI_freelinkN(&ob->defbase, dg);
+
+ /* Update the active deform index if necessary */
+ if (ob->actdef > def_nr)
+ ob->actdef--;
+
+ /* remove all dverts */
+ if (BLI_listbase_is_empty(&ob->defbase)) {
+ if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+ CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
+ me->dvert = NULL;
+ }
+ else if (ob->type == OB_LATTICE) {
+ Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data));
+ if (lt->dvert) {
+ MEM_freeN(lt->dvert);
+ lt->dvert = NULL;
+ }
+ }
+ }
+ else if (ob->actdef < 1) { /* Keep a valid active index if we still have some vgroups. */
+ ob->actdef = 1;
+ }
+}
+
+static void object_defgroup_remove_object_mode(Object *ob, bDeformGroup *dg)
+{
+ MDeformVert *dvert_array = NULL;
+ int dvert_tot = 0;
+ const int def_nr = BLI_findindex(&ob->defbase, dg);
+
+ BLI_assert(def_nr != -1);
+
+ BKE_object_defgroup_array_get(ob->data, &dvert_array, &dvert_tot);
+
+ if (dvert_array) {
+ int i, j;
+ MDeformVert *dv;
+ for (i = 0, dv = dvert_array; i < dvert_tot; i++, dv++) {
+ MDeformWeight *dw;
+
+ dw = defvert_find_index(dv, def_nr);
+ defvert_remove_group(dv, dw); /* dw can be NULL */
+
+ /* inline, make into a function if anything else needs to do this */
+ for (j = 0; j < dv->totweight; j++) {
+ if (dv->dw[j].def_nr > def_nr) {
+ dv->dw[j].def_nr--;
+ }
+ }
+ /* done */
+ }
+ }
+
+ object_defgroup_remove_common(ob, dg, def_nr);
+}
+
+static void object_defgroup_remove_edit_mode(Object *ob, bDeformGroup *dg)
+{
+ int i;
+ const int def_nr = BLI_findindex(&ob->defbase, dg);
+
+ BLI_assert(def_nr != -1);
+
+ /* Make sure that no verts are using this group - if none were removed, we can skip next per-vert update. */
+ if (!BKE_object_defgroup_clear(ob, dg, false)) {
+ /* Nothing to do. */
+ }
+ /* Else, make sure that any groups with higher indices are adjusted accordingly */
+ else if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+ BMEditMesh *em = me->edit_btmesh;
+ const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
+
+ BMIter iter;
+ BMVert *eve;
+ MDeformVert *dvert;
+
+ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
+ dvert = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
+
+ if (dvert) {
+ for (i = 0; i < dvert->totweight; i++) {
+ if (dvert->dw[i].def_nr > def_nr) {
+ dvert->dw[i].def_nr--;
+ }
+ }
+ }
+ }
+ }
+ else if (ob->type == OB_LATTICE) {
+ Lattice *lt = ((Lattice *)(ob->data))->editlatt->latt;
+ BPoint *bp;
+ MDeformVert *dvert = lt->dvert;
+ int a, tot;
+
+ if (dvert) {
+ tot = lt->pntsu * lt->pntsv * lt->pntsw;
+ for (a = 0, bp = lt->def; a < tot; a++, bp++, dvert++) {
+ for (i = 0; i < dvert->totweight; i++) {
+ if (dvert->dw[i].def_nr > def_nr) {
+ dvert->dw[i].def_nr--;
+ }
+ }
+ }
+ }
+ }
+
+ object_defgroup_remove_common(ob, dg, def_nr);
+}
+
+/**
+ * Remove given vgroup from object. Work in Object and Edit modes.
+ */
+void BKE_object_defgroup_remove(Object *ob, bDeformGroup *defgroup)
+{
+ if (BKE_object_is_in_editmode_vgroup(ob))
+ object_defgroup_remove_edit_mode(ob, defgroup);
+ else
+ object_defgroup_remove_object_mode(ob, defgroup);
+}
+
+/**
+ * Remove all vgroups from object. Work in Object and Edit modes.
+ */
+void BKE_object_defgroup_remove_all(Object *ob)
+{
+ bDeformGroup *dg = (bDeformGroup *)ob->defbase.first;
+ const bool edit_mode = BKE_object_is_in_editmode_vgroup(ob);
+
+ if (dg) {
+ while (dg) {
+ bDeformGroup *next_dg = dg->next;
+
+ if (edit_mode)
+ object_defgroup_remove_edit_mode(ob, dg);
+ else
+ object_defgroup_remove_object_mode(ob, dg);
+
+ dg = next_dg;
+ }
+ }
+ else { /* ob->defbase is empty... */
+ /* remove all dverts */
+ if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+ CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
+ me->dvert = NULL;
+ }
+ else if (ob->type == OB_LATTICE) {
+ Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data));
+ if (lt->dvert) {
+ MEM_freeN(lt->dvert);
+ lt->dvert = NULL;
+ }
+ }
+ /* Fix counters/indices */
+ ob->actdef = 0;
+ }
+}
+
+/**
+ * Get MDeformVert vgroup data from given object. Should only be used in Object mode.
+ *
+ * \return True if the id type supports weights.
+ */
+bool BKE_object_defgroup_array_get(ID *id, MDeformVert **dvert_arr, int *dvert_tot)
+{
+ if (id) {
+ switch (GS(id->name)) {
+ case ID_ME:
+ {
+ Mesh *me = (Mesh *)id;
+ *dvert_arr = me->dvert;
+ *dvert_tot = me->totvert;
+ return true;
+ }
+ case ID_LT:
+ {
+ Lattice *lt = object_defgroup_lattice_get(id);
+ *dvert_arr = lt->dvert;
+ *dvert_tot = lt->pntsu * lt->pntsv * lt->pntsw;
+ return true;
+ }
+ }
+ }
+
+ *dvert_arr = NULL;
+ *dvert_tot = 0;
+ return false;
+}
+/** \} */
/* --- functions for getting vgroup aligned maps --- */
@@ -46,11 +485,11 @@
* gets the status of "flag" for each bDeformGroup
* in ob->defbase and returns an array containing them
*/
-bool *BKE_objdef_lock_flags_get(Object *ob, const int defbase_tot)
+bool *BKE_object_defgroup_lock_flags_get(Object *ob, const int defbase_tot)
{
bool is_locked = false;
int i;
- //int defbase_tot = BLI_countlist(&ob->defbase);
+ //int defbase_tot = BLI_listbase_count(&ob->defbase);
bool *lock_flags = MEM_mallocN(defbase_tot * sizeof(bool), "defflags");
bDeformGroup *defgroup;
@@ -66,21 +505,21 @@ bool *BKE_objdef_lock_flags_get(Object *ob, const int defbase_tot)
return NULL;
}
-bool *BKE_objdef_validmap_get(Object *ob, const int defbase_tot)
+bool *BKE_object_defgroup_validmap_get(Object *ob, const int defbase_tot)
{
bDeformGroup *dg;
ModifierData *md;
- bool *vgroup_validmap;
+ bool *defgroup_validmap;
GHash *gh;
int i, step1 = 1;
- //int defbase_tot = BLI_countlist(&ob->defbase);
+ //int defbase_tot = BLI_listbase_count(&ob->defbase);
VirtualModifierData virtualModifierData;
if (BLI_listbase_is_empty(&ob->defbase)) {
return NULL;
}
- gh = BLI_ghash_str_new_ex("BKE_objdef_validmap_get gh", defbase_tot);
+ gh = BLI_ghash_str_new_ex(__func__, defbase_tot);
/* add all names to a hash table */
for (dg = ob->defbase.first; dg; dg = dg->next) {
@@ -115,23 +554,23 @@ bool *BKE_objdef_validmap_get(Object *ob, const int defbase_tot)
}
}
- vgroup_validmap = MEM_mallocN(sizeof(*vgroup_validmap) * defbase_tot, "wpaint valid map");
+ defgroup_validmap = MEM_mallocN(sizeof(*defgroup_validmap) * defbase_tot, "wpaint valid map");
/* add all names to a hash table */
for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) {
- vgroup_validmap[i] = (BLI_ghash_lookup(gh, dg->name) != NULL);
+ defgroup_validmap[i] = (BLI_ghash_lookup(gh, dg->name) != NULL);
}
BLI_assert(i == BLI_ghash_size(gh));
BLI_ghash_free(gh, NULL, NULL);
- return vgroup_validmap;
+ return defgroup_validmap;
}
/* Returns total selected vgroups,
* wpi.defbase_sel is assumed malloc'd, all values are set */
-bool *BKE_objdef_selected_get(Object *ob, int defbase_tot, int *r_dg_flags_sel_tot)
+bool *BKE_object_defgroup_selected_get(Object *ob, int defbase_tot, int *r_dg_flags_sel_tot)
{
bool *dg_selection = MEM_mallocN(defbase_tot * sizeof(bool), __func__);
bDeformGroup *defgroup;
@@ -158,3 +597,86 @@ bool *BKE_objdef_selected_get(Object *ob, int defbase_tot, int *r_dg_flags_sel_t
return dg_selection;
}
+
+
+/**
+ * Return the subset type of the Vertex Group Selection
+ */
+bool *BKE_object_defgroup_subset_from_select_type(
+ Object *ob, eVGroupSelect subset_type, int *r_defgroup_tot, int *r_subset_count)
+{
+ bool *defgroup_validmap = NULL;
+ *r_defgroup_tot = BLI_listbase_count(&ob->defbase);
+
+ switch (subset_type) {
+ case WT_VGROUP_ACTIVE:
+ {
+ const int def_nr_active = ob->actdef - 1;
+ defgroup_validmap = MEM_mallocN(*r_defgroup_tot * sizeof(*defgroup_validmap), __func__);
+ memset(defgroup_validmap, false, *r_defgroup_tot * sizeof(*defgroup_validmap));
+ if ((def_nr_active >= 0) && (def_nr_active < *r_defgroup_tot)) {
+ *r_subset_count = 1;
+ defgroup_validmap[def_nr_active] = true;
+ }
+ else {
+ *r_subset_count = 0;
+ }
+ break;
+ }
+ case WT_VGROUP_BONE_SELECT:
+ {
+ defgroup_validmap = BKE_object_defgroup_selected_get(ob, *r_defgroup_tot, r_subset_count);
+ break;
+ }
+ case WT_VGROUP_BONE_DEFORM:
+ {
+ int i;
+ defgroup_validmap = BKE_object_defgroup_validmap_get(ob, *r_defgroup_tot);
+ *r_subset_count = 0;
+ for (i = 0; i < *r_defgroup_tot; i++) {
+ if (defgroup_validmap[i] == true) {
+ *r_subset_count += 1;
+ }
+ }
+ break;
+ }
+ case WT_VGROUP_BONE_DEFORM_OFF:
+ {
+ int i;
+ defgroup_validmap = BKE_object_defgroup_validmap_get(ob, *r_defgroup_tot);
+ *r_subset_count = 0;
+ for (i = 0; i < *r_defgroup_tot; i++) {
+ defgroup_validmap[i] = !defgroup_validmap[i];
+ if (defgroup_validmap[i] == true) {
+ *r_subset_count += 1;
+ }
+ }
+ break;
+ }
+ case WT_VGROUP_ALL:
+ default:
+ {
+ defgroup_validmap = MEM_mallocN(*r_defgroup_tot * sizeof(*defgroup_validmap), __func__);
+ memset(defgroup_validmap, true, *r_defgroup_tot * sizeof(*defgroup_validmap));
+ *r_subset_count = *r_defgroup_tot;
+ break;
+ }
+ }
+
+ return defgroup_validmap;
+}
+
+/**
+ * store indices from the defgroup_validmap (faster lookups in some cases)
+ */
+void BKE_object_defgroup_subset_to_index_array(
+ const bool *defgroup_validmap, const int defgroup_tot, int *r_defgroup_subset_map)
+{
+ int i, j = 0;
+ for (i = 0; i < defgroup_tot; i++) {
+ if (defgroup_validmap[i]) {
+ r_defgroup_subset_map[j++] = i;
+ }
+ }
+}
+
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index 0d82c6e89a1..2bee6b76ad6 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -1240,7 +1240,7 @@ int count_duplilist(Object *ob)
DupliApplyData *duplilist_apply(Object *ob, ListBase *duplilist)
{
DupliApplyData *apply_data = NULL;
- int num_objects = BLI_countlist(duplilist);
+ int num_objects = BLI_listbase_count(duplilist);
if (num_objects > 0) {
DupliObject *dob;
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index d16575d80c8..96fff339521 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -316,7 +316,7 @@ void BKE_paint_curve_set(Brush *br, PaintCurve *pc)
void BKE_palette_color_remove(Palette *palette, PaletteColor *color)
{
if (color) {
- int numcolors = BLI_countlist(&palette->colors);
+ int numcolors = BLI_listbase_count(&palette->colors);
if ((numcolors == palette->active_color + 1) && (numcolors != 1))
palette->active_color--;
@@ -352,7 +352,7 @@ PaletteColor *BKE_palette_color_add(Palette *palette)
{
PaletteColor *color = MEM_callocN(sizeof(*color), "Pallete Color");
BLI_addtail(&palette->colors, color);
- palette->active_color = BLI_countlist(&palette->colors) - 1;
+ palette->active_color = BLI_listbase_count(&palette->colors) - 1;
return color;
}
@@ -644,11 +644,11 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
VirtualModifierData virtualModifierData;
if (mmd || ob->sculpt->bm)
- return 0;
+ return false;
/* non-locked shape keys could be handled in the same way as deformed mesh */
if ((ob->shapeflag & OB_SHAPE_LOCK) == 0 && me->key && ob->shapenr)
- return 1;
+ return true;
md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
@@ -658,11 +658,11 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
if (!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
if (ELEM(md->type, eModifierType_ShapeKey, eModifierType_Multires)) continue;
- if (mti->type == eModifierTypeType_OnlyDeform) return 1;
- else if ((sd->flags & SCULPT_ONLY_DEFORM) == 0) return 1;
+ if (mti->type == eModifierTypeType_OnlyDeform) return true;
+ else if ((sd->flags & SCULPT_ONLY_DEFORM) == 0) return true;
}
- return 0;
+ return false;
}
/**
@@ -740,7 +740,7 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
BKE_free_sculptsession_deformMats(ss);
- ss->orig_cos = (ss->kb) ? BKE_key_convert_to_vertcos(ob, ss->kb) : BKE_mesh_vertexCos_get(me, NULL);
+ ss->orig_cos = (ss->kb) ? BKE_keyblock_convert_to_vertcos(ob, ss->kb) : BKE_mesh_vertexCos_get(me, NULL);
BKE_crazyspace_build_sculpt(scene, ob, &ss->deform_imats, &ss->deform_cos);
BKE_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos);
@@ -755,14 +755,14 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
}
if (ss->kb != NULL && ss->deform_cos == NULL) {
- ss->deform_cos = BKE_key_convert_to_vertcos(ob, ss->kb);
+ ss->deform_cos = BKE_keyblock_convert_to_vertcos(ob, ss->kb);
}
/* if pbvh is deformed, key block is already applied to it */
if (ss->kb) {
bool pbvh_deformd = BKE_pbvh_isDeformed(ss->pbvh);
if (!pbvh_deformd || ss->deform_cos == NULL) {
- float (*vertCos)[3] = BKE_key_convert_to_vertcos(ob, ss->kb);
+ float (*vertCos)[3] = BKE_keyblock_convert_to_vertcos(ob, ss->kb);
if (vertCos) {
if (!pbvh_deformd) {
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 530573d6e38..d577293fccb 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -981,14 +981,14 @@ bool psys_render_simplify_params(ParticleSystem *psys, ChildParticle *cpa, float
int b;
if (!(psys->renderdata && (psys->part->simplify_flag & PART_SIMPLIFY_ENABLE)))
- return 0;
+ return false;
data = psys->renderdata;
if (!data->do_simplify)
- return 0;
+ return false;
b = (data->index_mf_to_mpoly) ? DM_origindex_mface_mpoly(data->index_mf_to_mpoly, data->index_mp_to_orig, cpa->num) : cpa->num;
if (b == ORIGINDEX_NONE) {
- return 0;
+ return false;
}
elem = &data->elems[b];
@@ -1043,7 +1043,7 @@ static float interpolate_particle_value(float v1, float v2, float v3, float v4,
return value;
}
-void psys_interpolate_particle(short type, ParticleKey keys[4], float dt, ParticleKey *result, int velocity)
+void psys_interpolate_particle(short type, ParticleKey keys[4], float dt, ParticleKey *result, bool velocity)
{
float t[4];
@@ -1073,7 +1073,6 @@ void psys_interpolate_particle(short type, ParticleKey keys[4], float dt, Partic
}
-
typedef struct ParticleInterpolationData {
HairKey *hkey[2];
@@ -3514,8 +3513,8 @@ ModifierData *object_add_particle_system(Scene *scene, Object *ob, const char *n
psys->part = psys_new_settings(DATA_("ParticleSettings"), NULL);
- if (BLI_countlist(&ob->particlesystem) > 1)
- BLI_snprintf(psys->name, sizeof(psys->name), DATA_("ParticleSystem %i"), BLI_countlist(&ob->particlesystem));
+ if (BLI_listbase_count_ex(&ob->particlesystem, 2) > 1)
+ BLI_snprintf(psys->name, sizeof(psys->name), DATA_("ParticleSystem %i"), BLI_listbase_count(&ob->particlesystem));
else
BLI_strncpy(psys->name, DATA_("ParticleSystem"), sizeof(psys->name));
@@ -3524,7 +3523,7 @@ ModifierData *object_add_particle_system(Scene *scene, Object *ob, const char *n
if (name)
BLI_strncpy_utf8(md->name, name, sizeof(md->name));
else
- BLI_snprintf(md->name, sizeof(md->name), DATA_("ParticleSystem %i"), BLI_countlist(&ob->particlesystem));
+ BLI_snprintf(md->name, sizeof(md->name), DATA_("ParticleSystem %i"), BLI_listbase_count(&ob->particlesystem));
modifier_unique_name(&ob->modifiers, md);
psmd = (ParticleSystemModifierData *) md;
@@ -4564,8 +4563,7 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa
psys_particle_on_emitter(psmd, PART_FROM_FACE, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, loc, nor, 0, 0, 0, 0);
if (psys->part->rotmode == PART_ROT_VEL) {
- copy_m3_m4(nmat, ob->imat);
- transpose_m3(nmat);
+ transpose_m3_m4(nmat, ob->imat);
mul_m3_v3(nmat, nor);
normalize_v3(nor);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 155299b69c3..7ad99c14565 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -2764,24 +2764,6 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
sphdata->pass++;
}
-/* 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;
@@ -2803,7 +2785,7 @@ static void sphclassical_density_accum_cb(void *userdata, int index, float UNUSE
/* 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 = qfac / pow3f(pfr->h) * pow4f(2.0f - rij_h) * ( 1.0f + 2.0f * rij_h);
q *= pfr->npsys->part->mass;
if (pfr->use_size)
@@ -2857,7 +2839,7 @@ static void sphclassical_force_cb(void *sphdata_v, ParticleKey *state, float *fo
float rest_density = fluid->rest_density * (fluid->flag & SPH_FAC_DENSITY ? 4.77f : 1.0f);
// Use speed of sound squared
- float stiffness = pow2(fluid->stiffness_k);
+ float stiffness = pow2f(fluid->stiffness_k);
ParticleData *npa;
float vec[3];
@@ -2878,10 +2860,10 @@ static void sphclassical_force_cb(void *sphdata_v, ParticleKey *state, float *fo
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);
+ pressure = stiffness * (pow7f(pa->sphdensity / rest_density) - 1.0f);
/* multiply by mass so that we return a force, not accel */
- qfac2 *= sphdata->mass / pow3(pfr.h);
+ qfac2 *= sphdata->mass / pow3f(pfr.h);
pfn = pfr.neighbors;
for (i = 0; i < pfr.tot_neighbors; i++, pfn++) {
@@ -2902,19 +2884,19 @@ static void sphclassical_force_cb(void *sphdata_v, ParticleKey *state, float *fo
if (rij_h > 2.0f)
continue;
- npressure = stiffness * (pow7(npa->sphdensity / rest_density) - 1.0f);
+ npressure = stiffness * (pow7f(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) );
+ dq = qfac2 * (2.0f * pow4f(2.0f - rij_h) - 4.0f * pow3f(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);
+ pressureTerm = pressure / pow2f(pa->sphdensity) + npressure / pow2f(npa->sphdensity);
/* Note that 'minus' is removed, because vec = vecBA, not vecAB.
* This applies to the viscosity calculation below, too. */
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index ff6fae08460..bd953890443 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -943,7 +943,7 @@ static bool update_search_cb(PBVHNode *node, void *data_v)
if (node->flag & PBVH_Leaf)
return (node->flag & flag) != 0;
- return 1;
+ return true;
}
static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
@@ -1474,10 +1474,10 @@ bool ray_face_intersection(const float ray_start[3],
(t3 && isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t2, t3, &dist, NULL, 0.1f) && dist < *fdist))
{
*fdist = dist;
- return 1;
+ return true;
}
else {
- return 0;
+ return false;
}
}
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index a6a7664ec61..19ed49c727a 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -50,7 +50,6 @@
#include "BLI_threads.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BLI_system.h"
#include "BLF_translation.h"
@@ -58,6 +57,7 @@
#include "WM_api.h"
+#include "BKE_appdir.h"
#include "BKE_anim.h"
#include "BKE_blender.h"
#include "BKE_cloth.h"
@@ -1043,8 +1043,6 @@ static void ptcache_rigidbody_interpolate(int index, void *rb_v, void **data, fl
{
RigidBodyWorld *rbw = rb_v;
Object *ob = NULL;
- ParticleKey keys[4];
- float dfra;
if (rbw->objects)
ob = rbw->objects[index];
@@ -1053,6 +1051,11 @@ static void ptcache_rigidbody_interpolate(int index, void *rb_v, void **data, fl
RigidBodyOb *rbo = ob->rigidbody_object;
if (rbo->type == RBO_TYPE_ACTIVE) {
+ ParticleKey keys[4];
+ ParticleKey result;
+ float dfra;
+
+ memset(keys, 0, sizeof(keys));
copy_v3_v3(keys[1].co, rbo->pos);
copy_qt_qt(keys[1].rot, rbo->orn);
@@ -1062,16 +1065,17 @@ static void ptcache_rigidbody_interpolate(int index, void *rb_v, void **data, fl
memcpy(keys[2].rot, data + 3, 4 * sizeof(float));
}
else {
- BKE_ptcache_make_particle_key(keys+2, 0, data, cfra2);
+ BKE_ptcache_make_particle_key(&keys[2], 0, data, cfra2);
}
dfra = cfra2 - cfra1;
- psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, keys, 1);
- interp_qt_qtqt(keys->rot, keys[1].rot, keys[2].rot, (cfra - cfra1) / dfra);
+ /* note: keys[0] and keys[3] unused for type < 1 (crappy) */
+ psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, &result, true);
+ interp_qt_qtqt(result.rot, keys[1].rot, keys[2].rot, (cfra - cfra1) / dfra);
- copy_v3_v3(rbo->pos, keys->co);
- copy_qt_qt(rbo->orn, keys->rot);
+ copy_v3_v3(rbo->pos, result.co);
+ copy_qt_qt(rbo->orn, result.rot);
}
}
}
@@ -1465,7 +1469,7 @@ static int ptcache_path(PTCacheID *pid, char *filename)
/* use the temp path. this is weak but better then not using point cache at all */
/* temporary directory is assumed to exist and ALWAYS has a trailing slash */
- BLI_snprintf(filename, MAX_PTCACHE_PATH, "%s"PTCACHE_PATH, BLI_temp_dir_session());
+ BLI_snprintf(filename, MAX_PTCACHE_PATH, "%s"PTCACHE_PATH, BKE_tempdir_session());
return BLI_add_slash(filename); /* new strlen() */
}
@@ -2567,12 +2571,19 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
if (pid->cache->flag & PTCACHE_DISK_CACHE) {
ptcache_path(pid, path);
- len = ptcache_filename(pid, filename, cfra, 0, 0); /* no path */
-
dir = opendir(path);
if (dir==NULL)
return;
-
+
+ len = ptcache_filename(pid, filename, cfra, 0, 0); /* no path */
+ /* append underscore terminator to ensure we don't match similar names
+ * from objects whose names start with the same prefix
+ */
+ if (len < sizeof(filename) - 2) {
+ BLI_strncpy(filename + len, "_", sizeof(filename) - 2 - len);
+ len += 1;
+ }
+
BLI_snprintf(ext, sizeof(ext), "_%02u"PTCACHE_EXT, pid->stack_index);
while ((de = readdir(dir)) != NULL) {
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 3d61b0bdefb..3bf5c4cc47e 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -62,8 +62,6 @@
#include "BKE_pointcache.h"
#include "BKE_rigidbody.h"
-#include "RNA_access.h"
-
#ifdef WITH_BULLET
/* ************************************** */
@@ -401,7 +399,7 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
height = size[2];
}
else if (rbo->shape == RB_SHAPE_SPHERE) {
- /* take radius to the the largest dimension to try and encompass everything */
+ /* take radius to the largest dimension to try and encompass everything */
radius = MAX3(size[0], size[1], size[2]);
}
@@ -483,7 +481,7 @@ void BKE_rigidbody_calc_volume(Object *ob, float *r_vol)
height = size[2];
}
else if (rbo->shape == RB_SHAPE_SPHERE) {
- /* take radius to the the largest dimension to try and encompass everything */
+ /* take radius to the largest dimension to try and encompass everything */
radius = max_fff(size[0], size[1], size[2]) * 0.5f;
}
@@ -1158,7 +1156,7 @@ static void rigidbody_update_ob_array(RigidBodyWorld *rbw)
GroupObject *go;
int i, n;
- n = BLI_countlist(&rbw->group->gobject);
+ n = BLI_listbase_count(&rbw->group->gobject);
if (rbw->numbodies != n) {
rbw->numbodies = n;
@@ -1499,7 +1497,7 @@ void BKE_rigidbody_rebuild_world(Scene *scene, float ctime)
cache = rbw->pointcache;
/* flag cache as outdated if we don't have a world or number of objects in the simulation has changed */
- if (rbw->physics_world == NULL || rbw->numbodies != BLI_countlist(&rbw->group->gobject)) {
+ if (rbw->physics_world == NULL || rbw->numbodies != BLI_listbase_count(&rbw->group->gobject)) {
cache->flag |= PTCACHE_OUTDATED;
}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 5bfd6e8a120..13e9b7fb0c4 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -63,12 +63,14 @@
#include "BKE_anim.h"
#include "BKE_animsys.h"
#include "BKE_action.h"
+#include "BKE_armature.h"
#include "BKE_colortools.h"
#include "BKE_depsgraph.h"
#include "BKE_editmesh.h"
#include "BKE_fcurve.h"
#include "BKE_freestyle.h"
#include "BKE_global.h"
+#include "BKE_gpencil.h"
#include "BKE_group.h"
#include "BKE_idprop.h"
#include "BKE_image.h"
@@ -98,6 +100,10 @@
# include <sys/time.h>
#endif
+const char *RE_engine_id_BLENDER_RENDER = "BLENDER_RENDER";
+const char *RE_engine_id_BLENDER_GAME = "BLENDER_GAME";
+const char *RE_engine_id_CYCLES = "CYCLES";
+
void free_avicodecdata(AviCodecData *acd)
{
if (acd) {
@@ -303,6 +309,19 @@ Scene *BKE_scene_copy(Scene *sce, int type)
BKE_sequence_base_dupli_recursive(sce, scen, &scen->ed->seqbase, &sce->ed->seqbase, SEQ_DUPE_ALL);
}
}
+
+ /* grease pencil */
+ if (scen->gpd) {
+ if (type == SCE_COPY_FULL) {
+ scen->gpd = gpencil_data_duplicate(scen->gpd, false);
+ }
+ else if (type == SCE_COPY_EMPTY) {
+ scen->gpd = NULL;
+ }
+ else {
+ id_us_plus((ID *)scen->gpd);
+ }
+ }
return scen;
}
@@ -595,7 +614,7 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
sce->r.ffcodecdata.audio_bitrate = 192;
sce->r.ffcodecdata.audio_channels = 2;
- BLI_strncpy(sce->r.engine, "BLENDER_RENDER", sizeof(sce->r.engine));
+ BLI_strncpy(sce->r.engine, RE_engine_id_BLENDER_RENDER, sizeof(sce->r.engine));
sce->audio.distance_model = 2.0f;
sce->audio.doppler_factor = 1.0f;
@@ -1092,27 +1111,24 @@ void BKE_scene_base_select(Scene *sce, Base *selbase)
}
/* checks for cycle, returns 1 if it's all OK */
-int BKE_scene_validate_setscene(Main *bmain, Scene *sce)
+bool BKE_scene_validate_setscene(Main *bmain, Scene *sce)
{
- Scene *scene;
+ Scene *sce_iter;
int a, totscene;
+
+ if (sce->set == NULL) return true;
+ totscene = BLI_listbase_count(&bmain->scene);
- if (sce->set == NULL) return 1;
-
- totscene = 0;
- for (scene = bmain->scene.first; scene; scene = scene->id.next)
- totscene++;
-
- for (a = 0, scene = sce; scene->set; scene = scene->set, a++) {
+ for (a = 0, sce_iter = sce; sce_iter->set; sce_iter = sce_iter->set, a++) {
/* more iterations than scenes means we have a cycle */
if (a > totscene) {
/* the tested scene gets zero'ed, that's typically current scene */
sce->set = NULL;
- return 0;
+ return false;
}
}
- return 1;
+ return true;
}
/* This function is needed to cope with fractional frames - including two Blender rendering features
@@ -1242,8 +1258,35 @@ static void scene_depsgraph_hack(EvaluationContext *eval_ctx, Scene *scene, Scen
}
}
}
+}
+/* That's like really a bummer, because currently animation data for armatures
+ * might want to use pose, and pose might be missing on the object.
+ * This happens when changing visible layers, which leads to situations when
+ * pose is missing or marked for recalc, animation will change it and then
+ * object update will restore the pose.
+ *
+ * This could be solved by the new dependency graph, but for until then we'll
+ * do an extra pass on the objects to ensure it's all fine.
+ */
+#define POSE_ANIMATION_WORKAROUND
+
+#ifdef POSE_ANIMATION_WORKAROUND
+static void scene_armature_depsgraph_workaround(Main *bmain)
+{
+ Object *ob;
+ if (BLI_listbase_is_empty(&bmain->armature) || !DAG_id_type_tagged(bmain, ID_OB)) {
+ return;
+ }
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
+ if (ob->type == OB_ARMATURE && ob->adt && ob->adt->recalc & ADT_RECALC_ANIM) {
+ if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC)) {
+ BKE_pose_rebuild(ob, ob->data);
+ }
+ }
+ }
}
+#endif
static void scene_rebuild_rbw_recursive(Scene *scene, float ctime)
{
@@ -1736,6 +1779,10 @@ void BKE_scene_update_for_newframe_ex(EvaluationContext *eval_ctx, Main *bmain,
BKE_mask_evaluate_all_masks(bmain, ctime, true);
+#ifdef POSE_ANIMATION_WORKAROUND
+ scene_armature_depsgraph_workaround(bmain);
+#endif
+
/* All 'standard' (i.e. without any dependencies) animation is handled here,
* with an 'local' to 'macro' order of evaluation. This should ensure that
* settings stored nestled within a hierarchy (i.e. settings in a Texture block
@@ -1805,13 +1852,13 @@ bool BKE_scene_remove_render_layer(Main *bmain, Scene *scene, SceneRenderLayer *
Scene *sce;
if (act == -1) {
- return 0;
+ return false;
}
else if ( (scene->r.layers.first == scene->r.layers.last) &&
(scene->r.layers.first == srl))
{
/* ensure 1 layer is kept */
- return 0;
+ return false;
}
BLI_remlink(&scene->r.layers, srl);
@@ -1833,7 +1880,7 @@ bool BKE_scene_remove_render_layer(Main *bmain, Scene *scene, SceneRenderLayer *
}
}
- return 1;
+ return true;
}
/* render simplification */
@@ -1902,9 +1949,13 @@ bool BKE_scene_use_new_shading_nodes(Scene *scene)
bool BKE_scene_uses_blender_internal(struct Scene *scene)
{
- return strcmp("BLENDER_RENDER", scene->r.engine) == 0;
+ return STREQ(scene->r.engine, RE_engine_id_BLENDER_RENDER);
}
+bool BKE_scene_uses_blender_game(struct Scene *scene)
+{
+ return STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME);
+}
void BKE_scene_base_flag_to_objects(struct Scene *scene)
{
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index c9647b05ce7..ddc0d5874f8 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -257,26 +257,15 @@ Editing *BKE_sequencer_editing_get(Scene *scene, bool alloc)
return scene->ed;
}
-static void seq_free_clipboard_recursive(Sequence *seq_parent)
-{
- Sequence *seq, *nseq;
-
- for (seq = seq_parent->seqbase.first; seq; seq = nseq) {
- nseq = seq->next;
- seq_free_clipboard_recursive(seq);
- }
-
- BKE_sequence_clipboard_pointers_free(seq_parent);
- BKE_sequence_free_ex(NULL, seq_parent, false);
-}
-
void BKE_sequencer_free_clipboard(void)
{
Sequence *seq, *nseq;
+ BKE_sequencer_base_clipboard_pointers_free(&seqbase_clipboard);
+
for (seq = seqbase_clipboard.first; seq; seq = nseq) {
nseq = seq->next;
- seq_free_clipboard_recursive(seq);
+ seq_free_sequence_recurse(NULL, seq);
}
BLI_listbase_clear(&seqbase_clipboard);
}
@@ -373,6 +362,33 @@ void BKE_sequence_clipboard_pointers_restore(Sequence *seq, Main *bmain)
seqclipboard_ptr_restore(bmain, (ID **)&seq->mask);
seqclipboard_ptr_restore(bmain, (ID **)&seq->sound);
}
+
+/* recursive versions of funcions above */
+void BKE_sequencer_base_clipboard_pointers_free(ListBase *seqbase)
+{
+ Sequence *seq;
+ for (seq = seqbase->first; seq; seq = seq->next) {
+ BKE_sequence_clipboard_pointers_free(seq);
+ BKE_sequencer_base_clipboard_pointers_free(&seq->seqbase);
+ }
+}
+void BKE_sequencer_base_clipboard_pointers_store(ListBase *seqbase)
+{
+ Sequence *seq;
+ for (seq = seqbase->first; seq; seq = seq->next) {
+ BKE_sequence_clipboard_pointers_store(seq);
+ BKE_sequencer_base_clipboard_pointers_store(&seq->seqbase);
+ }
+}
+void BKE_sequencer_base_clipboard_pointers_restore(ListBase *seqbase, Main *bmain)
+{
+ Sequence *seq;
+ for (seq = seqbase->first; seq; seq = seq->next) {
+ BKE_sequence_clipboard_pointers_restore(seq, bmain);
+ BKE_sequencer_base_clipboard_pointers_restore(&seq->seqbase, bmain);
+ }
+}
+
/* end clipboard pointer mess */
@@ -876,7 +892,6 @@ void BKE_sequencer_sort(Scene *scene)
Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq, *seqt;
-
if (ed == NULL)
return;
@@ -1474,20 +1489,25 @@ static void seq_proxy_build_frame(const SeqRenderData *context, Sequence *seq, i
int quality;
int rectx, recty;
int ok;
- ImBuf *ibuf;
+ ImBuf *ibuf_tmp, *ibuf;
if (!seq_proxy_get_fname(seq, cfra, proxy_render_size, name)) {
return;
}
- ibuf = seq_render_strip(context, seq, cfra);
+ ibuf_tmp = seq_render_strip(context, seq, cfra);
- rectx = (proxy_render_size * ibuf->x) / 100;
- recty = (proxy_render_size * ibuf->y) / 100;
+ rectx = (proxy_render_size * ibuf_tmp->x) / 100;
+ recty = (proxy_render_size * ibuf_tmp->y) / 100;
- if (ibuf->x != rectx || ibuf->y != recty) {
+ if (ibuf_tmp->x != rectx || ibuf_tmp->y != recty) {
+ ibuf = IMB_dupImBuf(ibuf_tmp);
+ IMB_freeImBuf(ibuf_tmp);
IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty);
}
+ else {
+ ibuf = ibuf_tmp;
+ }
/* depth = 32 is intentionally left in, otherwise ALPHA channels
* won't work... */
@@ -2509,6 +2529,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
int do_seq;
// bool have_seq = false; /* UNUSED */
bool have_comp = false;
+ bool use_gpencil = true;
Scene *scene;
int is_thread_main = BLI_thread_is_main();
@@ -2533,6 +2554,10 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
BKE_scene_camera_switch_update(scene);
camera = scene->camera;
}
+
+ if (seq->flag & SEQ_SCENE_NO_GPENCIL) {
+ use_gpencil = false;
+ }
if (have_comp == false && camera == NULL) {
scene->r.cfra = oldcfra;
@@ -2566,7 +2591,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
ibuf = sequencer_view3d_cb(scene, camera, width, height, IB_rect,
context->scene->r.seq_prev_type,
(context->scene->r.seq_flag & R_SEQ_SOLID_TEX) != 0,
- true, scene->r.alphamode, err_out);
+ use_gpencil, true, scene->r.alphamode, err_out);
if (ibuf == NULL) {
fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out);
}
@@ -3080,7 +3105,7 @@ ImBuf *BKE_sequencer_give_ibuf(const SeqRenderData *context, float cfra, int cha
if (ed == NULL) return NULL;
if ((chanshown < 0) && !BLI_listbase_is_empty(&ed->metastack)) {
- int count = BLI_countlist(&ed->metastack);
+ int count = BLI_listbase_count(&ed->metastack);
count = max_ii(count + chanshown, 0);
seqbasep = ((MetaStack *)BLI_findlink(&ed->metastack, count))->oldbasep;
}
@@ -3395,7 +3420,7 @@ static bool update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *cha
/* recurs downwards to see if this seq depends on the changed seq */
if (seq == NULL)
- return 0;
+ return false;
if (seq == changed_seq)
free_imbuf = true;
@@ -3513,28 +3538,16 @@ bool BKE_sequence_single_check(Sequence *seq)
}
/* check if the selected seq's reference unselected seq's */
-bool BKE_sequence_base_isolated_sel_check(ListBase *seqbase, bool one_only)
+bool BKE_sequence_base_isolated_sel_check(ListBase *seqbase)
{
Sequence *seq;
- /* is there a valid selection select */
+ /* is there more than 1 select */
bool ok = false;
- /* is there one selected already? */
- bool first = false;
for (seq = seqbase->first; seq; seq = seq->next) {
if (seq->flag & SELECT) {
- if (one_only) {
- ok = true;
- break;
- }
- else {
- if (first) {
- ok = true;
- break;
- }
- else
- first = true;
- }
+ ok = true;
+ break;
}
}
@@ -4616,11 +4629,15 @@ Sequence *BKE_sequence_dupli_recursive(Scene *scene, Scene *scene_to, Sequence *
return seqn;
}
-void BKE_sequence_base_dupli_recursive(Scene *scene, Scene *scene_to, ListBase *nseqbase, ListBase *seqbase, int dupe_flag)
+void BKE_sequence_base_dupli_recursive(
+ Scene *scene, Scene *scene_to, ListBase *nseqbase, ListBase *seqbase,
+ int dupe_flag)
{
Sequence *seq;
Sequence *seqn = NULL;
Sequence *last_seq = BKE_sequencer_active_get(scene);
+ /* always include meta's strips */
+ int dupe_flag_recursive = dupe_flag | SEQ_DUPE_ALL;
for (seq = seqbase->first; seq; seq = seq->next) {
seq->tmp = NULL;
@@ -4633,8 +4650,11 @@ void BKE_sequence_base_dupli_recursive(Scene *scene, Scene *scene_to, ListBase *
}
BLI_addtail(nseqbase, seqn);
- if (seq->type == SEQ_TYPE_META)
- BKE_sequence_base_dupli_recursive(scene, scene_to, &seqn->seqbase, &seq->seqbase, dupe_flag);
+ if (seq->type == SEQ_TYPE_META) {
+ BKE_sequence_base_dupli_recursive(
+ scene, scene_to, &seqn->seqbase, &seq->seqbase,
+ dupe_flag_recursive);
+ }
if (dupe_flag & SEQ_DUPE_CONTEXT) {
if (seq == last_seq) {
@@ -4664,3 +4684,70 @@ bool BKE_sequence_is_valid_check(Sequence *seq)
return true;
}
+int BKE_sequencer_find_next_prev_edit(
+ Scene *scene, int cfra, const short side,
+ const bool do_skip_mute, const bool do_center, const bool do_unselected)
+{
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
+ Sequence *seq;
+
+ int dist, best_dist, best_frame = cfra;
+ int seq_frames[2], seq_frames_tot;
+
+ /* in case where both is passed, frame just finds the nearest end while frame_left the nearest start */
+
+ best_dist = MAXFRAME * 2;
+
+ if (ed == NULL) return cfra;
+
+ for (seq = ed->seqbasep->first; seq; seq = seq->next) {
+ int i;
+
+ if (do_skip_mute && (seq->flag & SEQ_MUTE)) {
+ continue;
+ }
+
+ if (do_unselected && (seq->flag & SELECT))
+ continue;
+
+ if (do_center) {
+ seq_frames[0] = (seq->startdisp + seq->enddisp) / 2;
+ seq_frames_tot = 1;
+ }
+ else {
+ seq_frames[0] = seq->startdisp;
+ seq_frames[1] = seq->enddisp;
+
+ seq_frames_tot = 2;
+ }
+
+ for (i = 0; i < seq_frames_tot; i++) {
+ const int seq_frame = seq_frames[i];
+
+ dist = MAXFRAME * 2;
+
+ switch (side) {
+ case SEQ_SIDE_LEFT:
+ if (seq_frame < cfra) {
+ dist = cfra - seq_frame;
+ }
+ break;
+ case SEQ_SIDE_RIGHT:
+ if (seq_frame > cfra) {
+ dist = seq_frame - cfra;
+ }
+ break;
+ case SEQ_SIDE_BOTH:
+ dist = abs(seq_frame - cfra);
+ break;
+ }
+
+ if (dist < best_dist) {
+ best_frame = seq_frame;
+ best_dist = dist;
+ }
+ }
+ }
+
+ return best_frame;
+}
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index d2a4d15a2c6..d91818615f3 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -52,7 +52,6 @@
#include "BKE_deform.h"
#include "BKE_mesh.h" /* for OMP limits. */
#include "BKE_subsurf.h"
-#include "BKE_editmesh.h"
#include "BLI_strict_flags.h"
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 90ac712e55a..4c46875bd48 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -60,6 +60,7 @@
#include "DNA_scene_types.h"
#include "DNA_smoke_types.h"
+#include "BKE_appdir.h"
#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_bvhutils.h"
@@ -205,7 +206,7 @@ void smoke_reallocate_highres_fluid(SmokeDomainSettings *sds, float dx, int res[
/* smoke_turbulence_init uses non-threadsafe functions from fftw3 lib (like fftw_plan & co). */
BLI_lock_thread(LOCK_FFTW);
- sds->wt = smoke_turbulence_init(res, sds->amplify + 1, sds->noise, BLI_temp_dir_session(), use_fire, use_colors);
+ sds->wt = smoke_turbulence_init(res, sds->amplify + 1, sds->noise, BKE_tempdir_session(), use_fire, use_colors);
BLI_unlock_thread(LOCK_FFTW);
@@ -953,7 +954,7 @@ static bool subframe_updateObject(Scene *scene, Object *ob, int update_mesh, int
/* if other is dynamic paint canvas, don't update */
if (smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN))
- return 1;
+ return true;
/* if object has parents, update them too */
if (parent_recursion) {
@@ -965,7 +966,7 @@ static bool subframe_updateObject(Scene *scene, Object *ob, int update_mesh, int
/* skip subframe if object is parented
* to vertex of a dynamic paint canvas */
if (is_domain && (ob->partype == PARVERT1 || ob->partype == PARVERT3))
- return 0;
+ return false;
/* also update constraint targets */
for (con = ob->constraints.first; con; con = con->next) {
@@ -1011,7 +1012,7 @@ static bool subframe_updateObject(Scene *scene, Object *ob, int update_mesh, int
BKE_pose_where_is(scene, ob);
}
- return 0;
+ return false;
}
/**********************************************************
@@ -1424,7 +1425,7 @@ static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, Smoke
static void sample_derivedmesh(
SmokeFlowSettings *sfs, MVert *mvert, MTFace *tface, MFace *mface,
- float *influence_map, float *velocity_map, int index, int base_res[3], float flow_center[3],
+ float *influence_map, float *velocity_map, int index, const int base_res[3], float flow_center[3],
BVHTreeFromMesh *treeData, const float ray_start[3], const float *vert_vel,
bool has_velocity, int defgrp_index, MDeformVert *dvert, float x, float y, float z)
{
@@ -2020,7 +2021,7 @@ BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value
if (fuel && fuel[index] > FLT_EPSILON) {
/* instead of using 1.0 for all new fuel add slight falloff
* to reduce flow blockiness */
- float value = 1.0f - powf(1.0f - emission_value, 2.0f);
+ float value = 1.0f - pow2f(1.0f - emission_value);
if (value > react[index]) {
float f = fuel_flow / fuel[index];
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 13575560669..941344cf21e 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -3349,7 +3349,7 @@ static void mesh_to_softbody(Scene *scene, Object *ob)
build_bps_springlist(ob); /* scan for springs attached to bodypoints ONCE */
/* insert *other second order* springs if desired */
if (sb->secondspring > 0.0000001f) {
- add_2nd_order_springs(ob, sb->secondspring); /* exploits the the first run of build_bps_springlist(ob);*/
+ add_2nd_order_springs(ob, sb->secondspring); /* exploits the first run of build_bps_springlist(ob);*/
build_bps_springlist(ob); /* yes we need to do it again*/
}
springs_from_mesh(ob); /* write the 'rest'-length of the springs */
@@ -3561,7 +3561,7 @@ static void curve_surf_to_softbody(Scene *scene, Object *ob)
if (ob->softflag & OB_SB_EDGES) {
if (ob->type==OB_CURVE) {
- totspring= totvert - BLI_countlist(&cu->nurb);
+ totspring = totvert - BLI_listbase_count(&cu->nurb);
}
}
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index da6ead06d98..3c7b01f9052 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -36,6 +36,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
+#include "BLI_threads.h"
#include "DNA_anim_types.h"
#include "DNA_object_types.h"
@@ -116,6 +117,12 @@ void BKE_sound_free(bSound *sound)
}
sound_free_waveform(sound);
+
+ if (sound->mutex) {
+ BLI_mutex_free(sound->mutex);
+ sound->mutex = NULL;
+ }
+
#endif /* WITH_AUDASPACE */
}
@@ -296,12 +303,6 @@ void sound_cache(bSound *sound)
sound->playback_handle = sound->handle;
}
-void sound_cache_notifying(struct Main *main, bSound *sound)
-{
- sound_cache(sound);
- sound_update_sequencer(main, sound);
-}
-
void sound_delete_cache(bSound *sound)
{
sound->flags &= ~SOUND_FLAGS_CACHING;
@@ -680,22 +681,40 @@ void sound_free_waveform(bSound *sound)
sound->waveform = NULL;
}
-void sound_read_waveform(bSound *sound)
+void sound_read_waveform(bSound *sound, bool locked, short *stop)
{
AUD_SoundInfo info;
-
+ SoundWaveform *waveform = NULL;
+
info = AUD_getInfo(sound->playback_handle);
-
+
if (info.length > 0) {
- SoundWaveform *waveform = MEM_mallocN(sizeof(SoundWaveform), "SoundWaveform");
int length = info.length * SOUND_WAVE_SAMPLES_PER_SECOND;
-
+
+ waveform = MEM_mallocN(sizeof(SoundWaveform), "SoundWaveform");
waveform->data = MEM_mallocN(length * sizeof(float) * 3, "SoundWaveform.samples");
- waveform->length = AUD_readSound(sound->playback_handle, waveform->data, length, SOUND_WAVE_SAMPLES_PER_SECOND);
-
+ waveform->length = AUD_readSound(sound->playback_handle, waveform->data, length, SOUND_WAVE_SAMPLES_PER_SECOND, stop);
+
+ if (*stop) {
+ MEM_freeN(waveform->data);
+ MEM_freeN(waveform);
+ if (locked)
+ BLI_mutex_lock(sound->mutex);
+ sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING;
+ if (locked)
+ BLI_mutex_unlock(sound->mutex);
+ return;
+ }
+
sound_free_waveform(sound);
- sound->waveform = waveform;
}
+
+ if (locked)
+ BLI_mutex_lock(sound->mutex);
+ sound->waveform = waveform;
+ sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING;
+ if (locked)
+ BLI_mutex_unlock(sound->mutex);
}
void sound_update_scene(Main *bmain, struct Scene *scene)
@@ -830,7 +849,7 @@ void sound_stop_scene(struct Scene *UNUSED(scene)) {}
void sound_seek_scene(struct Main *UNUSED(bmain), struct Scene *UNUSED(scene)) {}
float sound_sync_scene(struct Scene *UNUSED(scene)) { return NAN_FLT; }
int sound_scene_playing(struct Scene *UNUSED(scene)) { return -1; }
-void sound_read_waveform(struct bSound *UNUSED(sound)) {}
+void sound_read_waveform(struct bSound *sound, bool locked, short *stop) { UNUSED_VARS(sound, locked, stop); }
void sound_init_main(struct Main *UNUSED(bmain)) {}
void sound_set_cfra(int UNUSED(cfra)) {}
void sound_update_sequencer(struct Main *UNUSED(main), struct bSound *UNUSED(sound)) {}
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 0bd9517dcfd..c777fcd5e7b 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -41,7 +41,6 @@
#include "MEM_guardedalloc.h"
-#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -66,8 +65,6 @@
#include "BKE_scene.h"
#include "BKE_subsurf.h"
-#include "PIL_time.h"
-
#ifndef USE_DYNSIZE
# include "BLI_array.h"
#endif
@@ -75,7 +72,6 @@
#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_glew.h"
-#include "GPU_material.h"
#include "CCGSubSurf.h"
@@ -411,7 +407,7 @@ static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result,
CCGFace **faceMap;
MTFace *tf;
MLoopUV *mluv;
- CCGFaceIterator *fi;
+ CCGFaceIterator fi;
int index, gridSize, gridFaces, /*edgeSize,*/ totface, x, y, S;
MLoopUV *dmloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, n);
/* need to update both CD_MTFACE & CD_MLOOPUV, hrmf, we could get away with
@@ -438,11 +434,10 @@ static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result,
/* make a map from original faces to CCGFaces */
faceMap = MEM_mallocN(totface * sizeof(*faceMap), "facemapuv");
- for (fi = ccgSubSurf_getFaceIterator(uvss); !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(fi);
+ for (ccgSubSurf_initFaceIterator(uvss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
+ CCGFace *f = ccgFaceIterator_getCurrent(&fi);
faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f))] = f;
}
- ccgFaceIterator_free(fi);
/* load coordinates from uvss into tface */
tf = tface;
@@ -699,9 +694,9 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3])
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
CCGSubSurf *ss = ccgdm->ss;
- CCGVertIterator *vi;
- CCGEdgeIterator *ei;
- CCGFaceIterator *fi;
+ CCGVertIterator vi;
+ CCGEdgeIterator ei;
+ CCGFaceIterator fi;
CCGKey key;
int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
int gridSize = ccgSubSurf_getGridSize(ss);
@@ -711,25 +706,23 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3])
if (!ccgSubSurf_getNumVerts(ss))
r_min[0] = r_min[1] = r_min[2] = r_max[0] = r_max[1] = r_max[2] = 0.0;
- for (vi = ccgSubSurf_getVertIterator(ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
- CCGVert *v = ccgVertIterator_getCurrent(vi);
+ for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
+ CCGVert *v = ccgVertIterator_getCurrent(&vi);
float *co = ccgSubSurf_getVertData(ss, v);
minmax_v3_v3v3(co, r_min, r_max);
}
- ccgVertIterator_free(vi);
- for (ei = ccgSubSurf_getEdgeIterator(ss); !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
- CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
+ for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
+ CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
for (i = 0; i < edgeSize; i++)
minmax_v3_v3v3(CCG_elem_offset_co(&key, edgeData, i), r_min, r_max);
}
- ccgEdgeIterator_free(ei);
- for (fi = ccgSubSurf_getFaceIterator(ss); !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(fi);
+ for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
+ CCGFace *f = ccgFaceIterator_getCurrent(&fi);
int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
for (S = 0; S < numVerts; S++) {
@@ -740,7 +733,6 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3])
minmax_v3_v3v3(CCG_grid_elem_co(&key, faceGridData, x, y), r_min, r_max);
}
}
- ccgFaceIterator_free(fi);
}
static int ccgDM_getNumVerts(DerivedMesh *dm)
@@ -1433,9 +1425,9 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3])
int edgeSize = ccgSubSurf_getEdgeSize(ss);
int gridSize = ccgSubSurf_getGridSize(ss);
int i;
- CCGVertIterator *vi;
- CCGEdgeIterator *ei;
- CCGFaceIterator *fi;
+ CCGVertIterator vi;
+ CCGEdgeIterator ei;
+ CCGFaceIterator fi;
CCGFace **faceMap2;
CCGEdge **edgeMap2;
CCGVert **vertMap2;
@@ -1443,30 +1435,27 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3])
totvert = ccgSubSurf_getNumVerts(ss);
vertMap2 = MEM_mallocN(totvert * sizeof(*vertMap2), "vertmap");
- for (vi = ccgSubSurf_getVertIterator(ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
- CCGVert *v = ccgVertIterator_getCurrent(vi);
+ for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
+ CCGVert *v = ccgVertIterator_getCurrent(&vi);
vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))] = v;
}
- ccgVertIterator_free(vi);
totedge = ccgSubSurf_getNumEdges(ss);
edgeMap2 = MEM_mallocN(totedge * sizeof(*edgeMap2), "edgemap");
- for (ei = ccgSubSurf_getEdgeIterator(ss), i = 0; !ccgEdgeIterator_isStopped(ei); i++, ccgEdgeIterator_next(ei)) {
- CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
+ for (ccgSubSurf_initEdgeIterator(ss, &ei), i = 0; !ccgEdgeIterator_isStopped(&ei); i++, ccgEdgeIterator_next(&ei)) {
+ CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))] = e;
}
- ccgEdgeIterator_free(ei);
totface = ccgSubSurf_getNumFaces(ss);
faceMap2 = MEM_mallocN(totface * sizeof(*faceMap2), "facemap");
- for (fi = ccgSubSurf_getFaceIterator(ss); !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(fi);
+ for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
+ CCGFace *f = ccgFaceIterator_getCurrent(&fi);
faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f))] = f;
}
- ccgFaceIterator_free(fi);
i = 0;
for (index = 0; index < totface; index++) {
@@ -1516,12 +1505,12 @@ static void ccgDM_foreachMappedVert(
DMForeachFlag flag)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
- CCGVertIterator *vi;
+ CCGVertIterator vi;
CCGKey key;
CCG_key_top_level(&key, ccgdm->ss);
- for (vi = ccgSubSurf_getVertIterator(ccgdm->ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
- CCGVert *v = ccgVertIterator_getCurrent(vi);
+ for (ccgSubSurf_initVertIterator(ccgdm->ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
+ CCGVert *v = ccgVertIterator_getCurrent(&vi);
const int index = ccgDM_getVertMapIndex(ccgdm->ss, v);
if (index != -1) {
@@ -1530,8 +1519,6 @@ static void ccgDM_foreachMappedVert(
func(userData, index, CCG_elem_co(&key, vd), no, NULL);
}
}
-
- ccgVertIterator_free(vi);
}
static void ccgDM_foreachMappedEdge(
@@ -1541,14 +1528,14 @@ static void ccgDM_foreachMappedEdge(
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
CCGSubSurf *ss = ccgdm->ss;
- CCGEdgeIterator *ei;
+ CCGEdgeIterator ei;
CCGKey key;
int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
CCG_key_top_level(&key, ss);
- for (ei = ccgSubSurf_getEdgeIterator(ss); !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
- CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
+ for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
+ CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
const int index = ccgDM_getEdgeMapIndex(ss, e);
if (index != -1) {
@@ -1558,8 +1545,6 @@ static void ccgDM_foreachMappedEdge(
}
}
}
-
- ccgEdgeIterator_free(ei);
}
static void ccgDM_foreachMappedLoop(
@@ -1597,28 +1582,26 @@ static void ccgDM_drawVerts(DerivedMesh *dm)
CCGSubSurf *ss = ccgdm->ss;
int edgeSize = ccgSubSurf_getEdgeSize(ss);
int gridSize = ccgSubSurf_getGridSize(ss);
- CCGVertIterator *vi;
- CCGEdgeIterator *ei;
- CCGFaceIterator *fi;
+ CCGVertIterator vi;
+ CCGEdgeIterator ei;
+ CCGFaceIterator fi;
glBegin(GL_POINTS);
- for (vi = ccgSubSurf_getVertIterator(ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
- CCGVert *v = ccgVertIterator_getCurrent(vi);
+ for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
+ CCGVert *v = ccgVertIterator_getCurrent(&vi);
glVertex3fv(ccgSubSurf_getVertData(ss, v));
}
- ccgVertIterator_free(vi);
- for (ei = ccgSubSurf_getEdgeIterator(ss); !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
- CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
+ for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
+ CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
int x;
for (x = 1; x < edgeSize - 1; x++)
glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x));
}
- ccgEdgeIterator_free(ei);
- for (fi = ccgSubSurf_getFaceIterator(ss); !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(fi);
+ for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
+ CCGFace *f = ccgFaceIterator_getCurrent(&fi);
int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
glVertex3fv(ccgSubSurf_getFaceCenterData(f));
@@ -1630,7 +1613,6 @@ static void ccgDM_drawVerts(DerivedMesh *dm)
for (x = 1; x < gridSize - 1; x++)
glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y));
}
- ccgFaceIterator_free(fi);
glEnd();
}
@@ -2289,7 +2271,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
DMSetDrawOptionsTex drawParams,
- DMSetDrawOptions drawParamsMapped,
+ DMSetDrawOptionsMappedTex drawParamsMapped,
DMCompareDrawOptions compareDrawOptions,
void *userData, DMDrawFlag flag)
{
@@ -2352,15 +2334,16 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
mat_nr_cache = mat_nr;
}
- tf = tf_base + gridOffset;
- tf_stencil = tf_stencil_base + gridOffset;
+
+ tf = tf_base ? tf_base + gridOffset : NULL;
+ tf_stencil = tf_stencil_base ? tf_stencil_base + gridOffset : NULL;
gridOffset += gridFaces * gridFaces * numVerts;
}
if (drawParams)
draw_option = drawParams(tf, (mcol != NULL), mat_nr);
else if (index != ORIGINDEX_NONE)
- draw_option = (drawParamsMapped) ? drawParamsMapped(userData, index) : DM_DRAW_OPTION_NORMAL;
+ draw_option = (drawParamsMapped) ? drawParamsMapped(userData, index, mat_nr) : DM_DRAW_OPTION_NORMAL;
else
draw_option = GPU_enable_material(mat_nr, NULL) ? DM_DRAW_OPTION_NORMAL : DM_DRAW_OPTION_SKIP;
@@ -2529,7 +2512,7 @@ static void ccgDM_drawFacesTex(DerivedMesh *dm,
}
static void ccgDM_drawMappedFacesTex(DerivedMesh *dm,
- DMSetDrawOptions setDrawOptions,
+ DMSetDrawOptionsMappedTex setDrawOptions,
DMCompareDrawOptions compareDrawOptions,
void *userData, DMDrawFlag flag)
{
@@ -2585,6 +2568,7 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
DMFlagMat *faceFlags = ccgdm->faceFlags;
int useColors = flag & DM_DRAW_USE_COLORS;
int gridFaces = gridSize - 1, totface;
+ int prev_mat_nr = -1;
CCG_key_top_level(&key, ss);
@@ -2625,9 +2609,16 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
{
DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
- if (index == ORIGINDEX_NONE)
- draw_option = setMaterial(faceFlags ? faceFlags[origIndex].mat_nr + 1 : 1, NULL); /* XXX, no faceFlags no material */
- else if (setDrawOptions)
+ if (setMaterial) {
+ int mat_nr = faceFlags ? faceFlags[origIndex].mat_nr + 1 : 1;
+
+ if (mat_nr != prev_mat_nr) {
+ setMaterial(mat_nr, NULL); /* XXX, no faceFlags no material */
+ prev_mat_nr = mat_nr;
+ }
+ }
+
+ if (setDrawOptions && (index != ORIGINDEX_NONE))
draw_option = setDrawOptions(userData, index);
if (draw_option != DM_DRAW_OPTION_SKIP) {
@@ -2744,15 +2735,15 @@ static void ccgDM_drawMappedEdges(DerivedMesh *dm,
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
CCGSubSurf *ss = ccgdm->ss;
- CCGEdgeIterator *ei;
+ CCGEdgeIterator ei;
CCGKey key;
int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
CCG_key_top_level(&key, ss);
ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
- for (ei = ccgSubSurf_getEdgeIterator(ss); !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
- CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
+ for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
+ CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
int index = ccgDM_getEdgeMapIndex(ss, e);
@@ -2770,8 +2761,6 @@ static void ccgDM_drawMappedEdges(DerivedMesh *dm,
}
glEnd();
}
-
- ccgEdgeIterator_free(ei);
}
static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm,
@@ -2782,14 +2771,14 @@ static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm,
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
CCGSubSurf *ss = ccgdm->ss;
CCGKey key;
- CCGEdgeIterator *ei;
+ CCGEdgeIterator ei;
int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
CCG_key_top_level(&key, ss);
ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
- for (ei = ccgSubSurf_getEdgeIterator(ss); !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
- CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
+ for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
+ CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
int index = ccgDM_getEdgeMapIndex(ss, e);
@@ -2808,8 +2797,6 @@ static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm,
}
glEnd();
}
-
- ccgEdgeIterator_free(ei);
}
static void ccgDM_foreachMappedFaceCenter(
@@ -2821,12 +2808,12 @@ static void ccgDM_foreachMappedFaceCenter(
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
CCGSubSurf *ss = ccgdm->ss;
CCGKey key;
- CCGFaceIterator *fi;
+ CCGFaceIterator fi;
CCG_key_top_level(&key, ss);
- for (fi = ccgSubSurf_getFaceIterator(ss); !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(fi);
+ for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
+ CCGFace *f = ccgFaceIterator_getCurrent(&fi);
const int index = ccgDM_getFaceMapIndex(ss, f);
if (index != -1) {
@@ -2836,8 +2823,6 @@ static void ccgDM_foreachMappedFaceCenter(
func(userData, index, CCG_elem_co(&key, vd), no);
}
}
-
- ccgFaceIterator_free(fi);
}
static void ccgDM_release(DerivedMesh *dm)
@@ -3433,9 +3418,9 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
DerivedMesh *dm)
{
CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
- CCGVertIterator *vi;
- CCGEdgeIterator *ei;
- CCGFaceIterator *fi;
+ CCGVertIterator vi;
+ CCGEdgeIterator ei;
+ CCGFaceIterator fi;
int index, totvert, totedge, totface;
int i;
int vertNum, edgeNum, faceNum;
@@ -3568,30 +3553,27 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
totvert = ccgSubSurf_getNumVerts(ss);
ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
- for (vi = ccgSubSurf_getVertIterator(ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
- CCGVert *v = ccgVertIterator_getCurrent(vi);
+ for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
+ CCGVert *v = ccgVertIterator_getCurrent(&vi);
ccgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))].vert = v;
}
- ccgVertIterator_free(vi);
totedge = ccgSubSurf_getNumEdges(ss);
ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
- for (ei = ccgSubSurf_getEdgeIterator(ss); !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
- CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
+ for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
+ CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
ccgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e;
}
- ccgEdgeIterator_free(ei);
totface = ccgSubSurf_getNumFaces(ss);
ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
- for (fi = ccgSubSurf_getFaceIterator(ss); !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
- CCGFace *f = ccgFaceIterator_getCurrent(fi);
+ for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
+ CCGFace *f = ccgFaceIterator_getCurrent(&fi);
ccgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f))].face = f;
}
- ccgFaceIterator_free(fi);
ccgdm->reverseFaceMap = MEM_callocN(sizeof(int) * ccgSubSurf_getNumFinalFaces(ss), "reverseFaceMap");
@@ -3996,13 +3978,13 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3])
*/
CCGSubSurf *ss = _getSubSurf(NULL, 1, 3, CCG_USE_ARENA);
float edge_sum[3], face_sum[3];
- CCGVertIterator *vi;
+ CCGVertIterator vi;
DerivedMesh *dm = CDDM_from_mesh(me);
ss_sync_from_derivedmesh(ss, dm, NULL, 0);
- for (vi = ccgSubSurf_getVertIterator(ss); !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
- CCGVert *v = ccgVertIterator_getCurrent(vi);
+ for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
+ CCGVert *v = ccgVertIterator_getCurrent(&vi);
int idx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
int N = ccgSubSurf_getVertNumEdges(v);
int numFaces = ccgSubSurf_getVertNumFaces(v);
@@ -4031,7 +4013,6 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3])
r_positions[idx][1] = (co[1] * N * N + edge_sum[1] * 4 + face_sum[1]) / (N * (N + 5));
r_positions[idx][2] = (co[2] * N * N + edge_sum[2] * 4 + face_sum[2]) / (N * (N + 5));
}
- ccgVertIterator_free(vi);
ccgSubSurf_free(ss);
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 8a272cd9d81..77629715edb 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -369,8 +369,8 @@ int BKE_text_reload(Text *text)
buffer = MEM_mallocN(len, "text_buffer");
- // under windows fread can return less then len bytes because
- // of CR stripping
+ /* under windows fread can return less than len bytes because
+ * of CR stripping */
len = fread(buffer, 1, len, fp);
fclose(fp);
@@ -425,8 +425,8 @@ Text *BKE_text_load_ex(Main *bmain, const char *file, const char *relpath, const
fseek(fp, 0L, SEEK_SET);
buffer = MEM_mallocN(len, "text_buffer");
- // under windows fread can return less then len bytes because
- // of CR stripping
+ /* under windows fread can return less than len bytes because
+ * of CR stripping */
len = fread(buffer, 1, len, fp);
fclose(fp);
@@ -1515,7 +1515,7 @@ static bool max_undo_test(Text *text, int x)
/* XXX error("Undo limit reached, buffer cleared\n"); */
MEM_freeN(text->undo_buf);
init_undo_text(text);
- return 0;
+ return false;
}
else {
void *tmp = text->undo_buf;
@@ -1526,7 +1526,7 @@ static bool max_undo_test(Text *text, int x)
}
}
- return 1;
+ return true;
}
#if 0 /* UNUSED */
@@ -2474,6 +2474,7 @@ void txt_delete_word(Text *text)
{
txt_jump_right(text, true, true);
txt_delete_sel(text);
+ txt_make_dirty(text);
}
void txt_backspace_char(Text *text)
@@ -2522,6 +2523,7 @@ void txt_backspace_word(Text *text)
{
txt_jump_left(text, true, true);
txt_delete_sel(text);
+ txt_make_dirty(text);
}
/* Max spaces to replace a tab with, currently hardcoded to TXT_TABSIZE = 4.
@@ -2548,13 +2550,13 @@ static bool txt_add_char_intern(Text *text, unsigned int add, bool replace_tabs)
if (add == '\n') {
txt_split_curline(text);
- return 1;
+ return true;
}
/* insert spaces rather than tabs */
if (add == '\t' && replace_tabs) {
txt_convert_tab_to_spaces(text);
- return 1;
+ return true;
}
txt_delete_sel(text);
@@ -2603,7 +2605,7 @@ bool txt_replace_char(Text *text, unsigned int add)
size_t del_size = 0, add_size;
char ch[BLI_UTF8_MAX];
- if (!text->curl) return 0;
+ if (!text->curl) return false;
/* If text is selected or we're at the end of the line just use txt_add_char */
if (text->curc == text->curl->len || txt_has_sel(text) || add == '\n') {
@@ -2642,7 +2644,7 @@ bool txt_replace_char(Text *text, unsigned int add)
text->curc += add_size;
txt_pop_sel(text);
}
- return 1;
+ return true;
}
void txt_indent(Text *text)
@@ -2977,37 +2979,37 @@ bool text_check_delim(const char ch)
for (a = 0; a < (sizeof(delims) - 1); a++) {
if (ch == delims[a])
- return 1;
+ return true;
}
- return 0;
+ return false;
}
bool text_check_digit(const char ch)
{
- if (ch < '0') return 0;
- if (ch <= '9') return 1;
- return 0;
+ if (ch < '0') return false;
+ if (ch <= '9') return true;
+ return false;
}
bool text_check_identifier(const char ch)
{
- if (ch < '0') return 0;
- if (ch <= '9') return 1;
- if (ch < 'A') return 0;
- if (ch <= 'Z' || ch == '_') return 1;
- if (ch < 'a') return 0;
- if (ch <= 'z') return 1;
- return 0;
+ if (ch < '0') return false;
+ if (ch <= '9') return true;
+ if (ch < 'A') return false;
+ if (ch <= 'Z' || ch == '_') return true;
+ if (ch < 'a') return false;
+ if (ch <= 'z') return true;
+ return false;
}
bool text_check_identifier_nodigit(const char ch)
{
- if (ch <= '9') return 0;
- if (ch < 'A') return 0;
- if (ch <= 'Z' || ch == '_') return 1;
- if (ch < 'a') return 0;
- if (ch <= 'z') return 1;
- return 0;
+ if (ch <= '9') return false;
+ if (ch < 'A') return false;
+ if (ch <= 'Z' || ch == '_') return true;
+ if (ch < 'a') return false;
+ if (ch <= 'z') return true;
+ return false;
}
#ifndef WITH_PYTHON
@@ -3025,8 +3027,8 @@ int text_check_identifier_nodigit_unicode(const unsigned int ch)
bool text_check_whitespace(const char ch)
{
if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n')
- return 1;
- return 0;
+ return true;
+ return false;
}
int text_find_identifier_start(const char *str, int i)
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index f938ed08142..3c02d5c19fc 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -37,7 +37,6 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_kdopbvh.h"
#include "BLI_utildefines.h"
@@ -328,7 +327,7 @@ bool do_colorband(const ColorBand *coba, float in, float out[4])
int ipotype;
int a;
- if (coba == NULL || coba->tot == 0) return 0;
+ if (coba == NULL || coba->tot == 0) return false;
cbd1 = coba->data;
@@ -464,7 +463,7 @@ bool do_colorband(const ColorBand *coba, float in, float out[4])
}
}
}
- return 1; /* OK */
+ return true; /* OK */
}
void colorband_table_RGBA(ColorBand *coba, float **array, int *size)
@@ -1302,7 +1301,7 @@ bool has_current_material_texture(Material *ma)
node = nodeGetActiveID(ma->nodetree, ID_TE);
if (node)
- return 1;
+ return true;
}
return (ma != NULL);
@@ -1596,17 +1595,17 @@ void BKE_free_oceantex(struct OceanTex *ot)
bool BKE_texture_dependsOnTime(const struct Tex *texture)
{
if (texture->ima && BKE_image_is_animated(texture->ima)) {
- return 1;
+ return true;
}
else if (texture->adt) {
/* assume anything in adt means the texture is animated */
- return 1;
+ return true;
}
else if (texture->type == TEX_NOISE) {
/* noise always varies with time */
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/* ------------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index 40d9dc0d7e0..d580c184a8b 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -1456,6 +1456,35 @@ MovieTrackingPlaneMarker *BKE_tracking_plane_marker_ensure(MovieTrackingPlaneTra
return plane_marker;
}
+void BKE_tracking_plane_marker_get_subframe_corners(MovieTrackingPlaneTrack *plane_track,
+ float framenr,
+ float corners[4][2])
+{
+ MovieTrackingPlaneMarker *marker = BKE_tracking_plane_marker_get(plane_track, (int)framenr);
+ MovieTrackingPlaneMarker *marker_last = plane_track->markers + (plane_track->markersnr - 1);
+ int i;
+ if (marker != marker_last) {
+ MovieTrackingPlaneMarker *marker_next = marker + 1;
+ if (marker_next->framenr == marker->framenr + 1) {
+ float fac = (framenr - (int) framenr) / (marker_next->framenr - marker->framenr);
+ for (i = 0; i < 4; ++i) {
+ interp_v2_v2v2(corners[i], marker->corners[i],
+ marker_next->corners[i], fac);
+ }
+ }
+ else {
+ for (i = 0; i < 4; ++i) {
+ copy_v2_v2(corners[i], marker->corners[i]);
+ }
+ }
+ }
+ else {
+ for (i = 0; i < 4; ++i) {
+ copy_v2_v2(corners[i], marker->corners[i]);
+ }
+ }
+}
+
/*********************** Object *************************/
MovieTrackingObject *BKE_tracking_object_add(MovieTracking *tracking, const char *name)
@@ -1475,7 +1504,7 @@ MovieTrackingObject *BKE_tracking_object_add(MovieTracking *tracking, const char
BLI_addtail(&tracking->objects, object);
tracking->tot_object++;
- tracking->objectnr = BLI_countlist(&tracking->objects) - 1;
+ tracking->objectnr = BLI_listbase_count(&tracking->objects) - 1;
object->scale = 1.0f;
object->keyframe1 = 1;
@@ -2410,30 +2439,30 @@ static void tracking_dopesheet_channels_sort(MovieTracking *tracking, int sort_m
if (inverse) {
if (sort_method == TRACKING_DOPE_SORT_NAME) {
- BLI_sortlist(&dopesheet->channels, channels_alpha_inverse_sort);
+ BLI_listbase_sort(&dopesheet->channels, channels_alpha_inverse_sort);
}
else if (sort_method == TRACKING_DOPE_SORT_LONGEST) {
- BLI_sortlist(&dopesheet->channels, channels_longest_segment_inverse_sort);
+ BLI_listbase_sort(&dopesheet->channels, channels_longest_segment_inverse_sort);
}
else if (sort_method == TRACKING_DOPE_SORT_TOTAL) {
- BLI_sortlist(&dopesheet->channels, channels_total_track_inverse_sort);
+ BLI_listbase_sort(&dopesheet->channels, channels_total_track_inverse_sort);
}
else if (sort_method == TRACKING_DOPE_SORT_AVERAGE_ERROR) {
- BLI_sortlist(&dopesheet->channels, channels_average_error_inverse_sort);
+ BLI_listbase_sort(&dopesheet->channels, channels_average_error_inverse_sort);
}
}
else {
if (sort_method == TRACKING_DOPE_SORT_NAME) {
- BLI_sortlist(&dopesheet->channels, channels_alpha_sort);
+ BLI_listbase_sort(&dopesheet->channels, channels_alpha_sort);
}
else if (sort_method == TRACKING_DOPE_SORT_LONGEST) {
- BLI_sortlist(&dopesheet->channels, channels_longest_segment_sort);
+ BLI_listbase_sort(&dopesheet->channels, channels_longest_segment_sort);
}
else if (sort_method == TRACKING_DOPE_SORT_TOTAL) {
- BLI_sortlist(&dopesheet->channels, channels_total_track_sort);
+ BLI_listbase_sort(&dopesheet->channels, channels_total_track_sort);
}
else if (sort_method == TRACKING_DOPE_SORT_AVERAGE_ERROR) {
- BLI_sortlist(&dopesheet->channels, channels_average_error_sort);
+ BLI_listbase_sort(&dopesheet->channels, channels_average_error_sort);
}
}
}
diff --git a/source/blender/blenkernel/intern/tracking_auto.c b/source/blender/blenkernel/intern/tracking_auto.c
new file mode 100644
index 00000000000..22a380ea835
--- /dev/null
+++ b/source/blender/blenkernel/intern/tracking_auto.c
@@ -0,0 +1,568 @@
+/*
+ * ***** 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.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ * Keir Mierle
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/tracking_auto.c
+ * \ingroup bke
+ */
+
+#include <stdlib.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_movieclip_types.h"
+#include "DNA_object_types.h" /* SELECT */
+
+#include "BLI_threads.h"
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+
+#include "BKE_movieclip.h"
+#include "BKE_tracking.h"
+
+#include "libmv-capi.h"
+#include "tracking_private.h"
+
+typedef struct AutoTrackOptions {
+ int clip_index; /** Index of the clip this track belogs to. */
+ int track_index; /* Index of the track in AutoTrack tracks structure. */
+ MovieTrackingTrack *track; /* Pointer to an original track/ */
+ libmv_TrackRegionOptions track_region_options; /* Options for the region
+ tracker. */
+ bool use_keyframe_match; /* Keyframe pattern matching. */
+
+ /* TODO(sergey): A bit awkward to keep it in here, only used to
+ * place a disabled marker once the tracking fails,
+ * Wither find a more clear way to do it or call it track context
+ * or state, not options.
+ */
+ bool is_failed;
+ int failed_frame;
+} AutoTrackOptions;
+
+typedef struct AutoTrackContext {
+ MovieClip *clips[MAX_ACCESSOR_CLIP];
+ int num_clips;
+
+ MovieClipUser user;
+ int frame_width, frame_height;
+
+ struct libmv_AutoTrack *autotrack;
+ TrackingImageAccessor *image_accessor;
+
+ int num_tracks; /* Number of tracks being tracked. */
+ AutoTrackOptions *options; /* Per-tracking track options. */
+
+ bool backwards;
+ bool sequence;
+ int first_frame;
+ int sync_frame;
+ bool first_sync;
+ SpinLock spin_lock;
+} AutoTrackContext;
+
+static void normalized_to_libmv_frame(const float normalized[2],
+ const int frame_dimensions[2],
+ float result[2])
+{
+ result[0] = normalized[0] * frame_dimensions[0] - 0.5f;
+ result[1] = normalized[1] * frame_dimensions[1] - 0.5f;
+}
+
+static void normalized_relative_to_libmv_frame(const float normalized[2],
+ const float origin[2],
+ const int frame_dimensions[2],
+ float result[2])
+{
+ result[0] = (normalized[0] + origin[0]) * frame_dimensions[0] - 0.5f;
+ result[1] = (normalized[1] + origin[1]) * frame_dimensions[1] - 0.5f;
+}
+
+static void libmv_frame_to_normalized(const float frame_coord[2],
+ const int frame_dimensions[2],
+ float result[2])
+{
+ result[0] = (frame_coord[0] + 0.5f) / frame_dimensions[0];
+ result[1] = (frame_coord[1] + 0.5f) / frame_dimensions[1];
+}
+
+static void libmv_frame_to_normalized_relative(const float frame_coord[2],
+ const float origin[2],
+ const int frame_dimensions[2],
+ float result[2])
+{
+ result[0] = (frame_coord[0] - origin[0]) / frame_dimensions[0];
+ result[1] = (frame_coord[1] - origin[1]) / frame_dimensions[1];
+}
+
+static void dna_marker_to_libmv_marker(/*const*/ MovieTrackingTrack *track,
+ /*const*/ MovieTrackingMarker *marker,
+ int clip,
+ int track_index,
+ int frame_width,
+ int frame_height,
+ bool backwards,
+ libmv_Marker *libmv_marker)
+{
+ const int frame_dimensions[2] = {frame_width, frame_height};
+ int i;
+ libmv_marker->clip = clip;
+ libmv_marker->frame = marker->framenr;
+ libmv_marker->track = track_index;
+
+ normalized_to_libmv_frame(marker->pos,
+ frame_dimensions,
+ libmv_marker->center);
+ for (i = 0; i < 4; ++i) {
+ normalized_relative_to_libmv_frame(marker->pattern_corners[i],
+ marker->pos,
+ frame_dimensions,
+ libmv_marker->patch[i]);
+ }
+
+ normalized_relative_to_libmv_frame(marker->search_min,
+ marker->pos,
+ frame_dimensions,
+ libmv_marker->search_region_min);
+
+ normalized_relative_to_libmv_frame(marker->search_max,
+ marker->pos,
+ frame_dimensions,
+ libmv_marker->search_region_max);
+
+ /* TODO(sergey): All the markers does have 1.0 weight. */
+ libmv_marker->weight = 1.0f;
+
+ if (marker->flag & MARKER_TRACKED) {
+ libmv_marker->source = LIBMV_MARKER_SOURCE_TRACKED;
+ }
+ else {
+ libmv_marker->source = LIBMV_MARKER_SOURCE_MANUAL;
+ }
+ libmv_marker->status = LIBMV_MARKER_STATUS_UNKNOWN;
+ libmv_marker->model_type = LIBMV_MARKER_MODEL_TYPE_POINT;
+ libmv_marker->model_id = 0;
+
+ /* TODO(sergey): We currently don't support reference marker from
+ * different clip.
+ */
+ libmv_marker->reference_clip = clip;
+
+ if (track->pattern_match == TRACK_MATCH_KEYFRAME) {
+ MovieTrackingMarker *keyframe_marker =
+ tracking_get_keyframed_marker(track,
+ marker->framenr,
+ backwards);
+ libmv_marker->reference_frame = keyframe_marker->framenr;
+ }
+ else {
+ libmv_marker->reference_frame = backwards ?
+ marker->framenr - 1 :
+ marker->framenr;
+ }
+
+ libmv_marker->disabled_channels =
+ ((track->flag & TRACK_DISABLE_RED) ? LIBMV_MARKER_CHANNEL_R : 0) |
+ ((track->flag & TRACK_DISABLE_GREEN) ? LIBMV_MARKER_CHANNEL_G : 0) |
+ ((track->flag & TRACK_DISABLE_BLUE) ? LIBMV_MARKER_CHANNEL_B : 0);
+}
+
+static void libmv_marker_to_dna_marker(libmv_Marker *libmv_marker,
+ int frame_width,
+ int frame_height,
+ MovieTrackingMarker *marker)
+{
+ const int frame_dimensions[2] = {frame_width, frame_height};
+ int i;
+ marker->framenr = libmv_marker->frame;
+
+ libmv_frame_to_normalized(libmv_marker->center,
+ frame_dimensions,
+ marker->pos);
+ for (i = 0; i < 4; ++i) {
+ libmv_frame_to_normalized_relative(libmv_marker->patch[i],
+ libmv_marker->center,
+ frame_dimensions,
+ marker->pattern_corners[i]);
+ }
+
+ libmv_frame_to_normalized_relative(libmv_marker->search_region_min,
+ libmv_marker->center,
+ frame_dimensions,
+ marker->search_min);
+
+ libmv_frame_to_normalized_relative(libmv_marker->search_region_max,
+ libmv_marker->center,
+ frame_dimensions,
+ marker->search_max);
+
+ marker->flag = 0;
+ if (libmv_marker->source == LIBMV_MARKER_SOURCE_TRACKED) {
+ marker->flag |= MARKER_TRACKED;
+ }
+ else {
+ marker->flag &= ~MARKER_TRACKED;
+ }
+}
+
+static bool check_track_trackable(MovieClip *clip,
+ MovieTrackingTrack *track,
+ MovieClipUser *user)
+{
+ if (TRACK_SELECTED(track) &&
+ (track->flag & (TRACK_LOCKED | TRACK_HIDDEN)) == 0)
+ {
+ MovieTrackingMarker *marker;
+ int frame;
+ frame = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr);
+ marker = BKE_tracking_marker_get(track, frame);
+ return (marker->flag & MARKER_DISABLED) == 0;
+ }
+ return false;
+}
+
+/* Returns false if marker crossed margin area from frame bounds. */
+static bool tracking_check_marker_margin(libmv_Marker *libmv_marker,
+ int margin,
+ int frame_width,
+ int frame_height)
+{
+ float patch_min[2], patch_max[2];
+ float margin_left, margin_top, margin_right, margin_bottom;
+
+ INIT_MINMAX2(patch_min, patch_max);
+ minmax_v2v2_v2(patch_min, patch_max, libmv_marker->patch[0]);
+ minmax_v2v2_v2(patch_min, patch_max, libmv_marker->patch[1]);
+ minmax_v2v2_v2(patch_min, patch_max, libmv_marker->patch[2]);
+ minmax_v2v2_v2(patch_min, patch_max, libmv_marker->patch[3]);
+
+ margin_left = max_ff(libmv_marker->center[0] - patch_min[0], margin);
+ margin_top = max_ff(patch_max[1] - libmv_marker->center[1], margin);
+ margin_right = max_ff(patch_max[0] - libmv_marker->center[0], margin);
+ margin_bottom = max_ff(libmv_marker->center[1] - patch_min[1], margin);
+
+ if (libmv_marker->center[0] < margin_left ||
+ libmv_marker->center[0] > frame_width - margin_right ||
+ libmv_marker->center[1] < margin_bottom ||
+ libmv_marker->center[1] > frame_height - margin_top)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+AutoTrackContext *BKE_autotrack_context_new(MovieClip *clip,
+ MovieClipUser *user,
+ const bool backwards,
+ const bool sequence)
+{
+ AutoTrackContext *context = MEM_callocN(sizeof(AutoTrackContext),
+ "autotrack context");
+ MovieTracking *tracking = &clip->tracking;
+ MovieTrackingTrack *track;
+ ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
+ int i, track_index, frame_width, frame_height;
+
+ BKE_movieclip_get_size(clip, user, &frame_width, &frame_height);
+
+ /* TODO(sergey): Currently using only a single clip. */
+ context->clips[0] = clip;
+ context->num_clips = 1;
+
+ context->user = *user;
+ context->user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
+ context->user.render_flag = 0;
+ context->frame_width = frame_width;
+ context->frame_height = frame_height;
+ context->backwards = backwards;
+ context->sequence = sequence;
+ context->first_frame = user->framenr;
+ context->sync_frame = user->framenr;
+ context->first_sync = true;
+
+ BLI_spin_init(&context->spin_lock);
+
+ context->image_accessor =
+ tracking_image_accessor_new(context->clips, 1, user->framenr);
+ context->autotrack =
+ libmv_autoTrackNew(context->image_accessor->libmv_accessor);
+
+ /* Fill in Autotrack with all markers we know. */
+ track_index = 0;
+ for (track = tracksbase->first;
+ track;
+ track = track->next)
+ {
+ if (check_track_trackable(clip, track, user)) {
+ context->num_tracks++;
+ }
+
+ for (i = 0; i < track->markersnr; ++i) {
+ MovieTrackingMarker *marker = track->markers + i;
+ if ((marker->flag & MARKER_DISABLED) == 0) {
+ libmv_Marker libmv_marker;
+ dna_marker_to_libmv_marker(track,
+ marker,
+ 0,
+ track_index,
+ frame_width,
+ frame_height,
+ backwards,
+ &libmv_marker);
+ libmv_autoTrackAddMarker(context->autotrack,
+ &libmv_marker);
+ }
+ }
+ track_index++;
+ }
+
+ /* Create per-track tracking options. */
+ context->options =
+ MEM_callocN(sizeof(AutoTrackOptions) * context->num_tracks,
+ "auto track options");
+ i = track_index = 0;
+ for (track = tracksbase->first;
+ track;
+ track = track->next)
+ {
+ if (check_track_trackable(clip, track, user)) {
+ AutoTrackOptions *options = &context->options[i++];
+ /* TODO(sergey): Single clip only for now. */
+ options->clip_index = 0;
+ options->track_index = track_index;
+ options->track = track;
+ tracking_configure_tracker(track,
+ NULL,
+ &options->track_region_options);
+ options->use_keyframe_match =
+ track->pattern_match == TRACK_MATCH_KEYFRAME;
+ }
+ ++track_index;
+ }
+
+ return context;
+}
+
+bool BKE_autotrack_context_step(AutoTrackContext *context)
+{
+ int frame_delta = context->backwards ? -1 : 1;
+ bool ok = false;
+ int track;
+
+#pragma omp parallel for if(context->num_tracks > 1)
+ for (track = 0; track < context->num_tracks; ++track) {
+ AutoTrackOptions *options = &context->options[track];
+ libmv_Marker libmv_current_marker,
+ libmv_reference_marker,
+ libmv_tracked_marker;
+ libmv_TrackRegionResult libmv_result;
+ int frame = BKE_movieclip_remap_scene_to_clip_frame(
+ context->clips[options->clip_index],
+ context->user.framenr);
+ bool has_marker;
+
+ BLI_spin_lock(&context->spin_lock);
+ has_marker = libmv_autoTrackGetMarker(context->autotrack,
+ options->clip_index,
+ frame,
+ options->track_index,
+ &libmv_current_marker);
+ BLI_spin_unlock(&context->spin_lock);
+
+ if (has_marker) {
+ if (!tracking_check_marker_margin(&libmv_current_marker,
+ options->track->margin,
+ context->frame_width,
+ context->frame_height))
+ {
+ continue;
+ }
+
+ libmv_tracked_marker = libmv_current_marker;
+ libmv_tracked_marker.frame = frame + frame_delta;
+
+ if (options->use_keyframe_match) {
+ libmv_tracked_marker.reference_frame =
+ libmv_current_marker.reference_frame;
+ libmv_autoTrackGetMarker(context->autotrack,
+ options->clip_index,
+ libmv_tracked_marker.reference_frame,
+ options->track_index,
+ &libmv_reference_marker);
+ }
+ else {
+ libmv_tracked_marker.reference_frame = frame;
+ libmv_reference_marker = libmv_current_marker;
+ }
+
+ if (libmv_autoTrackMarker(context->autotrack,
+ &options->track_region_options,
+ &libmv_tracked_marker,
+ &libmv_result))
+ {
+ BLI_spin_lock(&context->spin_lock);
+ libmv_autoTrackAddMarker(context->autotrack,
+ &libmv_tracked_marker);
+ BLI_spin_unlock(&context->spin_lock);
+ }
+ else {
+ options->is_failed = true;
+ options->failed_frame = frame + frame_delta;
+ }
+ ok = true;
+ }
+ }
+
+ BLI_spin_lock(&context->spin_lock);
+ context->user.framenr += frame_delta;
+ BLI_spin_unlock(&context->spin_lock);
+
+ return ok;
+}
+
+void BKE_autotrack_context_sync(AutoTrackContext *context)
+{
+ int newframe, frame_delta = context->backwards ? -1 : 1;
+ int clip, frame;
+
+ BLI_spin_lock(&context->spin_lock);
+ newframe = context->user.framenr;
+ for (frame = context->sync_frame;
+ frame != (context->backwards ? newframe - 1 : newframe + 1);
+ frame += frame_delta)
+ {
+ MovieTrackingMarker marker;
+ libmv_Marker libmv_marker;
+ int clip = 0;
+ int track;
+ for (track = 0; track < context->num_tracks; ++track) {
+ AutoTrackOptions *options = &context->options[track];
+ int track_frame = BKE_movieclip_remap_scene_to_clip_frame(
+ context->clips[options->clip_index], frame);
+ if (options->is_failed && options->failed_frame == track_frame) {
+ MovieTrackingMarker *prev_marker =
+ BKE_tracking_marker_get_exact(options->track, frame);
+ if (prev_marker) {
+ marker = *prev_marker;
+ marker.framenr = context->backwards ?
+ track_frame - 1 :
+ track_frame + 1;
+ marker.flag |= MARKER_DISABLED;
+ BKE_tracking_marker_insert(options->track, &marker);
+ continue;
+ }
+ }
+ if (libmv_autoTrackGetMarker(context->autotrack,
+ clip,
+ track_frame,
+ options->track_index,
+ &libmv_marker))
+ {
+ libmv_marker_to_dna_marker(&libmv_marker,
+ context->frame_width,
+ context->frame_height,
+ &marker);
+ if (context->first_sync && frame == context->sync_frame) {
+ tracking_marker_insert_disabled(options->track,
+ &marker,
+ !context->backwards,
+ false);
+ }
+ BKE_tracking_marker_insert(options->track, &marker);
+ tracking_marker_insert_disabled(options->track,
+ &marker,
+ context->backwards,
+ false);
+ }
+ }
+ }
+ BLI_spin_unlock(&context->spin_lock);
+
+ for (clip = 0; clip < context->num_clips; ++clip) {
+ MovieTracking *tracking = &context->clips[clip]->tracking;
+ BKE_tracking_dopesheet_tag_update(tracking);
+ }
+
+ context->sync_frame = newframe;
+ context->first_sync = false;
+}
+
+void BKE_autotrack_context_sync_user(AutoTrackContext *context,
+ MovieClipUser *user)
+{
+ user->framenr = context->sync_frame;
+}
+
+void BKE_autotrack_context_finish(AutoTrackContext *context)
+{
+ int clip_index;
+
+ for (clip_index = 0; clip_index < context->num_clips; ++clip_index) {
+ MovieClip *clip = context->clips[clip_index];
+ ListBase *plane_tracks_base =
+ BKE_tracking_get_active_plane_tracks(&clip->tracking);
+ MovieTrackingPlaneTrack *plane_track;
+
+ for (plane_track = plane_tracks_base->first;
+ plane_track;
+ plane_track = plane_track->next)
+ {
+ if ((plane_track->flag & PLANE_TRACK_AUTOKEY) == 0) {
+ int track;
+ for (track = 0; track < context->num_tracks; ++track) {
+ MovieTrackingTrack *old_track;
+ bool do_update = false;
+ int j;
+
+ old_track = context->options[track].track;
+ for (j = 0; j < plane_track->point_tracksnr; j++) {
+ if (plane_track->point_tracks[j] == old_track) {
+ do_update = true;
+ break;
+ }
+ }
+
+ if (do_update) {
+ BKE_tracking_track_plane_from_existing_motion(
+ plane_track,
+ context->first_frame);
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+void BKE_autotrack_context_free(AutoTrackContext *context)
+{
+ libmv_autoTrackDestroy(context->autotrack);
+ tracking_image_accessor_destroy(context->image_accessor);
+ MEM_freeN(context->options);
+ BLI_spin_end(&context->spin_lock);
+ MEM_freeN(context);
+}
diff --git a/source/blender/blenkernel/intern/tracking_detect.c b/source/blender/blenkernel/intern/tracking_detect.c
index 62039b761e8..6df51b5441a 100644
--- a/source/blender/blenkernel/intern/tracking_detect.c
+++ b/source/blender/blenkernel/intern/tracking_detect.c
@@ -40,7 +40,6 @@
#include "BKE_tracking.h"
#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
#include "libmv-capi.h"
diff --git a/source/blender/blenkernel/intern/tracking_region_tracker.c b/source/blender/blenkernel/intern/tracking_region_tracker.c
index c41106f37cb..dd7def16ca8 100644
--- a/source/blender/blenkernel/intern/tracking_region_tracker.c
+++ b/source/blender/blenkernel/intern/tracking_region_tracker.c
@@ -35,11 +35,8 @@
#include "MEM_guardedalloc.h"
#include "DNA_movieclip_types.h"
-#include "DNA_object_types.h" /* SELECT */
#include "BLI_utildefines.h"
-#include "BLI_math.h"
-#include "BLI_ghash.h"
#include "BLI_threads.h"
#include "BKE_tracking.h"
@@ -51,170 +48,6 @@
#include "libmv-capi.h"
#include "tracking_private.h"
-typedef struct TrackContext {
- /* the reference marker and cutout search area */
- MovieTrackingMarker reference_marker;
-
- /* keyframed patch. This is the search area */
- float *search_area;
- int search_area_height;
- int search_area_width;
- int framenr;
-
- float *mask;
-} TrackContext;
-
-typedef struct MovieTrackingContext {
- MovieClipUser user;
- MovieClip *clip;
- int clip_flag;
-
- int frames, first_frame;
- bool first_time;
-
- MovieTrackingSettings settings;
- TracksMap *tracks_map;
-
- bool backwards, sequence;
- int sync_frame;
-} MovieTrackingContext;
-
-static void track_context_free(void *customdata)
-{
- TrackContext *track_context = (TrackContext *)customdata;
-
- if (track_context->search_area)
- MEM_freeN(track_context->search_area);
-
- if (track_context->mask)
- MEM_freeN(track_context->mask);
-}
-
-/* Create context for motion 2D tracking, copies all data needed
- * for thread-safe tracking, allowing clip modifications during
- * tracking.
- */
-MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user,
- const bool backwards, const bool sequence)
-{
- MovieTrackingContext *context = MEM_callocN(sizeof(MovieTrackingContext), "trackingContext");
- MovieTracking *tracking = &clip->tracking;
- MovieTrackingSettings *settings = &tracking->settings;
- ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
- MovieTrackingTrack *track;
- MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
- int num_tracks = 0;
-
- context->clip = clip;
- context->settings = *settings;
- context->backwards = backwards;
- context->sync_frame = user->framenr;
- context->first_time = true;
- context->first_frame = user->framenr;
- context->sequence = sequence;
-
- /* count */
- track = tracksbase->first;
- while (track) {
- if (TRACK_SELECTED(track) && (track->flag & (TRACK_LOCKED | TRACK_HIDDEN)) == 0) {
- int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr);
- MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
-
- if ((marker->flag & MARKER_DISABLED) == 0)
- num_tracks++;
- }
-
- track = track->next;
- }
-
- /* create tracking contextx for all tracks which would be tracked */
- if (num_tracks) {
- int width, height;
-
- context->tracks_map = tracks_map_new(object->name, object->flag & TRACKING_OBJECT_CAMERA,
- num_tracks, sizeof(TrackContext));
-
- BKE_movieclip_get_size(clip, user, &width, &height);
-
- /* create tracking data */
- track = tracksbase->first;
- while (track) {
- if (TRACK_SELECTED(track) && (track->flag & (TRACK_HIDDEN | TRACK_LOCKED)) == 0) {
- int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, user->framenr);
- MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
-
- if ((marker->flag & MARKER_DISABLED) == 0) {
- TrackContext track_context;
- memset(&track_context, 0, sizeof(TrackContext));
- tracks_map_insert(context->tracks_map, track, &track_context);
- }
- }
-
- track = track->next;
- }
- }
-
- /* store needed clip flags passing to get_buffer functions
- * - MCLIP_USE_PROXY is needed to because timecode affects on movie clip
- * only in case Proxy/Timecode flag is set, so store this flag to use
- * timecodes properly but reset render size to SIZE_FULL so correct resolution
- * would be used for images
- * - MCLIP_USE_PROXY_CUSTOM_DIR is needed because proxy/timecode files might
- * be stored in a different location
- * ignore all the rest possible flags for now
- */
- context->clip_flag = clip->flag & MCLIP_TIMECODE_FLAGS;
-
- context->user = *user;
- context->user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
- context->user.render_flag = 0;
-
- if (!sequence)
- BLI_begin_threaded_malloc();
-
- return context;
-}
-
-/* Free context used for tracking. */
-void BKE_tracking_context_free(MovieTrackingContext *context)
-{
- if (!context->sequence)
- BLI_end_threaded_malloc();
-
- tracks_map_free(context->tracks_map, track_context_free);
-
- MEM_freeN(context);
-}
-
-/* Synchronize tracks between clip editor and tracking context,
- * by merging them together so all new created tracks and tracked
- * ones presents in the movie clip.
- */
-void BKE_tracking_context_sync(MovieTrackingContext *context)
-{
- MovieTracking *tracking = &context->clip->tracking;
- int newframe;
-
- tracks_map_merge(context->tracks_map, tracking);
-
- if (context->backwards)
- newframe = context->user.framenr + 1;
- else
- newframe = context->user.framenr - 1;
-
- context->sync_frame = newframe;
-
- BKE_tracking_dopesheet_tag_update(tracking);
-}
-
-/* Synchronize clip user's frame number with a frame number from tracking context,
- * used to update current frame displayed in the clip editor while tracking.
- */
-void BKE_tracking_context_sync_user(const MovieTrackingContext *context, MovieClipUser *user)
-{
- user->framenr = context->sync_frame;
-}
-
/* **** utility functions for tracking **** */
/* convert from float and byte RGBA to grayscale. Supports different coefficients for RGB. */
@@ -280,7 +113,7 @@ static float *track_get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track,
return gray_pixels;
}
-/* Get image boffer for a given frame
+/* Get image buffer for a given frame
*
* Frame is in clip space.
*/
@@ -296,51 +129,6 @@ static ImBuf *tracking_context_get_frame_ibuf(MovieClip *clip, MovieClipUser *us
return ibuf;
}
-/* Get previous keyframed marker. */
-static MovieTrackingMarker *tracking_context_get_keyframed_marker(MovieTrackingTrack *track,
- int curfra, bool backwards)
-{
- MovieTrackingMarker *marker_keyed = NULL;
- MovieTrackingMarker *marker_keyed_fallback = NULL;
- int a = BKE_tracking_marker_get(track, curfra) - track->markers;
-
- while (a >= 0 && a < track->markersnr) {
- int next = backwards ? a + 1 : a - 1;
- bool is_keyframed = false;
- MovieTrackingMarker *cur_marker = &track->markers[a];
- MovieTrackingMarker *next_marker = NULL;
-
- if (next >= 0 && next < track->markersnr)
- next_marker = &track->markers[next];
-
- if ((cur_marker->flag & MARKER_DISABLED) == 0) {
- /* If it'll happen so we didn't find a real keyframe marker,
- * fallback to the first marker in current tracked segment
- * as a keyframe.
- */
- if (next_marker && next_marker->flag & MARKER_DISABLED) {
- if (marker_keyed_fallback == NULL)
- marker_keyed_fallback = cur_marker;
- }
-
- is_keyframed |= (cur_marker->flag & MARKER_TRACKED) == 0;
- }
-
- if (is_keyframed) {
- marker_keyed = cur_marker;
-
- break;
- }
-
- a = next;
- }
-
- if (marker_keyed == NULL)
- marker_keyed = marker_keyed_fallback;
-
- return marker_keyed;
-}
-
/* Get image buffer for previous marker's keyframe. */
static ImBuf *tracking_context_get_keyframed_ibuf(MovieClip *clip, MovieClipUser *user, int clip_flag,
MovieTrackingTrack *track, int curfra, bool backwards,
@@ -349,7 +137,7 @@ static ImBuf *tracking_context_get_keyframed_ibuf(MovieClip *clip, MovieClipUser
MovieTrackingMarker *marker_keyed;
int keyed_framenr;
- marker_keyed = tracking_context_get_keyframed_marker(track, curfra, backwards);
+ marker_keyed = tracking_get_keyframed_marker(track, curfra, backwards);
if (marker_keyed == NULL) {
return NULL;
}
@@ -381,50 +169,9 @@ static ImBuf *tracking_context_get_reference_ibuf(MovieClip *clip, MovieClipUser
return ibuf;
}
-/* Update track's reference patch (patch from which track is tracking from)
- *
- * Returns false if reference image buffer failed to load.
- */
-static bool track_context_update_reference(MovieTrackingContext *context, TrackContext *track_context,
- MovieTrackingTrack *track, MovieTrackingMarker *marker, int curfra,
- int frame_width, int frame_height)
-{
- MovieTrackingMarker *reference_marker = NULL;
- ImBuf *reference_ibuf = NULL;
- int width, height;
-
- /* calculate patch for keyframed position */
- reference_ibuf = tracking_context_get_reference_ibuf(context->clip, &context->user, context->clip_flag,
- track, curfra, context->backwards, &reference_marker);
-
- if (!reference_ibuf)
- return false;
-
- track_context->reference_marker = *reference_marker;
-
- if (track_context->search_area) {
- MEM_freeN(track_context->search_area);
- }
-
- track_context->search_area = track_get_search_floatbuf(reference_ibuf, track, reference_marker, &width, &height);
- track_context->search_area_height = height;
- track_context->search_area_width = width;
-
- if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0) {
- if (track_context->mask)
- MEM_freeN(track_context->mask);
-
- track_context->mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker);
- }
-
- IMB_freeImBuf(reference_ibuf);
-
- return true;
-}
-
/* Fill in libmv tracker options structure with settings need to be used to perform track. */
-static void tracking_configure_tracker(const MovieTrackingTrack *track, float *mask,
- libmv_TrackRegionOptions *options)
+void tracking_configure_tracker(const MovieTrackingTrack *track, float *mask,
+ libmv_TrackRegionOptions *options)
{
options->motion_model = track->motion_model;
@@ -442,102 +189,6 @@ static void tracking_configure_tracker(const MovieTrackingTrack *track, float *m
options->image1_mask = NULL;
}
-/* returns false if marker crossed margin area from frame bounds */
-static bool tracking_check_marker_margin(MovieTrackingTrack *track, MovieTrackingMarker *marker,
- int frame_width, int frame_height)
-{
- float pat_min[2], pat_max[2];
- float margin_left, margin_top, margin_right, margin_bottom;
- float normalized_track_margin[2];
-
- /* margin from frame boundaries */
- BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
-
- normalized_track_margin[0] = (float)track->margin / frame_width;
- normalized_track_margin[1] = (float)track->margin / frame_height;
-
- margin_left = max_ff(-pat_min[0], normalized_track_margin[0]);
- margin_top = max_ff( pat_max[1], normalized_track_margin[1]);
- margin_right = max_ff( pat_max[0], normalized_track_margin[0]);
- margin_bottom = max_ff(-pat_min[1], normalized_track_margin[1]);
-
- /* do not track markers which are too close to boundary */
- if (marker->pos[0] < margin_left || marker->pos[0] > 1.0f - margin_right ||
- marker->pos[1] < margin_bottom || marker->pos[1] > 1.0f - margin_top)
- {
- return false;
- }
-
- return true;
-}
-
-/* Scale search area of marker based on scale changes of pattern area,
- *
- * TODO(sergey): currently based on pattern bounding box scale change,
- * smarter approach here is welcome.
- */
-static void tracking_scale_marker_search(const MovieTrackingMarker *old_marker, MovieTrackingMarker *new_marker)
-{
- float old_pat_min[2], old_pat_max[2];
- float new_pat_min[2], new_pat_max[2];
- float scale_x, scale_y;
-
- BKE_tracking_marker_pattern_minmax(old_marker, old_pat_min, old_pat_max);
- BKE_tracking_marker_pattern_minmax(new_marker, new_pat_min, new_pat_max);
-
- scale_x = (new_pat_max[0] - new_pat_min[0]) / (old_pat_max[0] - old_pat_min[0]);
- scale_y = (new_pat_max[1] - new_pat_min[1]) / (old_pat_max[1] - old_pat_min[1]);
-
- new_marker->search_min[0] *= scale_x;
- new_marker->search_min[1] *= scale_y;
-
- new_marker->search_max[0] *= scale_x;
- new_marker->search_max[1] *= scale_y;
-}
-
-/* Insert new marker which was tracked from old_marker to a new image,
- * will also ensure tracked segment is surrounded by disabled markers.
- */
-static void tracking_insert_new_marker(MovieTrackingContext *context, MovieTrackingTrack *track,
- const MovieTrackingMarker *old_marker, int curfra, bool tracked,
- int frame_width, int frame_height,
- const double dst_pixel_x[5], const double dst_pixel_y[5])
-{
- MovieTrackingMarker new_marker;
- int frame_delta = context->backwards ? -1 : 1;
- int nextfra = curfra + frame_delta;
-
- new_marker = *old_marker;
-
- if (tracked) {
- tracking_set_marker_coords_from_tracking(frame_width, frame_height, &new_marker, dst_pixel_x, dst_pixel_y);
- new_marker.flag |= MARKER_TRACKED;
- new_marker.framenr = nextfra;
-
- tracking_scale_marker_search(old_marker, &new_marker);
-
- if (context->first_time) {
- /* check if there's no keyframe/tracked markers before tracking marker.
- * if so -- create disabled marker before currently tracking "segment"
- */
-
- tracking_marker_insert_disabled(track, old_marker, !context->backwards, false);
- }
-
- /* insert currently tracked marker */
- BKE_tracking_marker_insert(track, &new_marker);
-
- /* make currently tracked segment be finished with disabled marker */
- tracking_marker_insert_disabled(track, &new_marker, context->backwards, false);
- }
- else {
- new_marker.framenr = nextfra;
- new_marker.flag |= MARKER_DISABLED;
-
- BKE_tracking_marker_insert(track, &new_marker);
- }
-}
-
/* Peform tracking from a reference_marker to destination_ibuf.
* Uses marker as an initial position guess.
*
@@ -601,130 +252,6 @@ static bool configure_and_run_tracker(ImBuf *destination_ibuf, MovieTrackingTrac
return tracked;
}
-/* Track all the tracks from context one more frame,
- * returns FALSe if nothing was tracked.
- */
-bool BKE_tracking_context_step(MovieTrackingContext *context)
-{
- ImBuf *destination_ibuf;
- int frame_delta = context->backwards ? -1 : 1;
- int curfra = BKE_movieclip_remap_scene_to_clip_frame(context->clip, context->user.framenr);
- int a, map_size;
- bool ok = false;
-
- int frame_width, frame_height;
-
- map_size = tracks_map_get_size(context->tracks_map);
-
- /* Nothing to track, avoid unneeded frames reading to save time and memory. */
- if (!map_size)
- return false;
-
- /* Get an image buffer for frame we're tracking to. */
- context->user.framenr += frame_delta;
-
- destination_ibuf = BKE_movieclip_get_ibuf_flag(context->clip, &context->user,
- context->clip_flag, MOVIECLIP_CACHE_SKIP);
- if (!destination_ibuf)
- return false;
-
- frame_width = destination_ibuf->x;
- frame_height = destination_ibuf->y;
-
-#pragma omp parallel for private(a) shared(destination_ibuf, ok) if (map_size > 1)
- for (a = 0; a < map_size; a++) {
- TrackContext *track_context = NULL;
- MovieTrackingTrack *track;
- MovieTrackingMarker *marker;
-
- tracks_map_get_indexed_element(context->tracks_map, a, &track, (void **)&track_context);
-
- marker = BKE_tracking_marker_get_exact(track, curfra);
-
- if (marker && (marker->flag & MARKER_DISABLED) == 0) {
- bool tracked = false, need_readjust;
- double dst_pixel_x[5], dst_pixel_y[5];
-
- if (track->pattern_match == TRACK_MATCH_KEYFRAME)
- need_readjust = context->first_time;
- else
- need_readjust = true;
-
- /* do not track markers which are too close to boundary */
- if (tracking_check_marker_margin(track, marker, frame_width, frame_height)) {
- if (need_readjust) {
- if (track_context_update_reference(context, track_context, track, marker,
- curfra, frame_width, frame_height) == false)
- {
- /* happens when reference frame fails to be loaded */
- continue;
- }
- }
-
- tracked = configure_and_run_tracker(destination_ibuf, track,
- &track_context->reference_marker, marker,
- track_context->search_area,
- track_context->search_area_width,
- track_context->search_area_height,
- track_context->mask,
- dst_pixel_x, dst_pixel_y);
- }
-
- BLI_spin_lock(&context->tracks_map->spin_lock);
- tracking_insert_new_marker(context, track, marker, curfra, tracked,
- frame_width, frame_height, dst_pixel_x, dst_pixel_y);
- BLI_spin_unlock(&context->tracks_map->spin_lock);
-
- ok = true;
- }
- }
-
- IMB_freeImBuf(destination_ibuf);
-
- context->first_time = false;
- context->frames++;
-
- return ok;
-}
-
-void BKE_tracking_context_finish(MovieTrackingContext *context)
-{
- MovieClip *clip = context->clip;
- ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(&clip->tracking);
- MovieTrackingPlaneTrack *plane_track;
- int map_size = tracks_map_get_size(context->tracks_map);
-
- for (plane_track = plane_tracks_base->first;
- plane_track;
- plane_track = plane_track->next)
- {
- if ((plane_track->flag & PLANE_TRACK_AUTOKEY) == 0) {
- int i;
- for (i = 0; i < map_size; i++) {
- TrackContext *track_context = NULL;
- MovieTrackingTrack *track, *old_track;
- bool do_update = false;
- int j;
-
- tracks_map_get_indexed_element(context->tracks_map, i, &track, (void **)&track_context);
-
- old_track = BLI_ghash_lookup(context->tracks_map->hash, track);
- for (j = 0; j < plane_track->point_tracksnr; j++) {
- if (plane_track->point_tracks[j] == old_track) {
- do_update = true;
- break;
- }
- }
-
- if (do_update) {
- BKE_tracking_track_plane_from_existing_motion(plane_track, context->first_frame);
- break;
- }
- }
- }
- }
-}
-
static bool refine_marker_reference_frame_get(MovieTrackingTrack *track,
MovieTrackingMarker *marker,
bool backwards,
diff --git a/source/blender/blenkernel/intern/tracking_solver.c b/source/blender/blenkernel/intern/tracking_solver.c
index 056220e27d8..d5e2f24e9ed 100644
--- a/source/blender/blenkernel/intern/tracking_solver.c
+++ b/source/blender/blenkernel/intern/tracking_solver.c
@@ -356,7 +356,7 @@ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieClip *clip
MovieReconstructContext *context = MEM_callocN(sizeof(MovieReconstructContext), "MovieReconstructContext data");
ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
float aspy = 1.0f / tracking->camera.pixel_aspect;
- int num_tracks = BLI_countlist(tracksbase);
+ int num_tracks = BLI_listbase_count(tracksbase);
int sfra = INT_MAX, efra = INT_MIN;
MovieTrackingTrack *track;
@@ -391,7 +391,7 @@ MovieReconstructContext *BKE_tracking_reconstruction_context_new(MovieClip *clip
last_marker--;
}
- if (first < track->markersnr - 1)
+ if (first <= track->markersnr - 1)
sfra = min_ii(sfra, first_marker->framenr);
if (last >= 0)
@@ -509,6 +509,11 @@ bool BKE_tracking_reconstruction_finish(MovieReconstructContext *context, MovieT
MovieTrackingReconstruction *reconstruction;
MovieTrackingObject *object;
+ if (!libmv_reconstructionIsValid(context->reconstruction)) {
+ printf("Failed solve the motion: most likely there are no good keyframes\n");
+ return false;
+ }
+
tracks_map_merge(context->tracks_map, tracking);
BKE_tracking_dopesheet_tag_update(tracking);
diff --git a/source/blender/blenkernel/intern/tracking_util.c b/source/blender/blenkernel/intern/tracking_util.c
index 0a8293630c7..17e4a3c73c3 100644
--- a/source/blender/blenkernel/intern/tracking_util.c
+++ b/source/blender/blenkernel/intern/tracking_util.c
@@ -47,8 +47,13 @@
#include "BLF_translation.h"
+#include "BKE_movieclip.h"
#include "BKE_tracking.h"
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+#include "IMB_moviecache.h"
+
#include "tracking_private.h"
#include "libmv-capi.h"
@@ -390,8 +395,7 @@ void tracking_marker_insert_disabled(MovieTrackingTrack *track, const MovieTrack
}
-/* Fill in Libmv C-API camera intrinsics options from tracking structure.
- */
+/* Fill in Libmv C-API camera intrinsics options from tracking structure. */
void tracking_cameraIntrinscisOptionsFromTracking(MovieTracking *tracking,
int calibration_width, int calibration_height,
libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
@@ -453,3 +457,441 @@ void tracking_trackingCameraFromIntrinscisOptions(MovieTracking *tracking,
BLI_assert(!"Unknown distortion model");
}
}
+
+/* Get previous keyframed marker. */
+MovieTrackingMarker *tracking_get_keyframed_marker(MovieTrackingTrack *track,
+ int current_frame,
+ bool backwards)
+{
+ MovieTrackingMarker *marker_keyed = NULL;
+ MovieTrackingMarker *marker_keyed_fallback = NULL;
+ int a = BKE_tracking_marker_get(track, current_frame) - track->markers;
+
+ while (a >= 0 && a < track->markersnr) {
+ int next = backwards ? a + 1 : a - 1;
+ bool is_keyframed = false;
+ MovieTrackingMarker *cur_marker = &track->markers[a];
+ MovieTrackingMarker *next_marker = NULL;
+
+ if (next >= 0 && next < track->markersnr)
+ next_marker = &track->markers[next];
+
+ if ((cur_marker->flag & MARKER_DISABLED) == 0) {
+ /* If it'll happen so we didn't find a real keyframe marker,
+ * fallback to the first marker in current tracked segment
+ * as a keyframe.
+ */
+ if (next_marker && next_marker->flag & MARKER_DISABLED) {
+ if (marker_keyed_fallback == NULL)
+ marker_keyed_fallback = cur_marker;
+ }
+
+ is_keyframed |= (cur_marker->flag & MARKER_TRACKED) == 0;
+ }
+
+ if (is_keyframed) {
+ marker_keyed = cur_marker;
+
+ break;
+ }
+
+ a = next;
+ }
+
+ if (marker_keyed == NULL)
+ marker_keyed = marker_keyed_fallback;
+
+ return marker_keyed;
+}
+
+/*********************** Frame accessr *************************/
+
+typedef struct AccessCacheKey {
+ int clip_index;
+ int frame;
+ int downscale;
+ libmv_InputMode input_mode;
+ int64_t transform_key;
+} AccessCacheKey;
+
+static unsigned int accesscache_hashhash(const void *key_v)
+{
+ const AccessCacheKey *key = (const AccessCacheKey *) key_v;
+ /* TODP(sergey): Need better hasing here for faster frame access. */
+ return key->clip_index << 16 | key->frame;
+}
+
+static bool accesscache_hashcmp(const void *a_v, const void *b_v)
+{
+ const AccessCacheKey *a = (const AccessCacheKey *) a_v;
+ const AccessCacheKey *b = (const AccessCacheKey *) b_v;
+
+#define COMPARE_FIELD(field)
+ { \
+ if (a->clip_index != b->clip_index) { \
+ return false; \
+ } \
+ } (void) 0
+
+ COMPARE_FIELD(clip_index);
+ COMPARE_FIELD(frame);
+ COMPARE_FIELD(downscale);
+ COMPARE_FIELD(input_mode);
+ COMPARE_FIELD(transform_key);
+
+#undef COMPARE_FIELD
+
+ return true;
+}
+
+static void accesscache_put(TrackingImageAccessor *accessor,
+ int clip_index,
+ int frame,
+ libmv_InputMode input_mode,
+ int downscale,
+ int64_t transform_key,
+ ImBuf *ibuf)
+{
+ AccessCacheKey key;
+ key.clip_index = clip_index;
+ key.frame = frame;
+ key.input_mode = input_mode;
+ key.downscale = downscale;
+ key.transform_key = transform_key;
+ IMB_moviecache_put(accessor->cache, &key, ibuf);
+}
+
+static ImBuf *accesscache_get(TrackingImageAccessor *accessor,
+ int clip_index,
+ int frame,
+ libmv_InputMode input_mode,
+ int downscale,
+ int64_t transform_key)
+{
+ AccessCacheKey key;
+ key.clip_index = clip_index;
+ key.frame = frame;
+ key.input_mode = input_mode;
+ key.downscale = downscale;
+ key.transform_key = transform_key;
+ return IMB_moviecache_get(accessor->cache, &key);
+}
+
+static ImBuf *accessor_get_preprocessed_ibuf(TrackingImageAccessor *accessor,
+ int clip_index,
+ int frame)
+{
+ MovieClip *clip;
+ MovieClipUser user;
+ ImBuf *ibuf;
+ int scene_frame;
+
+ BLI_assert(clip_index < accessor->num_clips);
+
+ clip = accessor->clips[clip_index];
+ scene_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, frame);
+ BKE_movieclip_user_set_frame(&user, scene_frame);
+ user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
+ user.render_flag = 0;
+ ibuf = BKE_movieclip_get_ibuf(clip, &user);
+
+ return ibuf;
+}
+
+static ImBuf *make_grayscale_ibuf_copy(ImBuf *ibuf)
+{
+ ImBuf *grayscale = IMB_allocImBuf(ibuf->x, ibuf->y, 32, 0);
+ size_t size;
+ int i;
+
+ BLI_assert(ibuf->channels == 3 || ibuf->channels == 4);
+
+ /* TODO(sergey): Bummer, currently IMB API only allows to create 4 channels
+ * float buffer, so we do it manually here.
+ *
+ * Will generalize it later.
+ */
+ size = (size_t)grayscale->x * (size_t)grayscale->y * sizeof(float);
+ grayscale->channels = 1;
+ if ((grayscale->rect_float = MEM_mapallocN(size, "tracking grayscale image"))) {
+ grayscale->mall |= IB_rectfloat;
+ grayscale->flags |= IB_rectfloat;
+ }
+
+ for (i = 0; i < grayscale->x * grayscale->y; ++i) {
+ const float *pixel = ibuf->rect_float + ibuf->channels * i;
+
+ grayscale->rect_float[i] = 0.2126f * pixel[0] +
+ 0.7152f * pixel[1] +
+ 0.0722f * pixel[2];
+ }
+
+ return grayscale;
+}
+
+static void ibuf_to_float_image(const ImBuf *ibuf, libmv_FloatImage *float_image)
+{
+ BLI_assert(ibuf->rect_float != NULL);
+ float_image->buffer = ibuf->rect_float;
+ float_image->width = ibuf->x;
+ float_image->height = ibuf->y;
+ float_image->channels = ibuf->channels;
+}
+
+static ImBuf *float_image_to_ibuf(libmv_FloatImage *float_image)
+{
+ ImBuf *ibuf = IMB_allocImBuf(float_image->width, float_image->height, 32, 0);
+ size_t size = (size_t)ibuf->x * (size_t)ibuf->y *
+ float_image->channels * sizeof(float);
+ ibuf->channels = float_image->channels;
+ if ((ibuf->rect_float = MEM_mapallocN(size, "tracking grayscale image"))) {
+ ibuf->mall |= IB_rectfloat;
+ ibuf->flags |= IB_rectfloat;
+ }
+ memcpy(ibuf->rect_float, float_image->buffer, size);
+ return ibuf;
+}
+
+static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
+ int clip_index,
+ int frame,
+ libmv_InputMode input_mode,
+ int downscale,
+ const libmv_Region *region,
+ const libmv_FrameTransform *transform)
+{
+ ImBuf *ibuf, *orig_ibuf, *final_ibuf;
+ int64_t transform_key = 0;
+
+ if (transform != NULL) {
+ transform_key = libmv_frameAccessorgetTransformKey(transform);
+ }
+
+ /* First try to get fully processed image from the cache. */
+ ibuf = accesscache_get(accessor,
+ clip_index,
+ frame,
+ input_mode,
+ downscale,
+ transform_key);
+ if (ibuf != NULL) {
+ return ibuf;
+ }
+
+ /* And now we do postprocessing of the original frame. */
+ orig_ibuf = accessor_get_preprocessed_ibuf(accessor, clip_index, frame);
+
+ if (orig_ibuf == NULL) {
+ return NULL;
+ }
+
+ if (region != NULL) {
+ int width = region->max[0] - region->min[0],
+ height = region->max[1] - region->min[1];
+
+ /* If the requested region goes outside of the actual frame we still
+ * return the requested region size, but only fill it's partially with
+ * the data we can.
+ */
+ int clamped_origin_x = max_ii((int)region->min[0], 0),
+ clamped_origin_y = max_ii((int)region->min[1], 0);
+ int dst_offset_x = clamped_origin_x - (int)region->min[0],
+ dst_offset_y = clamped_origin_y - (int)region->min[1];
+ int clamped_width = width - dst_offset_x,
+ clamped_height = height - dst_offset_y;
+ clamped_width = min_ii(clamped_width, orig_ibuf->x - clamped_origin_x);
+ clamped_height = min_ii(clamped_height, orig_ibuf->y - clamped_origin_y);
+
+ final_ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat);
+
+ if (orig_ibuf->rect_float != NULL) {
+ IMB_rectcpy(final_ibuf, orig_ibuf,
+ dst_offset_x, dst_offset_y,
+ clamped_origin_x, clamped_origin_y,
+ clamped_width, clamped_height);
+ }
+ else {
+ int y;
+ /* TODO(sergey): We don't do any color space or alpha conversion
+ * here. Probably Libmv is better to work in the linear space,
+ * but keep sRGB space here for compatibility for now.
+ */
+ for (y = 0; y < clamped_height; ++y) {
+ int x;
+ for (x = 0; x < clamped_width; ++x) {
+ int src_x = x + clamped_origin_x,
+ src_y = y + clamped_origin_y;
+ int dst_x = x + dst_offset_x,
+ dst_y = y + dst_offset_y;
+ int dst_index = (dst_y * width + dst_x) * 4,
+ src_index = (src_y * orig_ibuf->x + src_x) * 4;
+ rgba_uchar_to_float(final_ibuf->rect_float + dst_index,
+ (unsigned char *)orig_ibuf->rect +
+ src_index);
+ }
+ }
+ }
+ }
+ else {
+ /* Libmv only works with float images,
+ *
+ * This would likely make it so loads of float buffers are being stored
+ * in the cache which is nice on the one hand (faster re-use of the
+ * frames) but on the other hand it bumps the memory usage up.
+ */
+ BLI_lock_thread(LOCK_MOVIECLIP);
+ IMB_float_from_rect(orig_ibuf);
+ BLI_unlock_thread(LOCK_MOVIECLIP);
+ final_ibuf = orig_ibuf;
+ }
+
+ if (downscale > 0) {
+ if (final_ibuf == orig_ibuf) {
+ final_ibuf = IMB_dupImBuf(orig_ibuf);
+ }
+ IMB_scaleImBuf(final_ibuf,
+ ibuf->x / (1 << downscale),
+ ibuf->y / (1 << downscale));
+ }
+
+ if (transform != NULL) {
+ libmv_FloatImage input_image, output_image;
+ ibuf_to_float_image(final_ibuf, &input_image);
+ libmv_frameAccessorgetTransformRun(transform,
+ &input_image,
+ &output_image);
+ if (final_ibuf != orig_ibuf) {
+ IMB_freeImBuf(final_ibuf);
+ }
+ final_ibuf = float_image_to_ibuf(&output_image);
+ libmv_floatImageDestroy(&output_image);
+ }
+
+ if (input_mode == LIBMV_IMAGE_MODE_RGBA) {
+ BLI_assert(ibuf->channels == 3 || ibuf->channels == 4);
+ /* pass */
+ }
+ else /* if (input_mode == LIBMV_IMAGE_MODE_MONO) */ {
+ if (final_ibuf->channels != 1) {
+ ImBuf *grayscale_ibuf = make_grayscale_ibuf_copy(final_ibuf);
+ if (final_ibuf != orig_ibuf) {
+ /* We dereference original frame later. */
+ IMB_freeImBuf(final_ibuf);
+ }
+ final_ibuf = grayscale_ibuf;
+ }
+ }
+
+ /* it's possible processing still didn't happen at this point,
+ * but we really need a copy of the buffer to be transformed
+ * and to be put to the cache.
+ */
+ if (final_ibuf == orig_ibuf) {
+ final_ibuf = IMB_dupImBuf(orig_ibuf);
+ }
+
+ IMB_freeImBuf(orig_ibuf);
+
+ /* We put postprocessed frame to the cache always for now,
+ * not the smartest thing in the world, but who cares at this point.
+ */
+
+ /* TODO(sergey): Disable cache for now, because we don't store region
+ * in the cache key and can't check whether cached version is usable for
+ * us or not.
+ *
+ * Need to think better about what to cache and when.
+ */
+ if (false) {
+ accesscache_put(accessor,
+ clip_index,
+ frame,
+ input_mode,
+ downscale,
+ transform_key,
+ final_ibuf);
+ }
+
+ return final_ibuf;
+}
+
+static libmv_CacheKey accessor_get_image_callback(
+ struct libmv_FrameAccessorUserData *user_data,
+ int clip_index,
+ int frame,
+ libmv_InputMode input_mode,
+ int downscale,
+ const libmv_Region *region,
+ const libmv_FrameTransform *transform,
+ float **destination,
+ int *width,
+ int *height,
+ int *channels)
+{
+ TrackingImageAccessor *accessor = (TrackingImageAccessor *) user_data;
+ ImBuf *ibuf;
+
+ BLI_assert(clip_index >= 0 && clip_index < accessor->num_clips);
+
+ ibuf = accessor_get_ibuf(accessor,
+ clip_index,
+ frame,
+ input_mode,
+ downscale,
+ region,
+ transform);
+
+ if (ibuf) {
+ *destination = ibuf->rect_float;
+ *width = ibuf->x;
+ *height = ibuf->y;
+ *channels = ibuf->channels;
+ }
+ else {
+ *destination = NULL;
+ *width = 0;
+ *height = 0;
+ *channels = 0;
+ }
+
+ return ibuf;
+}
+
+static void accessor_release_image_callback(libmv_CacheKey cache_key)
+{
+ ImBuf *ibuf = (ImBuf *) cache_key;
+ IMB_freeImBuf(ibuf);
+}
+
+TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR_CLIP],
+ int num_clips,
+ int start_frame)
+{
+ TrackingImageAccessor *accessor =
+ MEM_callocN(sizeof(TrackingImageAccessor), "tracking image accessor");
+
+ BLI_assert(num_clips <= MAX_ACCESSOR_CLIP);
+
+ accessor->cache = IMB_moviecache_create("frame access cache",
+ sizeof(AccessCacheKey),
+ accesscache_hashhash,
+ accesscache_hashcmp);
+
+ memcpy(accessor->clips, clips, num_clips * sizeof(MovieClip *));
+ accessor->num_clips = num_clips;
+ accessor->start_frame = start_frame;
+
+ accessor->libmv_accessor =
+ libmv_FrameAccessorNew((libmv_FrameAccessorUserData *) accessor,
+ accessor_get_image_callback,
+ accessor_release_image_callback);
+
+ return accessor;
+}
+
+void tracking_image_accessor_destroy(TrackingImageAccessor *accessor)
+{
+ IMB_moviecache_free(accessor->cache);
+ libmv_FrameAccessorDestroy(accessor->libmv_accessor);
+ MEM_freeN(accessor);
+}
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index 8e3c92314e6..8113e2bf9ef 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -38,8 +38,8 @@
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
-#include "BLI_listbase.h"
#include "BLI_utildefines.h"
+#include "BLI_listbase.h"
#include "BKE_animsys.h"
#include "BKE_global.h"
@@ -49,6 +49,8 @@
#include "BKE_node.h"
#include "BKE_world.h"
+#include "GPU_material.h"
+
void BKE_world_free_ex(World *wrld, bool do_id_user)
{
MTex *mtex;
@@ -69,6 +71,9 @@ void BKE_world_free_ex(World *wrld, bool do_id_user)
MEM_freeN(wrld->nodetree);
}
+ if (wrld->gpumaterial.first)
+ GPU_material_free(&wrld->gpumaterial);
+
BKE_icon_delete((struct ID *)wrld);
wrld->id.icon_id = 0;
}
@@ -134,6 +139,8 @@ World *BKE_world_copy(World *wrld)
if (wrld->preview)
wrldn->preview = BKE_previewimg_copy(wrld->preview);
+ BLI_listbase_clear(&wrldn->gpumaterial);
+
return wrldn;
}
@@ -158,6 +165,8 @@ World *localize_world(World *wrld)
wrldn->preview = NULL;
+ BLI_listbase_clear(&wrldn->gpumaterial);
+
return wrldn;
}
diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c
index aef44993912..8a6a0438b84 100644
--- a/source/blender/blenkernel/intern/writeavi.c
+++ b/source/blender/blenkernel/intern/writeavi.c
@@ -80,7 +80,9 @@ static void filepath_avi(char *string, RenderData *rd);
# include "BKE_writeffmpeg.h"
#endif
-#include "BKE_writeframeserver.h"
+#ifdef WITH_FRAMESERVER
+# include "BKE_writeframeserver.h"
+#endif
bMovieHandle *BKE_movie_handle_get(const char imtype)
{
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index ca21180000d..d4f5da2e36f 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -57,7 +57,6 @@
#include "BKE_sound.h"
#include "BKE_writeffmpeg.h"
-#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "ffmpeg_compat.h"
@@ -484,7 +483,6 @@ static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char
AVDictionary **dictionary)
{
IDProperty *prop;
- void *iter;
IDProperty *curr;
/* TODO(sergey): This is actually rather stupid, because changing
@@ -495,7 +493,7 @@ static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char
*
* For as long we don't allow editing properties in the interface
* it's all good. bug if we allow editing them, we'll need to
- * repace it with some smarter code which would port settings
+ * replace it with some smarter code which would port settings
* from deprecated to new one.
*/
ffmpeg_set_expert_options(rd);
@@ -509,9 +507,7 @@ static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char
return;
}
- iter = IDP_GetGroupIterator(prop);
-
- while ((curr = IDP_GroupIterNext(iter)) != NULL) {
+ for (curr = prop->data.group.first; curr; curr = curr->next) {
if (ffmpeg_proprty_valid(c, prop_name, curr))
set_ffmpeg_property_option(c, curr, dictionary);
}
@@ -696,7 +692,7 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
}
if (codec->sample_fmts) {
- /* check if the prefered sample format for this codec is supported.
+ /* check if the preferred sample format for this codec is supported.
* this is because, depending on the version of libav, and with the whole ffmpeg/libav fork situation,
* you have various implementations around. float samples in particular are not always supported.
*/
diff --git a/source/blender/blenkernel/tracking_private.h b/source/blender/blenkernel/tracking_private.h
index 6efa1533e3e..591ee4d0d01 100644
--- a/source/blender/blenkernel/tracking_private.h
+++ b/source/blender/blenkernel/tracking_private.h
@@ -95,4 +95,32 @@ void tracking_cameraIntrinscisOptionsFromTracking(struct MovieTracking *tracking
void tracking_trackingCameraFromIntrinscisOptions(struct MovieTracking *tracking,
const struct libmv_CameraIntrinsicsOptions *camera_intrinsics_options);
+struct libmv_TrackRegionOptions;
+
+void tracking_configure_tracker(const MovieTrackingTrack *track, float *mask,
+ struct libmv_TrackRegionOptions *options);
+
+struct MovieTrackingMarker *tracking_get_keyframed_marker(
+ struct MovieTrackingTrack *track,
+ int current_frame,
+ bool backwards);
+
+/*********************** Frame accessr *************************/
+
+struct libmv_FrameAccessor;
+
+#define MAX_ACCESSOR_CLIP 64
+typedef struct TrackingImageAccessor {
+ struct MovieCache *cache;
+ struct MovieClip *clips[MAX_ACCESSOR_CLIP];
+ int num_clips;
+ int start_frame;
+ struct libmv_FrameAccessor *libmv_accessor;
+} TrackingImageAccessor;
+
+TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR_CLIP],
+ int num_clips,
+ int start_frame);
+void tracking_image_accessor_destroy(TrackingImageAccessor *accessor);
+
#endif /* __TRACKING_PRIVATE_H__ */