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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2009-04-20 19:06:46 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2009-04-20 19:06:46 +0400
commit874c29cea8e6f9bc411fccf2d6f4cb07e94328d0 (patch)
tree5971e577cf7c02e05a1e37b5ad058c71a6744877 /source/blender/blenkernel
parent7555bfa793a2b0fc187c6211c56986f35b2d7b09 (diff)
parentc5bc4e4fb1a33eda8c31f2ea02e91f32f74c8fa5 (diff)
2.50: svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r19323:HEAD
Notes: * blenderbuttons and ICON_SNAP_PEEL_OBJECT were not merged.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h2
-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_curve.h6
-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_shrinkwrap.h19
-rw-r--r--source/blender/blenkernel/BKE_suggestions.h2
-rw-r--r--source/blender/blenkernel/SConscript32
-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.c5
-rw-r--r--source/blender/blenkernel/intern/anim.c108
-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/constraint.c197
-rw-r--r--source/blender/blenkernel/intern/curve.c18
-rw-r--r--source/blender/blenkernel/intern/effect.c29
-rw-r--r--source/blender/blenkernel/intern/modifier.c121
-rw-r--r--source/blender/blenkernel/intern/node.c39
-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/shrinkwrap.c298
-rw-r--r--source/blender/blenkernel/intern/suggestions.c2
-rw-r--r--source/blender/blenkernel/intern/world.c2
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c36
36 files changed, 1091 insertions, 444 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 1c5cc2ff311..8c54c35473c 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;
@@ -70,6 +71,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_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_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_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_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/SConscript b/source/blender/blenkernel/SConscript
index 1ea9cfae78e..86ff3a43045 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -15,49 +15,51 @@ incs += ' ../gpu #/extern/glew/include'
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'
+ defs.append('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['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 cbdbe19f0b9..fd92360f6c2 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -76,6 +76,7 @@
#include "BKE_texture.h"
#include "BKE_utildefines.h"
#include "BKE_particle.h"
+#include "BKE_bvhutils.h"
#include "BLO_sys_types.h" // for intptr_t support
@@ -177,6 +178,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,
@@ -213,6 +216,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);
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index cffd97c70b1..1aceca454d2 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -226,14 +226,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);
@@ -759,7 +761,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;
@@ -787,11 +789,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)
@@ -871,76 +868,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/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/constraint.c b/source/blender/blenkernel/intern/constraint.c
index dd8fd88f76c..c055a0ca6a7 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -41,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"
@@ -65,6 +66,8 @@
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_idprop.h"
+#include "BKE_shrinkwrap.h"
+#include "BKE_mesh.h"
#ifndef DISABLE_PYTHON
#include "BPY_extern.h"
@@ -387,7 +390,7 @@ void constraint_mat_convertspace (Object *ob, bPoseChannel *pchan, float mat[][4
/* ------------ General Target Matrix Tools ---------- */
/* function that sets the given matrix based on given vertex group in mesh */
-static void contarget_get_mesh_mat (Object *ob, 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;
@@ -396,6 +399,7 @@ static void contarget_get_mesh_mat (Object *ob, char *substring, float mat[][4])
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);
@@ -408,10 +412,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 */
@@ -477,10 +490,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);
+ 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 */
@@ -542,7 +555,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)) {
@@ -559,7 +572,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) {
@@ -641,7 +654,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);
}
@@ -1056,7 +1069,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;
@@ -1746,7 +1759,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
@@ -1853,7 +1866,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:
@@ -3108,6 +3121,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.
@@ -3139,6 +3311,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
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/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/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 7f062ff5a9b..6578feeeed1 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -6022,6 +6022,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)
@@ -6070,22 +6144,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 */
@@ -6379,6 +6475,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];
@@ -7189,7 +7286,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;
@@ -7245,7 +7342,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();
@@ -8268,16 +8365,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/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/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index 0d9a6a7bc48..8bf56f136bc 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 "BLI_arithb.h"
@@ -93,7 +95,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;
EditMesh *em = BKE_mesh_get_editmesh(me);
@@ -151,7 +153,6 @@ static float squared_dist(const float *a, const float *b)
return INPR(tmp, tmp);
}
-
/*
* Shrinkwrap to the nearest vertex
*
@@ -186,8 +187,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)
//
@@ -290,174 +300,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);
}
/*
@@ -473,8 +426,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)
@@ -500,7 +451,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)
@@ -539,53 +497,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)
{
@@ -593,20 +587,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/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,