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_addon.h42
-rw-r--r--source/blender/blenkernel/BKE_blender.h2
-rw-r--r--source/blender/blenkernel/BKE_brush.h1
-rw-r--r--source/blender/blenkernel/BKE_constraint.h48
-rw-r--r--source/blender/blenkernel/BKE_deform.h3
-rw-r--r--source/blender/blenkernel/BKE_displist.h2
-rw-r--r--source/blender/blenkernel/BKE_idprop.h2
-rw-r--r--source/blender/blenkernel/BKE_image.h6
-rw-r--r--source/blender/blenkernel/BKE_key.h2
-rw-r--r--source/blender/blenkernel/BKE_mesh.h2
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/BKE_packedFile.h2
-rw-r--r--source/blender/blenkernel/BKE_paint.h8
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h167
-rw-r--r--source/blender/blenkernel/BKE_screen.h18
-rw-r--r--source/blender/blenkernel/BKE_shrinkwrap.h14
-rw-r--r--source/blender/blenkernel/BKE_suggestions.h2
-rw-r--r--source/blender/blenkernel/BKE_text.h1
-rw-r--r--source/blender/blenkernel/CMakeLists.txt6
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c25
-rw-r--r--source/blender/blenkernel/intern/action.c6
-rw-r--r--source/blender/blenkernel/intern/addon.c85
-rw-r--r--source/blender/blenkernel/intern/armature.c17
-rw-r--r--source/blender/blenkernel/intern/blender.c11
-rw-r--r--source/blender/blenkernel/intern/bmfont.c4
-rw-r--r--source/blender/blenkernel/intern/booleanops_mesh.c24
-rw-r--r--source/blender/blenkernel/intern/bpath.c7
-rw-r--r--source/blender/blenkernel/intern/brush.c526
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c36
-rw-r--r--source/blender/blenkernel/intern/cloth.c2
-rw-r--r--source/blender/blenkernel/intern/collision.c6
-rw-r--r--source/blender/blenkernel/intern/constraint.c112
-rw-r--r--source/blender/blenkernel/intern/context.c20
-rw-r--r--source/blender/blenkernel/intern/deform.c70
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c10
-rw-r--r--source/blender/blenkernel/intern/displist.c43
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c8
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c59
-rw-r--r--source/blender/blenkernel/intern/fcurve.c14
-rw-r--r--source/blender/blenkernel/intern/idprop.c7
-rw-r--r--source/blender/blenkernel/intern/image.c133
-rw-r--r--source/blender/blenkernel/intern/key.c11
-rw-r--r--source/blender/blenkernel/intern/lattice.c8
-rw-r--r--source/blender/blenkernel/intern/mask_rasterize.c2
-rw-r--r--source/blender/blenkernel/intern/material.c14
-rw-r--r--source/blender/blenkernel/intern/mesh.c90
-rw-r--r--source/blender/blenkernel/intern/movieclip.c2
-rw-r--r--source/blender/blenkernel/intern/multires.c4
-rw-r--r--source/blender/blenkernel/intern/node.c11
-rw-r--r--source/blender/blenkernel/intern/object.c79
-rw-r--r--source/blender/blenkernel/intern/ocean.c354
-rw-r--r--source/blender/blenkernel/intern/packedFile.c37
-rw-r--r--source/blender/blenkernel/intern/paint.c2
-rw-r--r--source/blender/blenkernel/intern/particle_system.c6
-rw-r--r--source/blender/blenkernel/intern/pbvh.c366
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c1414
-rw-r--r--source/blender/blenkernel/intern/pbvh_intern.h186
-rw-r--r--source/blender/blenkernel/intern/pointcache.c4
-rw-r--r--source/blender/blenkernel/intern/scene.c1
-rw-r--r--source/blender/blenkernel/intern/screen.c1
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c572
-rw-r--r--source/blender/blenkernel/intern/seqmodifier.c20
-rw-r--r--source/blender/blenkernel/intern/sequencer.c135
-rw-r--r--source/blender/blenkernel/intern/smoke.c2
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c15
-rw-r--r--source/blender/blenkernel/intern/suggestions.c8
-rw-r--r--source/blender/blenkernel/intern/text.c15
-rw-r--r--source/blender/blenkernel/intern/texture.c2
68 files changed, 3145 insertions, 1770 deletions
diff --git a/source/blender/blenkernel/BKE_addon.h b/source/blender/blenkernel/BKE_addon.h
new file mode 100644
index 00000000000..eafaec3e605
--- /dev/null
+++ b/source/blender/blenkernel/BKE_addon.h
@@ -0,0 +1,42 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __BKE_ADDON_H__
+#define __BKE_ADDON_H__
+
+#include "RNA_types.h"
+
+typedef struct bAddonPrefType {
+ /* type info */
+ char idname[64]; // best keep the same size as BKE_ST_MAXNAME
+
+ /* RNA integration */
+ ExtensionRNA ext;
+} bAddonPrefType;
+
+bAddonPrefType *BKE_addon_pref_type_find(const char *idname, int quiet);
+void BKE_addon_pref_type_add(bAddonPrefType *apt);
+void BKE_addon_pref_type_remove(bAddonPrefType *apt);
+
+void BKE_addon_pref_type_init(void);
+void BKE_addon_pref_type_free(void);
+
+#endif /* __BKE_ADDON_H__ */
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 11759a82e60..10528f1b270 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -42,7 +42,7 @@ extern "C" {
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
#define BLENDER_VERSION 265
-#define BLENDER_SUBVERSION 3
+#define BLENDER_SUBVERSION 5
/* 262 was the last editmesh release but it has compatibility code for bmesh data */
#define BLENDER_MINVERSION 262
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index cbffb6c0cea..248fe9c8968 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -99,6 +99,7 @@ float BKE_brush_unprojected_radius_get(const struct Scene *scene, struct Brush *
void BKE_brush_unprojected_radius_set(struct Scene *scene, struct Brush *brush, float value);
float BKE_brush_alpha_get(const struct Scene *scene, struct Brush *brush);
+void BKE_brush_alpha_set(Scene *scene, struct Brush *brush, float alpha);
float BKE_brush_weight_get(const Scene *scene, struct Brush *brush);
void BKE_brush_weight_set(const Scene *scene, struct Brush *brush, float value);
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index 79e75127763..c79dc62bb61 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -108,8 +108,8 @@ typedef struct bConstraintTypeInfo {
} bConstraintTypeInfo;
/* Function Prototypes for bConstraintTypeInfo's */
-bConstraintTypeInfo *constraint_get_typeinfo(struct bConstraint *con);
-bConstraintTypeInfo *get_constraint_typeinfo(int type);
+bConstraintTypeInfo *BKE_constraint_get_typeinfo(struct bConstraint *con);
+bConstraintTypeInfo *BKE_get_constraint_typeinfo(int type);
/* ---------------------------------------------------------------------------- */
/* Useful macros for testing various common flag combinations */
@@ -120,38 +120,38 @@ bConstraintTypeInfo *get_constraint_typeinfo(int type);
/* ---------------------------------------------------------------------------- */
/* Constraint function prototypes */
-void unique_constraint_name(struct bConstraint *con, struct ListBase *list);
+void BKE_unique_constraint_name(struct bConstraint *con, struct ListBase *list);
-void free_constraints(struct ListBase *list);
-void copy_constraints(struct ListBase *dst, const struct ListBase *src, int do_extern);
-void relink_constraints(struct ListBase *list);
-void id_loop_constraints(struct ListBase *list, ConstraintIDFunc func, void *userdata);
-void free_constraint_data(struct bConstraint *con);
+void BKE_free_constraints(struct ListBase *list);
+void BKE_copy_constraints(struct ListBase *dst, const struct ListBase *src, int do_extern);
+void BKE_relink_constraints(struct ListBase *list);
+void BKE_id_loop_constraints(struct ListBase *list, ConstraintIDFunc func, void *userdata);
+void BKE_free_constraint_data(struct bConstraint *con);
/* Constraint API function prototypes */
-struct bConstraint *constraints_get_active(struct ListBase *list);
-void constraints_set_active(ListBase *list, struct bConstraint *con);
-struct bConstraint *constraints_findByName(struct ListBase *list, const char *name);
-
-struct bConstraint *add_ob_constraint(struct Object *ob, const char *name, short type);
-struct bConstraint *add_pose_constraint(struct Object *ob, struct bPoseChannel *pchan, const char *name, short type);
+struct bConstraint *BKE_constraints_get_active(struct ListBase *list);
+void BKE_constraints_set_active(ListBase *list, struct bConstraint *con);
+struct bConstraint *BKE_constraints_findByName(struct ListBase *list, const char *name);
+
+struct bConstraint *BKE_add_ob_constraint(struct Object *ob, const char *name, short type);
+struct bConstraint *BKE_add_pose_constraint(struct Object *ob, struct bPoseChannel *pchan, const char *name, short type);
-int remove_constraint(ListBase *list, struct bConstraint *con);
-void remove_constraints_type(ListBase *list, short type, short last_only);
+int BKE_remove_constraint(ListBase *list, struct bConstraint *con);
+void BKE_remove_constraints_type(ListBase *list, short type, short last_only);
/* Constraints + Proxies function prototypes */
-void extract_proxylocal_constraints(struct ListBase *dst, struct ListBase *src);
-short proxylocked_constraints_owner(struct Object *ob, struct bPoseChannel *pchan);
+void BKE_extract_proxylocal_constraints(struct ListBase *dst, struct ListBase *src);
+short BKE_proxylocked_constraints_owner(struct Object *ob, struct bPoseChannel *pchan);
/* Constraint Evaluation function prototypes */
-struct bConstraintOb *constraints_make_evalob(struct Scene *scene, struct Object *ob, void *subdata, short datatype);
-void constraints_clear_evalob(struct bConstraintOb *cob);
+struct bConstraintOb *BKE_constraints_make_evalob(struct Scene *scene, struct Object *ob, void *subdata, short datatype);
+void BKE_constraints_clear_evalob(struct bConstraintOb *cob);
-void constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, float mat[4][4], short from, short to);
+void BKE_constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, float mat[4][4], short from, short to);
-void get_constraint_target_matrix(struct Scene *scene, struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[4][4], float ctime);
-void get_constraint_targets_for_solving(struct bConstraint *con, struct bConstraintOb *ob, struct ListBase *targets, float ctime);
-void solve_constraints(struct ListBase *conlist, struct bConstraintOb *cob, float ctime);
+void BKE_get_constraint_target_matrix(struct Scene *scene, struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[4][4], float ctime);
+void BKE_get_constraint_targets_for_solving(struct bConstraint *con, struct bConstraintOb *ob, struct ListBase *targets, float ctime);
+void BKE_solve_constraints(struct ListBase *conlist, struct bConstraintOb *cob, float ctime);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h
index 8306da71432..ab27421b383 100644
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@ -56,6 +56,9 @@ void defvert_remove_group(struct MDeformVert *dvert, struct
void defvert_clear(struct MDeformVert *dvert);
int defvert_find_shared(const struct MDeformVert *dvert_a, const struct MDeformVert *dvert_b);
+void BKE_defvert_array_free(struct MDeformVert *dvert, int totvert);
+void BKE_defvert_array_copy(struct MDeformVert *dst, const struct MDeformVert *src, int totvert);
+
float defvert_find_weight(const struct MDeformVert *dvert, const int defgroup);
float defvert_array_find_weight_safe(const struct MDeformVert *dvert, const int index, const int defgroup);
diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h
index 758a2a8a2e8..6b986cdceda 100644
--- a/source/blender/blenkernel/BKE_displist.h
+++ b/source/blender/blenkernel/BKE_displist.h
@@ -83,7 +83,7 @@ void BKE_displist_elem_free(DispList *dl);
DispList *BKE_displist_find_or_create(struct ListBase *lb, int type);
DispList *BKE_displist_find(struct ListBase *lb, int type);
void BKE_displist_normals_add(struct ListBase *lb);
-void BKE_displist_count(struct ListBase *lb, int *totvert, int *totface);
+void BKE_displist_count(struct ListBase *lb, int *totvert, int *totface, int *tottri);
void BKE_displist_free(struct ListBase *lb);
int BKE_displist_has_faces(struct ListBase *lb);
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index a9f6a61a655..ad3e4bb2251 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -315,6 +315,8 @@ __attribute__((nonnull))
* the actual struct IDProperty struct either.*/
void IDP_FreeProperty(struct IDProperty *prop);
+void IDP_ClearProperty(IDProperty *prop);
+
/** Unlinks any struct IDProperty<->ID linkage that might be going on.*/
void IDP_UnlinkProperty(struct IDProperty *prop);
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 1f9630d9fce..499609932d1 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -60,8 +60,10 @@ int BKE_imbuf_alpha_test(struct ImBuf *ibuf);
int BKE_imbuf_write_stamp(struct Scene *scene, struct Object *camera, struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf);
int BKE_imbuf_write(struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf);
int BKE_imbuf_write_as(struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf, const short is_copy);
-void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame, const char imtype, const short use_ext, const short use_frames);
-int BKE_add_image_extension(char *string, const char imtype);
+void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame, const struct ImageFormatData *im_format, const short use_ext, const short use_frames);
+void BKE_makepicstring_from_type(char *string, const char *base, const char *relbase, int frame, const char imtype, const short use_ext, const short use_frames);
+int BKE_add_image_extension(char *string, const struct ImageFormatData *im_format);
+int BKE_add_image_extension_from_type(char *string, const char imtype);
char BKE_ftype_to_imtype(const int ftype);
int BKE_imtype_to_ftype(const char imtype);
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index d7d75b4c4c9..a159cbb13d4 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -59,7 +59,7 @@ void key_curve_position_weights(float t, float data[4], int type);
void key_curve_tangent_weights(float t, float data[4], int type);
void key_curve_normal_weights(float t, float data[4], int type);
-float *do_ob_key(struct Scene *scene, struct Object *ob);
+float *BKE_key_evaluate_object(struct Scene *scene, struct Object *ob, int *r_totelem);
struct Key *BKE_key_from_object(struct Object *ob);
struct KeyBlock *BKE_keyblock_from_object(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 320ced67a2f..db9f1228f76 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -162,8 +162,6 @@ void BKE_mesh_from_nurbs(struct Object *ob);
void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase,
int **orco_index_ptr);
void BKE_mesh_from_curve(struct Scene *scene, struct Object *ob);
-void free_dverts(struct MDeformVert *dvert, int totvert);
-void copy_dverts(struct MDeformVert *dst, const struct MDeformVert *src, int totvert);
void BKE_mesh_delete_material_index(struct Mesh *me, short index);
void BKE_mesh_smooth_flag_set(struct Object *meshOb, int enableSmooth);
void BKE_mesh_convert_mfaces_to_mpolys(struct Mesh *mesh);
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index b8f168cbdea..0a2f757b38e 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -557,6 +557,7 @@ struct ShadeResult;
#define SH_NODE_BSDF_REFRACTION 173
#define SH_NODE_TANGENT 174
#define SH_NODE_NORMAL_MAP 175
+#define SH_NODE_HAIR_INFO 176
/* custom defines options for Material node */
#define SH_NODE_MAT_DIFF 1
diff --git a/source/blender/blenkernel/BKE_packedFile.h b/source/blender/blenkernel/BKE_packedFile.h
index 603cb1f22a6..9dcbb41c7dc 100644
--- a/source/blender/blenkernel/BKE_packedFile.h
+++ b/source/blender/blenkernel/BKE_packedFile.h
@@ -48,6 +48,7 @@ struct PackedFile *newPackedFile(struct ReportList *reports, const char *filenam
struct PackedFile *newPackedFileMemory(void *mem, int memlen);
void packAll(struct Main *bmain, struct ReportList *reports);
+void packLibraries(struct Main *bmain, struct ReportList *reports);
/* unpack */
char *unpackFile(struct ReportList *reports, const char *abs_name, const char *local_name, struct PackedFile *pf, int how);
@@ -55,6 +56,7 @@ int unpackVFont(struct ReportList *reports, struct VFont *vfont, int how);
int unpackSound(struct Main *bmain, struct ReportList *reports, struct bSound *sound, int how);
int unpackImage(struct ReportList *reports, struct Image *ima, int how);
void unpackAll(struct Main *bmain, struct ReportList *reports, int how);
+int unpackLibraries(struct Main *bmain, struct ReportList *reports);
int writePackedFile(struct ReportList *reports, const char *filename, struct PackedFile *pf, int guimode);
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index c452c177143..0a4a7f75e25 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -33,6 +33,7 @@
*/
struct bContext;
+struct BMesh;
struct Brush;
struct MDisps;
struct MeshElemMap;
@@ -92,6 +93,12 @@ typedef struct SculptSession {
/* Mesh connectivity */
const struct MeshElemMap *pmap;
+ /* BMesh for dynamic topology sculpting */
+ struct BMesh *bm;
+ int bm_smooth_shading;
+ /* Undo/redo log for dynamic topology sculpting */
+ struct BMLog *bm_log;
+
/* PBVH acceleration structure */
struct PBVH *pbvh;
int show_diffuse_color;
@@ -121,5 +128,6 @@ typedef struct SculptSession {
void free_sculptsession(struct Object *ob);
void free_sculptsession_deformMats(struct SculptSession *ss);
+void sculptsession_bm_to_me(struct Object *ob, int reorder);
#endif
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 302de593963..709db7e4570 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -18,8 +18,8 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#ifndef __BLI_PBVH_H__
-#define __BLI_PBVH_H__
+#ifndef __BKE_PBVH_H__
+#define __BKE_PBVH_H__
/** \file BKE_pbvh.h
* \ingroup bke
@@ -27,13 +27,18 @@
*/
#include "BLI_bitmap.h"
+#include "BLI_ghash.h"
+#include "BLI_utildefines.h"
+
+/* Needed for BMesh functions used in the PBVH iterator macro */
+#include "bmesh.h"
struct CCGElem;
struct CCGKey;
struct CustomData;
struct DMFlagMat;
struct DMGridAdjacency;
-struct ListBase;
+struct GHash;
struct MFace;
struct MVert;
struct PBVH;
@@ -49,32 +54,35 @@ typedef struct {
/* Callbacks */
/* returns 1 if the search should continue from this node, 0 otherwise */
-typedef int (*BLI_pbvh_SearchCallback)(PBVHNode *node, void *data);
+typedef int (*BKE_pbvh_SearchCallback)(PBVHNode *node, void *data);
-typedef void (*BLI_pbvh_HitCallback)(PBVHNode *node, void *data);
-typedef void (*BLI_pbvh_HitOccludedCallback)(PBVHNode *node, void *data, float *tmin);
+typedef void (*BKE_pbvh_HitCallback)(PBVHNode *node, void *data);
+typedef void (*BKE_pbvh_HitOccludedCallback)(PBVHNode *node, void *data, float *tmin);
/* Building */
-PBVH *BLI_pbvh_new(void);
-void BLI_pbvh_build_mesh(PBVH *bvh, struct MFace *faces, struct MVert *verts,
+PBVH *BKE_pbvh_new(void);
+void BKE_pbvh_build_mesh(PBVH *bvh, struct MFace *faces, struct MVert *verts,
int totface, int totvert, struct CustomData *vdata);
-void BLI_pbvh_build_grids(PBVH *bvh, struct CCGElem **grid_elems,
+void BKE_pbvh_build_grids(PBVH *bvh, struct CCGElem **grid_elems,
struct DMGridAdjacency *gridadj, int totgrid,
struct CCGKey *key, void **gridfaces, struct DMFlagMat *flagmats,
unsigned int **grid_hidden);
-void BLI_pbvh_free(PBVH *bvh);
+void BKE_pbvh_build_bmesh(PBVH *bvh, struct BMesh *bm, int smooth_shading,
+ struct BMLog *log);
+
+void BKE_pbvh_free(PBVH *bvh);
/* Hierarchical Search in the BVH, two methods:
* - for each hit calling a callback
* - gather nodes in an array (easy to multithread) */
-void BLI_pbvh_search_callback(PBVH *bvh,
- BLI_pbvh_SearchCallback scb, void *search_data,
- BLI_pbvh_HitCallback hcb, void *hit_data);
+void BKE_pbvh_search_callback(PBVH *bvh,
+ BKE_pbvh_SearchCallback scb, void *search_data,
+ BKE_pbvh_HitCallback hcb, void *hit_data);
-void BLI_pbvh_search_gather(PBVH *bvh,
- BLI_pbvh_SearchCallback scb, void *search_data,
+void BKE_pbvh_search_gather(PBVH *bvh,
+ BKE_pbvh_SearchCallback scb, void *search_data,
PBVHNode ***array, int *tot);
/* Raycast
@@ -82,33 +90,45 @@ void BLI_pbvh_search_gather(PBVH *bvh,
* it's up to the callback to find the primitive within the leaves that is
* hit first */
-void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data,
+void BKE_pbvh_raycast(PBVH *bvh, BKE_pbvh_HitOccludedCallback cb, void *data,
const float ray_start[3], const float ray_normal[3],
int original);
-int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
+int BKE_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], int use_origco,
const float ray_start[3], const float ray_normal[3],
float *dist);
/* Drawing */
-void BLI_pbvh_node_draw(PBVHNode *node, void *data);
-void BLI_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
- int (*setMaterial)(int, void *attribs));
+void BKE_pbvh_node_draw(PBVHNode *node, void *data);
+void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
+ int (*setMaterial)(int, void *attribs), int wireframe);
/* PBVH Access */
typedef enum {
PBVH_FACES,
PBVH_GRIDS,
+ PBVH_BMESH
} PBVHType;
-PBVHType BLI_pbvh_type(const PBVH *bvh);
+PBVHType BKE_pbvh_type(const PBVH *bvh);
/* multires hidden data, only valid for type == PBVH_GRIDS */
-unsigned int **BLI_pbvh_grid_hidden(const PBVH *bvh);
+unsigned int **BKE_pbvh_grid_hidden(const PBVH *bvh);
/* multires level, only valid for type == PBVH_GRIDS */
-void BLI_pbvh_get_grid_key(const PBVH *pbvh, struct CCGKey *key);
+void BKE_pbvh_get_grid_key(const PBVH *pbvh, struct CCGKey *key);
+
+/* Only valid for type == PBVH_BMESH */
+BMesh *BKE_pbvh_get_bmesh(PBVH *pbvh);
+void BKE_pbvh_bmesh_detail_size_set(PBVH *pbvh, float detail_size);
+
+typedef enum {
+ PBVH_Subdivide = 1,
+ PBVH_Collapse = 2,
+} PBVHTopologyUpdateMode;
+int BKE_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode,
+ const float center[3], float radius);
/* Node Access */
@@ -122,45 +142,60 @@ typedef enum {
PBVH_UpdateRedraw = 32,
PBVH_RebuildDrawBuffers = 64,
- PBVH_FullyHidden = 128
+ PBVH_FullyHidden = 128,
+
+ PBVH_UpdateTopology = 256,
} PBVHNodeFlags;
-void BLI_pbvh_node_mark_update(PBVHNode *node);
-void BLI_pbvh_node_mark_rebuild_draw(PBVHNode *node);
-void BLI_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden);
+void BKE_pbvh_node_mark_update(PBVHNode *node);
+void BKE_pbvh_node_mark_rebuild_draw(PBVHNode *node);
+void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden);
+void BKE_pbvh_node_mark_topology_update(PBVHNode *node);
-void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node,
+void BKE_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node,
int **grid_indices, int *totgrid, int *maxgrid, int *gridsize,
struct CCGElem ***grid_elems, struct DMGridAdjacency **gridadj);
-void BLI_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node,
+void BKE_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node,
int *uniquevert, int *totvert);
-void BLI_pbvh_node_get_verts(PBVH *bvh, PBVHNode *node,
+void BKE_pbvh_node_get_verts(PBVH *bvh, PBVHNode *node,
int **vert_indices, struct MVert **verts);
-void BLI_pbvh_node_get_BB(PBVHNode * node, float bb_min[3], float bb_max[3]);
-void BLI_pbvh_node_get_original_BB(PBVHNode * node, float bb_min[3], float bb_max[3]);
+void BKE_pbvh_node_get_BB(PBVHNode * node, float bb_min[3], float bb_max[3]);
+void BKE_pbvh_node_get_original_BB(PBVHNode * node, float bb_min[3], float bb_max[3]);
-float BLI_pbvh_node_get_tmin(PBVHNode *node);
+float BKE_pbvh_node_get_tmin(PBVHNode *node);
/* test if AABB is at least partially inside the planes' volume */
-int BLI_pbvh_node_planes_contain_AABB(PBVHNode *node, void *data);
+int BKE_pbvh_node_planes_contain_AABB(PBVHNode *node, void *data);
/* test if AABB is at least partially outside the planes' volume */
-int BLI_pbvh_node_planes_exclude_AABB(PBVHNode *node, void *data);
+int BKE_pbvh_node_planes_exclude_AABB(PBVHNode *node, void *data);
+
+struct GHash *BKE_pbvh_bmesh_node_unique_verts(PBVHNode *node);
+struct GHash *BKE_pbvh_bmesh_node_other_verts(PBVHNode *node);
+void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node);
+void BKE_pbvh_bmesh_after_stroke(PBVH *bvh);
/* Update Normals/Bounding Box/Draw Buffers/Redraw and clear flags */
-void BLI_pbvh_update(PBVH *bvh, int flags, float (*face_nors)[3]);
-void BLI_pbvh_redraw_BB(PBVH * bvh, float bb_min[3], float bb_max[3]);
-void BLI_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface);
-void BLI_pbvh_grids_update(PBVH *bvh, struct CCGElem **grid_elems,
+void BKE_pbvh_update(PBVH *bvh, int flags, float (*face_nors)[3]);
+void BKE_pbvh_redraw_BB(PBVH * bvh, float bb_min[3], float bb_max[3]);
+void BKE_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface);
+void BKE_pbvh_grids_update(PBVH *bvh, struct CCGElem **grid_elems,
struct DMGridAdjacency *gridadj, void **gridfaces,
struct DMFlagMat *flagmats, unsigned int **grid_hidden);
-/* vertex deformer */
-float (*BLI_pbvh_get_vertCos(struct PBVH *pbvh))[3];
-void BLI_pbvh_apply_vertCos(struct PBVH *pbvh, float (*vertCos)[3]);
-int BLI_pbvh_isDeformed(struct PBVH *pbvh);
+/* Layer displacement */
+
+/* Get the node's displacement layer, creating it if necessary */
+float *BKE_pbvh_node_layer_disp_get(PBVH *pbvh, PBVHNode *node);
+/* If the node has a displacement layer, free it and set to null */
+void BKE_pbvh_node_layer_disp_free(PBVHNode *node);
+
+/* vertex deformer */
+float (*BKE_pbvh_get_vertCos(struct PBVH *pbvh))[3];
+void BKE_pbvh_apply_vertCos(struct PBVH *pbvh, float (*vertCos)[3]);
+int BKE_pbvh_isDeformed(struct PBVH *pbvh);
/* Vertex Iterator */
@@ -197,9 +232,15 @@ typedef struct PBVHVertexIter {
int *vert_indices;
float *vmask;
+ /* bmesh */
+ struct GHashIterator bm_unique_verts;
+ struct GHashIterator bm_other_verts;
+ struct CustomData *bm_vdata;
+
/* result: these are all computed in the macro, but we assume
* that compiler optimization's will skip the ones we don't use */
struct MVert *mvert;
+ struct BMVert *bm_vert;
float *co;
short *no;
float *fno;
@@ -213,7 +254,7 @@ typedef struct PBVHVertexIter {
void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
PBVHVertexIter *vi, int mode);
-#define BLI_pbvh_vertex_iter_begin(bvh, node, vi, mode) \
+#define BKE_pbvh_vertex_iter_begin(bvh, node, vi, mode) \
pbvh_vertex_iter_init(bvh, node, &vi, mode); \
\
for (vi.i = 0, vi.g = 0; vi.g < vi.totgrid; vi.g++) { \
@@ -241,7 +282,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
continue; \
} \
} \
- else { \
+ else if (vi.mverts) { \
vi.mvert = &vi.mverts[vi.vert_indices[vi.gx]]; \
if (mode == PBVH_ITER_UNIQUE && vi.mvert->flag & ME_HIDE) \
continue; \
@@ -250,21 +291,39 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
if (vi.vmask) \
vi.mask = &vi.vmask[vi.vert_indices[vi.gx]]; \
} \
-
-#define BLI_pbvh_vertex_iter_end \
+ else { \
+ if (!BLI_ghashIterator_isDone(&vi.bm_unique_verts)) {\
+ vi.bm_vert = BLI_ghashIterator_getKey(&vi.bm_unique_verts); \
+ BLI_ghashIterator_step(&vi.bm_unique_verts); \
+ } \
+ else { \
+ vi.bm_vert = BLI_ghashIterator_getKey(&vi.bm_other_verts); \
+ BLI_ghashIterator_step(&vi.bm_other_verts); \
+ } \
+ if (mode == PBVH_ITER_UNIQUE && \
+ BM_elem_flag_test(vi.bm_vert, BM_ELEM_HIDDEN)) \
+ continue; \
+ vi.co = vi.bm_vert->co; \
+ vi.fno = vi.bm_vert->no; \
+ vi.mask = CustomData_bmesh_get(vi.bm_vdata, \
+ vi.bm_vert->head.data, \
+ CD_PAINT_MASK); \
+ }
+
+#define BKE_pbvh_vertex_iter_end \
} \
} \
}
-void BLI_pbvh_node_get_proxies(PBVHNode *node, PBVHProxyNode **proxies, int *proxy_count);
-void BLI_pbvh_node_free_proxies(PBVHNode *node);
-PBVHProxyNode *BLI_pbvh_node_add_proxy(PBVH *bvh, PBVHNode *node);
-void BLI_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***nodes, int *totnode);
+void BKE_pbvh_node_get_proxies(PBVHNode *node, PBVHProxyNode **proxies, int *proxy_count);
+void BKE_pbvh_node_free_proxies(PBVHNode *node);
+PBVHProxyNode *BKE_pbvh_node_add_proxy(PBVH *bvh, PBVHNode *node);
+void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***nodes, int *totnode);
-//void BLI_pbvh_node_BB_reset(PBVHNode *node);
-//void BLI_pbvh_node_BB_expand(PBVHNode *node, float co[3]);
+//void BKE_pbvh_node_BB_reset(PBVHNode *node);
+//void BKE_pbvh_node_BB_expand(PBVHNode *node, float co[3]);
void pbvh_show_diffuse_color_set(PBVH *bvh, int show_diffuse_color);
-#endif /* __BLI_PBVH_H__ */
+#endif /* __BKE_PBVH_H__ */
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 8aa08beec57..3c6f886b59a 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -46,6 +46,7 @@ struct bContext;
struct bContextDataResult;
struct bScreen;
struct uiLayout;
+struct uiList;
struct uiMenuItem;
struct wmKeyConfig;
struct wmNotifier;
@@ -181,6 +182,23 @@ typedef struct PanelType {
ExtensionRNA ext;
} PanelType;
+/* uilist types */
+
+/* draw an item in the uiList */
+typedef void (*uiListDrawItemFunc)(struct uiList *, struct bContext *, struct uiLayout *, struct PointerRNA *,
+ struct PointerRNA *, int, struct PointerRNA *, const char *, int);
+
+typedef struct uiListType {
+ struct uiListType *next, *prev;
+
+ char idname[BKE_ST_MAXNAME]; /* unique name */
+
+ uiListDrawItemFunc draw_item;
+
+ /* RNA integration */
+ ExtensionRNA ext;
+} uiListType;
+
/* header types */
typedef struct HeaderType {
diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h
index d1332ba937e..61d82e6c604 100644
--- a/source/blender/blenkernel/BKE_shrinkwrap.h
+++ b/source/blender/blenkernel/BKE_shrinkwrap.h
@@ -121,7 +121,8 @@ typedef struct ShrinkwrapCalcData {
} ShrinkwrapCalcData;
-void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts);
+void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Object *ob, struct DerivedMesh *dm,
+ float (*vertexCos)[3], int numVerts);
/*
* This function casts a ray in the given BVHTree.. but it takes into consideration the space_transform, that is:
@@ -130,9 +131,12 @@ void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Object
* then the input (vert, dir, BVHTreeRayHit) must be defined in ob1 coordinates space
* and the BVHTree must be built in ob2 coordinate space.
*
- * Thus it provides an easy way to cast the same ray across several trees (where each tree was built on its own coords space)
+ * Thus it provides an easy way to cast the same ray across several trees
+ * (where each tree was built on its own coords space)
*/
-int normal_projection_project_vertex(char options, const float *vert, const float *dir, const SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata);
+int normal_projection_project_vertex(char options, const float vert[3], const float dir[3],
+ const SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit,
+ BVHTree_RayCastCallback callback, void *userdata);
/*
* NULL initializers to local data
@@ -142,6 +146,4 @@ int normal_projection_project_vertex(char options, const float *vert, const floa
#define NULL_BVHTreeRayHit {NULL, }
#define NULL_BVHTreeNearest {0, }
-
-#endif
-
+#endif /* __BKE_SHRINKWRAP_H__ */
diff --git a/source/blender/blenkernel/BKE_suggestions.h b/source/blender/blenkernel/BKE_suggestions.h
index 9b61d9141fb..c36a2d61968 100644
--- a/source/blender/blenkernel/BKE_suggestions.h
+++ b/source/blender/blenkernel/BKE_suggestions.h
@@ -75,7 +75,7 @@ short texttool_text_is_active(Text *text);
/* Suggestions */
void texttool_suggest_add(const char *name, char type);
-void texttool_suggest_prefix(const char *prefix);
+void texttool_suggest_prefix(const char *prefix, const int prefix_len);
void texttool_suggest_clear(void);
SuggItem *texttool_suggest_first(void);
SuggItem *texttool_suggest_last(void);
diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h
index accac8694a9..1e3dd426efa 100644
--- a/source/blender/blenkernel/BKE_text.h
+++ b/source/blender/blenkernel/BKE_text.h
@@ -106,6 +106,7 @@ int text_check_delim(const char ch);
int text_check_digit(const char ch);
int text_check_identifier(const char ch);
int text_check_whitespace(const char ch);
+int text_find_identifier_start(const char *str, int i);
enum {
TXT_MOVE_LINE_UP = -1,
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 7a11bdb1f39..23f23acad6b 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -58,6 +58,7 @@ set(SRC
intern/CCGSubSurf.c
intern/DerivedMesh.c
intern/action.c
+ intern/addon.c
intern/anim.c
intern/anim_sys.c
intern/armature.c
@@ -123,6 +124,7 @@ set(SRC
intern/particle.c
intern/particle_system.c
intern/pbvh.c
+ intern/pbvh_bmesh.c
intern/pointcache.c
intern/property.c
intern/report.c
@@ -152,6 +154,7 @@ set(SRC
BKE_DerivedMesh.h
BKE_action.h
+ BKE_addon.h
BKE_anim.h
BKE_animsys.h
BKE_armature.h
@@ -242,6 +245,7 @@ set(SRC
depsgraph_private.h
nla_private.h
intern/CCGSubSurf.h
+ intern/pbvh_intern.h
)
add_definitions(-DGLEW_STATIC)
@@ -255,7 +259,7 @@ endif()
if(WITH_BULLET)
list(APPEND INC_SYS
- ../../../extern/bullet2/src
+ ${BULLET_INCLUDE_DIRS}
)
add_definitions(-DUSE_BULLET)
endif()
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 2dc01513149..ec8d37e1ae3 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1340,6 +1340,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
int has_multires = mmd != NULL, multires_applied = 0;
int sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt;
+ int sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm);
const int draw_flag = ((scene->toolsettings->multipaint ? CALC_WP_MULTIPAINT : 0) |
(scene->toolsettings->auto_normalize ? CALC_WP_AUTO_NORMALIZE : 0));
@@ -1407,7 +1408,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
if (!modifier_isEnabled(scene, md, required_mode)) continue;
if (useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue;
- if (mti->type == eModifierTypeType_OnlyDeform) {
+ if (mti->type == eModifierTypeType_OnlyDeform && !sculpt_dyntopo) {
if (!deformedVerts)
deformedVerts = mesh_getVertexCos(me, &numVerts);
@@ -1465,9 +1466,14 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
modifier_setError(md, "Modifier requires original data, bad stack position");
continue;
}
- if (sculpt_mode && (!has_multires || multires_applied)) {
+ if (sculpt_mode &&
+ (!has_multires || multires_applied || ob->sculpt->bm))
+ {
int unsupported = 0;
+ if (sculpt_dyntopo)
+ unsupported = TRUE;
+
if (scene->toolsettings->sculpt->flags & SCULPT_ONLY_DEFORM)
unsupported |= mti->type != eModifierTypeType_OnlyDeform;
@@ -2310,20 +2316,19 @@ DerivedMesh *editbmesh_get_derived_base(Object *obedit, BMEditMesh *em)
static void make_vertexcosnos__mapFunc(void *userData, int index, const float co[3],
const float no_f[3], const short no_s[3])
{
- float *vec = userData;
-
- vec += 6 * index;
+ DMCoNo *co_no = &((DMCoNo *)userData)[index];
/* check if we've been here before (normal should not be 0) */
- if (vec[3] || vec[4] || vec[5]) return;
+ if (!is_zero_v3(co_no->no)) {
+ return;
+ }
- copy_v3_v3(vec, co);
- vec += 3;
+ copy_v3_v3(co_no->co, co);
if (no_f) {
- copy_v3_v3(vec, no_f);
+ copy_v3_v3(co_no->no, no_f);
}
else {
- normal_short_to_float_v3(vec, no_s);
+ normal_short_to_float_v3(co_no->no, no_s);
}
}
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 83d1538ecbe..63e12dfb99d 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -543,7 +543,7 @@ void BKE_pose_copy_data(bPose **dst, bPose *src, int copycon)
for (pchan = outPose->chanbase.first; pchan; pchan = pchan->next) {
/* TODO: rename this argument... */
if (copycon) {
- copy_constraints(&listb, &pchan->constraints, TRUE); // copy_constraints NULLs listb
+ BKE_copy_constraints(&listb, &pchan->constraints, TRUE); // BKE_copy_constraints NULLs listb
pchan->constraints = listb;
pchan->mpath = NULL; /* motion paths should not get copied yet... */
}
@@ -621,7 +621,7 @@ void BKE_pose_channel_free(bPoseChannel *pchan)
pchan->mpath = NULL;
}
- free_constraints(&pchan->constraints);
+ BKE_free_constraints(&pchan->constraints);
if (pchan->prop) {
IDP_FreeProperty(pchan->prop);
@@ -711,7 +711,7 @@ void BKE_pose_channel_copy_data(bPoseChannel *pchan, const bPoseChannel *pchan_f
pchan->iklinweight = pchan_from->iklinweight;
/* constraints */
- copy_constraints(&pchan->constraints, &pchan_from->constraints, TRUE);
+ BKE_copy_constraints(&pchan->constraints, &pchan_from->constraints, TRUE);
/* id-properties */
if (pchan->prop) {
diff --git a/source/blender/blenkernel/intern/addon.c b/source/blender/blenkernel/intern/addon.c
new file mode 100644
index 00000000000..7f475cd4732
--- /dev/null
+++ b/source/blender/blenkernel/intern/addon.c
@@ -0,0 +1,85 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#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;
+
+
+bAddonPrefType *BKE_addon_pref_type_find(const char *idname, int quiet)
+{
+ if (idname[0]) {
+ bAddonPrefType *apt;
+
+ apt = BLI_ghash_lookup(global_addonpreftype_hash, idname);
+ if (apt) {
+ return apt;
+ }
+
+ if (!quiet) {
+ printf("search for unknown addon-pref '%s'\n", idname);
+ }
+ }
+ else {
+ if (!quiet) {
+ printf("search for empty addon-pref");
+ }
+ }
+
+ return NULL;
+}
+
+void BKE_addon_pref_type_add(bAddonPrefType *apt)
+{
+ BLI_ghash_insert(global_addonpreftype_hash, (void *)apt->idname, apt);
+}
+
+void BKE_addon_pref_type_remove(bAddonPrefType *apt)
+{
+ BLI_ghash_remove(global_addonpreftype_hash, (void *)apt->idname, NULL, (GHashValFreeFP)MEM_freeN);
+}
+
+void BKE_addon_pref_type_init(void)
+{
+ BLI_assert(global_addonpreftype_hash == NULL);
+ global_addonpreftype_hash = BLI_ghash_str_new(__func__);
+}
+
+void BKE_addon_pref_type_free(void)
+{
+ BLI_ghash_free(global_addonpreftype_hash, NULL, (GHashValFreeFP)MEM_freeN);
+ global_addonpreftype_hash = NULL;
+}
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 9155d67dc36..ad14dee168a 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1620,15 +1620,16 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
* 2. copy proxy-pchan's constraints on-to new
* 3. add extracted local constraints back on top
*
- * Note for copy_constraints: when copying constraints, disable 'do_extern' otherwise
- * we get the libs direct linked in this blend. */
- extract_proxylocal_constraints(&proxylocal_constraints, &pchan->constraints);
- copy_constraints(&pchanw.constraints, &pchanp->constraints, FALSE);
+ * Note for BKE_copy_constraints: when copying constraints, disable 'do_extern' otherwise
+ * we get the libs direct linked in this blend.
+ */
+ BKE_extract_proxylocal_constraints(&proxylocal_constraints, &pchan->constraints);
+ BKE_copy_constraints(&pchanw.constraints, &pchanp->constraints, FALSE);
BLI_movelisttolist(&pchanw.constraints, &proxylocal_constraints);
/* constraints - set target ob pointer to own object */
for (con = pchanw.constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -2426,15 +2427,15 @@ void BKE_pose_where_is_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float
/* prepare PoseChannel for Constraint solving
* - makes a copy of matrix, and creates temporary struct to use
*/
- cob = constraints_make_evalob(scene, ob, pchan, CONSTRAINT_OBTYPE_BONE);
+ cob = BKE_constraints_make_evalob(scene, ob, pchan, CONSTRAINT_OBTYPE_BONE);
/* Solve PoseChannel's Constraints */
- solve_constraints(&pchan->constraints, cob, ctime); /* ctime doesnt alter objects */
+ BKE_solve_constraints(&pchan->constraints, cob, ctime); /* ctime doesnt alter objects */
/* cleanup after Constraint Solving
* - applies matrix back to pchan, and frees temporary struct used
*/
- constraints_clear_evalob(cob);
+ BKE_constraints_clear_evalob(cob);
/* prevent constraints breaking a chain */
if (pchan->bone->flag & BONE_CONNECTED) {
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 5c0856bc95b..11ae242023c 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -387,6 +387,7 @@ void BKE_userdef_free(void)
wmKeyMap *km;
wmKeyMapItem *kmi;
wmKeyMapDiffItem *kmdi;
+ bAddon *addon, *addon_next;
for (km = U.user_keymaps.first; km; km = km->next) {
for (kmdi = km->diff_items.first; kmdi; kmdi = kmdi->next) {
@@ -407,11 +408,19 @@ void BKE_userdef_free(void)
BLI_freelistN(&km->items);
}
+ for (addon = U.addons.first; addon; addon = addon_next) {
+ addon_next = addon->next;
+ if (addon->prop) {
+ IDP_FreeProperty(addon->prop);
+ MEM_freeN(addon->prop);
+ }
+ MEM_freeN(addon);
+ }
+
BLI_freelistN(&U.uistyles);
BLI_freelistN(&U.uifonts);
BLI_freelistN(&U.themes);
BLI_freelistN(&U.user_keymaps);
- BLI_freelistN(&U.addons);
}
/* handle changes in settings that need recalc */
diff --git a/source/blender/blenkernel/intern/bmfont.c b/source/blender/blenkernel/intern/bmfont.c
index 0495e729937..fc83b24da5b 100644
--- a/source/blender/blenkernel/intern/bmfont.c
+++ b/source/blender/blenkernel/intern/bmfont.c
@@ -65,8 +65,8 @@ void printfGlyph(bmGlyph * glyph)
printf(" advan: %3d reser: %3d\n", glyph->advance, glyph->reserved);
}
-#define MAX2(x,y) ((x) > (y) ? (x) : (y))
-#define MAX3(x,y,z) MAX2(MAX2((x), (y)), (z))
+#define MAX2(x, y) ((x) > (y) ? (x) : (y))
+#define MAX3(x, y, z) (MAX2(MAX2((x), (y)), (z)))
void calcAlpha(ImBuf * ibuf)
{
diff --git a/source/blender/blenkernel/intern/booleanops_mesh.c b/source/blender/blenkernel/intern/booleanops_mesh.c
index 461b945282f..f53a89fccfd 100644
--- a/source/blender/blenkernel/intern/booleanops_mesh.c
+++ b/source/blender/blenkernel/intern/booleanops_mesh.c
@@ -56,7 +56,7 @@ CSG_DestroyBlenderMeshInternals(
CSG_MeshDescriptor *mesh
) {
/* Free face and vertex iterators. */
- FreeMeshDescriptors(&(mesh->m_face_iterator),&(mesh->m_vertex_iterator));
+ FreeMeshDescriptors(&(mesh->m_face_iterator), &(mesh->m_vertex_iterator));
}
@@ -138,7 +138,7 @@ CSG_AddMeshToBlender(
if (mesh == NULL) return 0;
if (mesh->base == NULL) return 0;
- invert_m4_m4(inv_mat,mesh->base->object->obmat);
+ invert_m4_m4(inv_mat, mesh->base->object->obmat);
/* Create a new blender mesh object - using 'base' as
* a template for the new object. */
@@ -191,7 +191,7 @@ CSG_PerformOp(
default : op_type = e_csg_intersection;
}
- output->m_descriptor = CSG_DescibeOperands(bool_op,mesh1->m_descriptor,mesh2->m_descriptor);
+ output->m_descriptor = CSG_DescibeOperands(bool_op, mesh1->m_descriptor, mesh2->m_descriptor);
output->base = mesh1->base;
if (output->m_descriptor.user_face_vertex_data_size) {
@@ -228,8 +228,8 @@ CSG_PerformOp(
/* get the ouput mesh descriptors. */
- CSG_OutputFaceDescriptor(bool_op,&(output->m_face_iterator));
- CSG_OutputVertexDescriptor(bool_op,&(output->m_vertex_iterator));
+ CSG_OutputFaceDescriptor(bool_op, &(output->m_face_iterator));
+ CSG_OutputVertexDescriptor(bool_op, &(output->m_vertex_iterator));
output->m_destroy_func = CSG_DestroyCSGMeshInternals;
return 1;
@@ -242,20 +242,20 @@ NewBooleanMeshTest(
int op_type
) {
- CSG_MeshDescriptor m1,m2,output;
- CSG_MeshDescriptor output2,output3;
+ CSG_MeshDescriptor m1, m2, output;
+ CSG_MeshDescriptor output2, output3;
- if (!MakeCSGMeshFromBlenderBase(base,&m1)) {
+ if (!MakeCSGMeshFromBlenderBase(base, &m1)) {
return 0;
}
- if (!MakeCSGMeshFromBlenderBase(base_select,&m2)) {
+ if (!MakeCSGMeshFromBlenderBase(base_select, &m2)) {
return 0;
}
- CSG_PerformOp(&m1,&m2,1,&output);
- CSG_PerformOp(&m1,&m2,2,&output2);
- CSG_PerformOp(&m1,&m2,3,&output3);
+ CSG_PerformOp(&m1, &m2, 1, &output);
+ CSG_PerformOp(&m1, &m2, 2, &output2);
+ CSG_PerformOp(&m1, &m2, 3, &output3);
if (!CSG_AddMeshToBlender(&output)) {
return 0;
diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c
index 0d44f5cad6f..6db1052d6bd 100644
--- a/source/blender/blenkernel/intern/bpath.c
+++ b/source/blender/blenkernel/intern/bpath.c
@@ -603,8 +603,11 @@ void BKE_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
case ID_LI:
{
Library *lib = (Library *)id;
- if (rewrite_path_fixed(lib->name, visit_cb, absbase, bpath_user_data)) {
- BKE_library_filepath_set(lib, lib->name);
+ /* keep packedfile paths always relative to the blend */
+ if (lib->packedfile == NULL) {
+ if (rewrite_path_fixed(lib->name, visit_cb, absbase, bpath_user_data)) {
+ BKE_library_filepath_set(lib, lib->name);
+ }
}
break;
}
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 405b1efb25d..aeb0407b37f 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -29,29 +29,16 @@
* \ingroup bke
*/
-
-#include <math.h>
-#include <string.h>
-
#include "MEM_guardedalloc.h"
#include "DNA_brush_types.h"
-#include "DNA_color_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
-#include "DNA_userdef_types.h"
-#include "DNA_windowmanager_types.h"
-
-#include "WM_types.h"
-
-#include "RNA_access.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_rand.h"
-#include "BLI_utildefines.h"
-#include "BKE_blender.h"
#include "BKE_brush.h"
#include "BKE_colortools.h"
#include "BKE_global.h"
@@ -66,7 +53,6 @@
#include "IMB_imbuf_types.h"
#include "RE_render_ext.h" /* externtex */
-#include "RE_shader_ext.h"
static void brush_defaults(Brush *brush)
{
@@ -696,7 +682,7 @@ float BKE_brush_unprojected_radius_get(const Scene *scene, Brush *brush)
brush->unprojected_radius;
}
-static void brush_alpha_set(Scene *scene, Brush *brush, float alpha)
+void BKE_brush_alpha_set(Scene *scene, Brush *brush, float alpha)
{
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
@@ -754,315 +740,6 @@ void BKE_brush_scale_size(int *r_brush_size,
(*r_brush_size) = (int)((float)(*r_brush_size) * scale);
}
-/* Brush Painting */
-
-typedef struct BrushPainterCache {
- short enabled;
-
- int size; /* size override, if 0 uses 2*BKE_brush_size_get(brush) */
- short flt; /* need float imbuf? */
- short texonly; /* no alpha, color or fallof, only texture in imbuf */
-
- int lastsize;
- float lastalpha;
- float lastjitter;
-
- ImBuf *ibuf;
- ImBuf *texibuf;
- ImBuf *maskibuf;
-} BrushPainterCache;
-
-struct BrushPainter {
- Scene *scene;
- Brush *brush;
-
- float lastmousepos[2]; /* mouse position of last paint call */
-
- float accumdistance; /* accumulated distance of brush since last paint op */
- float lastpaintpos[2]; /* position of last paint op */
- float startpaintpos[2]; /* position of first paint */
-
- double accumtime; /* accumulated time since last paint op (airbrush) */
- double lasttime; /* time of last update */
-
- float lastpressure;
-
- short firsttouch; /* first paint op */
-
- float startsize;
- float startalpha;
- float startjitter;
- float startspacing;
-
- BrushPainterCache cache;
-};
-
-BrushPainter *BKE_brush_painter_new(Scene *scene, Brush *brush)
-{
- BrushPainter *painter = MEM_callocN(sizeof(BrushPainter), "BrushPainter");
-
- painter->brush = brush;
- painter->scene = scene;
- painter->firsttouch = 1;
- painter->cache.lastsize = -1; /* force ibuf create in refresh */
-
- painter->startsize = BKE_brush_size_get(scene, brush);
- painter->startalpha = BKE_brush_alpha_get(scene, brush);
- painter->startjitter = brush->jitter;
- painter->startspacing = brush->spacing;
-
- return painter;
-}
-
-void BKE_brush_painter_require_imbuf(BrushPainter *painter, short flt, short texonly, int size)
-{
- if ((painter->cache.flt != flt) || (painter->cache.size != size) ||
- ((painter->cache.texonly != texonly) && texonly))
- {
- if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
- if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
- painter->cache.ibuf = painter->cache.maskibuf = NULL;
- painter->cache.lastsize = -1; /* force ibuf create in refresh */
- }
-
- if (painter->cache.flt != flt) {
- if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
- painter->cache.texibuf = NULL;
- painter->cache.lastsize = -1; /* force ibuf create in refresh */
- }
-
- painter->cache.size = size;
- painter->cache.flt = flt;
- painter->cache.texonly = texonly;
- painter->cache.enabled = 1;
-}
-
-void BKE_brush_painter_free(BrushPainter *painter)
-{
- Brush *brush = painter->brush;
-
- BKE_brush_size_set(painter->scene, brush, painter->startsize);
- brush_alpha_set(painter->scene, brush, painter->startalpha);
- brush->jitter = painter->startjitter;
- brush->spacing = painter->startspacing;
-
- if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
- if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
- if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
- MEM_freeN(painter);
-}
-
-static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
- int x, int y, int w, int h, int xt, int yt,
- const float pos[2])
-{
- Scene *scene = painter->scene;
- Brush *brush = painter->brush;
- ImBuf *ibuf, *maskibuf, *texibuf;
- float *bf, *mf, *tf, *otf = NULL, xoff, yoff, xy[2], rgba[4];
- unsigned char *b, *m, *t, *ot = NULL;
- int dotexold, origx = x, origy = y;
- const int radius = BKE_brush_size_get(painter->scene, brush);
-
- xoff = -radius + 0.5f;
- yoff = -radius + 0.5f;
- xoff += (int)pos[0] - (int)painter->startpaintpos[0];
- yoff += (int)pos[1] - (int)painter->startpaintpos[1];
-
- ibuf = painter->cache.ibuf;
- texibuf = painter->cache.texibuf;
- maskibuf = painter->cache.maskibuf;
-
- dotexold = (oldtexibuf != NULL);
-
- /* not sure if it's actually needed or it's a mistake in coords/sizes
- * calculation in brush_painter_fixed_tex_partial_update(), but without this
- * limitation memory gets corrupted at fast strokes with quite big spacing (sergey) */
- w = min_ii(w, ibuf->x);
- h = min_ii(h, ibuf->y);
-
- if (painter->cache.flt) {
- for (; y < h; y++) {
- bf = ibuf->rect_float + (y * ibuf->x + origx) * 4;
- tf = texibuf->rect_float + (y * texibuf->x + origx) * 4;
- mf = maskibuf->rect_float + (y * maskibuf->x + origx) * 4;
-
- if (dotexold)
- otf = oldtexibuf->rect_float + ((y - origy + yt) * oldtexibuf->x + xt) * 4;
-
- for (x = origx; x < w; x++, bf += 4, mf += 4, tf += 4) {
- if (dotexold) {
- copy_v3_v3(tf, otf);
- tf[3] = otf[3];
- otf += 4;
- }
- else {
- xy[0] = x + xoff;
- xy[1] = y + yoff;
-
- BKE_brush_sample_tex(scene, brush, xy, tf, 0);
- }
-
- bf[0] = tf[0] * mf[0];
- bf[1] = tf[1] * mf[1];
- bf[2] = tf[2] * mf[2];
- bf[3] = tf[3] * mf[3];
- }
- }
- }
- else {
- for (; y < h; y++) {
- b = (unsigned char *)ibuf->rect + (y * ibuf->x + origx) * 4;
- t = (unsigned char *)texibuf->rect + (y * texibuf->x + origx) * 4;
- m = (unsigned char *)maskibuf->rect + (y * maskibuf->x + origx) * 4;
-
- if (dotexold)
- ot = (unsigned char *)oldtexibuf->rect + ((y - origy + yt) * oldtexibuf->x + xt) * 4;
-
- for (x = origx; x < w; x++, b += 4, m += 4, t += 4) {
- if (dotexold) {
- t[0] = ot[0];
- t[1] = ot[1];
- t[2] = ot[2];
- t[3] = ot[3];
- ot += 4;
- }
- else {
- xy[0] = x + xoff;
- xy[1] = y + yoff;
-
- BKE_brush_sample_tex(scene, brush, xy, rgba, 0);
- rgba_float_to_uchar(t, rgba);
- }
-
- b[0] = t[0] * m[0] / 255;
- b[1] = t[1] * m[1] / 255;
- b[2] = t[2] * m[2] / 255;
- b[3] = t[3] * m[3] / 255;
- }
- }
- }
-}
-
-static void brush_painter_fixed_tex_partial_update(BrushPainter *painter, const float pos[2])
-{
- const Scene *scene = painter->scene;
- Brush *brush = painter->brush;
- BrushPainterCache *cache = &painter->cache;
- ImBuf *oldtexibuf, *ibuf;
- int imbflag, destx, desty, srcx, srcy, w, h, x1, y1, x2, y2;
- const int diameter = 2 * BKE_brush_size_get(scene, brush);
-
- imbflag = (cache->flt) ? IB_rectfloat : IB_rect;
- if (!cache->ibuf)
- cache->ibuf = IMB_allocImBuf(diameter, diameter, 32, imbflag);
- ibuf = cache->ibuf;
-
- oldtexibuf = cache->texibuf;
- cache->texibuf = IMB_allocImBuf(diameter, diameter, 32, imbflag);
-
- if (oldtexibuf) {
- srcx = srcy = 0;
- destx = (int)painter->lastpaintpos[0] - (int)pos[0];
- desty = (int)painter->lastpaintpos[1] - (int)pos[1];
- w = oldtexibuf->x;
- h = oldtexibuf->y;
-
- IMB_rectclip(cache->texibuf, oldtexibuf, &destx, &desty, &srcx, &srcy, &w, &h);
- }
- else {
- srcx = srcy = 0;
- destx = desty = 0;
- w = h = 0;
- }
-
- x1 = destx;
- y1 = desty;
- x2 = destx + w;
- y2 = desty + h;
-
- /* blend existing texture in new position */
- if ((x1 < x2) && (y1 < y2))
- brush_painter_do_partial(painter, oldtexibuf, x1, y1, x2, y2, srcx, srcy, pos);
-
- if (oldtexibuf)
- IMB_freeImBuf(oldtexibuf);
-
- /* sample texture in new areas */
- if ((0 < x1) && (0 < ibuf->y))
- brush_painter_do_partial(painter, NULL, 0, 0, x1, ibuf->y, 0, 0, pos);
- if ((x2 < ibuf->x) && (0 < ibuf->y))
- brush_painter_do_partial(painter, NULL, x2, 0, ibuf->x, ibuf->y, 0, 0, pos);
- if ((x1 < x2) && (0 < y1))
- brush_painter_do_partial(painter, NULL, x1, 0, x2, y1, 0, 0, pos);
- if ((x1 < x2) && (y2 < ibuf->y))
- brush_painter_do_partial(painter, NULL, x1, y2, x2, ibuf->y, 0, 0, pos);
-}
-
-static void brush_painter_refresh_cache(BrushPainter *painter, const float pos[2], int use_color_correction)
-{
- const Scene *scene = painter->scene;
- Brush *brush = painter->brush;
- BrushPainterCache *cache = &painter->cache;
- MTex *mtex = &brush->mtex;
- int size;
- short flt;
- const int diameter = 2 * BKE_brush_size_get(scene, brush);
- const float alpha = BKE_brush_alpha_get(scene, brush);
-
- if (diameter != cache->lastsize ||
- alpha != cache->lastalpha ||
- brush->jitter != cache->lastjitter)
- {
- if (cache->ibuf) {
- IMB_freeImBuf(cache->ibuf);
- cache->ibuf = NULL;
- }
- if (cache->maskibuf) {
- IMB_freeImBuf(cache->maskibuf);
- cache->maskibuf = NULL;
- }
-
- flt = cache->flt;
- size = (cache->size) ? cache->size : diameter;
-
- if (brush->flag & BRUSH_FIXED_TEX) {
- BKE_brush_imbuf_new(scene, brush, flt, 3, size, &cache->maskibuf, use_color_correction);
- brush_painter_fixed_tex_partial_update(painter, pos);
- }
- else
- BKE_brush_imbuf_new(scene, brush, flt, 2, size, &cache->ibuf, use_color_correction);
-
- cache->lastsize = diameter;
- cache->lastalpha = alpha;
- cache->lastjitter = brush->jitter;
- }
- else if ((brush->flag & BRUSH_FIXED_TEX) && mtex && mtex->tex) {
- int dx = (int)painter->lastpaintpos[0] - (int)pos[0];
- int dy = (int)painter->lastpaintpos[1] - (int)pos[1];
-
- if ((dx != 0) || (dy != 0))
- brush_painter_fixed_tex_partial_update(painter, pos);
- }
-}
-
-void BKE_brush_painter_break_stroke(BrushPainter *painter)
-{
- painter->firsttouch = 1;
-}
-
-static void brush_pressure_apply(BrushPainter *painter, Brush *brush, float pressure)
-{
- if (BKE_brush_use_alpha_pressure(painter->scene, brush))
- brush_alpha_set(painter->scene, brush, max_ff(0.0f, painter->startalpha * pressure));
- if (BKE_brush_use_size_pressure(painter->scene, brush))
- BKE_brush_size_set(painter->scene, brush, max_ff(1.0f, painter->startsize * pressure));
- if (brush->flag & BRUSH_JITTER_PRESSURE)
- brush->jitter = max_ff(0.0f, painter->startjitter * pressure);
- if (brush->flag & BRUSH_SPACING_PRESSURE)
- brush->spacing = max_ff(1.0f, painter->startspacing * (1.5f - pressure));
-}
-
void BKE_brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2], float jitterpos[2])
{
int use_jitter = brush->jitter != 0;
@@ -1090,165 +767,6 @@ void BKE_brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2],
}
}
-int BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, const float pos[2], double time, float pressure,
- void *user, int use_color_correction)
-{
- Scene *scene = painter->scene;
- Brush *brush = painter->brush;
- int totpaintops = 0;
-
- if (pressure == 0.0f) {
- if (painter->lastpressure) // XXX - hack, operator misses
- pressure = painter->lastpressure;
- else
- pressure = 1.0f; /* zero pressure == not using tablet */
- }
- if (painter->firsttouch) {
- /* paint exactly once on first touch */
- painter->startpaintpos[0] = pos[0];
- painter->startpaintpos[1] = pos[1];
-
- brush_pressure_apply(painter, brush, pressure);
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, pos, use_color_correction);
- totpaintops += func(user, painter->cache.ibuf, pos, pos);
-
- painter->lasttime = time;
- painter->firsttouch = 0;
- painter->lastpaintpos[0] = pos[0];
- painter->lastpaintpos[1] = pos[1];
- }
-#if 0
- else if (painter->brush->flag & BRUSH_AIRBRUSH) {
- float spacing, step, paintpos[2], dmousepos[2], len;
- double starttime, curtime = time;
-
- /* compute brush spacing adapted to brush size */
- spacing = brush->rate; //radius*brush->spacing*0.01f;
-
- /* setup starting time, direction vector and accumulated time */
- starttime = painter->accumtime;
- sub_v2_v2v2(dmousepos, pos, painter->lastmousepos);
- len = normalize_v2(dmousepos);
- painter->accumtime += curtime - painter->lasttime;
-
- /* do paint op over unpainted time distance */
- while (painter->accumtime >= spacing) {
- step = (spacing - starttime) * len;
- paintpos[0] = painter->lastmousepos[0] + dmousepos[0] * step;
- paintpos[1] = painter->lastmousepos[1] + dmousepos[1] * step;
-
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter);
- totpaintops += func(user, painter->cache.ibuf,
- painter->lastpaintpos, paintpos);
-
- painter->lastpaintpos[0] = paintpos[0];
- painter->lastpaintpos[1] = paintpos[1];
- painter->accumtime -= spacing;
- starttime -= spacing;
- }
-
- painter->lasttime = curtime;
- }
-#endif
- else {
- float startdistance, spacing, step, paintpos[2], dmousepos[2], finalpos[2];
- float t, len, press;
- const int radius = BKE_brush_size_get(scene, brush);
-
- /* compute brush spacing adapted to brush radius, spacing may depend
- * on pressure, so update it */
- brush_pressure_apply(painter, brush, painter->lastpressure);
- spacing = max_ff(1.0f, radius) * brush->spacing * 0.01f;
-
- /* setup starting distance, direction vector and accumulated distance */
- startdistance = painter->accumdistance;
- sub_v2_v2v2(dmousepos, pos, painter->lastmousepos);
- len = normalize_v2(dmousepos);
- painter->accumdistance += len;
-
- if (brush->flag & BRUSH_SPACE) {
- /* do paint op over unpainted distance */
- while ((len > 0.0f) && (painter->accumdistance >= spacing)) {
- step = spacing - startdistance;
- paintpos[0] = painter->lastmousepos[0] + dmousepos[0] * step;
- paintpos[1] = painter->lastmousepos[1] + dmousepos[1] * step;
-
- t = step / len;
- press = (1.0f - t) * painter->lastpressure + t * pressure;
- brush_pressure_apply(painter, brush, press);
- spacing = max_ff(1.0f, radius) * brush->spacing * 0.01f;
-
- BKE_brush_jitter_pos(scene, brush, paintpos, finalpos);
-
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, finalpos, use_color_correction);
-
- totpaintops +=
- func(user, painter->cache.ibuf, painter->lastpaintpos, finalpos);
-
- painter->lastpaintpos[0] = paintpos[0];
- painter->lastpaintpos[1] = paintpos[1];
- painter->accumdistance -= spacing;
- startdistance -= spacing;
- }
- }
- else {
- BKE_brush_jitter_pos(scene, brush, pos, finalpos);
-
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, finalpos, use_color_correction);
-
- totpaintops += func(user, painter->cache.ibuf, pos, finalpos);
-
- painter->lastpaintpos[0] = pos[0];
- painter->lastpaintpos[1] = pos[1];
- painter->accumdistance = 0;
- }
-
- /* do airbrush paint ops, based on the number of paint ops left over
- * from regular painting. this is a temporary solution until we have
- * accurate time stamps for mouse move events */
- if (brush->flag & BRUSH_AIRBRUSH) {
- double curtime = time;
- double painttime = brush->rate * totpaintops;
-
- painter->accumtime += curtime - painter->lasttime;
- if (painter->accumtime <= painttime)
- painter->accumtime = 0.0;
- else
- painter->accumtime -= painttime;
-
- while (painter->accumtime >= (double)brush->rate) {
- brush_pressure_apply(painter, brush, pressure);
-
- BKE_brush_jitter_pos(scene, brush, pos, finalpos);
-
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, finalpos, use_color_correction);
-
- totpaintops +=
- func(user, painter->cache.ibuf, painter->lastmousepos, finalpos);
- painter->accumtime -= (double)brush->rate;
- }
-
- painter->lasttime = curtime;
- }
- }
-
- painter->lastmousepos[0] = pos[0];
- painter->lastmousepos[1] = pos[1];
- painter->lastpressure = pressure;
-
- brush_alpha_set(scene, brush, painter->startalpha);
- BKE_brush_size_set(scene, brush, painter->startsize);
- brush->jitter = painter->startjitter;
- brush->spacing = painter->startspacing;
-
- return totpaintops;
-}
-
/* Uses the brush curve control to find a strength value between 0 and 1 */
float BKE_brush_curve_strength_clamp(Brush *br, float p, const float len)
{
@@ -1275,48 +793,6 @@ float BKE_brush_curve_strength(Brush *br, float p, const float len)
return curvemapping_evaluateF(br->curve, 0, p);
}
-/* TODO: should probably be unified with BrushPainter stuff? */
-unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side)
-{
- unsigned int *texcache = NULL;
- MTex *mtex = &br->mtex;
- TexResult texres = {0};
- int hasrgb, ix, iy;
- int side = half_side * 2;
-
- if (mtex->tex) {
- float x, y, step = 2.0 / side, co[3];
-
- texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");
-
- /*do normalized cannonical view coords for texture*/
- for (y = -1.0, iy = 0; iy < side; iy++, y += step) {
- for (x = -1.0, ix = 0; ix < side; ix++, x += step) {
- co[0] = x;
- co[1] = y;
- co[2] = 0.0f;
-
- /* This is copied from displace modifier code */
- hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres);
-
- /* if the texture gave an RGB value, we assume it didn't give a valid
- * intensity, so calculate one (formula from do_material_tex).
- * if the texture didn't give an RGB value, copy the intensity across
- */
- if (hasrgb & TEX_RGB)
- texres.tin = rgb_to_grayscale(&texres.tr);
-
- ((char *)texcache)[(iy * side + ix) * 4] =
- ((char *)texcache)[(iy * side + ix) * 4 + 1] =
- ((char *)texcache)[(iy * side + ix) * 4 + 2] =
- ((char *)texcache)[(iy * side + ix) * 4 + 3] = (char)(texres.tin * 255.0f);
- }
- }
- }
-
- return texcache;
-}
-
/**** Radial Control ****/
struct ImBuf *BKE_brush_gen_radial_control_imbuf(Brush *br)
{
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 61d0936d41d..51890851ebc 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -262,6 +262,17 @@ static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
cddm->pbvh_draw = can_pbvh_draw(ob, dm);
}
+ /* Sculpting on a BMesh (dynamic-topology) gets a special PBVH */
+ if (!cddm->pbvh && ob->sculpt->bm) {
+ cddm->pbvh = BKE_pbvh_new();
+ cddm->pbvh_draw = TRUE;
+
+ BKE_pbvh_build_bmesh(cddm->pbvh, ob->sculpt->bm,
+ ob->sculpt->bm_smooth_shading,
+ ob->sculpt->bm_log);
+ }
+
+
/* always build pbvh from original mesh, and only use it for drawing if
* this derivedmesh is just original mesh. it's the multires subsurf dm
* that this is actually for, to support a pbvh on a modified mesh */
@@ -270,14 +281,14 @@ static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
Mesh *me = ob->data;
int deformed = 0;
- cddm->pbvh = BLI_pbvh_new();
+ cddm->pbvh = BKE_pbvh_new();
cddm->pbvh_draw = can_pbvh_draw(ob, dm);
pbvh_show_diffuse_color_set(cddm->pbvh, ob->sculpt->show_diffuse_color);
BKE_mesh_tessface_ensure(me);
- BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
+ BKE_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
me->totface, me->totvert, &me->vdata);
deformed = ss->modifiers_active || me->key;
@@ -290,7 +301,7 @@ static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
totvert = deformdm->getNumVerts(deformdm);
vertCos = MEM_callocN(3 * totvert * sizeof(float), "cdDM_getPBVH vertCos");
deformdm->getVertCos(deformdm, vertCos);
- BLI_pbvh_apply_vertCos(cddm->pbvh, vertCos);
+ BKE_pbvh_apply_vertCos(cddm->pbvh, vertCos);
MEM_freeN(vertCos);
}
}
@@ -310,7 +321,7 @@ static void cdDM_update_normals_from_pbvh(DerivedMesh *dm)
face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
- BLI_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors);
+ BKE_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors);
}
static void cdDM_drawVerts(DerivedMesh *dm)
@@ -414,6 +425,14 @@ static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges
MVert *mvert = cddm->mvert;
MEdge *medge = cddm->medge;
int i;
+
+ if (cddm->pbvh && cddm->pbvh_draw &&
+ BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH)
+ {
+ BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, TRUE);
+
+ return;
+ }
if (GPU_buffer_legacy(dm)) {
DEBUG_VBO("Using legacy code. cdDM_drawEdges\n");
@@ -530,7 +549,8 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
if (dm->numTessFaceData) {
float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL);
- BLI_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors, setMaterial);
+ BKE_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors,
+ setMaterial, FALSE);
glShadeModel(GL_FLAT);
}
@@ -664,8 +684,9 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
}
else {
if (nors) {
- nors += 3; continue;
+ nors += 3;
}
+ continue;
}
}
else if (drawParamsMapped) {
@@ -673,8 +694,9 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
}
else {
if (nors) {
- nors += 3; continue;
+ nors += 3;
}
+ continue;
}
}
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index f1d73c7777a..fdd7dc94979 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -1153,7 +1153,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
if ( !mface[i].v4 )
continue;
- spring = ( ClothSpring *) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
+ spring = (ClothSpring *)MEM_callocN(sizeof(ClothSpring), "cloth spring");
if (!spring) {
cloth_free_errorsprings(cloth, edgehash, edgelist);
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index f0043d9fa77..60bf67e19e3 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -528,7 +528,7 @@ static void add_collision_object(Object ***objs, unsigned int *numobj, unsigned
/* extend array */
if (*numobj >= *maxobj) {
*maxobj *= 2;
- *objs= MEM_reallocN(*objs, sizeof(Object*)*(*maxobj));
+ *objs= MEM_reallocN(*objs, sizeof(Object *)*(*maxobj));
}
(*objs)[*numobj] = ob;
@@ -740,7 +740,7 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData * clmd, float step, flo
/* move object to position (step) in time */
for (i = 0; i < numcollobj; i++) {
Object *collob= collobjs[i];
- CollisionModifierData *collmd = (CollisionModifierData*)modifiers_findByType(collob, eModifierType_Collision);
+ CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType(collob, eModifierType_Collision);
if (!collmd->bvhtree)
continue;
@@ -760,7 +760,7 @@ int cloth_bvh_objcollision(Object *ob, ClothModifierData * clmd, float step, flo
// check all collision objects
for (i = 0; i < numcollobj; i++) {
Object *collob= collobjs[i];
- CollisionModifierData *collmd = (CollisionModifierData*)modifiers_findByType(collob, eModifierType_Collision);
+ CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType(collob, eModifierType_Collision);
BVHTreeOverlap *overlap = NULL;
unsigned int result = 0;
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index c3aab22fe5a..1a25def3829 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -96,7 +96,7 @@
/* -------------- Naming -------------- */
/* Find the first available, non-duplicate name for a given constraint */
-void unique_constraint_name(bConstraint *con, ListBase *list)
+void BKE_unique_constraint_name(bConstraint *con, ListBase *list)
{
BLI_uniquename(list, con, "Const", '.', offsetof(bConstraint, name), sizeof(con->name));
}
@@ -105,7 +105,7 @@ void unique_constraint_name(bConstraint *con, ListBase *list)
/* package an object/bone for use in constraint evaluation */
/* This function MEM_calloc's a bConstraintOb struct, that will need to be freed after evaluation */
-bConstraintOb *constraints_make_evalob(Scene *scene, Object *ob, void *subdata, short datatype)
+bConstraintOb *BKE_constraints_make_evalob(Scene *scene, Object *ob, void *subdata, short datatype)
{
bConstraintOb *cob;
@@ -169,7 +169,7 @@ bConstraintOb *constraints_make_evalob(Scene *scene, Object *ob, void *subdata,
}
/* cleanup after constraint evaluation */
-void constraints_clear_evalob(bConstraintOb *cob)
+void BKE_constraints_clear_evalob(bConstraintOb *cob)
{
float delta[4][4], imat[4][4];
@@ -219,7 +219,7 @@ void constraints_clear_evalob(bConstraintOb *cob)
* of a matrix from one space to another for constraint evaluation.
* For now, this is only implemented for Objects and PoseChannels.
*/
-void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[4][4], short from, short to)
+void BKE_constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[4][4], short from, short to)
{
float diff_mat[4][4];
float imat[4][4];
@@ -242,7 +242,7 @@ void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[4][4
/* use pose-space as stepping stone for other spaces... */
if (ELEM(to, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_PARLOCAL)) {
/* call self with slightly different values */
- constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
}
}
break;
@@ -278,7 +278,7 @@ void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[4][4
/* use pose-space as stepping stone for other spaces */
if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL)) {
/* call self with slightly different values */
- constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
}
}
break;
@@ -293,7 +293,7 @@ void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[4][4
/* use pose-space as stepping stone for other spaces */
if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL)) {
/* call self with slightly different values */
- constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to);
}
}
break;
@@ -499,7 +499,7 @@ static void constraint_target_to_mat4(Object *ob, const char *substring, float m
/* Case OBJECT */
if (!strlen(substring)) {
copy_m4_m4(mat, ob->obmat);
- constraint_mat_convertspace(ob, NULL, mat, from, to);
+ BKE_constraint_mat_convertspace(ob, NULL, mat, from, to);
}
/* Case VERTEXGROUP */
/* Current method just takes the average location of all the points in the
@@ -512,11 +512,11 @@ static void constraint_target_to_mat4(Object *ob, const char *substring, float m
*/
else if (ob->type == OB_MESH) {
contarget_get_mesh_mat(ob, substring, mat);
- constraint_mat_convertspace(ob, NULL, mat, from, to);
+ BKE_constraint_mat_convertspace(ob, NULL, mat, from, to);
}
else if (ob->type == OB_LATTICE) {
contarget_get_lattice_mat(ob, substring, mat);
- constraint_mat_convertspace(ob, NULL, mat, from, to);
+ BKE_constraint_mat_convertspace(ob, NULL, mat, from, to);
}
/* Case BONE */
else {
@@ -549,7 +549,7 @@ static void constraint_target_to_mat4(Object *ob, const char *substring, float m
copy_m4_m4(mat, ob->obmat);
/* convert matrix space as required */
- constraint_mat_convertspace(ob, pchan, mat, from, to);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, from, to);
}
}
@@ -4211,7 +4211,7 @@ static void constraints_init_typeinfo(void)
/* This function should be used for getting the appropriate type-info when only
* a constraint type is known
*/
-bConstraintTypeInfo *get_constraint_typeinfo(int type)
+bConstraintTypeInfo *BKE_get_constraint_typeinfo(int type)
{
/* initialize the type-info list? */
if (CTI_INIT) {
@@ -4236,11 +4236,11 @@ bConstraintTypeInfo *get_constraint_typeinfo(int type)
/* This function should always be used to get the appropriate type-info, as it
* has checks which prevent segfaults in some weird cases.
*/
-bConstraintTypeInfo *constraint_get_typeinfo(bConstraint *con)
+bConstraintTypeInfo *BKE_constraint_get_typeinfo(bConstraint *con)
{
/* only return typeinfo for valid constraints */
if (con)
- return get_constraint_typeinfo(con->type);
+ return BKE_get_constraint_typeinfo(con->type);
else
return NULL;
}
@@ -4252,7 +4252,7 @@ bConstraintTypeInfo *constraint_get_typeinfo(bConstraint *con)
/* ---------- Data Management ------- */
-/* helper function for free_constraint_data() - unlinks references */
+/* helper function for BKE_free_constraint_data() - unlinks references */
static void con_unlink_refs_cb(bConstraint *UNUSED(con), ID **idpoin, short isReference, void *UNUSED(userData))
{
if (*idpoin && isReference)
@@ -4263,10 +4263,10 @@ static void con_unlink_refs_cb(bConstraint *UNUSED(con), ID **idpoin, short isRe
* be sure to run BIK_clear_data() when freeing an IK constraint,
* unless DAG_scene_sort is called.
*/
-void free_constraint_data(bConstraint *con)
+void BKE_free_constraint_data(bConstraint *con)
{
if (con->data) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (cti) {
/* perform any special freeing constraint may have */
@@ -4284,13 +4284,13 @@ void free_constraint_data(bConstraint *con)
}
/* Free all constraints from a constraint-stack */
-void free_constraints(ListBase *list)
+void BKE_free_constraints(ListBase *list)
{
bConstraint *con;
/* Free constraint data and also any extra data */
for (con = list->first; con; con = con->next)
- free_constraint_data(con);
+ BKE_free_constraint_data(con);
/* Free the whole list */
BLI_freelistN(list);
@@ -4298,10 +4298,10 @@ void free_constraints(ListBase *list)
/* Remove the specified constraint from the given constraint stack */
-int remove_constraint(ListBase *list, bConstraint *con)
+int BKE_remove_constraint(ListBase *list, bConstraint *con)
{
if (con) {
- free_constraint_data(con);
+ BKE_free_constraint_data(con);
BLI_freelinkN(list, con);
return 1;
}
@@ -4310,7 +4310,7 @@ int remove_constraint(ListBase *list, bConstraint *con)
}
/* Remove all the constraints of the specified type from the given constraint stack */
-void remove_constraints_type(ListBase *list, short type, short last_only)
+void BKE_remove_constraints_type(ListBase *list, short type, short last_only)
{
bConstraint *con, *conp;
@@ -4322,7 +4322,7 @@ void remove_constraints_type(ListBase *list, short type, short last_only)
conp = con->prev;
if (con->type == type) {
- remove_constraint(list, con);
+ BKE_remove_constraint(list, con);
if (last_only)
return;
}
@@ -4335,7 +4335,7 @@ void remove_constraints_type(ListBase *list, short type, short last_only)
static bConstraint *add_new_constraint_internal(const char *name, short type)
{
bConstraint *con = MEM_callocN(sizeof(bConstraint), "Constraint");
- bConstraintTypeInfo *cti = get_constraint_typeinfo(type);
+ bConstraintTypeInfo *cti = BKE_get_constraint_typeinfo(type);
const char *newName;
/* Set up a generic constraint datablock */
@@ -4385,17 +4385,17 @@ static bConstraint *add_new_constraint(Object *ob, bPoseChannel *pchan, const ch
* (otherwise unique-naming code will fail, since it assumes element exists in list)
*/
BLI_addtail(list, con);
- unique_constraint_name(con, list);
+ BKE_unique_constraint_name(con, list);
/* if the target list is a list on some PoseChannel belonging to a proxy-protected
* Armature layer, we must tag newly added constraints with a flag which allows them
* to persist after proxy syncing has been done
*/
- if (proxylocked_constraints_owner(ob, pchan))
+ if (BKE_proxylocked_constraints_owner(ob, pchan))
con->flag |= CONSTRAINT_PROXY_LOCAL;
/* make this constraint the active one */
- constraints_set_active(list, con);
+ BKE_constraints_set_active(list, con);
}
/* set type+owner specific immutable settings */
@@ -4419,7 +4419,7 @@ static bConstraint *add_new_constraint(Object *ob, bPoseChannel *pchan, const ch
/* ......... */
/* Add new constraint for the given bone */
-bConstraint *add_pose_constraint(Object *ob, bPoseChannel *pchan, const char *name, short type)
+bConstraint *BKE_add_pose_constraint(Object *ob, bPoseChannel *pchan, const char *name, short type)
{
if (pchan == NULL)
return NULL;
@@ -4428,14 +4428,14 @@ bConstraint *add_pose_constraint(Object *ob, bPoseChannel *pchan, const char *na
}
/* Add new constraint for the given object */
-bConstraint *add_ob_constraint(Object *ob, const char *name, short type)
+bConstraint *BKE_add_ob_constraint(Object *ob, const char *name, short type)
{
return add_new_constraint(ob, NULL, name, type);
}
/* ......... */
-/* helper for relink_constraints() - call ID_NEW() on every ID reference the constraint has */
+/* helper for BKE_relink_constraints() - call ID_NEW() on every ID reference the constraint has */
static void con_relink_id_cb(bConstraint *UNUSED(con), ID **idpoin, short UNUSED(isReference), void *UNUSED(userdata))
{
/* ID_NEW() expects a struct with inline "id" member as first
@@ -4449,20 +4449,20 @@ static void con_relink_id_cb(bConstraint *UNUSED(con), ID **idpoin, short UNUSED
}
/* Reassign links that constraints have to other data (called during file loading?) */
-void relink_constraints(ListBase *conlist)
+void BKE_relink_constraints(ListBase *conlist)
{
/* just a wrapper around ID-loop for just calling ID_NEW() on all ID refs */
- id_loop_constraints(conlist, con_relink_id_cb, NULL);
+ BKE_id_loop_constraints(conlist, con_relink_id_cb, NULL);
}
/* Run the given callback on all ID-blocks in list of constraints */
-void id_loop_constraints(ListBase *conlist, ConstraintIDFunc func, void *userdata)
+void BKE_id_loop_constraints(ListBase *conlist, ConstraintIDFunc func, void *userdata)
{
bConstraint *con;
for (con = conlist->first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (cti) {
if (cti->id_looper)
@@ -4473,14 +4473,14 @@ void id_loop_constraints(ListBase *conlist, ConstraintIDFunc func, void *userdat
/* ......... */
-/* helper for copy_constraints(), to be used for making sure that ID's are valid */
+/* helper for BKE_copy_constraints(), to be used for making sure that ID's are valid */
static void con_extern_cb(bConstraint *UNUSED(con), ID **idpoin, short UNUSED(isReference), void *UNUSED(userData))
{
if (*idpoin && (*idpoin)->lib)
id_lib_extern(*idpoin);
}
-/* helper for copy_constraints(), to be used for making sure that usercounts of copied ID's are fixed up */
+/* helper for BKE_copy_constraints(), to be used for making sure that usercounts of copied ID's are fixed up */
static void con_fix_copied_refs_cb(bConstraint *UNUSED(con), ID **idpoin, short isReference, void *UNUSED(userData))
{
/* increment usercount if this is a reference type */
@@ -4489,7 +4489,7 @@ static void con_fix_copied_refs_cb(bConstraint *UNUSED(con), ID **idpoin, short
}
/* duplicate all of the constraints in a constraint stack */
-void copy_constraints(ListBase *dst, const ListBase *src, int do_extern)
+void BKE_copy_constraints(ListBase *dst, const ListBase *src, int do_extern)
{
bConstraint *con, *srccon;
@@ -4497,7 +4497,7 @@ void copy_constraints(ListBase *dst, const ListBase *src, int do_extern)
BLI_duplicatelist(dst, src);
for (con = dst->first, srccon = src->first; con && srccon; srccon = srccon->next, con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
/* make a new copy of the constraint's data */
con->data = MEM_dupallocN(con->data);
@@ -4524,13 +4524,13 @@ void copy_constraints(ListBase *dst, const ListBase *src, int do_extern)
/* ......... */
-bConstraint *constraints_findByName(ListBase *list, const char *name)
+bConstraint *BKE_constraints_findByName(ListBase *list, const char *name)
{
return BLI_findstring(list, name, offsetof(bConstraint, name));
}
/* finds the 'active' constraint in a constraint stack */
-bConstraint *constraints_get_active(ListBase *list)
+bConstraint *BKE_constraints_get_active(ListBase *list)
{
bConstraint *con;
@@ -4547,7 +4547,7 @@ bConstraint *constraints_get_active(ListBase *list)
}
/* Set the given constraint as the active one (clearing all the others) */
-void constraints_set_active(ListBase *list, bConstraint *con)
+void BKE_constraints_set_active(ListBase *list, bConstraint *con)
{
bConstraint *c;
@@ -4564,7 +4564,7 @@ void constraints_set_active(ListBase *list, bConstraint *con)
/* -------- Constraints and Proxies ------- */
/* Rescue all constraints tagged as being CONSTRAINT_PROXY_LOCAL (i.e. added to bone that's proxy-synced in this file) */
-void extract_proxylocal_constraints(ListBase *dst, ListBase *src)
+void BKE_extract_proxylocal_constraints(ListBase *dst, ListBase *src)
{
bConstraint *con, *next;
@@ -4581,7 +4581,7 @@ void extract_proxylocal_constraints(ListBase *dst, ListBase *src)
}
/* Returns if the owner of the constraint is proxy-protected */
-short proxylocked_constraints_owner(Object *ob, bPoseChannel *pchan)
+short BKE_proxylocked_constraints_owner(Object *ob, bPoseChannel *pchan)
{
/* Currently, constraints can only be on object or bone level */
if (ob && ob->proxy) {
@@ -4610,9 +4610,9 @@ short proxylocked_constraints_owner(Object *ob, bPoseChannel *pchan)
* None of the actual calculations of the matrices should be done here! Also, this function is
* not to be used by any new constraints, particularly any that have multiple targets.
*/
-void get_constraint_target_matrix(struct Scene *scene, bConstraint *con, int n, short ownertype, void *ownerdata, float mat[4][4], float ctime)
+void BKE_get_constraint_target_matrix(Scene *scene, bConstraint *con, int index, short ownertype, void *ownerdata, float mat[4][4], float ctime)
{
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintOb *cob;
bConstraintTarget *ct;
@@ -4657,10 +4657,8 @@ void get_constraint_target_matrix(struct Scene *scene, bConstraint *con, int n,
cti->get_constraint_targets(con, &targets);
/* only calculate the target matrix on the first target */
- ct = (bConstraintTarget *)targets.first;
- while (ct && n-- > 0)
- ct = ct->next;
-
+ ct = (bConstraintTarget *)BLI_findlink(&targets, index);
+
if (ct) {
if (cti->get_target_matrix)
cti->get_target_matrix(con, cob, ct, ctime);
@@ -4679,9 +4677,9 @@ void get_constraint_target_matrix(struct Scene *scene, bConstraint *con, int n,
}
/* Get the list of targets required for solving a constraint */
-void get_constraint_targets_for_solving(bConstraint *con, bConstraintOb *cob, ListBase *targets, float ctime)
+void BKE_get_constraint_targets_for_solving(bConstraint *con, bConstraintOb *cob, ListBase *targets, float ctime)
{
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (cti && cti->get_constraint_targets) {
bConstraintTarget *ct;
@@ -4711,10 +4709,10 @@ void get_constraint_targets_for_solving(bConstraint *con, bConstraintOb *cob, Li
/* This function is called whenever constraints need to be evaluated. Currently, all
* constraints that can be evaluated are everytime this gets run.
*
- * constraints_make_evalob and constraints_clear_evalob should be called before and
+ * BKE_constraints_make_evalob and BKE_constraints_clear_evalob should be called before and
* after running this function, to sort out cob
*/
-void solve_constraints(ListBase *conlist, bConstraintOb *cob, float ctime)
+void BKE_solve_constraints(ListBase *conlist, bConstraintOb *cob, float ctime)
{
bConstraint *con;
float oldmat[4][4];
@@ -4726,7 +4724,7 @@ void solve_constraints(ListBase *conlist, bConstraintOb *cob, float ctime)
/* loop over available constraints, solving and blending them */
for (con = conlist->first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
/* these we can skip completely (invalid constraints...) */
@@ -4746,10 +4744,10 @@ void solve_constraints(ListBase *conlist, bConstraintOb *cob, float ctime)
copy_m4_m4(oldmat, cob->matrix);
/* move owner matrix into right space */
- constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace);
+ BKE_constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace);
/* prepare targets for constraint solving */
- get_constraint_targets_for_solving(con, cob, &targets, ctime);
+ BKE_get_constraint_targets_for_solving(con, cob, &targets, ctime);
/* Solve the constraint and put result in cob->matrix */
cti->evaluate_constraint(con, cob, &targets);
@@ -4764,7 +4762,7 @@ void solve_constraints(ListBase *conlist, bConstraintOb *cob, float ctime)
/* move owner back into worldspace for next constraint/other business */
if ((con->flag & CONSTRAINT_SPACEONCE) == 0)
- constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, con->ownspace, CONSTRAINT_SPACE_WORLD);
+ BKE_constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, con->ownspace, CONSTRAINT_SPACE_WORLD);
/* Interpolate the enforcement, to blend result of constraint into final owner transform
* - all this happens in worldspace to prevent any weirdness creeping in ([#26014] and [#25725]),
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 7009f1235c9..a45afa5e69a 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -29,6 +29,7 @@
#include <string.h>
+#include <stdlib.h>
#include <stddef.h>
#include "MEM_guardedalloc.h"
@@ -327,10 +328,13 @@ static void *ctx_data_pointer_get(const bContext *C, const char *member)
{
bContextDataResult result;
- if (C && ctx_data_get((bContext *)C, member, &result) == 1)
+ if (C && ctx_data_get((bContext *)C, member, &result) == 1) {
+ BLI_assert(result.type == CTX_DATA_TYPE_POINTER);
return result.ptr.data;
-
- return NULL;
+ }
+ else {
+ return NULL;
+ }
}
static int ctx_data_pointer_verify(const bContext *C, const char *member, void **pointer)
@@ -343,6 +347,7 @@ static int ctx_data_pointer_verify(const bContext *C, const char *member, void *
return 1;
}
else if (ctx_data_get((bContext *)C, member, &result) == 1) {
+ BLI_assert(result.type == CTX_DATA_TYPE_POINTER);
*pointer = result.ptr.data;
return 1;
}
@@ -357,6 +362,7 @@ static int ctx_data_collection_get(const bContext *C, const char *member, ListBa
bContextDataResult result;
if (ctx_data_get((bContext *)C, member, &result) == 1) {
+ BLI_assert(result.type == CTX_DATA_TYPE_COLLECTION);
*list = result.list;
return 1;
}
@@ -371,10 +377,13 @@ PointerRNA CTX_data_pointer_get(const bContext *C, const char *member)
{
bContextDataResult result;
- if (ctx_data_get((bContext *)C, member, &result) == 1)
+ if (ctx_data_get((bContext *)C, member, &result) == 1) {
+ BLI_assert(result.type == CTX_DATA_TYPE_POINTER);
return result.ptr;
- else
+ }
+ else {
return PointerRNA_NULL;
+ }
}
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
@@ -399,6 +408,7 @@ ListBase CTX_data_collection_get(const bContext *C, const char *member)
bContextDataResult result;
if (ctx_data_get((bContext *)C, member, &result) == 1) {
+ BLI_assert(result.type == CTX_DATA_TYPE_COLLECTION);
return result.list;
}
else {
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 7c13ca388e0..cea92d53916 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -34,6 +34,7 @@
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
+#include <stddef.h>
#include "MEM_guardedalloc.h"
@@ -337,37 +338,12 @@ void defvert_flip_merged(MDeformVert *dvert, const int *flip_map, const int flip
bDeformGroup *defgroup_find_name(Object *ob, const char *name)
{
- /* return a pointer to the deform group with this name
- * or return NULL otherwise.
- */
- bDeformGroup *curdef;
-
- for (curdef = ob->defbase.first; curdef; curdef = curdef->next) {
- if (!strcmp(curdef->name, name)) {
- return curdef;
- }
- }
- return NULL;
+ return BLI_findstring(&ob->defbase, name, offsetof(bDeformGroup, name));
}
int defgroup_name_index(Object *ob, const char *name)
{
- /* Return the location of the named deform group within the list of
- * deform groups. This function is a combination of BLI_findlink and
- * defgroup_find_name. The other two could be called instead, but that
- * require looping over the vertexgroups twice.
- */
- bDeformGroup *curdef;
- int def_nr;
-
- if (name && name[0] != '\0') {
- for (curdef = ob->defbase.first, def_nr = 0; curdef; curdef = curdef->next, def_nr++) {
- if (!strcmp(curdef->name, name))
- return def_nr;
- }
- }
-
- return -1;
+ return (name) ? BLI_findstringindex(&ob->defbase, name, offsetof(bDeformGroup, name)) : -1;
}
/* note, must be freed */
@@ -810,3 +786,43 @@ int defvert_find_shared(const MDeformVert *dvert_a, const MDeformVert *dvert_b)
return -1;
}
+
+/* -------------------------------------------------------------------- */
+/* Defvert Array functions */
+
+void BKE_defvert_array_copy(MDeformVert *dst, const MDeformVert *src, int copycount)
+{
+ /* Assumes dst is already set up */
+ int i;
+
+ if (!src || !dst)
+ return;
+
+ memcpy(dst, src, copycount * sizeof(MDeformVert));
+
+ for (i = 0; i < copycount; i++) {
+ if (src[i].dw) {
+ dst[i].dw = MEM_mallocN(sizeof(MDeformWeight) * src[i].totweight, "copy_deformWeight");
+ memcpy(dst[i].dw, src[i].dw, sizeof(MDeformWeight) * src[i].totweight);
+ }
+ }
+
+}
+
+void BKE_defvert_array_free(MDeformVert *dvert, int totvert)
+{
+ /* Instead of freeing the verts directly,
+ * call this function to delete any special
+ * vert data */
+ int i;
+
+ if (!dvert)
+ return;
+
+ /* Free any special data from the verts */
+ for (i = 0; i < totvert; i++) {
+ if (dvert[i].dw) MEM_freeN(dvert[i].dw);
+ }
+ MEM_freeN(dvert);
+}
+
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 6ba140fcec1..42389564ec0 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -472,7 +472,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -754,7 +754,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
/* object constraints */
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -2295,7 +2295,7 @@ static void dag_object_time_update_flags(Object *ob)
if (ob->constraints.first) {
bConstraint *con;
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -2738,7 +2738,7 @@ static void dag_id_flush_update(Scene *sce, ID *id)
for (obt = bmain->object.first; obt; obt = obt->id.next) {
bConstraint *con;
for (con = obt->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (ELEM3(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER,
CONSTRAINT_TYPE_OBJECTSOLVER))
{
@@ -3030,7 +3030,7 @@ void DAG_pose_sort(Object *ob)
addtoroot = 0;
}
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 083cb02fd3d..71e9daaee6b 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -225,29 +225,48 @@ void BKE_displist_normals_add(ListBase *lb)
}
}
-void BKE_displist_count(ListBase *lb, int *totvert, int *totface)
+void BKE_displist_count(ListBase *lb, int *totvert, int *totface, int *tottri)
{
DispList *dl;
- dl = lb->first;
- while (dl) {
+ for (dl = lb->first; dl; dl = dl->next) {
+ int vert_tot = 0;
+ int face_tot = 0;
+ int tri_tot = 0;
+
switch (dl->type) {
case DL_SURF:
- *totvert += dl->nr * dl->parts;
- *totface += (dl->nr - 1) * (dl->parts - 1);
+ {
+ vert_tot = dl->nr * dl->parts;
+ face_tot = (dl->nr - 1) * (dl->parts - 1);
+ tri_tot = face_tot * 2;
break;
+ }
case DL_INDEX3:
+ {
+ vert_tot = dl->nr;
+ face_tot = dl->parts;
+ tri_tot = face_tot;
+ break;
+ }
case DL_INDEX4:
- *totvert += dl->nr;
- *totface += dl->parts;
+ {
+ vert_tot = dl->nr;
+ face_tot = dl->parts;
+ tri_tot = face_tot * 2;
break;
+ }
case DL_POLY:
case DL_SEGM:
- *totvert += dl->nr * dl->parts;
+ {
+ vert_tot = dl->nr * dl->parts;
break;
+ }
}
- dl = dl->next;
+ *totvert += vert_tot;
+ *totface += face_tot;
+ *tottri += tri_tot;
}
}
@@ -487,7 +506,7 @@ void BKE_displist_fill(ListBase *dispbase, ListBase *to, int flipnormal)
}
/* XXX (obedit && obedit->actcol)?(obedit->actcol-1):0)) { */
- if (totvert && (tot = BLI_scanfill_calc(&sf_ctx, BLI_SCANFILL_CALC_REMOVE_DOUBLES))) {
+ if (totvert && (tot = BLI_scanfill_calc(&sf_ctx, BLI_SCANFILL_CALC_REMOVE_DOUBLES | BLI_SCANFILL_CALC_HOLES))) {
if (tot) {
dlnew = MEM_callocN(sizeof(DispList), "filldisplist");
dlnew->type = DL_INDEX3;
@@ -780,7 +799,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
required_mode |= eModifierMode_Editmode;
if (cu->editnurb == NULL) {
- keyVerts = do_ob_key(scene, ob);
+ keyVerts = BKE_key_evaluate_object(scene, ob, &numVerts);
if (keyVerts) {
/* split coords from key data, the latter also includes
@@ -789,7 +808,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
* shape key modifier yet. */
deformedVerts = BKE_curve_keyVertexCos_get(cu, nurb, keyVerts);
originalVerts = MEM_dupallocN(deformedVerts);
- numVerts = BKE_nurbList_verts_count(nurb);
+ BLI_assert(BKE_nurbList_verts_count(nurb) == numVerts);
}
}
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index e32f8d53b7d..fff51ab2a59 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -529,7 +529,7 @@ static int subframe_updateObject(Scene *scene, Object *ob, int flags, float fram
/* also update constraint targets */
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
if (cti && cti->get_constraint_targets) {
@@ -2689,7 +2689,7 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, char *filenam
if (format == R_IMF_IMTYPE_OPENEXR) format = R_IMF_IMTYPE_PNG;
#endif
BLI_strncpy(output_file, filename, sizeof(output_file));
- BKE_add_image_extension(output_file, format);
+ BKE_add_image_extension_from_type(output_file, format);
/* Validate output file path */
BLI_path_abs(output_file, G.main->name);
@@ -2839,7 +2839,9 @@ static void dynamicPaint_freeBrushMaterials(BrushMaterials *bMats)
/*
* Get material diffuse color and alpha (including linked textures) in given coordinates
*/
-static void dynamicPaint_doMaterialTex(BrushMaterials *bMats, float color[3], float *alpha, Object *brushOb, const float volume_co[3], const float surface_co[3], int faceIndex, short isQuad, DerivedMesh *orcoDm)
+static void dynamicPaint_doMaterialTex(BrushMaterials *bMats, float color[3], float *alpha, Object *brushOb,
+ const float volume_co[3], const float surface_co[3],
+ int faceIndex, short isQuad, DerivedMesh *orcoDm)
{
Material *mat = bMats->mat;
MFace *mface = orcoDm->getTessFaceArray(orcoDm);
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 480ff23f100..1c43b418a1c 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -113,8 +113,13 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *em)
#define USE_TESSFACE_SPEEDUP
BMesh *bm = em->bm;
- BMLoop *(*looptris)[3] = NULL;
- BLI_array_declare(looptris);
+
+ /* this assumes all faces can be scan-filled, which isn't always true,
+ * worst case we over alloc a little which is acceptable */
+ const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop);
+ const int looptris_tot_prev_alloc = em->looptris ? (MEM_allocN_len(em->looptris) / sizeof(*em->looptris)) : 0;
+
+ BMLoop *(*looptris)[3];
BMIter iter;
BMFace *efa;
BMLoop *l;
@@ -135,17 +140,16 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *em)
#else
/* this means no reallocs for quad dominant models, for */
- if ( (em->looptris != NULL) &&
- (em->tottri != 0) &&
- /* (totrti <= bm->totface * 2) would be fine for all quads,
- * but in case there are some ngons, still re-use the array */
- (em->tottri <= bm->totface * 3))
+ if ((em->looptris != NULL) &&
+ /* (em->tottri >= looptris_tot)) */
+ /* check against alloc'd size incase we over alloc'd a little */
+ ((looptris_tot_prev_alloc >= looptris_tot) && (looptris_tot_prev_alloc <= looptris_tot * 2)))
{
looptris = em->looptris;
}
else {
if (em->looptris) MEM_freeN(em->looptris);
- BLI_array_reserve(looptris, bm->totface);
+ looptris = MEM_mallocN(sizeof(*looptris) * looptris_tot, __func__);
}
#endif
@@ -163,20 +167,16 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *em)
else if (efa->len == 3) {
#if 0
int j;
- BLI_array_grow_one(looptris);
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) {
looptris[i][j] = l;
}
i += 1;
#else
/* more cryptic but faster */
- BLI_array_grow_one(looptris);
- {
- BMLoop **l_ptr = looptris[i++];
- l_ptr[0] = l = BM_FACE_FIRST_LOOP(efa);
- l_ptr[1] = l = l->next;
- l_ptr[2] = l->next;
- }
+ BMLoop **l_ptr = looptris[i++];
+ l_ptr[0] = l = BM_FACE_FIRST_LOOP(efa);
+ l_ptr[1] = l = l->next;
+ l_ptr[2] = l->next;
#endif
}
else if (efa->len == 4) {
@@ -199,15 +199,12 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *em)
i += 1;
#else
/* more cryptic but faster */
- BLI_array_grow_items(looptris, 2);
- {
- BMLoop **l_ptr_a = looptris[i++];
- BMLoop **l_ptr_b = looptris[i++];
- (l_ptr_a[0] = l_ptr_b[0] = l = BM_FACE_FIRST_LOOP(efa));
- (l_ptr_a[1] = l = l->next);
- (l_ptr_a[2] = l_ptr_b[1] = l = l->next);
- ( l_ptr_b[2] = l->next);
- }
+ BMLoop **l_ptr_a = looptris[i++];
+ BMLoop **l_ptr_b = looptris[i++];
+ (l_ptr_a[0] = l_ptr_b[0] = l = BM_FACE_FIRST_LOOP(efa));
+ (l_ptr_a[1] = l = l->next);
+ (l_ptr_a[2] = l_ptr_b[1] = l = l->next);
+ ( l_ptr_b[2] = l->next);
#endif
}
@@ -250,9 +247,10 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *em)
BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert);
totfilltri = BLI_scanfill_calc_ex(&sf_ctx, 0, efa->no);
- BLI_array_grow_items(looptris, totfilltri);
+ BLI_assert(totfilltri <= efa->len - 2);
for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
+ BMLoop **l_ptr = looptris[i++];
BMLoop *l1 = sf_tri->v1->tmp.p;
BMLoop *l2 = sf_tri->v2->tmp.p;
BMLoop *l3 = sf_tri->v3->tmp.p;
@@ -261,10 +259,9 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *em)
if (BM_elem_index_get(l2) > BM_elem_index_get(l3)) { SWAP(BMLoop *, l2, l3); }
if (BM_elem_index_get(l1) > BM_elem_index_get(l2)) { SWAP(BMLoop *, l1, l2); }
- looptris[i][0] = l1;
- looptris[i][1] = l2;
- looptris[i][2] = l3;
- i += 1;
+ l_ptr[0] = l1;
+ l_ptr[1] = l2;
+ l_ptr[2] = l3;
}
BLI_scanfill_end(&sf_ctx);
@@ -274,6 +271,8 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *em)
em->tottri = i;
em->looptris = looptris;
+ BLI_assert(em->tottri <= looptris_tot);
+
#undef USE_TESSFACE_SPEEDUP
}
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 5e01773cab9..23f3a3ad3fd 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -859,7 +859,7 @@ void testhandles_fcurve(FCurve *fcu, const short use_handle)
short flag = 0;
/* flag is initialized as selection status
- * of beztriple control-points (labelled 0,1,2)
+ * of beztriple control-points (labelled 0, 1, 2)
*/
if (bezt->f2 & SELECT) flag |= (1 << 1); // == 2
if (use_handle == FALSE) {
@@ -1192,7 +1192,7 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
/* extract transform just like how the constraints do it! */
copy_m4_m4(mat, pchan->pose_mat);
- constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
/* ... and from that, we get our transform */
copy_v3_v3(tmp_loc, mat[3]);
@@ -1217,7 +1217,7 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
/* extract transform just like how the constraints do it! */
copy_m4_m4(mat, ob->obmat);
- constraint_mat_convertspace(ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL);
+ BKE_constraint_mat_convertspace(ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL);
/* ... and from that, we get our transform */
copy_v3_v3(tmp_loc, mat[3]);
@@ -1288,7 +1288,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
/* just like how the constraints do it! */
copy_m4_m4(mat, pchan->pose_mat);
- constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
+ BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
}
else {
/* specially calculate local matrix, since chan_mat is not valid
@@ -1315,7 +1315,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
/* just like how the constraints do it! */
copy_m4_m4(mat, ob->obmat);
- constraint_mat_convertspace(ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL);
+ BKE_constraint_mat_convertspace(ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL);
}
else {
/* transforms to matrix */
@@ -2022,12 +2022,12 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime
}
else {
/* bezier interpolation */
- /* v1,v2 are the first keyframe and its 2nd handle */
+ /* (v1, v2) are the first keyframe and its 2nd handle */
v1[0] = prevbezt->vec[1][0];
v1[1] = prevbezt->vec[1][1];
v2[0] = prevbezt->vec[2][0];
v2[1] = prevbezt->vec[2][1];
- /* v3,v4 are the last keyframe's 1st handle + the last keyframe */
+ /* (v3, v4) are the last keyframe's 1st handle + the last keyframe */
v3[0] = bezt->vec[0][0];
v3[1] = bezt->vec[0][1];
v4[0] = bezt->vec[1][0];
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 5dd0f08dc71..3be47668fb5 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -815,6 +815,13 @@ void IDP_FreeProperty(IDProperty *prop)
}
}
+void IDP_ClearProperty(IDProperty *prop)
+{
+ IDP_FreeProperty(prop);
+ prop->data.pointer = NULL;
+ prop->len = prop->totallen = 0;
+}
+
/* Unlinks any IDProperty<->ID linkage that might be going on.
* note: currently unused.*/
void IDP_UnlinkProperty(IDProperty *prop)
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index f3cdf11d664..dbc423f98b3 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -312,10 +312,6 @@ static void image_assign_ibuf(Image *ima, ImBuf *ibuf, int index, int frame)
break;
ibuf->index = index;
- if (ima->flag & IMA_CM_PREDIVIDE)
- ibuf->flags |= IB_cm_predivide;
- else
- ibuf->flags &= ~IB_cm_predivide;
/* this function accepts (link == NULL) */
BLI_insertlinkbefore(&ima->ibufs, link, ibuf);
@@ -552,6 +548,26 @@ int BKE_image_scale(Image *image, int width, int height)
return (ibuf != NULL);
}
+static void image_init_color_management(Image *ima)
+{
+ ImBuf *ibuf;
+ char name[FILE_MAX];
+
+ BKE_image_user_file_path(NULL, ima, name);
+
+ /* will set input color space to image format default's */
+ ibuf = IMB_loadiffname(name, IB_test | IB_alphamode_detect, ima->colorspace_settings.name);
+
+ if (ibuf) {
+ if (ibuf->flags & IB_alphamode_premul)
+ ima->alpha_mode = IMA_ALPHA_PREMUL;
+ else
+ ima->alpha_mode = IMA_ALPHA_STRAIGHT;
+
+ IMB_freeImBuf(ibuf);
+ }
+}
+
Image *BKE_image_load(const char *filepath)
{
Image *ima;
@@ -579,6 +595,8 @@ Image *BKE_image_load(const char *filepath)
if (BLI_testextensie_array(filepath, imb_ext_movie))
ima->source = IMA_SRC_MOVIE;
+ image_init_color_management(ima);
+
return ima;
}
@@ -666,7 +684,7 @@ static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char
/* both byte and float buffers are filling in sRGB space, need to linearize float buffer after BKE_image_buf_fill* functions */
IMB_buffer_float_from_float(rect_float, rect_float, ibuf->channels, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB,
- ibuf->flags & IB_cm_predivide, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+ TRUE, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
}
return ibuf;
@@ -1119,6 +1137,8 @@ char BKE_imtype_valid_depths(const char imtype)
return R_IMF_CHAN_DEPTH_10;
case R_IMF_IMTYPE_JP2:
return R_IMF_CHAN_DEPTH_8 | R_IMF_CHAN_DEPTH_12 | R_IMF_CHAN_DEPTH_16;
+ case R_IMF_IMTYPE_PNG:
+ return R_IMF_CHAN_DEPTH_8 | R_IMF_CHAN_DEPTH_16;
/* most formats are 8bit only */
default:
return R_IMF_CHAN_DEPTH_8;
@@ -1165,9 +1185,10 @@ char BKE_imtype_from_arg(const char *imtype_arg)
else return R_IMF_IMTYPE_INVALID;
}
-int BKE_add_image_extension(char *string, const char imtype)
+static int do_add_image_extension(char *string, const char imtype, const ImageFormatData *im_format)
{
const char *extension = NULL;
+ (void)im_format; /* may be unused, depends on build options */
if (imtype == R_IMF_IMTYPE_IRIS) {
if (!BLI_testextensie(string, ".rgb"))
@@ -1232,8 +1253,22 @@ int BKE_add_image_extension(char *string, const char imtype)
}
#ifdef WITH_OPENJPEG
else if (imtype == R_IMF_IMTYPE_JP2) {
- if (!BLI_testextensie(string, ".jp2"))
- extension = ".jp2";
+ if (im_format) {
+ if (im_format->jp2_codec == R_IMF_JP2_CODEC_JP2) {
+ if (!BLI_testextensie(string, ".jp2"))
+ extension = ".jp2";
+ }
+ else if (im_format->jp2_codec == R_IMF_JP2_CODEC_J2K) {
+ if (!BLI_testextensie(string, ".j2c"))
+ extension = ".j2c";
+ }
+ else
+ BLI_assert(!"Unsupported jp2 codec was specified in im_format->jp2_codec");
+ }
+ else {
+ if (!BLI_testextensie(string, ".jp2"))
+ extension = ".jp2";
+ }
}
#endif
else { // R_IMF_IMTYPE_AVIRAW, R_IMF_IMTYPE_AVIJPEG, R_IMF_IMTYPE_JPEG90, R_IMF_IMTYPE_QUICKTIME etc
@@ -1259,11 +1294,22 @@ int BKE_add_image_extension(char *string, const char imtype)
}
}
+int BKE_add_image_extension(char *string, const ImageFormatData *im_format)
+{
+ return do_add_image_extension(string, im_format->imtype, im_format);
+}
+
+int BKE_add_image_extension_from_type(char *string, const char imtype)
+{
+ return do_add_image_extension(string, imtype, NULL);
+}
+
void BKE_imformat_defaults(ImageFormatData *im_format)
{
memset(im_format, 0, sizeof(*im_format));
im_format->planes = R_IMF_PLANES_RGB;
im_format->imtype = R_IMF_IMTYPE_PNG;
+ im_format->depth = R_IMF_CHAN_DEPTH_8;
im_format->quality = 90;
im_format->compress = 90;
@@ -1288,9 +1334,13 @@ void BKE_imbuf_to_image_format(struct ImageFormatData *im_format, const ImBuf *i
im_format->imtype = R_IMF_IMTYPE_RADHDR;
#endif
- else if (ftype == PNG)
+ else if (ftype == PNG) {
im_format->imtype = R_IMF_IMTYPE_PNG;
+ if (custom_flags & PNG_16BIT)
+ im_format->depth = R_IMF_CHAN_DEPTH_16;
+ }
+
#ifdef WITH_DDS
else if (ftype == DDS)
im_format->imtype = R_IMF_IMTYPE_DDS;
@@ -1351,6 +1401,13 @@ void BKE_imbuf_to_image_format(struct ImageFormatData *im_format, const ImBuf *i
if (ftype & JP2_CINE_48FPS)
im_format->jp2_flag |= R_IMF_JP2_FLAG_CINE_48;
}
+
+ if (ftype & JP2_JP2)
+ im_format->jp2_codec = R_IMF_JP2_CODEC_JP2;
+ else if (ftype & JP2_J2K)
+ im_format->jp2_codec = R_IMF_JP2_CODEC_J2K;
+ else
+ BLI_assert(!"Unsupported jp2 codec was specified in file type");
}
#endif
@@ -1815,8 +1872,12 @@ int BKE_imbuf_write(ImBuf *ibuf, const char *name, ImageFormatData *imf)
else if (ELEM5(imtype, R_IMF_IMTYPE_PNG, R_IMF_IMTYPE_FFMPEG, R_IMF_IMTYPE_H264, R_IMF_IMTYPE_THEORA, R_IMF_IMTYPE_XVID)) {
ibuf->ftype = PNG;
- if (imtype == R_IMF_IMTYPE_PNG)
+ if (imtype == R_IMF_IMTYPE_PNG) {
+ if (imf->depth == R_IMF_CHAN_DEPTH_16)
+ ibuf->ftype |= PNG_16BIT;
+
ibuf->ftype |= compress;
+ }
}
#ifdef WITH_DDS
@@ -1906,6 +1967,13 @@ int BKE_imbuf_write(ImBuf *ibuf, const char *name, ImageFormatData *imf)
if (imf->jp2_flag & R_IMF_JP2_FLAG_CINE_48)
ibuf->ftype |= JP2_CINE_48FPS;
}
+
+ if (imf->jp2_codec == R_IMF_JP2_CODEC_JP2)
+ ibuf->ftype |= JP2_JP2;
+ else if (imf->jp2_codec == R_IMF_JP2_CODEC_J2K)
+ ibuf->ftype |= JP2_J2K;
+ else
+ BLI_assert(!"Unsupported jp2 codec was specified in im_format->jp2_codec");
}
#endif
else {
@@ -1956,7 +2024,8 @@ int BKE_imbuf_write_stamp(Scene *scene, struct Object *camera, ImBuf *ibuf, cons
}
-void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame, const char imtype, const short use_ext, const short use_frames)
+static void do_makepicstring(char *string, const char *base, const char *relbase, int frame, const char imtype,
+ const ImageFormatData *im_format, const short use_ext, const short use_frames)
{
if (string == NULL) return;
BLI_strncpy(string, base, FILE_MAX - 10); /* weak assumption */
@@ -1966,8 +2035,17 @@ void BKE_makepicstring(char *string, const char *base, const char *relbase, int
BLI_path_frame(string, frame, 4);
if (use_ext)
- BKE_add_image_extension(string, imtype);
+ do_add_image_extension(string, imtype, im_format);
+}
+void BKE_makepicstring(char *string, const char *base, const char *relbase, int frame, const ImageFormatData *im_format, const short use_ext, const short use_frames)
+{
+ do_makepicstring(string, base, relbase, frame, im_format->imtype, im_format, use_ext, use_frames);
+}
+
+void BKE_makepicstring_from_type(char *string, const char *base, const char *relbase, int frame, const char imtype, const short use_ext, const short use_frames)
+{
+ do_makepicstring(string, base, relbase, frame, imtype, NULL, use_ext, use_frames);
}
/* used by sequencer too */
@@ -2284,7 +2362,7 @@ void BKE_image_backup_render(Scene *scene, Image *ima)
static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr)
{
const char *colorspace = ima->colorspace_settings.name;
- int predivide = ima->flag & IMA_CM_PREDIVIDE;
+ int predivide = ima->alpha_mode == IMA_ALPHA_PREMUL;
ima->rr = RE_MultilayerConvert(ibuf->userdata, colorspace, predivide, ibuf->x, ibuf->y);
@@ -2316,6 +2394,18 @@ static void image_initialize_after_load(Image *ima, ImBuf *ibuf)
}
+static int imbuf_alpha_flags_for_image(Image *ima)
+{
+ int flag = 0;
+
+ if (ima->flag & IMA_IGNORE_ALPHA)
+ flag |= IB_ignore_alpha;
+ else if (ima->alpha_mode == IMA_ALPHA_PREMUL)
+ flag |= IB_alphamode_premul;
+
+ return flag;
+}
+
static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
{
struct ImBuf *ibuf;
@@ -2330,8 +2420,7 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
BKE_image_user_file_path(iuser, ima, name);
flag = IB_rect | IB_multilayer;
- if (ima->flag & IMA_DO_PREMUL)
- flag |= IB_premul;
+ flag |= imbuf_alpha_flags_for_image(ima);
/* read ibuf */
ibuf = IMB_loadiffname(name, flag, ima->colorspace_settings.name);
@@ -2490,15 +2579,14 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
/* is there a PackedFile with this image ? */
if (ima->packedfile) {
flag = IB_rect | IB_multilayer;
- if (ima->flag & IMA_DO_PREMUL) flag |= IB_premul;
+ flag |= imbuf_alpha_flags_for_image(ima);
ibuf = IMB_ibImageFromMemory((unsigned char *)ima->packedfile->data, ima->packedfile->size, flag,
ima->colorspace_settings.name, "<packed data>");
}
else {
flag = IB_rect | IB_multilayer | IB_metadata;
- if (ima->flag & IMA_DO_PREMUL)
- flag |= IB_premul;
+ flag |= imbuf_alpha_flags_for_image(ima);
/* get the right string */
BKE_image_user_frame_calc(iuser, cfra, 0);
@@ -2718,15 +2806,6 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
ibuf->dither = dither;
- if (iuser->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE) {
- ibuf->flags |= IB_cm_predivide;
- ima->flag |= IMA_CM_PREDIVIDE;
- }
- else {
- ibuf->flags &= ~IB_cm_predivide;
- ima->flag &= ~IMA_CM_PREDIVIDE;
- }
-
ima->ok = IMA_OK_LOADED;
return ibuf;
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index ad95f09826a..ccc57a24540 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -1300,13 +1300,13 @@ static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, const int
}
/* returns key coordinates (+ tilt) when key applied, NULL otherwise */
-float *do_ob_key(Scene *scene, Object *ob)
+float *BKE_key_evaluate_object(Scene *scene, Object *ob, int *r_totelem)
{
Key *key = BKE_key_from_object(ob);
KeyBlock *actkb = BKE_keyblock_from_object(ob);
char *out;
int tot = 0, size = 0;
-
+
if (key == NULL || key->block.first == NULL)
return NULL;
@@ -1344,7 +1344,7 @@ float *do_ob_key(Scene *scene, Object *ob)
return NULL;
/* allocate array */
- out = MEM_callocN(size, "do_ob_key out");
+ out = MEM_callocN(size, "BKE_key_evaluate_object out");
/* prevent python from screwing this up? anyhoo, the from pointer could be dropped */
key->from = (ID *)ob->data;
@@ -1383,6 +1383,9 @@ float *do_ob_key(Scene *scene, Object *ob)
else if (ob->type == OB_SURF) do_curve_key(scene, ob, key, out, tot);
}
+ if (r_totelem) {
+ *r_totelem = tot;
+ }
return (float *)out;
}
@@ -1732,7 +1735,7 @@ void BKE_key_convert_to_mesh(KeyBlock *kb, Mesh *me)
}
/************************* vert coords ************************/
-float (*BKE_key_convert_to_vertcos(Object * ob, KeyBlock * kb))[3]
+float (*BKE_key_convert_to_vertcos(Object *ob, KeyBlock *kb))[3]
{
float (*vertCos)[3], *co;
float *fp = kb->data;
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index d98188d8a6f..fa01e9fd933 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -88,7 +88,7 @@ void BKE_lattice_resize(Lattice *lt, int uNew, int vNew, int wNew, Object *ltOb)
/* vertex weight groups are just freed all for now */
if (lt->dvert) {
- free_dverts(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
+ BKE_defvert_array_free(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
lt->dvert = NULL;
}
@@ -209,7 +209,7 @@ Lattice *BKE_lattice_copy(Lattice *lt)
if (lt->dvert) {
int tot = lt->pntsu * lt->pntsv * lt->pntsw;
ltn->dvert = MEM_mallocN(sizeof(MDeformVert) * tot, "Lattice MDeformVert");
- copy_dverts(ltn->dvert, lt->dvert, tot);
+ BKE_defvert_array_copy(ltn->dvert, lt->dvert, tot);
}
ltn->editlatt = NULL;
@@ -220,12 +220,12 @@ Lattice *BKE_lattice_copy(Lattice *lt)
void BKE_lattice_free(Lattice *lt)
{
if (lt->def) MEM_freeN(lt->def);
- if (lt->dvert) free_dverts(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
+ if (lt->dvert) BKE_defvert_array_free(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
if (lt->editlatt) {
Lattice *editlt = lt->editlatt->latt;
if (editlt->def) MEM_freeN(editlt->def);
- if (editlt->dvert) free_dverts(editlt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
+ if (editlt->dvert) BKE_defvert_array_free(editlt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
MEM_freeN(editlt);
MEM_freeN(lt->editlatt);
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 2fa928e7c07..73452b216ff 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -933,7 +933,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas
}
/* main scan-fill */
- sf_tri_tot = BLI_scanfill_calc_ex(&sf_ctx, 0, zvec);
+ sf_tri_tot = BLI_scanfill_calc_ex(&sf_ctx, BLI_SCANFILL_CALC_HOLES, zvec);
face_array = MEM_mallocN(sizeof(*face_array) * (sf_tri_tot + tot_feather_quads), "maskrast_face_index");
face_index = 0;
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 54bd03ece70..4655dd04261 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -631,11 +631,14 @@ Material *give_current_material(Object *ob, short act)
if (totcolp == NULL || ob->totcol == 0) return NULL;
if (act < 0) {
- printf("no!\n");
+ printf("Negative material index!\n");
}
- if (act > ob->totcol) act = ob->totcol;
- else if (act <= 0) act = 1;
+ /* return NULL for invalid 'act', can happen for mesh face indices */
+ if (act > ob->totcol)
+ return NULL;
+ else if (act <= 0)
+ return NULL;
if (ob->matbits && ob->matbits[act - 1]) { /* in object */
ma = ob->mat[act - 1];
@@ -1237,6 +1240,11 @@ int object_remove_material_slot(Object *ob)
if (*matarar == NULL) return FALSE;
+ /* can happen on face selection in editmode */
+ if (ob->actcol > ob->totcol) {
+ ob->actcol = ob->totcol;
+ }
+
/* we delete the actcol */
mao = (*matarar)[ob->actcol - 1];
if (mao) mao->id.us--;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 3eb96f218e4..30e7cb3bb36 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -430,42 +430,6 @@ void BKE_mesh_free(Mesh *me, int unlink)
if (me->edit_btmesh) MEM_freeN(me->edit_btmesh);
}
-void copy_dverts(MDeformVert *dst, const MDeformVert *src, int copycount)
-{
- /* Assumes dst is already set up */
- int i;
-
- if (!src || !dst)
- return;
-
- memcpy(dst, src, copycount * sizeof(MDeformVert));
-
- for (i = 0; i < copycount; i++) {
- if (src[i].dw) {
- dst[i].dw = MEM_mallocN(sizeof(MDeformWeight) * src[i].totweight, "copy_deformWeight");
- memcpy(dst[i].dw, src[i].dw, sizeof(MDeformWeight) * src[i].totweight);
- }
- }
-
-}
-
-void free_dverts(MDeformVert *dvert, int totvert)
-{
- /* Instead of freeing the verts directly,
- * call this function to delete any special
- * vert data */
- int i;
-
- if (!dvert)
- return;
-
- /* Free any special data from the verts */
- for (i = 0; i < totvert; i++) {
- if (dvert[i].dw) MEM_freeN(dvert[i].dw);
- }
- MEM_freeN(dvert);
-}
-
static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata)
{
if (free_customdata) {
@@ -2488,7 +2452,7 @@ void BKE_mesh_loops_to_mface_corners(CustomData *fdata, CustomData *ldata,
*/
int BKE_mesh_recalc_tessellation(CustomData *fdata,
CustomData *ldata, CustomData *pdata,
- MVert *mvert, int totface, int UNUSED(totloop),
+ MVert *mvert, int totface, int totloop,
int totpoly,
/* when tessellating to recalculate normals after
* we can skip copying here */
@@ -2503,15 +2467,15 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
#define TESSFACE_SCANFILL (1 << 0)
#define TESSFACE_IS_QUAD (1 << 1)
+ const int looptris_tot = poly_to_tri_count(totpoly, totloop);
+
MPoly *mp, *mpoly;
MLoop *ml, *mloop;
- MFace *mface = NULL, *mf;
- BLI_array_declare(mface);
+ MFace *mface, *mf;
ScanFillContext sf_ctx;
ScanFillVert *sf_vert, *sf_vert_last, *sf_vert_first;
ScanFillFace *sf_tri;
- int *mface_to_poly_map = NULL;
- BLI_array_declare(mface_to_poly_map);
+ int *mface_to_poly_map;
int lindex[4]; /* only ever use 3 in this case */
int poly_index, j, mface_index;
@@ -2525,8 +2489,9 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
/* allocate the length of totfaces, avoid many small reallocs,
* if all faces are tri's it will be correct, quads == 2x allocs */
- BLI_array_reserve(mface_to_poly_map, totpoly);
- BLI_array_reserve(mface, totpoly);
+ /* take care. we are _not_ calloc'ing so be sure to initialize each field */
+ mface_to_poly_map = MEM_mallocN(sizeof(*mface_to_poly_map) * looptris_tot, __func__);
+ mface = MEM_mallocN(sizeof(*mface) * looptris_tot, __func__);
mface_index = 0;
mp = mpoly;
@@ -2538,8 +2503,6 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
#ifdef USE_TESSFACE_SPEEDUP
#define ML_TO_MF(i1, i2, i3) \
- BLI_array_grow_one(mface_to_poly_map); \
- BLI_array_grow_one(mface); \
mface_to_poly_map[mface_index] = poly_index; \
mf = &mface[mface_index]; \
/* set loop indices, transformed to vert indices later */ \
@@ -2549,12 +2512,11 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
mf->v4 = 0; \
mf->mat_nr = mp->mat_nr; \
mf->flag = mp->flag; \
+ mf->edcode = 0; \
(void)0
/* ALMOST IDENTICAL TO DEFINE ABOVE (see EXCEPTION) */
#define ML_TO_MF_QUAD() \
- BLI_array_grow_one(mface_to_poly_map); \
- BLI_array_grow_one(mface); \
mface_to_poly_map[mface_index] = poly_index; \
mf = &mface[mface_index]; \
/* set loop indices, transformed to vert indices later */ \
@@ -2564,7 +2526,7 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
mf->v4 = mp->loopstart + 3; /* EXCEPTION */ \
mf->mat_nr = mp->mat_nr; \
mf->flag = mp->flag; \
- mf->edcode |= TESSFACE_IS_QUAD; /* EXCEPTION */ \
+ mf->edcode = TESSFACE_IS_QUAD; /* EXCEPTION */ \
(void)0
@@ -2607,29 +2569,26 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert_first);
totfilltri = BLI_scanfill_calc(&sf_ctx, 0);
- if (totfilltri) {
- BLI_array_grow_items(mface_to_poly_map, totfilltri);
- BLI_array_grow_items(mface, totfilltri);
+ BLI_assert(totfilltri <= mp->totloop - 2);
- for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next, mf++) {
- mface_to_poly_map[mface_index] = poly_index;
- mf = &mface[mface_index];
+ for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next, mf++) {
+ mface_to_poly_map[mface_index] = poly_index;
+ mf = &mface[mface_index];
- /* set loop indices, transformed to vert indices later */
- mf->v1 = sf_tri->v1->keyindex;
- mf->v2 = sf_tri->v2->keyindex;
- mf->v3 = sf_tri->v3->keyindex;
- mf->v4 = 0;
+ /* set loop indices, transformed to vert indices later */
+ mf->v1 = sf_tri->v1->keyindex;
+ mf->v2 = sf_tri->v2->keyindex;
+ mf->v3 = sf_tri->v3->keyindex;
+ mf->v4 = 0;
- mf->mat_nr = mp->mat_nr;
- mf->flag = mp->flag;
+ mf->mat_nr = mp->mat_nr;
+ mf->flag = mp->flag;
#ifdef USE_TESSFACE_SPEEDUP
- mf->edcode |= TESSFACE_SCANFILL; /* tag for sorting loop indices */
+ mf->edcode = TESSFACE_SCANFILL; /* tag for sorting loop indices */
#endif
- mface_index++;
- }
+ mface_index++;
}
BLI_scanfill_end(&sf_ctx);
@@ -2639,9 +2598,10 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
CustomData_free(fdata, totface);
totface = mface_index;
+ BLI_assert(totface <= looptris_tot);
/* not essential but without this we store over-alloc'd memory in the CustomData layers */
- if (LIKELY((MEM_allocN_len(mface) / sizeof(*mface)) != totface)) {
+ if (LIKELY(looptris_tot != totface)) {
mface = MEM_reallocN(mface, sizeof(*mface) * totface);
mface_to_poly_map = MEM_reallocN(mface_to_poly_map, sizeof(*mface_to_poly_map) * totface);
}
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 4156b5b4367..69e368f0d08 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -1325,7 +1325,7 @@ void BKE_movieclip_unlink(Main *bmain, MovieClip *clip)
bConstraint *con;
for (con = ob->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
if (cti->type == CONSTRAINT_TYPE_FOLLOWTRACK) {
bFollowTrackConstraint *data = (bFollowTrackConstraint *) con->data;
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 06d7cf55d49..b12463daf72 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -379,7 +379,7 @@ void multires_force_update(Object *ob)
ob->derivedFinal = NULL;
}
if (ob->sculpt && ob->sculpt->pbvh) {
- BLI_pbvh_free(ob->sculpt->pbvh);
+ BKE_pbvh_free(ob->sculpt->pbvh);
ob->sculpt->pbvh = NULL;
}
}
@@ -1407,7 +1407,7 @@ void multires_stitch_grids(Object *ob)
int totface;
if (ccgdm->pbvh) {
- BLI_pbvh_get_grid_updates(ccgdm->pbvh, 0, (void ***)&faces, &totface);
+ BKE_pbvh_get_grid_updates(ccgdm->pbvh, 0, (void ***)&faces, &totface);
if (totface) {
ccgSubSurf_stitchFaces(ccgdm->ss, 0, faces, totface);
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 8babdf2402f..84e280034ed 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1161,11 +1161,11 @@ void ntreeSetOutput(bNodeTree *ntree)
bNodeTree *ntreeFromID(ID *id)
{
switch (GS(id->name)) {
- case ID_MA: return ((Material*)id)->nodetree;
- case ID_LA: return ((Lamp*)id)->nodetree;
- case ID_WO: return ((World*)id)->nodetree;
- case ID_TE: return ((Tex*)id)->nodetree;
- case ID_SCE: return ((Scene*)id)->nodetree;
+ case ID_MA: return ((Material *)id)->nodetree;
+ case ID_LA: return ((Lamp *)id)->nodetree;
+ case ID_WO: return ((World *)id)->nodetree;
+ case ID_TE: return ((Tex *)id)->nodetree;
+ case ID_SCE: return ((Scene *)id)->nodetree;
default: return NULL;
}
}
@@ -2323,6 +2323,7 @@ static void registerShaderNodes(bNodeTreeType *ttype)
register_node_type_sh_layer_weight(ttype);
register_node_type_sh_tex_coord(ttype);
register_node_type_sh_particle_info(ttype);
+ register_node_type_sh_hair_info(ttype);
register_node_type_sh_bump(ttype);
register_node_type_sh_script(ttype);
register_node_type_sh_tangent(ttype);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index d13d456a183..5a22973164e 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -268,14 +268,44 @@ void free_sculptsession_deformMats(SculptSession *ss)
ss->deform_imats = NULL;
}
+/* Write out the sculpt dynamic-topology BMesh to the Mesh */
+void sculptsession_bm_to_me(struct Object *ob, int reorder)
+{
+ if (ob && ob->sculpt) {
+ SculptSession *ss = ob->sculpt;
+
+ if (ss->bm) {
+ if (ob->data) {
+ BMIter iter;
+ BMFace *efa;
+ BM_ITER_MESH (efa, &iter, ss->bm, BM_FACES_OF_MESH) {
+ BM_elem_flag_set(efa, BM_ELEM_SMOOTH,
+ ss->bm_smooth_shading);
+ }
+ if (reorder)
+ BM_log_mesh_elems_reorder(ss->bm, ss->bm_log);
+ BM_mesh_bm_to_me(ss->bm, ob->data, FALSE);
+ }
+ }
+ }
+}
+
void free_sculptsession(Object *ob)
{
if (ob && ob->sculpt) {
SculptSession *ss = ob->sculpt;
DerivedMesh *dm = ob->derivedFinal;
+ if (ss->bm) {
+ sculptsession_bm_to_me(ob, TRUE);
+ BM_mesh_free(ss->bm);
+ }
+
if (ss->pbvh)
- BLI_pbvh_free(ss->pbvh);
+ BKE_pbvh_free(ss->pbvh);
+ if (ss->bm_log)
+ BM_log_free(ss->bm_log);
+
if (dm && dm->getPBVH)
dm->getPBVH(NULL, dm); /* signal to clear */
@@ -353,7 +383,7 @@ void BKE_object_free(Object *ob)
free_controllers(&ob->controllers);
free_actuators(&ob->actuators);
- free_constraints(&ob->constraints);
+ BKE_free_constraints(&ob->constraints);
free_partdeflect(ob->pd);
@@ -438,7 +468,7 @@ void BKE_object_unlink(Object *ob)
bPoseChannel *pchan;
for (pchan = obt->pose->chanbase.first; pchan; pchan = pchan->next) {
for (con = pchan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -469,7 +499,7 @@ void BKE_object_unlink(Object *ob)
sca_remove_ob_poin(obt, ob);
for (con = obt->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1143,7 +1173,7 @@ static void copy_object_pose(Object *obn, Object *ob)
}
for (con = chan->constraints.first; con; con = con->next) {
- bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+ bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1243,7 +1273,7 @@ static Object *object_copy_do(Object *ob, int copy_caches)
BKE_pose_rebuild(obn, obn->data);
}
defgroup_copy_list(&obn->defbase, &ob->defbase);
- copy_constraints(&obn->constraints, &ob->constraints, TRUE);
+ BKE_copy_constraints(&obn->constraints, &ob->constraints, TRUE);
obn->mode = 0;
obn->sculpt = NULL;
@@ -2127,9 +2157,9 @@ void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime)
if (ob->constraints.first && !(ob->transflag & OB_NO_CONSTRAINTS)) {
bConstraintOb *cob;
- cob = constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
- solve_constraints(&ob->constraints, cob, ctime);
- constraints_clear_evalob(cob);
+ cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+ BKE_solve_constraints(&ob->constraints, cob, ctime);
+ BKE_constraints_clear_evalob(cob);
}
/* set negative scale flag in object */
@@ -2198,9 +2228,9 @@ void BKE_object_where_is_calc_simul(Scene *scene, Object *ob)
if (ob->constraints.first) {
bConstraintOb *cob;
- cob = constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
- solve_constraints(&ob->constraints, cob, (float)scene->r.cfra);
- constraints_clear_evalob(cob);
+ cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+ BKE_solve_constraints(&ob->constraints, cob, (float)scene->r.cfra);
+ BKE_constraints_clear_evalob(cob);
}
}
@@ -2799,7 +2829,7 @@ void BKE_object_sculpt_modifiers_changed(Object *ob)
* changing PVBH node organization, we hope topology does not change in
* the meantime .. weak */
if (ss->pbvh) {
- BLI_pbvh_free(ss->pbvh);
+ BKE_pbvh_free(ss->pbvh);
ss->pbvh = NULL;
}
@@ -2809,10 +2839,10 @@ void BKE_object_sculpt_modifiers_changed(Object *ob)
PBVHNode **nodes;
int n, totnode;
- BLI_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
+ BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
for (n = 0; n < totnode; n++)
- BLI_pbvh_node_mark_update(nodes[n]);
+ BKE_pbvh_node_mark_update(nodes[n]);
MEM_freeN(nodes);
}
@@ -2965,12 +2995,13 @@ static KeyBlock *insert_meshkey(Scene *scene, Object *ob, const char *name, int
}
else {
/* copy from current values */
- float *data = do_ob_key(scene, ob);
+ int totelem;
+ float *data = BKE_key_evaluate_object(scene, ob, &totelem);
/* create new block with prepared data */
kb = BKE_keyblock_add_ctime(key, name, FALSE);
kb->data = data;
- kb->totelem = me->totvert;
+ kb->totelem = totelem;
}
return kb;
@@ -3002,11 +3033,12 @@ static KeyBlock *insert_lattkey(Scene *scene, Object *ob, const char *name, int
}
else {
/* copy from current values */
- float *data = do_ob_key(scene, ob);
+ int totelem;
+ float *data = BKE_key_evaluate_object(scene, ob, &totelem);
/* create new block with prepared data */
kb = BKE_keyblock_add_ctime(key, name, FALSE);
- kb->totelem = lt->pntsu * lt->pntsv * lt->pntsw;
+ kb->totelem = totelem;
kb->data = data;
}
@@ -3041,11 +3073,12 @@ static KeyBlock *insert_curvekey(Scene *scene, Object *ob, const char *name, int
}
else {
/* copy from current values */
- float *data = do_ob_key(scene, ob);
+ int totelem;
+ float *data = BKE_key_evaluate_object(scene, ob, &totelem);
/* create new block with prepared data */
kb = BKE_keyblock_add_ctime(key, name, FALSE);
- kb->totelem = BKE_nurbList_verts_count(lb);
+ kb->totelem = totelem;
kb->data = data;
}
@@ -3148,11 +3181,11 @@ void BKE_object_relink(Object *ob)
if (ob->id.lib)
return;
- relink_constraints(&ob->constraints);
+ BKE_relink_constraints(&ob->constraints);
if (ob->pose) {
bPoseChannel *chan;
for (chan = ob->pose->chanbase.first; chan; chan = chan->next) {
- relink_constraints(&chan->constraints);
+ BKE_relink_constraints(&chan->constraints);
}
}
modifiers_foreachIDLink(ob, copy_object__forwardModifierLinks, NULL);
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index e694a7e7eb3..c4274aa1f93 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -35,16 +35,15 @@
#include "DNA_scene_types.h"
+#include "BKE_global.h" /* XXX TESTING */
#include "BKE_image.h"
#include "BKE_ocean.h"
-#include "BKE_global.h" // XXX TESTING
-#include "BLI_math_base.h"
-#include "BLI_math_inline.h"
+#include "BLI_math.h"
+#include "BLI_path_util.h"
#include "BLI_rand.h"
#include "BLI_string.h"
#include "BLI_threads.h"
-#include "BLI_path_util.h"
#include "BLI_utildefines.h"
#include "IMB_imbuf.h"
@@ -54,7 +53,7 @@
#ifdef WITH_OCEANSIM
-// Ocean code
+/* Ocean code */
#include "fftw3.h"
#define GRAVITY 9.81f
@@ -82,7 +81,7 @@ typedef struct Ocean {
float _Lx;
float _Lz;
- float normalize_factor; // init w
+ float normalize_factor; /* init w */
float time;
short _do_disp_y;
@@ -96,51 +95,52 @@ typedef struct Ocean {
/* ********* sim data arrays ********* */
/* two dimensional arrays of complex */
- fftw_complex *_fft_in; // init w sim w
- fftw_complex *_fft_in_x; // init w sim w
- fftw_complex *_fft_in_z; // init w sim w
- fftw_complex *_fft_in_jxx; // init w sim w
- fftw_complex *_fft_in_jzz; // init w sim w
- fftw_complex *_fft_in_jxz; // init w sim w
- fftw_complex *_fft_in_nx; // init w sim w
- fftw_complex *_fft_in_nz; // init w sim w
- fftw_complex *_htilda; // init w sim w (only once)
+ fftw_complex *_fft_in; /* init w sim w */
+ fftw_complex *_fft_in_x; /* init w sim w */
+ fftw_complex *_fft_in_z; /* init w sim w */
+ fftw_complex *_fft_in_jxx; /* init w sim w */
+ fftw_complex *_fft_in_jzz; /* init w sim w */
+ fftw_complex *_fft_in_jxz; /* init w sim w */
+ fftw_complex *_fft_in_nx; /* init w sim w */
+ fftw_complex *_fft_in_nz; /* init w sim w */
+ fftw_complex *_htilda; /* init w sim w (only once) */
/* fftw "plans" */
- fftw_plan _disp_y_plan; // init w sim r
- fftw_plan _disp_x_plan; // init w sim r
- fftw_plan _disp_z_plan; // init w sim r
- fftw_plan _N_x_plan; // init w sim r
- fftw_plan _N_z_plan; // init w sim r
- fftw_plan _Jxx_plan; // init w sim r
- fftw_plan _Jxz_plan; // init w sim r
- fftw_plan _Jzz_plan; // init w sim r
+ fftw_plan _disp_y_plan; /* init w sim r */
+ fftw_plan _disp_x_plan; /* init w sim r */
+ fftw_plan _disp_z_plan; /* init w sim r */
+ fftw_plan _N_x_plan; /* init w sim r */
+ fftw_plan _N_z_plan; /* init w sim r */
+ fftw_plan _Jxx_plan; /* init w sim r */
+ fftw_plan _Jxz_plan; /* init w sim r */
+ fftw_plan _Jzz_plan; /* init w sim r */
/* two dimensional arrays of float */
- double *_disp_y; // init w sim w via plan?
- double *_N_x; // init w sim w via plan?
- /*float * _N_y; all member of this array has same values, so convert this array to a float to reduce memory usage (MEM01)*/
- double _N_y; // sim w ********* can be rearranged?
- double *_N_z; // init w sim w via plan?
- double *_disp_x; // init w sim w via plan?
- double *_disp_z; // init w sim w via plan?
+ double *_disp_y; /* init w sim w via plan? */
+ double *_N_x; /* init w sim w via plan? */
+ /* all member of this array has same values, so convert this array to a float to reduce memory usage (MEM01)*/
+ /*float * _N_y; */
+ double _N_y; /* sim w ********* can be rearranged? */
+ double *_N_z; /* init w sim w via plan? */
+ double *_disp_x; /* init w sim w via plan? */
+ double *_disp_z; /* init w sim w via plan? */
/* two dimensional arrays of float */
/* Jacobian and minimum eigenvalue */
- double *_Jxx; // init w sim w
- double *_Jzz; // init w sim w
- double *_Jxz; // init w sim w
+ double *_Jxx; /* init w sim w */
+ double *_Jzz; /* init w sim w */
+ double *_Jxz; /* init w sim w */
/* one dimensional float array */
- float *_kx; // init w sim r
- float *_kz; // init w sim r
+ float *_kx; /* init w sim r */
+ float *_kz; /* init w sim r */
/* two dimensional complex array */
- fftw_complex *_h0; // init w sim r
- fftw_complex *_h0_minus; // init w sim r
+ fftw_complex *_h0; /* init w sim r */
+ fftw_complex *_h0_minus; /* init w sim r */
/* two dimensional float array */
- float *_k; // init w sim r
+ float *_k; /* init w sim r */
} Ocean;
@@ -152,10 +152,13 @@ static float nextfr(float min, float max)
static float gaussRand(void)
{
- float x; // Note: to avoid numerical problems with very small
- float y; // numbers, we make these variables singe-precision
- float length2; // floats, but later we call the double-precision log()
- // and sqrt() functions instead of logf() and sqrtf().
+ /* Note: to avoid numerical problems with very small numbers, we make these variables singe-precision floats,
+ * but later we call the double-precision log() and sqrt() functions instead of logf() and sqrtf().
+ */
+ float x;
+ float y;
+ float length2;
+
do {
x = (float) (nextfr(-1, 1));
y = (float)(nextfr(-1, 1));
@@ -167,12 +170,7 @@ static float gaussRand(void)
/**
* Some useful functions
- * */
-MINLINE float lerp(float a, float b, float f)
-{
- return a + (b - a) * f;
-}
-
+ */
MINLINE float catrom(float p0, float p1, float p2, float p3, float f)
{
return 0.5f * ((2.0f * p1) +
@@ -186,23 +184,24 @@ MINLINE float omega(float k, float depth)
return sqrtf(GRAVITY * k * tanhf(k * depth));
}
-// modified Phillips spectrum
+/* modified Phillips spectrum */
static float Ph(struct Ocean *o, float kx, float kz)
{
float tmp;
float k2 = kx * kx + kz * kz;
if (k2 == 0.0f) {
- return 0.0f; // no DC component
+ return 0.0f; /* no DC component */
}
- // damp out the waves going in the direction opposite the wind
+ /* damp out the waves going in the direction opposite the wind */
tmp = (o->_wx * kx + o->_wz * kz) / sqrtf(k2);
if (tmp < 0) {
tmp *= o->_damp_reflections;
}
- return o->_A * expf(-1.0f / (k2 * (o->_L * o->_L))) * expf(-k2 * (o->_l * o->_l)) * powf(fabsf(tmp), o->_wind_alignment) / (k2 * k2);
+ return o->_A * expf(-1.0f / (k2 * (o->_L * o->_L))) * expf(-k2 * (o->_l * o->_l)) *
+ powf(fabsf(tmp), o->_wind_alignment) / (k2 * k2);
}
static void compute_eigenstuff(struct OceanResult *ocr, float jxx, float jzz, float jxz)
@@ -240,7 +239,7 @@ static void init_complex(fftw_complex cmpl, float real, float image)
cmpl[1] = image;
}
-#if 0 // unused
+#if 0 /* unused */
static void add_complex_f(fftw_complex res, fftw_complex cmpl, float f)
{
res[0] = cmpl[0] + f;
@@ -306,7 +305,7 @@ void BKE_ocean_eval_uv(struct Ocean *oc, struct OceanResult *ocr, float u, float
float frac_x, frac_z;
float uu, vv;
- // first wrap the texture so 0 <= (u, v) < 1
+ /* first wrap the texture so 0 <= (u, v) < 1 */
u = fmodf(u, 1.0f);
v = fmodf(v, 1.0f);
@@ -334,7 +333,9 @@ void BKE_ocean_eval_uv(struct Ocean *oc, struct OceanResult *ocr, float u, float
j1 = j1 % oc->_N;
-#define BILERP(m) (lerp(lerp(m[i0 * oc->_N + j0], m[i1 * oc->_N + j0], frac_x), lerp(m[i0 * oc->_N + j1], m[i1 * oc->_N + j1], frac_x), frac_z))
+#define BILERP(m) (interpf(interpf(m[i1 * oc->_N + j1], m[i0 * oc->_N + j1], frac_x), \
+ interpf(m[i1 * oc->_N + j0], m[i0 * oc->_N + j0], frac_x), \
+ frac_z))
{
if (oc->_do_disp_y) {
ocr->disp[1] = BILERP(oc->_disp_y);
@@ -364,14 +365,14 @@ void BKE_ocean_eval_uv(struct Ocean *oc, struct OceanResult *ocr, float u, float
BLI_rw_mutex_unlock(&oc->oceanmutex);
}
-// use catmullrom interpolation rather than linear
+/* use catmullrom interpolation rather than linear */
void BKE_ocean_eval_uv_catrom(struct Ocean *oc, struct OceanResult *ocr, float u, float v)
{
int i0, i1, i2, i3, j0, j1, j2, j3;
float frac_x, frac_z;
float uu, vv;
- // first wrap the texture so 0 <= (u, v) < 1
+ /* first wrap the texture so 0 <= (u, v) < 1 */
u = fmod(u, 1.0f);
v = fmod(v, 1.0f);
@@ -408,11 +409,15 @@ void BKE_ocean_eval_uv_catrom(struct Ocean *oc, struct OceanResult *ocr, float u
j0 = j0 < 0 ? j0 + oc->_N : j0;
j3 = j3 >= oc->_N ? j3 - oc->_N : j3;
-#define INTERP(m) catrom(catrom(m[i0 * oc->_N + j0], m[i1 * oc->_N + j0], m[i2 * oc->_N + j0], m[i3 * oc->_N + j0], frac_x), \
- catrom(m[i0 * oc->_N + j1], m[i1 * oc->_N + j1], m[i2 * oc->_N + j1], m[i3 * oc->_N + j1], frac_x), \
- catrom(m[i0 * oc->_N + j2], m[i1 * oc->_N + j2], m[i2 * oc->_N + j2], m[i3 * oc->_N + j2], frac_x), \
- catrom(m[i0 * oc->_N + j3], m[i1 * oc->_N + j3], m[i2 * oc->_N + j3], m[i3 * oc->_N + j3], frac_x), \
- frac_z)
+#define INTERP(m) catrom(catrom(m[i0 * oc->_N + j0], m[i1 * oc->_N + j0], \
+ m[i2 * oc->_N + j0], m[i3 * oc->_N + j0], frac_x), \
+ catrom(m[i0 * oc->_N + j1], m[i1 * oc->_N + j1], \
+ m[i2 * oc->_N + j1], m[i3 * oc->_N + j1], frac_x), \
+ catrom(m[i0 * oc->_N + j2], m[i1 * oc->_N + j2], \
+ m[i2 * oc->_N + j2], m[i3 * oc->_N + j2], frac_x), \
+ catrom(m[i0 * oc->_N + j3], m[i1 * oc->_N + j3], \
+ m[i2 * oc->_N + j3], m[i3 * oc->_N + j3], frac_x), \
+ frac_z)
{
if (oc->_do_disp_y) {
@@ -452,9 +457,9 @@ void BKE_ocean_eval_xz_catrom(struct Ocean *oc, struct OceanResult *ocr, float x
BKE_ocean_eval_uv_catrom(oc, ocr, x / oc->_Lx, z / oc->_Lz);
}
-// note that this doesn't wrap properly for i, j < 0, but its
-// not really meant for that being just a way to get the raw data out
-// to save in some image format.
+/* note that this doesn't wrap properly for i, j < 0, but its not really meant for that being just a way to get
+ * the raw data out to save in some image format.
+ */
void BKE_ocean_eval_ij(struct Ocean *oc, struct OceanResult *ocr, int i, int j)
{
BLI_rw_mutex_lock(&oc->oceanmutex, THREAD_LOCK_READ);
@@ -496,11 +501,10 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
BLI_rw_mutex_lock(&o->oceanmutex, THREAD_LOCK_WRITE);
- // compute a new htilda
+ /* compute a new htilda */
#pragma omp parallel for private(i, j)
for (i = 0; i < o->_M; ++i) {
- // note the <= _N/2 here, see the fftw doco about
- // the mechanics of the complex->real fft storage
+ /* note the <= _N/2 here, see the fftw doco about the mechanics of the complex->real fft storage */
for (j = 0; j <= o->_N / 2; ++j) {
fftw_complex exp_param1;
fftw_complex exp_param2;
@@ -527,15 +531,15 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
#pragma omp section
{
if (o->_do_disp_y) {
- // y displacement
+ /* y displacement */
fftw_execute(o->_disp_y_plan);
}
- } // section 1
+ } /* section 1 */
#pragma omp section
{
if (o->_do_chop) {
- // x displacement
+ /* x displacement */
for (i = 0; i < o->_M; ++i) {
for (j = 0; j <= o->_N / 2; ++j) {
fftw_complex mul_param;
@@ -546,18 +550,21 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
mul_complex_f(mul_param, mul_param, chop_amount);
mul_complex_c(mul_param, mul_param, minus_i);
mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
- mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0f ? 0.0f : o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j]));
+ mul_complex_f(mul_param, mul_param,
+ ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
+ 0.0f :
+ o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j]));
init_complex(o->_fft_in_x[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
}
}
fftw_execute(o->_disp_x_plan);
}
- } //section 2
+ } /* section 2 */
#pragma omp section
{
if (o->_do_chop) {
- // z displacement
+ /* z displacement */
for (i = 0; i < o->_M; ++i) {
for (j = 0; j <= o->_N / 2; ++j) {
fftw_complex mul_param;
@@ -568,28 +575,34 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
mul_complex_f(mul_param, mul_param, chop_amount);
mul_complex_c(mul_param, mul_param, minus_i);
mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
- mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0f ? 0.0f : o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
+ mul_complex_f(mul_param, mul_param,
+ ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
+ 0.0f :
+ o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
init_complex(o->_fft_in_z[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
}
}
fftw_execute(o->_disp_z_plan);
}
- } // section 3
+ } /* section 3 */
#pragma omp section
{
if (o->_do_jacobian) {
- // Jxx
+ /* Jxx */
for (i = 0; i < o->_M; ++i) {
for (j = 0; j <= o->_N / 2; ++j) {
fftw_complex mul_param;
- //init_complex(mul_param, -scale, 0);
+ /* init_complex(mul_param, -scale, 0); */
init_complex(mul_param, -1, 0);
mul_complex_f(mul_param, mul_param, chop_amount);
mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
- mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0f ? 0.0f : o->_kx[i] * o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j]));
+ mul_complex_f(mul_param, mul_param,
+ ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
+ 0.0f :
+ o->_kx[i] * o->_kx[i] / o->_k[i * (1 + o->_N / 2) + j]));
init_complex(o->_fft_in_jxx[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
}
}
@@ -601,22 +614,25 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
}
}
}
- } // section 4
+ } /* section 4 */
#pragma omp section
{
if (o->_do_jacobian) {
- // Jzz
+ /* Jzz */
for (i = 0; i < o->_M; ++i) {
for (j = 0; j <= o->_N / 2; ++j) {
fftw_complex mul_param;
- //init_complex(mul_param, -scale, 0);
+ /* init_complex(mul_param, -scale, 0); */
init_complex(mul_param, -1, 0);
mul_complex_f(mul_param, mul_param, chop_amount);
mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
- mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0f ? 0.0f : o->_kz[j] * o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
+ mul_complex_f(mul_param, mul_param,
+ ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
+ 0.0f :
+ o->_kz[j] * o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
init_complex(o->_fft_in_jzz[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
}
}
@@ -627,32 +643,35 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
}
}
}
- } // section 5
+ } /* section 5 */
#pragma omp section
{
if (o->_do_jacobian) {
- // Jxz
+ /* Jxz */
for (i = 0; i < o->_M; ++i) {
for (j = 0; j <= o->_N / 2; ++j) {
fftw_complex mul_param;
- //init_complex(mul_param, -scale, 0);
+ /* init_complex(mul_param, -scale, 0); */
init_complex(mul_param, -1, 0);
mul_complex_f(mul_param, mul_param, chop_amount);
mul_complex_c(mul_param, mul_param, o->_htilda[i * (1 + o->_N / 2) + j]);
- mul_complex_f(mul_param, mul_param, (o->_k[i * (1 + o->_N / 2) + j] == 0.0f ? 0.0f : o->_kx[i] * o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
+ mul_complex_f(mul_param, mul_param,
+ ((o->_k[i * (1 + o->_N / 2) + j] == 0.0f) ?
+ 0.0f :
+ o->_kx[i] * o->_kz[j] / o->_k[i * (1 + o->_N / 2) + j]));
init_complex(o->_fft_in_jxz[i * (1 + o->_N / 2) + j], real_c(mul_param), image_c(mul_param));
}
}
fftw_execute(o->_Jxz_plan);
}
- } // section 6
+ } /* section 6 */
#pragma omp section
{
- // fft normals
+ /* fft normals */
if (o->_do_normals) {
for (i = 0; i < o->_M; ++i) {
for (j = 0; j <= o->_N / 2; ++j) {
@@ -667,7 +686,7 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
fftw_execute(o->_N_x_plan);
}
- } // section 7
+ } /* section 7 */
#pragma omp section
{
@@ -694,9 +713,9 @@ void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount
#endif
o->_N_y = 1.0f / scale;
}
- } // section 8
+ } /* section 8 */
- } // omp sections
+ } /* omp sections */
BLI_rw_mutex_unlock(&o->oceanmutex);
}
@@ -726,7 +745,8 @@ static void set_height_normalize_factor(struct Ocean *oc)
BLI_rw_mutex_unlock(&oc->oceanmutex);
- if (max_h == 0.0f) max_h = 0.00001f; // just in case ...
+ if (max_h == 0.0f)
+ max_h = 0.00001f; /* just in case ... */
res = 1.0f / (max_h);
@@ -743,7 +763,8 @@ struct Ocean *BKE_add_ocean(void)
}
void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V, float l, float A, float w, float damp,
- float alignment, float depth, float time, short do_height_field, short do_chop, short do_normals, short do_jacobian, int seed)
+ float alignment, float depth, float time, short do_height_field, short do_chop, short do_normals,
+ short do_jacobian, int seed)
{
int i, j, ii;
@@ -761,8 +782,8 @@ void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V,
o->_Lx = Lx;
o->_Lz = Lz;
o->_wx = cos(w);
- o->_wz = -sin(w); // wave direction
- o->_L = V * V / GRAVITY; // largest wave for a given velocity V
+ o->_wz = -sin(w); /* wave direction */
+ o->_L = V * V / GRAVITY; /* largest wave for a given velocity V */
o->time = time;
o->_do_disp_y = do_height_field;
@@ -776,30 +797,30 @@ void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V,
o->_kx = (float *) MEM_mallocN(o->_M * sizeof(float), "ocean_kx");
o->_kz = (float *) MEM_mallocN(o->_N * sizeof(float), "ocean_kz");
- // make this robust in the face of erroneous usage
+ /* make this robust in the face of erroneous usage */
if (o->_Lx == 0.0f)
o->_Lx = 0.001f;
if (o->_Lz == 0.0f)
o->_Lz = 0.001f;
- // the +ve components and DC
+ /* the +ve components and DC */
for (i = 0; i <= o->_M / 2; ++i)
o->_kx[i] = 2.0f * (float)M_PI * i / o->_Lx;
- // the -ve components
+ /* the -ve components */
for (i = o->_M - 1, ii = 0; i > o->_M / 2; --i, ++ii)
o->_kx[i] = -2.0f * (float)M_PI * ii / o->_Lx;
- // the +ve components and DC
+ /* the +ve components and DC */
for (i = 0; i <= o->_N / 2; ++i)
o->_kz[i] = 2.0f * (float)M_PI * i / o->_Lz;
- // the -ve components
+ /* the -ve components */
for (i = o->_N - 1, ii = 0; i > o->_N / 2; --i, ++ii)
o->_kz[i] = -2.0f * (float)M_PI * ii / o->_Lz;
- // pre-calculate the k matrix
+ /* pre-calculate the k matrix */
for (i = 0; i < o->_M; ++i)
for (j = 0; j <= o->_N / 2; ++j)
o->_k[i * (1 + o->_N / 2) + j] = sqrt(o->_kx[i] * o->_kx[i] + o->_kz[j] * o->_kz[j]);
@@ -819,11 +840,11 @@ void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V,
}
}
- o->_fft_in = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in");
- o->_htilda = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_htilda");
+ o->_fft_in = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in");
+ o->_htilda = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_htilda");
if (o->_do_disp_y) {
- o->_disp_y = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_y");
+ o->_disp_y = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_y");
o->_disp_y_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in, o->_disp_y, FFTW_ESTIMATE);
}
@@ -831,32 +852,35 @@ void BKE_init_ocean(struct Ocean *o, int M, int N, float Lx, float Lz, float V,
o->_fft_in_nx = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_nx");
o->_fft_in_nz = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_nz");
- o->_N_x = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_x");
+ o->_N_x = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_x");
/* o->_N_y = (float *) fftwf_malloc(o->_M * o->_N * sizeof(float)); (MEM01) */
- o->_N_z = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_z");
+ o->_N_z = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_N_z");
o->_N_x_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_nx, o->_N_x, FFTW_ESTIMATE);
o->_N_z_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_nz, o->_N_z, FFTW_ESTIMATE);
}
if (o->_do_chop) {
- o->_fft_in_x = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_x");
- o->_fft_in_z = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_z");
+ o->_fft_in_x = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_x");
+ o->_fft_in_z = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_z");
- o->_disp_x = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_x");
- o->_disp_z = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_z");
+ o->_disp_x = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_x");
+ o->_disp_z = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_disp_z");
o->_disp_x_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_x, o->_disp_x, FFTW_ESTIMATE);
o->_disp_z_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_z, o->_disp_z, FFTW_ESTIMATE);
}
if (o->_do_jacobian) {
- o->_fft_in_jxx = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_jxx");
- o->_fft_in_jzz = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_jzz");
- o->_fft_in_jxz = (fftw_complex *) MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex), "ocean_fft_in_jxz");
+ o->_fft_in_jxx = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
+ "ocean_fft_in_jxx");
+ o->_fft_in_jzz = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
+ "ocean_fft_in_jzz");
+ o->_fft_in_jxz = (fftw_complex *)MEM_mallocN(o->_M * (1 + o->_N / 2) * sizeof(fftw_complex),
+ "ocean_fft_in_jxz");
- o->_Jxx = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jxx");
- o->_Jzz = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jzz");
- o->_Jxz = (double *) MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jxz");
+ o->_Jxx = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jxx");
+ o->_Jzz = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jzz");
+ o->_Jxz = (double *)MEM_mallocN(o->_M * o->_N * sizeof(double), "ocean_Jxz");
o->_Jxx_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jxx, o->_Jxx, FFTW_ESTIMATE);
o->_Jzz_plan = fftw_plan_dft_c2r_2d(o->_M, o->_N, o->_fft_in_jzz, o->_Jzz, FFTW_ESTIMATE);
@@ -967,7 +991,7 @@ static void cache_filename(char *string, const char *path, const char *relbase,
BLI_join_dirfile(cachepath, sizeof(cachepath), path, fname);
- BKE_makepicstring(string, cachepath, relbase, frame, R_IMF_IMTYPE_OPENEXR, 1, TRUE);
+ BKE_makepicstring_from_type(string, cachepath, relbase, frame, R_IMF_IMTYPE_OPENEXR, 1, TRUE);
}
/* silly functions but useful to inline when the args do a lot of indirections */
@@ -1076,8 +1100,7 @@ void BKE_ocean_cache_eval_ij(struct OceanCache *och, struct OceanResult *ocr, in
}
}
-struct OceanCache *BKE_init_ocean_cache(const char *bakepath, const char *relbase,
- int start, int end, float wave_scale,
+struct OceanCache *BKE_init_ocean_cache(const char *bakepath, const char *relbase, int start, int end, float wave_scale,
float chop_amount, float foam_coverage, float foam_fade, int resolution)
{
OceanCache *och = MEM_callocN(sizeof(OceanCache), "ocean cache data");
@@ -1112,7 +1135,7 @@ void BKE_simulate_ocean_cache(struct OceanCache *och, int frame)
/* ibufs array is zero based, but filenames are based on frame numbers */
/* still need to clamp frame numbers to valid range of images on disk though */
CLAMP(frame, och->start, och->end);
- f = frame - och->start; // shift to 0 based
+ f = frame - och->start; /* shift to 0 based */
/* if image is already loaded in mem, return */
if (och->ibufs_disp[f] != NULL) return;
@@ -1121,22 +1144,35 @@ void BKE_simulate_ocean_cache(struct OceanCache *och, int frame)
cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_DISPLACE);
och->ibufs_disp[f] = IMB_loadiffname(string, 0, NULL);
- //if (och->ibufs_disp[f] == NULL) printf("error loading %s\n", string);
- //else printf("loaded cache %s\n", string);
+#if 0
+ if (och->ibufs_disp[f] == NULL)
+ printf("error loading %s\n", string);
+ else
+ printf("loaded cache %s\n", string);
+#endif
cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_FOAM);
och->ibufs_foam[f] = IMB_loadiffname(string, 0, NULL);
- //if (och->ibufs_foam[f] == NULL) printf("error loading %s\n", string);
- //else printf("loaded cache %s\n", string);
+#if 0
+ if (och->ibufs_foam[f] == NULL)
+ printf("error loading %s\n", string);
+ else
+ printf("loaded cache %s\n", string);
+#endif
cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_NORMAL);
och->ibufs_norm[f] = IMB_loadiffname(string, 0, NULL);
- //if (och->ibufs_norm[f] == NULL) printf("error loading %s\n", string);
- //else printf("loaded cache %s\n", string);
+#if 0
+ if (och->ibufs_norm[f] == NULL)
+ printf("error loading %s\n", string);
+ else
+ printf("loaded cache %s\n", string);
+#endif
}
-void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(void *, float progress, int *cancel), void *update_cb_data)
+void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(void *, float progress, int *cancel),
+ void *update_cb_data)
{
/* note: some of these values remain uninitialized unless certain options
* are enabled, take care that BKE_ocean_eval_ij() initializes a member
@@ -1197,13 +1233,13 @@ void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(v
pr = prev_foam[res_x * y + x];
}
- /* r = BLI_frand(); */ /* UNUSED */ // randomly reduce foam
+ /* r = BLI_frand(); */ /* UNUSED */ /* randomly reduce foam */
- //pr = pr * och->foam_fade; // overall fade
+ /* pr = pr * och->foam_fade; */ /* overall fade */
- // remember ocean coord sys is Y up!
- // break up the foam where height (Y) is low (wave valley),
- // and X and Z displacement is greatest
+ /* remember ocean coord sys is Y up!
+ * break up the foam where height (Y) is low (wave valley), and X and Z displacement is greatest
+ */
#if 0
vec[0] = ocr.disp[0];
@@ -1219,22 +1255,27 @@ void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(v
neg_eplus = ocr.Eplus[2] < 0.0f ? 1.0f + ocr.Eplus[2] : 1.0f;
neg_eplus = neg_eplus < 0.0f ? 0.0f : neg_eplus;
- //if (ocr.disp[1] < 0.0 || r > och->foam_fade)
- // pr *= och->foam_fade;
+#if 0
+ if (ocr.disp[1] < 0.0 || r > och->foam_fade)
+ pr *= och->foam_fade;
- //pr = pr * (1.0 - hor_stretch) * ocr.disp[1];
- //pr = pr * neg_disp * neg_eplus;
+ pr = pr * (1.0 - hor_stretch) * ocr.disp[1];
+ pr = pr * neg_disp * neg_eplus;
+#endif
- if (pr < 1.0f) pr *= pr;
+ if (pr < 1.0f)
+ pr *= pr;
pr *= och->foam_fade * (0.75f + neg_eplus * 0.25f);
-
- foam_result = pr + ocr.foam;
+ /* A full clamping should not be needed! */
+ foam_result = min_ff(pr + ocr.foam, 1.0f);
prev_foam[res_x * y + x] = foam_result;
+ /*foam_result = min_ff(foam_result, 1.0f); */
+
value_to_rgba_unit_alpha(&ibuf_foam->rect_float[4 * (res_x * y + x)], foam_result);
}
@@ -1279,7 +1320,7 @@ void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(v
och->baked = 1;
}
-#else // WITH_OCEANSIM
+#else /* WITH_OCEANSIM */
/* stub */
typedef struct Ocean {
@@ -1297,8 +1338,9 @@ void BKE_ocean_eval_uv(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr)
{
}
-// use catmullrom interpolation rather than linear
-void BKE_ocean_eval_uv_catrom(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), float UNUSED(u), float UNUSED(v))
+/* use catmullrom interpolation rather than linear */
+void BKE_ocean_eval_uv_catrom(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), float UNUSED(u),
+ float UNUSED(v))
{
}
@@ -1306,7 +1348,8 @@ void BKE_ocean_eval_xz(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr)
{
}
-void BKE_ocean_eval_xz_catrom(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), float UNUSED(x), float UNUSED(z))
+void BKE_ocean_eval_xz_catrom(struct Ocean *UNUSED(oc), struct OceanResult *UNUSED(ocr), float UNUSED(x),
+ float UNUSED(z))
{
}
@@ -1325,8 +1368,10 @@ struct Ocean *BKE_add_ocean(void)
return oc;
}
-void BKE_init_ocean(struct Ocean *UNUSED(o), int UNUSED(M), int UNUSED(N), float UNUSED(Lx), float UNUSED(Lz), float UNUSED(V), float UNUSED(l), float UNUSED(A), float UNUSED(w), float UNUSED(damp),
- float UNUSED(alignment), float UNUSED(depth), float UNUSED(time), short UNUSED(do_height_field), short UNUSED(do_chop), short UNUSED(do_normals), short UNUSED(do_jacobian), int UNUSED(seed))
+void BKE_init_ocean(struct Ocean *UNUSED(o), int UNUSED(M), int UNUSED(N), float UNUSED(Lx), float UNUSED(Lz),
+ float UNUSED(V), float UNUSED(l), float UNUSED(A), float UNUSED(w), float UNUSED(damp),
+ float UNUSED(alignment), float UNUSED(depth), float UNUSED(time), short UNUSED(do_height_field),
+ short UNUSED(do_chop), short UNUSED(do_normals), short UNUSED(do_jacobian), int UNUSED(seed))
{
}
@@ -1351,17 +1396,19 @@ void BKE_free_ocean_cache(struct OceanCache *och)
MEM_freeN(och);
}
-void BKE_ocean_cache_eval_uv(struct OceanCache *UNUSED(och), struct OceanResult *UNUSED(ocr), int UNUSED(f), float UNUSED(u), float UNUSED(v))
+void BKE_ocean_cache_eval_uv(struct OceanCache *UNUSED(och), struct OceanResult *UNUSED(ocr), int UNUSED(f),
+ float UNUSED(u), float UNUSED(v))
{
}
-void BKE_ocean_cache_eval_ij(struct OceanCache *UNUSED(och), struct OceanResult *UNUSED(ocr), int UNUSED(f), int UNUSED(i), int UNUSED(j))
+void BKE_ocean_cache_eval_ij(struct OceanCache *UNUSED(och), struct OceanResult *UNUSED(ocr), int UNUSED(f),
+ int UNUSED(i), int UNUSED(j))
{
}
-OceanCache *BKE_init_ocean_cache(const char *UNUSED(bakepath), const char *UNUSED(relbase),
- int UNUSED(start), int UNUSED(end), float UNUSED(wave_scale),
- float UNUSED(chop_amount), float UNUSED(foam_coverage), float UNUSED(foam_fade), int UNUSED(resolution))
+OceanCache *BKE_init_ocean_cache(const char *UNUSED(bakepath), const char *UNUSED(relbase), int UNUSED(start),
+ int UNUSED(end), float UNUSED(wave_scale), float UNUSED(chop_amount),
+ float UNUSED(foam_coverage), float UNUSED(foam_fade), int UNUSED(resolution))
{
OceanCache *och = MEM_callocN(sizeof(OceanCache), "ocean cache data");
@@ -1372,9 +1419,10 @@ void BKE_simulate_ocean_cache(struct OceanCache *UNUSED(och), int UNUSED(frame))
{
}
-void BKE_bake_ocean(struct Ocean *UNUSED(o), struct OceanCache *UNUSED(och), void (*update_cb)(void *, float progress, int *cancel), void *UNUSED(update_cb_data))
+void BKE_bake_ocean(struct Ocean *UNUSED(o), struct OceanCache *UNUSED(och),
+ void (*update_cb)(void *, float progress, int *cancel), void *UNUSED(update_cb_data))
{
/* unused */
(void)update_cb;
}
-#endif // WITH_OCEANSIM
+#endif /* WITH_OCEANSIM */ \ No newline at end of file
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index dec49f417ae..9f77094994d 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -43,6 +43,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_image_types.h"
+#include "DNA_ID.h"
#include "DNA_sound_types.h"
#include "DNA_vfont_types.h"
#include "DNA_packedFile_types.h"
@@ -226,6 +227,7 @@ PackedFile *newPackedFile(ReportList *reports, const char *filename, const char
return (pf);
}
+/* no libraries for now */
void packAll(Main *bmain, ReportList *reports)
{
Image *ima;
@@ -538,6 +540,41 @@ int unpackImage(ReportList *reports, Image *ima, int how)
return(ret_value);
}
+int unpackLibraries(Main *bmain, ReportList *reports)
+{
+ Library *lib;
+ char *newname;
+ int ret_value = RET_ERROR;
+
+ for (lib = bmain->library.first; lib; lib = lib->id.next) {
+ if (lib->packedfile && lib->name[0]) {
+
+ newname = unpackFile(reports, lib->filepath, lib->filepath, lib->packedfile, PF_WRITE_ORIGINAL);
+ if (newname != NULL) {
+ ret_value = RET_OK;
+
+ printf("Saved .blend library: %s\n", newname);
+
+ freePackedFile(lib->packedfile);
+ lib->packedfile = NULL;
+
+ MEM_freeN(newname);
+ }
+ }
+ }
+
+ return(ret_value);
+}
+
+void packLibraries(Main *bmain, ReportList *reports)
+{
+ Library *lib;
+
+ for (lib = bmain->library.first; lib; lib = lib->id.next)
+ if (lib->packedfile == NULL)
+ lib->packedfile = newPackedFile(reports, lib->name, bmain->name);
+}
+
void unpackAll(Main *bmain, ReportList *reports, int how)
{
Image *ima;
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index fa5268e039e..5847e7508f0 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -212,7 +212,7 @@ int paint_is_face_hidden(const MFace *f, const MVert *mvert)
}
/* returns non-zero if any of the corners of the grid
- * face whose inner corner is at (x,y) are hidden,
+ * face whose inner corner is at (x, y) are hidden,
* zero otherwise */
int paint_is_grid_face_hidden(const unsigned int *grid_hidden,
int gridsize, int x, int y)
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 090082b333d..3b897e94241 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -522,9 +522,9 @@ static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys)
vec[0]/=delta[0];
vec[1]/=delta[1];
vec[2]/=delta[2];
- (pa + ((int)(vec[0] * (size[0] - 1)) * res +
- (int)(vec[1] * (size[1] - 1))) * res +
- (int)(vec[2] * (size[2] - 1)))->flag &= ~PARS_UNEXIST;
+ pa[((int)(vec[0] * (size[0] - 1)) * res +
+ (int)(vec[1] * (size[1] - 1))) * res +
+ (int)(vec[2] * (size[2] - 1))].flag &= ~PARS_UNEXIST;
}
}
else if (ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)) {
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 209461bad2f..2df2dd631d5 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -41,124 +41,12 @@
#include "GPU_buffers.h"
+#include "pbvh_intern.h"
+
#define LEAF_LIMIT 10000
//#define PERFCNTRS
-/* Axis-aligned bounding box */
-typedef struct {
- float bmin[3], bmax[3];
-} BB;
-
-/* Axis-aligned bounding box with centroid */
-typedef struct {
- float bmin[3], bmax[3], bcentroid[3];
-} BBC;
-
-struct PBVHNode {
- /* Opaque handle for drawing code */
- GPU_Buffers *draw_buffers;
-
- /* Voxel bounds */
- BB vb;
- BB orig_vb;
-
- /* For internal nodes, the offset of the children in the PBVH
- * 'nodes' array. */
- int children_offset;
-
- /* Pointer into the PBVH prim_indices array and the number of
- * primitives used by this leaf node.
- *
- * Used for leaf nodes in both mesh- and multires-based PBVHs.
- */
- int *prim_indices;
- unsigned int totprim;
-
- /* Array of indices into the mesh's MVert array. Contains the
- * indices of all vertices used by faces that are within this
- * node's bounding box.
- *
- * Note that a vertex might be used by a multiple faces, and
- * these faces might be in different leaf nodes. Such a vertex
- * will appear in the vert_indices array of each of those leaf
- * nodes.
- *
- * In order to support cases where you want access to multiple
- * nodes' vertices without duplication, the vert_indices array
- * is ordered such that the first part of the array, up to
- * index 'uniq_verts', contains "unique" vertex indices. These
- * vertices might not be truly unique to this node, but if
- * they appear in another node's vert_indices array, they will
- * be above that node's 'uniq_verts' value.
- *
- * Used for leaf nodes in a mesh-based PBVH (not multires.)
- */
- int *vert_indices;
- unsigned int uniq_verts, face_verts;
-
- /* An array mapping face corners into the vert_indices
- * array. The array is sized to match 'totprim', and each of
- * the face's corners gets an index into the vert_indices
- * array, in the same order as the corners in the original
- * MFace. The fourth value should not be used if the original
- * face is a triangle.
- *
- * Used for leaf nodes in a mesh-based PBVH (not multires.)
- */
- int (*face_vert_indices)[4];
-
- /* Indicates whether this node is a leaf or not; also used for
- * marking various updates that need to be applied. */
- PBVHNodeFlags flag : 8;
-
- /* Used for raycasting: how close bb is to the ray point. */
- float tmin;
-
- int proxy_count;
- PBVHProxyNode *proxies;
-};
-
-struct PBVH {
- PBVHType type;
-
- PBVHNode *nodes;
- int node_mem_count, totnode;
-
- int *prim_indices;
- int totprim;
- int totvert;
-
- int leaf_limit;
-
- /* Mesh data */
- MVert *verts;
- MFace *faces;
- CustomData *vdata;
-
- /* Grid Data */
- CCGKey gridkey;
- CCGElem **grids;
- DMGridAdjacency *gridadj;
- void **gridfaces;
- const DMFlagMat *grid_flag_mats;
- int totgrid;
- BLI_bitmap *grid_hidden;
-
- /* Only used during BVH build and update,
- * don't need to remain valid after */
- BLI_bitmap vert_bitmap;
-
-#ifdef PERFCNTRS
- int perf_modified;
-#endif
-
- /* flag are verts/faces deformed */
- int deformed;
-
- int show_diffuse_color;
-};
-
#define STACK_FIXED_DEPTH 100
typedef struct PBVHStack {
@@ -168,7 +56,7 @@ typedef struct PBVHStack {
typedef struct PBVHIter {
PBVH *bvh;
- BLI_pbvh_SearchCallback scb;
+ BKE_pbvh_SearchCallback scb;
void *search_data;
PBVHStack *stack;
@@ -178,14 +66,14 @@ typedef struct PBVHIter {
int stackspace;
} PBVHIter;
-static void BB_reset(BB *bb)
+void BB_reset(BB *bb)
{
bb->bmin[0] = bb->bmin[1] = bb->bmin[2] = FLT_MAX;
bb->bmax[0] = bb->bmax[1] = bb->bmax[2] = -FLT_MAX;
}
/* Expand the bounding box to include a new coordinate */
-static void BB_expand(BB *bb, float co[3])
+void BB_expand(BB *bb, const float co[3])
{
int i;
for (i = 0; i < 3; ++i) {
@@ -195,7 +83,7 @@ static void BB_expand(BB *bb, float co[3])
}
/* Expand the bounding box to include another bounding box */
-static void BB_expand_with_bb(BB *bb, BB *bb2)
+void BB_expand_with_bb(BB *bb, BB *bb2)
{
int i;
for (i = 0; i < 3; ++i) {
@@ -205,7 +93,7 @@ static void BB_expand_with_bb(BB *bb, BB *bb2)
}
/* Return 0, 1, or 2 to indicate the widest axis of the bounding box */
-static int BB_widest_axis(BB *bb)
+int BB_widest_axis(const BB *bb)
{
float dim[3];
int i;
@@ -227,7 +115,7 @@ static int BB_widest_axis(BB *bb)
}
}
-static void BBC_update_centroid(BBC *bbc)
+void BBC_update_centroid(BBC *bbc)
{
int i;
for (i = 0; i < 3; ++i)
@@ -244,11 +132,11 @@ static void update_node_vb(PBVH *bvh, PBVHNode *node)
if (node->flag & PBVH_Leaf) {
PBVHVertexIter vd;
- BLI_pbvh_vertex_iter_begin(bvh, node, vd, PBVH_ITER_ALL)
+ BKE_pbvh_vertex_iter_begin(bvh, node, vd, PBVH_ITER_ALL)
{
BB_expand(&vb, vd.co);
}
- BLI_pbvh_vertex_iter_end;
+ BKE_pbvh_vertex_iter_end;
}
else {
BB_expand_with_bb(&vb,
@@ -260,12 +148,12 @@ static void update_node_vb(PBVH *bvh, PBVHNode *node)
node->vb = vb;
}
-//void BLI_pbvh_node_BB_reset(PBVHNode *node)
+//void BKE_pbvh_node_BB_reset(PBVHNode *node)
//{
// BB_reset(&node->vb);
//}
//
-//void BLI_pbvh_node_BB_expand(PBVHNode *node, float co[3])
+//void BKE_pbvh_node_BB_expand(PBVHNode *node, float co[3])
//{
// BB_expand(&node->vb, co);
//}
@@ -332,7 +220,7 @@ static int partition_indices_material(PBVH *bvh, int lo, int hi)
}
}
-static void grow_nodes(PBVH *bvh, int totnode)
+void pbvh_grow_nodes(PBVH *bvh, int totnode)
{
if (totnode > bvh->node_mem_count) {
PBVHNode *prev = bvh->nodes;
@@ -545,7 +433,7 @@ static void build_sub(PBVH *bvh, int node_index, BB *cb, BBC *prim_bbc,
/* Add two child nodes */
bvh->nodes[node_index].children_offset = bvh->totnode;
- grow_nodes(bvh, bvh->totnode + 2);
+ pbvh_grow_nodes(bvh, bvh->totnode + 2);
/* Update parent node bounding box */
update_vb(bvh, &bvh->nodes[node_index], prim_bbc, offset, count);
@@ -605,7 +493,7 @@ static void pbvh_build(PBVH *bvh, BB *cb, BBC *prim_bbc, int totprim)
}
/* Do a full rebuild with on Mesh data structure */
-void BLI_pbvh_build_mesh(PBVH *bvh, MFace *faces, MVert *verts, int totface, int totvert, struct CustomData *vdata)
+void BKE_pbvh_build_mesh(PBVH *bvh, MFace *faces, MVert *verts, int totface, int totvert, struct CustomData *vdata)
{
BBC *prim_bbc = NULL;
BB cb;
@@ -647,7 +535,7 @@ void BLI_pbvh_build_mesh(PBVH *bvh, MFace *faces, MVert *verts, int totface, int
}
/* Do a full rebuild with on Grids data structure */
-void BLI_pbvh_build_grids(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj,
+void BKE_pbvh_build_grids(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj,
int totgrid, CCGKey *key, void **gridfaces, DMFlagMat *flagmats, BLI_bitmap *grid_hidden)
{
BBC *prim_bbc = NULL;
@@ -690,14 +578,14 @@ void BLI_pbvh_build_grids(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj,
MEM_freeN(prim_bbc);
}
-PBVH *BLI_pbvh_new(void)
+PBVH *BKE_pbvh_new(void)
{
PBVH *bvh = MEM_callocN(sizeof(PBVH), "pbvh");
return bvh;
}
-void BLI_pbvh_free(PBVH *bvh)
+void BKE_pbvh_free(PBVH *bvh)
{
PBVHNode *node;
int i;
@@ -712,6 +600,14 @@ void BLI_pbvh_free(PBVH *bvh)
MEM_freeN(node->vert_indices);
if (node->face_vert_indices)
MEM_freeN(node->face_vert_indices);
+ BKE_pbvh_node_layer_disp_free(node);
+
+ if (node->bm_faces)
+ BLI_ghash_free(node->bm_faces, NULL, NULL);
+ if (node->bm_unique_verts)
+ BLI_ghash_free(node->bm_unique_verts, NULL, NULL);
+ if (node->bm_other_verts)
+ BLI_ghash_free(node->bm_other_verts, NULL, NULL);
}
}
@@ -731,10 +627,15 @@ void BLI_pbvh_free(PBVH *bvh)
if (bvh->prim_indices)
MEM_freeN(bvh->prim_indices);
+ if (bvh->bm_vert_to_node)
+ BLI_ghash_free(bvh->bm_vert_to_node, NULL, NULL);
+ if (bvh->bm_face_to_node)
+ BLI_ghash_free(bvh->bm_face_to_node, NULL, NULL);
+
MEM_freeN(bvh);
}
-static void pbvh_iter_begin(PBVHIter *iter, PBVH *bvh, BLI_pbvh_SearchCallback scb, void *search_data)
+static void pbvh_iter_begin(PBVHIter *iter, PBVH *bvh, BKE_pbvh_SearchCallback scb, void *search_data)
{
iter->bvh = bvh;
iter->scb = scb;
@@ -845,8 +746,8 @@ static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter)
return NULL;
}
-void BLI_pbvh_search_gather(PBVH *bvh,
- BLI_pbvh_SearchCallback scb, void *search_data,
+void BKE_pbvh_search_gather(PBVH *bvh,
+ BKE_pbvh_SearchCallback scb, void *search_data,
PBVHNode ***r_array, int *r_tot)
{
PBVHIter iter;
@@ -886,9 +787,9 @@ void BLI_pbvh_search_gather(PBVH *bvh,
*r_tot = tot;
}
-void BLI_pbvh_search_callback(PBVH *bvh,
- BLI_pbvh_SearchCallback scb, void *search_data,
- BLI_pbvh_HitCallback hcb, void *hit_data)
+void BKE_pbvh_search_callback(PBVH *bvh,
+ BKE_pbvh_SearchCallback scb, void *search_data,
+ BKE_pbvh_HitCallback hcb, void *hit_data)
{
PBVHIter iter;
PBVHNode *node;
@@ -929,7 +830,7 @@ static void node_tree_insert(node_tree *tree, node_tree *new_node)
}
}
-static void traverse_tree(node_tree *tree, BLI_pbvh_HitOccludedCallback hcb, void *hit_data, float *tmin)
+static void traverse_tree(node_tree *tree, BKE_pbvh_HitOccludedCallback hcb, void *hit_data, float *tmin)
{
if (tree->left) traverse_tree(tree->left, hcb, hit_data, tmin);
@@ -953,14 +854,14 @@ static void free_tree(node_tree *tree)
free(tree);
}
-float BLI_pbvh_node_get_tmin(PBVHNode *node)
+float BKE_pbvh_node_get_tmin(PBVHNode *node)
{
return node->tmin;
}
-static void BLI_pbvh_search_callback_occluded(PBVH *bvh,
- BLI_pbvh_SearchCallback scb, void *search_data,
- BLI_pbvh_HitOccludedCallback hcb, void *hit_data)
+static void BKE_pbvh_search_callback_occluded(PBVH *bvh,
+ BKE_pbvh_SearchCallback scb, void *search_data,
+ BKE_pbvh_HitOccludedCallback hcb, void *hit_data)
{
PBVHIter iter;
PBVHNode *node;
@@ -1011,6 +912,11 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
float (*vnor)[3];
int n;
+ if (bvh->type == PBVH_BMESH) {
+ pbvh_bmesh_normals_update(nodes, totnode);
+ return;
+ }
+
if (bvh->type != PBVH_FACES)
return;
@@ -1104,8 +1010,7 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
MEM_freeN(vnor);
}
-static void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes,
- int totnode, int flag)
+void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes, int totnode, int flag)
{
int n;
@@ -1152,6 +1057,11 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
node->prim_indices,
node->totprim);
break;
+ case PBVH_BMESH:
+ node->draw_buffers =
+ GPU_build_bmesh_buffers(bvh->flags &
+ PBVH_DYNTOPO_SMOOTH_SHADING);
+ break;
}
node->flag &= ~PBVH_RebuildDrawBuffers;
@@ -1179,6 +1089,13 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
node->face_vert_indices,
bvh->show_diffuse_color);
break;
+ case PBVH_BMESH:
+ GPU_update_bmesh_buffers(node->draw_buffers,
+ bvh->bm,
+ node->bm_faces,
+ node->bm_unique_verts,
+ node->bm_other_verts);
+ break;
}
node->flag &= ~PBVH_UpdateDrawBuffers;
@@ -1217,7 +1134,7 @@ static int pbvh_flush_bb(PBVH *bvh, PBVHNode *node, int flag)
return update;
}
-void BLI_pbvh_update(PBVH *bvh, int flag, float (*face_nors)[3])
+void BKE_pbvh_update(PBVH *bvh, int flag, float (*face_nors)[3])
{
PBVHNode **nodes;
int totnode;
@@ -1225,7 +1142,7 @@ void BLI_pbvh_update(PBVH *bvh, int flag, float (*face_nors)[3])
if (!bvh->nodes)
return;
- BLI_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(flag),
+ BKE_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(flag),
&nodes, &totnode);
if (flag & PBVH_UpdateNormals)
@@ -1240,7 +1157,7 @@ void BLI_pbvh_update(PBVH *bvh, int flag, float (*face_nors)[3])
if (nodes) MEM_freeN(nodes);
}
-void BLI_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3])
+void BKE_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3])
{
PBVHIter iter;
PBVHNode *node;
@@ -1260,7 +1177,7 @@ void BLI_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3])
copy_v3_v3(bb_max, bb.bmax);
}
-void BLI_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface)
+void BKE_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface)
{
PBVHIter iter;
PBVHNode *node;
@@ -1316,36 +1233,42 @@ void BLI_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *tot
/***************************** PBVH Access ***********************************/
-PBVHType BLI_pbvh_type(const PBVH *bvh)
+PBVHType BKE_pbvh_type(const PBVH *bvh)
{
return bvh->type;
}
-BLI_bitmap *BLI_pbvh_grid_hidden(const PBVH *bvh)
+BLI_bitmap *BKE_pbvh_grid_hidden(const PBVH *bvh)
{
BLI_assert(bvh->type == PBVH_GRIDS);
return bvh->grid_hidden;
}
-void BLI_pbvh_get_grid_key(const PBVH *bvh, CCGKey *key)
+void BKE_pbvh_get_grid_key(const PBVH *bvh, CCGKey *key)
{
BLI_assert(bvh->type == PBVH_GRIDS);
*key = bvh->gridkey;
}
+BMesh *BKE_pbvh_get_bmesh(PBVH *bvh)
+{
+ BLI_assert(bvh->type == PBVH_BMESH);
+ return bvh->bm;
+}
+
/***************************** Node Access ***********************************/
-void BLI_pbvh_node_mark_update(PBVHNode *node)
+void BKE_pbvh_node_mark_update(PBVHNode *node)
{
node->flag |= PBVH_UpdateNormals | PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
}
-void BLI_pbvh_node_mark_rebuild_draw(PBVHNode *node)
+void BKE_pbvh_node_mark_rebuild_draw(PBVHNode *node)
{
node->flag |= PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
}
-void BLI_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden)
+void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden)
{
BLI_assert(node->flag & PBVH_Leaf);
@@ -1355,13 +1278,13 @@ void BLI_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden)
node->flag &= ~PBVH_FullyHidden;
}
-void BLI_pbvh_node_get_verts(PBVH *bvh, PBVHNode *node, int **vert_indices, MVert **verts)
+void BKE_pbvh_node_get_verts(PBVH *bvh, PBVHNode *node, int **vert_indices, MVert **verts)
{
if (vert_indices) *vert_indices = node->vert_indices;
if (verts) *verts = bvh->verts;
}
-void BLI_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node, int *uniquevert, int *totvert)
+void BKE_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node, int *uniquevert, int *totvert)
{
int tot;
@@ -1375,10 +1298,15 @@ void BLI_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node, int *uniquevert, int *to
if (totvert) *totvert = node->uniq_verts + node->face_verts;
if (uniquevert) *uniquevert = node->uniq_verts;
break;
+ case PBVH_BMESH:
+ tot = BLI_ghash_size(node->bm_unique_verts);
+ if (totvert) *totvert = tot + BLI_ghash_size(node->bm_other_verts);
+ if (uniquevert) *uniquevert = tot;
+ break;
}
}
-void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int **grid_indices, int *totgrid, int *maxgrid, int *gridsize, CCGElem ***griddata, DMGridAdjacency **gridadj)
+void BKE_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int **grid_indices, int *totgrid, int *maxgrid, int *gridsize, CCGElem ***griddata, DMGridAdjacency **gridadj)
{
switch (bvh->type) {
case PBVH_GRIDS:
@@ -1390,6 +1318,7 @@ void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int **grid_indices, int
if (gridadj) *gridadj = bvh->gridadj;
break;
case PBVH_FACES:
+ case PBVH_BMESH:
if (grid_indices) *grid_indices = NULL;
if (totgrid) *totgrid = 0;
if (maxgrid) *maxgrid = 0;
@@ -1400,19 +1329,19 @@ void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int **grid_indices, int
}
}
-void BLI_pbvh_node_get_BB(PBVHNode *node, float bb_min[3], float bb_max[3])
+void BKE_pbvh_node_get_BB(PBVHNode *node, float bb_min[3], float bb_max[3])
{
copy_v3_v3(bb_min, node->vb.bmin);
copy_v3_v3(bb_max, node->vb.bmax);
}
-void BLI_pbvh_node_get_original_BB(PBVHNode *node, float bb_min[3], float bb_max[3])
+void BKE_pbvh_node_get_original_BB(PBVHNode *node, float bb_min[3], float bb_max[3])
{
copy_v3_v3(bb_min, node->orig_vb.bmin);
copy_v3_v3(bb_max, node->orig_vb.bmax);
}
-void BLI_pbvh_node_get_proxies(PBVHNode *node, PBVHProxyNode **proxies, int *proxy_count)
+void BKE_pbvh_node_get_proxies(PBVHNode *node, PBVHProxyNode **proxies, int *proxy_count)
{
if (node->proxy_count > 0) {
if (proxies) *proxies = node->proxies;
@@ -1437,14 +1366,14 @@ static int ray_aabb_intersect(PBVHNode *node, void *data_v)
float bb_min[3], bb_max[3];
if (rcd->original)
- BLI_pbvh_node_get_original_BB(node, bb_min, bb_max);
+ BKE_pbvh_node_get_original_BB(node, bb_min, bb_max);
else
- BLI_pbvh_node_get_BB(node, bb_min, bb_max);
+ BKE_pbvh_node_get_BB(node, bb_min, bb_max);
return isect_ray_aabb(&rcd->ray, bb_min, bb_max, &node->tmin);
}
-void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data,
+void BKE_pbvh_raycast(PBVH *bvh, BKE_pbvh_HitOccludedCallback cb, void *data,
const float ray_start[3], const float ray_normal[3],
int original)
{
@@ -1453,14 +1382,14 @@ void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data,
isect_ray_aabb_initialize(&rcd.ray, ray_start, ray_normal);
rcd.original = original;
- BLI_pbvh_search_callback_occluded(bvh, ray_aabb_intersect, &rcd, cb, data);
+ BKE_pbvh_search_callback_occluded(bvh, ray_aabb_intersect, &rcd, cb, data);
}
-static int ray_face_intersection(const float ray_start[3],
- const float ray_normal[3],
- const float *t0, const float *t1,
- const float *t2, const float *t3,
- float *fdist)
+int ray_face_intersection(const float ray_start[3],
+ const float ray_normal[3],
+ const float *t0, const float *t1,
+ const float *t2, const float *t3,
+ float *fdist)
{
float dist;
@@ -1566,7 +1495,7 @@ static int pbvh_grids_node_raycast(PBVH *bvh, PBVHNode *node,
return hit;
}
-int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
+int BKE_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], int use_origco,
const float ray_start[3], const float ray_normal[3],
float *dist)
{
@@ -1584,6 +1513,9 @@ int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
hit |= pbvh_grids_node_raycast(bvh, node, origco,
ray_start, ray_normal, dist);
break;
+ case PBVH_BMESH:
+ hit = pbvh_bmesh_node_raycast(node, ray_start, ray_normal, dist, use_origco);
+ break;
}
return hit;
@@ -1591,8 +1523,15 @@ int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
//#include <GL/glew.h>
-void BLI_pbvh_node_draw(PBVHNode *node, void *setMaterial)
+typedef struct {
+ DMSetMaterial setMaterial;
+ int wireframe;
+} PBVHNodeDrawData;
+
+void BKE_pbvh_node_draw(PBVHNode *node, void *data_v)
{
+ PBVHNodeDrawData *data = data_v;
+
#if 0
/* XXX: Just some quick code to show leaf nodes in different colors */
float col[3]; int i;
@@ -1611,7 +1550,9 @@ void BLI_pbvh_node_draw(PBVHNode *node, void *setMaterial)
#endif
if (!(node->flag & PBVH_FullyHidden))
- GPU_draw_buffers(node->draw_buffers, setMaterial);
+ GPU_draw_buffers(node->draw_buffers,
+ data->setMaterial,
+ data->wireframe);
}
typedef enum {
@@ -1654,19 +1595,19 @@ static PlaneAABBIsect test_planes_aabb(const float bb_min[3],
return ret;
}
-int BLI_pbvh_node_planes_contain_AABB(PBVHNode *node, void *data)
+int BKE_pbvh_node_planes_contain_AABB(PBVHNode *node, void *data)
{
float bb_min[3], bb_max[3];
- BLI_pbvh_node_get_BB(node, bb_min, bb_max);
+ BKE_pbvh_node_get_BB(node, bb_min, bb_max);
return test_planes_aabb(bb_min, bb_max, data) != ISECT_OUTSIDE;
}
-int BLI_pbvh_node_planes_exclude_AABB(PBVHNode *node, void *data)
+int BKE_pbvh_node_planes_exclude_AABB(PBVHNode *node, void *data)
{
float bb_min[3], bb_max[3];
- BLI_pbvh_node_get_BB(node, bb_min, bb_max);
+ BKE_pbvh_node_get_BB(node, bb_min, bb_max);
return test_planes_aabb(bb_min, bb_max, data) != ISECT_INSIDE;
}
@@ -1679,16 +1620,17 @@ static void pbvh_node_check_diffuse_changed(PBVH *bvh, PBVHNode *node)
node->flag |= PBVH_UpdateDrawBuffers;
}
-void BLI_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
- DMSetMaterial setMaterial)
+void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
+ DMSetMaterial setMaterial, int wireframe)
{
+ PBVHNodeDrawData draw_data = {setMaterial, wireframe};
PBVHNode **nodes;
int a, totnode;
for (a = 0; a < bvh->totnode; a++)
pbvh_node_check_diffuse_changed(bvh, &bvh->nodes[a]);
- BLI_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(PBVH_UpdateNormals | PBVH_UpdateDrawBuffers),
+ BKE_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(PBVH_UpdateNormals | PBVH_UpdateDrawBuffers),
&nodes, &totnode);
pbvh_update_normals(bvh, nodes, totnode, face_nors);
@@ -1697,15 +1639,15 @@ void BLI_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
if (nodes) MEM_freeN(nodes);
if (planes) {
- BLI_pbvh_search_callback(bvh, BLI_pbvh_node_planes_contain_AABB,
- planes, BLI_pbvh_node_draw, setMaterial);
+ BKE_pbvh_search_callback(bvh, BKE_pbvh_node_planes_contain_AABB,
+ planes, BKE_pbvh_node_draw, &draw_data);
}
else {
- BLI_pbvh_search_callback(bvh, NULL, NULL, BLI_pbvh_node_draw, setMaterial);
+ BKE_pbvh_search_callback(bvh, NULL, NULL, BKE_pbvh_node_draw, &draw_data);
}
}
-void BLI_pbvh_grids_update(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj, void **gridfaces,
+void BKE_pbvh_grids_update(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj, void **gridfaces,
DMFlagMat *flagmats, BLI_bitmap *grid_hidden)
{
int a;
@@ -1719,11 +1661,31 @@ void BLI_pbvh_grids_update(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj,
bvh->grid_hidden = grid_hidden;
for (a = 0; a < bvh->totnode; ++a)
- BLI_pbvh_node_mark_rebuild_draw(&bvh->nodes[a]);
+ BKE_pbvh_node_mark_rebuild_draw(&bvh->nodes[a]);
+ }
+}
+
+/* Get the node's displacement layer, creating it if necessary */
+float *BKE_pbvh_node_layer_disp_get(PBVH *bvh, PBVHNode *node)
+{
+ if (!node->layer_disp) {
+ int totvert = 0;
+ BKE_pbvh_node_num_verts(bvh, node, &totvert, NULL);
+ node->layer_disp = MEM_callocN(sizeof(float) * totvert, "layer disp");
}
+ return node->layer_disp;
}
-float (*BLI_pbvh_get_vertCos(PBVH * pbvh))[3]
+/* If the node has a displacement layer, free it and set to null */
+void BKE_pbvh_node_layer_disp_free(PBVHNode *node)
+{
+ if (node->layer_disp) {
+ MEM_freeN(node->layer_disp);
+ node->layer_disp = NULL;
+ }
+}
+
+float (*BKE_pbvh_get_vertCos(PBVH * pbvh))[3]
{
int a;
float (*vertCos)[3] = NULL;
@@ -1732,7 +1694,7 @@ float (*BLI_pbvh_get_vertCos(PBVH * pbvh))[3]
float *co;
MVert *mvert = pbvh->verts;
- vertCos = MEM_callocN(3 * pbvh->totvert * sizeof(float), "BLI_pbvh_get_vertCoords");
+ vertCos = MEM_callocN(3 * pbvh->totvert * sizeof(float), "BKE_pbvh_get_vertCoords");
co = (float *)vertCos;
for (a = 0; a < pbvh->totvert; a++, mvert++, co += 3) {
@@ -1743,7 +1705,7 @@ float (*BLI_pbvh_get_vertCos(PBVH * pbvh))[3]
return vertCos;
}
-void BLI_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
+void BKE_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
{
int a;
@@ -1772,21 +1734,21 @@ void BLI_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
BKE_mesh_calc_normals_tessface(pbvh->verts, pbvh->totvert, pbvh->faces, pbvh->totprim, NULL);
for (a = 0; a < pbvh->totnode; ++a)
- BLI_pbvh_node_mark_update(&pbvh->nodes[a]);
+ BKE_pbvh_node_mark_update(&pbvh->nodes[a]);
- BLI_pbvh_update(pbvh, PBVH_UpdateBB, NULL);
- BLI_pbvh_update(pbvh, PBVH_UpdateOriginalBB, NULL);
+ BKE_pbvh_update(pbvh, PBVH_UpdateBB, NULL);
+ BKE_pbvh_update(pbvh, PBVH_UpdateOriginalBB, NULL);
}
}
-int BLI_pbvh_isDeformed(PBVH *pbvh)
+int BKE_pbvh_isDeformed(PBVH *pbvh)
{
return pbvh->deformed;
}
/* Proxies */
-PBVHProxyNode *BLI_pbvh_node_add_proxy(PBVH *bvh, PBVHNode *node)
+PBVHProxyNode *BKE_pbvh_node_add_proxy(PBVH *bvh, PBVHNode *node)
{
int index, totverts;
@@ -1802,14 +1764,14 @@ PBVHProxyNode *BLI_pbvh_node_add_proxy(PBVH *bvh, PBVHNode *node)
else
node->proxies = MEM_mallocN(sizeof(PBVHProxyNode), "PBVHNodeProxy");
- BLI_pbvh_node_num_verts(bvh, node, &totverts, NULL);
+ BKE_pbvh_node_num_verts(bvh, node, &totverts, NULL);
node->proxies[index].co = MEM_callocN(sizeof(float[3]) * totverts, "PBVHNodeProxy.co");
}
return node->proxies + index;
}
-void BLI_pbvh_node_free_proxies(PBVHNode *node)
+void BKE_pbvh_node_free_proxies(PBVHNode *node)
{
#pragma omp critical
{
@@ -1827,7 +1789,7 @@ void BLI_pbvh_node_free_proxies(PBVHNode *node)
}
}
-void BLI_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot)
+void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot)
{
PBVHNode **array = NULL, **newarray, *node;
int tot = 0, space = 0;
@@ -1840,7 +1802,7 @@ void BLI_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot)
if (tot == space) {
/* resize array if needed */
space = (tot == 0) ? 32 : space * 2;
- newarray = MEM_callocN(sizeof(PBVHNode) * space, "BLI_pbvh_gather_proxies");
+ newarray = MEM_callocN(sizeof(PBVHNode) * space, "BKE_pbvh_gather_proxies");
if (array) {
memcpy(newarray, array, sizeof(PBVHNode) * tot);
@@ -1877,9 +1839,9 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
vi->fno = 0;
vi->mvert = 0;
- BLI_pbvh_node_get_grids(bvh, node, &grid_indices, &totgrid, NULL, &gridsize, &grids, NULL);
- BLI_pbvh_node_num_verts(bvh, node, &uniq_verts, &totvert);
- BLI_pbvh_node_get_verts(bvh, node, &vert_indices, &verts);
+ BKE_pbvh_node_get_grids(bvh, node, &grid_indices, &totgrid, NULL, &gridsize, &grids, NULL);
+ BKE_pbvh_node_num_verts(bvh, node, &uniq_verts, &totvert);
+ BKE_pbvh_node_get_verts(bvh, node, &vert_indices, &verts);
vi->key = &bvh->gridkey;
vi->grids = grids;
@@ -1894,12 +1856,18 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
vi->vert_indices = vert_indices;
vi->mverts = verts;
+ if (bvh->type == PBVH_BMESH) {
+ BLI_ghashIterator_init(&vi->bm_unique_verts, node->bm_unique_verts);
+ BLI_ghashIterator_init(&vi->bm_other_verts, node->bm_other_verts);
+ vi->bm_vdata = &bvh->bm->vdata;
+ }
+
vi->gh = NULL;
if (vi->grids && mode == PBVH_ITER_UNIQUE)
vi->grid_hidden = bvh->grid_hidden;
vi->mask = NULL;
- if (!vi->grids)
+ if (bvh->type == PBVH_FACES)
vi->vmask = CustomData_get_layer(bvh->vdata, CD_PAINT_MASK);
}
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
new file mode 100644
index 00000000000..791288a4dda
--- /dev/null
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -0,0 +1,1414 @@
+/*
+ * ***** 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 *****
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_buffer.h"
+#include "BLI_ghash.h"
+#include "BLI_heap.h"
+#include "BLI_math.h"
+
+#include "BKE_ccg.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_global.h"
+#include "BKE_pbvh.h"
+
+#include "GPU_buffers.h"
+
+#include "bmesh.h"
+#include "pbvh_intern.h"
+
+#include <assert.h>
+
+/****************************** Building ******************************/
+
+/* Update node data after splitting */
+static void pbvh_bmesh_node_finalize(PBVH *bvh, int node_index)
+{
+ GHashIterator gh_iter;
+ PBVHNode *n = &bvh->nodes[node_index];
+
+ /* Create vert hash sets */
+ n->bm_unique_verts = BLI_ghash_ptr_new("bm_unique_verts");
+ n->bm_other_verts = BLI_ghash_ptr_new("bm_other_verts");
+
+ BB_reset(&n->vb);
+
+ GHASH_ITER (gh_iter, n->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ BMIter bm_iter;
+ BMVert *v;
+ void *node_val = SET_INT_IN_POINTER(node_index);
+
+ /* Update ownership of faces */
+ BLI_ghash_insert(bvh->bm_face_to_node, f, node_val);
+
+ /* Update vertices */
+ BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) {
+ if (!BLI_ghash_haskey(n->bm_unique_verts, v)) {
+ if (BLI_ghash_haskey(bvh->bm_vert_to_node, v)) {
+ if (!BLI_ghash_haskey(n->bm_other_verts, v))
+ BLI_ghash_insert(n->bm_other_verts, v, NULL);
+ }
+ else {
+ BLI_ghash_insert(n->bm_unique_verts, v, NULL);
+ BLI_ghash_insert(bvh->bm_vert_to_node, v, node_val);
+ }
+ }
+ /* Update node bounding box */
+ BB_expand(&n->vb, v->co);
+ }
+ }
+
+ BLI_assert(n->vb.bmin[0] <= n->vb.bmax[0] &&
+ n->vb.bmin[1] <= n->vb.bmax[1] &&
+ n->vb.bmin[2] <= n->vb.bmax[2]);
+
+ n->orig_vb = n->vb;
+
+ /* Build GPU buffers */
+ if (!G.background) {
+ int smooth = bvh->flags & PBVH_DYNTOPO_SMOOTH_SHADING;
+ n->draw_buffers = GPU_build_bmesh_buffers(smooth);
+ n->flag |= PBVH_UpdateDrawBuffers;
+ }
+}
+
+/* Recursively split the node if it exceeds the leaf_limit */
+static void pbvh_bmesh_node_split(PBVH *bvh, GHash *prim_bbc, int node_index)
+{
+ GHash *empty, *other;
+ GHashIterator gh_iter;
+ PBVHNode *n, *c1, *c2;
+ BB cb;
+ float mid;
+ int axis, children;
+
+ n = &bvh->nodes[node_index];
+
+ if (BLI_ghash_size(n->bm_faces) <= bvh->leaf_limit) {
+ /* Node limit not exceeded */
+ pbvh_bmesh_node_finalize(bvh, node_index);
+ return;
+ }
+
+ /* Calculate bounding box around primitive centroids */
+ BB_reset(&cb);
+ GHASH_ITER (gh_iter, n->bm_faces) {
+ const BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ const BBC *bbc = BLI_ghash_lookup(prim_bbc, f);
+
+ BB_expand(&cb, bbc->bcentroid);
+ }
+
+ /* Find widest axis and its midpoint */
+ axis = BB_widest_axis(&cb);
+ mid = (cb.bmax[axis] + cb.bmin[axis]) * 0.5f;
+
+ /* Add two new child nodes */
+ children = bvh->totnode;
+ n->children_offset = children;
+ pbvh_grow_nodes(bvh, bvh->totnode + 2);
+
+ /* Array reallocated, update current node pointer */
+ n = &bvh->nodes[node_index];
+
+ /* Initialize children */
+ c1 = &bvh->nodes[children];
+ c2 = &bvh->nodes[children + 1];
+ c1->flag |= PBVH_Leaf;
+ c2->flag |= PBVH_Leaf;
+ c1->bm_faces = BLI_ghash_ptr_new("bm_faces");
+ c2->bm_faces = BLI_ghash_ptr_new("bm_faces");
+
+ /* Partition the parent node's faces between the two children */
+ GHASH_ITER (gh_iter, n->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ const BBC *bbc = BLI_ghash_lookup(prim_bbc, f);
+
+ if (bbc->bcentroid[axis] < mid)
+ BLI_ghash_insert(c1->bm_faces, f, NULL);
+ else
+ BLI_ghash_insert(c2->bm_faces, f, NULL);
+ }
+
+ /* Enforce at least one primitive in each node */
+ empty = NULL;
+ if (BLI_ghash_size(c1->bm_faces) == 0) {
+ empty = c1->bm_faces;
+ other = c2->bm_faces;
+ }
+ else if (BLI_ghash_size(c2->bm_faces) == 0) {
+ empty = c2->bm_faces;
+ other = c1->bm_faces;
+ }
+ if (empty) {
+ GHASH_ITER (gh_iter, other) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ BLI_ghash_insert(empty, key, NULL);
+ BLI_ghash_remove(other, key, NULL, NULL);
+ break;
+ }
+ }
+
+ /* Clear this node */
+
+ /* Mark this node's unique verts as unclaimed */
+ if (n->bm_unique_verts) {
+ GHASH_ITER (gh_iter, n->bm_unique_verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ BLI_ghash_remove(bvh->bm_vert_to_node, v, NULL, NULL);
+ }
+ BLI_ghash_free(n->bm_unique_verts, NULL, NULL);
+ }
+
+ /* Unclaim faces */
+ GHASH_ITER (gh_iter, n->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ BLI_ghash_remove(bvh->bm_face_to_node, f, NULL, NULL);
+ }
+ BLI_ghash_free(n->bm_faces, NULL, NULL);
+
+ if (n->bm_other_verts)
+ BLI_ghash_free(n->bm_other_verts, NULL, NULL);
+
+ if (n->layer_disp)
+ MEM_freeN(n->layer_disp);
+
+ n->bm_faces = NULL;
+ n->bm_unique_verts = NULL;
+ n->bm_other_verts = NULL;
+ n->layer_disp = NULL;
+
+ if (n->draw_buffers) {
+ GPU_free_buffers(n->draw_buffers);
+ n->draw_buffers = NULL;
+ }
+ n->flag &= ~PBVH_Leaf;
+
+ /* Recurse */
+ c1 = c2 = NULL;
+ pbvh_bmesh_node_split(bvh, prim_bbc, children);
+ pbvh_bmesh_node_split(bvh, prim_bbc, children + 1);
+
+ /* Array maybe reallocated, update current node pointer */
+ n = &bvh->nodes[node_index];
+
+ /* Update bounding box */
+ BB_reset(&n->vb);
+ BB_expand_with_bb(&n->vb, &bvh->nodes[n->children_offset].vb);
+ BB_expand_with_bb(&n->vb, &bvh->nodes[n->children_offset + 1].vb);
+ n->orig_vb = n->vb;
+}
+
+/* Recursively split the node if it exceeds the leaf_limit */
+static int pbvh_bmesh_node_limit_ensure(PBVH *bvh, int node_index)
+{
+ GHash *prim_bbc;
+ GHashIterator gh_iter;
+
+ if (BLI_ghash_size(bvh->nodes[node_index].bm_faces) <= bvh->leaf_limit) {
+ /* Node limit not exceeded */
+ return FALSE;
+ }
+
+ /* For each BMFace, store the AABB and AABB centroid */
+ prim_bbc = BLI_ghash_ptr_new("prim_bbc");
+
+ GHASH_ITER (gh_iter, bvh->nodes[node_index].bm_faces) {
+ BMIter bm_iter;
+ BMVert *v;
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ BBC *bbc = MEM_callocN(sizeof(BBC), "BBC");
+
+ BB_reset((BB *)bbc);
+ BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) {
+ BB_expand((BB *)bbc, v->co);
+ }
+ BBC_update_centroid(bbc);
+
+ BLI_ghash_insert(prim_bbc, f, bbc);
+ }
+
+ pbvh_bmesh_node_split(bvh, prim_bbc, node_index);
+
+ BLI_ghash_free(prim_bbc, NULL, (void *)MEM_freeN);
+
+ return TRUE;
+}
+
+/**********************************************************************/
+
+static PBVHNode *pbvh_bmesh_node_lookup(PBVH *bvh, GHash *map, void *key)
+{
+ int node_index;
+
+ BLI_assert(BLI_ghash_haskey(map, key));
+
+ node_index = GET_INT_FROM_POINTER(BLI_ghash_lookup(map, key));
+ BLI_assert(node_index < bvh->totnode);
+
+ return &bvh->nodes[node_index];
+}
+
+static BMVert *pbvh_bmesh_vert_create(PBVH *bvh, int node_index,
+ const float co[3],
+ const BMVert *example)
+{
+ BMVert *v = BM_vert_create(bvh->bm, co, example, 0);
+ void *val = SET_INT_IN_POINTER(node_index);
+
+ BLI_assert((bvh->totnode == 1 || node_index) && node_index <= bvh->totnode);
+
+ BLI_ghash_insert(bvh->nodes[node_index].bm_unique_verts, v, NULL);
+ BLI_ghash_insert(bvh->bm_vert_to_node, v, val);
+
+ /* Log the new vertex */
+ BM_log_vert_added(bvh->bm, bvh->bm_log, v);
+
+ return v;
+}
+
+static BMFace *pbvh_bmesh_face_create(PBVH *bvh, int node_index, BMVert *v1,
+ BMVert *v2, BMVert *v3,
+ const BMFace *UNUSED(example))
+{
+ BMFace *f;
+ void *val = SET_INT_IN_POINTER(node_index);
+
+ /* Note: passing NULL for the 'example' parameter, profiling shows
+ * a small performance bump */
+ f = BM_face_create_quad_tri(bvh->bm, v1, v2, v3, NULL, NULL, TRUE);
+ if (!BLI_ghash_haskey(bvh->bm_face_to_node, f)) {
+
+ BLI_ghash_insert(bvh->nodes[node_index].bm_faces, f, NULL);
+ BLI_ghash_insert(bvh->bm_face_to_node, f, val);
+
+ /* Log the new face */
+ BM_log_face_added(bvh->bm_log, f);
+ }
+
+ return f;
+}
+
+/* Return the number of faces in 'node' that use vertex 'v' */
+static int pbvh_bmesh_node_vert_use_count(PBVH *bvh, PBVHNode *node, BMVert *v)
+{
+ BMIter bm_iter;
+ BMFace *f;
+ int count = 0;
+
+ BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
+ PBVHNode *f_node;
+
+ f_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f);
+
+ if (f_node == node)
+ count++;
+ }
+
+ return count;
+}
+
+/* Return a node that uses vertex 'v' other than its current owner */
+static PBVHNode *pbvh_bmesh_vert_other_node_find(PBVH *bvh, BMVert *v)
+{
+ BMIter bm_iter;
+ BMFace *f;
+ PBVHNode *current_node;
+
+ current_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_vert_to_node, v);
+
+ BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
+ PBVHNode *f_node;
+
+ f_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f);
+
+ if (f_node != current_node)
+ return f_node;
+ }
+
+ return NULL;
+}
+
+static void pbvh_bmesh_vert_ownership_transfer(PBVH *bvh, PBVHNode *new_owner,
+ BMVert *v)
+{
+ PBVHNode *current_owner;
+
+ current_owner = pbvh_bmesh_node_lookup(bvh, bvh->bm_vert_to_node, v);
+ BLI_assert(current_owner != new_owner);
+
+ /* Remove current ownership */
+ BLI_ghash_remove(bvh->bm_vert_to_node, v, NULL, NULL);
+ BLI_ghash_remove(current_owner->bm_unique_verts, v, NULL, NULL);
+
+ /* Set new ownership */
+ BLI_ghash_insert(bvh->bm_vert_to_node, v,
+ SET_INT_IN_POINTER(new_owner - bvh->nodes));
+ BLI_ghash_insert(new_owner->bm_unique_verts, v, NULL);
+ BLI_ghash_remove(new_owner->bm_other_verts, v, NULL, NULL);
+ BLI_assert(!BLI_ghash_haskey(new_owner->bm_other_verts, v));
+}
+
+static void pbvh_bmesh_vert_remove(PBVH *bvh, BMVert *v)
+{
+ PBVHNode *v_node;
+ BMIter bm_iter;
+ BMFace *f;
+
+ BLI_assert(BLI_ghash_haskey(bvh->bm_vert_to_node, v));
+ v_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_vert_to_node, v);
+ BLI_ghash_remove(v_node->bm_unique_verts, v, NULL, NULL);
+ BLI_ghash_remove(bvh->bm_vert_to_node, v, NULL, NULL);
+
+ /* Have to check each neighboring face's node */
+ BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
+ PBVHNode *f_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f);
+
+ BLI_ghash_remove(f_node->bm_unique_verts, v, NULL, NULL);
+ BLI_ghash_remove(f_node->bm_other_verts, v, NULL, NULL);
+
+ BLI_assert(!BLI_ghash_haskey(f_node->bm_unique_verts, v));
+ BLI_assert(!BLI_ghash_haskey(f_node->bm_other_verts, v));
+ }
+}
+
+static void pbvh_bmesh_face_remove(PBVH *bvh, BMFace *f)
+{
+ PBVHNode *f_node;
+ BMIter bm_iter;
+ BMVert *v;
+
+ f_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f);
+
+ /* Check if any of this face's vertices need to be removed
+ * from the node */
+ BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) {
+ if (pbvh_bmesh_node_vert_use_count(bvh, f_node, v) == 1) {
+ if (BLI_ghash_lookup(f_node->bm_unique_verts, v)) {
+ /* Find a different node that uses 'v' */
+ PBVHNode *new_node;
+
+ new_node = pbvh_bmesh_vert_other_node_find(bvh, v);
+ BLI_assert(new_node || BM_vert_face_count(v) == 1);
+
+ if (new_node) {
+ pbvh_bmesh_vert_ownership_transfer(bvh, new_node, v);
+ }
+ }
+ else {
+ /* Remove from other verts */
+ BLI_ghash_remove(f_node->bm_other_verts, v, NULL, NULL);
+ }
+ }
+ }
+
+ /* Remove face from node and top level */
+ BLI_ghash_remove(f_node->bm_faces, f, NULL, NULL);
+ BLI_ghash_remove(bvh->bm_face_to_node, f, NULL, NULL);
+
+ /* Log removed face */
+ BM_log_face_removed(bvh->bm_log, f);
+}
+
+static BMVert *bm_triangle_other_vert_find(BMFace *triangle, const BMVert *v1,
+ const BMVert *v2)
+{
+ BLI_assert(triangle->len == 3);
+ BLI_assert(v1 != v2);
+
+ if (triangle->len == 3) {
+ BMIter iter;
+ BMVert *v, *other = NULL;
+ int found_v1 = FALSE, found_v2 = FALSE;
+
+ BM_ITER_ELEM (v, &iter, triangle, BM_VERTS_OF_FACE) {
+ if (v == v1)
+ found_v1 = TRUE;
+ else if (v == v2)
+ found_v2 = TRUE;
+ else
+ other = v;
+ }
+
+ if (found_v1 && found_v2)
+ return other;
+ }
+
+ BLI_assert(0);
+ return NULL;
+}
+
+static void pbvh_bmesh_edge_faces(BLI_Buffer *buf, BMEdge *e)
+{
+ BLI_buffer_resize(buf, BM_edge_face_count(e));
+ BM_iter_as_array(NULL, BM_FACES_OF_EDGE, e, buf->data, buf->count);
+}
+
+/* TODO: maybe a better way to do this, if not then this should go to
+ * bmesh_queries */
+static int bm_face_edge_backwards(BMFace *f, BMEdge *e)
+{
+ BMIter bm_iter;
+ BMLoop *l, *l1 = NULL, *l2 = NULL;
+
+ BM_ITER_ELEM (l, &bm_iter, f, BM_LOOPS_OF_FACE) {
+ if (l->v == e->v1)
+ l1 = l;
+ else if (l->v == e->v2)
+ l2 = l;
+ }
+
+ BLI_assert(l1 && l2);
+ BLI_assert(l1->next == l2 || l2->next == l1);
+ return l2->next == l1;
+}
+
+static void pbvh_bmesh_node_drop_orig(PBVHNode *node)
+{
+ if (node->bm_orco)
+ MEM_freeN(node->bm_orco);
+ if (node->bm_ortri)
+ MEM_freeN(node->bm_ortri);
+ node->bm_orco = NULL;
+ node->bm_ortri = NULL;
+ node->bm_tot_ortri = 0;
+}
+
+/****************************** EdgeQueue *****************************/
+
+typedef struct {
+ Heap *heap;
+ const float *center;
+ float radius_squared;
+ float limit_len_squared;
+} EdgeQueue;
+
+static int edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f)
+{
+ BMVert *v[3];
+ float c[3];
+
+ /* Get closest point in triangle to sphere center */
+ BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v, 3);
+ closest_on_tri_to_point_v3(c, q->center, v[0]->co, v[1]->co, v[2]->co);
+
+ /* Check if triangle intersects the sphere */
+ return ((len_squared_v3v3(q->center, c) <= q->radius_squared));
+}
+
+static void edge_queue_insert(EdgeQueue *q, BLI_mempool *pool, BMEdge *e,
+ float priority)
+{
+ BMVert **pair;
+
+ pair = BLI_mempool_alloc(pool);
+ pair[0] = e->v1;
+ pair[1] = e->v2;
+ BLI_heap_insert(q->heap, priority, pair);
+}
+
+static void long_edge_queue_edge_add(EdgeQueue *q, BLI_mempool *pool,
+ BMEdge *e)
+{
+ const float len_sq = BM_edge_calc_length_squared(e);
+ if (len_sq > q->limit_len_squared)
+ edge_queue_insert(q, pool, e, 1.0f / len_sq);
+}
+
+static void short_edge_queue_edge_add(EdgeQueue *q, BLI_mempool *pool,
+ BMEdge *e)
+{
+ const float len_sq = BM_edge_calc_length_squared(e);
+ if (len_sq < q->limit_len_squared)
+ edge_queue_insert(q, pool, e, len_sq);
+}
+
+static int long_edge_queue_face_add(EdgeQueue *q, BLI_mempool *pool,
+ BMFace *f)
+{
+ BMIter bm_iter;
+ BMEdge *e;
+
+ if (edge_queue_tri_in_sphere(q, f)) {
+ /* Check each edge of the face */
+ BM_ITER_ELEM (e, &bm_iter, f, BM_EDGES_OF_FACE) {
+ long_edge_queue_edge_add(q, pool, e);
+ }
+ }
+
+ return TRUE;
+}
+
+static int short_edge_queue_face_add(EdgeQueue *q, BLI_mempool *pool,
+ BMFace *f)
+{
+ BMIter bm_iter;
+ BMEdge *e;
+
+ if (edge_queue_tri_in_sphere(q, f)) {
+ /* Check each edge of the face */
+ BM_ITER_ELEM (e, &bm_iter, f, BM_EDGES_OF_FACE) {
+ short_edge_queue_edge_add(q, pool, e);
+ }
+ }
+
+ return TRUE;
+}
+
+/* Create a priority queue containing vertex pairs connected by a long
+ * edge as defined by PBVH.bm_max_edge_len.
+ *
+ * Only nodes marked for topology update are checked, and in those
+ * nodes only edges used by a face intersecting the (center, radius)
+ * sphere are checked.
+ *
+ * The highest priority (lowest number) is given to the longest edge.
+ */
+static void long_edge_queue_create(EdgeQueue *q, BLI_mempool *pool,
+ PBVH *bvh, const float center[3],
+ float radius)
+{
+ int n;
+
+ q->heap = BLI_heap_new();
+ q->center = center;
+ q->radius_squared = radius * radius;
+ q->limit_len_squared = bvh->bm_max_edge_len * bvh->bm_max_edge_len;
+
+ for (n = 0; n < bvh->totnode; n++) {
+ PBVHNode *node = &bvh->nodes[n];
+
+ /* Check leaf nodes marked for topology update */
+ if ((node->flag & PBVH_Leaf) &&
+ (node->flag & PBVH_UpdateTopology))
+ {
+ GHashIterator gh_iter;
+
+ /* Check each face */
+ GHASH_ITER (gh_iter, node->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+
+ long_edge_queue_face_add(q, pool, f);
+ }
+ }
+ }
+}
+
+/* Create a priority queue containing vertex pairs connected by a
+ * short edge as defined by PBVH.bm_min_edge_len.
+ *
+ * Only nodes marked for topology update are checked, and in those
+ * nodes only edges used by a face intersecting the (center, radius)
+ * sphere are checked.
+ *
+ * The highest priority (lowest number) is given to the shortest edge.
+ */
+static void short_edge_queue_create(EdgeQueue *q, BLI_mempool *pool,
+ PBVH *bvh, const float center[3],
+ float radius)
+{
+ int n;
+
+ q->heap = BLI_heap_new();
+ q->center = center;
+ q->radius_squared = radius * radius;
+ q->limit_len_squared = bvh->bm_min_edge_len * bvh->bm_min_edge_len;
+
+ for (n = 0; n < bvh->totnode; n++) {
+ PBVHNode *node = &bvh->nodes[n];
+
+ /* Check leaf nodes marked for topology update */
+ if ((node->flag & PBVH_Leaf) &&
+ (node->flag & PBVH_UpdateTopology))
+ {
+ GHashIterator gh_iter;
+
+ /* Check each face */
+ GHASH_ITER (gh_iter, node->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+
+ short_edge_queue_face_add(q, pool, f);
+ }
+ }
+ }
+}
+
+/*************************** Topology update **************************/
+
+static void pbvh_bmesh_split_edge(PBVH *bvh, EdgeQueue *q, BLI_mempool *pool,
+ BMEdge *e, BLI_Buffer *edge_faces)
+{
+ BMVert *v_new;
+ float mid[3];
+ int i, node_index;
+
+ /* Get all faces adjacent to the edge */
+ pbvh_bmesh_edge_faces(edge_faces, e);
+
+ /* Create a new vertex in current node at the edge's midpoint */
+ mid_v3_v3v3(mid, e->v1->co, e->v2->co);
+
+ node_index = GET_INT_FROM_POINTER(BLI_ghash_lookup(bvh->bm_vert_to_node,
+ e->v1));
+ v_new = pbvh_bmesh_vert_create(bvh, node_index, mid, e->v1);
+
+ /* For each face, add two new triangles and delete the original */
+ for (i = 0; i < edge_faces->count; i++) {
+ BMFace *f_adj = BLI_buffer_at(edge_faces, BMFace *, i);
+ BMFace *f_new;
+ BMVert *opp, *v1, *v2;
+ void *nip;
+ int ni;
+
+ BLI_assert(f_adj->len == 3);
+ nip = BLI_ghash_lookup(bvh->bm_face_to_node, f_adj);
+ ni = GET_INT_FROM_POINTER(nip);
+
+ /* Ensure node gets redrawn */
+ bvh->nodes[ni].flag |= PBVH_UpdateDrawBuffers;
+
+ /* Find the vertex not in the edge */
+ opp = bm_triangle_other_vert_find(f_adj, e->v1, e->v2);
+
+ /* Get e->v1 and e->v2 in the order they appear in the
+ * existing face so that the new faces' winding orders
+ * match */
+ v1 = e->v1;
+ v2 = e->v2;
+ if (bm_face_edge_backwards(f_adj, e))
+ SWAP(BMVert *, v1, v2);
+
+ if (ni != node_index && i == 0)
+ pbvh_bmesh_vert_ownership_transfer(bvh, &bvh->nodes[ni], v_new);
+
+ /* Create two new faces */
+ f_new = pbvh_bmesh_face_create(bvh, ni, v1, v_new, opp, f_adj);
+ long_edge_queue_face_add(q, pool, f_new);
+ f_new = pbvh_bmesh_face_create(bvh, ni, v_new, v2, opp, f_adj);
+ long_edge_queue_face_add(q, pool, f_new);
+
+ /* Delete original */
+ pbvh_bmesh_face_remove(bvh, f_adj);
+ BM_face_kill(bvh->bm, f_adj);
+
+ /* Ensure new vertex is in the node */
+ if (!BLI_ghash_haskey(bvh->nodes[ni].bm_unique_verts, v_new) &&
+ !BLI_ghash_haskey(bvh->nodes[ni].bm_other_verts, v_new))
+ {
+ BLI_ghash_insert(bvh->nodes[ni].bm_other_verts, v_new, NULL);
+ }
+
+ if (BM_vert_edge_count(opp) >= 9) {
+ BMIter bm_iter;
+ BMEdge *e2;
+
+ BM_ITER_ELEM (e2, &bm_iter, opp, BM_EDGES_OF_VERT) {
+ long_edge_queue_edge_add(q, pool, e2);
+ }
+ }
+ }
+
+ BM_edge_kill(bvh->bm, e);
+}
+
+static int pbvh_bmesh_subdivide_long_edges(PBVH *bvh, EdgeQueue *q,
+ BLI_mempool *pool,
+ BLI_Buffer *edge_faces)
+{
+ int any_subdivided = FALSE;
+
+ while (!BLI_heap_is_empty(q->heap)) {
+ BMVert **pair = BLI_heap_popmin(q->heap);
+ BMEdge *e;
+
+ /* Check that the edge still exists */
+ if (!(e = BM_edge_exists(pair[0], pair[1]))) {
+ BLI_mempool_free(pool, pair);
+ continue;
+ }
+
+ BLI_mempool_free(pool, pair);
+ pair = NULL;
+
+ /* Check that the edge's vertices are still in the PBVH. It's
+ * possible that an edge collapse has deleted adjacent faces
+ * and the node has been split, thus leaving wire edges and
+ * associated vertices. */
+ if (!BLI_ghash_haskey(bvh->bm_vert_to_node, e->v1) ||
+ !BLI_ghash_haskey(bvh->bm_vert_to_node, e->v2))
+ {
+ continue;
+ }
+
+ if (BM_edge_calc_length_squared(e) <= q->limit_len_squared)
+ continue;
+
+ any_subdivided = TRUE;
+
+ pbvh_bmesh_split_edge(bvh, q, pool, e, edge_faces);
+ }
+
+ return any_subdivided;
+}
+
+static void pbvh_bmesh_collapse_edge(PBVH *bvh, BMEdge *e, BMVert *v1,
+ BMVert *v2, GHash *deleted_verts,
+ BLI_Buffer *edge_faces,
+ BLI_Buffer *deleted_faces)
+{
+ BMIter bm_iter;
+ BMFace *f;
+ int i;
+
+ /* Get all faces adjacent to the edge */
+ pbvh_bmesh_edge_faces(edge_faces, e);
+
+ /* Remove the merge vertex from the PBVH */
+ pbvh_bmesh_vert_remove(bvh, v2);
+
+ /* Remove all faces adjacent to the edge */
+ for (i = 0; i < edge_faces->count; i++) {
+ BMFace *f_adj = BLI_buffer_at(edge_faces, BMFace *, i);
+
+ pbvh_bmesh_face_remove(bvh, f_adj);
+ BM_face_kill(bvh->bm, f_adj);
+ }
+
+ /* Kill the edge */
+ BLI_assert(BM_edge_face_count(e) == 0);
+ BM_edge_kill(bvh->bm, e);
+
+ /* For all remaining faces of v2, create a new face that is the
+ same except it uses v1 instead of v2 */
+ /* Note: this could be done with BM_vert_splice(), but that
+ * requires handling other issues like duplicate edges, so doesn't
+ * really buy anything. */
+ deleted_faces->count = 0;
+ BM_ITER_ELEM (f, &bm_iter, v2, BM_FACES_OF_VERT) {
+ BMVert *v[3];
+ BMFace *existing_face;
+ PBVHNode *n;
+ int ni;
+
+ /* Get vertices, replace use of v2 with v1 */
+ BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v, 3);
+ for (i = 0; i < 3; i++) {
+ if (v[i] == v2)
+ v[i] = v1;
+ }
+
+ /* Check if a face using these vertices already exists. If so,
+ * skip adding this face and mark the existing one for
+ * deletion as well. Prevents extraneous "flaps" from being
+ * created. */
+ if (BM_face_exists(v, 3, &existing_face)) {
+ BLI_assert(existing_face);
+ BLI_buffer_append(deleted_faces, BMFace *, existing_face);
+ }
+ else {
+ n = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f);
+ ni = n - bvh->nodes;
+ pbvh_bmesh_face_create(bvh, ni, v[0], v[1], v[2], f);
+
+ /* Ensure that v1 is in the new face's node */
+ if (!BLI_ghash_haskey(n->bm_unique_verts, v1) &&
+ !BLI_ghash_haskey(n->bm_other_verts, v1)) {
+ BLI_ghash_insert(n->bm_other_verts, v1, NULL);
+ }
+ }
+
+ BLI_buffer_append(deleted_faces, BMFace *, f);
+ }
+
+ /* Delete the tagged faces */
+ for (i = 0; i < deleted_faces->count; i++) {
+ BMFace *f_del = BLI_buffer_at(deleted_faces, BMFace *, i);
+ BMVert *v[3];
+ int j;
+
+ BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f_del, (void **)v, 3);
+
+ /* Check if any of the face's vertices are now unused, if so
+ remove them from the PBVH */
+ for (j = 0; j < 3; j++) {
+ if (v[j] != v2 && BM_vert_face_count(v[j]) == 0) {
+ BLI_ghash_insert(deleted_verts, v[j], NULL);
+ pbvh_bmesh_vert_remove(bvh, v[j]);
+ }
+ else {
+ v[j] = NULL;
+ }
+ }
+
+ /* Remove the face */
+ pbvh_bmesh_face_remove(bvh, f_del);
+ BM_face_kill(bvh->bm, f_del);
+
+ /* Delete unused vertices */
+ for (j = 0; j < 3; j++) {
+ if (v[j]) {
+ BM_log_vert_removed(bvh->bm, bvh->bm_log, v[j]);
+ BM_vert_kill(bvh->bm, v[j]);
+ }
+ }
+ }
+
+ /* Move v1 to the midpoint of v1 and v2 */
+ BM_log_vert_before_modified(bvh->bm, bvh->bm_log, v1);
+ mid_v3_v3v3(v1->co, v1->co, v2->co);
+
+ /* Delete v2 */
+ BLI_assert(BM_vert_face_count(v2) == 0);
+ BLI_ghash_insert(deleted_verts, v2, NULL);
+ BM_log_vert_removed(bvh->bm, bvh->bm_log, v2);
+ BM_vert_kill(bvh->bm, v2);
+}
+
+static int pbvh_bmesh_collapse_short_edges(PBVH *bvh, EdgeQueue *q,
+ BLI_mempool *pool,
+ BLI_Buffer *edge_faces,
+ BLI_Buffer *deleted_faces)
+{
+ float min_len_squared = bvh->bm_min_edge_len * bvh->bm_min_edge_len;
+ GHash *deleted_verts;
+ int any_collapsed = FALSE;
+
+ deleted_verts = BLI_ghash_ptr_new("deleted_verts");
+
+ while (!BLI_heap_is_empty(q->heap)) {
+ BMVert **pair = BLI_heap_popmin(q->heap);
+ BMEdge *e;
+ BMVert *v1, *v2;
+
+ v1 = pair[0];
+ v2 = pair[1];
+ BLI_mempool_free(pool, pair);
+ pair = NULL;
+
+ /* Check that the vertices/edge still exist */
+ if (BLI_ghash_haskey(deleted_verts, v1) ||
+ BLI_ghash_haskey(deleted_verts, v2) ||
+ !(e = BM_edge_exists(v1, v2)))
+ {
+ continue;
+ }
+
+ /* Check that the edge's vertices are still in the PBVH. It's
+ * possible that an edge collapse has deleted adjacent faces
+ * and the node has been split, thus leaving wire edges and
+ * associated vertices. */
+ if (!BLI_ghash_haskey(bvh->bm_vert_to_node, e->v1) ||
+ !BLI_ghash_haskey(bvh->bm_vert_to_node, e->v2))
+ {
+ continue;
+ }
+
+ if (BM_edge_calc_length_squared(e) >= min_len_squared)
+ continue;
+
+ any_collapsed = TRUE;
+
+ pbvh_bmesh_collapse_edge(bvh, e, v1, v2,
+ deleted_verts, edge_faces,
+ deleted_faces);
+ }
+
+ BLI_ghash_free(deleted_verts, NULL, NULL);
+
+ return any_collapsed;
+}
+
+/************************* Called from pbvh.c *************************/
+
+int pbvh_bmesh_node_raycast(PBVHNode *node, const float ray_start[3],
+ const float ray_normal[3], float *dist,
+ int use_original)
+{
+ GHashIterator gh_iter;
+ int hit = 0;
+
+ if (use_original && node->bm_tot_ortri) {
+ int i;
+ for (i = 0; i < node->bm_tot_ortri; i++) {
+ const int *t = node->bm_ortri[i];
+ hit |= ray_face_intersection(ray_start, ray_normal,
+ node->bm_orco[t[0]],
+ node->bm_orco[t[1]],
+ node->bm_orco[t[2]],
+ NULL, dist);
+ }
+ }
+ else {
+ GHASH_ITER (gh_iter, node->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+
+ BLI_assert(f->len == 3);
+ if (f->len == 3) {
+ BMVert *v[3];
+
+ BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v, 3);
+ hit |= ray_face_intersection(ray_start, ray_normal,
+ v[0]->co,
+ v[1]->co,
+ v[2]->co,
+ NULL, dist);
+ }
+ }
+ }
+
+ return hit;
+}
+
+void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode)
+{
+ int n;
+
+ for (n = 0; n < totnode; n++) {
+ PBVHNode *node = nodes[n];
+ GHashIterator gh_iter;
+
+ GHASH_ITER (gh_iter, node->bm_faces) {
+ BM_face_normal_update(BLI_ghashIterator_getKey(&gh_iter));
+ }
+ GHASH_ITER (gh_iter, node->bm_unique_verts) {
+ BM_vert_normal_update(BLI_ghashIterator_getKey(&gh_iter));
+ }
+ }
+}
+
+/***************************** Public API *****************************/
+
+/* Build a PBVH from a BMesh */
+void BKE_pbvh_build_bmesh(PBVH *bvh, BMesh *bm, int smooth_shading,
+ BMLog *log)
+{
+ BMIter iter;
+ BMFace *f;
+ PBVHNode *n;
+ int node_index = 0;
+
+ bvh->bm = bm;
+
+ BKE_pbvh_bmesh_detail_size_set(bvh, 0.75);
+
+ bvh->type = PBVH_BMESH;
+ bvh->bm_face_to_node = BLI_ghash_ptr_new("bm_face_to_node");
+ bvh->bm_vert_to_node = BLI_ghash_ptr_new("bm_vert_to_node");
+ bvh->bm_log = log;
+
+ /* TODO: choose leaf limit better */
+ bvh->leaf_limit = 100;
+
+ if (smooth_shading)
+ bvh->flags |= PBVH_DYNTOPO_SMOOTH_SHADING;
+
+ /* Start with all faces in the root node */
+ n = bvh->nodes = MEM_callocN(sizeof(PBVHNode), "PBVHNode");
+ bvh->totnode = 1;
+ n->flag = PBVH_Leaf;
+ n->bm_faces = BLI_ghash_ptr_new("bm_faces");
+ BM_ITER_MESH (f, &iter, bvh->bm, BM_FACES_OF_MESH) {
+ BLI_ghash_insert(n->bm_faces, f, NULL);
+ }
+
+ /* Recursively split the node until it is under the limit; if no
+ * splitting occurs then finalize the existing leaf node */
+ if (!pbvh_bmesh_node_limit_ensure(bvh, node_index))
+ pbvh_bmesh_node_finalize(bvh, 0);
+}
+
+/* Collapse short edges, subdivide long edges */
+int BKE_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode,
+ const float center[3], float radius)
+{
+ BLI_buffer_declare_static(BMFace *, edge_faces, BLI_BUFFER_NOP, 8);
+ BLI_buffer_declare_static(BMFace *, deleted_faces, BLI_BUFFER_NOP, 32);
+
+ int modified = FALSE;
+ int n;
+
+ if (mode & PBVH_Collapse) {
+ EdgeQueue q;
+ BLI_mempool *queue_pool = BLI_mempool_create(sizeof(BMVert) * 2,
+ 128, 128, 0);
+ short_edge_queue_create(&q, queue_pool, bvh, center, radius);
+ pbvh_bmesh_collapse_short_edges(bvh, &q, queue_pool, &edge_faces,
+ &deleted_faces);
+ BLI_heap_free(q.heap, NULL);
+ BLI_mempool_destroy(queue_pool);
+ }
+
+ if (mode & PBVH_Subdivide) {
+ EdgeQueue q;
+ BLI_mempool *queue_pool = BLI_mempool_create(sizeof(BMVert) * 2,
+ 128, 128, 0);
+ long_edge_queue_create(&q, queue_pool, bvh, center, radius);
+ pbvh_bmesh_subdivide_long_edges(bvh, &q, queue_pool, &edge_faces);
+ BLI_heap_free(q.heap, NULL);
+ BLI_mempool_destroy(queue_pool);
+ }
+
+ /* Unmark nodes */
+ for (n = 0; n < bvh->totnode; n++) {
+ PBVHNode *node = &bvh->nodes[n];
+
+ if (node->flag & PBVH_Leaf &&
+ node->flag & PBVH_UpdateTopology)
+ {
+ node->flag &= ~PBVH_UpdateTopology;
+ }
+ }
+ BLI_buffer_free(&edge_faces);
+ BLI_buffer_free(&deleted_faces);
+
+ return modified;
+}
+
+/* In order to perform operations on the original node coordinates
+ * (such as raycast), store the node's triangles and vertices.*/
+void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node)
+{
+ GHashIterator gh_iter;
+ int i, totvert, tottri;
+
+ /* Skip if original coords/triangles are already saved */
+ if (node->bm_orco)
+ return;
+
+ totvert = (BLI_ghash_size(node->bm_unique_verts) +
+ BLI_ghash_size(node->bm_other_verts));
+
+ tottri = BLI_ghash_size(node->bm_faces);
+
+ node->bm_orco = MEM_mallocN(sizeof(*node->bm_orco) * totvert, AT);
+ node->bm_ortri = MEM_mallocN(sizeof(*node->bm_ortri) * tottri, AT);
+
+ /* Copy out the vertices and assign a temporary index */
+ i = 0;
+ GHASH_ITER (gh_iter, node->bm_unique_verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ copy_v3_v3(node->bm_orco[i], v->co);
+ BM_elem_index_set(v, i); /* set_dirty! */
+ i++;
+ }
+ GHASH_ITER (gh_iter, node->bm_other_verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ copy_v3_v3(node->bm_orco[i], v->co);
+ BM_elem_index_set(v, i); /* set_dirty! */
+ i++;
+ }
+
+ /* Copy the triangles */
+ i = 0;
+ GHASH_ITER (gh_iter, node->bm_faces) {
+ BMIter bm_iter;
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ BMVert *v;
+ int j = 0;
+
+ BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) {
+ node->bm_ortri[i][j] = BM_elem_index_get(v);
+ j++;
+ }
+ i++;
+ }
+ node->bm_tot_ortri = i;
+}
+
+void BKE_pbvh_bmesh_after_stroke(PBVH *bvh)
+{
+ int i;
+ for (i = 0; i < bvh->totnode; i++) {
+ PBVHNode *n = &bvh->nodes[i];
+ if (n->flag & PBVH_Leaf) {
+ /* Free orco/ortri data */
+ pbvh_bmesh_node_drop_orig(n);
+
+ /* Recursively split nodes that have gotten too many
+ * elements */
+ pbvh_bmesh_node_limit_ensure(bvh, i);
+ }
+ }
+}
+
+void BKE_pbvh_bmesh_detail_size_set(PBVH *bvh, float detail_size)
+{
+ bvh->bm_max_edge_len = detail_size;
+ bvh->bm_min_edge_len = bvh->bm_max_edge_len * 0.4f;
+}
+
+void BKE_pbvh_node_mark_topology_update(PBVHNode *node)
+{
+ node->flag |= PBVH_UpdateTopology;
+}
+
+GHash *BKE_pbvh_bmesh_node_unique_verts(PBVHNode *node)
+{
+ return node->bm_unique_verts;
+}
+
+GHash *BKE_pbvh_bmesh_node_other_verts(PBVHNode *node)
+{
+ return node->bm_other_verts;
+}
+
+/****************************** Debugging *****************************/
+
+#if 0
+void bli_ghash_duplicate_key_check(GHash *gh)
+{
+ GHashIterator gh_iter1, gh_iter2;
+
+ GHASH_ITER (gh_iter1, gh) {
+ void *key1 = BLI_ghashIterator_getKey(&gh_iter1);
+ int dup = -1;
+
+ GHASH_ITER (gh_iter2, gh) {
+ void *key2 = BLI_ghashIterator_getKey(&gh_iter2);
+
+ if (key1 == key2) {
+ dup++;
+ if (dup > 0) {
+ BLI_assert(!"duplicate in hash");
+ }
+ }
+ }
+ }
+}
+
+void bmesh_print(BMesh *bm)
+{
+ BMIter iter, siter;
+ BMVert *v;
+ BMEdge *e;
+ BMFace *f;
+ BMLoop *l;
+
+ fprintf(stderr, "\nbm=%p, totvert=%d, totedge=%d, "
+ "totloop=%d, totface=%d\n",
+ bm, bm->totvert, bm->totedge,
+ bm->totloop, bm->totface);
+
+ fprintf(stderr, "vertices:\n");
+ BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) {
+ fprintf(stderr, " %d co=(%.3f %.3f %.3f) oflag=%x\n",
+ BM_elem_index_get(v), v->co[0], v->co[1], v->co[2],
+ v->oflags[bm->stackdepth - 1].f);
+ }
+
+ fprintf(stderr, "edges:\n");
+ BM_ITER_MESH(e, &iter, bm, BM_EDGES_OF_MESH) {
+ fprintf(stderr, " %d v1=%d, v2=%d, oflag=%x\n",
+ BM_elem_index_get(e),
+ BM_elem_index_get(e->v1),
+ BM_elem_index_get(e->v2),
+ e->oflags[bm->stackdepth - 1].f);
+ }
+
+ fprintf(stderr, "faces:\n");
+ BM_ITER_MESH(f, &iter, bm, BM_FACES_OF_MESH) {
+ fprintf(stderr, " %d len=%d, oflag=%x\n",
+ BM_elem_index_get(f), f->len,
+ f->oflags[bm->stackdepth - 1].f);
+
+ fprintf(stderr, " v: ");
+ BM_ITER_ELEM(v, &siter, f, BM_VERTS_OF_FACE) {
+ fprintf(stderr, "%d ", BM_elem_index_get(v));
+ }
+ fprintf(stderr, "\n");
+
+ fprintf(stderr, " e: ");
+ BM_ITER_ELEM(e, &siter, f, BM_EDGES_OF_FACE) {
+ fprintf(stderr, "%d ", BM_elem_index_get(e));
+ }
+ fprintf(stderr, "\n");
+
+ fprintf(stderr, " l: ");
+ BM_ITER_ELEM(l, &siter, f, BM_LOOPS_OF_FACE) {
+ fprintf(stderr, "%d(v=%d, e=%d) ",
+ BM_elem_index_get(l),
+ BM_elem_index_get(l->v),
+ BM_elem_index_get(l->e));
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+void pbvh_bmesh_print(PBVH *bvh)
+{
+ GHashIterator gh_iter;
+ int n;
+
+ fprintf(stderr, "\npbvh=%p\n", bvh);
+ fprintf(stderr, "bm_face_to_node:\n");
+ GHASH_ITER (gh_iter, bvh->bm_face_to_node) {
+ fprintf(stderr, " %d -> %d\n",
+ BM_elem_index_get((BMFace*)BLI_ghashIterator_getKey(&gh_iter)),
+ GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)));
+ }
+
+ fprintf(stderr, "bm_vert_to_node:\n");
+ GHASH_ITER (gh_iter, bvh->bm_vert_to_node) {
+ fprintf(stderr, " %d -> %d\n",
+ BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)),
+ GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)));
+ }
+
+ for (n = 0; n < bvh->totnode; n++) {
+ PBVHNode *node = &bvh->nodes[n];
+ if (!(node->flag & PBVH_Leaf))
+ continue;
+
+ fprintf(stderr, "node %d\n faces:\n", n);
+ GHASH_ITER (gh_iter, node->bm_faces)
+ fprintf(stderr, " %d\n",
+ BM_elem_index_get((BMFace*)BLI_ghashIterator_getKey(&gh_iter)));
+ fprintf(stderr, " unique verts:\n");
+ GHASH_ITER (gh_iter, node->bm_unique_verts)
+ fprintf(stderr, " %d\n",
+ BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)));
+ fprintf(stderr, " other verts:\n");
+ GHASH_ITER (gh_iter, node->bm_other_verts)
+ fprintf(stderr, " %d\n",
+ BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)));
+ }
+}
+
+void print_flag_factors(int flag)
+{
+ int i;
+ printf("flag=0x%x:\n", flag);
+ for (i = 0; i < 32; i++) {
+ if (flag & (1 << i)) {
+ printf(" %d (1 << %d)\n", 1 << i, i);
+ }
+ }
+}
+
+void pbvh_bmesh_verify(PBVH *bvh)
+{
+ GHashIterator gh_iter;
+ int i;
+
+ /* Check faces */
+ BLI_assert(bvh->bm->totface == BLI_ghash_size(bvh->bm_face_to_node));
+ GHASH_ITER (gh_iter, bvh->bm_face_to_node) {
+ BMIter bm_iter;
+ BMVert *v;
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ void *nip = BLI_ghashIterator_getValue(&gh_iter);
+ int ni = GET_INT_FROM_POINTER(nip);
+ PBVHNode *n = &bvh->nodes[ni];
+
+ /* Check that the face's node is a leaf */
+ BLI_assert(n->flag & PBVH_Leaf);
+
+ /* Check that the face's node knows it owns the face */
+ BLI_assert(BLI_ghash_haskey(n->bm_faces, f));
+
+ /* Check the face's vertices... */
+ BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) {
+ PBVHNode *nv;
+
+ /* Check that the vertex is in the node */
+ BLI_assert(BLI_ghash_haskey(n->bm_unique_verts, v) ^
+ BLI_ghash_haskey(n->bm_other_verts, v));
+
+ /* Check that the vertex has a node owner */
+ nv = pbvh_bmesh_node_lookup(bvh, bvh->bm_vert_to_node, v);
+
+ /* Check that the vertex's node knows it owns the vert */
+ BLI_assert(BLI_ghash_haskey(nv->bm_unique_verts, v));
+
+ /* Check that the vertex isn't duplicated as an 'other' vert */
+ BLI_assert(!BLI_ghash_haskey(nv->bm_other_verts, v));
+ }
+ }
+
+ /* Check verts */
+ BLI_assert(bvh->bm->totvert == BLI_ghash_size(bvh->bm_vert_to_node));
+ GHASH_ITER (gh_iter, bvh->bm_vert_to_node) {
+ BMIter bm_iter;
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ BMFace *f;
+ void *nip = BLI_ghashIterator_getValue(&gh_iter);
+ int ni = GET_INT_FROM_POINTER(nip);
+ PBVHNode *n = &bvh->nodes[ni];
+ int found;
+
+ /* Check that the vert's node is a leaf */
+ BLI_assert(n->flag & PBVH_Leaf);
+
+ /* Check that the vert's node knows it owns the vert */
+ BLI_assert(BLI_ghash_haskey(n->bm_unique_verts, v));
+
+ /* Check that the vertex isn't duplicated as an 'other' vert */
+ BLI_assert(!BLI_ghash_haskey(n->bm_other_verts, v));
+
+ /* Check that the vert's node also contains one of the vert's
+ * adjacent faces */
+ BM_ITER_ELEM (f, &bm_iter, v, BM_FACES_OF_VERT) {
+ if (BLI_ghash_lookup(bvh->bm_face_to_node, f) == nip) {
+ found = TRUE;
+ break;
+ }
+ }
+ BLI_assert(found);
+ }
+
+ /* Check that node elements are recorded in the top level */
+ for (i = 0; i < bvh->totnode; i++) {
+ PBVHNode *n = &bvh->nodes[i];
+ if (n->flag & PBVH_Leaf) {
+ /* Check for duplicate entries */
+ /* Slow */
+ #if 0
+ bli_ghash_duplicate_key_check(n->bm_faces);
+ bli_ghash_duplicate_key_check(n->bm_unique_verts);
+ bli_ghash_duplicate_key_check(n->bm_other_verts);
+ #endif
+
+ GHASH_ITER (gh_iter, n->bm_faces) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ void *nip = BLI_ghash_lookup(bvh->bm_face_to_node, f);
+ BLI_assert(BLI_ghash_haskey(bvh->bm_face_to_node, f));
+ BLI_assert(GET_INT_FROM_POINTER(nip) == (n - bvh->nodes));
+ }
+
+ GHASH_ITER (gh_iter, n->bm_unique_verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ void *nip = BLI_ghash_lookup(bvh->bm_vert_to_node, v);
+ BLI_assert(BLI_ghash_haskey(bvh->bm_vert_to_node, v));
+ BLI_assert(!BLI_ghash_haskey(n->bm_other_verts, v));
+ BLI_assert(GET_INT_FROM_POINTER(nip) == (n - bvh->nodes));
+ }
+
+ GHASH_ITER (gh_iter, n->bm_other_verts) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ BLI_assert(BLI_ghash_haskey(bvh->bm_vert_to_node, v));
+ BLI_assert(BM_vert_face_count(v) > 0);
+ }
+ }
+ }
+}
+
+#endif
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
new file mode 100644
index 00000000000..b3f7bf6e3d1
--- /dev/null
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -0,0 +1,186 @@
+/*
+ * ***** 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 __PBVH_INTERN_H__
+#define __PBVH_INTERN_H__
+
+/* Axis-aligned bounding box */
+typedef struct {
+ float bmin[3], bmax[3];
+} BB;
+
+/* Axis-aligned bounding box with centroid */
+typedef struct {
+ float bmin[3], bmax[3], bcentroid[3];
+} BBC;
+
+/* Note: this structure is getting large, might want to split it into
+ * union'd structs */
+struct PBVHNode {
+ /* Opaque handle for drawing code */
+ struct GPU_Buffers *draw_buffers;
+
+ /* Voxel bounds */
+ BB vb;
+ BB orig_vb;
+
+ /* For internal nodes, the offset of the children in the PBVH
+ * 'nodes' array. */
+ int children_offset;
+
+ /* Pointer into the PBVH prim_indices array and the number of
+ * primitives used by this leaf node.
+ *
+ * Used for leaf nodes in both mesh- and multires-based PBVHs.
+ */
+ int *prim_indices;
+ unsigned int totprim;
+
+ /* Array of indices into the mesh's MVert array. Contains the
+ * indices of all vertices used by faces that are within this
+ * node's bounding box.
+ *
+ * Note that a vertex might be used by a multiple faces, and
+ * these faces might be in different leaf nodes. Such a vertex
+ * will appear in the vert_indices array of each of those leaf
+ * nodes.
+ *
+ * In order to support cases where you want access to multiple
+ * nodes' vertices without duplication, the vert_indices array
+ * is ordered such that the first part of the array, up to
+ * index 'uniq_verts', contains "unique" vertex indices. These
+ * vertices might not be truly unique to this node, but if
+ * they appear in another node's vert_indices array, they will
+ * be above that node's 'uniq_verts' value.
+ *
+ * Used for leaf nodes in a mesh-based PBVH (not multires.)
+ */
+ int *vert_indices;
+ unsigned int uniq_verts, face_verts;
+
+ /* An array mapping face corners into the vert_indices
+ * array. The array is sized to match 'totprim', and each of
+ * the face's corners gets an index into the vert_indices
+ * array, in the same order as the corners in the original
+ * MFace. The fourth value should not be used if the original
+ * face is a triangle.
+ *
+ * Used for leaf nodes in a mesh-based PBVH (not multires.)
+ */
+ int (*face_vert_indices)[4];
+
+ /* Indicates whether this node is a leaf or not; also used for
+ * marking various updates that need to be applied. */
+ PBVHNodeFlags flag : 16;
+
+ /* Used for raycasting: how close bb is to the ray point. */
+ float tmin;
+
+ /* Scalar displacements for sculpt mode's layer brush. */
+ float *layer_disp;
+
+ int proxy_count;
+ PBVHProxyNode *proxies;
+
+ /* Dyntopo */
+ GHash *bm_faces;
+ GHash *bm_unique_verts;
+ GHash *bm_other_verts;
+ float (*bm_orco)[3];
+ int (*bm_ortri)[3];
+ int bm_tot_ortri;
+};
+
+typedef enum {
+ PBVH_DYNTOPO_SMOOTH_SHADING = 1
+} PBVHFlags;
+
+typedef struct PBVHBMeshLog PBVHBMeshLog;
+
+struct PBVH {
+ PBVHType type;
+ PBVHFlags flags;
+
+ PBVHNode *nodes;
+ int node_mem_count, totnode;
+
+ int *prim_indices;
+ int totprim;
+ int totvert;
+
+ int leaf_limit;
+
+ /* Mesh data */
+ MVert *verts;
+ MFace *faces;
+ CustomData *vdata;
+
+ /* Grid Data */
+ CCGKey gridkey;
+ CCGElem **grids;
+ DMGridAdjacency *gridadj;
+ void **gridfaces;
+ const DMFlagMat *grid_flag_mats;
+ int totgrid;
+ BLI_bitmap *grid_hidden;
+
+ /* Only used during BVH build and update,
+ * don't need to remain valid after */
+ BLI_bitmap vert_bitmap;
+
+#ifdef PERFCNTRS
+ int perf_modified;
+#endif
+
+ /* flag are verts/faces deformed */
+ int deformed;
+
+ int show_diffuse_color;
+
+ /* Dynamic topology */
+ BMesh *bm;
+ GHash *bm_face_to_node;
+ GHash *bm_vert_to_node;
+ float bm_max_edge_len;
+ float bm_min_edge_len;
+
+ struct BMLog *bm_log;
+};
+
+/* pbvh.c */
+void BB_reset(BB *bb);
+void BB_expand(BB *bb, const float co[3]);
+void BB_expand_with_bb(BB *bb, BB *bb2);
+void BBC_update_centroid(BBC *bbc);
+int BB_widest_axis(const BB *bb);
+void pbvh_grow_nodes(PBVH *bvh, int totnode);
+int ray_face_intersection(const float ray_start[3], const float ray_normal[3],
+ const float *t0, const float *t1, const float *t2,
+ const float *t3, float *fdist);
+void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes, int totnode, int flag);
+
+/* pbvh_bmesh.c */
+int pbvh_bmesh_node_raycast(PBVHNode *node, const float ray_start[3],
+ const float ray_normal[3], float *dist,
+ int use_original);
+
+void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode);
+
+#endif
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 2eadfe73858..9c3c1b0e508 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -1540,7 +1540,7 @@ void BKE_ptcache_mem_pointers_incr(PTCacheMem *pm)
for (i=0; i<BPHYS_TOT_DATA; i++) {
if (pm->cur[i])
- pm->cur[i] = (char*)pm->cur[i] + ptcache_data_size[i];
+ pm->cur[i] = (char *)pm->cur[i] + ptcache_data_size[i];
}
}
int BKE_ptcache_mem_pointers_seek(int point_index, PTCacheMem *pm)
@@ -1558,7 +1558,7 @@ int BKE_ptcache_mem_pointers_seek(int point_index, PTCacheMem *pm)
}
for (i=0; i<BPHYS_TOT_DATA; i++)
- pm->cur[i] = data_types & (1<<i) ? (char*)pm->data[i] + index * ptcache_data_size[i] : NULL;
+ pm->cur[i] = data_types & (1<<i) ? (char *)pm->data[i] + index * ptcache_data_size[i] : NULL;
return 1;
}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 538f21ce20b..04e612d1a33 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -414,6 +414,7 @@ static Scene *scene_add(Main *bmain, const char *name)
sce->r.im_format.planes = R_IMF_PLANES_RGB;
sce->r.im_format.imtype = R_IMF_IMTYPE_PNG;
+ sce->r.im_format.depth = R_IMF_CHAN_DEPTH_8;
sce->r.im_format.quality = 90;
sce->r.im_format.compress = 90;
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 56fddfdaa2b..81bcdc4b06e 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -279,6 +279,7 @@ void BKE_area_region_free(SpaceType *st, ARegion *ar)
}
BLI_freelistN(&ar->panels);
+ BLI_freelistN(&ar->ui_lists);
}
/* not area itself */
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 3bff209f53c..3ca04f235b8 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -156,42 +156,43 @@ static void init_alpha_over_or_under(Sequence *seq)
seq->seq1 = seq2;
}
-static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y, char *rect1, char *rect2, char *out)
+static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
{
- int fac2, mfac, fac, fac4;
- int xo, tempc;
- char *rt1, *rt2, *rt;
+ float fac2, mfac, fac, fac4;
+ int xo;
+ unsigned char *cp1, *cp2, *rt;
+ float tempc[4], rt1[4], rt2[4];
xo = x;
- rt1 = (char *) rect1;
- rt2 = (char *) rect2;
- rt = (char *) out;
+ cp1 = rect1;
+ cp2 = rect2;
+ rt = out;
- fac2 = (int) (256.0f * facf0);
- fac4 = (int) (256.0f * facf1);
+ fac2 = facf0;
+ fac4 = facf1;
while (y--) {
x = xo;
while (x--) {
-
/* rt = rt1 over rt2 (alpha from rt1) */
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
+
fac = fac2;
- mfac = 256 - ( (fac2 * rt1[3]) >> 8);
+ mfac = 1.0f - fac2 * rt1[3];
- if (fac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt2);
- else if (mfac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt1);
+ if (fac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp2);
+ else if (mfac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp1);
else {
- tempc = (fac * rt1[0] + mfac * rt2[0]) >> 8;
- if (tempc > 255) rt[0] = 255; else rt[0] = tempc;
- tempc = (fac * rt1[1] + mfac * rt2[1]) >> 8;
- if (tempc > 255) rt[1] = 255; else rt[1] = tempc;
- tempc = (fac * rt1[2] + mfac * rt2[2]) >> 8;
- if (tempc > 255) rt[2] = 255; else rt[2] = tempc;
- tempc = (fac * rt1[3] + mfac * rt2[3]) >> 8;
- if (tempc > 255) rt[3] = 255; else rt[3] = tempc;
+ tempc[0] = fac * rt1[0] + mfac * rt2[0];
+ tempc[1] = fac * rt1[1] + mfac * rt2[1];
+ tempc[2] = fac * rt1[2] + mfac * rt2[2];
+ tempc[3] = fac * rt1[3] + mfac * rt2[3];
+
+ premul_float_to_straight_uchar(rt, tempc);
}
- rt1 += 4; rt2 += 4; rt += 4;
+ cp1 += 4; cp2 += 4; rt += 4;
}
if (y == 0) break;
@@ -199,22 +200,23 @@ static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y, ch
x = xo;
while (x--) {
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
+
fac = fac4;
- mfac = 256 - ( (fac4 * rt1[3]) >> 8);
+ mfac = 1.0f - (fac4 * rt1[3]);
- if (fac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt2);
- else if (mfac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt1);
+ if (fac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp2);
+ else if (mfac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp1);
else {
- tempc = (fac * rt1[0] + mfac * rt2[0]) >> 8;
- if (tempc > 255) rt[0] = 255; else rt[0] = tempc;
- tempc = (fac * rt1[1] + mfac * rt2[1]) >> 8;
- if (tempc > 255) rt[1] = 255; else rt[1] = tempc;
- tempc = (fac * rt1[2] + mfac * rt2[2]) >> 8;
- if (tempc > 255) rt[2] = 255; else rt[2] = tempc;
- tempc = (fac * rt1[3] + mfac * rt2[3]) >> 8;
- if (tempc > 255) rt[3] = 255; else rt[3] = tempc;
+ tempc[0] = fac * rt1[0] + mfac * rt2[0];
+ tempc[1] = fac * rt1[1] + mfac * rt2[1];
+ tempc[2] = fac * rt1[2] + mfac * rt2[2];
+ tempc[3] = fac * rt1[3] + mfac * rt2[3];
+
+ premul_float_to_straight_uchar(rt, tempc);
}
- rt1 += 4; rt2 += 4; rt += 4;
+ cp1 += 4; cp2 += 4; rt += 4;
}
}
}
@@ -298,17 +300,17 @@ static void do_alphaover_effect(SeqRenderData context, Sequence *UNUSED(seq), fl
slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
- do_alphaover_effect_byte(facf0, facf1, context.rectx, total_lines, (char *) rect1, (char *) rect2, (char *) rect_out);
+ do_alphaover_effect_byte(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
}
/*********************** Alpha Under *************************/
-static void do_alphaunder_effect_byte(float facf0, float facf1, int x, int y, char *rect1, char *rect2, char *out)
+static void do_alphaunder_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
{
int fac2, mfac, fac, fac4;
int xo;
- char *rt1, *rt2, *rt;
+ unsigned char *rt1, *rt2, *rt;
xo = x;
rt1 = rect1;
@@ -460,17 +462,17 @@ static void do_alphaunder_effect(SeqRenderData context, Sequence *UNUSED(seq), f
slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
- do_alphaunder_effect_byte(facf0, facf1, context.rectx, total_lines, (char *) rect1, (char *) rect2, (char *) rect_out);
+ do_alphaunder_effect_byte(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
}
/*********************** Cross *************************/
-static void do_cross_effect_byte(float facf0, float facf1, int x, int y, char *rect1, char *rect2, char *out)
+static void do_cross_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
{
int fac1, fac2, fac3, fac4;
int xo;
- char *rt1, *rt2, *rt;
+ unsigned char *rt1, *rt2, *rt;
xo = x;
rt1 = rect1;
@@ -570,7 +572,7 @@ static void do_cross_effect(SeqRenderData context, Sequence *UNUSED(seq), float
slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
- do_cross_effect_byte(facf0, facf1, context.rectx, total_lines, (char *) rect1, (char *) rect2, (char *) rect_out);
+ do_cross_effect_byte(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
}
@@ -713,31 +715,32 @@ static void free_gammacross(Sequence *UNUSED(seq))
static void do_gammacross_effect_byte(float facf0, float UNUSED(facf1), int x, int y, unsigned char *rect1,
unsigned char *rect2, unsigned char *out)
{
- int fac1, fac2, col;
+ float fac1, fac2;
int xo;
- unsigned char *rt1, *rt2, *rt;
-
+ unsigned char *cp1, *cp2, *rt;
+ float rt1[4], rt2[4], tempc[4];
+
xo = x;
- rt1 = (unsigned char *) rect1;
- rt2 = (unsigned char *) rect2;
- rt = (unsigned char *) out;
+ cp1 = rect1;
+ cp2 = rect2;
+ rt = out;
- fac2 = (int)(256.0f * facf0);
- fac1 = 256 - fac2;
+ fac2 = facf0;
+ fac1 = 1.0f - fac2;
while (y--) {
x = xo;
while (x--) {
- col = (fac1 * igamtab1[rt1[0]] + fac2 * igamtab1[rt2[0]]) >> 8;
- if (col > 65535) rt[0] = 255; else rt[0] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
- col = (fac1 * igamtab1[rt1[1]] + fac2 * igamtab1[rt2[1]]) >> 8;
- if (col > 65535) rt[1] = 255; else rt[1] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
- col = (fac1 * igamtab1[rt1[2]] + fac2 * igamtab1[rt2[2]]) >> 8;
- if (col > 65535) rt[2] = 255; else rt[2] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
- col = (fac1 * igamtab1[rt1[3]] + fac2 * igamtab1[rt2[3]]) >> 8;
- if (col > 65535) rt[3] = 255; else rt[3] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
- rt1 += 4; rt2 += 4; rt += 4;
+ tempc[0] = gammaCorrect(fac1 * invGammaCorrect(rt1[0]) + fac2 * invGammaCorrect(rt2[0]));
+ tempc[1] = gammaCorrect(fac1 * invGammaCorrect(rt1[1]) + fac2 * invGammaCorrect(rt2[1]));
+ tempc[2] = gammaCorrect(fac1 * invGammaCorrect(rt1[2]) + fac2 * invGammaCorrect(rt2[2]));
+ tempc[3] = gammaCorrect(fac1 * invGammaCorrect(rt1[3]) + fac2 * invGammaCorrect(rt2[3]));
+
+ premul_float_to_straight_uchar(rt, tempc);
+ cp1 += 4; cp2 += 4; rt += 4;
}
if (y == 0)
@@ -746,16 +749,16 @@ static void do_gammacross_effect_byte(float facf0, float UNUSED(facf1), int x,
x = xo;
while (x--) {
- col = (fac1 * igamtab1[rt1[0]] + fac2 * igamtab1[rt2[0]]) >> 8;
- if (col > 65535) rt[0] = 255; else rt[0] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
- col = (fac1 * igamtab1[rt1[1]] + fac2 * igamtab1[rt2[1]]) >> 8;
- if (col > 65535) rt[1] = 255; else rt[1] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
- col = (fac1 * igamtab1[rt1[2]] + fac2 * igamtab1[rt2[2]]) >> 8;
- if (col > 65535) rt[2] = 255; else rt[2] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
- col = (fac1 * igamtab1[rt1[3]] + fac2 * igamtab1[rt2[3]]) >> 8;
- if (col > 65535) rt[3] = 255; else rt[3] = ( (char *)(gamtab + col))[MOST_SIG_BYTE];
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
- rt1 += 4; rt2 += 4; rt += 4;
+ tempc[0] = gammaCorrect(fac1 * invGammaCorrect(rt1[0]) + fac2 * invGammaCorrect(rt2[0]));
+ tempc[1] = gammaCorrect(fac1 * invGammaCorrect(rt1[1]) + fac2 * invGammaCorrect(rt2[1]));
+ tempc[2] = gammaCorrect(fac1 * invGammaCorrect(rt1[2]) + fac2 * invGammaCorrect(rt2[2]));
+ tempc[3] = gammaCorrect(fac1 * invGammaCorrect(rt1[3]) + fac2 * invGammaCorrect(rt2[3]));
+
+ premul_float_to_straight_uchar(rt, tempc);
+ cp1 += 4; cp2 += 4; rt += 4;
}
}
}
@@ -828,31 +831,34 @@ static void do_gammacross_effect(SeqRenderData context, Sequence *UNUSED(seq), f
static void do_add_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2,
unsigned char *out)
{
- int col, xo, fac1, fac3;
- char *rt1, *rt2, *rt;
+ int xo;
+ unsigned char *cp1, *cp2, *rt;
+ float fac1, fac3;
+ float tempc[4], rt1[4], rt2[4];
xo = x;
- rt1 = (char *)rect1;
- rt2 = (char *)rect2;
- rt = (char *)out;
+ cp1 = rect1;
+ cp2 = rect2;
+ rt = out;
- fac1 = (int)(256.0f * facf0);
- fac3 = (int)(256.0f * facf1);
+ fac1 = facf0;
+ fac3 = facf1;
while (y--) {
x = xo;
while (x--) {
- col = rt1[0] + ((fac1 * rt2[0]) >> 8);
- if (col > 255) rt[0] = 255; else rt[0] = col;
- col = rt1[1] + ((fac1 * rt2[1]) >> 8);
- if (col > 255) rt[1] = 255; else rt[1] = col;
- col = rt1[2] + ((fac1 * rt2[2]) >> 8);
- if (col > 255) rt[2] = 255; else rt[2] = col;
- col = rt1[3] + ((fac1 * rt2[3]) >> 8);
- if (col > 255) rt[3] = 255; else rt[3] = col;
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
- rt1 += 4; rt2 += 4; rt += 4;
+ tempc[0] = rt1[0] + fac1 * rt2[0];
+ tempc[1] = rt1[1] + fac1 * rt2[1];
+ tempc[2] = rt1[2] + fac1 * rt2[2];
+ tempc[3] = min_ff(1.0f, rt1[3] + fac1 * rt2[3]);
+
+ premul_float_to_straight_uchar(rt, tempc);
+
+ cp1 += 4; cp2 += 4; rt += 4;
}
if (y == 0)
@@ -861,16 +867,17 @@ static void do_add_effect_byte(float facf0, float facf1, int x, int y, unsigned
x = xo;
while (x--) {
- col = rt1[0] + ((fac3 * rt2[0]) >> 8);
- if (col > 255) rt[0] = 255; else rt[0] = col;
- col = rt1[1] + ((fac3 * rt2[1]) >> 8);
- if (col > 255) rt[1] = 255; else rt[1] = col;
- col = rt1[2] + ((fac3 * rt2[2]) >> 8);
- if (col > 255) rt[2] = 255; else rt[2] = col;
- col = rt1[3] + ((fac3 * rt2[3]) >> 8);
- if (col > 255) rt[3] = 255; else rt[3] = col;
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
- rt1 += 4; rt2 += 4; rt += 4;
+ tempc[0] = rt1[0] + fac3 * rt2[0];
+ tempc[1] = rt1[1] + fac3 * rt2[1];
+ tempc[2] = rt1[2] + fac3 * rt2[2];
+ tempc[3] = min_ff(1.0f, rt1[3] + fac3 * rt2[3]);
+
+ premul_float_to_straight_uchar(rt, tempc);
+
+ cp1 += 4; cp2 += 4; rt += 4;
}
}
}
@@ -890,22 +897,28 @@ static void do_add_effect_float(float facf0, float facf1, int x, int y, float *r
fac3 = facf1;
while (y--) {
- x = xo * 4;
+ x = xo;
while (x--) {
- *rt = *rt1 + fac1 * (*rt2);
+ rt[0] = rt1[0] + fac1 * rt2[0];
+ rt[1] = rt1[1] + fac1 * rt2[1];
+ rt[2] = rt1[2] + fac1 * rt2[2];
+ rt[3] = min_ff(1.0f, rt1[3] + fac1 * rt2[3]);
- rt1++; rt2++; rt++;
+ rt1 += 4; rt2 += 4; rt += 4;
}
if (y == 0)
break;
y--;
- x = xo * 4;
+ x = xo;
while (x--) {
- *rt = *rt1 + fac3 * (*rt2);
+ rt[0] = rt1[0] + fac1 * rt2[0];
+ rt[1] = rt1[1] + fac1 * rt2[1];
+ rt[2] = rt1[2] + fac1 * rt2[2];
+ rt[3] = min_ff(1.0f, rt1[3] + fac3 * rt2[3]);
- rt1++; rt2++; rt++;
+ rt1 += 4; rt2 += 4; rt += 4;
}
}
}
@@ -931,32 +944,35 @@ static void do_add_effect(SeqRenderData context, Sequence *UNUSED(seq), float UN
/*********************** Sub *************************/
-static void do_sub_effect_byte(float facf0, float facf1, int x, int y, char *rect1, char *rect2, char *out)
+static void do_sub_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect1, unsigned char *rect2, unsigned char *out)
{
- int col, xo, fac1, fac3;
- char *rt1, *rt2, *rt;
+ int xo;
+ unsigned char *cp1, *cp2, *rt;
+ float fac1, fac3;
+ float tempc[4], rt1[4], rt2[4];
xo = x;
- rt1 = (char *) rect1;
- rt2 = (char *) rect2;
- rt = (char *) out;
+ cp1 = rect1;
+ cp2 = rect2;
+ rt = out;
- fac1 = (int) (256.0f * facf0);
- fac3 = (int) (256.0f * facf1);
+ fac1 = facf0;
+ fac3 = facf1;
while (y--) {
x = xo;
while (x--) {
- col = rt1[0] - ((fac1 * rt2[0]) >> 8);
- if (col < 0) rt[0] = 0; else rt[0] = col;
- col = rt1[1] - ((fac1 * rt2[1]) >> 8);
- if (col < 0) rt[1] = 0; else rt[1] = col;
- col = rt1[2] - ((fac1 * rt2[2]) >> 8);
- if (col < 0) rt[2] = 0; else rt[2] = col;
- col = rt1[3] - ((fac1 * rt2[3]) >> 8);
- if (col < 0) rt[3] = 0; else rt[3] = col;
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
- rt1 += 4; rt2 += 4; rt += 4;
+ tempc[0] = rt1[0] - fac1 * rt2[0];
+ tempc[1] = rt1[1] - fac1 * rt2[1];
+ tempc[2] = rt1[2] - fac1 * rt2[2];
+ tempc[3] = rt1[3] - fac1 * rt2[3];
+
+ premul_float_to_straight_uchar(rt, tempc);
+
+ cp1 += 4; cp2 += 4; rt += 4;
}
if (y == 0)
@@ -965,16 +981,17 @@ static void do_sub_effect_byte(float facf0, float facf1, int x, int y, char *rec
x = xo;
while (x--) {
- col = rt1[0] - ((fac3 * rt2[0]) >> 8);
- if (col < 0) rt[0] = 0; else rt[0] = col;
- col = rt1[1] - ((fac3 * rt2[1]) >> 8);
- if (col < 0) rt[1] = 0; else rt[1] = col;
- col = rt1[2] - ((fac3 * rt2[2]) >> 8);
- if (col < 0) rt[2] = 0; else rt[2] = col;
- col = rt1[3] - ((fac3 * rt2[3]) >> 8);
- if (col < 0) rt[3] = 0; else rt[3] = col;
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
- rt1 += 4; rt2 += 4; rt += 4;
+ tempc[0] = rt1[0] - fac3 * rt2[0];
+ tempc[1] = rt1[1] - fac3 * rt2[1];
+ tempc[2] = rt1[2] - fac3 * rt2[2];
+ tempc[3] = rt1[3] - fac3 * rt2[3];
+
+ premul_float_to_straight_uchar(rt, tempc);
+
+ cp1 += 4; cp2 += 4; rt += 4;
}
}
}
@@ -1029,7 +1046,7 @@ static void do_sub_effect(SeqRenderData context, Sequence *UNUSED(seq), float UN
slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
- do_sub_effect_byte(facf0, facf1, context.rectx, total_lines, (char *) rect1, (char *) rect2, (char *) rect_out);
+ do_sub_effect_byte(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
}
@@ -1039,10 +1056,10 @@ static void do_sub_effect(SeqRenderData context, Sequence *UNUSED(seq), float UN
#define XOFF 8
#define YOFF 8
-static void do_drop_effect_byte(float facf0, float facf1, int x, int y, char *rect2i, char *rect1i, char *outi)
+static void do_drop_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect2i, unsigned char *rect1i, unsigned char *outi)
{
int height, width, temp, fac, fac1, fac2;
- char *rt1, *rt2, *out;
+ unsigned char *rt1, *rt2, *out;
int field = 1;
width = x;
@@ -1051,9 +1068,9 @@ static void do_drop_effect_byte(float facf0, float facf1, int x, int y, char *re
fac1 = (int) (70.0f * facf0);
fac2 = (int) (70.0f * facf1);
- rt2 = (char *) (rect2i + YOFF * width);
- rt1 = (char *) rect1i;
- out = (char *) outi;
+ rt2 = (unsigned char *) (rect2i + YOFF * width);
+ rt1 = (unsigned char *) rect1i;
+ out = (unsigned char *) outi;
for (y = 0; y < height - YOFF; y++) {
if (field) fac = fac1;
else fac = fac2;
@@ -1122,12 +1139,12 @@ static void do_mul_effect_byte(float facf0, float facf1, int x, int y, unsigned
unsigned char *out)
{
int xo, fac1, fac3;
- char *rt1, *rt2, *rt;
+ unsigned char *rt1, *rt2, *rt;
xo = x;
- rt1 = (char *)rect1;
- rt2 = (char *)rect2;
- rt = (char *)out;
+ rt1 = rect1;
+ rt2 = rect2;
+ rt = out;
fac1 = (int)(256.0f * facf0);
fac3 = (int)(256.0f * facf1);
@@ -1539,13 +1556,13 @@ static void do_wipe_effect_byte(Sequence *seq, float facf0, float UNUSED(facf1),
WipeZone wipezone;
WipeVars *wipe = (WipeVars *)seq->effectdata;
int xo, yo;
- char *rt1, *rt2, *rt;
+ unsigned char *cp1, *cp2, *rt;
precalc_wipe_zone(&wipezone, wipe, x, y);
- rt1 = (char *)rect1;
- rt2 = (char *)rect2;
- rt = (char *)out;
+ cp1 = rect1;
+ cp2 = rect2;
+ rt = out;
xo = x;
yo = y;
@@ -1553,11 +1570,18 @@ static void do_wipe_effect_byte(Sequence *seq, float facf0, float UNUSED(facf1),
for (x = 0; x < xo; x++) {
float check = check_zone(&wipezone, x, y, seq, facf0);
if (check) {
- if (rt1) {
- rt[0] = (int)(rt1[0] * check) + (int)(rt2[0] * (1 - check));
- rt[1] = (int)(rt1[1] * check) + (int)(rt2[1] * (1 - check));
- rt[2] = (int)(rt1[2] * check) + (int)(rt2[2] * (1 - check));
- rt[3] = (int)(rt1[3] * check) + (int)(rt2[3] * (1 - check));
+ if (cp1) {
+ float rt1[4], rt2[4], tempc[4];
+
+ straight_uchar_to_premul_float(rt1, cp1);
+ straight_uchar_to_premul_float(rt2, cp2);
+
+ tempc[0] = rt1[0] * check + rt2[0] * (1 - check);
+ tempc[1] = rt1[1] * check + rt2[1] * (1 - check);
+ tempc[2] = rt1[2] * check + rt2[2] * (1 - check);
+ tempc[3] = rt1[3] * check + rt2[3] * (1 - check);
+
+ premul_float_to_straight_uchar(rt, tempc);
}
else {
rt[0] = 0;
@@ -1567,11 +1591,11 @@ static void do_wipe_effect_byte(Sequence *seq, float facf0, float UNUSED(facf1),
}
}
else {
- if (rt2) {
- rt[0] = rt2[0];
- rt[1] = rt2[1];
- rt[2] = rt2[2];
- rt[3] = rt2[3];
+ if (cp2) {
+ rt[0] = cp2[0];
+ rt[1] = cp2[1];
+ rt[2] = cp2[2];
+ rt[3] = cp2[3];
}
else {
rt[0] = 0;
@@ -1582,11 +1606,11 @@ static void do_wipe_effect_byte(Sequence *seq, float facf0, float UNUSED(facf1),
}
rt += 4;
- if (rt1 != NULL) {
- rt1 += 4;
+ if (cp1 != NULL) {
+ cp1 += 4;
}
- if (rt2 != NULL) {
- rt2 += 4;
+ if (cp2 != NULL) {
+ cp2 += 4;
}
}
}
@@ -1803,166 +1827,6 @@ static ImBuf *do_transform_effect(SeqRenderData context, Sequence *seq, float UN
/*********************** Glow *************************/
-static void RVBlurBitmap2_byte(unsigned char *map, int width, int height, float blur, int quality)
-/* MUUUCCH better than the previous blur. */
-/* We do the blurring in two passes which is a whole lot faster. */
-/* I changed the math arount to implement an actual Gaussian */
-/* distribution. */
-/* */
-/* Watch out though, it tends to misbehaven with large blur values on */
-/* a small bitmap. Avoid avoid avoid. */
-/*=============================== */
-{
- unsigned char *temp = NULL, *swap;
- float *filter = NULL;
- int x, y, i, fx, fy;
- int index, ix, halfWidth;
- float fval, k, curColor[3], curColor2[3], weight = 0;
-
- /* If we're not really blurring, bail out */
- if (blur <= 0)
- return;
-
- /*Allocate memory for the tempmap and the blur filter matrix */
- temp = MEM_mallocN((width * height * 4), "blurbitmaptemp");
- if (!temp)
- return;
-
- /*Allocate memory for the filter elements */
- halfWidth = ((quality + 1) * blur);
- filter = (float *)MEM_mallocN(sizeof(float) * halfWidth * 2, "blurbitmapfilter");
- if (!filter) {
- MEM_freeN(temp);
- return;
- }
-
- /* Apparently we're calculating a bell curve based on the standard deviation (or radius)
- * This code is based on an example posted to comp.graphics.algorithms by
- * Blancmange (bmange@airdmhor.gen.nz)
- */
-
- k = -1.0f / (2.0f * (float)M_PI * blur * blur);
- for (ix = 0; ix < halfWidth; ix++) {
- weight = (float)exp(k * (ix * ix));
- filter[halfWidth - ix] = weight;
- filter[halfWidth + ix] = weight;
- }
- filter[0] = weight;
-
- /* Normalize the array */
- fval = 0;
- for (ix = 0; ix < halfWidth * 2; ix++)
- fval += filter[ix];
-
- for (ix = 0; ix < halfWidth * 2; ix++)
- filter[ix] /= fval;
-
- /* Blur the rows */
- for (y = 0; y < height; y++) {
- /* Do the left & right strips */
- for (x = 0; x < halfWidth; x++) {
- index = (x + y * width) * 4;
- fx = 0;
- zero_v3(curColor);
- zero_v3(curColor2);
-
- for (i = x - halfWidth; i < x + halfWidth; i++) {
- if ((i >= 0) && (i < width)) {
- curColor[0] += map[(i + y * width) * 4 + GlowR] * filter[fx];
- curColor[1] += map[(i + y * width) * 4 + GlowG] * filter[fx];
- curColor[2] += map[(i + y * width) * 4 + GlowB] * filter[fx];
-
- curColor2[0] += map[(width - 1 - i + y * width) * 4 + GlowR] * filter[fx];
- curColor2[1] += map[(width - 1 - i + y * width) * 4 + GlowG] * filter[fx];
- curColor2[2] += map[(width - 1 - i + y * width) * 4 + GlowB] * filter[fx];
- }
- fx++;
- }
- temp[index + GlowR] = curColor[0];
- temp[index + GlowG] = curColor[1];
- temp[index + GlowB] = curColor[2];
-
- temp[((width - 1 - x + y * width) * 4) + GlowR] = curColor2[0];
- temp[((width - 1 - x + y * width) * 4) + GlowG] = curColor2[1];
- temp[((width - 1 - x + y * width) * 4) + GlowB] = curColor2[2];
-
- }
-
- /* Do the main body */
- for (x = halfWidth; x < width - halfWidth; x++) {
- index = (x + y * width) * 4;
- fx = 0;
- zero_v3(curColor);
- for (i = x - halfWidth; i < x + halfWidth; i++) {
- curColor[0] += map[(i + y * width) * 4 + GlowR] * filter[fx];
- curColor[1] += map[(i + y * width) * 4 + GlowG] * filter[fx];
- curColor[2] += map[(i + y * width) * 4 + GlowB] * filter[fx];
- fx++;
- }
- temp[index + GlowR] = curColor[0];
- temp[index + GlowG] = curColor[1];
- temp[index + GlowB] = curColor[2];
- }
- }
-
- /* Swap buffers */
- swap = temp; temp = map; map = swap;
-
- /* Blur the columns */
- for (x = 0; x < width; x++) {
- /* Do the top & bottom strips */
- for (y = 0; y < halfWidth; y++) {
- index = (x + y * width) * 4;
- fy = 0;
- zero_v3(curColor);
- zero_v3(curColor2);
- for (i = y - halfWidth; i < y + halfWidth; i++) {
- if ((i >= 0) && (i < height)) {
- /* Bottom */
- curColor[0] += map[(x + i * width) * 4 + GlowR] * filter[fy];
- curColor[1] += map[(x + i * width) * 4 + GlowG] * filter[fy];
- curColor[2] += map[(x + i * width) * 4 + GlowB] * filter[fy];
-
- /* Top */
- curColor2[0] += map[(x + (height - 1 - i) * width) * 4 + GlowR] * filter[fy];
- curColor2[1] += map[(x + (height - 1 - i) * width) * 4 + GlowG] * filter[fy];
- curColor2[2] += map[(x + (height - 1 - i) * width) * 4 + GlowB] * filter[fy];
- }
- fy++;
- }
- temp[index + GlowR] = curColor[0];
- temp[index + GlowG] = curColor[1];
- temp[index + GlowB] = curColor[2];
- temp[((x + (height - 1 - y) * width) * 4) + GlowR] = curColor2[0];
- temp[((x + (height - 1 - y) * width) * 4) + GlowG] = curColor2[1];
- temp[((x + (height - 1 - y) * width) * 4) + GlowB] = curColor2[2];
- }
-
- /* Do the main body */
- for (y = halfWidth; y < height - halfWidth; y++) {
- index = (x + y * width) * 4;
- fy = 0;
- zero_v3(curColor);
- for (i = y - halfWidth; i < y + halfWidth; i++) {
- curColor[0] += map[(x + i * width) * 4 + GlowR] * filter[fy];
- curColor[1] += map[(x + i * width) * 4 + GlowG] * filter[fy];
- curColor[2] += map[(x + i * width) * 4 + GlowB] * filter[fy];
- fy++;
- }
- temp[index + GlowR] = curColor[0];
- temp[index + GlowG] = curColor[1];
- temp[index + GlowB] = curColor[2];
- }
- }
-
- /* Swap buffers */
- swap = temp; temp = map; /* map = swap; */ /* UNUSED */
-
- /* Tidy up */
- MEM_freeN(filter);
- MEM_freeN(temp);
-}
-
static void RVBlurBitmap2_float(float *map, int width, int height, float blur, int quality)
/* MUUUCCH better than the previous blur. */
/* We do the blurring in two passes which is a whole lot faster. */
@@ -2124,26 +1988,6 @@ static void RVBlurBitmap2_float(float *map, int width, int height, float blur, i
MEM_freeN(temp);
}
-
-/* Adds two bitmaps and puts the results into a third map. */
-/* C must have been previously allocated but it may be A or B. */
-/* We clamp values to 255 to prevent weirdness */
-/*=============================== */
-static void RVAddBitmaps_byte(unsigned char *a, unsigned char *b, unsigned char *c, int width, int height)
-{
- int x, y, index;
-
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- index = (x + y * width) * 4;
- c[index + GlowR] = MIN2(255, a[index + GlowR] + b[index + GlowR]);
- c[index + GlowG] = MIN2(255, a[index + GlowG] + b[index + GlowG]);
- c[index + GlowB] = MIN2(255, a[index + GlowB] + b[index + GlowB]);
- c[index + GlowA] = MIN2(255, a[index + GlowA] + b[index + GlowA]);
- }
- }
-}
-
static void RVAddBitmaps_float(float *a, float *b, float *c, int width, int height)
{
int x, y, index;
@@ -2159,37 +2003,6 @@ static void RVAddBitmaps_float(float *a, float *b, float *c, int width, int heig
}
}
-/* For each pixel whose total luminance exceeds the threshold,
- * Multiply it's value by BOOST and add it to the output map
- */
-static void RVIsolateHighlights_byte(unsigned char *in, unsigned char *out, int width, int height, int threshold,
- float boost, float clamp)
-{
- int x, y, index;
- int intensity;
-
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- index = (x + y * width) * 4;
-
- /* Isolate the intensity */
- intensity = (in[index + GlowR] + in[index + GlowG] + in[index + GlowB] - threshold);
- if (intensity > 0) {
- out[index + GlowR] = MIN2(255 * clamp, (in[index + GlowR] * boost * intensity) / 255);
- out[index + GlowG] = MIN2(255 * clamp, (in[index + GlowG] * boost * intensity) / 255);
- out[index + GlowB] = MIN2(255 * clamp, (in[index + GlowB] * boost * intensity) / 255);
- out[index + GlowA] = MIN2(255 * clamp, (in[index + GlowA] * boost * intensity) / 255);
- }
- else {
- out[index + GlowR] = 0;
- out[index + GlowG] = 0;
- out[index + GlowB] = 0;
- out[index + GlowA] = 0;
- }
- }
- }
-}
-
static void RVIsolateHighlights_float(float *in, float *out, int width, int height, float threshold, float boost, float clamp)
{
int x, y, index;
@@ -2254,16 +2067,27 @@ static void copy_glow_effect(Sequence *dst, Sequence *src)
}
static void do_glow_effect_byte(Sequence *seq, int render_size, float facf0, float UNUSED(facf1), int x, int y,
- char *rect1, char *UNUSED(rect2), char *out)
+ unsigned char *rect1, unsigned char *UNUSED(rect2), unsigned char *out)
{
- unsigned char *outbuf = (unsigned char *)out;
- unsigned char *inbuf = (unsigned char *)rect1;
+ float *outbuf, *inbuf;
GlowVars *glow = (GlowVars *)seq->effectdata;
-
- RVIsolateHighlights_byte(inbuf, outbuf, x, y, glow->fMini * 765, glow->fBoost * facf0, glow->fClamp);
- RVBlurBitmap2_byte(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality);
+
+ inbuf = MEM_mallocN(4 * sizeof(float) * x * y, "glow effect input");
+ outbuf = MEM_mallocN(4 * sizeof(float) * x * y, "glow effect output");
+
+ IMB_buffer_float_from_byte(inbuf, rect1, IB_PROFILE_SRGB, IB_PROFILE_SRGB, FALSE, x, y, x, x);
+ IMB_buffer_float_premultiply(inbuf, x, y);
+
+ RVIsolateHighlights_float(inbuf, outbuf, x, y, glow->fMini * 3.0f, glow->fBoost * facf0, glow->fClamp);
+ RVBlurBitmap2_float(outbuf, x, y, glow->dDist * (render_size / 100.0f), glow->dQuality);
if (!glow->bNoComp)
- RVAddBitmaps_byte(inbuf, outbuf, outbuf, x, y);
+ RVAddBitmaps_float(inbuf, outbuf, outbuf, x, y);
+
+ IMB_buffer_float_unpremultiply(outbuf, x, y);
+ IMB_buffer_byte_from_float(out, outbuf, 4, 0.0f, IB_PROFILE_SRGB, IB_PROFILE_SRGB, FALSE, x, y, x, x);
+
+ MEM_freeN(inbuf);
+ MEM_freeN(outbuf);
}
static void do_glow_effect_float(Sequence *seq, int render_size, float facf0, float UNUSED(facf1), int x, int y,
@@ -2292,7 +2116,7 @@ static ImBuf *do_glow_effect(SeqRenderData context, Sequence *seq, float UNUSED(
}
else {
do_glow_effect_byte(seq, render_size, facf0, facf1, context.rectx, context.recty,
- (char *) ibuf1->rect, (char *) ibuf2->rect, (char *) out->rect);
+ (unsigned char *) ibuf1->rect, (unsigned char *) ibuf2->rect, (unsigned char *) out->rect);
}
return out;
@@ -2735,7 +2559,7 @@ static ImBuf *do_speed_effect(SeqRenderData context, Sequence *UNUSED(seq), floa
}
else {
do_cross_effect_byte(facf0, facf1, context.rectx, context.recty,
- (char *) ibuf1->rect, (char *) ibuf2->rect, (char *) out->rect);
+ (unsigned char *) ibuf1->rect, (unsigned char *) ibuf2->rect, (unsigned char *) out->rect);
}
return out;
}
@@ -2761,8 +2585,8 @@ static void do_overdrop_effect(SeqRenderData context, Sequence *UNUSED(seq), flo
slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
- do_drop_effect_byte(facf0, facf1, x, y, (char *) rect1, (char *) rect2, (char *) rect_out);
- do_alphaover_effect_byte(facf0, facf1, x, y, (char *) rect1, (char *) rect2, (char *) rect_out);
+ do_drop_effect_byte(facf0, facf1, x, y, rect1, rect2, rect_out);
+ do_alphaover_effect_byte(facf0, facf1, x, y, rect1, rect2, rect_out);
}
}
diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c
index 5b2e9f2bf23..3d8a2f7cddf 100644
--- a/source/blender/blenkernel/intern/seqmodifier.c
+++ b/source/blender/blenkernel/intern/seqmodifier.c
@@ -226,24 +226,28 @@ static void curves_apply_threaded(int width, int height, unsigned char *rect, fl
}
if (rect) {
unsigned char *pixel = rect + pixel_index;
- unsigned char result[3];
+ float result[3], tempc[4];
- curvemapping_evaluate_premulRGB(curve_mapping, result, pixel);
+ straight_uchar_to_premul_float(tempc, pixel);
+
+ curvemapping_evaluate_premulRGBF(curve_mapping, result, tempc);
if (mask_rect) {
float t[3];
rgb_uchar_to_float(t, mask_rect + pixel_index);
- pixel[0] = pixel[0] * (1.0f - t[0]) + result[0] * t[0];
- pixel[1] = pixel[1] * (1.0f - t[1]) + result[1] * t[1];
- pixel[2] = pixel[2] * (1.0f - t[2]) + result[2] * t[2];
+ tempc[0] = pixel[0] * (1.0f - t[0]) + result[0] * t[0];
+ tempc[1] = pixel[1] * (1.0f - t[1]) + result[1] * t[1];
+ tempc[2] = pixel[2] * (1.0f - t[2]) + result[2] * t[2];
}
else {
- pixel[0] = result[0];
- pixel[1] = result[1];
- pixel[2] = result[2];
+ tempc[0] = result[0];
+ tempc[1] = result[1];
+ tempc[2] = result[2];
}
+
+ premul_float_to_straight_uchar(pixel, tempc);
}
}
}
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 5e44f2d6d9e..8d010de408a 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -324,7 +324,6 @@ void BKE_sequencer_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, int make_
{
const char *from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
const char *to_colorspace = scene->sequencer_colorspace_settings.name;
- int predivide = ibuf->flags & IB_cm_predivide;
if (!ibuf->rect_float) {
if (make_float && ibuf->rect) {
@@ -354,7 +353,7 @@ void BKE_sequencer_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, int make_
imb_freerectImBuf(ibuf);
IMB_colormanagement_transform_threaded(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
- from_colorspace, to_colorspace, predivide);
+ from_colorspace, to_colorspace, TRUE);
}
}
@@ -367,10 +366,8 @@ void BKE_sequencer_imbuf_from_sequencer_space(Scene *scene, ImBuf *ibuf)
return;
if (to_colorspace && to_colorspace[0] != '\0') {
- int predivide = ibuf->flags & IB_cm_predivide;
-
IMB_colormanagement_transform_threaded(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
- from_colorspace, to_colorspace, predivide);
+ from_colorspace, to_colorspace, TRUE);
}
}
@@ -636,7 +633,7 @@ void BKE_sequence_calc(Scene *scene, Sequence *seq)
}
}
-/* note: caller should run calc_sequence(scene, seq) after */
+/* note: caller should run BKE_sequence_calc(scene, seq) after */
void BKE_sequence_reload_new_file(Scene *scene, Sequence *seq, int lock_range)
{
char str[FILE_MAX];
@@ -1517,18 +1514,6 @@ MINLINE float color_balance_fl(float in, const float lift, const float gain, con
return powf(x, gamma) * mul;
}
-static void make_cb_table_byte(float lift, float gain, float gamma,
- unsigned char *table, float mul)
-{
- int y;
-
- for (y = 0; y < 256; y++) {
- float v = color_balance_fl((float)y * (1.0f / 255.0f), lift, gain, gamma, mul);
-
- table[y] = FTOCHAR(v);
- }
-}
-
static void make_cb_table_float(float lift, float gain, float gamma,
float *table, float mul)
{
@@ -1543,35 +1528,33 @@ static void make_cb_table_float(float lift, float gain, float gamma,
static void color_balance_byte_byte(StripColorBalance *cb_, unsigned char *rect, unsigned char *mask_rect, int width, int height, float mul)
{
- unsigned char cb_tab[3][256];
- int c;
- unsigned char *p = rect;
- unsigned char *e = p + width * 4 * height;
+ //unsigned char cb_tab[3][256];
+ unsigned char *cp = rect;
+ unsigned char *e = cp + width * 4 * height;
unsigned char *m = mask_rect;
StripColorBalance cb = calc_cb(cb_);
- for (c = 0; c < 3; c++) {
- make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul);
- }
+ while (cp < e) {
+ float p[4];
+ int c;
- while (p < e) {
- if (m) {
- float t[3] = {m[0] / 255.0f, m[1] / 255.0f, m[2] / 255.0f};
+ straight_uchar_to_premul_float(p, cp);
- p[0] = p[0] * (1.0f - t[0]) + t[0] * cb_tab[0][p[0]];
- p[1] = p[1] * (1.0f - t[1]) + t[1] * cb_tab[1][p[1]];
- p[2] = p[2] * (1.0f - t[2]) + t[2] * cb_tab[2][p[2]];
+ for (c = 0; c < 3; c++) {
+ float t = color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul);
- m += 4;
- }
- else {
- p[0] = cb_tab[0][p[0]];
- p[1] = cb_tab[1][p[1]];
- p[2] = cb_tab[2][p[2]];
+ if (m)
+ p[c] = p[c] * (1.0f - (float)m[c] / 255.0f) + t * m[c];
+ else
+ p[c] = t;
}
- p += 4;
+ premul_float_to_straight_uchar(cp, p);
+
+ cp += 4;
+ if (m)
+ m += 4;
}
}
@@ -1795,7 +1778,7 @@ int BKE_sequencer_input_have_to_preprocess(SeqRenderData UNUSED(context), Sequen
{
float mul;
- if (seq->flag & (SEQ_FILTERY | SEQ_USE_CROP | SEQ_USE_TRANSFORM | SEQ_FLIPX | SEQ_FLIPY | SEQ_MAKE_PREMUL | SEQ_MAKE_FLOAT)) {
+ if (seq->flag & (SEQ_FILTERY | SEQ_USE_CROP | SEQ_USE_TRANSFORM | SEQ_FLIPX | SEQ_FLIPY | SEQ_MAKE_FLOAT)) {
return TRUE;
}
@@ -1892,7 +1875,8 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
ImBuf *i = IMB_allocImBuf(dx, dy, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
IMB_rectcpy(i, ibuf, t.xofs, t.yofs, c.left, c.bottom, sx, sy);
-
+ sequencer_imbuf_assign_spaces(context.scene, i);
+
IMB_freeImBuf(ibuf);
ibuf = i;
@@ -1931,12 +1915,6 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
multibuf(ibuf, mul);
}
- if (seq->flag & SEQ_MAKE_PREMUL) {
- if (ibuf->planes == 32 && ibuf->zbuf == NULL) {
- IMB_premultiply_alpha(ibuf);
- }
- }
-
if (ibuf->x != context.rectx || ibuf->y != context.recty) {
if (context.scene->r.mode & R_OSA) {
IMB_scaleImBuf(ibuf, (short)context.rectx, (short)context.recty);
@@ -2546,13 +2524,18 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo
case SEQ_TYPE_IMAGE:
{
StripElem *s_elem = BKE_sequencer_give_stripelem(seq, cfra);
+ int flag;
if (s_elem) {
BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name);
BLI_path_abs(name, G.main->name);
}
- if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect, seq->strip->colorspace_settings.name))) {
+ flag = IB_rect;
+ if (seq->alpha_mode == SEQ_ALPHA_PREMUL)
+ flag |= IB_alphamode_premul;
+
+ if (s_elem && (ibuf = IMB_loadiffname(name, flag, seq->strip->colorspace_settings.name))) {
/* we don't need both (speed reasons)! */
if (ibuf->rect_float && ibuf->rect)
imb_freerectImBuf(ibuf);
@@ -2641,7 +2624,7 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo
static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra)
{
ImBuf *ibuf = NULL;
- int use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra);
+ int use_preprocess = FALSE;
int is_proxy_image = FALSE;
float nr = give_stripelem_index(seq, cfra);
/* all effects are handled similarly with the exception of speed effect */
@@ -2650,30 +2633,36 @@ static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra)
ibuf = BKE_sequencer_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF);
- /* currently, we cache preprocessed images in SEQ_STRIPELEM_IBUF,
- * but not(!) on SEQ_STRIPELEM_IBUF_ENDSTILL and ..._STARTSTILL */
- if (ibuf)
- use_preprocess = FALSE;
-
- if (ibuf == NULL)
- ibuf = copy_from_ibuf_still(context, seq, nr);
-
if (ibuf == NULL) {
- ibuf = BKE_sequencer_preprocessed_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF);
+ if (ibuf == NULL)
+ ibuf = copy_from_ibuf_still(context, seq, nr);
if (ibuf == NULL) {
- /* MOVIECLIPs have their own proxy management */
- if (ibuf == NULL && seq->type != SEQ_TYPE_MOVIECLIP) {
- ibuf = seq_proxy_fetch(context, seq, cfra);
- is_proxy_image = (ibuf != NULL);
- }
+ ibuf = BKE_sequencer_preprocessed_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF);
+
+ if (ibuf == NULL) {
+ /* MOVIECLIPs have their own proxy management */
+ if (ibuf == NULL && seq->type != SEQ_TYPE_MOVIECLIP) {
+ ibuf = seq_proxy_fetch(context, seq, cfra);
+ is_proxy_image = (ibuf != NULL);
+ }
- if (ibuf == NULL)
- ibuf = do_render_strip_uncached(context, seq, cfra);
+ if (ibuf == NULL)
+ ibuf = do_render_strip_uncached(context, seq, cfra);
- if (ibuf)
- BKE_sequencer_preprocessed_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf);
+ if (ibuf)
+ BKE_sequencer_preprocessed_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf);
+ }
}
+
+ if (ibuf)
+ use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra);
+ }
+ else {
+ /* currently, we cache preprocessed images in SEQ_STRIPELEM_IBUF,
+ * but not(!) on SEQ_STRIPELEM_IBUF_ENDSTILL and ..._STARTSTILL
+ * so, no need in check for preprocess here
+ */
}
if (ibuf == NULL) {
@@ -3973,10 +3962,18 @@ void BKE_sequence_init_colorspace(Sequence *seq)
/* initialize input color space */
if (seq->type == SEQ_TYPE_IMAGE) {
- ibuf = IMB_loadiffname(name, IB_rect, seq->strip->colorspace_settings.name);
+ ibuf = IMB_loadiffname(name, IB_test | IB_alphamode_detect, seq->strip->colorspace_settings.name);
+
+ /* byte images are default to straight alpha, however sequencer
+ * works in premul space, so mark strip to be premultiplied first
+ */
+ seq->alpha_mode = SEQ_ALPHA_STRAIGHT;
+ if (ibuf) {
+ if (ibuf->flags & IB_alphamode_premul)
+ seq->alpha_mode = IMA_ALPHA_PREMUL;
- if (ibuf)
IMB_freeImBuf(ibuf);
+ }
}
}
}
@@ -4176,7 +4173,7 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
seqn->seqbase.first = seqn->seqbase.last = NULL;
/* WATCH OUT!!! - This metastrip is not recursively duplicated here - do this after!!! */
- /* - seq_dupli_recursive(&seq->seqbase,&seqn->seqbase);*/
+ /* - seq_dupli_recursive(&seq->seqbase, &seqn->seqbase);*/
}
else if (seq->type == SEQ_TYPE_SCENE) {
seqn->strip->stripdata = NULL;
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 629b2c989d3..2563fc268b1 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -2407,7 +2407,7 @@ static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene)
bv[3] = (float)sds->res[1]; // y
bv[5] = (float)sds->res[2]; // z
-// #pragma omp parallel for schedule(static,1)
+// #pragma omp parallel for schedule(static, 1)
for (z = 0; z < sds->res[2]; z++)
{
size_t index = z * slabsize;
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 37c9c1dd84e..b1917c6091d 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -1577,7 +1577,7 @@ static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
CCGFace **faces;
int totface;
- BLI_pbvh_get_grid_updates(ccgdm->pbvh, 1, (void ***)&faces, &totface);
+ BKE_pbvh_get_grid_updates(ccgdm->pbvh, 1, (void ***)&faces, &totface);
if (totface) {
ccgSubSurf_updateFromFaces(ccgdm->ss, 0, faces, totface);
ccgSubSurf_updateNormals(ccgdm->ss, faces, totface);
@@ -1715,7 +1715,8 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
if (ccgdm->pbvh && ccgdm->multires.mmd && !fast) {
if (dm->numTessFaceData) {
- BLI_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL, setMaterial);
+ BKE_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL,
+ setMaterial, FALSE);
glShadeModel(GL_FLAT);
}
@@ -3033,7 +3034,7 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
* when the ccgdm gets remade, the assumption is that the topology
* does not change. */
ccgdm_create_grids(dm);
- BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void **)ccgdm->gridFaces,
+ BKE_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void **)ccgdm->gridFaces,
ccgdm->gridFlagMats, ccgdm->gridHidden);
}
@@ -3051,15 +3052,15 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
numGrids = ccgDM_getNumGrids(dm);
- ob->sculpt->pbvh = ccgdm->pbvh = BLI_pbvh_new();
- BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
+ ob->sculpt->pbvh = ccgdm->pbvh = BKE_pbvh_new();
+ BKE_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
numGrids, &key, (void **) ccgdm->gridFaces, ccgdm->gridFlagMats, ccgdm->gridHidden);
}
else if (ob->type == OB_MESH) {
Mesh *me = ob->data;
- ob->sculpt->pbvh = ccgdm->pbvh = BLI_pbvh_new();
+ ob->sculpt->pbvh = ccgdm->pbvh = BKE_pbvh_new();
BLI_assert(!(me->mface == NULL && me->mpoly != NULL)); /* BMESH ONLY complain if mpoly is valid but not mface */
- BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
+ BKE_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
me->totface, me->totvert, &me->vdata);
}
diff --git a/source/blender/blenkernel/intern/suggestions.c b/source/blender/blenkernel/intern/suggestions.c
index ff9774f85af..6f9736df683 100644
--- a/source/blender/blenkernel/intern/suggestions.c
+++ b/source/blender/blenkernel/intern/suggestions.c
@@ -163,13 +163,13 @@ void texttool_suggest_add(const char *name, char type)
suggestions.top = 0;
}
-void texttool_suggest_prefix(const char *prefix)
+void texttool_suggest_prefix(const char *prefix, const int prefix_len)
{
SuggItem *match, *first, *last;
- int cmp, len = strlen(prefix), top = 0;
+ int cmp, top = 0;
if (!suggestions.first) return;
- if (len == 0) {
+ if (prefix_len == 0) {
suggestions.selected = suggestions.firstmatch = suggestions.first;
suggestions.lastmatch = suggestions.last;
return;
@@ -177,7 +177,7 @@ void texttool_suggest_prefix(const char *prefix)
first = last = NULL;
for (match = suggestions.first; match; match = match->next) {
- cmp = txttl_cmp(prefix, match->name, len);
+ cmp = txttl_cmp(prefix, match->name, prefix_len);
if (cmp == 0) {
if (!first) {
first = match;
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 322b77e0462..c337e339ebf 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -2936,3 +2936,18 @@ int text_check_whitespace(const char ch)
return 1;
return 0;
}
+
+int text_find_identifier_start(const char *str, int i)
+{
+ if (UNLIKELY(i <= 0)) {
+ return 0;
+ }
+
+ while (i--) {
+ if (!text_check_identifier(str[i])) {
+ break;
+ }
+ }
+ i++;
+ return i;
+}
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 149842bc038..fbaf6f70fbc 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -440,7 +440,7 @@ void default_tex(Tex *tex)
tex->type = TEX_CLOUDS;
tex->stype = 0;
tex->flag = TEX_CHECKER_ODD;
- tex->imaflag = TEX_INTERPOL | TEX_MIPMAP | TEX_USEALPHA;
+ tex->imaflag = TEX_INTERPOL | TEX_MIPMAP;
tex->extend = TEX_REPEAT;
tex->cropxmin = tex->cropymin = 0.0;
tex->cropxmax = tex->cropymax = 1.0;