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:
authorJoseph Eagar <joeedh@gmail.com>2009-05-23 07:24:15 +0400
committerJoseph Eagar <joeedh@gmail.com>2009-05-23 07:24:15 +0400
commitf026266e185f90543138a856898f50b2295a12fc (patch)
treef674a1a1b328a423ec4bdcdc4a11f35e56669e7a /source/blender/blenkernel
parentb7fe3258b66698f62f630d0b18431b54b65101ed (diff)
merge with 2.5 at r20307. note there were some python hacking necassary for this to work, so um hopefully there's not too much cruft from that.
[[Split portion of a mixed commit.]]
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h2
-rw-r--r--source/blender/blenkernel/BKE_action.h5
-rw-r--r--source/blender/blenkernel/BKE_animsys.h22
-rw-r--r--source/blender/blenkernel/BKE_blender.h3
-rw-r--r--source/blender/blenkernel/BKE_bmesh.h2
-rw-r--r--source/blender/blenkernel/BKE_bmeshCustomData.h2
-rw-r--r--source/blender/blenkernel/BKE_booleanops.h5
-rw-r--r--source/blender/blenkernel/BKE_bvhutils.h45
-rw-r--r--source/blender/blenkernel/BKE_cloth.h2
-rw-r--r--source/blender/blenkernel/BKE_collision.h2
-rw-r--r--source/blender/blenkernel/BKE_colortools.h1
-rw-r--r--source/blender/blenkernel/BKE_constraint.h4
-rw-r--r--source/blender/blenkernel/BKE_curve.h6
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h13
-rw-r--r--source/blender/blenkernel/BKE_global.h4
-rw-r--r--source/blender/blenkernel/BKE_gpencil.h63
-rw-r--r--source/blender/blenkernel/BKE_library.h1
-rw-r--r--source/blender/blenkernel/BKE_main.h1
-rw-r--r--source/blender/blenkernel/BKE_mesh.h4
-rw-r--r--source/blender/blenkernel/BKE_particle.h19
-rw-r--r--source/blender/blenkernel/BKE_scene.h3
-rw-r--r--source/blender/blenkernel/BKE_screen.h58
-rw-r--r--source/blender/blenkernel/BKE_shrinkwrap.h19
-rw-r--r--source/blender/blenkernel/BKE_suggestions.h2
-rw-r--r--source/blender/blenkernel/CMakeLists.txt6
-rw-r--r--source/blender/blenkernel/SConscript37
-rw-r--r--source/blender/blenkernel/intern/BME_Customdata.c2
-rw-r--r--source/blender/blenkernel/intern/BME_conversions.c2
-rw-r--r--source/blender/blenkernel/intern/BME_eulers.c2
-rw-r--r--source/blender/blenkernel/intern/BME_mesh.c2
-rw-r--r--source/blender/blenkernel/intern/BME_structure.c2
-rw-r--r--source/blender/blenkernel/intern/BME_tools.c2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c231
-rw-r--r--source/blender/blenkernel/intern/Makefile10
-rw-r--r--source/blender/blenkernel/intern/action.c115
-rw-r--r--source/blender/blenkernel/intern/anim.c112
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c65
-rw-r--r--source/blender/blenkernel/intern/blender.c13
-rw-r--r--source/blender/blenkernel/intern/bmesh_private.h2
-rw-r--r--source/blender/blenkernel/intern/booleanops.c122
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c196
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c13
-rw-r--r--source/blender/blenkernel/intern/colortools.c36
-rw-r--r--source/blender/blenkernel/intern/constraint.c235
-rw-r--r--source/blender/blenkernel/intern/context.c1
-rw-r--r--source/blender/blenkernel/intern/curve.c18
-rw-r--r--source/blender/blenkernel/intern/customdata.c8
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c94
-rw-r--r--source/blender/blenkernel/intern/effect.c29
-rw-r--r--source/blender/blenkernel/intern/exotic.c4
-rw-r--r--source/blender/blenkernel/intern/fcurve.c438
-rw-r--r--source/blender/blenkernel/intern/font.c20
-rw-r--r--source/blender/blenkernel/intern/gpencil.c516
-rw-r--r--source/blender/blenkernel/intern/image.c8
-rw-r--r--source/blender/blenkernel/intern/ipo.c53
-rw-r--r--source/blender/blenkernel/intern/library.c37
-rw-r--r--source/blender/blenkernel/intern/mesh.c15
-rw-r--r--source/blender/blenkernel/intern/modifier.c123
-rw-r--r--source/blender/blenkernel/intern/node.c39
-rw-r--r--source/blender/blenkernel/intern/object.c6
-rw-r--r--source/blender/blenkernel/intern/particle.c142
-rw-r--r--source/blender/blenkernel/intern/particle_system.c49
-rw-r--r--source/blender/blenkernel/intern/scene.c16
-rw-r--r--source/blender/blenkernel/intern/screen.c17
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c300
-rw-r--r--source/blender/blenkernel/intern/suggestions.c2
-rw-r--r--source/blender/blenkernel/intern/text.c48
-rw-r--r--source/blender/blenkernel/intern/world.c2
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c36
69 files changed, 2615 insertions, 899 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 8df30b1eaf5..42904014ea8 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -44,6 +44,7 @@
#include "DNA_customdata_types.h"
#include "BKE_customdata.h"
+#include "BKE_bvhutils.h"
struct MVert;
struct MEdge;
@@ -71,6 +72,7 @@ struct DerivedMesh {
int numVertData, numEdgeData, numFaceData;
int needsFree; /* checked on ->release, is set to 0 for cached results */
int deformedOnly; /* set by modifier stack if only deformed from original */
+ BVHCache bvhCache;
/* Misc. Queries */
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index a5a978ae3fa..67eb2ed58bf 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -64,9 +64,8 @@ void free_action(struct bAction *act);
// XXX is this needed?
void make_local_action(struct bAction *act);
-
+
/* Some kind of bounding box operation on the action */
-// XXX depreceated..
void calc_action_range(const struct bAction *act, float *start, float *end, int incl_hidden);
/* Action Groups API ----------------- */
@@ -135,7 +134,7 @@ void update_pose_constraint_flags(struct bPose *pose);
void framechange_poses_clear_unkeyed(void);
/* Used for the Action Constraint */
-void what_does_obaction(struct Scene *scene, struct Object *ob, struct Object *workob, struct bPose *pose, struct bAction *act, float cframe);
+void what_does_obaction(struct Scene *scene, struct Object *ob, struct Object *workob, struct bPose *pose, struct bAction *act, char groupname[], float cframe);
/* exported for game engine */
void blend_poses(struct bPose *dst, struct bPose *src, float srcweight, short mode);
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 44c8d827e8c..b45917e6ca1 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -12,6 +12,11 @@ struct AnimData;
struct KeyingSet;
struct KS_Path;
+struct PointerRNA;
+struct bAction;
+struct bActionGroup;
+struct AnimMapper;
+
/* ************************************* */
/* AnimData API */
@@ -50,6 +55,9 @@ void BKE_keyingsets_free(struct ListBase *list);
/* ************************************* */
/* Evaluation API */
+/* ------------- Main API -------------------- */
+/* In general, these ones should be called to do all animation evaluation */
+
/* Evaluation loop for evaluating animation data */
void BKE_animsys_evaluate_animdata(struct ID *id, struct AnimData *adt, float ctime, short recalc);
@@ -57,6 +65,20 @@ void BKE_animsys_evaluate_animdata(struct ID *id, struct AnimData *adt, float ct
void BKE_animsys_evaluate_all_animation(struct Main *main, float ctime);
+/* ------------ Specialised API --------------- */
+/* There are a few special tools which require these following functions. They are NOT to be used
+ * for standard animation evaluation UNDER ANY CIRCUMSTANCES!
+ *
+ * i.e. Pose Library (PoseLib) uses some of these for selectively applying poses, but
+ * Particles/Sequencer performing funky time manipulation is not ok.
+ */
+
+/* Evaluate Action (F-Curve Bag) */
+void animsys_evaluate_action(struct PointerRNA *ptr, struct bAction *act, struct AnimMapper *remap, float ctime);
+
+/* Evaluate Action Group */
+void animsys_evaluate_action_group(struct PointerRNA *ptr, struct bAction *act, struct bActionGroup *agrp, struct AnimMapper *remap, float ctime);
+
/* ************************************* */
#endif /* BKE_ANIM_SYS_H*/
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 5a374802d36..795c7585b9c 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -55,6 +55,9 @@ int BKE_read_file_from_memfile(struct bContext *C, struct MemFile *memfile, stru
void free_blender(void);
void initglobals(void);
+/* load new userdef from file, exit blender */
+void BKE_userdef_free(void);
+
/* set this callback when a UI is running */
void set_blender_test_break_cb(void (*func)(void) );
int blender_test_break(void);
diff --git a/source/blender/blenkernel/BKE_bmesh.h b/source/blender/blenkernel/BKE_bmesh.h
index b3ce5447e68..957cd8ef9bd 100644
--- a/source/blender/blenkernel/BKE_bmesh.h
+++ b/source/blender/blenkernel/BKE_bmesh.h
@@ -3,7 +3,7 @@
*
* BMesh modeler structure and functions.
*
- * $Id: BKE_bmesh.h,v 1.00 2007/01/17 17:42:01 Briggs Exp $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
diff --git a/source/blender/blenkernel/BKE_bmeshCustomData.h b/source/blender/blenkernel/BKE_bmeshCustomData.h
index 4f5f2641f54..e910fc13ed4 100644
--- a/source/blender/blenkernel/BKE_bmeshCustomData.h
+++ b/source/blender/blenkernel/BKE_bmeshCustomData.h
@@ -3,7 +3,7 @@
*
* BMesh modeler structure and functions.
*
- * $Id: BKE_bmesh.h,v 1.00 2007/01/17 17:42:01 Briggs Exp $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
diff --git a/source/blender/blenkernel/BKE_booleanops.h b/source/blender/blenkernel/BKE_booleanops.h
index b51ee2646fc..a32f21af859 100644
--- a/source/blender/blenkernel/BKE_booleanops.h
+++ b/source/blender/blenkernel/BKE_booleanops.h
@@ -43,8 +43,7 @@ int NewBooleanMesh(struct Scene *scene, struct Base *base, struct Base *base_sel
/* Performs a boolean between two mesh objects, it is assumed that both objects
are in fact mesh object. On success returns a DerivedMesh. On failure
returns NULL and reports an error. */
-struct DerivedMesh *NewBooleanDerivedMesh(struct Object *ob,
- struct Object *ob_select,
- int op);
+struct DerivedMesh *NewBooleanDerivedMesh(struct DerivedMesh *dm, struct Object *ob, struct DerivedMesh *dm_select, struct Object *ob_select,
+ int int_op_type);
#endif
diff --git a/source/blender/blenkernel/BKE_bvhutils.h b/source/blender/blenkernel/BKE_bvhutils.h
index dd9ea61f24b..66c8d99959a 100644
--- a/source/blender/blenkernel/BKE_bvhutils.h
+++ b/source/blender/blenkernel/BKE_bvhutils.h
@@ -31,6 +31,7 @@
#define BKE_BVHUTILS_H
#include "BLI_kdopbvh.h"
+#include "BLI_linklist.h"
/*
* This header encapsulates necessary code to buld a BVH
@@ -52,7 +53,7 @@ typedef struct BVHTreeFromMesh
BVHTree_RayCastCallback raycast_callback;
/* Mesh represented on this BVHTree */
- struct DerivedMesh *mesh;
+ struct DerivedMesh *mesh;
/* Vertex array, so that callbacks have instante access to data */
struct MVert *vert;
@@ -61,6 +62,9 @@ typedef struct BVHTreeFromMesh
/* radius for raycast */
float sphere_radius;
+ /* Private data */
+ int cached;
+
} BVHTreeFromMesh;
/*
@@ -74,7 +78,7 @@ typedef struct BVHTreeFromMesh
*
* free_bvhtree_from_mesh should be called when the tree is no longer needed.
*/
-void bvhtree_from_mesh_verts(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis);
+BVHTree* bvhtree_from_mesh_verts(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis);
/*
* Builds a bvh tree where nodes are the faces of the given mesh.
@@ -84,15 +88,50 @@ void bvhtree_from_mesh_verts(struct BVHTreeFromMesh *data, struct DerivedMesh *m
* so that the coordinates and rays are first translated on the mesh local coordinates.
* Reason for this is that later bvh_from_mesh_* might use a cache system and so it becames possible to reuse
* a BVHTree.
+ *
+ * The returned value is the same as in data->tree, its only returned to make it easier to test
+ * the success
*
* free_bvhtree_from_mesh should be called when the tree is no longer needed.
*/
-void bvhtree_from_mesh_faces(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis);
+BVHTree* bvhtree_from_mesh_faces(struct BVHTreeFromMesh *data, struct DerivedMesh *mesh, float epsilon, int tree_type, int axis);
/*
* Frees data allocated by a call to bvhtree_from_mesh_*.
*/
void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data);
+
+/*
+ * BVHCache
+ */
+
+//Using local coordinates
+#define BVHTREE_FROM_FACES 0
+#define BVHTREE_FROM_VERTICES 1
+
+typedef LinkNode* BVHCache;
+
+
+/*
+ * Queries a bvhcache for the chache bvhtree of the request type
+ */
+BVHTree *bvhcache_find(BVHCache *cache, int type);
+
+/*
+ * Inserts a BVHTree of the given type under the cache
+ * After that the caller no longer needs to worry when to free the BVHTree
+ * as that will be done when the cache is freed.
+ *
+ * A call to this assumes that there was no previous cached tree of the given type
+ */
+void bvhcache_insert(BVHCache *cache, BVHTree *tree, int type);
+
+/*
+ * inits and frees a bvhcache
+ */
+void bvhcache_init(BVHCache *cache);
+void bvhcache_free(BVHCache *cache);
+
#endif
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index 791cf40f8a0..e09be838f06 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -1,7 +1,7 @@
/**
* BKE_cloth.h
*
- * $Id: BKE_cloth.h,v 1.1 2007/08/01 02:07:27 daniel Exp $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h
index 2518c1d6939..e4eed084a3d 100644
--- a/source/blender/blenkernel/BKE_collision.h
+++ b/source/blender/blenkernel/BKE_collision.h
@@ -1,7 +1,7 @@
/**
* BKE_cloth.h
*
- * $Id: BKE_cloth.h,v 1.1 2007/08/01 02:07:27 daniel Exp $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h
index 555b467b1d6..6f6c4a834df 100644
--- a/source/blender/blenkernel/BKE_colortools.h
+++ b/source/blender/blenkernel/BKE_colortools.h
@@ -58,6 +58,7 @@ void curvemapping_premultiply(struct CurveMapping *cumap, int restore);
int curvemapping_RGBA_does_something(struct CurveMapping *cumap);
void curvemapping_initialize(struct CurveMapping *cumap);
void curvemapping_table_RGBA(struct CurveMapping *cumap, float **array, int *size);
+void colorcorrection_do_ibuf(struct ImBuf *ibuf, const char *profile);
#endif
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index 0d8c81a5a75..6e69906b71d 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -110,11 +110,13 @@ bConstraintTypeInfo *get_constraint_typeinfo(int type);
/* Constraint function prototypes */
void unique_constraint_name(struct bConstraint *con, struct ListBase *list);
-void free_constraints(struct ListBase *conlist);
+void free_constraints(struct ListBase *list);
void copy_constraints(struct ListBase *dst, struct ListBase *src);
void relink_constraints(struct ListBase *list);
void free_constraint_data(struct bConstraint *con);
+struct bConstraint *constraints_get_active(struct ListBase *list);
+
/* Constraints + Proxies function prototypes */
void extract_proxylocal_constraints(struct ListBase *dst, struct ListBase *src);
short proxylocked_constraints_owner(struct Object *ob, struct bPoseChannel *pchan);
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index b17f4a76198..e5a8df1a932 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -47,6 +47,10 @@ struct BevList;
#define SEGMENTSU(nu) ( ((nu)->flagu & CU_CYCLIC) ? (nu)->pntsu : (nu)->pntsu-1 )
#define SEGMENTSV(nu) ( ((nu)->flagv & CU_CYCLIC) ? (nu)->pntsv : (nu)->pntsv-1 )
+#define CU_DO_TILT(cu, nu) (((nu->type & CU_2D) && (cu->flag & CU_3D)==0) ? 0 : 1)
+#define CU_DO_RADIUS(cu, nu) ((CU_DO_TILT(cu, nu) || cu->bevobj || cu->ext1!=0.0 || cu->ext2!=0.0) ? 1:0)
+
+
void unlink_curve( struct Curve *cu);
void free_curve( struct Curve *cu);
void BKE_free_editfont(struct Curve *cu);
@@ -65,7 +69,7 @@ void duplicateNurblist( struct ListBase *lb1, struct ListBase *lb2);
void test2DNurb( struct Nurb *nu);
void minmaxNurb( struct Nurb *nu, float *min, float *max);
-void makeknots( struct Nurb *nu, short uv, short type);
+void makeknots( struct Nurb *nu, short uv);
void makeNurbfaces(struct Nurb *nu, float *coord_array, int rowstride);
void makeNurbcurve(struct Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, int resolu);
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index 9503c569e8b..9b8a2990fe5 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -6,9 +6,12 @@
#define BKE_FCURVE_H
//struct ListBase;
+
struct FCurve;
struct FModifier;
struct ChannelDriver;
+struct DriverTarget;
+
struct BezTriple;
/* ************** Keyframe Tools ***************** */
@@ -27,6 +30,11 @@ void bezt_add_to_cfra_elem(ListBase *lb, struct BezTriple *bezt);
void fcurve_free_driver(struct FCurve *fcu);
struct ChannelDriver *fcurve_copy_driver(struct ChannelDriver *driver);
+void driver_free_target(struct ChannelDriver *driver, struct DriverTarget *dtar);
+struct DriverTarget *driver_add_new_target(struct ChannelDriver *driver);
+
+float driver_get_target_value(struct ChannelDriver *driver, struct DriverTarget *dtar);
+
/* ************** F-Curve Modifiers *************** */
/* F-Curve Modifier Type-Info (fmi):
@@ -60,6 +68,8 @@ typedef struct FModifierTypeInfo {
void (*verify_data)(struct FModifier *fcm);
/* evaluation */
+ /* evaluate time that the modifier requires the F-Curve to be evaluated at */
+ float (*evaluate_modifier_time)(struct FCurve *fcu, struct FModifier *fcm, float cvalue, float evaltime);
/* evaluate the modifier for the given time and 'accumulated' value */
void (*evaluate_modifier)(struct FCurve *fcu, struct FModifier *fcm, float *cvalue, float evaltime);
} FModifierTypeInfo;
@@ -116,6 +126,9 @@ void copy_fcurves(ListBase *dst, ListBase *src);
/* find matching F-Curve in the given list of F-Curves */
struct FCurve *list_find_fcurve(ListBase *list, const char rna_path[], const int array_index);
+/* test if there is a keyframe at cfra */
+short on_keyframe_fcurve(struct FCurve *fcu, float cfra);
+
/* get the time extents for F-Curve */
void calc_fcurve_range(struct FCurve *fcu, float *min, float *max);
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index ac161caeb2e..4b7ddf43647 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -45,7 +45,6 @@ extern "C" {
struct Main;
struct Object;
struct bSoundListener;
-struct BMF_Font;
struct BME_Glob;
typedef struct Global {
@@ -53,9 +52,6 @@ typedef struct Global {
/* active pointers */
struct Main *main;
- /* fonts, allocated global data */
- struct BMF_Font *font, *fonts, *fontss;
-
/* strings: lastsaved */
char ima[256], sce[256], lib[256];
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
new file mode 100644
index 00000000000..581285be21c
--- /dev/null
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -0,0 +1,63 @@
+/**
+ * $Id: BDR_gpencil.h 19541 2009-04-05 06:54:47Z aligorith $
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2008, Blender Foundation
+ * This is a new part of Blender
+ *
+ * Contributor(s): Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BKE_GPENCIL_H
+#define BKE_GPENCIL_H
+
+struct ListBase;
+struct bGPdata;
+struct bGPDlayer;
+struct bGPDframe;
+
+/* ------------ Grease-Pencil API ------------------ */
+
+void free_gpencil_strokes(struct bGPDframe *gpf);
+void free_gpencil_frames(struct bGPDlayer *gpl);
+void free_gpencil_layers(struct ListBase *list);
+void free_gpencil_data(struct bGPdata *gpd);
+
+struct bGPDframe *gpencil_frame_addnew(struct bGPDlayer *gpl, int cframe);
+struct bGPDlayer *gpencil_layer_addnew(struct bGPdata *gpd);
+struct bGPdata *gpencil_data_addnew(char name[]);
+
+struct bGPDframe *gpencil_frame_duplicate(struct bGPDframe *src);
+struct bGPDlayer *gpencil_layer_duplicate(struct bGPDlayer *src);
+struct bGPdata *gpencil_data_duplicate(struct bGPdata *gpd);
+
+//struct bGPdata *gpencil_data_getactive(struct ScrArea *sa);
+//short gpencil_data_setactive(struct ScrArea *sa, struct bGPdata *gpd);
+//struct ScrArea *gpencil_data_findowner(struct bGPdata *gpd);
+
+void gpencil_frame_delete_laststroke(struct bGPDlayer *gpl, struct bGPDframe *gpf);
+
+struct bGPDframe *gpencil_layer_getframe(struct bGPDlayer *gpl, int cframe, short addnew);
+void gpencil_layer_delframe(struct bGPDlayer *gpl, struct bGPDframe *gpf);
+struct bGPDlayer *gpencil_layer_getactive(struct bGPdata *gpd);
+void gpencil_layer_setactive(struct bGPdata *gpd, struct bGPDlayer *active);
+void gpencil_layer_delactive(struct bGPdata *gpd);
+
+#endif /* BKE_GPENCIL_H */
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 212e9f08c35..e598394cc60 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -61,6 +61,7 @@ void free_main(struct Main *mainvar);
void splitIDname(char *name, char *left, int *nr);
void rename_id(struct ID *id, char *name);
void test_idbutton(char *name);
+void text_idbutton(struct ID *id, char *text);
void all_local(struct Library *lib, int untagged_only);
struct ID *find_id(char *type, char *name);
void clear_id_newpoins(void);
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index 30cf800a3d8..6881bdfdb2c 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -77,6 +77,7 @@ typedef struct Main {
ListBase brush;
ListBase particle;
ListBase wm;
+ ListBase gpencil;
} Main;
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index b2f533649e3..e168e616944 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -36,6 +36,7 @@
struct BoundBox;
struct DispList;
struct ListBase;
+struct EditMesh;
struct MDeformVert;
struct Mesh;
struct MFace;
@@ -51,6 +52,9 @@ struct CustomData;
extern "C" {
#endif
+struct EditMesh *BKE_mesh_get_editmesh(struct Mesh *me);
+void BKE_mesh_end_editmesh(struct Mesh *me, struct EditMesh *em);
+
void unlink_mesh(struct Mesh *me);
void free_mesh(struct Mesh *me);
struct Mesh *add_mesh(char *name);
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 8bf6d91e325..db4d948216e 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -1,7 +1,7 @@
/* BKE_particle.h
*
*
- * $Id: BKE_particle.h $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -180,7 +180,7 @@ typedef struct ParticleThreadContext {
/* path caching */
int editupdate, between, steps;
- int totchild, totparent;
+ int totchild, totparent, parent_pass;
float cfra;
@@ -195,6 +195,19 @@ typedef struct ParticleThread {
int num, tot;
} ParticleThread;
+typedef struct ParticleBillboardData
+{
+ struct Object *ob;
+ float vec[3], vel[3];
+ float offset[2];
+ float size, tilt, random, time;
+ int uv[3];
+ int lock, num;
+ int totnum;
+ short align, uv_split, anim, split_offset;
+}
+ParticleBillboardData;
+
/* ----------- functions needed outside particlesystem ---------------- */
/* particle.c */
int count_particles(struct ParticleSystem *psys);
@@ -268,6 +281,8 @@ void psys_threads_free(ParticleThread *threads);
void psys_thread_distribute_particle(ParticleThread *thread, struct ParticleData *pa, struct ChildParticle *cpa, int p);
void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, ParticleCacheKey *keys, int i);
+void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3], float zvec[3], float center[3]);
+
/* particle_system.c */
int psys_count_keyed_targets(struct Object *ob, struct ParticleSystem *psys);
void psys_get_reactor_target(struct Object *ob, struct ParticleSystem *psys, struct Object **target_ob, struct ParticleSystem **target_psys);
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 734687adafb..70eba5006d6 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -38,6 +38,7 @@ struct Base;
struct AviCodecData;
struct QuicktimeCodecData;
struct RenderData;
+struct Text;
/* note; doesn't work when scene is empty */
#define SETLOOPER(s, b) sce= s, b= (Base*)sce->base.first; b; b= (Base*)(b->next?b->next:sce->set?(sce=sce->set)->base.first:NULL)
@@ -73,5 +74,7 @@ int get_render_child_particle_number(struct RenderData *r, int num);
int get_render_shadow_samples(struct RenderData *r, int samples);
float get_render_aosss_error(struct RenderData *r, float error);
+void free_dome_warp_text(struct Text *txt);
+
#endif
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index a25a7cff51d..9b5d99f6ae6 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -37,6 +37,8 @@ struct bContextDataResult;
struct bScreen;
struct ListBase;
struct Panel;
+struct Header;
+struct Menu;
struct ScrArea;
struct SpaceType;
struct wmNotifier;
@@ -44,6 +46,10 @@ struct wmWindow;
struct wmWindowManager;
struct uiLayout;
struct uiMenuItem;
+struct StructRNA;
+struct PointerRNA;
+struct FunctionRNA;
+struct ParameterList;
/* spacetype has everything stored to get an editor working, it gets initialized via
ED_spacetypes_init() in editors/area/spacetypes.c */
@@ -131,6 +137,9 @@ typedef struct ARegionType {
/* header type definitions */
ListBase headertypes;
+ /* menu type definitions */
+ ListBase menutypes;
+
/* hardcoded constraints, smaller than these values region is not visible */
int minsizex, minsizey;
/* default keymaps to add */
@@ -142,17 +151,24 @@ typedef struct ARegionType {
typedef struct PanelType {
struct PanelType *next, *prev;
- char *idname; /* unique name */
- char *name; /* for panel header */
- char *context; /* for buttons window */
+ char idname[BKE_ST_MAXNAME]; /* unique name */
+ char label[BKE_ST_MAXNAME]; /* for panel header */
+ char context[BKE_ST_MAXNAME]; /* for buttons window */
+ int space_type;
+ int region_type;
/* verify if the panel should draw or not */
- int (*poll)(const struct bContext *);
+ int (*poll)(const struct bContext *, struct PanelType *);
+ /* draw header (optional) */
+ void (*draw_header)(const struct bContext *, struct Panel *);
/* draw entirely, view changes should be handled here */
void (*draw)(const struct bContext *, struct Panel *);
/* python integration */
- void *py_data;
+ void *py_data;
+ struct StructRNA *py_srna;
+ int (*py_call)(struct PointerRNA *, struct FunctionRNA *, struct ParameterList *);
+ void (*py_free)(void *py_data);
} PanelType;
/* header types */
@@ -160,16 +176,40 @@ typedef struct PanelType {
typedef struct HeaderType {
struct HeaderType *next, *prev;
- char *idname; /* unique name */
- char *name; /* for UI */
+ char idname[BKE_ST_MAXNAME]; /* unique name */
+ int space_type;
/* draw entirely, view changes should be handled here */
- void (*draw)(const struct bContext *, struct uiLayout *);
+ void (*draw)(const struct bContext *, struct Header *);
/* python integration */
- void *py_data;
+ void *py_data;
+ struct StructRNA *py_srna;
+ int (*py_call)(struct PointerRNA *, struct FunctionRNA *, struct ParameterList *);
+ void (*py_free)(void *py_data);
} HeaderType;
+/* menu types */
+
+typedef struct MenuType {
+ struct MenuType *next, *prev;
+
+ char idname[BKE_ST_MAXNAME]; /* unique name */
+ char label[BKE_ST_MAXNAME]; /* for button text */
+ int space_type;
+
+ /* verify if the menu should draw or not */
+ int (*poll)(const struct bContext *, struct MenuType *);
+ /* draw entirely, view changes should be handled here */
+ void (*draw)(const struct bContext *, struct Menu *);
+
+ /* python integration */
+ void *py_data;
+ struct StructRNA *py_srna;
+ int (*py_call)(struct PointerRNA *, struct FunctionRNA *, struct ParameterList *);
+ void (*py_free)(void *py_data);
+} MenuType;
+
/* spacetypes */
struct SpaceType *BKE_spacetype_from_id(int spaceid);
struct ARegionType *BKE_regiontype_from_id(struct SpaceType *st, int regionid);
diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h
index 103b78f0d6e..eb0e3c4ef00 100644
--- a/source/blender/blenkernel/BKE_shrinkwrap.h
+++ b/source/blender/blenkernel/BKE_shrinkwrap.h
@@ -35,6 +35,8 @@
#include "BKE_customdata.h"
struct DerivedMesh;
struct Object;
+struct DerivedMesh *object_get_derived_final(struct Scene *scene, struct Object *ob, CustomDataMask dataMask);
+
/* SpaceTransform stuff */
/*
@@ -59,7 +61,7 @@ struct Object;
* space_transform_invert_normal(&data, &no);
*
*/
-
+struct Object;
typedef struct SpaceTransform
{
@@ -92,6 +94,8 @@ void space_transform_invert(const struct SpaceTransform *data, float *co);
struct Object;
struct Scene;
struct DerivedMesh;
+struct MVert;
+struct MDeformVert;
struct ShrinkwrapModifierData;
struct MDeformVert;
struct BVHTree;
@@ -102,8 +106,8 @@ typedef struct ShrinkwrapCalcData
ShrinkwrapModifierData *smd; //shrinkwrap modifier data
struct Object *ob; //object we are applying shrinkwrap to
- struct DerivedMesh *original; //mesh before shrinkwrap
+ MVert *vert; //Array of verts being projected (to fetch normals or other data)
float (*vertexCos)[3]; //vertexs being shrinkwraped
int numVerts;
@@ -120,6 +124,17 @@ typedef struct ShrinkwrapCalcData
void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Scene *scene, 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:
+ *
+ * if transf was configured with "space_transform_setup( &transf, ob1, ob2 )"
+ * 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)
+ */
+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);
+
+/*
* NULL initializers to local data
*/
#define NULL_ShrinkwrapCalcData {NULL, }
diff --git a/source/blender/blenkernel/BKE_suggestions.h b/source/blender/blenkernel/BKE_suggestions.h
index d58b8f58bf5..473e3f547f2 100644
--- a/source/blender/blenkernel/BKE_suggestions.h
+++ b/source/blender/blenkernel/BKE_suggestions.h
@@ -1,5 +1,5 @@
/**
- * $Id: $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 5a612df2589..ebe0ea74c28 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -31,7 +31,7 @@ SET(INC
../render/extern/include ../../../intern/decimation/extern
../imbuf ../avi ../../../intern/elbeem/extern ../../../intern/opennl/extern
../../../intern/iksolver/extern ../blenloader ../quicktime
- ../../../intern/bmfont ../../../extern/bullet2/src
+ ../../../extern/bullet2/src
../nodes ../../../extern/glew/include ../gpu ../makesrna
../../../intern/bsp/extern
${SDL_INC}
@@ -66,10 +66,6 @@ ELSE(WITH_PYTHON)
ADD_DEFINITIONS(-DDISABLE_PYTHON)
ENDIF(WITH_PYTHON)
-IF(WITH_INTERNATIONAL)
- ADD_DEFINITIONS(-DWITH_FREETYPE2)
-ENDIF(WITH_INTERNATIONAL)
-
IF(NOT WITH_ELBEEM)
ADD_DEFINITIONS(-DDISABLE_ELBEEM)
ENDIF(NOT WITH_ELBEEM)
diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript
index 3754abb38ec..ae522b029cb 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -8,7 +8,6 @@ incs += ' ../render/extern/include #/intern/decimation/extern ../makesrna'
incs += ' ../imbuf ../avi #/intern/elbeem/extern ../nodes'
incs += ' #/intern/iksolver/extern ../blenloader'
incs += ' #/extern/bullet2/src'
-incs += ' #/intern/bmfont'
incs += ' #/intern/opennl/extern #/intern/bsp/extern'
incs += ' ../gpu #/extern/glew/include'
incs += ' ../bmesh'
@@ -16,49 +15,51 @@ incs += ' ../bmesh'
incs += ' ' + env['BF_OPENGL_INC']
incs += ' ' + env['BF_ZLIB_INC']
-defs = ''
+defs = []
if not env['WITH_BF_PYTHON']:
- defs += 'DISABLE_PYTHON'
+ defs.append('DISABLE_PYTHON')
else:
incs += ' ../python'
incs += ' ' + env['BF_PYTHON_INC']
+ if env['BF_DEBUG']:
+ defs.append('_DEBUG')
if env['WITH_BF_QUICKTIME']:
- incs += ' ../quicktime'
+ incs += ' ../quicktime'
if env['WITH_BF_SDL']:
incs += ' ' + env['BF_SDL_INC']
else:
- defs += ' DISABLE_SDL'
+ defs.append('DISABLE_SDL')
-if env['WITH_BF_INTERNATIONAL']:
- defs += ' WITH_FREETYPE2'
-
if env['WITH_BF_OPENEXR']:
- defs += ' WITH_OPENEXR'
+ defs.append('WITH_OPENEXR')
if env['WITH_BF_OPENJPEG']:
- defs += ' WITH_OPENJPEG'
+ defs.append('WITH_OPENJPEG')
if env['WITH_BF_DDS']:
- defs += ' WITH_DDS'
+ defs.append('WITH_DDS')
if env['WITH_BF_FFMPEG']:
- defs += ' WITH_FFMPEG'
- incs += ' ' + env['BF_FFMPEG_INC']
+ defs.append('WITH_FFMPEG')
+ incs += ' ' + env['BF_FFMPEG_INC']
if env['WITH_BF_QUICKTIME']:
- defs += ' WITH_QUICKTIME'
- incs += ' ' + env['BF_QUICKTIME_INC']
+ defs.append('WITH_QUICKTIME')
+ incs += ' ' + env['BF_QUICKTIME_INC']
if env['WITH_BF_BULLET']:
- defs += ' WITH_BULLET'
+ defs.append('WITH_BULLET')
if env['BF_NO_ELBEEM']:
- defs += ' DISABLE_ELBEEM'
+ defs.append('DISABLE_ELBEEM')
+if env['WITH_BF_LCMS']:
+ defs.append('WITH_LCMS')
+
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
incs += ' ' + env['BF_PTHREADS_INC']
-env.BlenderLib ( libname = 'bf_blenkernel', sources = sources, includes = Split(incs), defines = Split(defs), libtype=['core'], priority = [165] )
+env.BlenderLib ( libname = 'bf_blenkernel', sources = sources, includes = Split(incs), defines = defs, libtype=['core'], priority = [165] )
diff --git a/source/blender/blenkernel/intern/BME_Customdata.c b/source/blender/blenkernel/intern/BME_Customdata.c
index 1fc8a4071dc..ea149e03959 100644
--- a/source/blender/blenkernel/intern/BME_Customdata.c
+++ b/source/blender/blenkernel/intern/BME_Customdata.c
@@ -3,7 +3,7 @@
*
* Custom Data functions for Bmesh
*
- * $Id: BKE_bmesh.h,v 1.00 2007/01/17 17:42:01 Briggs Exp $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
diff --git a/source/blender/blenkernel/intern/BME_conversions.c b/source/blender/blenkernel/intern/BME_conversions.c
index 1e332bcf393..177bb4a136b 100644
--- a/source/blender/blenkernel/intern/BME_conversions.c
+++ b/source/blender/blenkernel/intern/BME_conversions.c
@@ -3,7 +3,7 @@
*
* BMesh mesh level functions.
*
- * $Id: BME_eulers.c,v 1.00 2007/01/17 17:42:01 Briggs Exp $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
diff --git a/source/blender/blenkernel/intern/BME_eulers.c b/source/blender/blenkernel/intern/BME_eulers.c
index 801e0b8bdec..d0b4ab6a9ca 100644
--- a/source/blender/blenkernel/intern/BME_eulers.c
+++ b/source/blender/blenkernel/intern/BME_eulers.c
@@ -3,7 +3,7 @@
*
* BMesh Euler construction API.
*
- * $Id: BME_eulers.c,v 1.00 2007/01/17 17:42:01 Briggs Exp $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
diff --git a/source/blender/blenkernel/intern/BME_mesh.c b/source/blender/blenkernel/intern/BME_mesh.c
index ad46a7c1eb7..f635cfcfcd2 100644
--- a/source/blender/blenkernel/intern/BME_mesh.c
+++ b/source/blender/blenkernel/intern/BME_mesh.c
@@ -3,7 +3,7 @@
*
* BMesh mesh level functions.
*
- * $Id: BME_eulers.c,v 1.00 2007/01/17 17:42:01 Briggs Exp $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
diff --git a/source/blender/blenkernel/intern/BME_structure.c b/source/blender/blenkernel/intern/BME_structure.c
index ca27f5efd10..22ee48e4f7e 100644
--- a/source/blender/blenkernel/intern/BME_structure.c
+++ b/source/blender/blenkernel/intern/BME_structure.c
@@ -3,7 +3,7 @@
*
* Low level routines for manipulating the BMesh structure.
*
- * $Id: BME_structure.c,v 1.00 2007/01/17 17:42:01 Briggs Exp $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
diff --git a/source/blender/blenkernel/intern/BME_tools.c b/source/blender/blenkernel/intern/BME_tools.c
index 3ddd790e90b..a41307de183 100644
--- a/source/blender/blenkernel/intern/BME_tools.c
+++ b/source/blender/blenkernel/intern/BME_tools.c
@@ -3,7 +3,7 @@
*
* Functions for changing the topology of a mesh.
*
- * $Id: BME_eulers.c,v 1.00 2007/01/17 17:42:01 Briggs Exp $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index f5eb628ffe6..2eed104f43b 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -77,6 +77,7 @@
#include "BKE_utildefines.h"
#include "BKE_particle.h"
#include "BKE_tessmesh.h"
+#include "BKE_bvhutils.h"
#include "BLO_sys_types.h" // for intptr_t support
@@ -178,6 +179,8 @@ void DM_init_funcs(DerivedMesh *dm)
dm->getVertDataArray = DM_get_vert_data_layer;
dm->getEdgeDataArray = DM_get_edge_data_layer;
dm->getFaceDataArray = DM_get_face_data_layer;
+
+ bvhcache_init(&dm->bvhCache);
}
void DM_init(DerivedMesh *dm,
@@ -214,6 +217,8 @@ void DM_from_template(DerivedMesh *dm, DerivedMesh *source,
int DM_release(DerivedMesh *dm)
{
if (dm->needsFree) {
+ bvhcache_free(&dm->bvhCache);
+
CustomData_free(&dm->vertData, dm->numVertData);
CustomData_free(&dm->edgeData, dm->numEdgeData);
CustomData_free(&dm->faceData, dm->numFaceData);
@@ -1434,6 +1439,7 @@ static float *get_editbmesh_orco_verts(BMEditMesh *em)
return orco;
}
+/* orco custom data layer */
static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, BMEditMesh *em)
{
DerivedMesh *dm;
@@ -1485,6 +1491,96 @@ static void add_orco_dm(Object *ob, BMEditMesh *em, DerivedMesh *dm, DerivedMesh
DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco);
}
+/* weight paint colors */
+
+/* Something of a hack, at the moment deal with weightpaint
+ * by tucking into colors during modifier eval, only in
+ * wpaint mode. Works ok but need to make sure recalc
+ * happens on enter/exit wpaint.
+ */
+
+void weight_to_rgb(float input, float *fr, float *fg, float *fb)
+{
+ float blend;
+
+ blend= ((input/2.0f)+0.5f);
+
+ if (input<=0.25f){ // blue->cyan
+ *fr= 0.0f;
+ *fg= blend*input*4.0f;
+ *fb= blend;
+ }
+ else if (input<=0.50f){ // cyan->green
+ *fr= 0.0f;
+ *fg= blend;
+ *fb= blend*(1.0f-((input-0.25f)*4.0f));
+ }
+ else if (input<=0.75){ // green->yellow
+ *fr= blend * ((input-0.50f)*4.0f);
+ *fg= blend;
+ *fb= 0.0f;
+ }
+ else if (input<=1.0){ // yellow->red
+ *fr= blend;
+ *fg= blend * (1.0f-((input-0.75f)*4.0f));
+ *fb= 0.0f;
+ }
+}
+
+static void calc_weightpaint_vert_color(Object *ob, ColorBand *coba, int vert, unsigned char *col)
+{
+ Mesh *me = ob->data;
+ float colf[4], input = 0.0f;
+ int i;
+
+ if (me->dvert) {
+ for (i=0; i<me->dvert[vert].totweight; i++)
+ if (me->dvert[vert].dw[i].def_nr==ob->actdef-1)
+ input+=me->dvert[vert].dw[i].weight;
+ }
+
+ CLAMP(input, 0.0f, 1.0f);
+
+ if(coba)
+ do_colorband(coba, input, colf);
+ else
+ weight_to_rgb(input, colf, colf+1, colf+2);
+
+ col[3] = (unsigned char)(colf[0] * 255.0f);
+ col[2] = (unsigned char)(colf[1] * 255.0f);
+ col[1] = (unsigned char)(colf[2] * 255.0f);
+ col[0] = 255;
+}
+
+static ColorBand *stored_cb= NULL;
+
+void vDM_ColorBand_store(ColorBand *coba)
+{
+ stored_cb= coba;
+}
+
+static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm)
+{
+ Mesh *me = ob->data;
+ MFace *mf = me->mface;
+ ColorBand *coba= stored_cb; /* warning, not a local var */
+ unsigned char *wtcol;
+ int i;
+
+ wtcol = MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap");
+
+ memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4);
+ for (i=0; i<me->totface; i++, mf++) {
+ calc_weightpaint_vert_color(ob, coba, mf->v1, &wtcol[(i*4 + 0)*4]);
+ calc_weightpaint_vert_color(ob, coba, mf->v2, &wtcol[(i*4 + 1)*4]);
+ calc_weightpaint_vert_color(ob, coba, mf->v3, &wtcol[(i*4 + 2)*4]);
+ if (mf->v4)
+ calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4]);
+ }
+
+ CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, dm->numFaceData);
+}
+
static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos)[3],
DerivedMesh **deform_r, DerivedMesh **final_r,
int useRenderParams, int useDeform,
@@ -1548,6 +1644,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
*/
if (deform_r) {
*deform_r = CDDM_from_mesh(me, ob);
+
if(deformedVerts) {
CDDM_apply_vert_coords(*deform_r, deformedVerts);
CDDM_calc_normals(*deform_r);
@@ -1633,6 +1730,9 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
CDDM_apply_vert_coords(dm, deformedVerts);
CDDM_calc_normals(dm);
}
+
+ if(dataMask & CD_MASK_WEIGHT_MCOL)
+ add_weight_mcol_dm(ob, dm);
}
/* create an orco derivedmesh in parallel */
@@ -1696,14 +1796,21 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
CDDM_apply_vert_coords(finaldm, deformedVerts);
CDDM_calc_normals(finaldm);
+
+ if(dataMask & CD_MASK_WEIGHT_MCOL)
+ add_weight_mcol_dm(ob, finaldm);
} else if(dm) {
finaldm = dm;
} else {
finaldm = CDDM_from_mesh(me, ob);
+
if(deformedVerts) {
CDDM_apply_vert_coords(finaldm, deformedVerts);
CDDM_calc_normals(finaldm);
}
+
+ if(dataMask & CD_MASK_WEIGHT_MCOL)
+ add_weight_mcol_dm(ob, finaldm);
}
/* add an orco layer if needed */
@@ -1936,96 +2043,6 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
MEM_freeN(deformedVerts);
}
-/***/
-
-
- /* Something of a hack, at the moment deal with weightpaint
- * by tucking into colors during modifier eval, only in
- * wpaint mode. Works ok but need to make sure recalc
- * happens on enter/exit wpaint.
- */
-
-void weight_to_rgb(float input, float *fr, float *fg, float *fb)
-{
- float blend;
-
- blend= ((input/2.0f)+0.5f);
-
- if (input<=0.25f){ // blue->cyan
- *fr= 0.0f;
- *fg= blend*input*4.0f;
- *fb= blend;
- }
- else if (input<=0.50f){ // cyan->green
- *fr= 0.0f;
- *fg= blend;
- *fb= blend*(1.0f-((input-0.25f)*4.0f));
- }
- else if (input<=0.75){ // green->yellow
- *fr= blend * ((input-0.50f)*4.0f);
- *fg= blend;
- *fb= 0.0f;
- }
- else if (input<=1.0){ // yellow->red
- *fr= blend;
- *fg= blend * (1.0f-((input-0.75f)*4.0f));
- *fb= 0.0f;
- }
-}
-static void calc_weightpaint_vert_color(Object *ob, ColorBand *coba, int vert, unsigned char *col)
-{
- Mesh *me = ob->data;
- float colf[4], input = 0.0f;
- int i;
-
- if (me->dvert) {
- for (i=0; i<me->dvert[vert].totweight; i++)
- if (me->dvert[vert].dw[i].def_nr==ob->actdef-1)
- input+=me->dvert[vert].dw[i].weight;
- }
-
- CLAMP(input, 0.0f, 1.0f);
-
- if(coba)
- do_colorband(coba, input, colf);
- else
- weight_to_rgb(input, colf, colf+1, colf+2);
-
- col[3] = (unsigned char)(colf[0] * 255.0f);
- col[2] = (unsigned char)(colf[1] * 255.0f);
- col[1] = (unsigned char)(colf[2] * 255.0f);
- col[0] = 255;
-}
-
-static ColorBand *stored_cb= NULL;
-
-void vDM_ColorBand_store(ColorBand *coba)
-{
- stored_cb= coba;
-}
-
-static unsigned char *calc_weightpaint_colors(Object *ob)
-{
- Mesh *me = ob->data;
- MFace *mf = me->mface;
- ColorBand *coba= stored_cb; /* warning, not a local var */
- unsigned char *wtcol;
- int i;
-
- wtcol = MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap");
-
- memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4);
- for (i=0; i<me->totface; i++, mf++) {
- calc_weightpaint_vert_color(ob, coba, mf->v1, &wtcol[(i*4 + 0)*4]);
- calc_weightpaint_vert_color(ob, coba, mf->v2, &wtcol[(i*4 + 1)*4]);
- calc_weightpaint_vert_color(ob, coba, mf->v3, &wtcol[(i*4 + 2)*4]);
- if (mf->v4)
- calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4]);
- }
-
- return wtcol;
-}
-
static void clear_mesh_caches(Object *ob)
{
Mesh *me= ob->data;
@@ -2056,42 +2073,16 @@ static void clear_mesh_caches(Object *ob)
static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask)
{
- Mesh *me = ob->data;
- float min[3], max[3];
- //int needMapping= 0;
-
Object *obact = scene->basact?scene->basact->object:NULL;
int editing = (FACESEL_PAINT_TEST)|(G.f & G_PARTICLEEDIT);
int needMapping = editing && (ob==obact);
+ float min[3], max[3];
clear_mesh_caches(ob);
- if( (G.f & G_WEIGHTPAINT) && ob==obact ) {
-// if(dataMask & CD_MASK_WEIGHTPAINT) {
- MCol *wpcol = (MCol*)calc_weightpaint_colors(ob);
- int layernum = CustomData_number_of_layers(&me->fdata, CD_MCOL);
- int prevactive = CustomData_get_active_layer(&me->fdata, CD_MCOL);
- int prevrender = CustomData_get_render_layer(&me->fdata, CD_MCOL);
-
- /* ugly hack here, we temporarily add a new active mcol layer with
- weightpaint colors in it, that is then duplicated in CDDM_from_mesh */
- CustomData_add_layer(&me->fdata, CD_MCOL, CD_ASSIGN, wpcol, me->totface);
- CustomData_set_layer_active(&me->fdata, CD_MCOL, layernum);
- CustomData_set_layer_render(&me->fdata, CD_MCOL, layernum);
-
- mesh_calc_modifiers(scene, ob, NULL, &ob->derivedDeform,
- &ob->derivedFinal, 0, 1,
- needMapping, dataMask, -1);
-
- CustomData_free_layer_active(&me->fdata, CD_MCOL, me->totface);
- CustomData_set_layer_active(&me->fdata, CD_MCOL, prevactive);
- CustomData_set_layer_render(&me->fdata, CD_MCOL, prevrender);
- }
- else {
- mesh_calc_modifiers(scene, ob, NULL, &ob->derivedDeform,
- &ob->derivedFinal, G.rendering, 1,
- needMapping, dataMask, -1);
- }
+ mesh_calc_modifiers(scene, ob, NULL, &ob->derivedDeform,
+ &ob->derivedFinal, 0, 1,
+ needMapping, dataMask, -1);
INIT_MINMAX(min, max);
diff --git a/source/blender/blenkernel/intern/Makefile b/source/blender/blenkernel/intern/Makefile
index 6554c93662d..1528ec1c86e 100644
--- a/source/blender/blenkernel/intern/Makefile
+++ b/source/blender/blenkernel/intern/Makefile
@@ -59,8 +59,6 @@ CPPFLAGS += -I../../editors/include
# to include the render stuff:
CPPFLAGS += -I../../render/extern/include
-# for image stamping
-CPPFLAGS += -I$(NAN_BMFONT)/include
# for sound
#CPPFLAGS += -I../../../kernel/gen_system
CPPFLAGS += $(NAN_SDLCFLAGS)
@@ -85,12 +83,8 @@ CPPFLAGS += -I..
# path to bullet2, for cloth
CPPFLAGS += -I../../../../extern/bullet2/src
-
-ifeq ($(WITH_FREETYPE2), true)
- CPPFLAGS += -DWITH_FREETYPE2
- CPPFLAGS += -I$(NAN_FREETYPE)/include
- CPPFLAGS += -I$(NAN_FREETYPE)/include/freetype2
-endif
+CPPFLAGS += -I$(NAN_FREETYPE)/include
+CPPFLAGS += -I$(NAN_FREETYPE)/include/freetype2
ifeq ($(WITH_FFMPEG),true)
CPPFLAGS += -DWITH_FFMPEG
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 9ed469c9028..d54bc749b71 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -65,6 +65,9 @@
#include "BLI_blenlib.h"
#include "BLI_ghash.h"
+#include "RNA_access.h"
+#include "RNA_types.h"
+
//XXX #include "nla.h"
/* *********************** NOTE ON POSE AND ACTION **********************
@@ -169,17 +172,39 @@ void free_action (bAction *act)
bAction *copy_action (bAction *src)
{
bAction *dst = NULL;
- //bActionGroup *dgrp, *sgrp; // XXX not used yet
+ bActionGroup *dgrp, *sgrp;
+ FCurve *dfcu, *sfcu;
if (src == NULL)
return NULL;
dst= copy_libblock(src);
- BLI_duplicatelist(&dst->groups, &src->groups); // XXX not used yet
+ /* duplicate the lists of groups and markers */
+ BLI_duplicatelist(&dst->groups, &src->groups);
BLI_duplicatelist(&dst->markers, &src->markers);
- /* copy f-curves */
- copy_fcurves(&dst->curves, &src->curves);
+ /* copy F-Curves, fixing up the links as we go */
+ dst->curves.first= dst->curves.last= NULL;
+
+ for (sfcu= src->curves.first; sfcu; sfcu= sfcu->next) {
+ /* duplicate F-Curve */
+ dfcu= copy_fcurve(sfcu);
+ BLI_addtail(&dst->curves, dfcu);
+
+ /* fix group links (kindof bad list-in-list search, but this is the most reliable way) */
+ for (dgrp=dst->groups.first, sgrp=src->groups.first; dgrp && sgrp; dgrp=dgrp->next, sgrp=sgrp->next) {
+ if (sfcu->grp == sgrp) {
+ dfcu->grp= dgrp;
+
+ if (dgrp->channels.first == sfcu)
+ dgrp->channels.first= dfcu;
+ if (dgrp->channels.last == sfcu)
+ dgrp->channels.last= dfcu;
+
+ break;
+ }
+ }
+ }
dst->id.flag |= LIB_FAKEUSER; // XXX this is nasty for new users... maybe we don't want this anymore
dst->id.us++;
@@ -740,38 +765,27 @@ float get_action_frame_inv(Object *ob, float cframe)
/* Calculate the extents of given action */
void calc_action_range(const bAction *act, float *start, float *end, int incl_hidden)
{
- // FCurve *fcu;
+ FCurve *fcu;
float min=999999999.0f, max=-999999999.0f;
- int foundvert=0;
+ short foundvert=0;
if (act) {
-#if 0 // XXX old animation system
- for (chan=act->chanbase.first; chan; chan=chan->next) {
- if ((incl_hidden) || (chan->flag & ACHAN_HIDDEN)==0) {
- if (chan->ipo) {
- for (icu=chan->ipo->curve.first; icu; icu=icu->next) {
- if (icu->totvert) {
- min= MIN2(min, icu->bezt[0].vec[1][0]);
- max= MAX2(max, icu->bezt[icu->totvert-1].vec[1][0]);
- foundvert=1;
- }
- }
- }
- for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (conchan->ipo) {
- for (icu=conchan->ipo->curve.first; icu; icu=icu->next) {
- if (icu->totvert) {
- min= MIN2(min, icu->bezt[0].vec[1][0]);
- max= MAX2(max, icu->bezt[icu->totvert-1].vec[1][0]);
- foundvert=1;
- }
- }
- }
- }
+ for (fcu= act->curves.first; fcu; fcu= fcu->next) {
+ if (fcu->totvert) {
+ float nmin, nmax;
+
+ /* get extents for this curve */
+ calc_fcurve_range(fcu, &nmin, &nmax);
+
+ /* compare to the running tally */
+ min= MIN2(min, nmin);
+ max= MAX2(max, nmax);
+
+ foundvert= 1;
}
}
-#endif // XXX old animation system
}
+
if (foundvert) {
if(min==max) max+= 1.0f;
*start= min;
@@ -847,9 +861,11 @@ void copy_pose_result(bPose *to, bPose *from)
if(pchanto) {
Mat4CpyMat4(pchanto->pose_mat, pchanfrom->pose_mat);
Mat4CpyMat4(pchanto->chan_mat, pchanfrom->chan_mat);
+
/* used for local constraints */
VECCOPY(pchanto->loc, pchanfrom->loc);
QUATCOPY(pchanto->quat, pchanfrom->quat);
+ VECCOPY(pchanto->eul, pchanfrom->eul);
VECCOPY(pchanto->size, pchanfrom->size);
VECCOPY(pchanto->pose_head, pchanfrom->pose_head);
@@ -862,13 +878,12 @@ void copy_pose_result(bPose *to, bPose *from)
/* For the calculation of the effects of an Action at the given frame on an object
* This is currently only used for the Action Constraint
*/
-void what_does_obaction (Scene *scene, Object *ob, Object *workob, bPose *pose, bAction *act, float cframe)
+void what_does_obaction (Scene *scene, Object *ob, Object *workob, bPose *pose, bAction *act, char groupname[], float cframe)
{
- AnimData adt;
+ bActionGroup *agrp= action_groups_find_named(act, groupname);
- /* clear workob and animdata */
+ /* clear workob */
clear_workob(workob);
- memset(&adt, 0, sizeof(AnimData));
/* init workob */
Mat4CpyMat4(workob->obmat, ob->obmat);
@@ -893,14 +908,30 @@ void what_does_obaction (Scene *scene, Object *ob, Object *workob, bPose *pose,
strcpy(workob->parsubstr, ob->parsubstr);
strcpy(workob->id.name, "OB<ConstrWorkOb>"); /* we don't use real object name, otherwise RNA screws with the real thing */
- /* init animdata, and attach to workob */
- workob->adt= &adt;
-
- adt.recalc= ADT_RECALC_ANIM;
- adt.action= act;
-
- /* execute effects of Action on to workob (or it's PoseChannels) */
- BKE_animsys_evaluate_animdata(&workob->id, &adt, cframe, ADT_RECALC_ANIM);
+ /* if we're given a group to use, it's likely to be more efficient (though a bit more dangerous) */
+ if (agrp) {
+ /* specifically evaluate this group only */
+ PointerRNA id_ptr;
+
+ /* get RNA-pointer for the workob's ID */
+ RNA_id_pointer_create(&workob->id, &id_ptr);
+
+ /* execute action for this group only */
+ animsys_evaluate_action_group(&id_ptr, act, agrp, NULL, cframe);
+ }
+ else {
+ AnimData adt;
+
+ /* init animdata, and attach to workob */
+ memset(&adt, 0, sizeof(AnimData));
+ workob->adt= &adt;
+
+ adt.recalc= ADT_RECALC_ANIM;
+ adt.action= act;
+
+ /* execute effects of Action on to workob (or it's PoseChannels) */
+ BKE_animsys_evaluate_animdata(&workob->id, &adt, cframe, ADT_RECALC_ANIM);
+ }
}
/* ********** NLA with non-poses works with ipo channels ********** */
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index bd99893bc37..b2cbd82cfc2 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -227,14 +227,16 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK
cu= ob->data;
if(cu->path==NULL || cu->path->data==NULL) {
printf("no path!\n");
+ return 0;
}
path= cu->path;
fp= path->data;
/* test for cyclic */
bl= cu->bev.first;
+ if (!bl) return 0;
if (!bl->nr) return 0;
- if(bl && bl->poly> -1) cycl= 1;
+ if(bl->poly> -1) cycl= 1;
ctime *= (path->len-1);
@@ -571,11 +573,10 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
if(level>MAX_DUPLI_RECUR) return;
Mat4CpyMat4(pmat, par->obmat);
-
em = me->edit_btmesh;
+
if(em) {
int totvert;
-
dm= editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
totface= dm->getNumFaces(dm);
@@ -584,7 +585,6 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
totvert= dm->getNumVerts(dm);
mvert= MEM_mallocN(sizeof(MVert)*totvert, "mvert temp");
dm->copyVertArray(dm, mvert);
-
}
else {
dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
@@ -758,7 +758,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
float ctime, pa_time, scale = 1.0f;
float tmat[4][4], mat[4][4], pamat[4][4], size=0.0;
float (*obmat)[4], (*oldobmat)[4];
- int lay, a, b, k, step_nbr = 0, counter, hair = 0;
+ int lay, a, b, counter, hair = 0;
int totpart, totchild, totgroup=0, pa_num;
if(psys==0) return;
@@ -786,11 +786,6 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
if((part->draw_as == PART_DRAW_OB && part->dup_ob) ||
(part->draw_as == PART_DRAW_GR && part->dup_group && part->dup_group->gobject.first)) {
- if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) && part->draw & PART_DRAW_KEYS)
- step_nbr = part->keys_step;
- else
- step_nbr = 0;
-
/* if we have a hair particle system, use the path cache */
if(part->type == PART_HAIR) {
if(psys->flag & PSYS_HAIR_DONE)
@@ -870,76 +865,65 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
oldobmat= obcopy.obmat;
}
- for(k=0; k<=step_nbr; k++, counter++) {
- if(hair) {
- /* hair we handle separate and compute transform based on hair keys */
- if(a < totpart) {
- cache = psys->pathcache[a];
- psys_get_dupli_path_transform(par, psys, psmd, pa, 0, cache, pamat, &scale);
- }
- else {
- cache = psys->childcache[a-totpart];
- psys_get_dupli_path_transform(par, psys, psmd, 0, cpa, cache, pamat, &scale);
- }
-
- VECCOPY(pamat[3], cache->co);
- pamat[3][3]= 1.0f;
-
- }
- else if(step_nbr) {
- /* other keys */
- state.time = (float)k / (float)step_nbr;
- psys_get_particle_on_path(scene, par, psys, a, &state, 0);
-
- QuatToMat4(state.rot, pamat);
- VECCOPY(pamat[3], state.co);
- pamat[3][3]= 1.0f;
+ if(hair) {
+ /* hair we handle separate and compute transform based on hair keys */
+ if(a < totpart) {
+ cache = psys->pathcache[a];
+ psys_get_dupli_path_transform(par, psys, psmd, pa, 0, cache, pamat, &scale);
}
else {
- /* first key */
- state.time = -1.0;
- if(psys_get_particle_state(scene, par, psys, a, &state, 0) == 0)
- continue;
-
- QuatToMat4(state.rot, pamat);
- VECCOPY(pamat[3], state.co);
- pamat[3][3]= 1.0f;
+ cache = psys->childcache[a-totpart];
+ psys_get_dupli_path_transform(par, psys, psmd, 0, cpa, cache, pamat, &scale);
}
- if(part->draw_as==PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) {
- for(go= part->dup_group->gobject.first, b=0; go; go= go->next, b++) {
- Mat4MulMat4(tmat, oblist[b]->obmat, pamat);
- Mat4MulFloat3((float *)tmat, size*scale);
- if(par_space_mat)
- Mat4MulMat4(mat, tmat, par_space_mat);
- else
- Mat4CpyMat4(mat, tmat);
+ VECCOPY(pamat[3], cache->co);
+ pamat[3][3]= 1.0f;
+
+ }
+ else {
+ /* first key */
+ state.time = ctime;
+ if(psys_get_particle_state(scene, par, psys, a, &state, 0) == 0)
+ continue;
- dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS, animated);
- Mat4CpyMat4(dob->omat, obcopylist[b].obmat);
- if(G.rendering)
- psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco);
- }
- }
- else {
- /* to give ipos in object correct offset */
- where_is_object_time(scene, ob, ctime-pa_time);
-
- Mat4CpyMat4(mat, pamat);
+ QuatToMat4(state.rot, pamat);
+ VECCOPY(pamat[3], state.co);
+ pamat[3][3]= 1.0f;
+ }
- Mat4MulMat4(tmat, obmat, mat);
+ if(part->draw_as==PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) {
+ for(go= part->dup_group->gobject.first, b=0; go; go= go->next, b++) {
+ Mat4MulMat4(tmat, oblist[b]->obmat, pamat);
Mat4MulFloat3((float *)tmat, size*scale);
if(par_space_mat)
Mat4MulMat4(mat, tmat, par_space_mat);
else
Mat4CpyMat4(mat, tmat);
- dob= new_dupli_object(lb, ob, mat, par->lay, counter, OB_DUPLIPARTS, animated);
- Mat4CpyMat4(dob->omat, oldobmat);
+ dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS, animated);
+ Mat4CpyMat4(dob->omat, obcopylist[b].obmat);
if(G.rendering)
psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco);
}
}
+ else {
+ /* to give ipos in object correct offset */
+ where_is_object_time(scene, ob, ctime-pa_time);
+
+ Mat4CpyMat4(mat, pamat);
+
+ Mat4MulMat4(tmat, obmat, mat);
+ Mat4MulFloat3((float *)tmat, size*scale);
+ if(par_space_mat)
+ Mat4MulMat4(mat, tmat, par_space_mat);
+ else
+ Mat4CpyMat4(mat, tmat);
+
+ dob= new_dupli_object(lb, ob, mat, ob->lay, counter, OB_DUPLIPARTS, animated);
+ Mat4CpyMat4(dob->omat, oldobmat);
+ if(G.rendering)
+ psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco);
+ }
}
/* restore objects since they were changed in where_is_object_time */
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 0097b30b685..30dcb383ef6 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -4,6 +4,7 @@
#include <stdio.h>
#include <string.h>
+#include <stddef.h>
#include "MEM_guardedalloc.h"
@@ -238,6 +239,9 @@ KeyingSet *BKE_keyingset_add (ListBase *list, const char name[], short flag, sho
/* add KeyingSet to list */
BLI_addtail(list, ks);
+ /* make sure KeyingSet has a unique name (this helps with identification) */
+ BLI_uniquename(list, ks, "Keying Set", ' ', offsetof(KeyingSet, name), 64);
+
/* return new KeyingSet for further editing */
return ks;
}
@@ -275,6 +279,10 @@ void BKE_keyingset_add_destination (KeyingSet *ks, ID *id, const char group_name
strcpy(ksp->group, "");
}
+ /* store additional info for relative paths (just in case user makes the set relative) */
+ if (id)
+ ksp->idtype= GS(id->name);
+
/* just copy path info */
// XXX no checks are performed for templates yet
// should array index be checked too?
@@ -369,22 +377,22 @@ static short animsys_write_rna_setting (PointerRNA *ptr, char *path, int array_i
/* set value - only for animatable numerical values */
if (RNA_property_animateable(&new_ptr, prop))
{
- switch (RNA_property_type(&new_ptr, prop))
+ switch (RNA_property_type(prop))
{
case PROP_BOOLEAN:
- if (RNA_property_array_length(&new_ptr, prop))
+ if (RNA_property_array_length(prop))
RNA_property_boolean_set_index(&new_ptr, prop, array_index, (int)value);
else
RNA_property_boolean_set(&new_ptr, prop, (int)value);
break;
case PROP_INT:
- if (RNA_property_array_length(&new_ptr, prop))
+ if (RNA_property_array_length(prop))
RNA_property_int_set_index(&new_ptr, prop, array_index, (int)value);
else
RNA_property_int_set(&new_ptr, prop, (int)value);
break;
case PROP_FLOAT:
- if (RNA_property_array_length(&new_ptr, prop))
+ if (RNA_property_array_length(prop))
RNA_property_float_set_index(&new_ptr, prop, array_index, value);
else
RNA_property_float_set(&new_ptr, prop, value);
@@ -393,12 +401,12 @@ static short animsys_write_rna_setting (PointerRNA *ptr, char *path, int array_i
RNA_property_enum_set(&new_ptr, prop, (int)value);
break;
default:
- break;
+ /* nothing can be done here... so it is unsuccessful? */
+ return 0;
}
}
/* successful */
- // XXX should the unhandled case also be successful?
return 1;
}
else {
@@ -415,21 +423,25 @@ static short animsys_write_rna_setting (PointerRNA *ptr, char *path, int array_i
}
/* Simple replacement based data-setting of the FCurve using RNA */
-static void animsys_execute_fcurve (PointerRNA *ptr, AnimMapper *remap, FCurve *fcu)
+static short animsys_execute_fcurve (PointerRNA *ptr, AnimMapper *remap, FCurve *fcu)
{
char *path = NULL;
short free_path=0;
+ short ok= 0;
/* get path, remapped as appropriate to work in its new environment */
free_path= animsys_remap_path(remap, fcu->rna_path, &path);
/* write value to setting */
if (path)
- animsys_write_rna_setting(ptr, path, fcu->array_index, fcu->curval);
+ ok= animsys_write_rna_setting(ptr, path, fcu->array_index, fcu->curval);
/* free temp path-info */
if (free_path)
MEM_freeN(path);
+
+ /* return whether we were successful */
+ return ok;
}
/* Evaluate all the F-Curves in the given list
@@ -465,20 +477,25 @@ static void animsys_evaluate_drivers (PointerRNA *ptr, AnimData *adt, float ctim
for (fcu= adt->drivers.first; fcu; fcu= fcu->next)
{
ChannelDriver *driver= fcu->driver;
+ short ok= 0;
/* check if this driver's curve should be skipped */
// FIXME: maybe we shouldn't check for muted, though that would make things more confusing, as there's already too many ways to disable?
if ((fcu->flag & (FCURVE_MUTED|FCURVE_DISABLED)) == 0)
{
/* check if driver itself is tagged for recalculation */
- if ((driver) /*&& (driver->flag & DRIVER_FLAG_RECALC)*/) { // XXX driver recalc flag is not set yet by depsgraph!
+ if ((driver) && !(driver->flag & DRIVER_FLAG_INVALID)/*&& (driver->flag & DRIVER_FLAG_RECALC)*/) { // XXX driver recalc flag is not set yet by depsgraph!
/* evaluate this using values set already in other places */
// NOTE: for 'layering' option later on, we should check if we should remove old value before adding new to only be done when drivers only changed
calculate_fcurve(fcu, ctime);
- animsys_execute_fcurve(ptr, NULL, fcu);
+ ok= animsys_execute_fcurve(ptr, NULL, fcu);
/* clear recalc flag */
driver->flag &= ~DRIVER_FLAG_RECALC;
+
+ /* set error-flag if evaluation failed */
+ if (ok == 0)
+ driver->flag |= DRIVER_FLAG_INVALID;
}
}
}
@@ -487,8 +504,29 @@ static void animsys_evaluate_drivers (PointerRNA *ptr, AnimData *adt, float ctim
/* ***************************************** */
/* Actions Evaluation */
+/* Evaluate Action Group */
+void animsys_evaluate_action_group (PointerRNA *ptr, bAction *act, bActionGroup *agrp, AnimMapper *remap, float ctime)
+{
+ FCurve *fcu;
+
+ /* check if mapper is appropriate for use here (we set to NULL if it's inappropriate) */
+ if ELEM(NULL, act, agrp) return;
+ if ((remap) && (remap->target != act)) remap= NULL;
+
+ /* calculate then execute each curve */
+ for (fcu= agrp->channels.first; (fcu) && (fcu->grp == agrp); fcu= fcu->next)
+ {
+ /* check if this curve should be skipped */
+ if ((fcu->flag & (FCURVE_MUTED|FCURVE_DISABLED)) == 0)
+ {
+ calculate_fcurve(fcu, ctime);
+ animsys_execute_fcurve(ptr, remap, fcu);
+ }
+ }
+}
+
/* Evaluate Action (F-Curve Bag) */
-static void animsys_evaluate_action (PointerRNA *ptr, bAction *act, AnimMapper *remap, float ctime)
+void animsys_evaluate_action (PointerRNA *ptr, bAction *act, AnimMapper *remap, float ctime)
{
/* check if mapper is appropriate for use here (we set to NULL if it's inappropriate) */
if (act == NULL) return;
@@ -846,7 +884,10 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
// TODO...
/* objects */
- EVAL_ANIM_IDS(main->object.first, 0);
+ /* ADT_RECALC_ANIM doesn't need to be supplied here, since object AnimData gets
+ * this tagged by Depsgraph on framechange
+ */
+ EVAL_ANIM_IDS(main->object.first, /*ADT_RECALC_ANIM*/0);
/* worlds */
EVAL_ANIM_IDS(main->world.first, ADT_RECALC_ANIM);
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 2033250585d..3169905b7f5 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -325,8 +325,8 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename)
if (bfd->user) {
/* only here free userdef themes... */
- BLI_freelistN(&U.themes);
-
+ BKE_userdef_free();
+
U= *bfd->user;
MEM_freeN(bfd->user);
}
@@ -414,6 +414,15 @@ static void handle_subversion_warning(Main *main)
}
+void BKE_userdef_free(void)
+{
+
+ BLI_freelistN(&U.uistyles);
+ BLI_freelistN(&U.uifonts);
+ BLI_freelistN(&U.themes);
+
+}
+
/* returns:
0: no load file
1: OK
diff --git a/source/blender/blenkernel/intern/bmesh_private.h b/source/blender/blenkernel/intern/bmesh_private.h
index f34ef0090f3..dd7d20bcf15 100644
--- a/source/blender/blenkernel/intern/bmesh_private.h
+++ b/source/blender/blenkernel/intern/bmesh_private.h
@@ -3,7 +3,7 @@
*
* low level, 'private' function prototypes for bmesh kernel.
*
- * $Id: BKE_bmesh.h,v 1.00 2007/01/17 17:42:01 Briggs Exp $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
diff --git a/source/blender/blenkernel/intern/booleanops.c b/source/blender/blenkernel/intern/booleanops.c
index e57dfea8eaf..27b78c6644c 100644
--- a/source/blender/blenkernel/intern/booleanops.c
+++ b/source/blender/blenkernel/intern/booleanops.c
@@ -65,7 +65,7 @@
*/
typedef struct {
- Mesh *mesh;
+ DerivedMesh *dm;
Object *ob;
int pos;
} VertexIt;
@@ -93,13 +93,13 @@ static void VertexIt_Destruct(CSG_VertexIteratorDescriptor * iterator)
static int VertexIt_Done(CSG_IteratorPtr it)
{
VertexIt * iterator = (VertexIt *)it;
- return(iterator->pos >= iterator->mesh->totvert);
+ return(iterator->pos >= iterator->dm->getNumVerts(iterator->dm));
}
static void VertexIt_Fill(CSG_IteratorPtr it, CSG_IVertex *vert)
{
VertexIt * iterator = (VertexIt *)it;
- MVert *verts = iterator->mesh->mvert;
+ MVert *verts = iterator->dm->getVertArray(iterator->dm);
float global_pos[3];
@@ -127,7 +127,7 @@ static void VertexIt_Reset(CSG_IteratorPtr it)
iterator->pos = 0;
}
-static void VertexIt_Construct(CSG_VertexIteratorDescriptor *output, Object *ob)
+static void VertexIt_Construct(CSG_VertexIteratorDescriptor *output, DerivedMesh *dm, Object *ob)
{
VertexIt *it;
@@ -139,8 +139,8 @@ static void VertexIt_Construct(CSG_VertexIteratorDescriptor *output, Object *ob)
return;
}
// assign blender specific variables
- it->ob = ob;
- it->mesh = ob->data;
+ it->dm = dm;
+ it->ob = ob; // needed for obmat transformations
it->pos = 0;
@@ -149,7 +149,7 @@ static void VertexIt_Construct(CSG_VertexIteratorDescriptor *output, Object *ob)
output->Fill = VertexIt_Fill;
output->Done = VertexIt_Done;
output->Reset = VertexIt_Reset;
- output->num_elements = it->mesh->totvert;
+ output->num_elements = it->dm->getNumVerts(it->dm);
output->it = it;
}
@@ -158,7 +158,7 @@ static void VertexIt_Construct(CSG_VertexIteratorDescriptor *output, Object *ob)
*/
typedef struct {
- Mesh *mesh;
+ DerivedMesh *dm;
int pos;
int offset;
} FaceIt;
@@ -177,14 +177,14 @@ static int FaceIt_Done(CSG_IteratorPtr it)
{
// assume CSG_IteratorPtr is of the correct type.
FaceIt * iterator = (FaceIt *)it;
- return(iterator->pos >= iterator->mesh->totface);
+ return(iterator->pos >= iterator->dm->getNumFaces(iterator->dm));
}
static void FaceIt_Fill(CSG_IteratorPtr it, CSG_IFace *face)
{
// assume CSG_IteratorPtr is of the correct type.
FaceIt *face_it = (FaceIt *)it;
- MFace *mfaces = face_it->mesh->mface;
+ MFace *mfaces = face_it->dm->getFaceArray(face_it->dm);
MFace *mface = &mfaces[face_it->pos];
face->vertex_index[0] = mface->v1;
@@ -213,7 +213,7 @@ static void FaceIt_Reset(CSG_IteratorPtr it)
}
static void FaceIt_Construct(
- CSG_FaceIteratorDescriptor *output, Object *ob, int offset)
+ CSG_FaceIteratorDescriptor *output, DerivedMesh *dm, int offset)
{
FaceIt *it;
if (output == 0) return;
@@ -224,7 +224,7 @@ static void FaceIt_Construct(
return ;
}
// assign blender specific variables
- it->mesh = ob->data;
+ it->dm = dm;
it->offset = offset;
it->pos = 0;
@@ -233,7 +233,7 @@ static void FaceIt_Construct(
output->Fill = FaceIt_Fill;
output->Done = FaceIt_Done;
output->Reset = FaceIt_Reset;
- output->num_elements = it->mesh->totface;
+ output->num_elements = it->dm->getNumFaces(it->dm);
output->it = it;
}
@@ -276,7 +276,7 @@ static Object *AddNewBlenderMesh(Scene *scene, Base *base)
}
static void InterpCSGFace(
- DerivedMesh *dm, Mesh *orig_me, int index, int orig_index, int nr,
+ DerivedMesh *dm, DerivedMesh *orig_dm, int index, int orig_index, int nr,
float mapmat[][4])
{
float obco[3], *co[4], *orig_co[4], w[4][4];
@@ -284,13 +284,13 @@ static void InterpCSGFace(
int j;
mface = CDDM_get_face(dm, index);
- orig_mface = orig_me->mface + orig_index;
+ orig_mface = orig_dm->getFaceArray(orig_dm) + orig_index;
// get the vertex coordinates from the original mesh
- orig_co[0] = (orig_me->mvert + orig_mface->v1)->co;
- orig_co[1] = (orig_me->mvert + orig_mface->v2)->co;
- orig_co[2] = (orig_me->mvert + orig_mface->v3)->co;
- orig_co[3] = (orig_mface->v4)? (orig_me->mvert + orig_mface->v4)->co: NULL;
+ orig_co[0] = (orig_dm->getVertArray(orig_dm) + orig_mface->v1)->co;
+ orig_co[1] = (orig_dm->getVertArray(orig_dm) + orig_mface->v2)->co;
+ orig_co[2] = (orig_dm->getVertArray(orig_dm) + orig_mface->v3)->co;
+ orig_co[3] = (orig_mface->v4)? (orig_dm->getVertArray(orig_dm) + orig_mface->v4)->co: NULL;
// get the vertex coordinates from the new derivedmesh
co[0] = CDDM_get_vert(dm, mface->v1)->co;
@@ -308,7 +308,7 @@ static void InterpCSGFace(
InterpWeightsQ3Dfl(orig_co[0], orig_co[1], orig_co[2], orig_co[3], obco, w[j]);
}
- CustomData_interp(&orig_me->fdata, &dm->faceData, &orig_index, NULL, (float*)w, 1, index);
+ CustomData_interp(&orig_dm->faceData, &dm->faceData, &orig_index, NULL, (float*)w, 1, index);
}
/* Iterate over the CSG Output Descriptors and create a new DerivedMesh
@@ -320,27 +320,28 @@ static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh(
float mapmat[][4],
Material **mat,
int *totmat,
+ DerivedMesh *dm1,
Object *ob1,
+ DerivedMesh *dm2,
Object *ob2)
{
- DerivedMesh *dm;
+ DerivedMesh *result, *orig_dm;
GHash *material_hash = NULL;
Mesh *me1= (Mesh*)ob1->data;
Mesh *me2= (Mesh*)ob2->data;
int i;
// create a new DerivedMesh
- dm = CDDM_new(vertex_it->num_elements, 0, face_it->num_elements);
-
- CustomData_merge(&me1->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
- CD_DEFAULT, face_it->num_elements);
- CustomData_merge(&me2->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
- CD_DEFAULT, face_it->num_elements);
+ result = CDDM_new(vertex_it->num_elements, 0, face_it->num_elements);
+ CustomData_merge(&dm1->faceData, &result->faceData, CD_MASK_DERIVEDMESH,
+ CD_DEFAULT, face_it->num_elements);
+ CustomData_merge(&dm2->faceData, &result->faceData, CD_MASK_DERIVEDMESH,
+ CD_DEFAULT, face_it->num_elements);
// step through the vertex iterators:
for (i = 0; !vertex_it->Done(vertex_it->it); i++) {
CSG_IVertex csgvert;
- MVert *mvert = CDDM_get_vert(dm, i);
+ MVert *mvert = CDDM_get_vert(result, i);
// retrieve a csg vertex from the boolean module
vertex_it->Fill(vertex_it->it, &csgvert);
@@ -371,15 +372,16 @@ static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh(
face_it->Step(face_it->it);
// find the original mesh and data
- orig_ob = (csgface.orig_face < me1->totface)? ob1: ob2;
+ orig_ob = (csgface.orig_face < dm1->getNumFaces(dm1))? ob1: ob2;
+ orig_dm = (csgface.orig_face < dm1->getNumFaces(dm1))? dm1: dm2;
orig_me = (orig_ob == ob1)? me1: me2;
- orig_index = (orig_ob == ob1)? csgface.orig_face: csgface.orig_face - me1->totface;
+ orig_index = (orig_ob == ob1)? csgface.orig_face: csgface.orig_face - dm1->getNumFaces(dm1);
// copy all face layers, including mface
- CustomData_copy_data(&orig_me->fdata, &dm->faceData, orig_index, i, 1);
+ CustomData_copy_data(&orig_dm->faceData, &result->faceData, orig_index, i, 1);
// set mface
- mface = CDDM_get_face(dm, i);
+ mface = CDDM_get_face(result, i);
mface->v1 = csgface.vertex_index[0];
mface->v2 = csgface.vertex_index[1];
mface->v3 = csgface.vertex_index[2];
@@ -400,29 +402,30 @@ static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh(
else
mface->mat_nr = 0;
- InterpCSGFace(dm, orig_me, i, orig_index, csgface.vertex_number,
+ InterpCSGFace(result, orig_dm, i, orig_index, csgface.vertex_number,
(orig_me == me2)? mapmat: NULL);
- test_index_face(mface, &dm->faceData, i, csgface.vertex_number);
+ test_index_face(mface, &result->faceData, i, csgface.vertex_number);
}
if (material_hash)
BLI_ghash_free(material_hash, NULL, NULL);
- CDDM_calc_edges(dm);
- CDDM_calc_normals(dm);
+ CDDM_calc_edges(result);
+ CDDM_calc_normals(result);
- return dm;
+ return result;
}
static void BuildMeshDescriptors(
+ struct DerivedMesh *dm,
struct Object *ob,
int face_offset,
struct CSG_FaceIteratorDescriptor * face_it,
struct CSG_VertexIteratorDescriptor * vertex_it)
{
- VertexIt_Construct(vertex_it,ob);
- FaceIt_Construct(face_it,ob,face_offset);
+ VertexIt_Construct(vertex_it,dm, ob);
+ FaceIt_Construct(face_it,dm,face_offset);
}
static void FreeMeshDescriptors(
@@ -434,19 +437,17 @@ static void FreeMeshDescriptors(
}
DerivedMesh *NewBooleanDerivedMesh_intern(
- struct Object *ob, struct Object *ob_select,
+ DerivedMesh *dm, struct Object *ob, DerivedMesh *dm_select, struct Object *ob_select,
int int_op_type, Material **mat, int *totmat)
{
float inv_mat[4][4];
float map_mat[4][4];
- DerivedMesh *dm = NULL;
- Mesh *me1 = get_mesh(ob_select);
- Mesh *me2 = get_mesh(ob);
+ DerivedMesh *result = NULL;
- if (me1 == NULL || me2 == NULL) return 0;
- if (!me1->totface || !me2->totface) return 0;
+ if (dm == NULL || dm_select == NULL) return 0;
+ if (!dm->getNumFaces(dm) || !dm_select->getNumFaces(dm_select)) return 0;
// we map the final object back into ob's local coordinate space. For this
// we need to compute the inverse transform from global to ob (inv_mat),
@@ -477,8 +478,8 @@ DerivedMesh *NewBooleanDerivedMesh_intern(
default : op_type = e_csg_intersection;
}
- BuildMeshDescriptors(ob_select, 0, &fd_1, &vd_1);
- BuildMeshDescriptors(ob, me1->totface, &fd_2, &vd_2);
+ BuildMeshDescriptors(dm_select, ob_select, 0, &fd_1, &vd_1);
+ BuildMeshDescriptors(dm, ob, dm_select->getNumFaces(dm_select) , &fd_2, &vd_2);
bool_op = CSG_NewBooleanFunction();
@@ -492,8 +493,8 @@ DerivedMesh *NewBooleanDerivedMesh_intern(
// iterate through results of operation and insert
// into new object
- dm = ConvertCSGDescriptorsToDerivedMesh(
- &fd_o, &vd_o, inv_mat, map_mat, mat, totmat, ob_select, ob);
+ result = ConvertCSGDescriptorsToDerivedMesh(
+ &fd_o, &vd_o, inv_mat, map_mat, mat, totmat, dm_select, ob_select, dm, ob);
// free up the memory
CSG_FreeVertexDescriptor(&vd_o);
@@ -508,7 +509,7 @@ DerivedMesh *NewBooleanDerivedMesh_intern(
FreeMeshDescriptors(&fd_2, &vd_2);
}
- return dm;
+ return result;
}
int NewBooleanMesh(Scene *scene, Base *base, Base *base_select, int int_op_type)
@@ -517,24 +518,30 @@ int NewBooleanMesh(Scene *scene, Base *base, Base *base_select, int int_op_type)
int a, maxmat, totmat= 0;
Object *ob_new, *ob, *ob_select;
Material **mat;
+ DerivedMesh *result;
+ DerivedMesh *dm_select;
DerivedMesh *dm;
ob= base->object;
ob_select= base_select->object;
+ dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
+ dm_select = mesh_create_derived_view(scene, ob_select, 0); // no modifiers in editmode ??
+
maxmat= ob->totcol + ob_select->totcol;
mat= (Material**)MEM_mallocN(sizeof(Material*)*maxmat, "NewBooleanMeshMat");
/* put some checks in for nice user feedback */
- if((!(get_mesh(ob)->totface)) || (!(get_mesh(ob_select)->totface)))
+ if (dm == NULL || dm_select == NULL) return 0;
+ if (!dm->getNumFaces(dm) || !dm_select->getNumFaces(dm_select))
{
MEM_freeN(mat);
return -1;
}
- dm= NewBooleanDerivedMesh_intern(ob, ob_select, int_op_type, mat, &totmat);
+ result= NewBooleanDerivedMesh_intern(dm, ob, dm_select, ob_select, int_op_type, mat, &totmat);
- if (dm == NULL) {
+ if (result == NULL) {
MEM_freeN(mat);
return 0;
}
@@ -543,8 +550,11 @@ int NewBooleanMesh(Scene *scene, Base *base, Base *base_select, int int_op_type)
ob_new= AddNewBlenderMesh(scene, base_select);
me_new= ob_new->data;
- DM_to_mesh(dm, me_new);
+ DM_to_mesh(result, me_new);
+ result->release(result);
+
dm->release(dm);
+ dm_select->release(dm_select);
/* add materials to object */
for (a = 0; a < totmat; a++)
@@ -558,9 +568,9 @@ int NewBooleanMesh(Scene *scene, Base *base, Base *base_select, int int_op_type)
return 1;
}
-DerivedMesh *NewBooleanDerivedMesh(struct Object *ob, struct Object *ob_select,
+DerivedMesh *NewBooleanDerivedMesh(DerivedMesh *dm, struct Object *ob, DerivedMesh *dm_select, struct Object *ob_select,
int int_op_type)
{
- return NewBooleanDerivedMesh_intern(ob, ob_select, int_op_type, NULL, NULL);
+ return NewBooleanDerivedMesh_intern(dm, ob, dm_select, ob_select, int_op_type, NULL, NULL);
}
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index ae449843d2a..d9e005811d0 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -30,6 +30,7 @@
#include <stdio.h>
#include <string.h>
#include <math.h>
+#include <assert.h>
#include "BKE_bvhutils.h"
@@ -45,6 +46,8 @@
#include "BKE_global.h"
#include "BLI_arithb.h"
+#include "BLI_linklist.h"
+#include "MEM_guardedalloc.h"
/* Math stuff for ray casting on mesh faces and for nearest surface */
@@ -480,30 +483,47 @@ static void mesh_faces_spherecast(void *userdata, int index, const BVHTreeRay *r
* BVH builders
*/
// Builds a bvh tree.. where nodes are the vertexs of the given mesh
-void bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis)
+BVHTree* bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis)
{
- int i;
- int numVerts= mesh->getNumVerts(mesh);
- MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT);
- BVHTree *tree = NULL;
+ BVHTree *tree = bvhcache_find(&mesh->bvhCache, BVHTREE_FROM_VERTICES);
- memset(data, 0, sizeof(*data));
+ //Not in cache
+ if(tree == NULL)
+ {
+ int i;
+ int numVerts= mesh->getNumVerts(mesh);
+ MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT);
- if(vert == NULL)
+ if(vert != NULL)
+ {
+ tree = BLI_bvhtree_new(numVerts, epsilon, tree_type, axis);
+
+ if(tree != NULL)
+ {
+ for(i = 0; i < numVerts; i++)
+ BLI_bvhtree_insert(tree, i, vert[i].co, 1);
+
+ BLI_bvhtree_balance(tree);
+
+ //Save on cache for later use
+// printf("BVHTree built and saved on cache\n");
+ bvhcache_insert(&mesh->bvhCache, tree, BVHTREE_FROM_VERTICES);
+ }
+ }
+ }
+ else
{
- printf("bvhtree cant be build: cant get a vertex array");
- return;
+// printf("BVHTree is already build, using cached tree\n");
}
- tree = BLI_bvhtree_new(numVerts, epsilon, tree_type, axis);
- if(tree != NULL)
- {
- for(i = 0; i < numVerts; i++)
- BLI_bvhtree_insert(tree, i, vert[i].co, 1);
- BLI_bvhtree_balance(tree);
+ //Setup BVHTreeFromMesh
+ memset(data, 0, sizeof(*data));
+ data->tree = tree;
- data->tree = tree;
+ if(data->tree)
+ {
+ data->cached = TRUE;
//a NULL nearest callback works fine
//remeber the min distance to point is the same as the min distance to BV of point
@@ -516,43 +536,62 @@ void bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *mesh, float eps
data->sphere_radius = epsilon;
}
+
+ return data->tree;
}
// Builds a bvh tree.. where nodes are the faces of the given mesh.
-void bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis)
+BVHTree* bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis)
{
- int i;
- int numFaces= mesh->getNumFaces(mesh);
- MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT);
- MFace *face = mesh->getFaceDataArray(mesh, CD_MFACE);
- BVHTree *tree = NULL;
-
- memset(data, 0, sizeof(*data));
+ BVHTree *tree = bvhcache_find(&mesh->bvhCache, BVHTREE_FROM_FACES);
- if(vert == NULL && face == NULL)
+ //Not in cache
+ if(tree == NULL)
{
- printf("bvhtree cant be build: cant get a vertex/face array");
- return;
- }
+ int i;
+ int numFaces= mesh->getNumFaces(mesh);
+ MVert *vert = mesh->getVertDataArray(mesh, CD_MVERT);
+ MFace *face = mesh->getFaceDataArray(mesh, CD_MFACE);
- /* Create a bvh-tree of the given target */
- tree = BLI_bvhtree_new(numFaces, epsilon, tree_type, axis);
- if(tree != NULL)
- {
- for(i = 0; i < numFaces; i++)
+ if(vert != NULL && face != NULL)
{
- float co[4][3];
- VECCOPY(co[0], vert[ face[i].v1 ].co);
- VECCOPY(co[1], vert[ face[i].v2 ].co);
- VECCOPY(co[2], vert[ face[i].v3 ].co);
- if(face[i].v4)
- VECCOPY(co[3], vert[ face[i].v4 ].co);
+ /* Create a bvh-tree of the given target */
+ tree = BLI_bvhtree_new(numFaces, epsilon, tree_type, axis);
+ if(tree != NULL)
+ {
+ for(i = 0; i < numFaces; i++)
+ {
+ float co[4][3];
+ VECCOPY(co[0], vert[ face[i].v1 ].co);
+ VECCOPY(co[1], vert[ face[i].v2 ].co);
+ VECCOPY(co[2], vert[ face[i].v3 ].co);
+ if(face[i].v4)
+ VECCOPY(co[3], vert[ face[i].v4 ].co);
- BLI_bvhtree_insert(tree, i, co[0], face[i].v4 ? 4 : 3);
+ BLI_bvhtree_insert(tree, i, co[0], face[i].v4 ? 4 : 3);
+ }
+ BLI_bvhtree_balance(tree);
+
+ //Save on cache for later use
+// printf("BVHTree built and saved on cache\n");
+ bvhcache_insert(&mesh->bvhCache, tree, BVHTREE_FROM_FACES);
+ }
}
- BLI_bvhtree_balance(tree);
+ }
+ else
+ {
+// printf("BVHTree is already build, using cached tree\n");
+ }
+
+
+ //Setup BVHTreeFromMesh
+ memset(data, 0, sizeof(*data));
+ data->tree = tree;
+
+ if(data->tree)
+ {
+ data->cached = TRUE;
- data->tree = tree;
data->nearest_callback = mesh_faces_nearest_point;
data->raycast_callback = mesh_faces_spherecast;
@@ -562,6 +601,8 @@ void bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float eps
data->sphere_radius = epsilon;
}
+ return data->tree;
+
}
// Frees data allocated by a call to bvhtree_from_mesh_*.
@@ -569,9 +610,78 @@ void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data)
{
if(data->tree)
{
- BLI_bvhtree_free(data->tree);
+ if(!data->cached)
+ BLI_bvhtree_free(data->tree);
+
memset( data, 0, sizeof(data) );
}
}
+/* BVHCache */
+typedef struct BVHCacheItem
+{
+ int type;
+ BVHTree *tree;
+
+} BVHCacheItem;
+
+static void bvhcacheitem_set_if_match(void *_cached, void *_search)
+{
+ BVHCacheItem * cached = (BVHCacheItem *)_cached;
+ BVHCacheItem * search = (BVHCacheItem *)_search;
+
+ if(search->type == cached->type)
+ {
+ search->tree = cached->tree;
+ }
+}
+
+BVHTree *bvhcache_find(BVHCache *cache, int type)
+{
+ BVHCacheItem item;
+ item.type = type;
+ item.tree = NULL;
+
+ BLI_linklist_apply(*cache, bvhcacheitem_set_if_match, &item);
+ return item.tree;
+}
+
+void bvhcache_insert(BVHCache *cache, BVHTree *tree, int type)
+{
+ BVHCacheItem *item = NULL;
+
+ assert( tree != NULL );
+ assert( bvhcache_find(cache, type) == NULL );
+
+ item = MEM_mallocN(sizeof(BVHCacheItem), "BVHCacheItem");
+ assert( item != NULL );
+
+ item->type = type;
+ item->tree = tree;
+
+ BLI_linklist_prepend( cache, item );
+}
+
+
+void bvhcache_init(BVHCache *cache)
+{
+ *cache = NULL;
+}
+
+static void bvhcacheitem_free(void *_item)
+{
+ BVHCacheItem *item = (BVHCacheItem *)_item;
+
+ BLI_bvhtree_free(item->tree);
+ MEM_freeN(item);
+}
+
+
+void bvhcache_free(BVHCache *cache)
+{
+ BLI_linklist_free(*cache, (LinkNodeFreeFP)bvhcacheitem_free);
+ *cache = NULL;
+}
+
+
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 7476d2f5fda..ecdf0e78df2 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -483,10 +483,14 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
MVert *mv = cddm->mvert;
MFace *mf = cddm->mface;
- MCol *mc = DM_get_face_data_layer(dm, CD_MCOL);
+ MCol *mc;
float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
+ mc = DM_get_face_data_layer(dm, CD_WEIGHT_MCOL);
+ if(!mc)
+ mc = DM_get_face_data_layer(dm, CD_MCOL);
+
for(i = 0; i < dm->numFaceData; i++, mf++) {
int drawSmooth = (mf->flag & ME_SMOOTH);
@@ -927,13 +931,6 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob)
index = CustomData_get_layer(&dm->faceData, CD_ORIGINDEX);
for(i = 0; i < mesh->totface; ++i, ++index)
*index = i;
-
- /* works in conjunction with hack during modifier calc, where active mcol
- layer with weight paint colors is temporarily added */
- /* XXX make this real but temporary layer */
-// if ((G.f & G_WEIGHTPAINT) &&
-// (ob && ob==(scene->basact?scene->basact->object:NULL)))
-// CustomData_duplicate_referenced_layer(&dm->faceData, CD_MCOL);
return dm;
}
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 1bc34aea9a1..e8716aba296 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -32,6 +32,10 @@
#include <stdlib.h>
#include <float.h>
+#ifdef WITH_LCMS
+#include <lcms.h>
+#endif
+
#include "MEM_guardedalloc.h"
#include "DNA_color_types.h"
@@ -650,6 +654,38 @@ void curvemapping_evaluate_premulRGBF(CurveMapping *cumap, float *vecout, const
vecout[2]= curvemap_evaluateF(cumap->cm+2, fac);
}
+void colorcorrection_do_ibuf(ImBuf *ibuf, const char *profile)
+{
+ if (ibuf->crect == NULL)
+ {
+#ifdef WITH_LCMS
+ cmsHPROFILE imageProfile, proofingProfile;
+ cmsHTRANSFORM hTransform;
+
+ ibuf->crect = MEM_mallocN(ibuf->x*ibuf->y*sizeof(int), "imbuf crect");
+
+ imageProfile = cmsCreate_sRGBProfile();
+ proofingProfile = cmsOpenProfileFromFile(profile, "r");
+
+ cmsErrorAction(LCMS_ERROR_SHOW);
+
+ hTransform = cmsCreateProofingTransform(imageProfile, TYPE_RGBA_8, imageProfile, TYPE_RGBA_8,
+ proofingProfile,
+ INTENT_ABSOLUTE_COLORIMETRIC,
+ INTENT_ABSOLUTE_COLORIMETRIC,
+ cmsFLAGS_SOFTPROOFING);
+
+ cmsDoTransform(hTransform, ibuf->rect, ibuf->crect, ibuf->x * ibuf->y);
+
+ cmsDeleteTransform(hTransform);
+ cmsCloseProfile(imageProfile);
+ cmsCloseProfile(proofingProfile);
+#else
+ ibuf->crect = ibuf->rect;
+#endif
+ }
+}
+
void curvemapping_do_ibuf(CurveMapping *cumap, ImBuf *ibuf)
{
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 5adbcadcf39..25fc7bd3b4f 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -34,7 +34,6 @@
#include <float.h>
#include "MEM_guardedalloc.h"
-//XXX #include "nla.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
@@ -42,6 +41,7 @@
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_action_types.h"
#include "DNA_curve_types.h"
@@ -67,6 +67,8 @@
#include "BKE_library.h"
#include "BKE_idprop.h"
#include "BKE_mesh.h"
+#include "BKE_shrinkwrap.h"
+#include "BKE_mesh.h"
#ifndef DISABLE_PYTHON
#include "BPY_extern.h"
@@ -95,7 +97,7 @@
/* Find the first available, non-duplicate name for a given constraint */
void unique_constraint_name (bConstraint *con, ListBase *list)
{
- BLI_uniquename(list, con, "Const", offsetof(bConstraint, name), 32);
+ BLI_uniquename(list, con, "Const", '.', offsetof(bConstraint, name), 32);
}
/* ----------------- Evaluation Loop Preparation --------------- */
@@ -389,15 +391,16 @@ void constraint_mat_convertspace (Object *ob, bPoseChannel *pchan, float mat[][4
/* ------------ General Target Matrix Tools ---------- */
/* function that sets the given matrix based on given vertex group in mesh */
-static void contarget_get_mesh_mat (Object *ob, char *substring, float mat[][4])
+static void contarget_get_mesh_mat (Scene *scene, Object *ob, char *substring, float mat[][4])
{
DerivedMesh *dm;
Mesh *me= ob->data;
- EditMesh *em = EM_GetEditMesh(me);
+ EditMesh *em = BKE_mesh_get_editmesh(me);
float vec[3] = {0.0f, 0.0f, 0.0f}, tvec[3];
float normal[3] = {0.0f, 0.0f, 0.0f}, plane[3];
float imat[3][3], tmat[3][3];
int dgroup;
+ short freeDM = 0;
/* initialize target matrix using target matrix */
Mat4CpyMat4(mat, ob->obmat);
@@ -410,10 +413,19 @@ static void contarget_get_mesh_mat (Object *ob, char *substring, float mat[][4])
if (em) {
/* target is in editmode, so get a special derived mesh */
dm = CDDM_from_editmesh(em, ob->data);
+ freeDM= 1;
}
else {
- /* when not in EditMode, this should exist */
- dm = (DerivedMesh *)ob->derivedFinal;
+ /* when not in EditMode, use the 'final' derived mesh
+ * - check if the custom data masks for derivedFinal mean that we can just use that
+ * (this is more effficient + sufficient for most cases)
+ */
+ if (ob->lastDataMask != CD_MASK_DERIVEDMESH) {
+ dm = mesh_get_derived_final(scene, ob, CD_MASK_DERIVEDMESH);
+ freeDM= 1;
+ }
+ else
+ dm = (DerivedMesh *)ob->derivedFinal;
}
/* only continue if there's a valid DerivedMesh */
@@ -479,10 +491,10 @@ static void contarget_get_mesh_mat (Object *ob, char *substring, float mat[][4])
}
/* free temporary DerivedMesh created (in EditMode case) */
- if (em) {
- if (dm) dm->release(dm);
- EM_EndEditMesh(me, em);
- }
+ if (dm && freeDM)
+ dm->release(dm);
+ if (em)
+ BKE_mesh_end_editmesh(me, em);
}
/* function that sets the given matrix based on given vertex group in lattice */
@@ -544,7 +556,7 @@ static void contarget_get_lattice_mat (Object *ob, char *substring, float mat[][
/* generic function to get the appropriate matrix for most target cases */
/* The cases where the target can be object data have not been implemented */
-static void constraint_target_to_mat4 (Object *ob, char *substring, float mat[][4], short from, short to, float headtail)
+static void constraint_target_to_mat4 (Scene *scene, Object *ob, char *substring, float mat[][4], short from, short to, float headtail)
{
/* Case OBJECT */
if (!strlen(substring)) {
@@ -561,7 +573,7 @@ static void constraint_target_to_mat4 (Object *ob, char *substring, float mat[][
* way as constraints can only really affect things on object/bone level.
*/
else if (ob->type == OB_MESH) {
- contarget_get_mesh_mat(ob, substring, mat);
+ contarget_get_mesh_mat(scene, ob, substring, mat);
constraint_mat_convertspace(ob, NULL, mat, from, to);
}
else if (ob->type == OB_LATTICE) {
@@ -643,7 +655,7 @@ static bConstraintTypeInfo CTI_CONSTRNAME = {
static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
{
if (VALID_CONS_TARGET(ct))
- constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
+ constraint_target_to_mat4(cob->scene, ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
else if (ct)
Mat4One(ct->matrix);
}
@@ -1058,7 +1070,7 @@ static void kinematic_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstra
bKinematicConstraint *data= con->data;
if (VALID_CONS_TARGET(ct))
- constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
+ constraint_target_to_mat4(cob->scene, ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
else if (ct) {
if (data->flag & CONSTRAINT_IK_AUTO) {
Object *ob= cob->ob;
@@ -1748,7 +1760,7 @@ static void pycon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintT
/* firstly calculate the matrix the normal way, then let the py-function override
* this matrix if it needs to do so
*/
- constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
+ constraint_target_to_mat4(cob->scene, ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
/* only execute target calculation if allowed */
#ifndef DISABLE_PYTHON
@@ -1855,7 +1867,7 @@ static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraint
Mat4One(ct->matrix);
/* get the transform matrix of the target */
- constraint_target_to_mat4(ct->tar, ct->subtarget, tempmat, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
+ constraint_target_to_mat4(cob->scene, ct->tar, ct->subtarget, tempmat, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
/* determine where in transform range target is */
/* data->type is mapped as follows for backwards compatability:
@@ -1891,7 +1903,6 @@ static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraint
printf("do Action Constraint %s - Ob %s Pchan %s \n", con->name, cob->ob->id.name+2, (cob->pchan)?cob->pchan->name:NULL);
/* Get the appropriate information from the action */
- // XXX probably we might need some special filtering methods to make this more efficient
if (cob->type == CONSTRAINT_OBTYPE_BONE) {
Object workob;
bPose *pose;
@@ -1905,8 +1916,7 @@ static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraint
tchan= verify_pose_channel(pose, pchan->name);
/* evaluate action using workob (it will only set the PoseChannel in question) */
- // XXX we need some flags to prevent evaluation from setting disabled flags on all other settings
- what_does_obaction(cob->scene, cob->ob, &workob, pose, data->act, t);
+ what_does_obaction(cob->scene, cob->ob, &workob, pose, data->act, pchan->name, t);
/* convert animation to matrices for use here */
chan_calc_mat(tchan);
@@ -1919,7 +1929,8 @@ static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraint
Object workob;
/* evaluate using workob */
- what_does_obaction(cob->scene, cob->ob, &workob, NULL, data->act, t);
+ // FIXME: we don't have any consistent standards on limiting effects on object...
+ what_does_obaction(cob->scene, cob->ob, &workob, NULL, data->act, NULL, t);
object_to_mat4(&workob, ct->matrix);
}
else {
@@ -3111,6 +3122,165 @@ static bConstraintTypeInfo CTI_TRANSFORM = {
transform_evaluate /* evaluate */
};
+/* ---------- Shrinkwrap Constraint ----------- */
+
+static int shrinkwrap_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bShrinkwrapConstraint *data = con->data;
+ bConstraintTarget *ct;
+
+ SINGLETARGETNS_GET_TARS(con, data->target, ct, list)
+
+ return 1;
+ }
+
+ return 0;
+}
+
+
+static void shrinkwrap_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+ if (con && list) {
+ bShrinkwrapConstraint *data = con->data;
+ bConstraintTarget *ct= list->first;
+
+ SINGLETARGETNS_FLUSH_TARS(con, data->target, ct, list, nocopy)
+ }
+}
+
+
+static void shrinkwrap_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
+{
+ bShrinkwrapConstraint *scon = (bShrinkwrapConstraint *) con->data;
+
+ if( VALID_CONS_TARGET(ct) && (ct->tar->type == OB_MESH) )
+ {
+ int fail = FALSE;
+ float co[3] = {0.0f, 0.0f, 0.0f};
+ float no[3] = {0.0f, 0.0f, 0.0f};
+ float dist;
+
+ SpaceTransform transform;
+ DerivedMesh *target = object_get_derived_final(cob->scene, ct->tar, CD_MASK_BAREMESH);
+ BVHTreeRayHit hit;
+ BVHTreeNearest nearest;
+
+ BVHTreeFromMesh treeData;
+ memset( &treeData, 0, sizeof(treeData) );
+
+ nearest.index = -1;
+ nearest.dist = FLT_MAX;
+
+ hit.index = -1;
+ hit.dist = 100000.0f; //TODO should use FLT_MAX.. but normal projection doenst yet supports it
+
+ Mat4One(ct->matrix);
+
+ if(target != NULL)
+ {
+ space_transform_from_matrixs(&transform, cob->matrix, ct->tar->obmat);
+
+ switch(scon->shrinkType)
+ {
+ case MOD_SHRINKWRAP_NEAREST_SURFACE:
+ case MOD_SHRINKWRAP_NEAREST_VERTEX:
+
+ if(scon->shrinkType == MOD_SHRINKWRAP_NEAREST_VERTEX)
+ bvhtree_from_mesh_verts(&treeData, target, 0.0, 2, 6);
+ else
+ bvhtree_from_mesh_faces(&treeData, target, 0.0, 2, 6);
+
+ if(treeData.tree == NULL)
+ {
+ fail = TRUE;
+ break;
+ }
+
+ space_transform_apply(&transform, co);
+
+ BLI_bvhtree_find_nearest(treeData.tree, co, &nearest, treeData.nearest_callback, &treeData);
+
+ dist = VecLenf(co, nearest.co);
+ VecLerpf(co, co, nearest.co, (dist - scon->dist)/dist); /* linear interpolation */
+ space_transform_invert(&transform, co);
+ break;
+
+ case MOD_SHRINKWRAP_PROJECT:
+ if(scon->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_X_AXIS) no[0] = 1.0f;
+ if(scon->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Y_AXIS) no[1] = 1.0f;
+ if(scon->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS) no[2] = 1.0f;
+
+ if(INPR(no,no) < FLT_EPSILON)
+ {
+ fail = TRUE;
+ break;
+ }
+
+ Normalize(no);
+
+
+ bvhtree_from_mesh_faces(&treeData, target, scon->dist, 4, 6);
+ if(treeData.tree == NULL)
+ {
+ fail = TRUE;
+ break;
+ }
+
+ if(normal_projection_project_vertex(0, co, no, &transform, treeData.tree, &hit, treeData.raycast_callback, &treeData) == FALSE)
+ {
+ fail = TRUE;
+ break;
+ }
+ VECCOPY(co, hit.co);
+ break;
+ }
+
+ free_bvhtree_from_mesh(&treeData);
+
+ target->release(target);
+
+ if(fail == TRUE)
+ {
+ /* Don't move the point */
+ co[0] = co[1] = co[2] = 0.0f;
+ }
+
+ /* co is in local object coordinates, change it to global and update target position */
+ VecMat4MulVecfl(co, cob->matrix, co);
+ VECCOPY(ct->matrix[3], co);
+ }
+ }
+}
+
+static void shrinkwrap_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bConstraintTarget *ct= targets->first;
+
+ /* only evaluate if there is a target */
+ if (VALID_CONS_TARGET(ct))
+ {
+ VECCOPY(cob->matrix[3], ct->matrix[3]);
+ }
+}
+
+static bConstraintTypeInfo CTI_SHRINKWRAP = {
+ CONSTRAINT_TYPE_SHRINKWRAP, /* type */
+ sizeof(bShrinkwrapConstraint), /* size */
+ "Shrinkwrap", /* name */
+ "bShrinkwrapConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ NULL, /* new data */
+ shrinkwrap_get_tars, /* get constraint targets */
+ shrinkwrap_flush_tars, /* flush constraint targets */
+ shrinkwrap_get_tarmat, /* get a target matrix */
+ shrinkwrap_evaluate /* evaluate */
+};
+
+
+
/* ************************* Constraints Type-Info *************************** */
/* All of the constraints api functions use bConstraintTypeInfo structs to carry out
* and operations that involve constraint specific code.
@@ -3142,6 +3312,7 @@ static void constraints_init_typeinfo () {
constraintsTypeInfo[17]= &CTI_RIGIDBODYJOINT; /* RigidBody Constraint */
constraintsTypeInfo[18]= &CTI_CLAMPTO; /* ClampTo Constraint */
constraintsTypeInfo[19]= &CTI_TRANSFORM; /* Transformation Constraint */
+ constraintsTypeInfo[20]= &CTI_SHRINKWRAP; /* Shrinkwrap Constraint */
}
/* This function should be used for getting the appropriate type-info when only
@@ -3204,17 +3375,16 @@ void free_constraint_data (bConstraint *con)
}
/* Free all constraints from a constraint-stack */
-void free_constraints (ListBase *conlist)
+void free_constraints (ListBase *list)
{
bConstraint *con;
/* Free constraint data and also any extra data */
- for (con= conlist->first; con; con= con->next) {
+ for (con= list->first; con; con= con->next)
free_constraint_data(con);
- }
/* Free the whole list */
- BLI_freelistN(conlist);
+ BLI_freelistN(list);
}
/* Reassign links that constraints have to other data (called during file loading?) */
@@ -3267,6 +3437,23 @@ void copy_constraints (ListBase *dst, ListBase *src)
}
}
+/* finds the 'active' constraint in a constraint stack */
+bConstraint *constraints_get_active (ListBase *list)
+{
+ bConstraint *con;
+
+ /* search for the first constraint with the 'active' flag set */
+ if (list) {
+ for (con= list->first; con; con= con->next) {
+ if (con->flag & CONSTRAINT_ACTIVE)
+ return con;
+ }
+ }
+
+ /* no active constraint found */
+ return NULL;
+}
+
/* -------- Constraints and Proxies ------- */
/* Rescue all constraints tagged as being CONSTRAINT_PROXY_LOCAL (i.e. added to bone that's proxy-synced in this file) */
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 47622611cb9..9d2830983e1 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -41,7 +41,6 @@
#include "BKE_context.h"
#include "BKE_main.h"
-#include "BKE_report.h"
#include "BKE_screen.h"
#include <string.h>
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 30cb4016061..fab9669d55f 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -591,8 +591,8 @@ static void makecyclicknots(float *knots, short pnts, short order)
}
-/* type - 0: uniform, 1: endpoints, 2: bezier, note, cyclic nurbs are always uniform */
-void makeknots(Nurb *nu, short uv, short type)
+
+void makeknots(Nurb *nu, short uv)
{
if( (nu->type & 7)==CU_NURBS ) {
if(uv == 1) {
@@ -603,7 +603,7 @@ void makeknots(Nurb *nu, short uv, short type)
calcknots(nu->knotsu, nu->pntsu, nu->orderu, 0); /* cyclic should be uniform */
makecyclicknots(nu->knotsu, nu->pntsu, nu->orderu);
} else {
- calcknots(nu->knotsu, nu->pntsu, nu->orderu, type);
+ calcknots(nu->knotsu, nu->pntsu, nu->orderu, nu->flagu>>1);
}
}
else nu->knotsu= NULL;
@@ -616,7 +616,7 @@ void makeknots(Nurb *nu, short uv, short type)
calcknots(nu->knotsv, nu->pntsv, nu->orderv, 0); /* cyclic should be uniform */
makecyclicknots(nu->knotsv, nu->pntsv, nu->orderv);
} else {
- calcknots(nu->knotsv, nu->pntsv, nu->orderv, type);
+ calcknots(nu->knotsv, nu->pntsv, nu->orderv, nu->flagv>>1);
}
}
else nu->knotsv= NULL;
@@ -1572,8 +1572,8 @@ void makeBevelList(Object *ob)
while(nu) {
/* check if we will calculate tilt data */
- do_tilt = ((nu->type & CU_2D) && (cu->flag & CU_3D)==0) ? 0 : 1;
- do_radius = (do_tilt || cu->bevobj) ? 1 : 0; /* normal display uses the radius, better just to calculate them */
+ do_tilt = CU_DO_TILT(cu, nu);
+ do_radius = CU_DO_RADIUS(cu, nu); /* normal display uses the radius, better just to calculate them */
/* check we are a single point? also check we are not a surface and that the orderu is sane,
* enforced in the UI but can go wrong possibly */
@@ -2370,7 +2370,7 @@ void sethandlesNurb(ListBase *editnurb, short code)
if(code==1 || code==2) {
nu= editnurb->first;
while(nu) {
- if( (nu->type & 7)==1) {
+ if( (nu->type & 7)==CU_BEZIER) {
bezt= nu->bezt;
a= nu->pntsu;
while(a--) {
@@ -2400,7 +2400,7 @@ void sethandlesNurb(ListBase *editnurb, short code)
} else {
/* Toggle */
while(nu) {
- if( (nu->type & 7)==1) {
+ if( (nu->type & 7)==CU_BEZIER) {
bezt= nu->bezt;
a= nu->pntsu;
while(a--) {
@@ -2417,7 +2417,7 @@ void sethandlesNurb(ListBase *editnurb, short code)
}
nu= editnurb->first;
while(nu) {
- if( (nu->type & 7)==1) {
+ if( (nu->type & 7)==CU_BEZIER) {
bezt= nu->bezt;
a= nu->pntsu;
while(a--) {
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index daac8b71dd1..35f0b4b087c 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -708,14 +708,16 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol},
{sizeof(float)*3*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
{sizeof(MDisps), "MDisps", 1, NULL, layerCopy_mdisps,
- layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL}
+ layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL},
+ {sizeof(MCol)*4, "MCol", 4, "WeightCol", NULL, NULL, layerInterp_mcol,
+ layerSwap_mcol, layerDefault_mcol},
};
const char *LAYERTYPENAMES[CD_NUMTYPES] = {
"CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
"CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty",
"CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV",
- "CDMloopCol", "CDTangent", "CDMDisps"};
+ "CDMloopCol", "CDTangent", "CDMDisps", "CDWeightMCol"};
const CustomDataMask CD_MASK_BAREMESH =
CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE;
@@ -729,7 +731,7 @@ const CustomDataMask CD_MASK_EDITMESH =
const CustomDataMask CD_MASK_DERIVEDMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
- CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT;
+ CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT | CD_MASK_WEIGHT_MCOL;
const CustomDataMask CD_MASK_BMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
const CustomDataMask CD_MASK_FACECORNERS =
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 917fb7d1de4..dfe3b7ea279 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -33,8 +33,6 @@
#include "BLI_winstuff.h"
#endif
-//#include "BMF_Api.h"
-
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
@@ -312,62 +310,29 @@ static void dag_add_driver_relation(AnimData *adt, DagForest *dag, DagNode *node
for (fcu= adt->drivers.first; fcu; fcu= fcu->next) {
ChannelDriver *driver= fcu->driver;
+ DriverTarget *dtar;
- if (driver->type == DRIVER_TYPE_PYTHON) {
- /* PyDriver / 'Expression' */
-
- /* skip if invalid in some way */
- if ((driver->flag & DRIVER_FLAG_INVALID) || (driver->expression[0] == '\0'))
- continue;
-#ifndef DISABLE_PYTHON
- else {
- /* now we need refs to all objects mentioned in this
- * pydriver expression, to call 'dag_add_relation'
- * for each of them */
- Object **obarray = NULL; // XXX BPY_pydriver_get_objects(fcu->driver);
- if (obarray) {
- Object *ob, **oba = obarray;
+ /* loop over targets, adding relationships as appropriate */
+ for (dtar= driver->targets.first; dtar; dtar= dtar->next) {
+ if (dtar->id) {
+ if (GS(dtar->id->name)==ID_OB) {
+ Object *ob= (Object *)dtar->id;
- while (*oba) {
- ob = *oba;
- node1 = dag_get_node(dag, ob);
- if (ob->type == OB_ARMATURE)
- dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Python Driver");
- else
- dag_add_relation(dag, node1, node, isdata?DAG_RL_OB_DATA:DAG_RL_OB_OB, "Python Driver");
- oba++;
- }
+ /* normal channel-drives-channel */
+ node1 = dag_get_node(dag, dtar->id);
- MEM_freeN(obarray);
+ /* check if bone... */
+ if ((ob->type==OB_ARMATURE) && dtar->rna_path && strstr(dtar->rna_path, "pose.pose_channels["))
+ dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Driver");
+ /* check if ob data */
+ else if (dtar->rna_path && strstr(dtar->rna_path, "data."))
+ dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Driver");
+ /* normal */
+ else
+ dag_add_relation(dag, node1, node, isdata?DAG_RL_OB_DATA:DAG_RL_OB_OB, "Driver");
}
}
-#endif /* DISABLE_PYTHON */
- }
- else if (driver->type == DRIVER_TYPE_ROTDIFF) {
- // XXX rotational difference
}
- else if (driver->id) {
- if(GS(driver->id->name)==ID_OB) {
- /* normal channel-drives-channel */
- node1 = dag_get_node(dag, driver->id);
-
- // XXX how to find out rnapath is bone?
- if( ((Object *)driver->id)->type==OB_ARMATURE )
- dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Ipo Driver");
- else
- dag_add_relation(dag, node1, node, isdata?DAG_RL_OB_DATA:DAG_RL_OB_OB, "Ipo Driver");
- }
- }
-#if 0 // XXX old 'normal' type
-
- else if (icu->driver->ob) {
- node1 = dag_get_node(dag, icu->driver->ob);
- if(icu->driver->blocktype==ID_AR)
- dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB, "Ipo Driver");
- else
- dag_add_relation(dag, node1, node, isdata?DAG_RL_OB_DATA:DAG_RL_OB_OB, "Ipo Driver");
- }
-#endif // XXX old 'normal' type
}
}
@@ -447,35 +412,10 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
/* driver dependencies, nla modifiers */
#if 0 // XXX old animation system
- if(ob->ipo)
- dag_add_driver_relation(ob->ipo, dag, node, 0);
-
- key= ob_get_key(ob);
- if(key && key->ipo)
- dag_add_driver_relation(key->ipo, dag, node, 1);
-
- for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next)
- if(conchan->ipo)
- dag_add_driver_relation(conchan->ipo, dag, node, 0);
-
- if(ob->action) {
- bActionChannel *chan;
- for (chan = ob->action->chanbase.first; chan; chan=chan->next){
- if(chan->ipo)
- dag_add_driver_relation(chan->ipo, dag, node, 1);
- for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next)
- if(conchan->ipo)
- dag_add_driver_relation(conchan->ipo, dag, node, 1);
- }
- }
if(ob->nlastrips.first) {
bActionStrip *strip;
bActionChannel *chan;
for(strip= ob->nlastrips.first; strip; strip= strip->next) {
- if(strip->act && strip->act!=ob->action)
- for (chan = strip->act->chanbase.first; chan; chan=chan->next)
- if(chan->ipo)
- dag_add_driver_relation(chan->ipo, dag, node, 1);
if(strip->modifiers.first) {
bActionModifier *amod;
for(amod= strip->modifiers.first; amod; amod= amod->next) {
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 5217464c2c9..077a0c437d4 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -299,24 +299,22 @@ static float wind_func(struct RNG *rng, float strength)
return ret;
}
-
+/* maxdist: zero effect from this distance outwards (if usemax) */
+/* mindist: full effect up to this distance (if usemin) */
+/* power: falloff with formula 1/r^power */
static float falloff_func(float fac, int usemin, float mindist, int usemax, float maxdist, float power)
{
- if(!usemin)
- mindist= 0.0f;
+ /* first quick checks */
+ if(usemax && fac > maxdist)
+ return 0.0f;
- if(fac < mindist) {
+ if(usemin && fac < mindist)
return 1.0f;
- }
- else if(usemax) {
- if(fac>maxdist || (maxdist-mindist)<=0.0f)
- return 0.0f;
- fac= (fac-mindist)/(maxdist-mindist);
- return 1.0f - (float)pow((double)fac, (double)power);
- }
- else
- return pow((double)1.0f+fac-mindist, (double)-power);
+ if(!usemin)
+ mindist = 0.0;
+
+ return pow((double)1.0+fac-mindist, (double)-power);
}
static float falloff_func_dist(PartDeflect *pd, float fac)
@@ -443,14 +441,11 @@ void do_physical_effector(Scene *scene, Object *ob, float *opco, short type, flo
else
VecCopyf(mag_vec,vec_to_part);
- Normalize(mag_vec);
-
VecMulf(mag_vec,force_val*falloff);
VecSubf(field,field,mag_vec);
VecCopyf(mag_vec,velocity);
- /* 1.9 is an experimental value to get critical damping at damp=1.0 */
- VecMulf(mag_vec,damp*1.9f*(float)sqrt(force_val));
+ VecMulf(mag_vec,damp*2.0f*(float)sqrt(force_val));
VecSubf(field,field,mag_vec);
break;
case PFIELD_CHARGE:
diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c
index 660a02bcb9e..5488d50e226 100644
--- a/source/blender/blenkernel/intern/exotic.c
+++ b/source/blender/blenkernel/intern/exotic.c
@@ -2388,7 +2388,7 @@ void write_stl(Scene *scene, char *str)
static void write_videoscape_mesh(Scene *scene, Object *ob, char *str)
{
Mesh *me= ob->data;
- EditMesh *em = EM_GetEditMesh(me);
+ EditMesh *em = BKE_mesh_get_editmesh(me);
Material *ma;
MFace *mface;
FILE *fp;
@@ -2490,7 +2490,7 @@ static void write_videoscape_mesh(Scene *scene, Object *ob, char *str)
fclose(fp);
- if (em) EM_EndEditMesh(me, em);
+ if (em) BKE_mesh_end_editmesh(me, em);
}
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 2dfa1db171f..fed5ffc2ebd 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -5,6 +5,7 @@
#include <math.h>
#include <stdio.h>
+#include <stddef.h>
#include <string.h>
#include <float.h>
@@ -18,6 +19,7 @@
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
+#include "BLI_noise.h"
#include "BKE_fcurve.h"
#include "BKE_curve.h"
@@ -98,7 +100,9 @@ FCurve *copy_fcurve (FCurve *fcu)
/* make a copy */
fcu_d= MEM_dupallocN(fcu);
+
fcu_d->next= fcu_d->prev= NULL;
+ fcu_d->grp= NULL;
/* copy curve data */
fcu_d->bezt= MEM_dupallocN(fcu_d->bezt);
@@ -171,13 +175,27 @@ FCurve *list_find_fcurve (ListBase *list, const char rna_path[], const int array
return NULL;
}
+short on_keyframe_fcurve(FCurve *fcu, float cfra)
+{
+ BezTriple *bezt;
+ unsigned i;
+
+ bezt= fcu->bezt;
+ for (i=0; i<fcu->totvert; i++, bezt++) {
+ if (IS_EQ(bezt->vec[1][0], cfra))
+ return 1;
+ }
+
+ return 0;
+}
+
/* Calculate the extents of F-Curve's data */
void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax)
{
float xminv=999999999.0f, xmaxv=-999999999.0f;
float yminv=999999999.0f, ymaxv=-999999999.0f;
short foundvert=0;
- int i;
+ unsigned int i;
if (fcu->totvert) {
if (fcu->bezt) {
@@ -192,8 +210,10 @@ void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
BezTriple *bezt;
for (bezt=fcu->bezt, i=0; i < fcu->totvert; bezt++, i++) {
- yminv= MIN2(yminv, bezt->vec[1][1]);
- ymaxv= MAX2(ymaxv, bezt->vec[1][1]);
+ if (bezt->vec[1][1] < yminv)
+ yminv= bezt->vec[1][1];
+ if (bezt->vec[1][1] > ymaxv)
+ ymaxv= bezt->vec[1][1];
}
}
}
@@ -209,8 +229,10 @@ void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
FPoint *fpt;
for (fpt=fcu->fpt, i=0; i < fcu->totvert; fpt++, i++) {
- yminv= MIN2(yminv, fpt->vec[1]);
- ymaxv= MAX2(ymaxv, fpt->vec[1]);
+ if (fpt->vec[1] < yminv)
+ yminv= fpt->vec[1];
+ if (fpt->vec[1] > ymaxv)
+ ymaxv= fpt->vec[1];
}
}
}
@@ -418,7 +440,7 @@ void calchandles_fcurve (FCurve *fcu)
void testhandles_fcurve (FCurve *fcu)
{
BezTriple *bezt;
- int a;
+ unsigned int a;
/* only beztriples have handles (bpoints don't though) */
if ELEM(NULL, fcu, fcu->bezt)
@@ -475,7 +497,7 @@ void sort_time_fcurve (FCurve *fcu)
/* currently, will only be needed when there are beztriples */
if (fcu->bezt) {
BezTriple *bezt;
- int a;
+ unsigned int a;
/* loop over ALL points to adjust position in array and recalculate handles */
for (a=0, bezt=fcu->bezt; a < fcu->totvert; a++, bezt++) {
@@ -509,7 +531,7 @@ void sort_time_fcurve (FCurve *fcu)
/* This function tests if any BezTriples are out of order, thus requiring a sort */
short test_time_fcurve (FCurve *fcu)
{
- int a;
+ unsigned int a;
/* sanity checks */
if (fcu == NULL)
@@ -543,19 +565,61 @@ short test_time_fcurve (FCurve *fcu)
/* Driver API --------------------------------- */
+/* This frees the driver target itself */
+void driver_free_target (ChannelDriver *driver, DriverTarget *dtar)
+{
+ /* sanity checks */
+ if (dtar == NULL)
+ return;
+
+ /* free target vars */
+ if (dtar->rna_path)
+ MEM_freeN(dtar->rna_path);
+
+ /* remove the target from the driver */
+ if (driver)
+ BLI_freelinkN(&driver->targets, dtar);
+ else
+ MEM_freeN(dtar);
+}
+
+/* Add a new driver target variable */
+DriverTarget *driver_add_new_target (ChannelDriver *driver)
+{
+ DriverTarget *dtar;
+
+ /* sanity checks */
+ if (driver == NULL)
+ return NULL;
+
+ /* make a new target */
+ dtar= MEM_callocN(sizeof(DriverTarget), "DriverTarget");
+ BLI_addtail(&driver->targets, dtar);
+
+ /* give the target a 'unique' name */
+ strcpy(dtar->name, "var");
+ BLI_uniquename(&driver->targets, dtar, "var", '_', offsetof(DriverTarget, name), 64);
+
+ /* return the target */
+ return dtar;
+}
+
/* This frees the driver itself */
void fcurve_free_driver(FCurve *fcu)
{
ChannelDriver *driver;
+ DriverTarget *dtar, *dtarn;
/* sanity checks */
if ELEM(NULL, fcu, fcu->driver)
return;
driver= fcu->driver;
- /* free RNA-paths, as these were allocated when getting the path string */
- if (driver->rna_path) MEM_freeN(driver->rna_path);
- if (driver->rna_path2) MEM_freeN(driver->rna_path2);
+ /* free driver targets */
+ for (dtar= driver->targets.first; dtar; dtar= dtarn) {
+ dtarn= dtar->next;
+ driver_free_target(driver, dtar);
+ }
/* free driver itself, then set F-Curve's point to this to NULL (as the curve may still be used) */
MEM_freeN(driver);
@@ -566,6 +630,7 @@ void fcurve_free_driver(FCurve *fcu)
ChannelDriver *fcurve_copy_driver (ChannelDriver *driver)
{
ChannelDriver *ndriver;
+ DriverTarget *dtar;
/* sanity checks */
if (driver == NULL)
@@ -573,8 +638,16 @@ ChannelDriver *fcurve_copy_driver (ChannelDriver *driver)
/* copy all data */
ndriver= MEM_dupallocN(driver);
- ndriver->rna_path= MEM_dupallocN(ndriver->rna_path);
- ndriver->rna_path2= MEM_dupallocN(ndriver->rna_path2);
+
+ /* copy targets */
+ ndriver->targets.first= ndriver->targets.last= NULL;
+ BLI_duplicatelist(&ndriver->targets, &driver->targets);
+
+ for (dtar= ndriver->targets.first; dtar; dtar= dtar->next) {
+ /* make a copy of target's rna path if available */
+ if (dtar->rna_path)
+ dtar->rna_path = MEM_dupallocN(dtar->rna_path);
+ }
/* return the new driver */
return ndriver;
@@ -582,10 +655,8 @@ ChannelDriver *fcurve_copy_driver (ChannelDriver *driver)
/* Driver Evaluation -------------------------- */
-/* Helper function to obtain a value using RNA from the specified source (for evaluating drivers)
- * - target: used to specify which of the two driver-targets to use
- */
-static float driver_get_driver_value (ChannelDriver *driver, short target)
+/* Helper function to obtain a value using RNA from the specified source (for evaluating drivers) */
+float driver_get_target_value (ChannelDriver *driver, DriverTarget *dtar)
{
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
@@ -594,21 +665,15 @@ static float driver_get_driver_value (ChannelDriver *driver, short target)
int index;
float value= 0.0f;
- /* get RNA-pointer for the ID-block given in driver */
- if (target == 1) {
- /* second target */
- RNA_id_pointer_create(driver->id2, &id_ptr);
- id= driver->id2;
- path= driver->rna_path2;
- index= driver->array_index2;
- }
- else {
- /* first/main target */
- RNA_id_pointer_create(driver->id, &id_ptr);
- id= driver->id;
- path= driver->rna_path;
- index= driver->array_index;
- }
+ /* sanity check */
+ if ELEM(NULL, driver, dtar)
+ return 0.0f;
+
+ /* get RNA-pointer for the ID-block given in target */
+ RNA_id_pointer_create(dtar->id, &id_ptr);
+ id= dtar->id;
+ path= dtar->rna_path;
+ index= dtar->array_index;
/* error check for missing pointer... */
if (id == NULL) {
@@ -620,21 +685,21 @@ static float driver_get_driver_value (ChannelDriver *driver, short target)
/* get property to read from, and get value as appropriate */
if (RNA_path_resolve(&id_ptr, path, &ptr, &prop)) {
- switch (RNA_property_type(&ptr, prop)) {
+ switch (RNA_property_type(prop)) {
case PROP_BOOLEAN:
- if (RNA_property_array_length(&ptr, prop))
+ if (RNA_property_array_length(prop))
value= (float)RNA_property_boolean_get_index(&ptr, prop, index);
else
value= (float)RNA_property_boolean_get(&ptr, prop);
break;
case PROP_INT:
- if (RNA_property_array_length(&ptr, prop))
+ if (RNA_property_array_length(prop))
value= (float)RNA_property_int_get_index(&ptr, prop, index);
else
value= (float)RNA_property_int_get(&ptr, prop);
break;
case PROP_FLOAT:
- if (RNA_property_array_length(&ptr, prop))
+ if (RNA_property_array_length(prop))
value= RNA_property_float_get_index(&ptr, prop, index);
else
value= RNA_property_float_get(&ptr, prop);
@@ -650,21 +715,80 @@ static float driver_get_driver_value (ChannelDriver *driver, short target)
return value;
}
+/* Get two PoseChannels from the targets of the given Driver */
+static void driver_get_target_pchans2 (ChannelDriver *driver, bPoseChannel **pchan1, bPoseChannel **pchan2)
+{
+ DriverTarget *dtar;
+ short i = 0;
+
+ /* before doing anything */
+ *pchan1= NULL;
+ *pchan2= NULL;
+
+ /* only take the first two targets */
+ for (dtar= driver->targets.first; (dtar) && (i < 2); dtar=dtar->next, i++) {
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+
+ /* get RNA-pointer for the ID-block given in target */
+ if (dtar->id)
+ RNA_id_pointer_create(dtar->id, &id_ptr);
+ else
+ continue;
+
+ /* resolve path so that we have pointer to the right posechannel */
+ if (RNA_path_resolve(&id_ptr, dtar->rna_path, &ptr, &prop)) {
+ /* is pointer valid (i.e. pointing to an actual posechannel */
+ if ((ptr.type == &RNA_PoseChannel) && (ptr.data)) {
+ /* first or second target? */
+ if (i)
+ *pchan1= ptr.data;
+ else
+ *pchan2= ptr.data;
+ }
+ }
+ }
+}
+
/* Evaluate an Channel-Driver to get a 'time' value to use instead of "evaltime"
* - "evaltime" is the frame at which F-Curve is being evaluated
* - has to return a float value
*/
static float evaluate_driver (ChannelDriver *driver, float evaltime)
{
+ DriverTarget *dtar;
+
/* check if driver can be evaluated */
- if (driver->flag & DRIVER_FLAG_DISABLED)
+ if (driver->flag & DRIVER_FLAG_INVALID)
return 0.0f;
+ // TODO: the flags for individual targets need to be used too for more fine-grained support...
switch (driver->type) {
- case DRIVER_TYPE_CHANNEL: /* channel/setting drivers channel/setting */
- return driver_get_driver_value(driver, 0);
-
-
+ case DRIVER_TYPE_AVERAGE: /* average values of driver targets */
+ {
+ /* check how many targets there are first (i.e. just one?) */
+ if (driver->targets.first == driver->targets.last) {
+ /* just one target, so just use that */
+ dtar= driver->targets.first;
+ return driver_get_target_value(driver, dtar);
+ }
+ else {
+ /* more than one target, so average the values of the targets */
+ int tot = 0;
+ float value = 0.0f;
+
+ /* loop through targets, adding (hopefully we don't get any overflow!) */
+ for (dtar= driver->targets.first; dtar; dtar=dtar->next) {
+ value += driver_get_target_value(driver, dtar);
+ tot++;
+ }
+
+ /* return the average of these */
+ return (value / (float)tot);
+ }
+ }
+ break;
+
case DRIVER_TYPE_PYTHON: /* expression */
{
#ifndef DISABLE_PYTHON
@@ -684,11 +808,30 @@ static float evaluate_driver (ChannelDriver *driver, float evaltime)
break;
- case DRIVER_TYPE_ROTDIFF: /* difference of rotations of 2 bones (should be in same armature) */
+ case DRIVER_TYPE_ROTDIFF: /* difference of rotations of 2 bones (should ideally be in same armature) */
{
- /*
+ bPoseChannel *pchan, *pchan2;
float q1[4], q2[4], quat[4], angle;
+ /* get pose channels, and check if we've got two */
+ driver_get_target_pchans2(driver, &pchan, &pchan2);
+ if (ELEM(NULL, pchan, pchan2)) {
+ /* disable this driver, since it doesn't work correctly... */
+ driver->flag |= DRIVER_FLAG_INVALID;
+
+ /* check what the error was */
+ if ((pchan == NULL) && (pchan2 == NULL))
+ printf("Driver Evaluation Error: Rotational difference failed - first 2 targets invalid \n");
+ else if (pchan == NULL)
+ printf("Driver Evaluation Error: Rotational difference failed - first target not valid PoseChannel \n");
+ else if (pchan2 == NULL)
+ printf("Driver Evaluation Error: Rotational difference failed - second target not valid PoseChannel \n");
+
+ /* stop here... */
+ return 0.0f;
+ }
+
+ /* use the final posed locations */
Mat4ToQuat(pchan->pose_mat, q1);
Mat4ToQuat(pchan2->pose_mat, q2);
@@ -698,7 +841,6 @@ static float evaluate_driver (ChannelDriver *driver, float evaltime)
angle= ABS(angle);
return (angle > M_PI) ? (float)((2.0f * M_PI) - angle) : (float)(angle);
- */
}
break;
@@ -895,7 +1037,8 @@ static float fcurve_eval_keyframes (FCurve *fcu, BezTriple *bezts, float evaltim
{
BezTriple *bezt, *prevbezt, *lastbezt;
float v1[2], v2[2], v3[2], v4[2], opl[32], dx, fac;
- int a, b;
+ unsigned int a;
+ int b;
float cvalue = 0.0f;
/* get pointers */
@@ -1115,6 +1258,7 @@ static FModifierTypeInfo FMI_MODNAME = {
fcm_modname_copy, /* copy data */
fcm_modname_new_data, /* new data */
fcm_modname_verify, /* verify */
+ fcm_modname_time, /* evaluate time */
fcm_modname_evaluate /* evaluate */
};
#endif
@@ -1370,7 +1514,7 @@ static void fcm_generator_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue,
/* execute function callback to set value if appropriate */
if (fn) {
- float value= data->coefficients[0]*fn(arg) + data->coefficients[3];
+ float value= (float)(data->coefficients[0]*fn(arg) + data->coefficients[3]);
if (data->flag & FCM_GENERATOR_ADDITIVE)
*cvalue += value;
@@ -1399,6 +1543,7 @@ static FModifierTypeInfo FMI_GENERATOR = {
fcm_generator_copy, /* copy data */
fcm_generator_new_data, /* new data */
fcm_generator_verify, /* verify */
+ NULL, /* evaluate time */
fcm_generator_evaluate /* evaluate */
};
@@ -1505,6 +1650,7 @@ static FModifierTypeInfo FMI_ENVELOPE = {
fcm_envelope_copy, /* copy data */
fcm_envelope_new_data, /* new data */
fcm_envelope_verify, /* verify */
+ NULL, /* evaluate time */
fcm_envelope_evaluate /* evaluate */
};
@@ -1520,6 +1666,11 @@ static FModifierTypeInfo FMI_ENVELOPE = {
* as appropriate
*/
+/* temp data used during evaluation */
+typedef struct tFCMED_Cycles {
+ float cycyofs; /* y-offset to apply */
+} tFCMED_Cycles;
+
static void fcm_cycles_new_data (void *mdata)
{
FMod_Cycles *data= (FMod_Cycles *)mdata;
@@ -1527,13 +1678,11 @@ static void fcm_cycles_new_data (void *mdata)
/* turn on cycles by default */
data->before_mode= data->after_mode= FCM_EXTRAPOLATE_CYCLIC;
}
-
-static void fcm_cycles_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime)
+
+static float fcm_cycles_time (FCurve *fcu, FModifier *fcm, float cvalue, float evaltime)
{
FMod_Cycles *data= (FMod_Cycles *)fcm->data;
- ListBase mods = {NULL, NULL};
float prevkey[2], lastkey[2], cycyofs=0.0f;
- float new_value;
short side=0, mode=0;
int cycles=0;
@@ -1541,7 +1690,7 @@ static void fcm_cycles_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, flo
// FIXME...
if (fcm->prev) {
fcm->flag |= FMODIFIER_FLAG_DISABLED;
- return;
+ return evaltime;
}
/* calculate new evaltime due to cyclic interpolation */
@@ -1566,7 +1715,7 @@ static void fcm_cycles_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, flo
lastkey[1]= lastfpt->vec[1];
}
else
- return;
+ return evaltime;
/* check if modifier will do anything
* 1) if in data range, definitely don't do anything
@@ -1587,11 +1736,12 @@ static void fcm_cycles_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, flo
}
}
if ELEM(0, side, mode)
- return;
+ return evaltime;
/* find relative place within a cycle */
{
float cycdx=0, cycdy=0, ofs=0;
+ float cycle= 0;
/* ofs is start frame of cycle */
ofs= prevkey[0];
@@ -1602,19 +1752,22 @@ static void fcm_cycles_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, flo
/* check if cycle is infinitely small, to be point of being impossible to use */
if (cycdx == 0)
- return;
+ return evaltime;
+ /* calculate the 'number' of the cycle */
+ cycle= ((float)side * (evaltime - ofs) / cycdx);
+
/* check that cyclic is still enabled for the specified time */
if (cycles == 0) {
/* catch this case so that we don't exit when we have cycles=0
* as this indicates infinite cycles...
*/
}
- else if ( ((float)side * (evaltime - ofs) / cycdx) > (cycles+1) ) {
+ else if (cycle > (cycles+1)) {
/* we are too far away from range to evaluate
* TODO: but we should still hold last value...
*/
- return;
+ return evaltime;
}
/* check if 'cyclic extrapolation', and thus calculate y-offset for this cycle */
@@ -1624,21 +1777,49 @@ static void fcm_cycles_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, flo
}
/* calculate where in the cycle we are (overwrite evaltime to reflect this) */
- evaltime= (float)(fmod(evaltime-ofs, cycdx) + ofs);
+ if ((mode == FCM_EXTRAPOLATE_MIRROR) && ((int)(cycle) % 2)) {
+ /* when 'mirror' option is used and cycle number is odd, this cycle is played in reverse
+ * - for 'before' extrapolation, we need to flip in a different way, otherwise values past
+ * then end of the curve get referenced (result of fmod will be negative, and with different phase)
+ */
+ if (side < 0)
+ evaltime= (float)(prevkey[0] - fmod(evaltime-ofs, cycdx));
+ else
+ evaltime= (float)(lastkey[0] - fmod(evaltime-ofs, cycdx));
+ }
+ else {
+ /* the cycle is played normally... */
+ evaltime= (float)(fmod(evaltime-ofs, cycdx) + ofs);
+ }
if (evaltime < ofs) evaltime += cycdx;
}
+ /* store temp data if needed */
+ if (mode == FCM_EXTRAPOLATE_CYCLIC_OFFSET) {
+ tFCMED_Cycles *edata;
+
+ /* for now, this is just a float, but we could get more stuff... */
+ fcm->edata= edata= MEM_callocN(sizeof(tFCMED_Cycles), "tFCMED_Cycles");
+ edata->cycyofs= cycyofs;
+ }
- /* store modifiers after (and including ourself) before recalculating curve with new evaltime */
- mods= fcu->modifiers;
- fcu->modifiers.first= fcu->modifiers.last= NULL;
-
- /* re-enter the evaluation loop (but without the burden of evaluating any modifiers, so 'should' be relatively quick) */
- new_value= evaluate_fcurve(fcu, evaltime);
+ /* return the new frame to evaluate */
+ return evaltime;
+}
+
+static void fcm_cycles_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime)
+{
+ tFCMED_Cycles *edata= (tFCMED_Cycles *)fcm->edata;
- /* restore modifiers, and set new value (don't assume everything is still ok after being re-entrant) */
- fcu->modifiers= mods;
- *cvalue= new_value + cycyofs;
+ /* use temp data */
+ if (edata) {
+ /* add cyclic offset - no need to check for now, otherwise the data wouldn't exist! */
+ *cvalue += edata->cycyofs;
+
+ /* free temp data */
+ MEM_freeN(edata);
+ fcm->edata= NULL;
+ }
}
static FModifierTypeInfo FMI_CYCLES = {
@@ -1652,12 +1833,48 @@ static FModifierTypeInfo FMI_CYCLES = {
NULL, /* copy data */
fcm_cycles_new_data, /* new data */
NULL /*fcm_cycles_verify*/, /* verify */
+ fcm_cycles_time, /* evaluate time */
fcm_cycles_evaluate /* evaluate */
};
/* Noise F-Curve Modifier --------------------------- */
-#if 0 // XXX not yet implemented
+static void fcm_noise_new_data (void *mdata)
+{
+ FMod_Noise *data= (FMod_Noise *)mdata;
+
+ /* defaults */
+ data->size= 1.0f;
+ data->strength= 1.0f;
+ data->phase= 1.0f;
+ data->depth = 0;
+ data->modification = FCM_NOISE_MODIF_REPLACE;
+}
+
+static void fcm_noise_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime)
+{
+ FMod_Noise *data= (FMod_Noise *)fcm->data;
+ float noise;
+
+ noise = BLI_turbulence(data->size, evaltime, data->phase, 0.f, data->depth);
+
+ switch (data->modification) {
+ case FCM_NOISE_MODIF_ADD:
+ *cvalue= *cvalue + noise * data->strength;
+ break;
+ case FCM_NOISE_MODIF_SUBTRACT:
+ *cvalue= *cvalue - noise * data->strength;
+ break;
+ case FCM_NOISE_MODIF_MULTIPLY:
+ *cvalue= *cvalue * noise * data->strength;
+ break;
+ case FCM_NOISE_MODIF_REPLACE:
+ default:
+ *cvalue= *cvalue + (noise - 0.5f) * data->strength;
+ break;
+ }
+}
+
static FModifierTypeInfo FMI_NOISE = {
FMODIFIER_TYPE_NOISE, /* type */
sizeof(FMod_Noise), /* size */
@@ -1669,9 +1886,9 @@ static FModifierTypeInfo FMI_NOISE = {
NULL, /* copy data */
fcm_noise_new_data, /* new data */
NULL /*fcm_noise_verify*/, /* verify */
+ NULL, /* evaluate time */
fcm_noise_evaluate /* evaluate */
};
-#endif // XXX not yet implemented
/* Filter F-Curve Modifier --------------------------- */
@@ -1687,6 +1904,7 @@ static FModifierTypeInfo FMI_FILTER = {
NULL, /* copy data */
NULL, /* new data */
NULL /*fcm_filter_verify*/, /* verify */
+ NULL, /* evlauate time */
fcm_filter_evaluate /* evaluate */
};
#endif // XXX not yet implemented
@@ -1742,10 +1960,53 @@ static FModifierTypeInfo FMI_PYTHON = {
fcm_python_copy, /* copy data */
fcm_python_new_data, /* new data */
NULL /*fcm_python_verify*/, /* verify */
+ NULL /*fcm_python_time*/, /* evaluate time */
fcm_python_evaluate /* evaluate */
};
+/* Limits F-Curve Modifier --------------------------- */
+
+static float fcm_limits_time (FCurve *fcu, FModifier *fcm, float cvalue, float evaltime)
+{
+ FMod_Limits *data= (FMod_Limits *)fcm->data;
+
+ /* check for the time limits */
+ if ((data->flag & FCM_LIMIT_XMIN) && (evaltime < data->rect.xmin))
+ return data->rect.xmin;
+ if ((data->flag & FCM_LIMIT_XMAX) && (evaltime > data->rect.xmax))
+ return data->rect.xmax;
+
+ /* modifier doesn't change time */
+ return evaltime;
+}
+
+static void fcm_limits_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime)
+{
+ FMod_Limits *data= (FMod_Limits *)fcm->data;
+
+ /* value limits now */
+ if ((data->flag & FCM_LIMIT_YMIN) && (*cvalue < data->rect.ymin))
+ *cvalue= data->rect.ymin;
+ if ((data->flag & FCM_LIMIT_YMAX) && (*cvalue > data->rect.ymax))
+ *cvalue= data->rect.ymax;
+}
+
+static FModifierTypeInfo FMI_LIMITS = {
+ FMODIFIER_TYPE_LIMITS, /* type */
+ sizeof(FMod_Limits), /* size */
+ FMI_TYPE_GENERATE_CURVE, /* action type */ /* XXX... err... */
+ FMI_REQUIRES_RUNTIME_CHECK, /* requirements */
+ "Limits", /* name */
+ "FMod_Limits", /* struct name */
+ NULL, /* free data */
+ NULL, /* copy data */
+ NULL, /* new data */
+ NULL, /* verify */
+ fcm_limits_time, /* evaluate time */
+ fcm_limits_evaluate /* evaluate */
+};
+
/* F-Curve Modifier API --------------------------- */
/* All of the F-Curve Modifier api functions use FModifierTypeInfo structs to carry out
* and operations that involve F-Curve modifier specific code.
@@ -1762,9 +2023,10 @@ static void fmods_init_typeinfo ()
fmodifiersTypeInfo[1]= &FMI_GENERATOR; /* Generator F-Curve Modifier */
fmodifiersTypeInfo[2]= &FMI_ENVELOPE; /* Envelope F-Curve Modifier */
fmodifiersTypeInfo[3]= &FMI_CYCLES; /* Cycles F-Curve Modifier */
- fmodifiersTypeInfo[4]= NULL/*&FMI_NOISE*/; /* Apply-Noise F-Curve Modifier */ // XXX unimplemented
+ fmodifiersTypeInfo[4]= &FMI_NOISE; /* Apply-Noise F-Curve Modifier */
fmodifiersTypeInfo[5]= NULL/*&FMI_FILTER*/; /* Filter F-Curve Modifier */ // XXX unimplemented
fmodifiersTypeInfo[6]= &FMI_PYTHON; /* Custom Python F-Curve Modifier */
+ fmodifiersTypeInfo[7]= &FMI_LIMITS; /* Limits F-Curve Modifier */
}
/* This function should be used for getting the appropriate type-info when only
@@ -1981,9 +2243,11 @@ void fcurve_set_active_modifier (FCurve *fcu, FModifier *fcm)
float evaluate_fcurve (FCurve *fcu, float evaltime)
{
FModifier *fcm;
- float cvalue = 0.0f;
+ float cvalue= 0.0f;
+ float devaltime;
/* if there is a driver (only if this F-Curve is acting as 'driver'), evaluate it to find value to use as "evaltime"
+ * since drivers essentially act as alternative input (i.e. in place of 'time') for F-Curves
* - this value will also be returned as the value of the 'curve', if there are no keyframes
*/
if (fcu->driver) {
@@ -1991,11 +2255,37 @@ float evaluate_fcurve (FCurve *fcu, float evaltime)
evaltime= cvalue= evaluate_driver(fcu->driver, evaltime);
}
- /* evaluate curve-data */
+ /* evaluate time modifications imposed by some F-Curve Modifiers
+ * - this step acts as an optimisation to prevent the F-Curve stack being evaluated
+ * several times by modifiers requesting the time be modified, as the final result
+ * would have required using the modified time
+ * - modifiers only ever recieve the unmodified time, as subsequent modifiers should be
+ * working on the 'global' result of the modified curve, not some localised segment,
+ * so nevaltime gets set to whatever the last time-modifying modifier likes...
+ * - we start from the end of the stack, as only the last one matters for now
+ */
+ devaltime= evaltime;
+
+ for (fcm= fcu->modifiers.last; fcm; fcm= fcm->prev) {
+ FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
+
+ /* only evaluate if there's a callback for this */
+ // TODO: implement the 'influence' control feature...
+ if (fmi && fmi->evaluate_modifier_time) {
+ if ((fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED)) == 0)
+ devaltime= fmi->evaluate_modifier_time(fcu, fcm, cvalue, evaltime);
+ break;
+ }
+ }
+
+ /* evaluate curve-data
+ * - 'devaltime' instead of 'evaltime', as this is the time that the last time-modifying
+ * F-Curve modifier on the stack requested the curve to be evaluated at
+ */
if (fcu->bezt)
- cvalue= fcurve_eval_keyframes(fcu, fcu->bezt, evaltime);
+ cvalue= fcurve_eval_keyframes(fcu, fcu->bezt, devaltime);
else if (fcu->fpt)
- cvalue= fcurve_eval_samples(fcu, fcu->fpt, evaltime);
+ cvalue= fcurve_eval_samples(fcu, fcu->fpt, devaltime);
/* evaluate modifiers */
for (fcm= fcu->modifiers.first; fcm; fcm= fcm->next) {
@@ -2004,7 +2294,7 @@ float evaluate_fcurve (FCurve *fcu, float evaltime)
/* only evaluate if there's a callback for this */
// TODO: implement the 'influence' control feature...
if (fmi && fmi->evaluate_modifier) {
- if ((fcm->flag & FMODIFIER_FLAG_DISABLED) == 0)
+ if ((fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED)) == 0)
fmi->evaluate_modifier(fcu, fcm, &cvalue, evaltime);
}
}
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index ced8d3bdebb..b94652eb7c3 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -355,11 +355,7 @@ static VFontData *vfont_get_data(VFont *vfont)
}
if (pf) {
-#ifdef WITH_FREETYPE2
vfont->data= BLI_vfontdata_from_freetypefont(pf);
-#else
- vfont->data= BLI_vfontdata_from_psfont(pf);
-#endif
if (pf != vfont->packedfile) {
freePackedFile(pf);
}
@@ -398,12 +394,7 @@ VFont *load_vfont(char *name)
if (pf) {
VFontData *vfd;
-#ifdef WITH_FREETYPE2
vfd= BLI_vfontdata_from_freetypefont(pf);
-#else
- vfd= BLI_vfontdata_from_psfont(pf);
-#endif
-
if (vfd) {
vfont = alloc_libblock(&G.main->vfont, ID_VF, filename);
vfont->data = vfd;
@@ -755,21 +746,22 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
che = che->next;
}
-#ifdef WITH_FREETYPE2
- // The character wasn't in the current curve base so load it
- // But if the font is <builtin> then do not try loading since whole font is in the memory already
+ /*
+ * The character wasn't in the current curve base so load it
+ * But if the font is <builtin> then do not try loading since
+ * whole font is in the memory already
+ */
if(che == NULL && strcmp(vfont->name, "<builtin>")) {
BLI_vfontchar_from_freetypefont(vfont, ascii);
}
- // Try getting the character again from the list
+ /* Try getting the character again from the list */
che = vfd->characters.first;
while(che) {
if(che->index == ascii)
break;
che = che->next;
}
-#endif
/* No VFont found */
if (vfont==0) {
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
new file mode 100644
index 00000000000..6086aa58d40
--- /dev/null
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -0,0 +1,516 @@
+/**
+ * $Id: gpencil.c 19758 2009-04-16 13:10:08Z aligorith $
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2008, Blender Foundation
+ * This is a new part of Blender
+ *
+ * Contributor(s): Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+
+#include "DNA_listBase.h"
+#include "DNA_gpencil_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_vec_types.h"
+
+#include "BKE_blender.h"
+#include "BKE_context.h"
+#include "BKE_curve.h"
+#include "BKE_global.h"
+#include "BKE_gpencil.h"
+#include "BKE_image.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_utildefines.h"
+
+
+/* ************************************************** */
+/* GENERAL STUFF */
+
+/* --------- Memory Management ------------ */
+
+/* Free strokes belonging to a gp-frame */
+void free_gpencil_strokes (bGPDframe *gpf)
+{
+ bGPDstroke *gps, *gpsn;
+
+ /* error checking */
+ if (gpf == NULL) return;
+
+ /* free strokes */
+ for (gps= gpf->strokes.first; gps; gps= gpsn) {
+ gpsn= gps->next;
+
+ /* free stroke memory arrays, then stroke itself */
+ if (gps->points) MEM_freeN(gps->points);
+ BLI_freelinkN(&gpf->strokes, gps);
+ }
+}
+
+/* Free all of a gp-layer's frames */
+void free_gpencil_frames (bGPDlayer *gpl)
+{
+ bGPDframe *gpf, *gpfn;
+
+ /* error checking */
+ if (gpl == NULL) return;
+
+ /* free frames */
+ for (gpf= gpl->frames.first; gpf; gpf= gpfn) {
+ gpfn= gpf->next;
+
+ /* free strokes and their associated memory */
+ free_gpencil_strokes(gpf);
+ BLI_freelinkN(&gpl->frames, gpf);
+ }
+}
+
+/* Free all of the gp-layers for a viewport (list should be &gpd->layers or so) */
+void free_gpencil_layers (ListBase *list)
+{
+ bGPDlayer *gpl, *gpln;
+
+ /* error checking */
+ if (list == NULL) return;
+
+ /* delete layers*/
+ for (gpl= list->first; gpl; gpl= gpln) {
+ gpln= gpl->next;
+
+ /* free layers and their data */
+ free_gpencil_frames(gpl);
+ BLI_freelinkN(list, gpl);
+ }
+}
+
+/* Free all of GPencil datablock's related data, but not the block itself */
+void free_gpencil_data (bGPdata *gpd)
+{
+ /* free layers */
+ free_gpencil_layers(&gpd->layers);
+}
+
+/* -------- Container Creation ---------- */
+
+/* add a new gp-frame to the given layer */
+bGPDframe *gpencil_frame_addnew (bGPDlayer *gpl, int cframe)
+{
+ bGPDframe *gpf, *gf;
+ short state=0;
+
+ /* error checking */
+ if ((gpl == NULL) || (cframe <= 0))
+ return NULL;
+
+ /* allocate memory for this frame */
+ gpf= MEM_callocN(sizeof(bGPDframe), "bGPDframe");
+ gpf->framenum= cframe;
+
+ /* find appropriate place to add frame */
+ if (gpl->frames.first) {
+ for (gf= gpl->frames.first; gf; gf= gf->next) {
+ /* check if frame matches one that is supposed to be added */
+ if (gf->framenum == cframe) {
+ state= -1;
+ break;
+ }
+
+ /* if current frame has already exceeded the frame to add, add before */
+ if (gf->framenum > cframe) {
+ BLI_insertlinkbefore(&gpl->frames, gf, gpf);
+ state= 1;
+ break;
+ }
+ }
+ }
+
+ /* check whether frame was added successfully */
+ if (state == -1) {
+ MEM_freeN(gpf);
+ printf("Error: frame (%d) existed already for this layer \n", cframe);
+ }
+ else if (state == 0) {
+ /* add to end then! */
+ BLI_addtail(&gpl->frames, gpf);
+ }
+
+ /* return frame */
+ return gpf;
+}
+
+/* add a new gp-layer and make it the active layer */
+bGPDlayer *gpencil_layer_addnew (bGPdata *gpd)
+{
+ bGPDlayer *gpl;
+
+ /* check that list is ok */
+ if (gpd == NULL)
+ return NULL;
+
+ /* allocate memory for frame and add to end of list */
+ gpl= MEM_callocN(sizeof(bGPDlayer), "bGPDlayer");
+
+ /* add to datablock */
+ BLI_addtail(&gpd->layers, gpl);
+
+ /* set basic settings */
+ gpl->color[3]= 0.9f;
+ gpl->thickness = 3;
+
+ /* auto-name */
+ sprintf(gpl->info, "GP_Layer");
+ BLI_uniquename(&gpd->layers, gpl, "GP_Layer", '.', offsetof(bGPDlayer, info[0]), 128);
+
+ /* make this one the active one */
+ gpencil_layer_setactive(gpd, gpl);
+
+ /* return layer */
+ return gpl;
+}
+
+/* add a new gp-datablock */
+bGPdata *gpencil_data_addnew (char name[])
+{
+ bGPdata *gpd;
+
+ /* allocate memory for a new block */
+ gpd= alloc_libblock(&G.main->gpencil, ID_GD, name);
+
+ /* initial settings */
+ gpd->flag = (GP_DATA_DISPINFO|GP_DATA_EXPAND);
+
+ return gpd;
+}
+
+/* -------- Data Duplication ---------- */
+
+/* make a copy of a given gpencil frame */
+bGPDframe *gpencil_frame_duplicate (bGPDframe *src)
+{
+ bGPDstroke *gps, *gpsd;
+ bGPDframe *dst;
+
+ /* error checking */
+ if (src == NULL)
+ return NULL;
+
+ /* make a copy of the source frame */
+ dst= MEM_dupallocN(src);
+ dst->prev= dst->next= NULL;
+
+ /* copy strokes */
+ dst->strokes.first = dst->strokes.last= NULL;
+ for (gps= src->strokes.first; gps; gps= gps->next) {
+ /* make copy of source stroke, then adjust pointer to points too */
+ gpsd= MEM_dupallocN(gps);
+ gpsd->points= MEM_dupallocN(gps->points);
+
+ BLI_addtail(&dst->strokes, gpsd);
+ }
+
+ /* return new frame */
+ return dst;
+}
+
+/* make a copy of a given gpencil layer */
+bGPDlayer *gpencil_layer_duplicate (bGPDlayer *src)
+{
+ bGPDframe *gpf, *gpfd;
+ bGPDlayer *dst;
+
+ /* error checking */
+ if (src == NULL)
+ return NULL;
+
+ /* make a copy of source layer */
+ dst= MEM_dupallocN(src);
+ dst->prev= dst->next= NULL;
+
+ /* copy frames */
+ dst->frames.first= dst->frames.last= NULL;
+ for (gpf= src->frames.first; gpf; gpf= gpf->next) {
+ /* make a copy of source frame */
+ gpfd= gpencil_frame_duplicate(gpf);
+ BLI_addtail(&dst->frames, gpfd);
+
+ /* if source frame was the current layer's 'active' frame, reassign that too */
+ if (gpf == dst->actframe)
+ dst->actframe= gpfd;
+ }
+
+ /* return new layer */
+ return dst;
+}
+
+/* make a copy of a given gpencil datablock */
+bGPdata *gpencil_data_duplicate (bGPdata *src)
+{
+ bGPDlayer *gpl, *gpld;
+ bGPdata *dst;
+
+ /* error checking */
+ if (src == NULL)
+ return NULL;
+
+ /* make a copy of the base-data */
+ dst= MEM_dupallocN(src);
+
+ /* copy layers */
+ dst->layers.first= dst->layers.last= NULL;
+ for (gpl= src->layers.first; gpl; gpl= gpl->next) {
+ /* make a copy of source layer and its data */
+ gpld= gpencil_layer_duplicate(gpl);
+ BLI_addtail(&dst->layers, gpld);
+ }
+
+ /* return new */
+ return dst;
+}
+
+/* -------- GP-Frame API ---------- */
+
+/* delete the last stroke of the given frame */
+void gpencil_frame_delete_laststroke (bGPDlayer *gpl, bGPDframe *gpf)
+{
+ bGPDstroke *gps= (gpf) ? gpf->strokes.last : NULL;
+ int cfra = 1; // XXX FIXME!!!
+
+ /* error checking */
+ if (ELEM(NULL, gpf, gps))
+ return;
+
+ /* free the stroke and its data */
+ MEM_freeN(gps->points);
+ BLI_freelinkN(&gpf->strokes, gps);
+
+ /* if frame has no strokes after this, delete it */
+ if (gpf->strokes.first == NULL) {
+ gpencil_layer_delframe(gpl, gpf);
+ gpencil_layer_getframe(gpl, cfra, 0);
+ }
+}
+
+/* -------- GP-Layer API ---------- */
+
+/* get the appropriate gp-frame from a given layer
+ * - this sets the layer's actframe var (if allowed to)
+ * - extension beyond range (if first gp-frame is after all frame in interest and cannot add)
+ */
+bGPDframe *gpencil_layer_getframe (bGPDlayer *gpl, int cframe, short addnew)
+{
+ bGPDframe *gpf = NULL;
+ short found = 0;
+
+ /* error checking */
+ if (gpl == NULL) return NULL;
+ if (cframe <= 0) cframe = 1;
+
+ /* check if there is already an active frame */
+ if (gpl->actframe) {
+ gpf= gpl->actframe;
+
+ /* do not allow any changes to layer's active frame if layer is locked */
+ if (gpl->flag & GP_LAYER_LOCKED)
+ return gpf;
+ /* do not allow any changes to actframe if frame has painting tag attached to it */
+ if (gpf->flag & GP_FRAME_PAINT)
+ return gpf;
+
+ /* try to find matching frame */
+ if (gpf->framenum < cframe) {
+ for (; gpf; gpf= gpf->next) {
+ if (gpf->framenum == cframe) {
+ found= 1;
+ break;
+ }
+ else if ((gpf->next) && (gpf->next->framenum > cframe)) {
+ found= 1;
+ break;
+ }
+ }
+
+ /* set the appropriate frame */
+ if (addnew) {
+ if ((found) && (gpf->framenum == cframe))
+ gpl->actframe= gpf;
+ else
+ gpl->actframe= gpencil_frame_addnew(gpl, cframe);
+ }
+ else if (found)
+ gpl->actframe= gpf;
+ else
+ gpl->actframe= gpl->frames.last;
+ }
+ else {
+ for (; gpf; gpf= gpf->prev) {
+ if (gpf->framenum <= cframe) {
+ found= 1;
+ break;
+ }
+ }
+
+ /* set the appropriate frame */
+ if (addnew) {
+ if ((found) && (gpf->framenum == cframe))
+ gpl->actframe= gpf;
+ else
+ gpl->actframe= gpencil_frame_addnew(gpl, cframe);
+ }
+ else if (found)
+ gpl->actframe= gpf;
+ else
+ gpl->actframe= gpl->frames.first;
+ }
+ }
+ else if (gpl->frames.first) {
+ /* check which of the ends to start checking from */
+ const int first= ((bGPDframe *)(gpl->frames.first))->framenum;
+ const int last= ((bGPDframe *)(gpl->frames.last))->framenum;
+
+ if (abs(cframe-first) > abs(cframe-last)) {
+ /* find gp-frame which is less than or equal to cframe */
+ for (gpf= gpl->frames.last; gpf; gpf= gpf->prev) {
+ if (gpf->framenum <= cframe) {
+ found= 1;
+ break;
+ }
+ }
+ }
+ else {
+ /* find gp-frame which is less than or equal to cframe */
+ for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
+ if (gpf->framenum <= cframe) {
+ found= 1;
+ break;
+ }
+ }
+ }
+
+ /* set the appropriate frame */
+ if (addnew) {
+ if ((found) && (gpf->framenum == cframe))
+ gpl->actframe= gpf;
+ else
+ gpl->actframe= gpencil_frame_addnew(gpl, cframe);
+ }
+ else if (found)
+ gpl->actframe= gpf;
+ else {
+ /* unresolved errogenous situation! */
+ printf("Error: cannot find appropriate gp-frame \n");
+ /* gpl->actframe should still be NULL */
+ }
+ }
+ else {
+ /* currently no frames (add if allowed to) */
+ if (addnew)
+ gpl->actframe= gpencil_frame_addnew(gpl, cframe);
+ else {
+ /* don't do anything... this may be when no frames yet! */
+ /* gpl->actframe should still be NULL */
+ }
+ }
+
+ /* return */
+ return gpl->actframe;
+}
+
+/* delete the given frame from a layer */
+void gpencil_layer_delframe (bGPDlayer *gpl, bGPDframe *gpf)
+{
+ /* error checking */
+ if (ELEM(NULL, gpl, gpf))
+ return;
+
+ /* free the frame and its data */
+ free_gpencil_strokes(gpf);
+ BLI_freelinkN(&gpl->frames, gpf);
+ gpl->actframe = NULL;
+}
+
+/* get the active gp-layer for editing */
+bGPDlayer *gpencil_layer_getactive (bGPdata *gpd)
+{
+ bGPDlayer *gpl;
+
+ /* error checking */
+ if (ELEM(NULL, gpd, gpd->layers.first))
+ return NULL;
+
+ /* loop over layers until found (assume only one active) */
+ for (gpl=gpd->layers.first; gpl; gpl=gpl->next) {
+ if (gpl->flag & GP_LAYER_ACTIVE)
+ return gpl;
+ }
+
+ /* no active layer found */
+ return NULL;
+}
+
+/* set the active gp-layer */
+void gpencil_layer_setactive (bGPdata *gpd, bGPDlayer *active)
+{
+ bGPDlayer *gpl;
+
+ /* error checking */
+ if (ELEM3(NULL, gpd, gpd->layers.first, active))
+ return;
+
+ /* loop over layers deactivating all */
+ for (gpl=gpd->layers.first; gpl; gpl=gpl->next)
+ gpl->flag &= ~GP_LAYER_ACTIVE;
+
+ /* set as active one */
+ active->flag |= GP_LAYER_ACTIVE;
+}
+
+/* delete the active gp-layer */
+void gpencil_layer_delactive (bGPdata *gpd)
+{
+ bGPDlayer *gpl= gpencil_layer_getactive(gpd);
+
+ /* error checking */
+ if (ELEM(NULL, gpd, gpl))
+ return;
+
+ /* free layer */
+ free_gpencil_frames(gpl);
+ BLI_freelinkN(&gpd->layers, gpl);
+}
+
+/* ************************************************** */
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 53b805f5f4c..629f34518b9 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -77,9 +77,6 @@
#include "RE_pipeline.h"
-/* for stamp drawing to an image */
-#include "BMF_Api.h"
-
#include "GPU_extensions.h"
#include "GPU_draw.h"
@@ -1069,6 +1066,9 @@ static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix)
void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, int height, int channels)
{
+#if 0
+// XXX
+// This go back when BLF_draw_buffer is implemented - Diego
struct StampData stamp_data;
int x=1,y=1;
@@ -1188,7 +1188,7 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i
buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-1, y-1, x+text_width+text_pad+1, y+font_height+1);
BMF_DrawStringBuf(font, stamp_data.strip, x+(text_pad/2), y, scene->r.fg_stamp, rect, rectf, width, height, channels);
}
-
+#endif // 0 XXX
}
void BKE_stamp_info(Scene *scene, struct ImBuf *ibuf)
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index b9417ccb467..6a01311f6fc 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -160,7 +160,7 @@ static AdrBit2Path ma_mode_bits[]= {
// ...
{MA_RAYTRANSP, "raytrace_transparency.enabled", 0},
{MA_RAYMIRROR, "raytrace_mirror.enabled", 0},
- {MA_HALO, "halo.enabled", 0}
+// {MA_HALO, "type", MA_TYPE_HALO}
};
/* ----------------- */
@@ -950,6 +950,7 @@ char *get_rna_access (int blocktype, int adrcode, char actname[], char constname
static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver)
{
ChannelDriver *cdriver;
+ DriverTarget *dtar=NULL, *dtar2=NULL;
/* allocate memory for new driver */
cdriver= MEM_callocN(sizeof(ChannelDriver), "ChannelDriver");
@@ -957,6 +958,7 @@ static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver)
/* if 'pydriver', just copy data across */
if (idriver->type == IPO_DRIVER_TYPE_PYTHON) {
/* PyDriver only requires the expression to be copied */
+ // TODO: but the expression will be useless...
cdriver->type = DRIVER_TYPE_PYTHON;
strcpy(cdriver->expression, idriver->name); // XXX is this safe?
}
@@ -965,12 +967,15 @@ static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver)
if (idriver->blocktype == ID_AR) {
/* ID_PO */
if (idriver->adrcode == OB_ROT_DIFF) {
- if (G.f & G_DEBUG) printf("idriver_to_cdriver - rotdiff %p \n", idriver->ob);
/* Rotational Difference is a special type of driver now... */
cdriver->type= DRIVER_TYPE_ROTDIFF;
+ /* make 2 driver targets */
+ dtar= driver_add_new_target(cdriver);
+ dtar2= driver_add_new_target(cdriver);
+
/* driver must use bones from same armature... */
- cdriver->id= cdriver->id2= (ID *)idriver->ob;
+ dtar->id= dtar2->id= (ID *)idriver->ob;
/* paths for the two targets get the pointers to the relevant Pose-Channels
* - return pointers to Pose-Channels not rotation channels, as calculation code is picky
@@ -979,34 +984,36 @@ static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver)
* - we use several hacks here - blocktype == -1 specifies that no property needs to be found, and
* providing a name for 'actname' will automatically imply Pose-Channel with name 'actname'
*/
- cdriver->rna_path= get_rna_access(-1, -1, idriver->name, NULL, NULL);
- cdriver->rna_path2= get_rna_access(-1, -1, idriver->name+DRIVER_NAME_OFFS, NULL, NULL);
+ dtar->rna_path= get_rna_access(-1, -1, idriver->name, NULL, NULL);
+ dtar2->rna_path= get_rna_access(-1, -1, idriver->name+DRIVER_NAME_OFFS, NULL, NULL);
}
else {
- if (G.f & G_DEBUG) printf("idriver_to_cdriver - arm %p \n", idriver->ob);
/* 'standard' driver */
- cdriver->type= DRIVER_TYPE_CHANNEL;
- cdriver->id= (ID *)idriver->ob;
+ cdriver->type= DRIVER_TYPE_AVERAGE;
+
+ /* make 1 driver target */
+ dtar= driver_add_new_target(cdriver);
+ dtar->id= (ID *)idriver->ob;
switch (idriver->adrcode) {
case OB_LOC_X: /* x,y,z location are quite straightforward */
- cdriver->rna_path= get_rna_access(ID_PO, AC_LOC_X, idriver->name, NULL, &cdriver->array_index);
+ dtar->rna_path= get_rna_access(ID_PO, AC_LOC_X, idriver->name, NULL, &dtar->array_index);
break;
case OB_LOC_Y:
- cdriver->rna_path= get_rna_access(ID_PO, AC_LOC_Y, idriver->name, NULL, &cdriver->array_index);
+ dtar->rna_path= get_rna_access(ID_PO, AC_LOC_Y, idriver->name, NULL, &dtar->array_index);
break;
case OB_LOC_Z:
- cdriver->rna_path= get_rna_access(ID_PO, AC_LOC_Z, idriver->name, NULL, &cdriver->array_index);
+ dtar->rna_path= get_rna_access(ID_PO, AC_LOC_Z, idriver->name, NULL, &dtar->array_index);
break;
case OB_SIZE_X: /* x,y,z scaling are also quite straightforward */
- cdriver->rna_path= get_rna_access(ID_PO, AC_SIZE_X, idriver->name, NULL, &cdriver->array_index);
+ dtar->rna_path= get_rna_access(ID_PO, AC_SIZE_X, idriver->name, NULL, &dtar->array_index);
break;
case OB_SIZE_Y:
- cdriver->rna_path= get_rna_access(ID_PO, AC_SIZE_Y, idriver->name, NULL, &cdriver->array_index);
+ dtar->rna_path= get_rna_access(ID_PO, AC_SIZE_Y, idriver->name, NULL, &dtar->array_index);
break;
case OB_SIZE_Z:
- cdriver->rna_path= get_rna_access(ID_PO, AC_SIZE_Z, idriver->name, NULL, &cdriver->array_index);
+ dtar->rna_path= get_rna_access(ID_PO, AC_SIZE_Z, idriver->name, NULL, &dtar->array_index);
break;
case OB_ROT_X: /* rotation - we need to be careful with this... XXX (another reason why we need eulers) */
@@ -1015,8 +1022,8 @@ static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver)
{
// XXX this is not yet a 1:1 map, since we'd need euler rotations to make this work nicely (unless we make some hacks)
// XXX -1 here is a special hack...
- cdriver->rna_path= get_rna_access(ID_PO, -1, idriver->name, NULL, NULL);
- cdriver->array_index= idriver->adrcode - OB_ROT_X;
+ dtar->rna_path= get_rna_access(ID_PO, -1, idriver->name, NULL, NULL);
+ dtar->array_index= idriver->adrcode - OB_ROT_X;
}
break;
}
@@ -1024,14 +1031,16 @@ static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver)
}
else {
/* ID_OB */
- if (G.f & G_DEBUG) printf("idriver_to_cdriver - ob %p \n", idriver->ob);
- cdriver->type= DRIVER_TYPE_CHANNEL;
- cdriver->id= (ID *)idriver->ob;
- cdriver->rna_path= get_rna_access(ID_OB, idriver->adrcode, NULL, NULL, &cdriver->array_index);
+ cdriver->type= DRIVER_TYPE_AVERAGE;
+
+ /* make 1 driver target */
+ dtar= driver_add_new_target(cdriver);
+
+ dtar->id= (ID *)idriver->ob;
+ dtar->rna_path= get_rna_access(ID_OB, idriver->adrcode, NULL, NULL, &dtar->array_index);
}
}
- if (G.f & G_DEBUG) printf("\tcdriver -> id = %p \n", cdriver->id);
/* free old driver */
MEM_freeN(idriver);
@@ -1073,7 +1082,7 @@ static void fcurve_add_to_list (ListBase *groups, ListBase *list, FCurve *fcu, c
BLI_snprintf(agrp->name, 64, grpname);
BLI_addtail(&tmp_act.groups, agrp);
- BLI_uniquename(&tmp_act.groups, agrp, "Group", offsetof(bActionGroup, name), 64);
+ BLI_uniquename(&tmp_act.groups, agrp, "Group", '.', offsetof(bActionGroup, name), 64);
}
}
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 0712b53c5dd..d0e4c1a15bc 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -79,6 +79,7 @@
#include "DNA_space_types.h"
#include "DNA_windowmanager_types.h"
#include "DNA_anim_types.h"
+#include "DNA_gpencil_types.h"
#include "BLI_blenlib.h"
#include "BLI_dynstr.h"
@@ -114,6 +115,7 @@
#include "BKE_brush.h"
#include "BKE_idprop.h"
#include "BKE_particle.h"
+#include "BKE_gpencil.h"
#define MAX_IDPUP 60 /* was 24 */
@@ -199,6 +201,8 @@ ListBase *wich_libbase(Main *mainlib, short type)
return &(mainlib->particle);
case ID_WM:
return &(mainlib->wm);
+ case ID_GD:
+ return &(mainlib->gpencil);
}
return 0;
}
@@ -269,6 +273,7 @@ int set_listbasepointers(Main *main, ListBase **lb)
lb[a++]= &(main->scene);
lb[a++]= &(main->library);
lb[a++]= &(main->wm);
+ lb[a++]= &(main->gpencil);
lb[a]= NULL;
@@ -374,6 +379,9 @@ static ID *alloc_libblock_notest(short type)
case ID_WM:
id = MEM_callocN(sizeof(wmWindowManager), "Window manager");
break;
+ case ID_GD:
+ id = MEM_callocN(sizeof(bGPdata), "Grease Pencil");
+ break;
}
return id;
}
@@ -577,6 +585,9 @@ void free_libblock(ListBase *lb, void *idv)
if(free_windowmanager_cb)
free_windowmanager_cb(NULL, (wmWindowManager *)id);
break;
+ case ID_GD:
+ free_gpencil_data((bGPdata *)id);
+ break;
}
if (id->properties) {
@@ -986,14 +997,15 @@ static void lib_indirect_test_id(ID *id)
if(id->lib)
return;
-
+
if(GS(id->name)==ID_OB) {
Object *ob= (Object *)id;
bActionStrip *strip;
Mesh *me;
int a;
-
+
+ // XXX old animation system!
for (strip=ob->nlastrips.first; strip; strip=strip->next){
LIBTAG(strip->object);
LIBTAG(strip->act);
@@ -1090,6 +1102,27 @@ void test_idbutton(char *name)
if(idtest) if( new_id(lb, idtest, name)==0 ) sort_alpha_id(lb, idtest);
}
+void text_idbutton(struct ID *id, char *text)
+{
+ if(id) {
+ if(GS(id->name)==ID_SCE)
+ strcpy(text, "SCE: ");
+ else if(GS(id->name)==ID_SCE)
+ strcpy(text, "SCR: ");
+ else if(GS(id->name)==ID_MA && ((Material*)id)->use_nodes)
+ strcpy(text, "NT: ");
+ else {
+ text[0]= id->name[0];
+ text[1]= id->name[1];
+ text[2]= ':';
+ text[3]= ' ';
+ text[4]= 0;
+ }
+ }
+ else
+ strcpy(text, "");
+}
+
void rename_id(ID *id, char *name)
{
ListBase *lb;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index f554888d978..de6f2f7e558 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -66,11 +66,26 @@
/* -- */
#include "BKE_object.h"
#include "BKE_utildefines.h"
+#include "BKE_tessmesh.h"
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
#include "BLI_arithb.h"
+EditMesh *BKE_mesh_get_editmesh(Mesh *me)
+{
+ return bmesh_to_editmesh(me->edit_btmesh->bm);
+}
+
+void BKE_mesh_end_editmesh(Mesh *me, EditMesh *em)
+{
+ BM_Free_Mesh(me->edit_btmesh->bm);
+
+ me->edit_btmesh->bm = editmesh_to_bmesh(em);
+ TM_RecalcTesselation(me->edit_btmesh);
+}
+
+
void mesh_update_customdata_pointers(Mesh *me)
{
me->mvert = CustomData_get_layer(&me->vdata, CD_MVERT);
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index c96f0af0ffa..ad48814f21c 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -6023,6 +6023,80 @@ static void collisionModifier_deformVerts(
}
+
+/* Surface */
+
+static void surfaceModifier_initData(ModifierData *md)
+{
+ SurfaceModifierData *surmd = (SurfaceModifierData*) md;
+
+ surmd->bvhtree = NULL;
+}
+
+static void surfaceModifier_freeData(ModifierData *md)
+{
+ SurfaceModifierData *surmd = (SurfaceModifierData*) md;
+
+ if (surmd)
+ {
+ if(surmd->bvhtree) {
+ free_bvhtree_from_mesh(surmd->bvhtree);
+ MEM_freeN(surmd->bvhtree);
+ }
+
+ surmd->dm->release(surmd->dm);
+
+ surmd->bvhtree = NULL;
+ surmd->dm = NULL;
+ }
+}
+
+static int surfaceModifier_dependsOnTime(ModifierData *md)
+{
+ return 1;
+}
+
+static void surfaceModifier_deformVerts(
+ ModifierData *md, Object *ob, DerivedMesh *derivedData,
+ float (*vertexCos)[3], int numVerts)
+{
+ SurfaceModifierData *surmd = (SurfaceModifierData*) md;
+ unsigned int numverts = 0, i = 0;
+
+ if(surmd->dm)
+ surmd->dm->release(surmd->dm);
+
+ /* if possible use/create DerivedMesh */
+ if(derivedData) surmd->dm = CDDM_copy(derivedData);
+ else if(ob->type==OB_MESH) surmd->dm = CDDM_from_mesh(ob->data, ob);
+
+ if(!ob->pd)
+ {
+ printf("surfaceModifier_deformVerts: Should not happen!\n");
+ return;
+ }
+
+ if(surmd->dm)
+ {
+ CDDM_apply_vert_coords(surmd->dm, vertexCos);
+ CDDM_calc_normals(surmd->dm);
+
+ numverts = surmd->dm->getNumVerts ( surmd->dm );
+
+ /* convert to global coordinates */
+ for(i = 0; i<numverts; i++)
+ Mat4MulVecfl(ob->obmat, CDDM_get_vert(surmd->dm, i)->co);
+
+ if(surmd->bvhtree)
+ free_bvhtree_from_mesh(surmd->bvhtree);
+ else
+ surmd->bvhtree = MEM_callocN(sizeof(BVHTreeFromMesh), "BVHTreeFromMesh");
+
+ bvhtree_from_mesh_faces(surmd->bvhtree, surmd->dm, 0.0, 2, 6);
+ }
+}
+
+
/* Boolean */
static void booleanModifier_copyData(ModifierData *md, ModifierData *target)
@@ -6071,22 +6145,44 @@ static DerivedMesh *booleanModifier_applyModifier(
{
// XXX doesn't handle derived data
BooleanModifierData *bmd = (BooleanModifierData*) md;
+ DerivedMesh *dm = mesh_get_derived_final(md->scene, bmd->object, CD_MASK_BAREMESH);
/* we do a quick sanity check */
- if(((Mesh *)ob->data)->totface > 3
- && bmd->object && ((Mesh *)bmd->object->data)->totface > 3) {
- DerivedMesh *result = NewBooleanDerivedMesh(bmd->object, ob,
+ if(dm && (derivedData->getNumFaces(derivedData) > 3)
+ && bmd->object && dm->getNumFaces(dm) > 3) {
+ DerivedMesh *result = NewBooleanDerivedMesh(dm, bmd->object, derivedData, ob,
1 + bmd->operation);
+ if(dm)
+ dm->release(dm);
+
/* if new mesh returned, return it; otherwise there was
* an error, so delete the modifier object */
if(result)
return result;
else
bmd->object = NULL;
- }
+ }
+
+ if(dm)
+ dm->release(dm);
- return derivedData;
+ return derivedData;
+}
+
+CustomDataMask booleanModifier_requiredDataMask(ModifierData *md)
+{
+ CustomDataMask dataMask = (1 << CD_MTFACE) + (1 << CD_MEDGE);
+
+ dataMask |= (1 << CD_MDEFORMVERT);
+
+ /* particles only need this if they are after a non deform modifier, and
+ * the modifier stack will only create them in that case. */
+// dataMask |= CD_MASK_ORIGSPACE;
+
+// dataMask |= CD_MASK_ORCO;
+
+ return dataMask;
}
/* Particles */
@@ -6380,6 +6476,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED)){
float min_r[3], max_r[3];
+ INIT_MINMAX(min_r, max_r);
dm->getMinMax(dm, min_r, max_r);
min_co=min_r[track];
max_co=max_r[track];
@@ -7190,7 +7287,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
pa= pars+i;
/* get particle state */
- psys_particle_on_emitter(psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,loc0,nor,0,0,0,0);
+ psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc0,nor,0,0,0,0);
Mat4MulVecfl(ob->obmat,loc0);
state.time=cfra;
@@ -7246,7 +7343,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
*mf = source;
- test_index_face(mf, &explode->faceData, i, (mf->v4 ? 4 : 3));
+ test_index_face(mf, &explode->faceData, i, (orig_v4 ? 4 : 3));
}
MEM_printmemlist_stats();
@@ -7543,6 +7640,7 @@ static void meshdeformModifier_do(
DerivedMesh *tmpdm, *cagedm;
MDeformVert *dvert = NULL;
MDeformWeight *dw;
+ EditMesh *em = BKE_mesh_get_editmesh(me);
MVert *cagemvert;
float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
float weight, totweight, fac, co[3], *weights, (*dco)[3], (*bindcos)[3];
@@ -7556,6 +7654,7 @@ static void meshdeformModifier_do(
tmpdm= editbmesh_get_derived_cage_and_final(md->scene, ob, bem, &cagedm, 0);
if(tmpdm)
tmpdm->release(tmpdm);
+ BKE_mesh_end_editmesh(me, em);
}
else
cagedm= mmd->object->derivedFinal;
@@ -8268,16 +8367,24 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti->deformVerts = collisionModifier_deformVerts;
// mti->copyData = collisionModifier_copyData;
+ mti = INIT_TYPE(Surface);
+ mti->type = eModifierTypeType_OnlyDeform;
+ mti->initData = surfaceModifier_initData;
+ mti->flags = eModifierTypeFlag_AcceptsMesh;
+ mti->dependsOnTime = surfaceModifier_dependsOnTime;
+ mti->freeData = surfaceModifier_freeData;
+ mti->deformVerts = surfaceModifier_deformVerts;
+
mti = INIT_TYPE(Boolean);
mti->type = eModifierTypeType_Nonconstructive;
mti->flags = eModifierTypeFlag_AcceptsMesh
- | eModifierTypeFlag_RequiresOriginalData
| eModifierTypeFlag_UsesPointCache;
mti->copyData = booleanModifier_copyData;
mti->isDisabled = booleanModifier_isDisabled;
mti->applyModifier = booleanModifier_applyModifier;
mti->foreachObjectLink = booleanModifier_foreachObjectLink;
mti->updateDepgraph = booleanModifier_updateDepgraph;
+ mti->requiredDataMask = booleanModifier_requiredDataMask;
mti = INIT_TYPE(MeshDeform);
mti->type = eModifierTypeType_OnlyDeform;
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 1acad4e9e86..941e73982a5 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1739,7 +1739,8 @@ void ntreeSolveOrder(bNodeTree *ntree)
might be different for editor or for "real" use... */
}
-/* should be callback! */
+/* Should be callback! */
+/* Do not call execs here */
void NodeTagChanged(bNodeTree *ntree, bNode *node)
{
if(ntree->type==NTREE_COMPOSIT) {
@@ -1753,8 +1754,6 @@ void NodeTagChanged(bNodeTree *ntree, bNode *node)
}
node->need_exec= 1;
}
- else if(ntree->type == NTREE_TEXTURE)
- ntreeTexUpdatePreviews(ntree);
}
void NodeTagIDChanged(bNodeTree *ntree, ID *id)
@@ -2067,6 +2066,11 @@ void ntreeBeginExecTree(bNodeTree *ntree)
/* tag used outputs, so we know when we can skip operations */
for(node= ntree->nodes.first; node; node= node->next) {
bNodeSocket *sock;
+
+ /* composite has own need_exec tag handling */
+ if(ntree->type!=NTREE_COMPOSIT)
+ node->need_exec= 1;
+
for(sock= node->inputs.first; sock; sock= sock->next) {
if(sock->link) {
ns= ntree->stack + sock->link->fromsock->stack_index;
@@ -2075,9 +2079,22 @@ void ntreeBeginExecTree(bNodeTree *ntree)
}
else
sock->ns.sockettype= sock->type;
+
+ if(sock->link) {
+ bNodeLink *link= sock->link;
+ /* this is the test for a cyclic case */
+ if(link->fromnode && link->tonode) {
+ if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF);
+ else {
+ node->need_exec= 0;
+ }
+ }
+ }
}
+
if(node->type==NODE_GROUP && node->id)
group_tag_used_outputs(node, ntree->stack);
+
}
if(ntree->type==NTREE_COMPOSIT)
@@ -2160,13 +2177,15 @@ void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread)
}
for(node= ntree->nodes.first; node; node= node->next) {
- if(node->typeinfo->execfunc) {
- node_get_stack(node, stack, nsin, nsout);
- node->typeinfo->execfunc(callerdata, node, nsin, nsout);
- }
- else if(node->type==NODE_GROUP && node->id) {
- node_get_stack(node, stack, nsin, nsout);
- node_group_execute(stack, callerdata, node, nsin, nsout);
+ if(node->need_exec) {
+ if(node->typeinfo->execfunc) {
+ node_get_stack(node, stack, nsin, nsout);
+ node->typeinfo->execfunc(callerdata, node, nsin, nsout);
+ }
+ else if(node->type==NODE_GROUP && node->id) {
+ node_get_stack(node, stack, nsin, nsout);
+ node_group_execute(stack, callerdata, node, nsin, nsout);
+ }
}
}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 2c851a1115a..77775e431f3 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1643,7 +1643,7 @@ static void give_parvert(Object *par, int nr, float *vec)
if(par->type==OB_MESH) {
Mesh *me= par->data;
- em = EM_GetEditMesh(me);
+ em = BKE_mesh_get_editmesh(me);
if(em) {
EditVert *eve;
@@ -1654,7 +1654,7 @@ static void give_parvert(Object *par, int nr, float *vec)
break;
}
}
- EM_EndEditMesh(me, em);
+ BKE_mesh_end_editmesh(me, em);
}
else {
DerivedMesh *dm = par->derivedFinal;
@@ -2299,7 +2299,7 @@ void object_handle_update(Scene *scene, Object *ob)
if(ob->type==OB_MESH) {
BMEditMesh *em = ((Mesh*)ob->data)->edit_btmesh;
- // here was vieweditdatamask? XXX
+ // here was vieweditdatamask? XXX
if(ob==scene->obedit) {
makeDerivedMesh(scene, ob, em, CD_MASK_BAREMESH);
} else
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 2b1dcc782c6..7d998a481f6 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -1,7 +1,7 @@
/* particle.c
*
*
- * $Id: particle.c $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -1460,7 +1460,7 @@ static void do_prekink(ParticleKey *state, ParticleKey *par, float *par_rot, flo
case PART_KINK_WAVE:
vec[axis]=1.0;
if(obmat)
- Mat4MulVecfl(obmat,vec);
+ Mat4Mul3Vecfl(obmat,vec);
if(par_rot)
QuatMulVecf(par_rot,vec);
@@ -1806,10 +1806,13 @@ void psys_find_parents(Object *ob, ParticleSystemModifierData *psmd, ParticleSys
int from=PART_FROM_FACE;
totparent=(int)(totchild*part->parents*0.3);
+ if(G.rendering && part->child_nbr && part->ren_child_nbr)
+ totparent*=(float)part->child_nbr/(float)part->ren_child_nbr;
+
tree=BLI_kdtree_new(totparent);
for(p=0,cpa=psys->child; p<totparent; p++,cpa++){
- psys_particle_on_emitter(psmd,from,cpa->num,-1,cpa->fuv,cpa->foffset,co,0,0,0,orco,0);
+ psys_particle_on_emitter(psmd,from,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,0,0,0,orco,0);
BLI_kdtree_insert(tree, p, orco, NULL);
}
@@ -1873,6 +1876,10 @@ int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, in
if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
totparent=(int)(totchild*part->parents*0.3);
+
+ if(G.rendering && part->child_nbr && part->ren_child_nbr)
+ totparent*=(float)part->child_nbr/(float)part->ren_child_nbr;
+
/* part->parents could still be 0 so we can't test with totparent */
between=1;
}
@@ -1905,6 +1912,7 @@ int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, in
ctx->steps= steps;
ctx->totchild= totchild;
ctx->totparent= totparent;
+ ctx->parent_pass= 0;
ctx->cfra= cfra;
psys->lattice = psys_get_lattice(scene, ob, psys);
@@ -1944,14 +1952,14 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
ParticleCacheKey *state, *par = NULL, *key[4];
ParticleData *pa=NULL;
ParticleTexture ptex;
- float *cpa_fuv=0;
+ float *cpa_fuv=0, *par_rot=0;
float co[3], orco[3], ornor[3], t, rough_t, cpa_1st[3], dvec[3];
float branch_begin, branch_end, branch_prob, branchfac, rough_rand;
float pa_rough1, pa_rough2, pa_roughe;
float length, pa_length, pa_clump, pa_kink, pa_effector;
float max_length = 1.0f, cur_length = 0.0f;
float eff_length, eff_vec[3];
- int k, cpa_num, guided=0;
+ int k, cpa_num, guided = 0;
short cpa_from;
if(part->flag & PART_BRANCHING) {
@@ -2055,9 +2063,10 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
ptex.clump=1.0;
ptex.kink=1.0;
ptex.rough= 1.0;
+ ptex.exist= 1.0;
get_cpa_texture(ctx->dm,ctx->ma,cpa_num,cpa_fuv,orco,&ptex,
- MAP_PA_LENGTH|MAP_PA_CLUMP|MAP_PA_KINK|MAP_PA_ROUGH);
+ MAP_PA_DENS|MAP_PA_LENGTH|MAP_PA_CLUMP|MAP_PA_KINK|MAP_PA_ROUGH);
pa_length=ptex.length;
pa_clump=ptex.clump;
@@ -2067,6 +2076,11 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
pa_roughe=ptex.rough;
pa_effector= 1.0f;
+ if(ptex.exist < cpa->rand[1]) {
+ keys->steps = -1;
+ return;
+ }
+
if(ctx->vg_length)
pa_length*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_length);
if(ctx->vg_clump)
@@ -2137,15 +2151,16 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
t=(float)k/(float)ctx->steps;
if(ctx->totparent){
- if(i>=ctx->totparent)
- /* this is not threadsafe, but should only happen for
- * branching particles particles, which are not threaded */
+ if(i>=ctx->totparent) {
+ /* this is now threadsafe, virtual parents are calculated before rest of children */
par = cache[cpa->parent] + k;
+ }
else
par=0;
}
else if(cpa->parent>=0){
par=pcache[cpa->parent]+k;
+ par_rot = par->rot;
}
/* apply different deformations to the child path */
@@ -2155,7 +2170,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
if(guided==0){
if(part->kink)
- do_prekink((ParticleKey*)state, (ParticleKey*)par, par->rot, t,
+ do_prekink((ParticleKey*)state, (ParticleKey*)par, par_rot, t,
part->kink_freq * pa_kink, part->kink_shape, part->kink_amp, part->kink, part->kink_axis, ob->obmat);
do_clump((ParticleKey*)state, (ParticleKey*)par, t, part->clumpfac, part->clumppow, pa_clump);
@@ -2254,10 +2269,15 @@ static void *exec_child_path_cache(void *data)
ParticleSystem *psys= ctx->psys;
ParticleCacheKey **cache= psys->childcache;
ChildParticle *cpa;
- int i, totchild= ctx->totchild;
+ int i, totchild= ctx->totchild, first= 0;
+
+ if(thread->tot > 1){
+ first= ctx->parent_pass? 0 : ctx->totparent;
+ totchild= ctx->parent_pass? ctx->totparent : ctx->totchild;
+ }
- cpa= psys->child + thread->num;
- for(i=thread->num; i<totchild; i+=thread->tot, cpa+=thread->tot)
+ cpa= psys->child + first + thread->num;
+ for(i=first+thread->num; i<totchild; i+=thread->tot, cpa+=thread->tot)
psys_thread_create_path(thread, cpa, cache[i], i);
return 0;
@@ -2296,6 +2316,22 @@ void psys_cache_child_paths(Scene *scene, Object *ob, ParticleSystem *psys, floa
totthread= pthreads[0].tot;
if(totthread > 1) {
+
+ /* make virtual child parents thread safe by calculating them first */
+ if(totparent) {
+ BLI_init_threads(&threads, exec_child_path_cache, totthread);
+
+ for(i=0; i<totthread; i++) {
+ pthreads[i].ctx->parent_pass = 1;
+ BLI_insert_thread(&threads, &pthreads[i]);
+ }
+
+ BLI_end_threads(&threads);
+
+ for(i=0; i<totthread; i++)
+ pthreads[i].ctx->parent_pass = 0;
+ }
+
BLI_init_threads(&threads, exec_child_path_cache, totthread);
for(i=0; i<totthread; i++)
@@ -3171,6 +3207,8 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float
ptex->kink= texture_value_blend(def,ptex->kink,value,var,blend,neg & MAP_PA_KINK);
if((event & mtex->pmapto) & MAP_PA_ROUGH)
ptex->rough= texture_value_blend(def,ptex->rough,value,var,blend,neg & MAP_PA_ROUGH);
+ if((event & mtex->pmapto) & MAP_PA_DENS)
+ ptex->exist= texture_value_blend(def,ptex->exist,value,var,blend,neg & MAP_PA_DENS);
}
}
if(event & MAP_PA_TIME) { CLAMP(ptex->time,0.0,1.0); }
@@ -3178,6 +3216,7 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float
if(event & MAP_PA_CLUMP) { CLAMP(ptex->clump,0.0,1.0); }
if(event & MAP_PA_KINK) { CLAMP(ptex->kink,0.0,1.0); }
if(event & MAP_PA_ROUGH) { CLAMP(ptex->rough,0.0,1.0); }
+ if(event & MAP_PA_DENS) { CLAMP(ptex->exist,0.0,1.0); }
}
void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd, ParticleSystem *psys, ParticleData *pa, ParticleTexture *ptex, int event)
{
@@ -3496,6 +3535,10 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
totparent=(int)(totchild*part->parents*0.3);
+
+ if(G.rendering && part->child_nbr && part->ren_child_nbr)
+ totparent*=(float)part->child_nbr/(float)part->ren_child_nbr;
+
/* part->parents could still be 0 so we can't test with totparent */
between=1;
}
@@ -3872,3 +3915,76 @@ void psys_get_dupli_path_transform(Object *ob, ParticleSystem *psys, ParticleSys
*scale= len;
}
+void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3], float zvec[3], float center[3])
+{
+ float onevec[3] = {0.0f,0.0f,0.0f}, tvec[3], tvec2[3];
+
+ xvec[0] = 1.0f; xvec[1] = 0.0f; xvec[2] = 0.0f;
+ yvec[0] = 0.0f; yvec[1] = 1.0f; yvec[2] = 0.0f;
+
+ if(bb->align < PART_BB_VIEW)
+ onevec[bb->align]=1.0f;
+
+ if(bb->lock && (bb->align == PART_BB_VIEW)) {
+ VECCOPY(xvec, bb->ob->obmat[0]);
+ Normalize(xvec);
+
+ VECCOPY(yvec, bb->ob->obmat[1]);
+ Normalize(yvec);
+
+ VECCOPY(zvec, bb->ob->obmat[2]);
+ Normalize(zvec);
+ }
+ else if(bb->align == PART_BB_VEL) {
+ float temp[3];
+
+ VECCOPY(temp, bb->vel);
+ Normalize(temp);
+
+ VECSUB(zvec, bb->ob->obmat[3], bb->vec);
+
+ if(bb->lock) {
+ float fac = -Inpf(zvec, temp);
+
+ VECADDFAC(zvec, zvec, temp, fac);
+ }
+ Normalize(zvec);
+
+ Crossf(xvec,temp,zvec);
+ Normalize(xvec);
+
+ Crossf(yvec,zvec,xvec);
+ }
+ else {
+ VECSUB(zvec, bb->ob->obmat[3], bb->vec);
+ if(bb->lock)
+ zvec[bb->align] = 0.0f;
+ Normalize(zvec);
+
+ if(bb->align < PART_BB_VIEW)
+ Crossf(xvec, onevec, zvec);
+ else
+ Crossf(xvec, bb->ob->obmat[1], zvec);
+ Normalize(xvec);
+
+ Crossf(yvec,zvec,xvec);
+ }
+
+ VECCOPY(tvec, xvec);
+ VECCOPY(tvec2, yvec);
+
+ VecMulf(xvec, cos(bb->tilt * (float)M_PI));
+ VecMulf(tvec2, sin(bb->tilt * (float)M_PI));
+ VECADD(xvec, xvec, tvec2);
+
+ VecMulf(yvec, cos(bb->tilt * (float)M_PI));
+ VecMulf(tvec, -sin(bb->tilt * (float)M_PI));
+ VECADD(yvec, yvec, tvec);
+
+ VecMulf(xvec, bb->size);
+ VecMulf(yvec, bb->size);
+
+ VECADDFAC(center, bb->vec, xvec, bb->offset[0]);
+ VECADDFAC(center, center, yvec, bb->offset[1]);
+}
+
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 928730fb1f0..f8b1852b728 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -1,7 +1,7 @@
/* particle_system.c
*
*
- * $Id: particle_system.c $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -75,6 +75,7 @@
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_scene.h"
+#include "BKE_bvhutils.h"
#include "PIL_time.h"
@@ -1294,7 +1295,8 @@ int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, Derive
MEM_freeN(sum);
/* for hair, sort by origindex, allows optimizations in rendering */
- if(part->type == PART_HAIR) {
+ /* however with virtual parents the children need to be in random order */
+ if(part->type == PART_HAIR && !(part->childtype==PART_CHILD_FACES && part->parents!=0.0)) {
COMPARE_ORIG_INDEX= dm->getFaceDataArray(dm, CD_ORIGINDEX);
if(COMPARE_ORIG_INDEX)
qsort(index, totpart, sizeof(int), compare_orig_index);
@@ -1611,7 +1613,7 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps
NormalQuat(pa->r_rot);
- if(part->distr!=PART_DISTR_GRID && part->from != PART_FROM_VERT){
+ if(part->type!=PART_HAIR && part->distr!=PART_DISTR_GRID && part->from != PART_FROM_VERT){
/* any unique random number will do (r_ave[0]) */
if(ptex.exist < 0.5*(1.0+pa->r_ave[0]))
pa->flag |= PARS_UNEXIST;
@@ -1733,6 +1735,8 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
VECSUB(p_vel,pa->r_ve,p_vel);
Normalize(p_vel);
VecMulf(p_vel,speed);
+
+ VECCOPY(pa->fuv,loc); /* abusing pa->fuv (not used for "from particle") for storing emit location */
}
else{
/* get precise emitter matrix if particle is born */
@@ -2447,7 +2451,6 @@ void psys_end_effectors(ParticleSystem *psys)
if(ec->rng)
rng_free(ec->rng);
-
}
BLI_freelistN(lb);
@@ -2486,7 +2489,12 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa
ec->locations=MEM_callocN(totpart*3*sizeof(float),"particle locations");
for(p=0,pa=psys->particles; p<totpart; p++, pa++){
- psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,0,0);
+ if(part->from == PART_FROM_PARTICLE) {
+ VECCOPY(loc, pa->fuv);
+ }
+ else
+ psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,0,0);
+
Mat4MulVecfl(ob->obmat,loc);
ec->distances[p]=VecLenf(loc,vec);
VECSUB(loc,loc,vec);
@@ -2539,6 +2547,7 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Scene *scene,
ParticleData *epa;
ParticleKey estate;
PartDeflect *pd;
+ SurfaceModifierData *surmd = NULL;
ListBase *lb=&psys->effectors;
ParticleEffectorCache *ec;
float distance, vec_to_part[3];
@@ -2566,8 +2575,34 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Scene *scene,
if(psys->part->type!=PART_HAIR && psys->part->integrator)
where_is_object_time(scene, eob,cfra);
- /* use center of object for distance calculus */
- VecSubf(vec_to_part, state->co, eob->obmat[3]);
+ if(pd && pd->flag&PFIELD_SURFACE) {
+ surmd = (SurfaceModifierData *)modifiers_findByType ( eob, eModifierType_Surface );
+ }
+ if(surmd) {
+ /* closest point in the object surface is an effector */
+ BVHTreeNearest nearest;
+ float velocity[3];
+
+ nearest.index = -1;
+ nearest.dist = FLT_MAX;
+
+ /* using velocity corrected location allows for easier sliding over effector surface */
+ VecCopyf(velocity, state->vel);
+ VecMulf(velocity, psys_get_timestep(psys->part));
+ VecAddf(vec_to_part, state->co, velocity);
+
+ BLI_bvhtree_find_nearest(surmd->bvhtree->tree, vec_to_part, &nearest, surmd->bvhtree->nearest_callback, surmd->bvhtree);
+
+ if(nearest.index != -1) {
+ VecSubf(vec_to_part, state->co, nearest.co);
+ }
+ else
+ vec_to_part[0] = vec_to_part[1] = vec_to_part[2] = 0.0f;
+ }
+ else
+ /* use center of object for distance calculus */
+ VecSubf(vec_to_part, state->co, eob->obmat[3]);
+
distance = VecLength(vec_to_part);
falloff=effector_falloff(pd,eob->obmat[2],vec_to_part);
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 22f26741c55..5c936c3ab39 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -243,6 +243,11 @@ Scene *add_scene(char *name)
sce->r.threads= 1;
sce->r.stereomode = 1; // no stereo
+ sce->r.domeangle = 180;
+ sce->r.domemode = 1;
+ sce->r.domesize = 1.0f;
+ sce->r.domeres = 4;
+ sce->r.domeresbuf = 1.0f;
sce->r.simplify_subsurf= 6;
sce->r.simplify_particles= 1.0f;
@@ -708,3 +713,14 @@ float get_render_aosss_error(RenderData *r, float error)
return error;
}
+void free_dome_warp_text(struct Text *txt)
+{
+ Scene *scene;
+
+ scene = G.main->scene.first;
+ while(scene) {
+ if (scene->r.dometext == txt)
+ scene->r.dometext = NULL;
+ scene = scene->id.next;
+ }
+} \ No newline at end of file
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 483876e5e05..e25e4be90c8 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -53,11 +53,28 @@ static ListBase spacetypes= {NULL, NULL};
static void spacetype_free(SpaceType *st)
{
ARegionType *art;
+ PanelType *pt;
+ HeaderType *ht;
+ MenuType *mt;
for(art= st->regiontypes.first; art; art= art->next) {
BLI_freelistN(&art->drawcalls);
+
+ for(pt= art->paneltypes.first; pt; pt= pt->next)
+ if(pt->py_free)
+ pt->py_free(pt->py_data);
+
+ for(ht= art->headertypes.first; ht; ht= ht->next)
+ if(ht->py_free)
+ ht->py_free(ht->py_data);
+
+ for(mt= art->menutypes.first; mt; mt= mt->next)
+ if(mt->py_free)
+ mt->py_free(mt->py_data);
+
BLI_freelistN(&art->paneltypes);
BLI_freelistN(&art->headertypes);
+ BLI_freelistN(&art->menutypes);
}
BLI_freelistN(&st->regiontypes);
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index 66cc92a19af..8fb4ed8e272 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -38,6 +38,7 @@
#include "DNA_modifier_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_mesh_types.h"
+#include "DNA_scene_types.h"
#include "BKE_shrinkwrap.h"
#include "BKE_DerivedMesh.h"
@@ -47,6 +48,7 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_displist.h"
#include "BKE_global.h"
+#include "BKE_mesh.h"
#include "BKE_subsurf.h"
#include "BKE_mesh.h"
#include "BKE_tessmesh.h"
@@ -95,7 +97,7 @@ typedef void ( *Shrinkwrap_ForeachVertexCallback) (DerivedMesh *target, float *c
/* get derived mesh */
//TODO is anyfunction that does this? returning the derivedFinal witouth we caring if its in edit mode or not?
-static DerivedMesh *object_get_derived_final(struct Scene *scene, Object *ob, CustomDataMask dataMask)
+DerivedMesh *object_get_derived_final(struct Scene *scene, Object *ob, CustomDataMask dataMask)
{
Mesh *me= ob->data;
BMEditMesh *em = me->edit_btmesh;
@@ -104,7 +106,7 @@ static DerivedMesh *object_get_derived_final(struct Scene *scene, Object *ob, Cu
{
DerivedMesh *final = NULL;
editbmesh_get_derived_cage_and_final(scene, ob, em, &final, dataMask);
-
+
return final;
}
else
@@ -152,7 +154,6 @@ static float squared_dist(const float *a, const float *b)
return INPR(tmp, tmp);
}
-
/*
* Shrinkwrap to the nearest vertex
*
@@ -187,8 +188,17 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
float weight = vertexgroup_get_vertex_weight(calc->dvert, i, calc->vgroup);
if(weight == 0.0f) continue;
- VECCOPY(tmp_co, co);
- space_transform_apply(&calc->local2target, tmp_co); //Convert the coordinates to the tree coordinates
+
+ //Convert the vertex to tree coordinates
+ if(calc->vert)
+ {
+ VECCOPY(tmp_co, calc->vert[i].co);
+ }
+ else
+ {
+ VECCOPY(tmp_co, co);
+ }
+ space_transform_apply(&calc->local2target, tmp_co);
//Use local proximity heuristics (to reduce the nearest search)
//
@@ -291,174 +301,117 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, struct S
int i;
//Options about projection direction
- const char use_normal = calc->smd->shrinkOpts;
- float proj_axis[3] = {0.0f, 0.0f, 0.0f};
- MVert *vert = NULL; //Needed in case of vertex normal
- DerivedMesh* ss_mesh = NULL;
+ const char use_normal = calc->smd->shrinkOpts;
+ float proj_axis[3] = {0.0f, 0.0f, 0.0f};
//Raycast and tree stuff
BVHTreeRayHit hit;
- BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh; //target
+ BVHTreeFromMesh treeData= NULL_BVHTreeFromMesh;
//auxiliar target
- DerivedMesh * aux_mesh = NULL;
- BVHTreeFromMesh auxData= NULL_BVHTreeFromMesh;
+ DerivedMesh *auxMesh = NULL;
+ BVHTreeFromMesh auxData = NULL_BVHTreeFromMesh;
SpaceTransform local2aux;
-do
-{
+ //If the user doesn't allows to project in any direction of projection axis
+ //then theres nothing todo.
+ if((use_normal & (MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR | MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR)) == 0)
+ return;
+
//Prepare data to retrieve the direction in which we should project each vertex
if(calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL)
{
- //No Mvert information: jump to "free memory and return" part
- if(calc->original == NULL) break;
-
- if(calc->smd->subsurfLevels)
- {
- SubsurfModifierData smd;
- memset(&smd, 0, sizeof(smd));
- smd.subdivType = ME_CC_SUBSURF; //catmull clark
- smd.levels = calc->smd->subsurfLevels; //levels
-
- ss_mesh = subsurf_make_derived_from_derived(calc->original, &smd, FALSE, NULL, 0, 0);
-
- if(ss_mesh)
- {
- vert = ss_mesh->getVertDataArray(ss_mesh, CD_MVERT);
- if(vert)
- {
- //TRICKY: this code assumes subsurface will have the transformed original vertices
- //in their original order at the end of the vert array.
- vert = vert
- + ss_mesh->getNumVerts(ss_mesh)
- - calc->original->getNumVerts(calc->original);
- }
- }
-
- //To make sure we are not letting any memory behind
- assert(smd.emCache == NULL);
- assert(smd.mCache == NULL);
- }
- else
- vert = calc->original->getVertDataArray(calc->original, CD_MVERT);
-
- //Not able to get vert information: jump to "free memory and return" part
- if(vert == NULL) break;
+ if(calc->vert == NULL) return;
}
else
{
- //The code supports any axis that is a combination of X,Y,Z.. altought currently UI only allows to set the 3 diferent axis
+ //The code supports any axis that is a combination of X,Y,Z
+ //altought currently UI only allows to set the 3 diferent axis
if(calc->smd->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_X_AXIS) proj_axis[0] = 1.0f;
if(calc->smd->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Y_AXIS) proj_axis[1] = 1.0f;
if(calc->smd->projAxis & MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS) proj_axis[2] = 1.0f;
Normalize(proj_axis);
- //Invalid projection direction: jump to "free memory and return" part
- if(INPR(proj_axis, proj_axis) < FLT_EPSILON) break;
+ //Invalid projection direction
+ if(INPR(proj_axis, proj_axis) < FLT_EPSILON)
+ return;
}
- //If the user doesn't allows to project in any direction of projection axis... then theres nothing todo.
- if((use_normal & (MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR | MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR)) == 0)
- break; //jump to "free memory and return" part
-
-
- //Build target tree
- BENCH(bvhtree_from_mesh_faces(&treeData, calc->target, calc->keepDist, 4, 6));
- if(treeData.tree == NULL)
- break; //jump to "free memory and return" part
-
-
- //Build auxiliar target
if(calc->smd->auxTarget)
{
+ auxMesh = object_get_derived_final(scene, calc->smd->auxTarget, CD_MASK_BAREMESH);
space_transform_setup( &local2aux, calc->ob, calc->smd->auxTarget);
-
- aux_mesh = CDDM_copy( object_get_derived_final(scene, calc->smd->auxTarget, CD_MASK_BAREMESH) ); //TODO currently we need a copy in case object_get_derived_final returns an emDM that does not defines getVertArray or getFace array
- if(aux_mesh)
- BENCH(bvhtree_from_mesh_faces(&auxData, aux_mesh, 0.0, 4, 6));
- else
- printf("Auxiliar target finalDerived mesh is null\n");
}
+ //After sucessufuly build the trees, start projection vertexs
+ if( bvhtree_from_mesh_faces(&treeData, calc->target, calc->keepDist, 4, 6)
+ && (auxMesh == NULL || bvhtree_from_mesh_faces(&auxData, auxMesh, 0.0, 4, 6)))
+ {
- //Now, everything is ready to project the vertexs!
#ifndef __APPLE__
#pragma omp parallel for private(i,hit) schedule(static)
#endif
- for(i = 0; i<calc->numVerts; ++i)
- {
- float *co = calc->vertexCos[i];
- float tmp_co[3], tmp_no[3];
- float lim = 10000.0f; //TODO: we should use FLT_MAX here, but sweepsphere code isnt prepared for that
- float weight = vertexgroup_get_vertex_weight(calc->dvert, i, calc->vgroup);
-
- if(weight == 0.0f) continue;
-
- if(ss_mesh)
- {
- VECCOPY(tmp_co, vert[i].co);
- }
- else
+ for(i = 0; i<calc->numVerts; ++i)
{
- VECCOPY(tmp_co, co);
- }
+ float *co = calc->vertexCos[i];
+ float tmp_co[3], tmp_no[3];
+ float weight = vertexgroup_get_vertex_weight(calc->dvert, i, calc->vgroup);
+ if(weight == 0.0f) continue;
- if(vert)
- NormalShortToFloat(tmp_no, vert[i].no);
- else
- VECCOPY( tmp_no, proj_axis );
-
+ if(calc->vert)
+ {
+ VECCOPY(tmp_co, calc->vert[i].co);
+ if(calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL)
+ NormalShortToFloat(tmp_no, calc->vert[i].no);
+ else
+ VECCOPY(tmp_no, proj_axis);
+ }
+ else
+ {
+ VECCOPY(tmp_co, co);
+ VECCOPY(tmp_no, proj_axis);
+ }
- hit.index = -1;
- hit.dist = lim;
+ hit.index = -1;
+ hit.dist = 10000.0f; //TODO: we should use FLT_MAX here, but sweepsphere code isnt prepared for that
- //Project over positive direction of axis
- if(use_normal & MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR)
- {
+ //Project over positive direction of axis
+ if(use_normal & MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR)
+ {
- if(auxData.tree)
- normal_projection_project_vertex(0, tmp_co, tmp_no, &local2aux, auxData.tree, &hit, auxData.raycast_callback, &auxData);
+ if(auxData.tree)
+ normal_projection_project_vertex(0, tmp_co, tmp_no, &local2aux, auxData.tree, &hit, auxData.raycast_callback, &auxData);
- normal_projection_project_vertex(calc->smd->shrinkOpts, tmp_co, tmp_no, &calc->local2target, treeData.tree, &hit, treeData.raycast_callback, &treeData);
- }
+ normal_projection_project_vertex(calc->smd->shrinkOpts, tmp_co, tmp_no, &calc->local2target, treeData.tree, &hit, treeData.raycast_callback, &treeData);
+ }
- //Project over negative direction of axis
- if(use_normal & MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR)
- {
- float inv_no[3] = { -tmp_no[0], -tmp_no[1], -tmp_no[2] };
+ //Project over negative direction of axis
+ if(use_normal & MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR)
+ {
+ float inv_no[3] = { -tmp_no[0], -tmp_no[1], -tmp_no[2] };
- if(auxData.tree)
- normal_projection_project_vertex(0, tmp_co, inv_no, &local2aux, auxData.tree, &hit, auxData.raycast_callback, &auxData);
+ if(auxData.tree)
+ normal_projection_project_vertex(0, tmp_co, inv_no, &local2aux, auxData.tree, &hit, auxData.raycast_callback, &auxData);
- normal_projection_project_vertex(calc->smd->shrinkOpts, tmp_co, inv_no, &calc->local2target, treeData.tree, &hit, treeData.raycast_callback, &treeData);
- }
+ normal_projection_project_vertex(calc->smd->shrinkOpts, tmp_co, inv_no, &calc->local2target, treeData.tree, &hit, treeData.raycast_callback, &treeData);
+ }
- if(hit.index != -1)
- {
- VecLerpf(co, co, hit.co, weight);
+ if(hit.index != -1)
+ {
+ VecLerpf(co, co, hit.co, weight);
+ }
}
}
-
-//Simple do{} while(0) structure to allow to easily jump to the "free memory and return" part
-} while(0);
-
//free data structures
-
free_bvhtree_from_mesh(&treeData);
free_bvhtree_from_mesh(&auxData);
-
- if(aux_mesh)
- aux_mesh->release(aux_mesh);
-
- if(ss_mesh)
- ss_mesh->release(ss_mesh);
}
/*
@@ -474,8 +427,6 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh;
BVHTreeNearest nearest = NULL_BVHTreeNearest;
-
-
//Create a bvh-tree of the given target
BENCH(bvhtree_from_mesh_faces( &treeData, calc->target, 0.0, 2, 6));
if(treeData.tree == NULL)
@@ -501,7 +452,14 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
if(weight == 0.0f) continue;
//Convert the vertex to tree coordinates
- VECCOPY(tmp_co, co);
+ if(calc->vert)
+ {
+ VECCOPY(tmp_co, calc->vert[i].co);
+ }
+ else
+ {
+ VECCOPY(tmp_co, co);
+ }
space_transform_apply(&calc->local2target, tmp_co);
//Use local proximity heuristics (to reduce the nearest search)
@@ -540,53 +498,89 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
}
}
-
free_bvhtree_from_mesh(&treeData);
}
/* Main shrinkwrap function */
-void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, struct Scene *scene, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts)
+void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts)
{
-
+
+ DerivedMesh *ss_mesh = NULL;
ShrinkwrapCalcData calc = NULL_ShrinkwrapCalcData;
-
+
//remove loop dependencies on derived meshs (TODO should this be done elsewhere?)
if(smd->target == ob) smd->target = NULL;
if(smd->auxTarget == ob) smd->auxTarget = NULL;
-
-
+
+
//Configure Shrinkwrap calc data
calc.smd = smd;
calc.ob = ob;
- calc.original = dm;
calc.numVerts = numVerts;
calc.vertexCos = vertexCos;
-
+
//DeformVertex
calc.vgroup = get_named_vertexgroup_num(calc.ob, calc.smd->vgroup_name);
- if(calc.original)
+ if(dm)
{
- calc.dvert = calc.original->getVertDataArray(calc.original, CD_MDEFORMVERT);
+ calc.dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
}
else if(calc.ob->type == OB_LATTICE)
{
calc.dvert = lattice_get_deform_verts(calc.ob);
}
-
-
+
+
if(smd->target)
{
- //TODO currently we need a copy in case object_get_derived_final returns an emDM that does not defines getVertArray or getFace array
- calc.target = CDDM_copy( object_get_derived_final(scene, smd->target, CD_MASK_BAREMESH) );
-
- //TODO there might be several "bugs" on non-uniform scales matrixs.. because it will no longer be nearest surface, not sphere projection
+ calc.target = object_get_derived_final(scene, smd->target, CD_MASK_BAREMESH);
+
+ //TODO there might be several "bugs" on non-uniform scales matrixs
+ //because it will no longer be nearest surface, not sphere projection
//because space has been deformed
space_transform_setup(&calc.local2target, ob, smd->target);
-
- calc.keepDist = smd->keepDist; //TODO: smd->keepDist is in global units.. must change to local
+
+ //TODO: smd->keepDist is in global units.. must change to local
+ calc.keepDist = smd->keepDist;
+ }
+
+
+
+ calc.vgroup = get_named_vertexgroup_num(calc.ob, smd->vgroup_name);
+
+ if(dm != NULL)
+ {
+ //Setup arrays to get vertexs positions, normals and deform weights
+ calc.vert = dm->getVertDataArray(dm, CD_MVERT);
+ calc.dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
+
+ //Using vertexs positions/normals as if a subsurface was applied
+ if(smd->subsurfLevels)
+ {
+ SubsurfModifierData ssmd;
+ memset(&ssmd, 0, sizeof(ssmd));
+ ssmd.subdivType = ME_CC_SUBSURF; //catmull clark
+ ssmd.levels = smd->subsurfLevels; //levels
+
+ ss_mesh = subsurf_make_derived_from_derived(dm, &ssmd, FALSE, NULL, 0, 0);
+
+ if(ss_mesh)
+ {
+ calc.vert = ss_mesh->getVertDataArray(ss_mesh, CD_MVERT);
+ if(calc.vert)
+ {
+ //TRICKY: this code assumes subsurface will have the transformed original vertices
+ //in their original order at the end of the vert array.
+ calc.vert = calc.vert + ss_mesh->getNumVerts(ss_mesh) - dm->getNumVerts(dm);
+ }
+ }
+
+ //Just to make sure we are not letting any memory behind
+ assert(ssmd.emCache == NULL);
+ assert(ssmd.mCache == NULL);
+ }
}
-
-
+
//Projecting target defined - lets work!
if(calc.target)
{
@@ -594,20 +588,20 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, struct Scene *scene,
{
case MOD_SHRINKWRAP_NEAREST_SURFACE:
BENCH(shrinkwrap_calc_nearest_surface_point(&calc));
- break;
-
+ break;
+
case MOD_SHRINKWRAP_PROJECT:
BENCH(shrinkwrap_calc_normal_projection(&calc, scene));
- break;
-
+ break;
+
case MOD_SHRINKWRAP_NEAREST_VERTEX:
BENCH(shrinkwrap_calc_nearest_vertex(&calc));
- break;
+ break;
}
}
-
+
//free memory
- if(calc.target)
- calc.target->release( calc.target );
+ if(ss_mesh)
+ ss_mesh->release(ss_mesh);
}
diff --git a/source/blender/blenkernel/intern/suggestions.c b/source/blender/blenkernel/intern/suggestions.c
index 6530909336c..dee33656332 100644
--- a/source/blender/blenkernel/intern/suggestions.c
+++ b/source/blender/blenkernel/intern/suggestions.c
@@ -1,5 +1,5 @@
/**
- * $Id: $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 47a33bdee66..8e3d59bbc58 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -1282,24 +1282,28 @@ void txt_insert_buf(Text *text, char *in_buffer)
/* Undo functions */
/******************/
-#define MAX_UNDO_TEST(x) \
- while (text->undo_pos+x >= text->undo_len) { \
- if(text->undo_len*2 > TXT_MAX_UNDO) { \
- error("Undo limit reached, buffer cleared\n"); \
- MEM_freeN(text->undo_buf); \
- text->undo_len= TXT_INIT_UNDO; \
- text->undo_buf= MEM_mallocN(text->undo_len, "undo buf"); \
- text->undo_pos=-1; \
- return; \
- } else { \
- void *tmp= text->undo_buf; \
- text->undo_buf= MEM_callocN(text->undo_len*2, "undo buf"); \
- memcpy(text->undo_buf, tmp, text->undo_len); \
- text->undo_len*=2; \
- MEM_freeN(tmp); \
- } \
+static int max_undo_test(Text *text, int x)
+{
+ while (text->undo_pos+x >= text->undo_len) {
+ if(text->undo_len*2 > TXT_MAX_UNDO) {
+ /* XXX error("Undo limit reached, buffer cleared\n"); */
+ MEM_freeN(text->undo_buf);
+ text->undo_len= TXT_INIT_UNDO;
+ text->undo_buf= MEM_mallocN(text->undo_len, "undo buf");
+ text->undo_pos=-1;
+ return 0;
+ } else {
+ void *tmp= text->undo_buf;
+ text->undo_buf= MEM_callocN(text->undo_len*2, "undo buf");
+ memcpy(text->undo_buf, tmp, text->undo_len);
+ text->undo_len*=2;
+ MEM_freeN(tmp);
+ }
}
+ return 1;
+}
+
static void dump_buffer(Text *text)
{
int i= 0;
@@ -1445,7 +1449,8 @@ void txt_print_undo(Text *text)
static void txt_undo_add_op(Text *text, int op)
{
- //XXX MAX_UNDO_TEST(2);
+ if(!max_undo_test(text, 2))
+ return;
text->undo_pos++;
text->undo_buf[text->undo_pos]= op;
@@ -1458,7 +1463,8 @@ static void txt_undo_add_block(Text *text, int op, char *buf)
length= strlen(buf);
- //XXX MAX_UNDO_TEST(length+11);
+ if(!max_undo_test(text, length+11))
+ return;
text->undo_pos++;
text->undo_buf[text->undo_pos]= op;
@@ -1492,7 +1498,8 @@ static void txt_undo_add_block(Text *text, int op, char *buf)
void txt_undo_add_toop(Text *text, int op, unsigned int froml, unsigned short fromc, unsigned int tol, unsigned short toc)
{
- //XXX MAX_UNDO_TEST(15);
+ if(!max_undo_test(text, 15))
+ return;
if (froml==tol && fromc==toc) return;
@@ -1535,7 +1542,8 @@ void txt_undo_add_toop(Text *text, int op, unsigned int froml, unsigned short fr
static void txt_undo_add_charop(Text *text, int op, char c)
{
- //XXX MAX_UNDO_TEST(4);
+ if(!max_undo_test(text, 4))
+ return;
text->undo_pos++;
text->undo_buf[text->undo_pos]= op;
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index 7278460c61c..8bad269a85e 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -107,6 +107,8 @@ World *add_world(char *name)
wrld->ao_approx_error= 0.25f;
wrld->physicsEngine= WOPHY_BULLET;//WOPHY_SUMO; Bullet by default
+ wrld->mode = WO_DBVT_CULLING; // DBVT culling by default
+ wrld->occlusionRes = 128;
wrld->preview = NULL;
return wrld;
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 8fd2426a1b6..472a6612a50 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -29,11 +29,11 @@
#include <stdlib.h>
-#include <ffmpeg/avformat.h>
-#include <ffmpeg/avcodec.h>
-#include <ffmpeg/rational.h>
-#include <ffmpeg/swscale.h>
-#include <ffmpeg/opt.h>
+#include <libavformat/avformat.h>
+#include <libavcodec/avcodec.h>
+#include <libavutil/rational.h>
+#include <libswscale/swscale.h>
+#include <libavcodec/opt.h>
#if LIBAVFORMAT_VERSION_INT < (49 << 16)
#define FFMPEG_OLD_FRAME_RATE 1
@@ -284,8 +284,8 @@ static AVFrame* generate_video_frame(uint8_t* pixels)
int height = c->height;
AVFrame* rgb_frame;
- if (c->pix_fmt != PIX_FMT_RGBA32) {
- rgb_frame = alloc_picture(PIX_FMT_RGBA32, width, height);
+ if (c->pix_fmt != PIX_FMT_BGR32) {
+ rgb_frame = alloc_picture(PIX_FMT_BGR32, width, height);
if (!rgb_frame) {
G.afbreek=1;
//XXX error("Couldn't allocate temporary frame");
@@ -309,9 +309,9 @@ static AVFrame* generate_video_frame(uint8_t* pixels)
uint8_t* end = src + width * 4;
while (src != end) {
target[3] = src[3];
- target[2] = src[0];
+ target[2] = src[2];
target[1] = src[1];
- target[0] = src[2];
+ target[0] = src[0];
target += 4;
src += 4;
@@ -325,9 +325,9 @@ static AVFrame* generate_video_frame(uint8_t* pixels)
uint8_t* src = rendered_frame + width * 4 * y;
uint8_t* end = src + width * 4;
while (src != end) {
- target[3] = src[2];
+ target[3] = src[0];
target[2] = src[1];
- target[1] = src[0];
+ target[1] = src[2];
target[0] = src[3];
target += 4;
@@ -336,7 +336,7 @@ static AVFrame* generate_video_frame(uint8_t* pixels)
}
}
- if (c->pix_fmt != PIX_FMT_RGBA32) {
+ if (c->pix_fmt != PIX_FMT_BGR32) {
sws_scale(img_convert_ctx, rgb_frame->data,
rgb_frame->linesize, 0, c->height,
current_frame->data, current_frame->linesize);
@@ -492,9 +492,11 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
c->pix_fmt = PIX_FMT_YUV420P;
}
- if (!strcmp(of->oformat->name, "mp4") ||
- !strcmp(of->oformat->name, "mov") ||
- !strcmp(of->oformat->name, "3gp")) {
+ if ((of->oformat->flags & AVFMT_GLOBALHEADER)
+// || !strcmp(of->oformat->name, "mp4")
+// || !strcmp(of->oformat->name, "mov")
+// || !strcmp(of->oformat->name, "3gp")
+ ) {
fprintf(stderr, "Using global header\n");
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
@@ -508,7 +510,7 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
/* xasp & yasp got float lately... */
- c->sample_aspect_ratio = av_d2q(
+ st->sample_aspect_ratio = c->sample_aspect_ratio = av_d2q(
((double) rd->xasp / (double) rd->yasp), 255);
set_ffmpeg_properties(rd, c, "video");
@@ -526,7 +528,7 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
current_frame = alloc_picture(c->pix_fmt, c->width, c->height);
img_convert_ctx = sws_getContext(c->width, c->height,
- PIX_FMT_RGBA32,
+ PIX_FMT_BGR32,
c->width, c->height,
c->pix_fmt,
SWS_BICUBIC,