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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Eagar <joeedh@gmail.com>2010-07-19 08:44:37 +0400
committerJoseph Eagar <joeedh@gmail.com>2010-07-19 08:44:37 +0400
commitc11c196efadf5ef52293d782638497f86a209722 (patch)
tree43abcd60b2400d28db8686f4dbea68f17475ef58 /source/blender/blenkernel/intern
parentf54aa7811029c90b6071ccc9e27e57a758e5884d (diff)
parent7f083c45bee15f7540e2a35a725efe28fc962239 (diff)
part 1 of merge from trunk at r30358; it compiles, but doesn't link quite yet :)
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/BME_Customdata.c8
-rw-r--r--source/blender/blenkernel/intern/BME_conversions.c8
-rw-r--r--source/blender/blenkernel/intern/BME_eulers.c11
-rw-r--r--source/blender/blenkernel/intern/BME_mesh.c6
-rw-r--r--source/blender/blenkernel/intern/BME_structure.c5
-rw-r--r--source/blender/blenkernel/intern/BME_tools.c8
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c14
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.h4
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c409
-rw-r--r--source/blender/blenkernel/intern/Makefile7
-rw-r--r--source/blender/blenkernel/intern/action.c104
-rw-r--r--source/blender/blenkernel/intern/anim.c194
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c191
-rw-r--r--source/blender/blenkernel/intern/armature.c185
-rw-r--r--source/blender/blenkernel/intern/blender.c52
-rw-r--r--source/blender/blenkernel/intern/bmfont.c10
-rw-r--r--source/blender/blenkernel/intern/boids.c48
-rw-r--r--source/blender/blenkernel/intern/booleanops.c3
-rw-r--r--source/blender/blenkernel/intern/booleanops_mesh.c14
-rw-r--r--source/blender/blenkernel/intern/brush.c115
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c11
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c195
-rw-r--r--source/blender/blenkernel/intern/cloth.c103
-rw-r--r--source/blender/blenkernel/intern/collision.c300
-rw-r--r--source/blender/blenkernel/intern/colortools.c333
-rw-r--r--source/blender/blenkernel/intern/constraint.c305
-rw-r--r--source/blender/blenkernel/intern/context.c18
-rw-r--r--source/blender/blenkernel/intern/curve.c350
-rw-r--r--source/blender/blenkernel/intern/customdata.c220
-rw-r--r--source/blender/blenkernel/intern/deform.c31
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c205
-rw-r--r--source/blender/blenkernel/intern/displist.c554
-rw-r--r--source/blender/blenkernel/intern/editderivedbmesh.c20
-rw-r--r--source/blender/blenkernel/intern/effect.c40
-rw-r--r--source/blender/blenkernel/intern/exotic.c119
-rw-r--r--source/blender/blenkernel/intern/fcurve.c30
-rw-r--r--source/blender/blenkernel/intern/fluidsim.c583
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c118
-rw-r--r--source/blender/blenkernel/intern/font.c168
-rw-r--r--source/blender/blenkernel/intern/gpencil.c14
-rw-r--r--source/blender/blenkernel/intern/group.c23
-rw-r--r--source/blender/blenkernel/intern/icons.c14
-rw-r--r--source/blender/blenkernel/intern/idprop.c61
-rw-r--r--source/blender/blenkernel/intern/image.c718
-rw-r--r--source/blender/blenkernel/intern/image_gen.c367
-rw-r--r--source/blender/blenkernel/intern/implicit.c70
-rw-r--r--source/blender/blenkernel/intern/ipo.c211
-rw-r--r--source/blender/blenkernel/intern/key.c219
-rw-r--r--source/blender/blenkernel/intern/lattice.c120
-rw-r--r--source/blender/blenkernel/intern/library.c104
-rw-r--r--source/blender/blenkernel/intern/material.c103
-rw-r--r--source/blender/blenkernel/intern/mball.c73
-rw-r--r--source/blender/blenkernel/intern/mesh.c278
-rw-r--r--source/blender/blenkernel/intern/modifier.c8132
-rw-r--r--source/blender/blenkernel/intern/modifiers_bmesh.c499
-rw-r--r--source/blender/blenkernel/intern/multires.c197
-rw-r--r--source/blender/blenkernel/intern/nla.c76
-rw-r--r--source/blender/blenkernel/intern/node.c105
-rw-r--r--source/blender/blenkernel/intern/object.c486
-rw-r--r--source/blender/blenkernel/intern/packedFile.c25
-rw-r--r--source/blender/blenkernel/intern/paint.c2
-rw-r--r--source/blender/blenkernel/intern/particle.c228
-rw-r--r--source/blender/blenkernel/intern/particle_system.c1151
-rw-r--r--source/blender/blenkernel/intern/pointcache.c488
-rw-r--r--source/blender/blenkernel/intern/property.c6
-rw-r--r--source/blender/blenkernel/intern/report.c21
-rw-r--r--source/blender/blenkernel/intern/sca.c271
-rw-r--r--source/blender/blenkernel/intern/scene.c273
-rw-r--r--source/blender/blenkernel/intern/screen.c84
-rw-r--r--source/blender/blenkernel/intern/script.c7
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c308
-rw-r--r--source/blender/blenkernel/intern/sequencer.c1023
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c18
-rw-r--r--source/blender/blenkernel/intern/simple_deform.c256
-rw-r--r--source/blender/blenkernel/intern/sketch.c6
-rw-r--r--source/blender/blenkernel/intern/smoke.c235
-rw-r--r--source/blender/blenkernel/intern/softbody.c1278
-rw-r--r--source/blender/blenkernel/intern/sound.c27
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c531
-rw-r--r--source/blender/blenkernel/intern/suggestions.c2
-rw-r--r--source/blender/blenkernel/intern/text.c30
-rw-r--r--source/blender/blenkernel/intern/texture.c63
-rw-r--r--source/blender/blenkernel/intern/unit.c2
-rw-r--r--source/blender/blenkernel/intern/world.c34
-rw-r--r--source/blender/blenkernel/intern/writeavi.c9
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c33
-rw-r--r--source/blender/blenkernel/intern/writeframeserver.c50
87 files changed, 8585 insertions, 14845 deletions
diff --git a/source/blender/blenkernel/intern/BME_Customdata.c b/source/blender/blenkernel/intern/BME_Customdata.c
index d70478bac21..913225a2f73 100644
--- a/source/blender/blenkernel/intern/BME_Customdata.c
+++ b/source/blender/blenkernel/intern/BME_Customdata.c
@@ -35,13 +35,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#include <string.h>
-#include "BKE_bmesh.h"
#include "BKE_bmeshCustomData.h"
#include "bmesh_private.h"
-#include <string.h>
#include "MEM_guardedalloc.h"
-#include "BLI_mempool.h"
/********************* Layer type information **********************/
typedef struct BME_LayerTypeInfo {
@@ -138,7 +136,7 @@ static void BME_CD_alloc_block(BME_CustomData *data, void **block)
}
void BME_CD_copy_data(const BME_CustomData *source, BME_CustomData *dest,
- void *src_block, void **dest_block)
+ void *src_block, void **dest_block)
{
const BME_LayerTypeInfo *typeInfo;
int dest_i, src_i;
@@ -154,7 +152,7 @@ void BME_CD_copy_data(const BME_CustomData *source, BME_CustomData *dest,
* (this should work because layers are ordered by type)
*/
while(dest_i < dest->totlayer
- && dest->layers[dest_i].type < source->layers[src_i].type)
+ && dest->layers[dest_i].type < source->layers[src_i].type)
++dest_i;
/* if there are no more dest layers, we're done */
diff --git a/source/blender/blenkernel/intern/BME_conversions.c b/source/blender/blenkernel/intern/BME_conversions.c
index 4181825acb5..aab0c0011a0 100644
--- a/source/blender/blenkernel/intern/BME_conversions.c
+++ b/source/blender/blenkernel/intern/BME_conversions.c
@@ -34,22 +34,14 @@
*/
#include "MEM_guardedalloc.h"
-#include "BKE_customdata.h"
-#include "DNA_listBase.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "BKE_utildefines.h"
#include "BKE_mesh.h"
-#include "BKE_bmesh.h"
-#include "BKE_global.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_cdderivedmesh.h"
-#include "BLI_blenlib.h"
-#include "BLI_editVert.h"
#include "BLI_edgehash.h"
//XXX #include "BIF_editmesh.h"
//XXX #include "editmesh.h"
diff --git a/source/blender/blenkernel/intern/BME_eulers.c b/source/blender/blenkernel/intern/BME_eulers.c
index 9c83f6aaf65..baa490bbeb5 100644
--- a/source/blender/blenkernel/intern/BME_eulers.c
+++ b/source/blender/blenkernel/intern/BME_eulers.c
@@ -35,17 +35,8 @@
#include "MEM_guardedalloc.h"
-#include "DNA_listBase.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_mesh_types.h"
-#include "BKE_utildefines.h"
-#include "BKE_customdata.h"
-#include "BKE_bmesh.h"
-
-#include "BLI_blenlib.h"
#include "bmesh_private.h"
-#include "BLI_ghash.h"
/*********************************************************
* "Euler API" *
@@ -81,7 +72,7 @@
code.
*The term "Euler Operator" is actually a misnomer when referring to a non-manifold
- data structure. Its use is in keeping with the convention established by others.
+ data structure. Its use is in keeping with the convention established by others.
TODO:
-Finish inserting 'strict' validation in all Eulers
diff --git a/source/blender/blenkernel/intern/BME_mesh.c b/source/blender/blenkernel/intern/BME_mesh.c
index e9a1284809a..938b193a433 100644
--- a/source/blender/blenkernel/intern/BME_mesh.c
+++ b/source/blender/blenkernel/intern/BME_mesh.c
@@ -35,13 +35,9 @@
#include "MEM_guardedalloc.h"
-#include "DNA_listBase.h"
-#include "BLI_blenlib.h"
-#include "BKE_utildefines.h"
#include "BKE_bmesh.h"
#include "bmesh_private.h"
-
/*
* BME MAKE MESH
*
@@ -92,7 +88,7 @@ void BME_free_mesh(BME_Mesh *bm)
if(bm->ldata.totlayer) BLI_mempool_destroy(bm->ldata.pool);
if(bm->pdata.totlayer) BLI_mempool_destroy(bm->pdata.pool);
- /*free custom data*/
+ /*free custom data*/
CustomData_free(&bm->vdata,0);
CustomData_free(&bm->edata,0);
CustomData_free(&bm->ldata,0);
diff --git a/source/blender/blenkernel/intern/BME_structure.c b/source/blender/blenkernel/intern/BME_structure.c
index bc14e5d37d6..53cf93c43af 100644
--- a/source/blender/blenkernel/intern/BME_structure.c
+++ b/source/blender/blenkernel/intern/BME_structure.c
@@ -36,12 +36,7 @@
#include <limits.h>
#include "MEM_guardedalloc.h"
-#include "DNA_listBase.h"
-#include "BKE_utildefines.h"
#include "BKE_bmesh.h"
-#include "BLI_blenlib.h"
-#include "BLI_linklist.h"
-#include "BLI_ghash.h"
/**
* MISC utility functions.
*
diff --git a/source/blender/blenkernel/intern/BME_tools.c b/source/blender/blenkernel/intern/BME_tools.c
index 483e7ad150e..66df8f2ad6a 100644
--- a/source/blender/blenkernel/intern/BME_tools.c
+++ b/source/blender/blenkernel/intern/BME_tools.c
@@ -36,15 +36,11 @@
#include "MEM_guardedalloc.h"
-#include "DNA_listBase.h"
#include "DNA_meshdata_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
-#include "BKE_utildefines.h"
#include "BKE_bmesh.h"
#include "BLI_math.h"
-#include "BLI_blenlib.h"
#include "BLI_cellalloc.h"
/*split this all into a seperate bevel.c file in src*/
@@ -55,8 +51,8 @@ BME_TransData_Head *BME_init_transdata(int bufsize) {
BME_TransData_Head *td;
td = MEM_callocN(sizeof(BME_TransData_Head), "BMesh transdata header");
- td->gh = BLI_ghash_new(BLI_ghashutil_ptrhash,BLI_ghashutil_ptrcmp);
- td->ma = BLI_memarena_new(bufsize);
+ td->gh = BLI_ghash_new(BLI_ghashutil_ptrhash,BLI_ghashutil_ptrcmp, "BME_init_transdata gh");
+ td->ma = BLI_memarena_new(bufsize, "BME_TransData arena");
BLI_memarena_use_calloc(td->ma);
return td;
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index eb316c64af4..bbd68fb797b 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -170,7 +170,7 @@ static void *_ehashIterator_getCurrent(EHashIterator *ehi) {
static void _ehashIterator_next(EHashIterator *ehi) {
if (ehi->curEntry) {
- ehi->curEntry = ehi->curEntry->next;
+ ehi->curEntry = ehi->curEntry->next;
while (!ehi->curEntry) {
ehi->curBucket++;
if (ehi->curBucket==ehi->eh->curSize)
@@ -1159,7 +1159,7 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss,
int normalDataOffset = ss->normalDataOffset;
int vertDataSize = ss->meshIFC.vertDataSize;
- #pragma omp parallel for private(ptrIdx) schedule(static)
+ #pragma omp parallel for private(ptrIdx) if(numEffectedF*edgeSize*edgeSize*4 >= CCG_OMP_LIMIT)
for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
CCGFace *f = (CCGFace*) effectedF[ptrIdx];
int S, x, y;
@@ -1285,7 +1285,7 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss,
}
}
- #pragma omp parallel for private(ptrIdx) schedule(static)
+ #pragma omp parallel for private(ptrIdx) if(numEffectedF*edgeSize*edgeSize*4 >= CCG_OMP_LIMIT)
for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
CCGFace *f = (CCGFace*) effectedF[ptrIdx];
int S, x, y;
@@ -1351,7 +1351,7 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
int vertDataSize = ss->meshIFC.vertDataSize;
void *q = ss->q, *r = ss->r;
- #pragma omp parallel for private(ptrIdx) schedule(static)
+ #pragma omp parallel for private(ptrIdx) if(numEffectedF*edgeSize*edgeSize*4 >= CCG_OMP_LIMIT)
for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) {
CCGFace *f = (CCGFace*) effectedF[ptrIdx];
int S, x, y;
@@ -1685,7 +1685,7 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
}
}
- #pragma omp parallel private(ptrIdx)
+ #pragma omp parallel private(ptrIdx) if(numEffectedF*edgeSize*edgeSize*4 >= CCG_OMP_LIMIT)
{
void *q, *r;
@@ -1791,14 +1791,14 @@ static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss,
gridSize = 1 + (1<<((nextLvl)-1));
cornerIdx = gridSize-1;
- #pragma omp parallel for private(i) schedule(static)
+ #pragma omp parallel for private(i) if(numEffectedF*edgeSize*edgeSize*4 >= CCG_OMP_LIMIT)
for (i=0; i<numEffectedE; i++) {
CCGEdge *e = effectedE[i];
VertDataCopy(EDGE_getCo(e, nextLvl, 0), VERT_getCo(e->v0, nextLvl));
VertDataCopy(EDGE_getCo(e, nextLvl, edgeSize-1), VERT_getCo(e->v1, nextLvl));
}
- #pragma omp parallel for private(i) schedule(static)
+ #pragma omp parallel for private(i) if(numEffectedF*edgeSize*edgeSize*4 >= CCG_OMP_LIMIT)
for (i=0; i<numEffectedF; i++) {
CCGFace *f = effectedF[i];
int S, x;
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h
index 12212c7a37b..34d684221b0 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf.h
@@ -39,6 +39,10 @@ typedef enum {
/***/
+#define CCG_OMP_LIMIT 1000000
+
+/***/
+
typedef struct _CCGSubSurf CCGSubSurf;
CCGSubSurf* ccgSubSurf_new (CCGMeshIFC *ifc, int subdivisionLevels, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 3235ccbbaa5..56b0a3bfb68 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -29,52 +29,29 @@
#include <string.h>
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "PIL_time.h"
#include "MEM_guardedalloc.h"
-#include "DNA_effect_types.h"
-#include "DNA_mesh_types.h"
+#include "DNA_cloth_types.h"
#include "DNA_key_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_force.h"
-#include "DNA_object_fluidsim.h" // N_T
#include "DNA_scene_types.h" // N_T
-#include "DNA_texture_types.h"
-#include "DNA_view3d_types.h"
-#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
-#include "DNA_particle_types.h"
-#include "BLI_math.h"
#include "BLI_blenlib.h"
-#include "BLI_edgehash.h"
#include "BLI_editVert.h"
-#include "BLI_linklist.h"
+#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_array.h"
+#include "BLI_pbvh.h"
#include "BKE_cdderivedmesh.h"
-#include "BKE_customdata.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_deform.h"
#include "BKE_displist.h"
-#include "BKE_effect.h"
-#include "BKE_fluidsim.h"
-#include "BKE_global.h"
#include "BKE_key.h"
-#include "BKE_material.h"
#include "BKE_modifier.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_paint.h"
-#include "BKE_subsurf.h"
#include "BKE_texture.h"
#include "BKE_utildefines.h"
#include "BKE_particle.h"
@@ -86,7 +63,7 @@
#include "BIF_gl.h"
#include "BIF_glutil.h"
-#include "gpu_buffers.h"
+#include "GPU_buffers.h"
#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_material.h"
@@ -139,7 +116,7 @@ static MFace *dm_getFaceArray(DerivedMesh *dm)
static MVert *dm_dupVertArray(DerivedMesh *dm)
{
MVert *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumVerts(dm),
- "dm_dupVertArray tmp");
+ "dm_dupVertArray tmp");
if(tmp) dm->copyVertArray(dm, tmp);
@@ -149,7 +126,7 @@ static MVert *dm_dupVertArray(DerivedMesh *dm)
static MEdge *dm_dupEdgeArray(DerivedMesh *dm)
{
MEdge *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumEdges(dm),
- "dm_dupEdgeArray tmp");
+ "dm_dupEdgeArray tmp");
if(tmp) dm->copyEdgeArray(dm, tmp);
@@ -159,7 +136,7 @@ static MEdge *dm_dupEdgeArray(DerivedMesh *dm)
static MFace *dm_dupFaceArray(DerivedMesh *dm)
{
MFace *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumTessFaces(dm),
- "dm_dupFaceArray tmp");
+ "dm_dupFaceArray tmp");
if(tmp) dm->copyTessFaceArray(dm, tmp);
@@ -237,11 +214,11 @@ void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type
int numLoops, int numPolys)
{
CustomData_copy(&source->vertData, &dm->vertData, CD_MASK_DERIVEDMESH,
- CD_CALLOC, numVerts);
+ CD_CALLOC, numVerts);
CustomData_copy(&source->edgeData, &dm->edgeData, CD_MASK_DERIVEDMESH,
- CD_CALLOC, numEdges);
+ CD_CALLOC, numEdges);
CustomData_copy(&source->faceData, &dm->faceData, CD_MASK_DERIVEDMESH,
- CD_CALLOC, numFaces);
+ CD_CALLOC, numFaces);
CustomData_copy(&source->loopData, &dm->loopData, CD_MASK_DERIVEDMESH,
CD_CALLOC, numLoops);
CustomData_copy(&source->polyData, &dm->polyData, CD_MASK_DERIVEDMESH,
@@ -434,8 +411,8 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me)
stack*/
if(tmp.totvert != me->totvert) {
printf("YEEK! this should be recoded! Shape key loss!!!\n");
- if(me->key) me->key->id.us--;
- me->key = NULL;
+ if(tmp.key) tmp.key->id.us--;
+ tmp.key = NULL;
}
*me = tmp;
@@ -553,24 +530,24 @@ void DM_set_face_data(DerivedMesh *dm, int index, int type, void *data)
}
void DM_copy_vert_data(DerivedMesh *source, DerivedMesh *dest,
- int source_index, int dest_index, int count)
+ int source_index, int dest_index, int count)
{
CustomData_copy_data(&source->vertData, &dest->vertData,
- source_index, dest_index, count);
+ source_index, dest_index, count);
}
void DM_copy_edge_data(DerivedMesh *source, DerivedMesh *dest,
- int source_index, int dest_index, int count)
+ int source_index, int dest_index, int count)
{
CustomData_copy_data(&source->edgeData, &dest->edgeData,
- source_index, dest_index, count);
+ source_index, dest_index, count);
}
void DM_copy_tessface_data(DerivedMesh *source, DerivedMesh *dest,
- int source_index, int dest_index, int count)
+ int source_index, int dest_index, int count)
{
CustomData_copy_data(&source->faceData, &dest->faceData,
- source_index, dest_index, count);
+ source_index, dest_index, count);
}
void DM_copy_loop_data(DerivedMesh *source, DerivedMesh *dest,
@@ -613,33 +590,32 @@ void DM_free_face_data(struct DerivedMesh *dm, int index, int count)
}
void DM_interp_vert_data(DerivedMesh *source, DerivedMesh *dest,
- int *src_indices, float *weights,
- int count, int dest_index)
+ int *src_indices, float *weights,
+ int count, int dest_index)
{
CustomData_interp(&source->vertData, &dest->vertData, src_indices,
- weights, NULL, count, dest_index);
+ weights, NULL, count, dest_index);
}
void DM_interp_edge_data(DerivedMesh *source, DerivedMesh *dest,
- int *src_indices,
- float *weights, EdgeVertWeight *vert_weights,
- int count, int dest_index)
+ int *src_indices,
+ float *weights, EdgeVertWeight *vert_weights,
+ int count, int dest_index)
{
CustomData_interp(&source->edgeData, &dest->edgeData, src_indices,
- weights, (float*)vert_weights, count, dest_index);
+ weights, (float*)vert_weights, count, dest_index);
}
void DM_interp_tessface_data(DerivedMesh *source, DerivedMesh *dest,
- int *src_indices,
- float *weights, FaceVertWeight *vert_weights,
- int count, int dest_index)
+ int *src_indices,
+ float *weights, FaceVertWeight *vert_weights,
+ int count, int dest_index)
{
CustomData_interp(&source->faceData, &dest->faceData, src_indices,
- weights, (float*)vert_weights, count, dest_index);
+ weights, (float*)vert_weights, count, dest_index);
}
-
-void DM_swap_tessface_data(DerivedMesh *dm, int index, int *corner_indices)
+void DM_swap_tessface_data(DerivedMesh *dm, int index, const int *corner_indices)
{
CustomData_swap(&dm->faceData, index, corner_indices);
}
@@ -750,7 +726,7 @@ static void emDM_drawMappedEdges(void *dm, int (*setDrawOptions)(void *userData,
glEnd();
}
}
-static void emDM_drawEdges(void *dm, int drawLooseEdges)
+static void emDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges)
{
emDM_drawMappedEdges(dm, NULL, NULL);
}
@@ -825,14 +801,14 @@ static void emDM__calcFaceCent(EditFace *efa, float cent[3], float (*vertexCos)[
{
if (vertexCos) {
VECCOPY(cent, vertexCos[(int) efa->v1->tmp.l]);
- add_v3_v3v3(cent, cent, vertexCos[(int) efa->v2->tmp.l]);
- add_v3_v3v3(cent, cent, vertexCos[(int) efa->v3->tmp.l]);
- if (efa->v4) add_v3_v3v3(cent, cent, vertexCos[(int) efa->v4->tmp.l]);
+ add_v3_v3(cent, vertexCos[(int) efa->v2->tmp.l]);
+ add_v3_v3(cent, vertexCos[(int) efa->v3->tmp.l]);
+ if (efa->v4) add_v3_v3(cent, vertexCos[(int) efa->v4->tmp.l]);
} else {
VECCOPY(cent, efa->v1->co);
- add_v3_v3v3(cent, cent, efa->v2->co);
- add_v3_v3v3(cent, cent, efa->v3->co);
- if (efa->v4) add_v3_v3v3(cent, cent, efa->v4->co);
+ add_v3_v3(cent, efa->v2->co);
+ add_v3_v3(cent, efa->v3->co);
+ if (efa->v4) add_v3_v3(cent, efa->v4->co);
}
if (efa->v4) {
@@ -876,8 +852,8 @@ static void emDM_drawMappedFaces(void *dm, int (*setDrawOptions)(void *userData,
draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
if(draw) {
if (draw==2) { /* enabled with stipple */
- glEnable(GL_POLYGON_STIPPLE);
- glPolygonStipple(stipple_quarttone);
+ glEnable(GL_POLYGON_STIPPLE);
+ glPolygonStipple(stipple_quarttone);
}
glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
@@ -947,9 +923,9 @@ static void emDM_drawMappedFaces(void *dm, int (*setDrawOptions)(void *userData,
}
static void emDM_drawFacesTex_common(void *dm,
- int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
- int (*drawParamsMapped)(void *userData, int index),
- void *userData)
+ int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
+ int (*drawParamsMapped)(void *userData, int index),
+ void *userData)
{
EditMeshDerivedMesh *emdm= dm;
EditMesh *em= emdm->em;
@@ -1125,8 +1101,8 @@ static void emDM_drawMappedFacesTex(void *dm, int (*setDrawOptions)(void *userDa
}
static void emDM_drawMappedFacesGLSL(void *dm,
- int (*setMaterial)(int, void *attribs),
- int (*setDrawOptions)(void *userData, int index), void *userData)
+ int (*setMaterial)(int, void *attribs),
+ int (*setDrawOptions)(void *userData, int index), void *userData)
{
EditMeshDerivedMesh *emdm= dm;
EditMesh *em= emdm->em;
@@ -1275,7 +1251,7 @@ static void emDM_drawMappedFacesGLSL(void *dm,
}
static void emDM_drawFacesGLSL(void *dm,
- int (*setMaterial)(int, void *attribs))
+ int (*setMaterial)(int, void *attribs))
{
((DerivedMesh*)dm)->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
}
@@ -1319,7 +1295,22 @@ static int emDM_getNumTessFaces(void *dm)
return BLI_countlist(&emdm->em->faces);
}
-static void emDM_getVert(void *dm, int index, MVert *vert_r)
+static void emDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
+{
+ EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
+ EditVert *eve;
+ int i;
+
+ for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
+ if (emdm->vertexCos) {
+ copy_v3_v3(cos_r[i], emdm->vertexCos[i]);
+ } else {
+ copy_v3_v3(cos_r[i], eve->co);
+ }
+ }
+}
+
+static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
{
EditVert *ev = ((EditMeshDerivedMesh *)dm)->em->verts.first;
int i;
@@ -1392,7 +1383,7 @@ static void emDM_getFace(void *dm, int index, MFace *face_r)
if(!v4) face_r->v4 = 0;
for(i = 0, ev = em->verts.first; v1 || v2 || v3 || v4;
- i++, ev = ev->next) {
+ i++, ev = ev->next) {
if(ev == v1) {
face_r->v1 = i;
v1 = NULL;
@@ -1538,14 +1529,14 @@ static void emDM_release(void *dm)
}
static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob,
- float (*vertexCos)[3])
+ float (*vertexCos)[3])
{
#if 0
EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm");
DM_init(&emdm->dm, DM_TYPE_EDITMESH, BLI_countlist(&em->verts),
BLI_countlist(&em->edges), BLI_countlist(&em->faces),
- 0, 0);
+ 0, 0);
emdm->dm.getMinMax = emDM_getMinMax;
@@ -1553,6 +1544,8 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob,
emdm->dm.getNumEdges = emDM_getNumEdges;
emdm->dm.getNumTessFaces = emDM_getNumTessFaces;
+ emdm->dm.getVertCos = emDM_getVertCos;
+
emdm->dm.getVert = emDM_getVert;
emdm->dm.getEdge = emDM_getEdge;
emdm->dm.getTessFace = emDM_getFace;
@@ -1588,7 +1581,7 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob,
for(eve = em->verts.first, i = 0; eve; eve = eve->next, ++i)
DM_set_vert_data(&emdm->dm, i, CD_MDEFORMVERT,
- CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT));
+ CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT));
}
if(vertexCos) {
@@ -1613,15 +1606,15 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob,
float *v4 = vertexCos[(int) efa->v4->tmp.l];
normal_quad_v3( no,v1, v2, v3, v4);
- add_v3_v3v3(emdm->vertexNos[(int) efa->v4->tmp.l], emdm->vertexNos[(int) efa->v4->tmp.l], no);
+ add_v3_v3(emdm->vertexNos[(int) efa->v4->tmp.l], no);
}
else {
normal_tri_v3( no,v1, v2, v3);
}
- add_v3_v3v3(emdm->vertexNos[(int) efa->v1->tmp.l], emdm->vertexNos[(int) efa->v1->tmp.l], no);
- add_v3_v3v3(emdm->vertexNos[(int) efa->v2->tmp.l], emdm->vertexNos[(int) efa->v2->tmp.l], no);
- add_v3_v3v3(emdm->vertexNos[(int) efa->v3->tmp.l], emdm->vertexNos[(int) efa->v3->tmp.l], no);
+ add_v3_v3(emdm->vertexNos[(int) efa->v1->tmp.l], no);
+ add_v3_v3(emdm->vertexNos[(int) efa->v2->tmp.l], no);
+ add_v3_v3(emdm->vertexNos[(int) efa->v3->tmp.l], no);
}
for(i=0, eve= em->verts.first; eve; i++, eve=eve->next) {
@@ -1693,55 +1686,89 @@ static float *get_editbmesh_orco_verts(BMEditMesh *em)
}
/* orco custom data layer */
-static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, BMEditMesh *em)
+static void *get_orco_coords_dm(Object *ob, BMEditMesh *em, int layer, int *free)
+{
+ *free= 0;
+
+ if(layer == CD_ORCO) {
+ /* get original coordinates */
+ *free= 1;
+
+ if(em)
+ return (float(*)[3])get_editbmesh_orco_verts(em);
+ else
+ return (float(*)[3])get_mesh_orco_verts(ob);
+ }
+ else if(layer == CD_CLOTH_ORCO) {
+ /* apply shape key for cloth, this should really be solved
+ by a more flexible customdata system, but not simple */
+ if(!em) {
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+ KeyBlock *kb= key_get_keyblock(ob_get_key(ob), clmd->sim_parms->shapekey_rest);
+
+ if(kb->data)
+ return kb->data;
+ }
+
+ return NULL;
+ }
+
+ return NULL;
+}
+
+static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, EditMesh *em, int layer)
{
DerivedMesh *dm;
float (*orco)[3];
+ int free;
- if(em) {
- dm= CDDM_from_BMEditMesh(em, me);
- orco= (float(*)[3])get_editbmesh_orco_verts(em);
- }
- else {
- dm= CDDM_from_mesh(me, ob);
- orco= (float(*)[3])get_mesh_orco_verts(ob);
+ if(em) dm= CDDM_from_BMEditMesh(em, me);
+ else dm= CDDM_from_mesh(me, ob);
+
+ orco= get_orco_coords_dm(ob, em, layer, &free);
+
+ if(orco) {
+ CDDM_apply_vert_coords(dm, orco);
+ if(free) MEM_freeN(orco);
}
- CDDM_apply_vert_coords(dm, orco);
CDDM_calc_normals(dm);
- MEM_freeN(orco);
return dm;
}
-static void add_orco_dm(Object *ob, BMEditMesh *em, DerivedMesh *dm, DerivedMesh *orcodm)
+static void add_orco_dm(Object *ob, BMEditMesh *em, DerivedMesh *dm,
+ DerivedMesh *orcodm, int layer)
{
float (*orco)[3], (*layerorco)[3];
- int totvert;
+ int totvert, free;
totvert= dm->getNumVerts(dm);
if(orcodm) {
orco= MEM_callocN(sizeof(float)*3*totvert, "dm orco");
+ free= 1;
if(orcodm->getNumVerts(orcodm) == totvert)
orcodm->getVertCos(orcodm, orco);
else
dm->getVertCos(dm, orco);
}
- else {
- if(em) orco= (float(*)[3])get_editbmesh_orco_verts(em);
- else orco= (float(*)[3])get_mesh_orco_verts(ob);
- }
+ else
+ orco= get_orco_coords_dm(ob, em, layer, &free);
- transform_mesh_orco_verts(ob->data, orco, totvert, 0);
+ if(orco) {
+ if(layer == CD_ORCO)
+ transform_mesh_orco_verts(ob->data, orco, totvert, 0);
+
+ if(!(layerorco = DM_get_vert_data_layer(dm, layer))) {
+ DM_add_vert_layer(dm, layer, CD_CALLOC, NULL);
+ layerorco = DM_get_vert_data_layer(dm, layer);
+ }
- if((layerorco = DM_get_vert_data_layer(dm, CD_ORCO))) {
- memcpy(layerorco, orco, sizeof(float)*totvert);
- MEM_freeN(orco);
+ memcpy(layerorco, orco, sizeof(float)*3*totvert);
+ if(free) MEM_freeN(orco);
}
- else
- DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco);
}
/* weight paint colors */
@@ -1862,16 +1889,16 @@ char *)&wlcol[totloop]);
* - apply deform modifiers and input vertexco
*/
static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos)[3],
- DerivedMesh **deform_r, DerivedMesh **final_r,
- int useRenderParams, int useDeform,
- int needMapping, CustomDataMask dataMask, int index, int useCache)
+ DerivedMesh **deform_r, DerivedMesh **final_r,
+ int useRenderParams, int useDeform,
+ int needMapping, CustomDataMask dataMask, int index, int useCache)
{
Mesh *me = ob->data;
ModifierData *firstmd, *md;
LinkNode *datamasks, *curr;
- CustomDataMask mask;
+ CustomDataMask mask, nextmask;
float (*deformedVerts)[3] = NULL;
- DerivedMesh *dm, *orcodm, *finaldm;
+ DerivedMesh *dm, *orcodm, *clothorcodm, *finaldm;
int numVerts = me->totvert;
int required_mode;
@@ -1944,6 +1971,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
*/
dm = NULL;
orcodm = NULL;
+ clothorcodm = NULL;
for(;md; md = md->next, curr = curr->next) {
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
@@ -1960,11 +1988,13 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue;
/* add an orco layer if needed by this modifier */
- if(dm && mti->requiredDataMask) {
+ if(mti->requiredDataMask)
mask = mti->requiredDataMask(ob, md);
- if(mask & CD_MASK_ORCO)
- add_orco_dm(ob, NULL, dm, orcodm);
- }
+ else
+ mask = 0;
+
+ if(dm && (mask & CD_MASK_ORCO))
+ add_orco_dm(ob, NULL, dm, orcodm, CD_ORCO);
/* How to apply modifier depends on (a) what we already have as
* a result of previous modifiers (could be a DerivedMesh or just
@@ -1972,7 +2002,6 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
*/
if(mti->type == eModifierTypeType_OnlyDeform) {
-
/* No existing verts to deform, need to build them. */
if(!deformedVerts) {
if(dm) {
@@ -1982,7 +2011,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
*/
numVerts = dm->getNumVerts(dm);
deformedVerts =
- MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv");
+ MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv");
dm->getVertCos(dm, deformedVerts);
} else {
deformedVerts = mesh_getVertexCos(me, &numVerts);
@@ -2031,26 +2060,20 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
}
}
- /* create an orco derivedmesh in parallel */
- mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link);
- if(mask & CD_MASK_ORCO) {
- if(!orcodm)
- orcodm= create_orco_dm(ob, me, NULL);
-
- mask &= ~CD_MASK_ORCO;
- DM_set_only_copy(orcodm, mask);
- ndm = mti->applyModifier(md, ob, orcodm, useRenderParams, 0);
-
- if(ndm) {
- /* if the modifier returned a new dm, release the old one */
- if(orcodm && orcodm != ndm) orcodm->release(orcodm);
- orcodm = ndm;
- }
- }
-
+ /* determine which data layers are needed by following modifiers */
+ if(curr->next)
+ nextmask= (CustomDataMask)GET_INT_FROM_POINTER(curr->next->link);
+ else
+ nextmask= dataMask;
+
/* set the DerivedMesh to only copy needed data */
+ mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link);
DM_set_only_copy(dm, mask);
+ /* add cloth rest shape key if need */
+ if(mask & CD_MASK_CLOTH_ORCO)
+ add_orco_dm(ob, NULL, dm, clothorcodm, CD_CLOTH_ORCO);
+
/* add an origspace layer if needed */
if(((CustomDataMask)GET_INT_FROM_POINTER(curr->link)) & CD_MASK_ORIGSPACE)
if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
@@ -2071,8 +2094,40 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
deformedVerts = NULL;
}
}
+
+ /* create an orco derivedmesh in parallel */
+ if(nextmask & CD_MASK_ORCO) {
+ if(!orcodm)
+ orcodm= create_orco_dm(ob, me, NULL, CD_ORCO);
+
+ nextmask &= ~CD_MASK_ORCO;
+ DM_set_only_copy(orcodm, nextmask);
+ ndm = mti->applyModifier(md, ob, orcodm, useRenderParams, 0);
+
+ if(ndm) {
+ /* if the modifier returned a new dm, release the old one */
+ if(orcodm && orcodm != ndm) orcodm->release(orcodm);
+ orcodm = ndm;
+ }
+ }
+
+ /* create cloth orco derivedmesh in parallel */
+ if(nextmask & CD_MASK_CLOTH_ORCO) {
+ if(!clothorcodm)
+ clothorcodm= create_orco_dm(ob, me, NULL, CD_CLOTH_ORCO);
+
+ nextmask &= ~CD_MASK_CLOTH_ORCO;
+ DM_set_only_copy(clothorcodm, nextmask);
+ ndm = mti->applyModifier(md, ob, clothorcodm, useRenderParams, 0);
+
+ if(ndm) {
+ /* if the modifier returned a new dm, release the old one */
+ if(clothorcodm && clothorcodm != ndm) clothorcodm->release(clothorcodm);
+ clothorcodm = ndm;
+ }
+ }
}
-
+
/* grab modifiers until index i */
if((index >= 0) && (modifiers_indexInObject(ob, md) >= index))
break;
@@ -2111,16 +2166,18 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
/* add an orco layer if needed */
if(dataMask & CD_MASK_ORCO) {
- add_orco_dm(ob, NULL, finaldm, orcodm);
+ add_orco_dm(ob, NULL, finaldm, orcodm, CD_ORCO);
if(deform_r && *deform_r)
- add_orco_dm(ob, NULL, *deform_r, NULL);
+ add_orco_dm(ob, NULL, *deform_r, NULL, CD_ORCO);
}
*final_r = finaldm;
if(orcodm)
orcodm->release(orcodm);
+ if(clothorcodm)
+ clothorcodm->release(clothorcodm);
if(deformedVerts && deformedVerts != inputVertexCos)
MEM_freeN(deformedVerts);
@@ -2160,8 +2217,8 @@ static int editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, Derived
}
static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, DerivedMesh **cage_r,
- DerivedMesh **final_r,
- CustomDataMask dataMask)
+ DerivedMesh **final_r,
+ CustomDataMask dataMask)
{
ModifierData *md;
float (*deformedVerts)[3] = NULL;
@@ -2198,7 +2255,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
if(dm && mti->requiredDataMask) {
mask = mti->requiredDataMask(ob, md);
if(mask & CD_MASK_ORCO)
- add_orco_dm(ob, em, dm, orcodm);
+ add_orco_dm(ob, em, dm, orcodm, CD_ORCO);
}
/* How to apply modifier depends on (a) what we already have as
@@ -2216,14 +2273,16 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
*/
numVerts = dm->getNumVerts(dm);
deformedVerts =
- MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv");
+ MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv");
dm->getVertCos(dm, deformedVerts);
} else {
deformedVerts = editbmesh_getVertexCos(em, &numVerts);
}
}
- mti->deformVertsEM(md, ob, em, dm, deformedVerts, numVerts);
+ if (mti->deformVertsEM)
+ mti->deformVertsEM(md, ob, em, dm, deformedVerts, numVerts);
+ else mti->deformVerts(md, ob, dm, deformedVerts, numVerts, 0, 0);
} else {
DerivedMesh *ndm;
@@ -2255,11 +2314,15 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link);
if(mask & CD_MASK_ORCO) {
if(!orcodm)
- orcodm= create_orco_dm(ob, ob->data, em);
+ orcodm= create_orco_dm(ob, ob->data, em, CD_ORCO);
mask &= ~CD_MASK_ORCO;
DM_set_only_copy(orcodm, mask);
- ndm = mti->applyModifierEM(md, ob, em, orcodm);
+
+ if (mti->applyModifierEM)
+ ndm = mti->applyModifierEM(md, ob, em, orcodm);
+ else
+ ndm = mti->applyModifier(md, ob, orcodm, 0, 0);
if(ndm) {
/* if the modifier returned a new dm, release the old one */
@@ -2275,7 +2338,10 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
DM_add_tessface_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
- ndm = mti->applyModifierEM(md, ob, em, dm);
+ if (mti->applyModifierEM)
+ ndm = mti->applyModifierEM(md, ob, em, dm);
+ else
+ ndm = mti->applyModifier(md, ob, dm, 0, 0);
if (ndm) {
if(dm && dm != ndm)
@@ -2298,8 +2364,8 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
*cage_r = dm;
} else {
*cage_r =
- getEditDerivedBMesh(em, ob,
- deformedVerts ? MEM_dupallocN(deformedVerts) : NULL);
+ getEditDerivedBMesh(em, ob,
+ deformedVerts ? MEM_dupallocN(deformedVerts) : NULL);
}
}
}
@@ -2328,7 +2394,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
/* add an orco layer if needed */
if(dataMask & CD_MASK_ORCO)
- add_orco_dm(ob, em, *final_r, orcodm);
+ add_orco_dm(ob, em, *final_r, orcodm, CD_ORCO);
if(orcodm)
orcodm->release(orcodm);
@@ -2363,6 +2429,15 @@ static void clear_mesh_caches(Object *ob)
ob->derivedDeform->release(ob->derivedDeform);
ob->derivedDeform= NULL;
}
+ /* we free pbvh on changes, except during sculpt since it can't deal with
+ changing PVBH node organization, we hope topology does not change in
+ the meantime .. weak */
+ if(ob->sculpt && ob->sculpt->pbvh) {
+ if(!ob->sculpt->cache) {
+ BLI_pbvh_free(ob->sculpt->pbvh);
+ ob->sculpt->pbvh= NULL;
+ }
+ }
}
static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask)
@@ -2370,8 +2445,7 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask)
Object *obact = scene->basact?scene->basact->object:NULL;
int editing = paint_facesel_test(ob);
/* weight paint and face select need original indicies because of selection buffer drawing */
- int needMapping = (ob==obact) && (editing || (ob->mode & OB_MODE_WEIGHT_PAINT) || editing);
- float min[3], max[3];
+ int needMapping = (ob==obact) && (editing || (ob->mode & (OB_MODE_WEIGHT_PAINT|OB_MODE_VERTEX_PAINT)) || editing);
clear_mesh_caches(ob);
@@ -2379,13 +2453,7 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask)
&ob->derivedFinal, 0, 1,
needMapping, dataMask, -1, 1);
- INIT_MINMAX(min, max);
-
- ob->derivedFinal->getMinMax(ob->derivedFinal, min, max);
-
- if(!ob->bb)
- ob->bb= MEM_callocN(sizeof(BoundBox), "bb");
- boundbox_set_from_min_max(ob->bb, min, max);
+ DM_set_object_boundbox (ob, ob->derivedFinal);
ob->derivedFinal->needsFree = 0;
ob->derivedDeform->needsFree = 0;
@@ -2394,8 +2462,6 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask)
static void editbmesh_build_data(Scene *scene, Object *obedit, BMEditMesh *em, CustomDataMask dataMask)
{
- float min[3], max[3];
-
clear_mesh_caches(obedit);
if (em->derivedFinal) {
@@ -2412,16 +2478,9 @@ static void editbmesh_build_data(Scene *scene, Object *obedit, BMEditMesh *em, C
}
editbmesh_calc_modifiers(scene, obedit, em, &em->derivedCage, &em->derivedFinal, dataMask);
- em->lastDataMask = dataMask;
-
- INIT_MINMAX(min, max);
-
- em->derivedFinal->getMinMax(em->derivedFinal, min, max);
-
- if(!obedit->bb)
- obedit->bb= MEM_callocN(sizeof(BoundBox), "bb");
- boundbox_set_from_min_max(obedit->bb, min, max);
+ DM_set_object_boundbox (obedit, em->derivedFinal);
+ em->lastDataMask = dataMask;
em->derivedFinal->needsFree = 0;
em->derivedCage->needsFree = 0;
}
@@ -2487,7 +2546,7 @@ DerivedMesh *mesh_create_derived_view(Scene *scene, Object *ob, CustomDataMask d
}
DerivedMesh *mesh_create_derived_no_deform(Scene *scene, Object *ob, float (*vertCos)[3],
- CustomDataMask dataMask)
+ CustomDataMask dataMask)
{
DerivedMesh *final;
@@ -2497,7 +2556,7 @@ DerivedMesh *mesh_create_derived_no_deform(Scene *scene, Object *ob, float (*ver
}
DerivedMesh *mesh_create_derived_no_virtual(Scene *scene, Object *ob, float (*vertCos)[3],
- CustomDataMask dataMask)
+ CustomDataMask dataMask)
{
DerivedMesh *final;
@@ -2507,8 +2566,8 @@ DerivedMesh *mesh_create_derived_no_virtual(Scene *scene, Object *ob, float (*ve
}
DerivedMesh *mesh_create_derived_no_deform_render(Scene *scene, Object *ob,
- float (*vertCos)[3],
- CustomDataMask dataMask)
+ float (*vertCos)[3],
+ CustomDataMask dataMask)
{
DerivedMesh *final;
@@ -2520,7 +2579,7 @@ DerivedMesh *mesh_create_derived_no_deform_render(Scene *scene, Object *ob,
/***/
DerivedMesh *editbmesh_get_derived_cage_and_final(Scene *scene, Object *obedit, BMEditMesh *em, DerivedMesh **final_r,
- CustomDataMask dataMask)
+ CustomDataMask dataMask)
{
/* if there's no derived mesh or the last data mask used doesn't include
* the data we need, rebuild the derived mesh
@@ -2698,7 +2757,7 @@ void DM_add_tangent_layer(DerivedMesh *dm)
tangent= DM_get_tessface_data_layer(dm, CD_TANGENT);
/* allocate some space */
- arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
+ arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "tangent layer arena");
BLI_memarena_use_calloc(arena);
vtangents= MEM_callocN(sizeof(VertexTangent*)*totvert, "VertexTangent");
@@ -2869,3 +2928,17 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
}
}
+/* Set object's bounding box based on DerivedMesh min/max data */
+void DM_set_object_boundbox(Object *ob, DerivedMesh *dm)
+{
+ float min[3], max[3];
+
+ INIT_MINMAX(min, max);
+
+ dm->getMinMax(dm, min, max);
+
+ if(!ob->bb)
+ ob->bb= MEM_callocN(sizeof(BoundBox), "bb");
+
+ boundbox_set_from_min_max(ob->bb, min, max);
+}
diff --git a/source/blender/blenkernel/intern/Makefile b/source/blender/blenkernel/intern/Makefile
index 70e1a785787..15c022592f9 100644
--- a/source/blender/blenkernel/intern/Makefile
+++ b/source/blender/blenkernel/intern/Makefile
@@ -85,6 +85,9 @@ CPPFLAGS += -I../../nodes
#path to gpu
CPPFLAGS += -I../../gpu
+#modifiers got moved
+CPPFLAGS += -I../../modifiers
+
# path to our own external headerfiles
CPPFLAGS += -I..
@@ -129,6 +132,10 @@ ifeq ($(WITH_QUICKTIME), true)
CPPFLAGS += -DWITH_QUICKTIME
endif
+ifeq ($(WITH_TIFF), true)
+ CPPFLAGS += -DWITH_TIFF
+endif
+
ifeq ($(OS), darwin)
ifeq ($(WITH_BF_OPENMP), true)
CPPFLAGS += -DPARALLEL=1
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 13f247e7c3c..6c8e5c48745 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -26,10 +26,6 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include <string.h>
#include <math.h>
#include <stdlib.h>
@@ -38,26 +34,16 @@
#include "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
-#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
-#include "DNA_curve_types.h"
-#include "DNA_key_types.h"
-#include "DNA_nla_types.h"
-#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "BKE_animsys.h"
#include "BKE_action.h"
#include "BKE_anim.h"
-#include "BKE_armature.h"
-#include "BKE_blender.h"
#include "BKE_constraint.h"
-#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_fcurve.h"
-#include "BKE_key.h"
-#include "BKE_lattice.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_object.h"
@@ -66,23 +52,22 @@
#include "BIK_api.h"
-#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_ghash.h"
+#include "BLI_math.h"
#include "RNA_access.h"
-#include "RNA_types.h"
/* *********************** NOTE ON POSE AND ACTION **********************
- Pose is the local (object level) component of armature. The current
- object pose is saved in files, and (will be) is presorted for dependency
+ object pose is saved in files, and (will be) is presorted for dependency
- Actions have fewer (or other) channels, and write data to a Pose
- Currently ob->pose data is controlled in where_is_pose only. The (recalc)
- event system takes care of calling that
+ event system takes care of calling that
- The NLA system (here too) uses Poses as interpolation format for Actions
- Therefore we assume poses to be static, and duplicates of poses have channels in
- same order, for quick interpolation reasons
+ same order, for quick interpolation reasons
****************************** (ton) ************************************ */
@@ -249,6 +234,30 @@ void set_active_action_group (bAction *act, bActionGroup *agrp, short select)
}
}
+/* Add a new action group with the given name to the action */
+bActionGroup *action_groups_add_new (bAction *act, const char name[])
+{
+ bActionGroup *agrp;
+
+ /* sanity check: must have action and name */
+ if (ELEM(NULL, act, name))
+ return NULL;
+
+ /* allocate a new one */
+ agrp = MEM_callocN(sizeof(bActionGroup), "bActionGroup");
+
+ /* make it selected, with default name */
+ agrp->flag = AGRP_SELECTED;
+ strncpy(agrp->name, name[0] ? name : "Group", sizeof(agrp->name));
+
+ /* add to action, and validate */
+ BLI_addtail(&act->groups, agrp);
+ BLI_uniquename(&act->groups, agrp, "Group", '.', offsetof(bActionGroup, name), sizeof(agrp->name));
+
+ /* return the new group */
+ return agrp;
+}
+
/* Add given channel into (active) group
* - assumes that channel is not linked to anything anymore
* - always adds at the end of the group
@@ -382,6 +391,9 @@ bPoseChannel *get_pose_channel(const bPose *pose, const char *name)
if (ELEM(NULL, pose, name) || (name[0] == 0))
return NULL;
+ if(pose->chanhash)
+ return BLI_ghash_lookup(pose->chanhash, (void *)name);
+
return BLI_findstring(&((bPose *)pose)->chanbase, name, offsetof(bPoseChannel, name));
}
@@ -417,6 +429,7 @@ bPoseChannel *verify_pose_channel(bPose *pose, const char *name)
chan->protectflag = OB_LOCK_ROT4D; /* lock by components by default */
BLI_addtail(&pose->chanbase, chan);
+ free_pose_channels_hash(pose);
return chan;
}
@@ -480,7 +493,7 @@ void copy_pose (bPose **dst, bPose *src, int copycon)
for (pchan=outPose->chanbase.first; pchan; pchan=pchan->next) {
// TODO: rename this argument...
if (copycon) {
- copy_constraints(&listb, &pchan->constraints); // copy_constraints NULLs listb
+ copy_constraints(&listb, &pchan->constraints, TRUE); // copy_constraints NULLs listb
pchan->constraints= listb;
pchan->path= NULL; // XXX remove this line when the new motionpaths are ready... (depreceated code)
pchan->mpath= NULL; /* motion paths should not get copied yet... */
@@ -531,6 +544,26 @@ void init_pose_ikparam(bPose *pose)
}
}
+void make_pose_channels_hash(bPose *pose)
+{
+ if(!pose->chanhash) {
+ bPoseChannel *pchan;
+
+ pose->chanhash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "make_pose_chan gh");
+ for(pchan=pose->chanbase.first; pchan; pchan=pchan->next)
+ BLI_ghash_insert(pose->chanhash, pchan->name, pchan);
+ }
+}
+
+void free_pose_channels_hash(bPose *pose)
+{
+ if(pose->chanhash) {
+ BLI_ghash_free(pose->chanhash, NULL, NULL);
+ pose->chanhash= NULL;
+ }
+}
+
+
void free_pose_channel(bPoseChannel *pchan)
{
// XXX this case here will need to be removed when the new motionpaths are ready
@@ -562,6 +595,8 @@ void free_pose_channels(bPose *pose)
BLI_freelistN(&pose->chanbase);
}
+
+ free_pose_channels_hash(pose);
}
void free_pose(bPose *pose)
@@ -632,7 +667,7 @@ void duplicate_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *pchan_
pchan->iklinweight= pchan_from->iklinweight;
/* constraints */
- copy_constraints(&pchan->constraints, &pchan_from->constraints);
+ copy_constraints(&pchan->constraints, &pchan_from->constraints, TRUE);
/* id-properties */
if(pchan->prop) {
@@ -1075,7 +1110,6 @@ void what_does_obaction (Scene *scene, Object *ob, Object *workob, bPose *pose,
copy_m4_m4(workob->parentinv, ob->parentinv);
copy_m4_m4(workob->constinv, ob->constinv);
workob->parent= ob->parent;
- workob->track= ob->track;
workob->rotmode= ob->rotmode;
@@ -1150,17 +1184,17 @@ static void blend_pose_strides(bPose *dst, bPose *src, float srcweight, short mo
bone matching diagram, strips A and B
- .------------------------.
- | A |
- '------------------------'
+ .------------------------.
+ | A |
+ '------------------------'
. . b2
- . .-------------v----------.
- . | B . |
- . '------------------------'
- . . .
- . . .
+ . .-------------v----------.
+ . | B . |
+ . '------------------------'
+ . . .
+ . . .
offset: . 0 . A-B . A-b2+B
- . . .
+ . . .
*/
@@ -1217,12 +1251,12 @@ static void blend_pose_offset_bone(bActionStrip *strip, bPose *dst, bPose *src,
/* if blending, we only add with factor scrweight */
mul_v3_fl(vec, srcweight);
- add_v3_v3v3(dst->cyclic_offset, dst->cyclic_offset, vec);
+ add_v3_v3(dst->cyclic_offset, vec);
}
}
}
- add_v3_v3v3(dst->cyclic_offset, dst->cyclic_offset, src->cyclic_offset);
+ add_v3_v3(dst->cyclic_offset, src->cyclic_offset);
}
/* added "sizecorr" here, to allow armatures to be scaled and still have striding.
@@ -1384,7 +1418,7 @@ static void do_nla(Scene *scene, Object *ob, int blocktype)
bActionStrip *strip, *striplast=NULL, *stripfirst=NULL;
float striptime, frametime, length, actlength;
float blendfac, stripframe;
- float scene_cfra= frame_to_float(scene, scene->r.cfra);
+ float scene_cfra= BKE_curframe(scene);
int doit, dostride;
if(blocktype==ID_AR) {
@@ -1582,7 +1616,7 @@ static void do_nla(Scene *scene, Object *ob, int blocktype)
}
else if(blocktype==ID_AR) {
/* apply stride offset to object */
- add_v3_v3v3(ob->obmat[3], ob->obmat[3], ob->pose->stride_offset);
+ add_v3_v3(ob->obmat[3], ob->pose->stride_offset);
}
/* free */
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index ddd5405a4c1..8c8567fdec9 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -40,31 +40,21 @@
#include "BLI_math.h"
#include "BLI_rand.h"
-#include "DNA_listBase.h"
#include "DNA_anim_types.h"
-#include "DNA_action_types.h"
#include "DNA_armature_types.h"
-#include "DNA_curve_types.h"
-#include "DNA_effect_types.h"
#include "DNA_group_types.h"
#include "DNA_key_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_object_types.h"
-#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_windowmanager_types.h"
#include "DNA_view3d_types.h"
#include "DNA_vfont_types.h"
#include "BKE_anim.h"
-#include "BKE_animsys.h"
#include "BKE_curve.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_displist.h"
-#include "BKE_effect.h"
+#include "BKE_depsgraph.h"
#include "BKE_font.h"
#include "BKE_group.h"
#include "BKE_global.h"
@@ -77,13 +67,9 @@
#include "BKE_scene.h"
#include "BKE_utildefines.h"
#include "BKE_tessmesh.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "BKE_depsgraph.h"
// XXX bad level call...
-#include "ED_mesh.h"
/* --------------------- */
/* forward declarations */
@@ -206,10 +192,15 @@ bMotionPath *animviz_verify_motionpaths(Scene *scene, Object *ob, bPoseChannel *
if (avs->path_bakeflag & MOTIONPATH_BAKE_HEADS)
mpath->flag |= MOTIONPATH_FLAG_BHEAD;
+ else
+ mpath->flag &= ~MOTIONPATH_FLAG_BHEAD;
/* allocate a cache */
mpath->points= MEM_callocN(sizeof(bMotionPathVert)*mpath->length, "bMotionPathVerts");
+ /* tag viz settings as currently having some path(s) which use it */
+ avs->path_bakeflag |= MOTIONPATH_BAKE_HAS_PATHS;
+
/* return it */
return mpath;
}
@@ -266,6 +257,83 @@ void animviz_get_object_motionpaths(Object *ob, ListBase *targets)
/* ........ */
+/* Note on evaluation optimisations:
+ * Optimisations currently used here play tricks with the depsgraph in order to try and
+ * evaluate as few objects as strictly necessary to get nicer performance under standard
+ * production conditions. For those people who really need the accurate version,
+ * disable the ifdef (i.e. 1 -> 0) and comment out the call to motionpaths_calc_optimise_depsgraph()
+ */
+
+/* tweak the object ordering to trick depsgraph into making MotionPath calculations run faster */
+static void motionpaths_calc_optimise_depsgraph(Scene *scene, ListBase *targets)
+{
+ Base *base, *baseNext;
+ MPathTarget *mpt;
+
+ /* make sure our temp-tag isn't already in use */
+ for (base= scene->base.first; base; base= base->next)
+ base->object->flag &= ~BA_TEMP_TAG;
+
+ /* for each target, dump its object to the start of the list if it wasn't moved already */
+ for (mpt= targets->first; mpt; mpt= mpt->next) {
+ for (base=scene->base.first; base; base=baseNext) {
+ baseNext = base->next;
+
+ if ((base->object == mpt->ob) && !(mpt->ob->flag & BA_TEMP_TAG)) {
+ BLI_remlink(&scene->base, base);
+ BLI_addhead(&scene->base, base);
+
+ mpt->ob->flag |= BA_TEMP_TAG;
+ break; // we really don't need to continue anymore once this happens, but this line might really 'break'
+ }
+ }
+ }
+
+ /* "brew me a list that's sorted a bit faster now depsy" */
+ DAG_scene_sort(scene);
+}
+
+/* update scene for current frame */
+static void motionpaths_calc_update_scene(Scene *scene)
+{
+#if 1 // 'production' optimisations always on
+ Base *base, *last=NULL;
+
+ /* only stuff that moves or needs display still */
+ DAG_scene_update_flags(scene, scene->lay);
+
+ /* find the last object with the tag
+ * - all those afterwards are assumed to not be relevant for our calculations
+ */
+ // optimise further by moving out...
+ for (base=scene->base.first; base; base=base->next) {
+ if (base->object->flag & BA_TEMP_TAG)
+ last = base;
+ }
+
+ /* perform updates for tagged objects */
+ // XXX: this will break if rigs depend on scene or other data that
+ // is animated but not attached to/updatable from objects
+ for (base=scene->base.first; base; base=base->next) {
+ /* update this object */
+ object_handle_update(scene, base->object);
+
+ /* if this is the last one we need to update, let's stop to save some time */
+ if (base == last)
+ break;
+ }
+#else // original, 'always correct' version
+ /* do all updates
+ * - if this is too slow, resort to using a more efficient way
+ * that doesn't force complete update, but for now, this is the
+ * most accurate way!
+ */
+ scene_update_for_newframe(scene, scene->lay); // XXX this is the best way we can get anything moving
+#endif
+}
+
+/* ........ */
+
/* perform baking for the targets on the current frame */
static void motionpaths_calc_bake_targets(Scene *scene, ListBase *targets)
{
@@ -327,7 +395,7 @@ void animviz_calc_motionpaths(Scene *scene, ListBase *targets)
// TODO: this method could be improved...
// 1) max range for standard baking
- // 2) minimum range for recalc baking (i.e. between keyfames, but how?)
+ // 2) minimum range for recalc baking (i.e. between keyframes, but how?)
for (mpt= targets->first; mpt; mpt= mpt->next) {
/* try to increase area to do (only as much as needed) */
sfra= MIN2(sfra, mpt->mpath->start_frame);
@@ -335,14 +403,14 @@ void animviz_calc_motionpaths(Scene *scene, ListBase *targets)
}
if (efra <= sfra) return;
+ /* optimise the depsgraph for faster updates */
+ // TODO: whether this is used should depend on some setting for the level of optimisations used
+ motionpaths_calc_optimise_depsgraph(scene, targets);
+
/* calculate path over requested range */
for (CFRA=sfra; CFRA<=efra; CFRA++) {
- /* do all updates
- * - if this is too slow, resort to using a more efficient way
- * that doesn't force complete update, but for now, this is the
- * most accurate way!
- */
- scene_update_for_newframe(scene, scene->lay); // XXX this is the best way we can get anything moving
+ /* update relevant data for new frame */
+ motionpaths_calc_update_scene(scene);
/* perform baking for targets */
motionpaths_calc_bake_targets(scene, targets);
@@ -350,7 +418,7 @@ void animviz_calc_motionpaths(Scene *scene, ListBase *targets)
/* reset original environment */
CFRA= cfra;
- scene_update_for_newframe(scene, scene->lay); // XXX this is the best way we can get anything moving
+ motionpaths_calc_update_scene(scene);
/* clear recalc flags from targets */
for (mpt= targets->first; mpt; mpt= mpt->next) {
@@ -410,7 +478,7 @@ void calc_curvepath(Object *ob)
bl= cu->bev.first;
if(bl==NULL || !bl->nr) return;
- cu->path=path= MEM_callocN(sizeof(Path), "path");
+ cu->path=path= MEM_callocN(sizeof(Path), "calc_curvepath");
/* if POLY: last vertice != first vertice */
cycl= (bl->poly!= -1);
@@ -451,7 +519,7 @@ void calc_curvepath(Object *ob)
fp= dist+1;
maxdist= dist+tot;
fac= 1.0f/((float)path->len-1.0f);
- fac = fac * path->totdist;
+ fac = fac * path->totdist;
for(a=0; a<path->len; a++) {
@@ -476,6 +544,7 @@ void calc_curvepath(Object *ob)
interp_v3_v3v3(pp->vec, bevp->vec, bevpn->vec, fac2);
pp->vec[3]= fac1*bevp->alfa + fac2*bevpn->alfa;
pp->radius= fac1*bevp->radius + fac2*bevpn->radius;
+ pp->weight= fac1*bevp->weight + fac2*bevpn->weight;
interp_qt_qtqt(pp->quat, bevp->quat, bevpn->quat, fac2);
normalize_qt(pp->quat);
@@ -507,7 +576,7 @@ int interval_test(int min, int max, int p1, int cycl)
* - *vec needs FOUR items!
* - ctime is normalized range <0-1>
*/
-int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius) /* returns OK */
+int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius, float *weight) /* returns OK */
{
Curve *cu;
Nurb *nu;
@@ -603,6 +672,9 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat,
if(radius)
*radius= data[0]*p0->radius + data[1]*p1->radius + data[2]*p2->radius + data[3]*p3->radius;
+ if(weight)
+ *weight= data[0]*p0->weight + data[1]*p1->weight + data[2]*p2->weight + data[3]*p3->weight;
+
return 1;
}
@@ -658,11 +730,21 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, i
}
dob= new_dupli_object(lb, go->ob, mat, ob->lay, 0, OB_DUPLIGROUP, animated);
- dob->no_draw= (dob->origlay & group->layer)==0;
-
+
+ /* check the group instance and object layers match, also that the object visible flags are ok. */
+ if( (dob->origlay & group->layer)==0 ||
+ (G.rendering==0 && dob->ob->restrictflag & OB_RESTRICT_VIEW) ||
+ (G.rendering && dob->ob->restrictflag & OB_RESTRICT_RENDER)
+ ) {
+ dob->no_draw= 1;
+ }
+ else {
+ dob->no_draw= 0;
+ }
+
if(go->ob->transflag & OB_DUPLI) {
copy_m4_m4(dob->ob->obmat, dob->mat);
- object_duplilist_recursive((ID *)group, scene, go->ob, lb, ob->obmat, level+1, animated);
+ object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, level+1, animated);
copy_m4_m4(dob->ob->obmat, dob->omat);
}
}
@@ -680,7 +762,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int level,
if(level>MAX_DUPLI_RECUR) return;
cfrao= scene->r.cfra;
- if(ob->parent==NULL && ob->track==NULL && ob->ipo==NULL && ob->constraints.first==NULL) return;
+ if(ob->parent==NULL && ob->constraints.first==NULL) return;
if(ob->transflag & OB_DUPLINOSPEED) enable_cu_speed= 0;
copyob= *ob; /* store transform info */
@@ -729,10 +811,9 @@ static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *n
vertexDupliData *vdd= userData;
float vec[3], q2[4], mat[3][3], tmat[4][4], obmat[4][4];
- VECCOPY(vec, co);
- mul_m4_v3(vdd->pmat, vec);
- sub_v3_v3v3(vec, vec, vdd->pmat[3]);
- add_v3_v3v3(vec, vec, vdd->obmat[3]);
+ mul_v3_m4v3(vec, vdd->pmat, co);
+ sub_v3_v3(vec, vdd->pmat[3]);
+ add_v3_v3(vec, vdd->obmat[3]);
copy_m4_m4(obmat, vdd->obmat);
VECCOPY(obmat[3], vec);
@@ -848,7 +929,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
/* mballs have a different dupli handling */
if(ob->type!=OB_MBALL) ob->flag |= OB_DONE; /* doesnt render */
- if(par->mode & OB_MODE_EDIT) {
+ if(me->edit_btmesh) {
dm->foreachMappedVert(dm, vertex_dupli__mapFunc, (void*) &vdd);
}
else {
@@ -988,7 +1069,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
mul_m4_v3(pmat, cent);
sub_v3_v3v3(cent, cent, pmat[3]);
- add_v3_v3v3(cent, cent, ob__obmat[3]);
+ add_v3_v3(cent, ob__obmat[3]);
copy_m4_m4(obmat, ob__obmat);
@@ -1011,7 +1092,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
copy_m4_m4(tmat, obmat);
mul_m4_m4m3(obmat, tmat, mat);
- dob= new_dupli_object(lb, ob, obmat, lay, a, OB_DUPLIFACES, animated);
+ dob= new_dupli_object(lb, ob, obmat, par->lay, a, OB_DUPLIFACES, animated);
if(G.rendering) {
w= (mv4)? 0.25f: 1.0f/3.0f;
@@ -1056,7 +1137,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
else go= go->next; /* group loop */
}
- if(par->mode & OB_MODE_EDIT) {
+ if(em) {
MEM_freeN(mface);
MEM_freeN(mvert);
}
@@ -1081,7 +1162,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
ParticleCacheKey *cache;
float ctime, pa_time, scale = 1.0f;
float tmat[4][4], mat[4][4], pamat[4][4], vec[3], size=0.0;
- float (*obmat)[4], (*oldobmat)[4], recurs_mat[4][4];
+ float (*obmat)[4], (*oldobmat)[4];
int lay, a, b, counter, hair = 0;
int totpart, totchild, totgroup=0, pa_num;
@@ -1098,10 +1179,6 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
if(!psys_check_enabled(par, psys))
return;
- /* particles are already in world space, don't want the object mat twice */
- if(par_space_mat)
- mul_m4_m4m4(recurs_mat, psys->imat, par_space_mat);
-
ctime = bsystem_time(scene, par, (float)scene->r.cfra, 0.0);
totpart = psys->totpart;
@@ -1110,11 +1187,21 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
BLI_srandom(31415926 + psys->seed);
lay= scene->lay;
- if((psys->renderdata || part->draw_as==PART_DRAW_REND) &&
- ((part->ren_as == PART_DRAW_OB && part->dup_ob) ||
- (part->ren_as == PART_DRAW_GR && part->dup_group && part->dup_group->gobject.first))) {
+ if((psys->renderdata || part->draw_as==PART_DRAW_REND) && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
- psys_check_group_weights(part);
+ /* first check for loops (particle system object used as dupli object) */
+ if(part->ren_as == PART_DRAW_OB) {
+ if(ELEM(part->dup_ob, NULL, par))
+ return;
+ }
+ else { /*PART_DRAW_GR */
+ if(part->dup_group == NULL || part->dup_group->gobject.first == NULL)
+ return;
+
+ for(go=part->dup_group->gobject.first; go; go=go->next)
+ if(go->ob == par)
+ return;
+ }
/* if we have a hair particle system, use the path cache */
if(part->type == PART_HAIR) {
@@ -1128,6 +1215,8 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
totpart = psys->totcached;
}
+ psys_check_group_weights(part);
+
psys->lattice = psys_get_lattice(&sim);
/* gather list of objects or single object */
@@ -1245,7 +1334,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
mul_m4_m4m4(tmat, oblist[b]->obmat, pamat);
mul_mat3_m4_fl(tmat, size*scale);
if(par_space_mat)
- mul_m4_m4m4(mat, tmat, recurs_mat);
+ mul_m4_m4m4(mat, tmat, par_space_mat);
else
copy_m4_m4(mat, tmat);
@@ -1271,7 +1360,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
VECADD(tmat[3], tmat[3], vec);
if(par_space_mat)
- mul_m4_m4m4(mat, tmat, recurs_mat);
+ mul_m4_m4m4(mat, tmat, par_space_mat);
else
copy_m4_m4(mat, tmat);
@@ -1442,7 +1531,10 @@ void free_object_duplilist(ListBase *lb)
{
DupliObject *dob;
- for(dob= lb->first; dob; dob= dob->next) {
+ /* loop in reverse order, if object is instanced multiple times
+ the original layer may not really be original otherwise, proper
+ solution is more complicated */
+ for(dob= lb->last; dob; dob= dob->prev) {
dob->ob->lay= dob->origlay;
copy_m4_m4(dob->ob->obmat, dob->omat);
}
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index a880417a111..10c2c1801cb 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -36,7 +36,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_dynstr.h"
#include "DNA_anim_types.h"
@@ -51,7 +50,6 @@
#include "BKE_utildefines.h"
#include "RNA_access.h"
-#include "RNA_types.h"
#include "nla_private.h"
@@ -274,7 +272,7 @@ static short check_rna_path_is_valid (ID *owner_id, char *path)
/* Check if some given RNA Path needs fixing - free the given path and set a new one as appropriate
* NOTE: we assume that oldName and newName have [" "] padding around them
*/
-static char *rna_path_rename_fix (ID *owner_id, char *prefix, char *oldName, char *newName, char *oldpath)
+static char *rna_path_rename_fix (ID *owner_id, char *prefix, char *oldName, char *newName, char *oldpath, int verify_paths)
{
char *prefixPtr= strstr(oldpath, prefix);
char *oldNamePtr= strstr(oldpath, oldName);
@@ -286,7 +284,7 @@ static char *rna_path_rename_fix (ID *owner_id, char *prefix, char *oldName, cha
*/
if ( (prefixPtr && oldNamePtr) && (prefixPtr+prefixLen == oldNamePtr) ) {
/* if we haven't aren't able to resolve the path now, try again after fixing it */
- if (check_rna_path_is_valid(owner_id, oldpath) == 0) {
+ if (!verify_paths || check_rna_path_is_valid(owner_id, oldpath) == 0) {
DynStr *ds= BLI_dynstr_new();
char *postfixPtr= oldNamePtr+oldNameLen;
char *newPath = NULL;
@@ -315,7 +313,7 @@ static char *rna_path_rename_fix (ID *owner_id, char *prefix, char *oldName, cha
/* check if the new path will solve our problems */
// TODO: will need to check whether this step really helps in practice
- if (check_rna_path_is_valid(owner_id, newPath)) {
+ if (!verify_paths || check_rna_path_is_valid(owner_id, newPath)) {
/* free the old path, and return the new one, since we've solved the issues */
MEM_freeN(oldpath);
return newPath;
@@ -332,7 +330,7 @@ static char *rna_path_rename_fix (ID *owner_id, char *prefix, char *oldName, cha
}
/* Check RNA-Paths for a list of F-Curves */
-static void fcurves_path_rename_fix (ID *owner_id, char *prefix, char *oldName, char *newName, ListBase *curves)
+static void fcurves_path_rename_fix (ID *owner_id, char *prefix, char *oldName, char *newName, ListBase *curves, int verify_paths)
{
FCurve *fcu;
@@ -340,7 +338,20 @@ static void fcurves_path_rename_fix (ID *owner_id, char *prefix, char *oldName,
for (fcu= curves->first; fcu; fcu= fcu->next) {
/* firstly, handle the F-Curve's own path */
if (fcu->rna_path)
- fcu->rna_path= rna_path_rename_fix(owner_id, prefix, oldName, newName, fcu->rna_path);
+ fcu->rna_path= rna_path_rename_fix(owner_id, prefix, oldName, newName, fcu->rna_path, verify_paths);
+ }
+}
+
+/* Check RNA-Paths for a list of Drivers */
+static void drivers_path_rename_fix (ID *owner_id, char *prefix, char *oldName, char *newName, char *oldKey, char *newKey, ListBase *curves, int verify_paths)
+{
+ FCurve *fcu;
+
+ /* we need to check every curve - drivers are F-Curves too! */
+ for (fcu= curves->first; fcu; fcu= fcu->next) {
+ /* firstly, handle the F-Curve's own path */
+ if (fcu->rna_path)
+ fcu->rna_path= rna_path_rename_fix(owner_id, prefix, oldKey, newKey, fcu->rna_path, verify_paths);
/* driver? */
if (fcu->driver) {
@@ -354,15 +365,16 @@ static void fcurves_path_rename_fix (ID *owner_id, char *prefix, char *oldName,
{
/* rename RNA path */
if (dtar->rna_path)
- dtar->rna_path= rna_path_rename_fix(dtar->id, prefix, oldName, newName, dtar->rna_path);
+ dtar->rna_path= rna_path_rename_fix(dtar->id, prefix, oldKey, newKey, dtar->rna_path, verify_paths);
/* also fix the bone-name (if applicable) */
- // XXX this has been disabled because the old/new names have padding which means this check will fail
- //if ( ((dtar->id) && (GS(dtar->id->name) == ID_OB)) &&
- // (dtar->pchan_name[0]) && (strcmp(oldName, dtar->pchan_name)==0) )
- //{
- // BLI_strncpy(dtar->pchan_name, newName, sizeof(dtar->pchan_name));
- //}
+ if (strstr(prefix, "bones")) {
+ if ( ((dtar->id) && (GS(dtar->id->name) == ID_OB)) &&
+ (dtar->pchan_name[0]) && (strcmp(oldName, dtar->pchan_name)==0) )
+ {
+ BLI_strncpy(dtar->pchan_name, newName, sizeof(dtar->pchan_name));
+ }
+ }
}
DRIVER_TARGETS_LOOPER_END
}
@@ -371,7 +383,7 @@ static void fcurves_path_rename_fix (ID *owner_id, char *prefix, char *oldName,
}
/* Fix all RNA-Paths for Actions linked to NLA Strips */
-static void nlastrips_path_rename_fix (ID *owner_id, char *prefix, char *oldName, char *newName, ListBase *strips)
+static void nlastrips_path_rename_fix (ID *owner_id, char *prefix, char *oldName, char *newName, ListBase *strips, int verify_paths)
{
NlaStrip *strip;
@@ -379,11 +391,11 @@ static void nlastrips_path_rename_fix (ID *owner_id, char *prefix, char *oldName
for (strip= strips->first; strip; strip= strip->next) {
/* fix strip's action */
if (strip->act)
- fcurves_path_rename_fix(owner_id, prefix, oldName, newName, &strip->act->curves);
+ fcurves_path_rename_fix(owner_id, prefix, oldName, newName, &strip->act->curves, verify_paths);
/* ignore own F-Curves, since those are local... */
/* check sub-strips (if metas) */
- nlastrips_path_rename_fix(owner_id, prefix, oldName, newName, &strip->strips);
+ nlastrips_path_rename_fix(owner_id, prefix, oldName, newName, &strip->strips, verify_paths);
}
}
@@ -391,31 +403,37 @@ static void nlastrips_path_rename_fix (ID *owner_id, char *prefix, char *oldName
* NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]>
* i.e. pose.bones["Bone"]
*/
-void BKE_animdata_fix_paths_rename (ID *owner_id, AnimData *adt, char *prefix, char *oldName, char *newName)
+void BKE_animdata_fix_paths_rename (ID *owner_id, AnimData *adt, char *prefix, char *oldName, char *newName, int oldSubscript, int newSubscript, int verify_paths)
{
NlaTrack *nlt;
char *oldN, *newN;
/* if no AnimData, no need to proceed */
- if (ELEM4(NULL, owner_id, adt, oldName, newName))
+ if (ELEM(NULL, owner_id, adt))
return;
- /* pad the names with [" "] so that only exact matches are made */
- oldN= BLI_sprintfN("[\"%s\"]", oldName);
- newN= BLI_sprintfN("[\"%s\"]", newName);
+ if ((oldName != NULL) && (newName != NULL)) {
+ /* pad the names with [" "] so that only exact matches are made */
+ oldN= BLI_sprintfN("[\"%s\"]", oldName);
+ newN= BLI_sprintfN("[\"%s\"]", newName);
+ }
+ else {
+ oldN= BLI_sprintfN("[%d]", oldSubscript);
+ newN= BLI_sprintfN("[%d]", newSubscript);
+ }
/* Active action and temp action */
if (adt->action)
- fcurves_path_rename_fix(owner_id, prefix, oldN, newN, &adt->action->curves);
+ fcurves_path_rename_fix(owner_id, prefix, oldN, newN, &adt->action->curves, verify_paths);
if (adt->tmpact)
- fcurves_path_rename_fix(owner_id, prefix, oldN, newN, &adt->tmpact->curves);
+ fcurves_path_rename_fix(owner_id, prefix, oldN, newN, &adt->tmpact->curves, verify_paths);
/* Drivers - Drivers are really F-Curves */
- fcurves_path_rename_fix(owner_id, prefix, oldN, newN, &adt->drivers);
+ drivers_path_rename_fix(owner_id, prefix, oldName, newName, oldN, newN, &adt->drivers, verify_paths);
/* NLA Data - Animation Data for Strips */
for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next)
- nlastrips_path_rename_fix(owner_id, prefix, oldN, newN, &nlt->strips);
+ nlastrips_path_rename_fix(owner_id, prefix, oldN, newN, &nlt->strips, verify_paths);
/* free the temp names */
MEM_freeN(oldN);
@@ -482,7 +500,7 @@ void BKE_all_animdata_fix_paths_rename (char *prefix, char *oldName, char *newNa
#define RENAMEFIX_ANIM_IDS(first) \
for (id= first; id; id= id->next) { \
AnimData *adt= BKE_animdata_from_id(id); \
- BKE_animdata_fix_paths_rename(id, adt, prefix, oldName, newName);\
+ BKE_animdata_fix_paths_rename(id, adt, prefix, oldName, newName, 0, 0, 1);\
}
/* nodes */
@@ -532,11 +550,11 @@ void BKE_all_animdata_fix_paths_rename (char *prefix, char *oldName, char *newNa
/* do compositing nodes first (since these aren't included in main tree) */
if (scene->nodetree) {
AnimData *adt2= BKE_animdata_from_id((ID *)scene->nodetree);
- BKE_animdata_fix_paths_rename((ID *)scene->nodetree, adt2, prefix, oldName, newName);
+ BKE_animdata_fix_paths_rename((ID *)scene->nodetree, adt2, prefix, oldName, newName, 0, 0, 1);
}
/* now fix scene animation data as per normal */
- BKE_animdata_fix_paths_rename((ID *)id, adt, prefix, oldName, newName);
+ BKE_animdata_fix_paths_rename((ID *)id, adt, prefix, oldName, newName, 0, 0, 1);
}
}
@@ -552,15 +570,9 @@ KS_Path *BKE_keyingset_find_path (KeyingSet *ks, ID *id, const char group_name[]
KS_Path *ksp;
/* sanity checks */
- if ELEM(NULL, ks, rna_path)
+ if ELEM3(NULL, ks, rna_path, id)
return NULL;
- /* ID is optional for relative KeyingSets, but is necessary for absolute KeyingSets */
- if (id == NULL) {
- if (ks->flag & KEYINGSET_ABSOLUTE)
- return NULL;
- }
-
/* loop over paths in the current KeyingSet, finding the first one where all settings match
* (i.e. the first one where none of the checks fail and equal 0)
*/
@@ -568,7 +580,7 @@ KS_Path *BKE_keyingset_find_path (KeyingSet *ks, ID *id, const char group_name[]
short eq_id=1, eq_path=1, eq_index=1, eq_group=1;
/* id */
- if ((ks->flag & KEYINGSET_ABSOLUTE) && (id != ksp->id))
+ if (id != ksp->id)
eq_id= 0;
/* path */
@@ -621,53 +633,48 @@ KeyingSet *BKE_keyingset_add (ListBase *list, const char name[], short flag, sho
return ks;
}
-/* Add a destination to a KeyingSet. Nothing is returned for now...
+/* Add a path to a KeyingSet. Nothing is returned for now...
* Checks are performed to ensure that destination is appropriate for the KeyingSet in question
*/
-void BKE_keyingset_add_path (KeyingSet *ks, ID *id, const char group_name[], const char rna_path[], int array_index, short flag, short groupmode)
+KS_Path *BKE_keyingset_add_path (KeyingSet *ks, ID *id, const char group_name[], const char rna_path[], int array_index, short flag, short groupmode)
{
KS_Path *ksp;
/* sanity checks */
if ELEM(NULL, ks, rna_path) {
- printf("ERROR: no Keying Set and/or RNA Path to add destination with \n");
- return;
+ printf("ERROR: no Keying Set and/or RNA Path to add path with \n");
+ return NULL;
}
- /* ID is optional for relative KeyingSets, but is necessary for absolute KeyingSets */
+ /* ID is required for all types of KeyingSets */
if (id == NULL) {
- if (ks->flag & KEYINGSET_ABSOLUTE) {
- printf("ERROR: No ID provided for absolute destination. \n");
- return;
- }
+ printf("ERROR: No ID provided for Keying Set Path. \n");
+ return NULL;
}
/* don't add if there is already a matching KS_Path in the KeyingSet */
if (BKE_keyingset_find_path(ks, id, group_name, rna_path, array_index, groupmode)) {
if (G.f & G_DEBUG)
printf("ERROR: destination already exists in Keying Set \n");
- return;
+ return NULL;
}
/* allocate a new KeyingSet Path */
ksp= MEM_callocN(sizeof(KS_Path), "KeyingSet Path");
/* just store absolute info */
- if (ks->flag & KEYINGSET_ABSOLUTE) {
- ksp->id= id;
- if (group_name)
- BLI_snprintf(ksp->group, 64, group_name);
- else
- strcpy(ksp->group, "");
- }
+ ksp->id= id;
+ if (group_name)
+ BLI_snprintf(ksp->group, 64, group_name);
+ else
+ strcpy(ksp->group, "");
/* store additional info for relative paths (just in case user makes the set relative) */
if (id)
ksp->idtype= GS(id->name);
/* just copy path info */
- // XXX no checks are performed for templates yet
- // should array index be checked too?
+ // TODO: should array index be checked too?
ksp->rna_path= BLI_strdupn(rna_path, strlen(rna_path));
ksp->array_index= array_index;
@@ -677,20 +684,37 @@ void BKE_keyingset_add_path (KeyingSet *ks, ID *id, const char group_name[], con
/* add KeyingSet path to KeyingSet */
BLI_addtail(&ks->paths, ksp);
+
+ /* return this path */
+ return ksp;
}
+/* Free the given Keying Set path */
+void BKE_keyingset_free_path (KeyingSet *ks, KS_Path *ksp)
+{
+ /* sanity check */
+ if ELEM(NULL, ks, ksp)
+ return;
+
+ /* free RNA-path info */
+ MEM_freeN(ksp->rna_path);
+
+ /* free path itself */
+ BLI_freelinkN(&ks->paths, ksp);
+}
+
/* Copy all KeyingSets in the given list */
-void BKE_keyingsets_copy(ListBase *newlist, ListBase *list)
+void BKE_keyingsets_copy (ListBase *newlist, ListBase *list)
{
KeyingSet *ksn;
KS_Path *kspn;
-
+
BLI_duplicatelist(newlist, list);
- for(ksn=newlist->first; ksn; ksn=ksn->next) {
+ for (ksn=newlist->first; ksn; ksn=ksn->next) {
BLI_duplicatelist(&ksn->paths, &ksn->paths);
-
- for(kspn=ksn->paths.first; kspn; kspn=kspn->next)
+
+ for (kspn=ksn->paths.first; kspn; kspn=kspn->next)
kspn->rna_path= MEM_dupallocN(kspn->rna_path);
}
}
@@ -709,12 +733,7 @@ void BKE_keyingset_free (KeyingSet *ks)
/* free each path as we go to avoid looping twice */
for (ksp= ks->paths.first; ksp; ksp= kspn) {
kspn= ksp->next;
-
- /* free RNA-path info */
- MEM_freeN(ksp->rna_path);
-
- /* free path itself */
- BLI_freelinkN(&ks->paths, ksp);
+ BKE_keyingset_free_path(ks, ksp);
}
}
@@ -768,28 +787,43 @@ static short animsys_write_rna_setting (PointerRNA *ptr, char *path, int array_i
PropertyRNA *prop;
PointerRNA new_ptr;
+ //printf("%p %s %i %f\n", ptr, path, array_index, value);
+
/* get property to write to */
if (RNA_path_resolve(ptr, path, &new_ptr, &prop))
{
/* set value - only for animatable numerical values */
if (RNA_property_animateable(&new_ptr, prop))
{
+ int array_len= RNA_property_array_length(&new_ptr, prop);
+
+ if(array_len && array_index >= array_len)
+ {
+ if (G.f & G_DEBUG) {
+ printf("Animato: Invalid array index. ID = '%s', '%s[%d]', array length is %d \n",
+ (ptr && ptr->id.data) ? (((ID *)ptr->id.data)->name+2) : "<No ID>",
+ path, array_index, array_len-1);
+ }
+
+ return 0;
+ }
+
switch (RNA_property_type(prop))
{
case PROP_BOOLEAN:
- if (RNA_property_array_length(&new_ptr, prop))
+ if (array_len)
RNA_property_boolean_set_index(&new_ptr, prop, array_index, (int)value);
else
RNA_property_boolean_set(&new_ptr, prop, (int)value);
break;
case PROP_INT:
- if (RNA_property_array_length(&new_ptr, prop))
+ if (array_len)
RNA_property_int_set_index(&new_ptr, prop, array_index, (int)value);
else
RNA_property_int_set(&new_ptr, prop, (int)value);
break;
case PROP_FLOAT:
- if (RNA_property_array_length(&new_ptr, prop))
+ if (array_len)
RNA_property_float_set_index(&new_ptr, prop, array_index, value);
else
RNA_property_float_set(&new_ptr, prop, value);
@@ -811,7 +845,7 @@ static short animsys_write_rna_setting (PointerRNA *ptr, char *path, int array_i
// XXX don't tag as failed yet though, as there are some legit situations (Action Constraint)
// where some channels will not exist, but shouldn't lock up Action
if (G.f & G_DEBUG) {
- printf("Animato: Invalid path. ID = '%s', '%s [%d]' \n",
+ printf("Animato: Invalid path. ID = '%s', '%s[%d]' \n",
(ptr && ptr->id.data) ? (((ID *)ptr->id.data)->name+2) : "<No ID>",
path, array_index);
}
@@ -983,6 +1017,14 @@ static void nlastrip_evaluate_controls (NlaStrip *strip, float ctime)
/* execute these settings as per normal */
animsys_evaluate_fcurves(&strip_ptr, &strip->fcurves, NULL, ctime);
}
+
+ /* if user can control the evaluation time (using F-Curves), consider the option which allows this time to be clamped
+ * to lie within extents of the action-clip, so that a steady changing rate of progress through several cycles of the clip
+ * can be achieved easily
+ */
+ // NOTE: if we add any more of these special cases, we better group them up nicely...
+ if ((strip->flag & NLASTRIP_FLAG_USR_TIME) && (strip->flag & NLASTRIP_FLAG_USR_TIME_CYCLIC))
+ strip->strip_time= fmod(strip->strip_time - strip->actstart, strip->actend - strip->actstart);
}
/* gets the strip active at the current time for a list of strips for evaluation purposes */
@@ -1718,7 +1760,7 @@ void BKE_animsys_evaluate_animdata (ID *id, AnimData *adt, float ctime, short re
*/
// TODO: need to double check that this all works correctly
if ((recalc & ADT_RECALC_ANIM) || (adt->recalc & ADT_RECALC_ANIM))
- {
+ {
/* evaluate NLA data */
if ((adt->nla_tracks.first) && !(adt->flag & ADT_NLA_EVAL_OFF))
{
@@ -1778,9 +1820,10 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
*/
#define EVAL_ANIM_IDS(first, aflag) \
for (id= first; id; id= id->next) { \
- AnimData *adt= BKE_animdata_from_id(id); \
- if ( (id->us > 1) || (id->us && !(id->flag & LIB_FAKEUSER)) ) \
+ if (ID_REAL_USERS(id) > 0) { \
+ AnimData *adt= BKE_animdata_from_id(id); \
BKE_animsys_evaluate_animdata(id, adt, ctime, aflag); \
+ } \
}
/* optimisation:
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 41fe3da248e..c44406b5ed4 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -40,27 +40,22 @@
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
-#include "DNA_action_types.h"
-#include "DNA_curve_types.h"
#include "DNA_constraint_types.h"
#include "DNA_mesh_types.h"
#include "DNA_lattice_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_nla_types.h"
-#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "DNA_view3d_types.h"
#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_action.h"
#include "BKE_anim.h"
-#include "BKE_blender.h"
#include "BKE_constraint.h"
#include "BKE_curve.h"
-#include "BKE_deform.h"
#include "BKE_depsgraph.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_deform.h"
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
@@ -68,15 +63,10 @@
#include "BKE_lattice.h"
#include "BKE_main.h"
#include "BKE_object.h"
-#include "BKE_object.h"
#include "BKE_utildefines.h"
#include "BIK_api.h"
#include "BKE_sketch.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
/* **************** Generic Functions, data level *************** */
bArmature *add_armature(char *name)
@@ -373,14 +363,14 @@ void bone_flip_name (char *name, int strip_number)
* axis: the axis to name on
* head/tail: the head/tail co-ordinate of the bone on the specified axis
*/
-void bone_autoside_name (char *name, int strip_number, short axis, float head, float tail)
+int bone_autoside_name (char *name, int strip_number, short axis, float head, float tail)
{
unsigned int len;
char basename[32]={""};
char extension[5]={""};
len= strlen(name);
- if (len == 0) return;
+ if (len == 0) return 0;
strcpy(basename, name);
/* Figure out extension to append:
@@ -474,9 +464,15 @@ void bone_autoside_name (char *name, int strip_number, short axis, float head, f
if ((32 - len) < strlen(extension) + 1) { /* add 1 for the '.' */
strncpy(name, basename, len-strlen(extension));
}
+
+ sprintf(name, "%s.%s", basename, extension);
+
+ return 1;
}
- sprintf(name, "%s.%s", basename, extension);
+ else {
+ return 0;
+ }
}
/* ************* B-Bone support ******************* */
@@ -692,11 +688,11 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest)
/* ************ Armature Deform ******************* */
-static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion, int rest_def)
+static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion)
{
Bone *bone= pchan->bone;
Mat4 *b_bone= b_bone_spline_setup(pchan, 0);
- Mat4 *b_bone_rest= (rest_def)? NULL: b_bone_spline_setup(pchan, 1);
+ Mat4 *b_bone_rest= b_bone_spline_setup(pchan, 1);
Mat4 *b_bone_mats;
DualQuat *b_bone_dual_quats= NULL;
float tmat[4][4];
@@ -716,17 +712,14 @@ static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion, int re
invert_m4_m4(b_bone_mats[0].mat, bone->arm_mat);
/* then we make the b_bone_mats:
- - first transform to local bone space
+ - first transform to local bone space
- translate over the curve to the bbone mat space
- transform with b_bone matrix
- transform back into global space */
unit_m4(tmat);
for(a=0; a<bone->segments; a++) {
- if(b_bone_rest)
- invert_m4_m4(tmat, b_bone_rest[a].mat);
- else
- tmat[3][1] = -a*(bone->length/(float)bone->segments);
+ invert_m4_m4(tmat, b_bone_rest[a].mat);
mul_serie_m4(b_bone_mats[a+1].mat, pchan->chan_mat, bone->arm_mat,
b_bone[a].mat, tmat, b_bone_mats[0].mat, NULL, NULL, NULL);
@@ -855,9 +848,8 @@ static float dist_bone_deform(bPoseChannel *pchan, float *vec, DualQuat *dq, flo
mul_m4_v3(pchan->chan_mat, cop);
// Make this a delta from the base position
- sub_v3_v3v3(cop, cop, co);
- cop[0]*=fac; cop[1]*=fac; cop[2]*=fac;
- add_v3_v3v3(vec, vec, cop);
+ sub_v3_v3(cop, co);
+ madd_v3_v3fl(vec, cop, fac);
if(mat)
pchan_deform_mat_add(pchan, fac, bbonemat, mat);
@@ -913,7 +905,7 @@ static void pchan_bone_deform(bPoseChannel *pchan, float weight, float *vec, Dua
}
void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
- float (*vertexCos)[3], float (*defMats)[3][3],
+ float (*vertexCos)[3], float (*defMats)[3][3],
int numVerts, int deformflag,
float (*prevCos)[3], const char *defgrp_name)
{
@@ -925,12 +917,11 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
float obinv[4][4], premat[4][4], postmat[4][4];
int use_envelope = deformflag & ARM_DEF_ENVELOPE;
int use_quaternion = deformflag & ARM_DEF_QUATERNION;
- int bbone_rest_def = deformflag & ARM_DEF_B_BONE_REST;
int invert_vgroup= deformflag & ARM_DEF_INVERT_VGROUP;
int numGroups = 0; /* safety for vertexgroup index overflow */
int i, target_totvert = 0; /* safety for vertexgroup overflow */
int use_dverts = 0;
- int armature_def_nr = -1;
+ int armature_def_nr;
int totchan;
if(arm->edbo) return;
@@ -952,7 +943,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
for(pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next) {
if(!(pchan->bone->flag & BONE_NO_DEFORM)) {
if(pchan->bone->segments > 1)
- pchan_b_bone_defmats(pchan, use_quaternion, bbone_rest_def);
+ pchan_b_bone_defmats(pchan, use_quaternion);
if(use_quaternion) {
pchan->dual_quat= &dualquats[totchan++];
@@ -962,26 +953,28 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
}
/* get the def_nr for the overall armature vertex group if present */
- for(i = 0, dg = target->defbase.first; dg; i++, dg = dg->next)
- if(defgrp_name && strcmp(defgrp_name, dg->name) == 0)
- armature_def_nr = i;
-
+ armature_def_nr= defgroup_name_index(target, defgrp_name);
+
+ if(ELEM(target->type, OB_MESH, OB_LATTICE)) {
+ numGroups = BLI_countlist(&target->defbase);
+
+ if(target->type==OB_MESH) {
+ Mesh *me= target->data;
+ dverts = me->dvert;
+ if(dverts)
+ target_totvert = me->totvert;
+ }
+ else {
+ Lattice *lt= target->data;
+ dverts = lt->dvert;
+ if(dverts)
+ target_totvert = lt->pntsu*lt->pntsv*lt->pntsw;
+ }
+ }
+
/* get a vertex-deform-index to posechannel array */
if(deformflag & ARM_DEF_VGROUP) {
if(ELEM(target->type, OB_MESH, OB_LATTICE)) {
- numGroups = BLI_countlist(&target->defbase);
-
- if(target->type==OB_MESH) {
- Mesh *me= target->data;
- dverts = me->dvert;
- target_totvert = me->totvert;
- }
- else {
- Lattice *lt= target->data;
- dverts = lt->dvert;
- if(dverts)
- target_totvert = lt->pntsu*lt->pntsv*lt->pntsw;
- }
/* if we have a DerivedMesh, only use dverts if it has them */
if(dm)
if(dm->getVertData(dm, 0, CD_MDEFORMVERT))
@@ -991,9 +984,9 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
if(use_dverts) {
defnrToPC = MEM_callocN(sizeof(*defnrToPC) * numGroups,
- "defnrToBone");
+ "defnrToBone");
for(i = 0, dg = target->defbase.first; dg;
- i++, dg = dg->next) {
+ i++, dg = dg->next) {
defnrToPC[i] = get_pose_channel(armOb->pose, dg->name);
/* exclude non-deforming bones */
if(defnrToPC[i]) {
@@ -1078,10 +1071,10 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
if(bone && bone->flag & BONE_MULT_VG_ENV) {
weight *= distfactor_to_bone(co, bone->arm_head,
- bone->arm_tail,
- bone->rad_head,
- bone->rad_tail,
- bone->dist);
+ bone->arm_tail,
+ bone->rad_head,
+ bone->rad_tail,
+ bone->dist);
}
pchan_bone_deform(pchan, weight, vec, dq, smat, co, &contrib);
}
@@ -1091,7 +1084,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
*/
if(deformed == 0 && use_envelope) {
for(pchan = armOb->pose->chanbase.first; pchan;
- pchan = pchan->next) {
+ pchan = pchan->next) {
if(!(pchan->bone->flag & BONE_NO_DEFORM))
contrib += dist_bone_deform(pchan, vec, dq, smat, co);
}
@@ -1099,7 +1092,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
}
else if(use_envelope) {
for(pchan = armOb->pose->chanbase.first; pchan;
- pchan = pchan->next) {
+ pchan = pchan->next) {
if(!(pchan->bone->flag & BONE_NO_DEFORM))
contrib += dist_bone_deform(pchan, vec, dq, smat, co);
}
@@ -1113,9 +1106,9 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
if(armature_weight != 1.0f) {
VECCOPY(dco, co);
mul_v3m3_dq( dco, (defMats)? summat: NULL,dq);
- sub_v3_v3v3(dco, dco, co);
+ sub_v3_v3(dco, co);
mul_v3_fl(dco, armature_weight);
- add_v3_v3v3(co, co, dco);
+ add_v3_v3(co, dco);
}
else
mul_v3m3_dq( co, (defMats)? summat: NULL,dq);
@@ -1301,10 +1294,10 @@ void pchan_apply_mat4(bPoseChannel *pchan, float mat[][4])
*/
void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4])
{
- float imat[4][4];
+ float imat[4][4];
- invert_m4_m4(imat, arm_mat);
- mul_m4_m4m4(delta_mat, pose_mat, imat);
+ invert_m4_m4(imat, arm_mat);
+ mul_m4_m4m4(delta_mat, pose_mat, imat);
}
/* **************** Rotation Mode Conversions ****************************** */
@@ -1377,21 +1370,21 @@ void BKE_rotMode_change_values (float quat[4], float eul[3], float axis[3], floa
*************************************************************************** */
/* Computes vector and roll based on a rotation. "mat" must
- contain only a rotation, and no scaling. */
+ contain only a rotation, and no scaling. */
void mat3_to_vec_roll(float mat[][3], float *vec, float *roll)
{
- if (vec)
- copy_v3_v3(vec, mat[1]);
+ if (vec)
+ copy_v3_v3(vec, mat[1]);
- if (roll) {
- float vecmat[3][3], vecmatinv[3][3], rollmat[3][3];
+ if (roll) {
+ float vecmat[3][3], vecmatinv[3][3], rollmat[3][3];
- vec_roll_to_mat3(mat[1], 0.0f, vecmat);
- invert_m3_m3(vecmatinv, vecmat);
- mul_m3_m3m3(rollmat, vecmatinv, mat);
+ vec_roll_to_mat3(mat[1], 0.0f, vecmat);
+ invert_m3_m3(vecmatinv, vecmat);
+ mul_m3_m3m3(rollmat, vecmatinv, mat);
- *roll= (float)atan2(rollmat[2][0], rollmat[2][2]);
- }
+ *roll= (float)atan2(rollmat[2][0], rollmat[2][2]);
+ }
}
/* Calculates the rest matrix of a bone based
@@ -1572,9 +1565,11 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
* 1. extract constraints not from proxy (CONSTRAINT_PROXY_LOCAL) from pchan's constraints
* 2. copy proxy-pchan's constraints on-to new
* 3. add extracted local constraints back on top
+ *
+ * note for copy_constraints: when copying constraints, disable 'do_extern' otherwise we get the libs direct linked in this blend.
*/
extract_proxylocal_constraints(&proxylocal_constraints, &pchan->constraints);
- copy_constraints(&pchanw.constraints, &pchanp->constraints);
+ copy_constraints(&pchanw.constraints, &pchanp->constraints, FALSE);
addlisttolist(&pchanw.constraints, &proxylocal_constraints);
/* constraints - set target ob pointer to own object */
@@ -1683,6 +1678,7 @@ void armature_rebuild_pose(Object *ob, bArmature *arm)
next= pchan->next;
if(pchan->bone==NULL) {
free_pose_channel(pchan);
+ free_pose_channels_hash(pose);
BLI_freelinkN(&pose->chanbase, pchan);
}
}
@@ -1702,6 +1698,8 @@ void armature_rebuild_pose(Object *ob, bArmature *arm)
ob->pose->flag &= ~POSE_RECALC;
ob->pose->flag |= POSE_WAS_REBUILT;
+
+ make_pose_channels_hash(ob->pose);
}
@@ -1776,20 +1774,13 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *ob, bPoseChannel
/* find the root bone and the chain of bones from the root to the tip
* NOTE: this assumes that the bones are connected, but that may not be true...
*/
- for (pchan= pchan_tip; pchan; pchan= pchan->parent) {
+ for (pchan= pchan_tip; pchan && (segcount < ikData->chainlen); pchan= pchan->parent, segcount++) {
/* store this segment in the chain */
pchanChain[segcount]= pchan;
/* if performing rebinding, calculate the length of the bone */
boneLengths[segcount]= pchan->bone->length;
totLength += boneLengths[segcount];
-
- /* check if we've gotten the number of bones required yet (after incrementing the count first)
- * NOTE: the 255 limit here is rather ugly, but the standard IK does this too!
- */
- segcount++;
- if ((segcount == ikData->chainlen) || (segcount > 255))
- break;
}
if (segcount == 0)
@@ -1947,7 +1938,7 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o
}
/* tail endpoint */
- if ( where_on_path(ikData->tar, tree->points[index], vec, dir, NULL, &rad) ) {
+ if ( where_on_path(ikData->tar, tree->points[index], vec, dir, NULL, &rad, NULL) ) {
/* apply curve's object-mode transforms to the position
* unless the option to allow curve to be positioned elsewhere is activated (i.e. no root)
*/
@@ -1963,7 +1954,7 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o
}
/* head endpoint */
- if ( where_on_path(ikData->tar, tree->points[index+1], vec, dir, NULL, &rad) ) {
+ if ( where_on_path(ikData->tar, tree->points[index+1], vec, dir, NULL, &rad, NULL) ) {
/* apply curve's object-mode transforms to the position
* unless the option to allow curve to be positioned elsewhere is activated (i.e. no root)
*/
@@ -2012,6 +2003,11 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o
rangle= dot_v3v3(rmat[1], splineVec);
rangle= acos( MAX2(-1.0f, MIN2(1.0f, rangle)) );
+ /* multiply the magnitude of the angle by the influence of the constraint to
+ * control the influence of the SplineIK effect
+ */
+ rangle *= tree->con->enforce;
+
/* construct rotation matrix from the axis-angle rotation found above
* - this call takes care to make sure that the axis provided is a unit vector first
*/
@@ -2058,7 +2054,7 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o
/* we need to clamp this within sensible values */
// NOTE: these should be fine for now, but should get sanitised in future
- scale= MIN2( MAX2(scale, 0.0001) , 100000);
+ scale= MIN2(MAX2(scale, 0.0001) , 100000);
}
else
scale= 1.0f;
@@ -2079,13 +2075,26 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o
}
}
- /* step 5: set the location of the bone in the matrix
- * - when the 'no-root' option is affected, the chain can retain
- * the shape but be moved elsewhere
- */
+ /* step 5: set the location of the bone in the matrix */
if (ikData->flag & CONSTRAINT_SPLINEIK_NO_ROOT) {
+ /* when the 'no-root' option is affected, the chain can retain
+ * the shape but be moved elsewhere
+ */
VECCOPY(poseHead, pchan->pose_head);
}
+ else if (tree->con->enforce < 1.0f) {
+ /* when the influence is too low
+ * - blend the positions for the 'root' bone
+ * - stick to the parent for any other
+ */
+ if (pchan->parent) {
+ VECCOPY(poseHead, pchan->pose_head);
+ }
+ else {
+ // FIXME: this introduces popping artifacts when we reach 0.0
+ interp_v3_v3v3(poseHead, pchan->pose_head, poseHead, tree->con->enforce);
+ }
+ }
VECCOPY(poseMat[3], poseHead);
/* finally, store the new transform */
@@ -2117,8 +2126,6 @@ static void splineik_execute_tree(Scene *scene, Object *ob, bPoseChannel *pchan_
splineik_evaluate_bone(tree, scene, ob, pchan, i, ctime);
}
- // TODO: if another pass is needed to ensure the validity of the chain after blending, it should go here
-
/* free the tree info specific to SplineIK trees now */
if (tree->chain) MEM_freeN(tree->chain);
if (tree->free_points) MEM_freeN(tree->points);
@@ -2268,7 +2275,7 @@ static void do_strip_modifiers(Scene *scene, Object *armob, Bone *bone, bPoseCha
nor[0] = BLI_gNoise(amod->noisesize, size[0]+ofs, size[1], size[2], 0, 0) - ofs;
nor[1] = BLI_gNoise(amod->noisesize, size[0], size[1]+ofs, size[2], 0, 0) - ofs;
nor[2] = BLI_gNoise(amod->noisesize, size[0], size[1], size[2]+ofs, 0, 0) - ofs;
- add_v3_v3v3(size, size, nor);
+ add_v3_v3(size, nor);
if (sizeo[0] != 0)
mul_v3_fl(pchan->pose_mat[0], size[0] / sizeo[0]);
@@ -2284,7 +2291,7 @@ static void do_strip_modifiers(Scene *scene, Object *armob, Bone *bone, bPoseCha
nor[2] = BLI_gNoise(amod->noisesize, eul[0], eul[1], eul[2]+ofs, 0, 0) - ofs;
compatible_eul(nor, eulo);
- add_v3_v3v3(eul, eul, nor);
+ add_v3_v3(eul, nor);
compatible_eul(eul, eulo);
loc_eul_size_to_mat4(pchan->pose_mat, loc, eul, size);
@@ -2387,7 +2394,7 @@ void where_is_pose_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float cti
/* only rootbones get the cyclic offset (unless user doesn't want that) */
if ((bone->flag & BONE_NO_CYCLICOFFSET) == 0)
- add_v3_v3v3(pchan->pose_mat[3], pchan->pose_mat[3], ob->pose->cyclic_offset);
+ add_v3_v3(pchan->pose_mat[3], ob->pose->cyclic_offset);
}
if(do_extra) {
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 81f3aeeffb6..590b9f7e476 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -48,45 +48,32 @@
#include "MEM_guardedalloc.h"
-#include "DNA_curve_types.h"
-#include "DNA_listBase.h"
-#include "DNA_sdna_types.h"
#include "DNA_userdef_types.h"
-#include "DNA_object_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
-#include "DNA_sound_types.h"
#include "DNA_sequence_types.h"
#include "BLI_blenlib.h"
#include "BLI_dynstr.h"
+#include "BLI_path_util.h"
-#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
-#include "BKE_animsys.h"
-#include "BKE_action.h"
#include "BKE_blender.h"
#include "BKE_context.h"
-#include "BKE_curve.h"
#include "BKE_depsgraph.h"
#include "BKE_displist.h"
-#include "BKE_font.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
-#include "BKE_library.h"
#include "BKE_ipo.h"
+#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_node.h"
-#include "BKE_object.h"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_sequencer.h"
-#include "BKE_sound.h"
-#include "BLI_editVert.h"
#include "BLO_undofile.h"
#include "BLO_readfile.h"
@@ -114,7 +101,7 @@ void free_blender(void)
BKE_spacetypes_free(); /* after free main, it uses space callbacks */
- IMB_freeImBufdata(); /* imbuf lib */
+ IMB_exit();
free_nodesystem();
}
@@ -144,6 +131,8 @@ void initglobals(void)
G.charstart = 0x0000;
G.charmin = 0x0000;
G.charmax = 0xffff;
+
+ G.f |= G_SCRIPT_AUTOEXEC;
}
/***/
@@ -290,6 +279,8 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename)
else bfd->globalf &= ~G_DEBUG;
if (G.f & G_SWAP_EXCHANGE) bfd->globalf |= G_SWAP_EXCHANGE;
else bfd->globalf &= ~G_SWAP_EXCHANGE;
+ if (G.f & G_SCRIPT_AUTOEXEC) bfd->globalf |= G_SCRIPT_AUTOEXEC;
+ else bfd->globalf &= ~G_SCRIPT_AUTOEXEC;
G.f= bfd->globalf;
@@ -297,14 +288,22 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename)
//setscreen(G.curscreen);
}
- // XXX temporarily here
- if(G.main->versionfile < 250)
- do_versions_ipos_to_animato(G.main); // XXX fixme... complicated versionpatching
+ // FIXME: this version patching should really be part of the file-reading code,
+ // but we still get too many unrelated data-corruption crashes otherwise...
+ if (G.main->versionfile < 250)
+ do_versions_ipos_to_animato(G.main);
- /* in case of autosave or quit.blend, use original filename instead
- * use relbase_valid to make sure the file is saved, else we get <memory2> in the filename */
- if(recover && bfd->filename[0] && G.relbase_valid)
+ if(recover && bfd->filename[0] && G.relbase_valid) {
+ /* in case of autosave or quit.blend, use original filename instead
+ * use relbase_valid to make sure the file is saved, else we get <memory2> in the filename */
filename= bfd->filename;
+ }
+#if 0
+ else if (!G.relbase_valid) {
+ /* otherwise, use an empty string as filename, rather than <memory2> */
+ filename="";
+ }
+#endif
/* these are the same at times, should never copy to the same location */
if(G.sce != filename)
@@ -314,8 +313,6 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename)
/* baseflags, groups, make depsgraph, etc */
set_scene_bg(CTX_data_scene(C));
-
- DAG_on_load_update();
MEM_freeN(bfd);
}
@@ -370,7 +367,7 @@ int BKE_read_file(bContext *C, char *dir, void *unused, ReportList *reports)
BlendFileData *bfd;
int retval= 1;
- if(strstr(dir, ".B25.blend")==0) /* dont print user-pref loading */
+ if(strstr(dir, BLENDER_STARTUP_FILE)==0) /* dont print user-pref loading */
printf("read blend: %s\n", dir);
bfd= BLO_read_from_file(dir, reports);
@@ -479,6 +476,9 @@ static int read_undosave(bContext *C, UndoElem *uel)
strcpy(G.sce, scestr);
G.fileflags= fileflags;
+ if(success)
+ DAG_on_load_update();
+
return success;
}
@@ -537,7 +537,7 @@ void BKE_write_undo(bContext *C, char *name)
sprintf(numstr, "%d.blend", counter);
BLI_make_file_string("/", tstr, btempdir, numstr);
- success= BLO_write_file(CTX_data_main(C), tstr, G.fileflags, NULL);
+ success= BLO_write_file(CTX_data_main(C), tstr, G.fileflags, NULL, NULL);
strcpy(curundo->str, tstr);
}
diff --git a/source/blender/blenkernel/intern/bmfont.c b/source/blender/blenkernel/intern/bmfont.c
index 409e7edb519..e2a6c04450b 100644
--- a/source/blender/blenkernel/intern/bmfont.c
+++ b/source/blender/blenkernel/intern/bmfont.c
@@ -51,17 +51,11 @@
#include <stdio.h>
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BKE_global.h"
#include "IMB_imbuf_types.h"
-#include "BKE_bmfont.h"
#include "BKE_bmfont_types.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
void printfGlyph(bmGlyph * glyph)
{
printf("unicode: %d '%c'\n", glyph->unicode, glyph->unicode);
@@ -180,8 +174,8 @@ void detectBitmapFont(ImBuf *ibuf)
unsigned short version;
int i;
- if (ibuf != NULL) {
- // bitmap must have an x size that is a power of two
+ if (ibuf != NULL && ibuf->rect != NULL) {
+ // bitmap must have an x size that is a power of two
if (is_power_of_two(ibuf->x)) {
rect = (unsigned char *) (ibuf->rect + (ibuf->x * (ibuf->y - 1)));
// printf ("starts with: %s %c %c %c %c\n", rect, rect[0], rect[1], rect[2], rect[3]);
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index b521ec41cba..82602a6951d 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -34,19 +34,13 @@
#include "MEM_guardedalloc.h"
-#include "DNA_particle_types.h"
-#include "DNA_modifier_types.h"
#include "DNA_object_force.h"
-#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "DNA_boid_types.h"
-#include "DNA_listBase.h"
#include "BLI_rand.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_kdtree.h"
-#include "BLI_kdopbvh.h"
#include "BKE_collision.h"
#include "BKE_effect.h"
#include "BKE_boids.h"
@@ -147,7 +141,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
get_effector_data(eff, &efd, &epoint, 1);
mul_v3_fl(efd.vel, efd.distance / (val->max_speed * bbd->timestep));
- add_v3_v3v3(efd.loc, efd.loc, efd.vel);
+ add_v3_v3(efd.loc, efd.vel);
sub_v3_v3v3(efd.vec_to_point, pa->prev_state.co, efd.loc);
efd.distance = len_v3(efd.vec_to_point);
}
@@ -361,7 +355,7 @@ static int rule_separate(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Pa
if(neighbors > 1 && ptn[1].dist!=0.0f) {
sub_v3_v3v3(vec, pa->prev_state.co, bbd->sim->psys->particles[ptn[1].index].state.co);
mul_v3_fl(vec, (2.0f * val->personal_space * pa->size - ptn[1].dist) / ptn[1].dist);
- add_v3_v3v3(bbd->wanted_co, bbd->wanted_co, vec);
+ add_v3_v3(bbd->wanted_co, vec);
bbd->wanted_speed = val->max_speed;
len = ptn[1].dist;
ret = 1;
@@ -378,7 +372,7 @@ static int rule_separate(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Pa
if(neighbors > 0 && ptn[0].dist < len) {
sub_v3_v3v3(vec, pa->prev_state.co, ptn[0].co);
mul_v3_fl(vec, (2.0f * val->personal_space * pa->size - ptn[0].dist) / ptn[1].dist);
- add_v3_v3v3(bbd->wanted_co, bbd->wanted_co, vec);
+ add_v3_v3(bbd->wanted_co, vec);
bbd->wanted_speed = val->max_speed;
len = ptn[0].dist;
ret = 1;
@@ -399,18 +393,18 @@ static int rule_flock(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
if(neighbors > 1) {
for(n=1; n<neighbors; n++) {
- add_v3_v3v3(loc, loc, bbd->sim->psys->particles[ptn[n].index].prev_state.co);
- add_v3_v3v3(vec, vec, bbd->sim->psys->particles[ptn[n].index].prev_state.vel);
+ add_v3_v3(loc, bbd->sim->psys->particles[ptn[n].index].prev_state.co);
+ add_v3_v3(vec, bbd->sim->psys->particles[ptn[n].index].prev_state.vel);
}
mul_v3_fl(loc, 1.0f/((float)neighbors - 1.0f));
mul_v3_fl(vec, 1.0f/((float)neighbors - 1.0f));
- sub_v3_v3v3(loc, loc, pa->prev_state.co);
- sub_v3_v3v3(vec, vec, pa->prev_state.vel);
+ sub_v3_v3(loc, pa->prev_state.co);
+ sub_v3_v3(vec, pa->prev_state.vel);
- add_v3_v3v3(bbd->wanted_co, bbd->wanted_co, vec);
- add_v3_v3v3(bbd->wanted_co, bbd->wanted_co, loc);
+ add_v3_v3(bbd->wanted_co, vec);
+ add_v3_v3(bbd->wanted_co, loc);
bbd->wanted_speed = len_v3(bbd->wanted_co);
ret = 1;
@@ -573,13 +567,13 @@ static int rule_average_speed(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
mul_v3_fl(bbd->wanted_co, 1.1f);
- add_v3_v3v3(bbd->wanted_co, bbd->wanted_co, vec);
+ add_v3_v3(bbd->wanted_co, vec);
/* leveling */
if(asbr->level > 0.0f && psys_uses_gravity(bbd->sim)) {
project_v3_v3v3(vec, bbd->wanted_co, bbd->sim->scene->physics_settings.gravity);
mul_v3_fl(vec, asbr->level);
- sub_v3_v3v3(bbd->wanted_co, bbd->wanted_co, vec);
+ sub_v3_v3(bbd->wanted_co, vec);
}
}
else {
@@ -596,7 +590,7 @@ static int rule_average_speed(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
if(asbr->level > 0.0f && psys_uses_gravity(bbd->sim)) {
project_v3_v3v3(vec, bbd->wanted_co, bbd->sim->scene->physics_settings.gravity);
mul_v3_fl(vec, asbr->level);
- sub_v3_v3v3(bbd->wanted_co, bbd->wanted_co, vec);
+ sub_v3_v3(bbd->wanted_co, vec);
}
}
@@ -754,7 +748,7 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro
/* take surface velocity into account */
closest_point_on_surface(surmd, pa->state.co, x, NULL, v);
- add_v3_v3v3(x, x, v);
+ add_v3_v3(x, v);
/* get actual position on surface */
closest_point_on_surface(surmd, x, ground_co, ground_nor, NULL);
@@ -771,10 +765,10 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro
if(!bbd->sim->colliders)
return NULL;
- VECCOPY(col.co1, pa->state.co);
- VECCOPY(col.co2, pa->state.co);
- add_v3_v3v3(col.co1, col.co1, zvec);
- sub_v3_v3v3(col.co2, col.co2, zvec);
+ copy_v3_v3(col.co1, pa->state.co);
+ copy_v3_v3(col.co2, pa->state.co);
+ add_v3_v3(col.co1, zvec);
+ sub_v3_v3(col.co2, zvec);
sub_v3_v3v3(ray_dir, col.co2, col.co1);
col.t = 0.0f;
hit.index = -1;
@@ -962,7 +956,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
int n = 0;
for(rule = state->rules.first; rule; rule=rule->next) {
if(apply_boid_rule(bbd, rule, &val, pa, -1.0f)) {
- add_v3_v3v3(wanted_co, wanted_co, bbd->wanted_co);
+ add_v3_v3(wanted_co, bbd->wanted_co);
wanted_speed += bbd->wanted_speed;
n++;
bbd->wanted_co[0]=bbd->wanted_co[1]=bbd->wanted_co[2]=bbd->wanted_speed=0.0f;
@@ -1211,7 +1205,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
mul_v3_fl(force, length);
}
- add_v3_v3v3(acc, acc, force);
+ add_v3_v3(acc, force);
/* store smoothed acceleration for nice banking etc. */
VECADDFAC(bpa->data.acc, bpa->data.acc, acc, dtime);
@@ -1228,8 +1222,8 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
VECCOPY(bvec, pa->prev_state.vel);
mul_v3_fl(bvec, dtime);
- add_v3_v3v3(dvec, dvec, bvec);
- add_v3_v3v3(pa->state.co, pa->state.co, dvec);
+ add_v3_v3(dvec, bvec);
+ add_v3_v3(pa->state.co, dvec);
VECADDFAC(pa->state.vel, pa->state.vel, acc, dtime);
diff --git a/source/blender/blenkernel/intern/booleanops.c b/source/blender/blenkernel/intern/booleanops.c
index f9b9b33d4ae..f9df0beca7c 100644
--- a/source/blender/blenkernel/intern/booleanops.c
+++ b/source/blender/blenkernel/intern/booleanops.c
@@ -45,7 +45,6 @@
#include "CSG_BooleanOps.h"
-#include "BKE_booleanops.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_customdata.h"
#include "BKE_depsgraph.h"
@@ -380,7 +379,7 @@ static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh(
// a hash table to remap materials to indices
if (mat) {
- material_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+ material_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "booleanops.c");
*totmat = 0;
}
diff --git a/source/blender/blenkernel/intern/booleanops_mesh.c b/source/blender/blenkernel/intern/booleanops_mesh.c
index 1e99661f445..431e51cf149 100644
--- a/source/blender/blenkernel/intern/booleanops_mesh.c
+++ b/source/blender/blenkernel/intern/booleanops_mesh.c
@@ -30,24 +30,10 @@
*/
#include "CSG_BooleanOps.h"
-#include "BKE_booleanops.h"
-#include "BKE_booleanops_mesh.h"
#include "MEM_guardedalloc.h"
-#include "DNA_material_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-#include "BKE_global.h"
-#include "BKE_mesh.h"
-#include "BKE_displist.h"
-#include "BKE_object.h"
-#include "BKE_utildefines.h"
-#include "BKE_library.h"
-#include "BKE_material.h"
-#include "BLI_math.h"
/**
* Implementation of boolean ops mesh interface.
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index bc30b2669e8..c423d426e32 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -34,9 +34,6 @@
#include "DNA_brush_types.h"
#include "DNA_color_types.h"
-#include "DNA_image_types.h"
-#include "DNA_object_types.h"
-#include "DNA_texture_types.h"
#include "DNA_scene_types.h"
#include "DNA_windowmanager_types.h"
@@ -56,9 +53,7 @@
#include "BKE_main.h"
#include "BKE_paint.h"
#include "BKE_texture.h"
-#include "BKE_utildefines.h"
-
-
+#include "BKE_icons.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -74,29 +69,59 @@ Brush *add_brush(const char *name)
brush= alloc_libblock(&G.main->brush, ID_BR, name);
- brush->rgb[0]= 1.0f;
+ /* BRUSH SCULPT TOOL SETTINGS */
+ brush->sculpt_tool = SCULPT_TOOL_DRAW; /* sculpting defaults to the draw tool for new brushes */
+ brush->size= 35; /* radius of the brush in pixels */
+ brush->alpha= 0.5f; /* brush strength/intensity probably variable should be renamed? */
+ brush->autosmooth_factor= 0.0f;
+ brush->crease_pinch_factor= 0.5f;
+ brush->sculpt_plane = SCULPT_DISP_DIR_VIEW;
+ brush->plane_offset= 0.0f; /* how far above or below the plane that is found by averaging the faces */
+ brush->plane_trim= 0.5f;
+ brush->clone.alpha= 0.5f;
+ brush->normal_weight= 0.0f;
+
+ /* BRUSH PAINT TOOL SETTINGS */
+ brush->rgb[0]= 1.0f; /* default rgb color of the brush when painting - white */
brush->rgb[1]= 1.0f;
brush->rgb[2]= 1.0f;
- brush->alpha= 0.2f;
- brush->size= 25;
- brush->spacing= 7.5f;
+
+ /* BRUSH STROKE SETTINGS */
+ brush->flag |= (BRUSH_SPACE|BRUSH_SPACE_ATTEN);
+ brush->spacing= 10; /* how far each brush dot should be spaced as a percentage of brush diameter */
+
brush->smooth_stroke_radius= 75;
- brush->smooth_stroke_factor= 0.9;
- brush->rate= 0.1f;
+ brush->smooth_stroke_factor= 0.9f;
+
+ brush->rate= 0.1f; /* time delay between dots of paint or sculpting when doing airbrush mode */
+
brush->jitter= 0.0f;
- brush->clone.alpha= 0.5;
- brush->sculpt_tool = SCULPT_TOOL_DRAW;
- brush->flag |= BRUSH_SPACE;
- brush_curve_preset(brush, CURVE_PRESET_SMOOTH);
-
+ /* BRUSH TEXTURE SETTINGS */
default_mtex(&brush->mtex);
+ brush->texture_sample_bias= 0; /* value to added to texture samples */
+
+ /* brush appearance */
+
+ brush->image_icon= NULL;
+
+ brush->add_col[0]= 1.00; /* add mode color is light red */
+ brush->add_col[1]= 0.39;
+ brush->add_col[2]= 0.39;
+
+ brush->sub_col[0]= 0.39; /* subtract mode color is light blue */
+ brush->sub_col[1]= 0.39;
+ brush->sub_col[2]= 1.00;
+
+ /* the default alpha falloff curve */
+ brush_curve_preset(brush, CURVE_PRESET_SMOOTH);
+
/* enable fake user by default */
brush->id.flag |= LIB_FAKEUSER;
brush_toggled_fake_user(brush);
-
- return brush;
+
+ return brush;
}
Brush *copy_brush(Brush *brush)
@@ -122,7 +147,7 @@ Brush *copy_brush(Brush *brush)
void free_brush(Brush *brush)
{
if(brush->mtex.tex) brush->mtex.tex->id.us--;
-
+
curvemapping_free(brush->curve);
}
@@ -237,7 +262,8 @@ void brush_curve_preset(Brush *b, /*CurveMappingPreset*/int preset)
cm = b->curve->cm;
cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
- curvemap_reset(cm, &b->curve->clipr, preset);
+ b->curve->preset = preset;
+ curvemap_reset(cm, &b->curve->clipr, b->curve->preset);
curvemapping_changed(b->curve, 0);
}
@@ -681,7 +707,7 @@ static void brush_painter_refresh_cache(BrushPainter *painter, float *pos)
short flt;
if ((brush->size != cache->lastsize) || (brush->alpha != cache->lastalpha)
- || (brush->jitter != cache->lastjitter)) {
+ || (brush->jitter != cache->lastjitter)) {
if (cache->ibuf) {
IMB_freeImBuf(cache->ibuf);
cache->ibuf= NULL;
@@ -734,11 +760,19 @@ static void brush_apply_pressure(BrushPainter *painter, Brush *brush, float pres
brush->spacing = MAX2(1.0, painter->startspacing*(1.5f-pressure));
}
-static void brush_jitter_pos(Brush *brush, float *pos, float *jitterpos)
+void brush_jitter_pos(Brush *brush, float *pos, float *jitterpos)
{
if(brush->jitter){
- jitterpos[0] = pos[0] + ((BLI_frand()-0.5f) * brush->size * brush->jitter * 2);
- jitterpos[1] = pos[1] + ((BLI_frand()-0.5f) * brush->size * brush->jitter * 2);
+ float rand_pos[2];
+
+ // find random position within a circle of diameter 1
+ do {
+ rand_pos[0] = BLI_frand()-0.5f;
+ rand_pos[1] = BLI_frand()-0.5f;
+ } while (len_v2(rand_pos) > 0.5f);
+
+ jitterpos[0] = pos[0] + 2*rand_pos[0]*brush->size*brush->jitter;
+ jitterpos[1] = pos[1] + 2*rand_pos[1]*brush->size*brush->jitter;
}
else {
VECCOPY2D(jitterpos, pos);
@@ -890,7 +924,7 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
/* Uses the brush curve control to find a strength value between 0 and 1 */
float brush_curve_strength_clamp(Brush *br, float p, const float len)
{
- if(p >= len) p= 1.0f;
+ if(p >= len) return 0;
else p= p/len;
p= curvemapping_evaluateF(br->curve, 0, p);
@@ -902,9 +936,12 @@ float brush_curve_strength_clamp(Brush *br, float p, const float len)
* used for sculpt only */
float brush_curve_strength(Brush *br, float p, const float len)
{
- if(p >= len) p= 1.0f;
- else p= p/len;
- return curvemapping_evaluateF(br->curve, 0, p);
+ if(p >= len)
+ p= 1.0f;
+ else
+ p= p/len;
+
+ return curvemapping_evaluateF(br->curve, 0, p);
}
/* TODO: should probably be unified with BrushPainter stuff? */
@@ -918,7 +955,7 @@ unsigned int *brush_gen_texture_cache(Brush *br, int half_side)
memset(&texres, 0, sizeof(TexResult));
- if(mtex && mtex->tex) {
+ if(mtex->tex) {
float x, y, step = 2.0 / side, co[3];
texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");
@@ -933,7 +970,7 @@ unsigned int *brush_gen_texture_cache(Brush *br, int half_side)
co[2]= 0.0f;
/* This is copied from displace modifier code */
- hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 1, &texres);
+ hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres);
/* if the texture gave an RGB value, we assume it didn't give a valid
* intensity, so calculate one (formula from do_material_tex).
@@ -941,7 +978,7 @@ unsigned int *brush_gen_texture_cache(Brush *br, int half_side)
*/
if(hasrgb & TEX_RGB)
texres.tin = (0.35 * texres.tr + 0.45 *
- texres.tg + 0.2 * texres.tb);
+ texres.tg + 0.2 * texres.tb);
texres.tin = texres.tin * 255.0;
((char*)texcache)[(iy*side+ix)*4] = (char)texres.tin;
@@ -996,9 +1033,9 @@ void brush_radial_control_invoke(wmOperator *op, Brush *br, float size_weight)
float original_value= 0;
if(mode == WM_RADIALCONTROL_SIZE)
- original_value = br->size * size_weight;
+ original_value = sculpt_get_brush_size(br) * size_weight;
else if(mode == WM_RADIALCONTROL_STRENGTH)
- original_value = br->alpha;
+ original_value = sculpt_get_brush_alpha(br);
else if(mode == WM_RADIALCONTROL_ANGLE) {
MTex *mtex = brush_active_texture(br);
if(mtex)
@@ -1016,9 +1053,15 @@ int brush_radial_control_exec(wmOperator *op, Brush *br, float size_weight)
const float conv = 0.017453293;
if(mode == WM_RADIALCONTROL_SIZE)
- br->size = new_value * size_weight;
+ if (sculpt_get_lock_brush_size(br)) {
+ float initial_value = RNA_float_get(op->ptr, "initial_value");
+ const float unprojected_radius = sculpt_get_brush_unprojected_radius(br);
+ sculpt_set_brush_unprojected_radius(br, unprojected_radius * new_value/initial_value * size_weight);
+ }
+ else
+ sculpt_set_brush_size(br, new_value * size_weight);
else if(mode == WM_RADIALCONTROL_STRENGTH)
- br->alpha = new_value;
+ sculpt_set_brush_alpha(br, new_value);
else if(mode == WM_RADIALCONTROL_ANGLE) {
MTex *mtex = brush_active_texture(br);
if(mtex)
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index 082910869bf..0b2f491b28d 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -32,21 +32,12 @@
#include <math.h>
#include <assert.h>
-#include "BKE_bvhutils.h"
-
-#include "DNA_object_types.h"
-#include "DNA_modifier_types.h"
#include "DNA_meshdata_types.h"
#include "BKE_DerivedMesh.h"
#include "BKE_utildefines.h"
-#include "BKE_deform.h"
-#include "BKE_cdderivedmesh.h"
-#include "BKE_displist.h"
-#include "BKE_global.h"
#include "BLI_math.h"
-#include "BLI_linklist.h"
#include "MEM_guardedalloc.h"
/* Math stuff for ray casting on mesh faces and for nearest surface */
@@ -219,7 +210,7 @@ static float nearest_point_in_tri_surface(const float *v0,const float *v1,const
}
else // Region 0
{
- // Minimum at interior lv
+ // Minimum at interior lv
float invDet;
if(fabs(Det) > FLT_EPSILON)
invDet = 1.0f / Det;
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 9ee4b66b194..7b6da4dd811 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -37,12 +37,9 @@
#include "BIF_gl.h"
#include "BKE_cdderivedmesh.h"
-#include "BKE_customdata.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
-#include "BKE_multires.h"
+#include "BKE_paint.h"
#include "BKE_utildefines.h"
#include "BKE_tessmesh.h"
@@ -52,18 +49,16 @@
#include "BLI_blenlib.h"
#include "BLI_edgehash.h"
#include "BLI_editVert.h"
+#include "BLI_math.h"
#include "BLI_pbvh.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_object_fluidsim.h"
#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
+#include "DNA_curve_types.h" /* for Curve */
#include "MEM_guardedalloc.h"
-#include "gpu_buffers.h"
+#include "GPU_buffers.h"
#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_material.h"
@@ -85,6 +80,7 @@ typedef struct {
/* Cached */
struct PBVH *pbvh;
+ int pbvh_draw;
/* Mesh connectivity */
struct ListBase *fmap;
struct IndexNode *fmap_mem;
@@ -197,22 +193,47 @@ static ListBase *cdDM_getFaceMap(Object *ob, DerivedMesh *dm)
Mesh *me= ob->data;
create_vert_face_map(&cddm->fmap, &cddm->fmap_mem, me->mface,
- me->totvert, me->totface);
+ me->totvert, me->totface);
}
return cddm->fmap;
}
+static int can_pbvh_draw(Object *ob, DerivedMesh *dm)
+{
+ CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
+ Mesh *me= (ob)? ob->data: NULL;
+
+ if(ob->sculpt->modifiers_active) return 0;
+
+ return (cddm->mvert == me->mvert) || ob->sculpt->kb;
+}
+
static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
{
CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
+ Mesh *me= (ob)? ob->data: NULL;
- if(!cddm->pbvh && ob->type == OB_MESH) {
- Mesh *me= ob->data;
+ if(!ob) {
+ cddm->pbvh= NULL;
+ return NULL;
+ }
+
+ if(!ob->sculpt)
+ return NULL;
+ if(ob->sculpt->pbvh) {
+ cddm->pbvh= ob->sculpt->pbvh;
+ cddm->pbvh_draw = can_pbvh_draw(ob, dm);
+ }
+ /* always build pbvh from original mesh, and only use it for drawing if
+ this derivedmesh is just original mesh. it's the multires subsurf dm
+ that this is actually for, to support a pbvh on a modified mesh */
+ if(!cddm->pbvh && ob->type == OB_MESH) {
cddm->pbvh = BLI_pbvh_new();
+ cddm->pbvh_draw = can_pbvh_draw(ob, dm);
BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
- me->totface, me->totvert);
+ me->totface, me->totvert);
}
return cddm->pbvh;
@@ -309,7 +330,7 @@ static void cdDM_drawUVEdges(DerivedMesh *dm)
}
}
-static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
+static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges)
{
CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
MVert *mvert = cddm->mvert;
@@ -320,7 +341,7 @@ static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
DEBUG_VBO( "Using legacy code. cdDM_drawEdges\n" );
glBegin(GL_LINES);
for(i = 0; i < dm->numEdgeData; i++, medge++) {
- if((medge->flag&ME_EDGEDRAW)
+ if((drawAllEdges || (medge->flag&ME_EDGEDRAW))
&& (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
glVertex3fv(mvert[medge->v1].co);
glVertex3fv(mvert[medge->v2].co);
@@ -336,7 +357,7 @@ static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
GPU_edge_setup(dm);
if( !GPU_buffer_legacy(dm) ) {
for(i = 0; i < dm->numEdgeData; i++, medge++) {
- if((medge->flag&ME_EDGEDRAW)
+ if((drawAllEdges || (medge->flag&ME_EDGEDRAW))
&& (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
draw = 1;
}
@@ -425,7 +446,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
glVertex3fv(mvert[index].co); \
}
- if(cddm->pbvh) {
+ if(cddm->pbvh && cddm->pbvh_draw) {
if(dm->numFaceData) {
float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL);
@@ -434,7 +455,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
return;
glShadeModel((mface->flag & ME_SMOOTH)? GL_SMOOTH: GL_FLAT);
- BLI_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors);
+ BLI_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors, (mface->flag & ME_SMOOTH));
glShadeModel(GL_FLAT);
}
@@ -736,7 +757,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
if( flag != lastFlag ) {
if( startFace < i ) {
if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */
- if (lastFlag==1 && mcol)
+ if (lastFlag==1 && col)
GPU_color_switch(1);
else
GPU_color_switch(0);
@@ -749,7 +770,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
}
if( startFace < dm->drawObject->nelements/3 ) {
if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */
- if (lastFlag==1 && mcol)
+ if (lastFlag==1 && col)
GPU_color_switch(1);
else
GPU_color_switch(0);
@@ -855,47 +876,41 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
}
}
else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
- int state = 1;
- int prevstate = 1;
int prevstart = 0;
GPU_vertex_setup(dm);
GPU_normal_setup(dm);
if( useColors && mc )
GPU_color_setup(dm);
if( !GPU_buffer_legacy(dm) ) {
+ int tottri = dm->drawObject->nelements/3;
glShadeModel(GL_SMOOTH);
- for( i = 0; i < dm->drawObject->nelements/3; i++ ) {
+
+ for( i = 0; i < tottri; i++ ) {
int actualFace = dm->drawObject->faceRemap[i];
int drawSmooth = (mf[actualFace].flag & ME_SMOOTH);
- int dontdraw = 0;
+ int draw = 1;
+
if(index) {
orig = index[actualFace];
if(setDrawOptions && orig == ORIGINDEX_NONE)
- dontdraw = 1;
+ draw = 0;
}
else
orig = actualFace;
- if( dontdraw ) {
- state = 0;
- }
- else {
- if(!setDrawOptions || setDrawOptions(userData, orig, &drawSmooth)) {
- state = 1;
- }
- else {
- state = 0;
- }
- }
- if( prevstate != state && prevstate == 1 ) {
- if( i-prevstart > 0 ) {
- glDrawArrays(GL_TRIANGLES,prevstart*3,(i-prevstart)*3);
- }
- prevstart = i;
+
+ if(draw && setDrawOptions && !setDrawOptions(userData, orig, &drawSmooth))
+ draw = 0;
+
+ /* Goal is to draw as long of a contiguous triangle
+ array as possible, so draw when we hit either an
+ invisible triangle or at the end of the array */
+ if(!draw || i == tottri - 1) {
+ if(prevstart != i)
+ /* Add one to the length (via `draw')
+ if we're drawing at the end of the array */
+ glDrawArrays(GL_TRIANGLES,prevstart*3, (i-prevstart+draw)*3);
+ prevstart = i + 1;
}
- prevstate = state;
- }
- if(state==1) {
- glDrawArrays(GL_TRIANGLES,prevstart*3,dm->drawObject->nelements-prevstart*3);
}
glShadeModel(GL_FLAT);
}
@@ -1291,10 +1306,10 @@ static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *us
}
static void cdDM_foreachMappedVert(
- DerivedMesh *dm,
- void (*func)(void *userData, int index, float *co,
- float *no_f, short *no_s),
- void *userData)
+ DerivedMesh *dm,
+ void (*func)(void *userData, int index, float *co,
+ float *no_f, short *no_s),
+ void *userData)
{
MVert *mv = CDDM_get_verts(dm);
int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
@@ -1311,10 +1326,10 @@ static void cdDM_foreachMappedVert(
}
static void cdDM_foreachMappedEdge(
- DerivedMesh *dm,
- void (*func)(void *userData, int index,
- float *v0co, float *v1co),
- void *userData)
+ DerivedMesh *dm,
+ void (*func)(void *userData, int index,
+ float *v0co, float *v1co),
+ void *userData)
{
CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
MVert *mv = cddm->mvert;
@@ -1333,17 +1348,16 @@ static void cdDM_foreachMappedEdge(
}
static void cdDM_foreachMappedFaceCenter(
- DerivedMesh *dm,
- void (*func)(void *userData, int index,
- float *cent, float *no),
- void *userData)
+ DerivedMesh *dm,
+ void (*func)(void *userData, int index,
+ float *cent, float *no),
+ void *userData)
{
CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
MVert *mv = cddm->mvert;
MPoly *mf = cddm->mpoly;
MLoop *ml = cddm->mloop;
int i, j, orig, *index;
- int maxf=0;
index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
mf = cddm->mpoly;
@@ -1403,7 +1417,6 @@ static void cdDM_recalcTesselation2(DerivedMesh *dm)
static void cdDM_free_internal(CDDerivedMesh *cddm)
{
- if(cddm->pbvh) BLI_pbvh_free(cddm->pbvh);
if(cddm->fmap) MEM_freeN(cddm->fmap);
if(cddm->fmap_mem) MEM_freeN(cddm->fmap_mem);
}
@@ -1532,11 +1545,11 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob)
alloctype= CD_REFERENCE;
CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
- mesh->totvert);
+ mesh->totvert);
CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
- mesh->totedge);
+ mesh->totedge);
CustomData_merge(&mesh->fdata, &dm->faceData, mask|CD_MASK_ORIGINDEX, alloctype,
- mesh->totface);
+ mesh->totface);
CustomData_merge(&mesh->ldata, &dm->loopData, mask, alloctype,
mesh->totloop);
CustomData_merge(&mesh->pdata, &dm->polyData, mask, alloctype,
@@ -1571,11 +1584,11 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
dm->deformedOnly = 1;
CustomData_merge(&em->vdata, &dm->vertData, CD_MASK_DERIVEDMESH,
- CD_CALLOC, dm->numVertData);
+ CD_CALLOC, dm->numVertData);
/* CustomData_merge(&em->edata, &dm->edgeData, CD_MASK_DERIVEDMESH,
- CD_CALLOC, dm->numEdgeData); */
+ CD_CALLOC, dm->numEdgeData); */
CustomData_merge(&em->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
- CD_CALLOC, dm->numFaceData);
+ CD_CALLOC, dm->numFaceData);
CustomData_merge(&em->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
CD_CALLOC, dm->numFaceData);
@@ -1596,7 +1609,7 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
index = dm->getVertDataArray(dm, CD_ORIGINDEX);
for(i = 0, eve = em->verts.first; i < dm->numVertData;
- i++, eve = eve->next, index++) {
+ i++, eve = eve->next, index++) {
MVert *mv = &mvert[i];
VECCOPY(mv->co, eve->co);
@@ -1616,7 +1629,7 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
for(i = 0, eed = em->edges.first; i < dm->numEdgeData;
- i++, eed = eed->next, index++) {
+ i++, eed = eed->next, index++) {
MEdge *med = &medge[i];
med->v1 = eed->v1->tmp.l;
@@ -1636,7 +1649,7 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
for(i = 0, efa = em->faces.first; i < dm->numFaceData;
- i++, efa = efa->next, index++) {
+ i++, efa = efa->next, index++) {
MFace *mf = &mface[i];
mf->v1 = efa->v1->tmp.l;
@@ -1655,10 +1668,45 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
return dm;
}
+DerivedMesh *CDDM_from_curve(Object *ob)
+{
+ return CDDM_from_curve_customDB(ob, &((Curve *)ob->data)->disp);
+}
+
+DerivedMesh *CDDM_from_curve_customDB(Object *ob, ListBase *dispbase)
+{
+ DerivedMesh *dm;
+ CDDerivedMesh *cddm;
+ MVert *allvert;
+ MEdge *alledge;
+ MFace *allface;
+ int totvert, totedge, totface;
+
+ if (nurbs_to_mdata_customdb(ob, dispbase, &allvert, &totvert, &alledge,
+ &totedge, &allface, &totface) != 0) {
+ /* Error initializing mdata. This often happens when curve is empty */
+ return CDDM_new(0, 0, 0, 0, 0);
+ }
+
+ dm = CDDM_new(totvert, totedge, totface, totface*4, totface);
+ dm->deformedOnly = 1;
+
+ cddm = (CDDerivedMesh*)dm;
+
+ memcpy(cddm->mvert, allvert, totvert*sizeof(MVert));
+ memcpy(cddm->medge, alledge, totedge*sizeof(MEdge));
+ memcpy(cddm->mface, allface, totface*sizeof(MFace));
+
+ MEM_freeN(allvert);
+ MEM_freeN(alledge);
+ MEM_freeN(allface);
+
+ return dm;
+}
static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata,
- int cdindex, BMLoop *l3[3],
- int numCol, int numTex)
+ int cdindex, BMLoop *l3[3],
+ int numCol, int numTex)
{
BMLoop *l;
BMFace *f = l3[0]->f;
@@ -2029,7 +2077,7 @@ DerivedMesh *CDDM_copy(DerivedMesh *source, int faces_from_tessfaces)
DerivedMesh *CDDM_from_template(DerivedMesh *source,
int numVerts, int numEdges, int numFaces,
- int numLoops, int numPolys)
+ int numLoops, int numPolys)
{
CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
DerivedMesh *dm = &cddm->dm;
@@ -2107,6 +2155,9 @@ void CDDM_calc_normals(DerivedMesh *dm)
if (CustomData_has_layer(&dm->faceData, CD_NORMAL))
CustomData_free_layer(&dm->faceData, CD_NORMAL, dm->numFaceData, 0);
+ temp_nors = MEM_callocN(numVerts * sizeof(*temp_nors),
+ "CDDM_calc_normals temp_nors");
+
/*recalc tesselation to ensure we have valid origindex values
for mface->mpoly lookups.*/
cdDM_recalcTesselation2(dm);
@@ -2202,7 +2253,7 @@ void CDDM_calc_edges(DerivedMesh *dm)
med = CustomData_get_layer(&edgeData, CD_MEDGE);
index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
for(i = 0; !BLI_edgehashIterator_isDone(ehi);
- BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
+ BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
med->flag = ME_EDGEDRAW|ME_EDGERENDER;
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index bb3c8476a2a..44b17265807 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -27,23 +27,13 @@
#include "MEM_guardedalloc.h"
-#include "BKE_cloth.h"
-
-#include "DNA_cloth_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_object_force.h"
-#include "DNA_scene_types.h"
-#include "DNA_particle_types.h"
-
-#include "BKE_deform.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_cdderivedmesh.h"
+#include "BKE_cloth.h"
#include "BKE_effect.h"
#include "BKE_global.h"
-#include "BKE_object.h"
#include "BKE_modifier.h"
+#include "BKE_pointcache.h"
#include "BKE_utildefines.h"
-#include "BKE_particle.h"
#include "BKE_pointcache.h"
@@ -87,7 +77,7 @@ double tval()
static CM_SOLVER_DEF solvers [] =
{
{ "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free },
- // { "Implicit C++", CM_IMPLICITCPP, implicitcpp_init, implicitcpp_solver, implicitcpp_free },
+ // { "Implicit C++", CM_IMPLICITCPP, implicitcpp_init, implicitcpp_solver, implicitcpp_free },
};
/* ********** cloth engine ******* */
@@ -368,14 +358,12 @@ static int do_init_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
/* initialize simulation data if it didn't exist already */
if(clmd->clothObject == NULL) {
if(!cloth_from_object(ob, clmd, result, framenr, 1)) {
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
+ BKE_ptcache_invalidate(cache);
return 0;
}
if(clmd->clothObject == NULL) {
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
+ BKE_ptcache_invalidate(cache);
return 0;
}
@@ -448,20 +436,17 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
clmd->sim_parms->timescale= timescale;
if(!result) {
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
- cache->last_exact= 0;
+ BKE_ptcache_invalidate(cache);
return dm;
}
if(clmd->sim_parms->reset || (framenr == (startframe - clmd->sim_parms->preroll)))
{
clmd->sim_parms->reset = 0;
- cache->flag |= PTCACHE_REDO_NEEDED;
+ cache->flag |= PTCACHE_OUTDATED;
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
- cache->simframe= 0;
+ BKE_ptcache_validate(cache, 0);
cache->last_exact= 0;
- cache->flag |= PTCACHE_SIMULATION_VALID;
cache->flag &= ~PTCACHE_REDO_NEEDED;
return result;
}
@@ -472,9 +457,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
* happen because of object changes! */
if(clmd->clothObject) {
if(result->getNumVerts(result) != clmd->clothObject->numverts) {
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
- cache->last_exact= 0;
+ BKE_ptcache_invalidate(cache);
return result;
}
}
@@ -484,9 +467,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
/* handle continuous simulation with the play button */
if(BKE_ptcache_get_continue_physics() || ((clmd->sim_parms->preroll > 0) && (framenr > startframe - clmd->sim_parms->preroll) && (framenr < startframe))) {
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
- cache->last_exact= 0;
+ BKE_ptcache_invalidate(cache);
/* do simulation */
if(!do_init_cloth(ob, clmd, result, framenr))
@@ -500,9 +481,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
/* simulation is only active during a specific period */
if(framenr < startframe) {
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
- cache->last_exact= 0;
+ BKE_ptcache_invalidate(cache);
return result;
}
else if(framenr > endframe) {
@@ -521,8 +500,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
if((framenr == startframe) && (clmd->sim_parms->preroll == 0)) {
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
do_init_cloth(ob, clmd, result, framenr);
- cache->simframe= framenr;
- cache->flag |= PTCACHE_SIMULATION_VALID;
+ BKE_ptcache_validate(cache, framenr);
cache->flag &= ~PTCACHE_REDO_NEEDED;
return result;
}
@@ -534,8 +512,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
implicit_set_positions(clmd);
cloth_to_object (ob, clmd, result);
- cache->simframe= framenr;
- cache->flag |= PTCACHE_SIMULATION_VALID;
+ BKE_ptcache_validate(cache, framenr);
if(cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED)
BKE_ptcache_write_cache(&pid, framenr);
@@ -544,13 +521,10 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
}
else if(cache_result==PTCACHE_READ_OLD) {
implicit_set_positions(clmd);
- cache->flag |= PTCACHE_SIMULATION_VALID;
}
else if( /*ob->id.lib ||*/ (cache->flag & PTCACHE_BAKED)) { /* 2.4x disabled lib, but this can be used in some cases, testing further - campbell */
/* if baked and nothing in cache, do nothing */
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
- cache->last_exact= 0;
+ BKE_ptcache_invalidate(cache);
return result;
}
@@ -561,13 +535,10 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
clmd->sim_parms->timescale *= framenr - cache->simframe;
/* do simulation */
- cache->flag |= PTCACHE_SIMULATION_VALID;
- cache->simframe= framenr;
+ BKE_ptcache_validate(cache, framenr);
if(!do_step_cloth(ob, clmd, result, framenr)) {
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
- cache->last_exact= 0;
+ BKE_ptcache_invalidate(cache);
}
else
BKE_ptcache_write_cache(&pid, framenr);
@@ -752,6 +723,15 @@ static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh *
}
+int cloth_uses_vgroup(ClothModifierData *clmd)
+{
+ return (((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) ||
+ (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) &&
+ ((clmd->sim_parms->vgroup_mass>0) ||
+ (clmd->sim_parms->vgroup_struct>0)||
+ (clmd->sim_parms->vgroup_bend>0)));
+}
+
/**
* cloth_apply_vgroup - applies a vertex group as specified by type
*
@@ -775,11 +755,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm )
verts = clothObj->verts;
- if (((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) ||
- (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) &&
- ((clmd->sim_parms->vgroup_mass>0) ||
- (clmd->sim_parms->vgroup_struct>0)||
- (clmd->sim_parms->vgroup_bend>0)))
+ if (cloth_uses_vgroup(clmd))
{
for ( i = 0; i < numverts; i++, verts++ )
{
@@ -801,7 +777,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm )
verts->goal = ( float ) pow ( verts->goal , 4.0f );
if ( verts->goal >=SOFTGOALSNAP )
{
- verts->flags |= CLOTH_VERT_FLAG_PINNED;
+ verts->flags |= CLOTH_VERT_FLAG_PINNED;
}
}
@@ -836,6 +812,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
int i = 0;
MVert *mvert = NULL;
ClothVertex *verts = NULL;
+ float (*shapekey_rest)[3]= NULL;
float tnull[3] = {0,0,0};
Cloth *cloth = NULL;
float maxdist = 0;
@@ -873,7 +850,11 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
clmd->clothObject->springs = NULL;
clmd->clothObject->numsprings = -1;
+ if( clmd->sim_parms->shapekey_rest )
+ shapekey_rest = dm->getVertDataArray ( dm, CD_CLOTH_ORCO );
+
mvert = dm->getVertArray ( dm );
+
verts = clmd->clothObject->verts;
// set initial values
@@ -881,8 +862,16 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
{
if(first)
{
- VECCOPY ( verts->x, mvert[i].co );
+ copy_v3_v3( verts->x, mvert[i].co );
+
mul_m4_v3( ob->obmat, verts->x );
+
+ if( shapekey_rest ) {
+ verts->xrest= shapekey_rest[i];
+ mul_m4_v3( ob->obmat, verts->xrest );
+ }
+ else
+ verts->xrest = verts->x;
}
/* no GUI interface yet */
@@ -1101,7 +1090,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
{
spring->ij = MIN2(medge[i].v1, medge[i].v2);
spring->kl = MAX2(medge[i].v2, medge[i].v1);
- VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
+ VECSUB ( temp, cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest );
spring->restlen = sqrt ( INPR ( temp, temp ) );
clmd->sim_parms->avg_spring_len += spring->restlen;
cloth->verts[spring->ij].avg_spring_len += spring->restlen;
@@ -1147,7 +1136,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
spring->ij = MIN2(mface[i].v1, mface[i].v3);
spring->kl = MAX2(mface[i].v3, mface[i].v1);
- VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
+ VECSUB ( temp, cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest );
spring->restlen = sqrt ( INPR ( temp, temp ) );
spring->type = CLOTH_SPRING_TYPE_SHEAR;
spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0;
@@ -1170,7 +1159,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
spring->ij = MIN2(mface[i].v2, mface[i].v4);
spring->kl = MAX2(mface[i].v4, mface[i].v2);
- VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
+ VECSUB ( temp, cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest );
spring->restlen = sqrt ( INPR ( temp, temp ) );
spring->type = CLOTH_SPRING_TYPE_SHEAR;
spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0;
@@ -1212,7 +1201,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
spring->ij = MIN2(tspring2->ij, index2);
spring->kl = MAX2(tspring2->ij, index2);
- VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
+ VECSUB ( temp, cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest );
spring->restlen = sqrt ( INPR ( temp, temp ) );
spring->type = CLOTH_SPRING_TYPE_BENDING;
spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0;
@@ -1252,7 +1241,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
spring->ij = tspring2->ij;
spring->kl = tspring->kl;
- VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
+ VECSUB ( temp, cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest );
spring->restlen = sqrt ( INPR ( temp, temp ) );
spring->type = CLOTH_SPRING_TYPE_BENDING;
spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0;
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index b024ba5f4e1..9b49ac9c6ff 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -40,6 +40,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
+#include "BKE_scene.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_modifier.h"
@@ -59,7 +60,7 @@ Collision modifier code start
/* step is limited from 0 (frame start position) to 1 (frame end position) */
void collision_move_object ( CollisionModifierData *collmd, float step, float prevstep )
{
- float tv[3] = {0,0,0};
+ float tv[3] = {0, 0, 0};
unsigned int i = 0;
for ( i = 0; i < collmd->numverts; i++ )
@@ -69,6 +70,7 @@ void collision_move_object ( CollisionModifierData *collmd, float step, float pr
VECADDS ( collmd->current_xnew[i].co, collmd->x[i].co, tv, step );
VECSUB ( collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co );
}
+
bvhtree_update_from_mvert ( collmd->bvhtree, collmd->mfaces, collmd->numfaces, collmd->current_x, collmd->current_xnew, collmd->numverts, 1 );
}
@@ -527,7 +529,7 @@ int cloth_collision_response_static ( ClothModifierData *clmd, CollisionModifier
float magtangent = 0, repulse = 0, d = 0;
double impulse = 0.0;
float vrel_t_pre[3];
- float temp[3];
+ float temp[3], spf;
// calculate tangential velocity
VECCOPY ( temp, collpair->normal );
@@ -565,10 +567,12 @@ int cloth_collision_response_static ( ClothModifierData *clmd, CollisionModifier
// Apply repulse impulse if distance too short
// I_r = -min(dt*kd, m(0,1d/dt - v_n))
+ spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
+
d = clmd->coll_parms->epsilon*8.0/9.0 + epsilon2*8.0/9.0 - collpair->distance;
- if ( ( magrelVel < 0.1*d*clmd->sim_parms->stepsPerFrame ) && ( d > ALMOST_ZERO ) )
+ if ( ( magrelVel < 0.1*d*spf ) && ( d > ALMOST_ZERO ) )
{
- repulse = MIN2 ( d*1.0/clmd->sim_parms->stepsPerFrame, 0.1*d*clmd->sim_parms->stepsPerFrame - magrelVel );
+ repulse = MIN2 ( d*1.0/spf, 0.1*d*spf - magrelVel );
// stay on the safe side and clamp repulse
if ( impulse > ALMOST_ZERO )
@@ -1299,188 +1303,130 @@ static int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierDa
}
#endif
-
-// return all collision objects in scene
-// collision object will exclude self
-Object **get_collisionobjects(Scene *scene, Object *self, int *numcollobj)
+static void add_collision_object(Object ***objs, int *numobj, int *maxobj, Object *ob, Object *self, int level)
{
- Base *base=NULL;
- Object **objs = NULL;
- Object *coll_ob = NULL;
- CollisionModifierData *collmd = NULL;
- int numobj = 0, maxobj = 100;
+ CollisionModifierData *cmd= NULL;
+
+ if(ob == self)
+ return;
+
+ /* only get objects with collision modifier */
+ if(ob->pd && ob->pd->deflect)
+ cmd= (CollisionModifierData *)modifiers_findByType(ob, eModifierType_Collision);
- objs = MEM_callocN(sizeof(Object *)*maxobj, "CollisionObjectsArray");
- // check all collision objects
- for ( base = scene->base.first; base; base = base->next )
- {
- /*Only proceed for mesh object in same layer */
- if(!(base->object->type==OB_MESH && (base->lay & self->lay)))
- continue;
-
- coll_ob = base->object;
-
- if(coll_ob == self)
- continue;
-
- if(coll_ob->pd && coll_ob->pd->deflect)
- {
- collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
+ if(cmd) {
+ /* extend array */
+ if(*numobj >= *maxobj) {
+ *maxobj *= 2;
+ *objs= MEM_reallocN(*objs, sizeof(Object*)*(*maxobj));
}
- else
- collmd = NULL;
- if ( collmd )
- {
- if(numobj >= maxobj)
- {
- // realloc
- int oldmax = maxobj;
- Object **tmp;
- maxobj *= 2;
- tmp = MEM_callocN(sizeof(Object *)*maxobj, "CollisionObjectsArray");
- memcpy(tmp, objs, sizeof(Object *)*oldmax);
- MEM_freeN(objs);
- objs = tmp;
-
- }
-
- objs[numobj] = coll_ob;
- numobj++;
- }
- else
- {
- if ( coll_ob->dup_group )
- {
- GroupObject *go;
- Group *group = coll_ob->dup_group;
+ (*objs)[*numobj] = ob;
+ (*numobj)++;
+ }
- for ( go= group->gobject.first; go; go= go->next )
- {
- coll_ob = go->ob;
- collmd = NULL;
-
- if(coll_ob == self)
- continue;
-
- if(coll_ob->pd && coll_ob->pd->deflect)
- {
- collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
- }
- else
- collmd = NULL;
+ /* objects in dupli groups, one level only for now */
+ if(ob->dup_group && level == 0) {
+ GroupObject *go;
+ Group *group= ob->dup_group;
- if ( !collmd )
- continue;
-
- if( !collmd->bvhtree)
- continue;
+ /* add objects */
+ for(go= group->gobject.first; go; go= go->next)
+ add_collision_object(objs, numobj, maxobj, go->ob, self, level+1);
+ }
+}
- if(numobj >= maxobj)
- {
- // realloc
- int oldmax = maxobj;
- Object **tmp;
- maxobj *= 2;
- tmp = MEM_callocN(sizeof(Object *)*maxobj, "CollisionObjectsArray");
- memcpy(tmp, objs, sizeof(Object *)*oldmax);
- MEM_freeN(objs);
- objs = tmp;
- }
-
- objs[numobj] = coll_ob;
- numobj++;
- }
- }
- }
+// return all collision objects in scene
+// collision object will exclude self
+Object **get_collisionobjects(Scene *scene, Object *self, Group *group, int *numcollobj)
+{
+ Base *base;
+ Object **objs;
+ GroupObject *go;
+ int numobj= 0, maxobj= 100;
+
+ objs= MEM_callocN(sizeof(Object *)*maxobj, "CollisionObjectsArray");
+
+ /* gather all collision objects */
+ if(group) {
+ /* use specified group */
+ for(go= group->gobject.first; go; go= go->next)
+ add_collision_object(&objs, &numobj, &maxobj, go->ob, self, 0);
}
- *numcollobj = numobj;
+ else {
+ Scene *sce; /* for SETLOOPER macro */
+ /* add objects in same layer in scene */
+ for(SETLOOPER(scene, base)) {
+ if(base->lay & self->lay)
+ add_collision_object(&objs, &numobj, &maxobj, base->object, self, 0);
+
+ }
+ }
+
+ *numcollobj= numobj;
+
return objs;
}
-ListBase *get_collider_cache(Scene *scene, Object *self)
+static void add_collider_cache_object(ListBase **objs, Object *ob, Object *self, int level)
{
- Base *base=NULL;
- ListBase *objs = NULL;
- Object *coll_ob = NULL;
- CollisionModifierData *collmd = NULL;
+ CollisionModifierData *cmd= NULL;
ColliderCache *col;
+
+ if(ob == self)
+ return;
+
+ if(ob->pd && ob->pd->deflect)
+ cmd =(CollisionModifierData *)modifiers_findByType(ob, eModifierType_Collision);
- // check all collision objects
- for ( base = scene->base.first; base; base = base->next )
- {
- /*Only proceed for mesh object in same layer */
- if(base->object->type!=OB_MESH)
- continue;
+ if(cmd && cmd->bvhtree) {
+ if(*objs == NULL)
+ *objs = MEM_callocN(sizeof(ListBase), "ColliderCache array");
+
+ col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
+ col->ob = ob;
+ col->collmd = cmd;
+ /* make sure collider is properly set up */
+ collision_move_object(cmd, 1.0, 0.0);
+ BLI_addtail(*objs, col);
+ }
- if(self && (base->lay & self->lay)==0)
- continue;
+ /* objects in dupli groups, one level only for now */
+ if(ob->dup_group && level == 0) {
+ GroupObject *go;
+ Group *group= ob->dup_group;
-
- coll_ob = base->object;
-
- if(coll_ob == self)
- continue;
-
- if(coll_ob->pd && coll_ob->pd->deflect)
- {
- collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
- }
- else
- collmd = NULL;
-
- if ( collmd )
- {
- if(objs == NULL)
- objs = MEM_callocN(sizeof(ListBase), "ColliderCache array");
-
- col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
- col->ob = coll_ob;
- col->collmd = collmd;
- /* make sure collider is properly set up */
- collision_move_object(collmd, 1.0, 0.0);
- BLI_addtail(objs, col);
- }
- else if ( coll_ob->dup_group )
- {
- GroupObject *go;
- Group *group = coll_ob->dup_group;
+ /* add objects */
+ for(go= group->gobject.first; go; go= go->next)
+ add_collider_cache_object(objs, go->ob, self, level+1);
+ }
+}
- for ( go= group->gobject.first; go; go= go->next )
- {
- coll_ob = go->ob;
- collmd = NULL;
-
- if(coll_ob == self)
- continue;
-
- if(coll_ob->pd && coll_ob->pd->deflect)
- {
- collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
- }
- else
- collmd = NULL;
+ListBase *get_collider_cache(Scene *scene, Object *self, Group *group)
+{
+ GroupObject *go;
+ ListBase *objs= NULL;
+
+ /* add object in same layer in scene */
+ if(group) {
+ for(go= group->gobject.first; go; go= go->next)
+ add_collider_cache_object(&objs, go->ob, self, 0);
+ }
+ else {
+ Scene *sce; /* for SETLOOPER macro */
+ Base *base;
- if ( !collmd )
- continue;
-
- if( !collmd->bvhtree)
- continue;
-
- if(objs == NULL)
- objs = MEM_callocN(sizeof(ListBase), "ColliderCache array");
-
- col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
- col->ob = coll_ob;
- col->collmd = collmd;
- /* make sure collider is properly set up */
- collision_move_object(collmd, 1.0, 0.0);
- BLI_addtail(objs, col);
- }
- }
+ /* add objects in same layer in scene */
+ for(SETLOOPER(scene, base)) {
+ if(!self || (base->lay & self->lay))
+ add_collider_cache_object(&objs, base->object, self, 0);
+
+ }
}
+
return objs;
}
+
void free_collider_cache(ListBase **colliders)
{
if(*colliders) {
@@ -1489,6 +1435,7 @@ void free_collider_cache(ListBase **colliders)
*colliders = NULL;
}
}
+
static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap)
{
int i;
@@ -1574,7 +1521,7 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl
bvhtree_update_from_cloth ( clmd, 1 ); // 0 means STATIC, 1 means MOVING (see later in this function)
bvhselftree_update_from_cloth ( clmd, 0 ); // 0 means STATIC, 1 means MOVING (see later in this function)
- collobjs = get_collisionobjects(clmd->scene, ob, &numcollobj);
+ collobjs = get_collisionobjects(clmd->scene, ob, clmd->coll_parms->group, &numcollobj);
if(!collobjs)
return 0;
@@ -1606,20 +1553,15 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl
overlap = BLI_bvhtree_overlap ( cloth_bvh, collmd->bvhtree, &result );
// go to next object if no overlap is there
- if(!result || !overlap)
- {
- if ( overlap )
- MEM_freeN ( overlap );
- continue;
- }
-
- /* check if collisions really happen (costly near check) */
- cloth_bvh_objcollisions_nearcheck ( clmd, collmd, &collisions[i], &collisions_index[i], result, overlap);
-
- // resolve nearby collisions
- ret += cloth_bvh_objcollisions_resolve ( clmd, collmd, collisions[i], collisions_index[i]);
- ret2 += ret;
+ if( result && overlap ) {
+ /* check if collisions really happen (costly near check) */
+ cloth_bvh_objcollisions_nearcheck ( clmd, collmd, &collisions[i], &collisions_index[i], result, overlap);
+ // resolve nearby collisions
+ ret += cloth_bvh_objcollisions_resolve ( clmd, collmd, collisions[i], collisions_index[i]);
+ ret2 += ret;
+ }
+
if ( overlap )
MEM_freeN ( overlap );
}
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 71b497660e9..a07c18f42f3 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -40,20 +40,14 @@
#include "DNA_color_types.h"
#include "DNA_curve_types.h"
-#include "DNA_image_types.h"
-#include "DNA_texture_types.h"
#include "BKE_colortools.h"
#include "BKE_curve.h"
-#include "BKE_global.h"
#include "BKE_ipo.h"
-#include "BKE_image.h"
-#include "BKE_main.h"
#include "BKE_utildefines.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_threads.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -132,6 +126,9 @@ CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, floa
cumap->cm[a].curve[1].x= maxx;
cumap->cm[a].curve[1].y= maxy;
}
+
+ cumap->changed_timestamp = 0;
+
return cumap;
}
@@ -239,16 +236,19 @@ void curvemap_insert(CurveMap *cuma, float x, float y)
cuma->curve= cmp;
}
-void curvemap_reset(CurveMap *cuma, rctf *clipr, CurveMappingPreset preset)
+void curvemap_reset(CurveMap *cuma, rctf *clipr, int preset)
{
if(cuma->curve)
MEM_freeN(cuma->curve);
switch(preset) {
case CURVE_PRESET_LINE: cuma->totpoint= 2; break;
- case CURVE_PRESET_SHARP: cuma->totpoint= 3; break;
+ case CURVE_PRESET_SHARP: cuma->totpoint= 4; break;
case CURVE_PRESET_SMOOTH: cuma->totpoint= 4; break;
case CURVE_PRESET_MAX: cuma->totpoint= 2; break;
+ case CURVE_PRESET_MID9: cuma->totpoint= 9; break;
+ case CURVE_PRESET_ROUND: cuma->totpoint= 4; break;
+ case CURVE_PRESET_ROOT: cuma->totpoint= 4; break;
}
cuma->curve= MEM_callocN(cuma->totpoint*sizeof(CurveMapPoint), "curve points");
@@ -256,27 +256,29 @@ void curvemap_reset(CurveMap *cuma, rctf *clipr, CurveMappingPreset preset)
switch(preset) {
case CURVE_PRESET_LINE:
cuma->curve[0].x= clipr->xmin;
- cuma->curve[0].y= clipr->ymin;
+ cuma->curve[0].y= clipr->ymax;
cuma->curve[0].flag= 0;
cuma->curve[1].x= clipr->xmax;
- cuma->curve[1].y= clipr->ymax;
+ cuma->curve[1].y= clipr->ymin;
cuma->curve[1].flag= 0;
break;
case CURVE_PRESET_SHARP:
cuma->curve[0].x= 0;
cuma->curve[0].y= 1;
- cuma->curve[1].x= 0.33;
- cuma->curve[1].y= 0.33;
- cuma->curve[2].x= 1;
- cuma->curve[2].y= 0;
+ cuma->curve[1].x= 0.25;
+ cuma->curve[1].y= 0.50;
+ cuma->curve[2].x= 0.75;
+ cuma->curve[2].y= 0.04;
+ cuma->curve[3].x= 1;
+ cuma->curve[3].y= 0;
break;
case CURVE_PRESET_SMOOTH:
cuma->curve[0].x= 0;
cuma->curve[0].y= 1;
cuma->curve[1].x= 0.25;
- cuma->curve[1].y= 0.92;
+ cuma->curve[1].y= 0.94;
cuma->curve[2].x= 0.75;
- cuma->curve[2].y= 0.08;
+ cuma->curve[2].y= 0.06;
cuma->curve[3].x= 1;
cuma->curve[3].y= 0;
break;
@@ -286,8 +288,38 @@ void curvemap_reset(CurveMap *cuma, rctf *clipr, CurveMappingPreset preset)
cuma->curve[1].x= 1;
cuma->curve[1].y= 1;
break;
+ case CURVE_PRESET_MID9:
+ {
+ int i;
+ for (i=0; i < cuma->totpoint; i++)
+ {
+ cuma->curve[i].x= i / ((float)cuma->totpoint-1);
+ cuma->curve[i].y= 0.5;
+ }
+ }
+ break;
+ case CURVE_PRESET_ROUND:
+ cuma->curve[0].x= 0;
+ cuma->curve[0].y= 1;
+ cuma->curve[1].x= 0.5;
+ cuma->curve[1].y= 0.90;
+ cuma->curve[2].x= 0.86;
+ cuma->curve[2].y= 0.5;
+ cuma->curve[3].x= 1;
+ cuma->curve[3].y= 0;
+ break;
+ case CURVE_PRESET_ROOT:
+ cuma->curve[0].x= 0;
+ cuma->curve[0].y= 1;
+ cuma->curve[1].x= 0.25;
+ cuma->curve[1].y= 0.95;
+ cuma->curve[2].x= 0.75;
+ cuma->curve[2].y= 0.44;
+ cuma->curve[3].x= 1;
+ cuma->curve[3].y= 0;
+ break;
}
-
+
if(cuma->table) {
MEM_freeN(cuma->table);
cuma->table= NULL;
@@ -463,7 +495,7 @@ static void curvemap_make_table(CurveMap *cuma, rctf *clipr)
if(vec[0] < bezt[0].vec[1][0])
vec[0]= bezt[0].vec[1][0];
- sub_v3_v3v3(vec, vec, bezt[0].vec[1]);
+ sub_v3_v3(vec, bezt[0].vec[1]);
nlen= len_v3(vec);
if(nlen>FLT_EPSILON) {
mul_v3_fl(vec, hlen/nlen);
@@ -480,7 +512,7 @@ static void curvemap_make_table(CurveMap *cuma, rctf *clipr)
if(vec[0] > bezt[a].vec[1][0])
vec[0]= bezt[a].vec[1][0];
- sub_v3_v3v3(vec, vec, bezt[a].vec[1]);
+ sub_v3_v3(vec, bezt[a].vec[1]);
nlen= len_v3(vec);
if(nlen>FLT_EPSILON) {
mul_v3_fl(vec, hlen/nlen);
@@ -615,7 +647,9 @@ void curvemapping_changed(CurveMapping *cumap, int rem_doubles)
float thresh= 0.01f*(clipr->xmax - clipr->xmin);
float dx= 0.0f, dy= 0.0f;
int a;
-
+
+ cumap->changed_timestamp++;
+
/* clamp with clip */
if(cumap->flag & CUMA_DO_CLIP) {
for(a=0; a<cuma->totpoint; a++) {
@@ -697,7 +731,7 @@ float curvemapping_evaluateF(CurveMapping *cumap, int cur, float value)
if(cuma->table==NULL) {
curvemap_make_table(cuma, &cumap->clipr);
if(cuma->table==NULL)
- return value;
+ return 1.0f-value;
}
return curvemap_evaluateF(cuma, value);
}
@@ -750,10 +784,10 @@ void colorcorrection_do_ibuf(ImBuf *ibuf, const char *profile)
cmsErrorAction(LCMS_ERROR_SHOW);
hTransform = cmsCreateProofingTransform(imageProfile, TYPE_RGBA_8, imageProfile, TYPE_RGBA_8,
- proofingProfile,
- INTENT_ABSOLUTE_COLORIMETRIC,
- INTENT_ABSOLUTE_COLORIMETRIC,
- cmsFLAGS_SOFTPROOFING);
+ proofingProfile,
+ INTENT_ABSOLUTE_COLORIMETRIC,
+ INTENT_ABSOLUTE_COLORIMETRIC,
+ cmsFLAGS_SOFTPROOFING);
cmsDoTransform(hTransform, ibuf->rect, ibuf->crect, ibuf->x * ibuf->y);
@@ -881,6 +915,8 @@ void curvemapping_table_RGBA(CurveMapping *cumap, float **array, int *size)
/* ***************** Histogram **************** */
+#define INV_255 (1.f/255.f)
+
DO_INLINE int get_bin_float(float f)
{
int bin= (int)(f*255);
@@ -893,59 +929,176 @@ DO_INLINE int get_bin_float(float f)
return bin;
}
+DO_INLINE void save_sample_line(Scopes *scopes, const int idx, const float fx, float *rgb, float *ycc)
+{
+ float yuv[3];
+
+ /* vectorscope*/
+ rgb_to_yuv(rgb[0], rgb[1], rgb[2], &yuv[0], &yuv[1], &yuv[2]);
+ scopes->vecscope[idx + 0] = yuv[1];
+ scopes->vecscope[idx + 1] = yuv[2];
+
+ /* waveform */
+ switch (scopes->wavefrm_mode) {
+ case SCOPES_WAVEFRM_RGB:
+ scopes->waveform_1[idx + 0] = fx;
+ scopes->waveform_1[idx + 1] = rgb[0];
+ scopes->waveform_2[idx + 0] = fx;
+ scopes->waveform_2[idx + 1] = rgb[1];
+ scopes->waveform_3[idx + 0] = fx;
+ scopes->waveform_3[idx + 1] = rgb[2];
+ break;
+ case SCOPES_WAVEFRM_LUMA:
+ scopes->waveform_1[idx + 0] = fx;
+ scopes->waveform_1[idx + 1] = ycc[0];
+ break;
+ case SCOPES_WAVEFRM_YCC_JPEG:
+ case SCOPES_WAVEFRM_YCC_709:
+ case SCOPES_WAVEFRM_YCC_601:
+ scopes->waveform_1[idx + 0] = fx;
+ scopes->waveform_1[idx + 1] = ycc[0];
+ scopes->waveform_2[idx + 0] = fx;
+ scopes->waveform_2[idx + 1] = ycc[1];
+ scopes->waveform_3[idx + 0] = fx;
+ scopes->waveform_3[idx + 1] = ycc[2];
+ break;
+ }
+}
-void histogram_update(Histogram *hist, ImBuf *ibuf)
+void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management)
{
- int x, y, n;
- double div;
- float *rf;
- unsigned char *rc;
- unsigned int *bin_r, *bin_g, *bin_b;
-
- if (hist->ok == 1 ) return;
-
- if (hist->xmax == 0.f) hist->xmax = 1.f;
- if (hist->ymax == 0.f) hist->ymax = 1.f;
-
+ int x, y, c, n, nl;
+ double div, divl;
+ float *rf=NULL;
+ unsigned char *rc=NULL;
+ unsigned int *bin_r, *bin_g, *bin_b, *bin_lum;
+ int savedlines, saveline;
+ float rgb[3], ycc[3], luma;
+ int ycc_mode=-1;
+
+ if (scopes->ok == 1 ) return;
+
+ if (scopes->hist.ymax == 0.f) scopes->hist.ymax = 1.f;
+
/* hmmmm */
if (!(ELEM(ibuf->channels, 3, 4))) return;
-
- hist->channels = 3;
-
+ scopes->hist.channels = 3;
+ scopes->hist.x_resolution = 256;
+
+ switch (scopes->wavefrm_mode) {
+ case SCOPES_WAVEFRM_RGB:
+ ycc_mode = -1;
+ break;
+ case SCOPES_WAVEFRM_LUMA:
+ case SCOPES_WAVEFRM_YCC_JPEG:
+ ycc_mode = BLI_YCC_JFIF_0_255;
+ break;
+ case SCOPES_WAVEFRM_YCC_601:
+ ycc_mode = BLI_YCC_ITU_BT601;
+ break;
+ case SCOPES_WAVEFRM_YCC_709:
+ ycc_mode = BLI_YCC_ITU_BT709;
+ break;
+ }
+
+ /* temp table to count pix value for histo */
bin_r = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins");
bin_g = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins");
bin_b = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins");
+ bin_lum = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins");
+
+ /* convert to number of lines with logarithmic scale */
+ scopes->sample_lines = (scopes->accuracy*0.01) * (scopes->accuracy*0.01) * ibuf->y;
- if (ibuf->rect_float) {
- hist->x_resolution = 256;
-
- /* divide into bins */
- rf = ibuf->rect_float;
- for (y = 0; y < ibuf->y; y++) {
- for (x = 0; x < ibuf->x; x++) {
- bin_r[ get_bin_float(rf[0]) ] += 1;
- bin_g[ get_bin_float(rf[1]) ] += 1;
- bin_b[ get_bin_float(rf[2]) ] += 1;
- rf+= ibuf->channels;
- }
- }
+ if (scopes->sample_full)
+ scopes->sample_lines = ibuf->y;
+
+ /* scan the image */
+ savedlines=0;
+ for (c=0; c<3; c++) {
+ scopes->minmax[c][0]=25500.0f;
+ scopes->minmax[c][1]=-25500.0f;
}
- else if (ibuf->rect) {
- hist->x_resolution = 256;
-
+
+ scopes->waveform_tot = ibuf->x*scopes->sample_lines;
+
+ if (scopes->waveform_1)
+ MEM_freeN(scopes->waveform_1);
+ if (scopes->waveform_2)
+ MEM_freeN(scopes->waveform_2);
+ if (scopes->waveform_3)
+ MEM_freeN(scopes->waveform_3);
+ if (scopes->vecscope)
+ MEM_freeN(scopes->vecscope);
+
+ scopes->waveform_1= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 1");
+ scopes->waveform_2= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 2");
+ scopes->waveform_3= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 3");
+ scopes->vecscope= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "vectorscope point channel");
+
+ if (ibuf->rect_float)
+ rf = ibuf->rect_float;
+ else if (ibuf->rect)
rc = (unsigned char *)ibuf->rect;
- for (y = 0; y < ibuf->y; y++) {
- for (x = 0; x < ibuf->x; x++) {
- bin_r[ rc[0] ] += 1;
- bin_g[ rc[1] ] += 1;
- bin_b[ rc[2] ] += 1;
- rc += ibuf->channels;
+
+ for (y = 0; y < ibuf->y; y++) {
+ if (savedlines<scopes->sample_lines && y>=((savedlines)*ibuf->y)/(scopes->sample_lines+1)) {
+ saveline=1;
+ } else saveline=0;
+ for (x = 0; x < ibuf->x; x++) {
+
+ if (ibuf->rect_float) {
+ if (use_color_management)
+ linearrgb_to_srgb_v3_v3(rgb, rf);
+ else
+ copy_v3_v3(rgb, rf);
+ }
+ else if (ibuf->rect) {
+ for (c=0; c<3; c++)
+ rgb[c] = rc[c] * INV_255;
+ }
+
+ /* we still need luma for histogram */
+ luma = 0.299*rgb[0] + 0.587*rgb[1] + 0.114 * rgb[2];
+
+ /* check for min max */
+ if(ycc_mode == -1 ) {
+ for (c=0; c<3; c++) {
+ if (rgb[c] < scopes->minmax[c][0]) scopes->minmax[c][0] = rgb[c];
+ if (rgb[c] > scopes->minmax[c][1]) scopes->minmax[c][1] = rgb[c];
+ }
+ }
+ else {
+ rgb_to_ycc(rgb[0],rgb[1],rgb[2],&ycc[0],&ycc[1],&ycc[2], ycc_mode);
+ for (c=0; c<3; c++) {
+ ycc[c] *=INV_255;
+ if (ycc[c] < scopes->minmax[c][0]) scopes->minmax[c][0] = ycc[c];
+ if (ycc[c] > scopes->minmax[c][1]) scopes->minmax[c][1] = ycc[c];
+ }
+ }
+ /* increment count for histo*/
+ bin_r[ get_bin_float(rgb[0]) ] += 1;
+ bin_g[ get_bin_float(rgb[1]) ] += 1;
+ bin_b[ get_bin_float(rgb[2]) ] += 1;
+ bin_lum[ get_bin_float(luma) ] += 1;
+
+ /* save sample if needed */
+ if(saveline) {
+ const float fx = (float)x / (float)ibuf->x;
+ const int idx = 2*(ibuf->x*savedlines+x);
+ save_sample_line(scopes, idx, fx, rgb, ycc);
}
+
+ rf+= ibuf->channels;
+ rc+= ibuf->channels;
}
+ if (saveline)
+ savedlines +=1;
}
-
- /* convert to float */
+
+ /* convert hist data to float (proportional to max count) */
n=0;
+ nl=0;
for (x=0; x<256; x++) {
if (bin_r[x] > n)
n = bin_r[x];
@@ -953,17 +1106,57 @@ void histogram_update(Histogram *hist, ImBuf *ibuf)
n = bin_g[x];
if (bin_b[x] > n)
n = bin_b[x];
+ if (bin_lum[x] > nl)
+ nl = bin_lum[x];
}
div = 1.f/(double)n;
+ divl = 1.f/(double)nl;
for (x=0; x<256; x++) {
- hist->data_r[x] = bin_r[x] * div;
- hist->data_g[x] = bin_g[x] * div;
- hist->data_b[x] = bin_b[x] * div;
+ scopes->hist.data_r[x] = bin_r[x] * div;
+ scopes->hist.data_g[x] = bin_g[x] * div;
+ scopes->hist.data_b[x] = bin_b[x] * div;
+ scopes->hist.data_luma[x] = bin_lum[x] * divl;
}
-
MEM_freeN(bin_r);
MEM_freeN(bin_g);
MEM_freeN(bin_b);
-
- hist->ok=1;
+ MEM_freeN(bin_lum);
+
+ scopes->ok = 1;
+}
+
+void scopes_free(Scopes *scopes)
+{
+ if (scopes->waveform_1) {
+ MEM_freeN(scopes->waveform_1);
+ scopes->waveform_1 = NULL;
+ }
+ if (scopes->waveform_2) {
+ MEM_freeN(scopes->waveform_2);
+ scopes->waveform_2 = NULL;
+ }
+ if (scopes->waveform_3) {
+ MEM_freeN(scopes->waveform_3);
+ scopes->waveform_3 = NULL;
+ }
+ if (scopes->vecscope) {
+ MEM_freeN(scopes->vecscope);
+ scopes->vecscope = NULL;
+ }
+}
+
+void scopes_new(Scopes *scopes)
+{
+ scopes->accuracy=30.0;
+ scopes->hist.mode=HISTO_MODE_RGB;
+ scopes->wavefrm_alpha=0.3;
+ scopes->vecscope_alpha=0.3;
+ scopes->wavefrm_height= 100;
+ scopes->vecscope_height= 100;
+ scopes->hist.height= 100;
+ scopes->ok= 0;
+ scopes->waveform_1 = NULL;
+ scopes->waveform_2 = NULL;
+ scopes->waveform_3 = NULL;
+ scopes->vecscope = NULL;
}
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index f7a9f284a29..673b3c6d482 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -36,6 +36,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_editVert.h"
#include "BLI_cellalloc.h"
@@ -77,12 +78,6 @@
#include "BPY_extern.h"
#endif
-#include "ED_mesh.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
@@ -433,8 +428,8 @@ static void contarget_get_mesh_mat (Scene *scene, Object *ob, char *substring, f
* - 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);
+ if (!(ob->lastDataMask & CD_MASK_MDEFORMVERT)) {
+ dm = mesh_get_derived_final(scene, ob, CD_MASK_MDEFORMVERT);
freeDM= 1;
}
else
@@ -457,8 +452,8 @@ static void contarget_get_mesh_mat (Scene *scene, Object *ob, char *substring, f
if (dvert[i].dw[j].def_nr == dgroup) {
dm->getVertCo(dm, i, co);
dm->getVertNo(dm, i, nor);
- add_v3_v3v3(vec, vec, co);
- add_v3_v3v3(normal, normal, nor);
+ add_v3_v3(vec, co);
+ add_v3_v3(normal, nor);
count++;
break;
}
@@ -543,7 +538,7 @@ static void contarget_get_lattice_mat (Object *ob, char *substring, float mat[][
else
memcpy(tvec, bp->vec, 3*sizeof(float));
- add_v3_v3v3(vec, vec, tvec);
+ add_v3_v3(vec, tvec);
grouped++;
break;
@@ -827,12 +822,12 @@ static void childof_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
/* extract components of both matrices */
VECCOPY(loc, ct->matrix[3]);
- mat4_to_eulO( eul, ct->rotOrder,ct->matrix);
- mat4_to_size( size,ct->matrix);
+ mat4_to_eulO(eul, ct->rotOrder, ct->matrix);
+ mat4_to_size(size, ct->matrix);
VECCOPY(loco, invmat[3]);
- mat4_to_eulO( eulo, cob->rotOrder,invmat);
- mat4_to_size( sizo,invmat);
+ mat4_to_eulO(eulo, cob->rotOrder, invmat);
+ mat4_to_size(sizo, invmat);
/* disable channels not enabled */
if (!(data->flag & CHILDOF_LOCX)) loc[0]= loco[0]= 0.0f;
@@ -1024,7 +1019,7 @@ static void trackto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
float tmat[4][4];
/* Get size property, since ob->size is only the object's own relative size, not its global one */
- mat4_to_size( size,cob->matrix);
+ mat4_to_size(size, cob->matrix);
/* Clear the object's rotation */
cob->matrix[0][0]=size[0];
@@ -1250,7 +1245,7 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
curvetime= data->offset_fac;
}
- if ( where_on_path(ct->tar, curvetime, vec, dir, NULL, &radius) ) {
+ if ( where_on_path(ct->tar, curvetime, vec, dir, NULL, &radius, NULL) ) {
if (data->followflag & FOLLOWPATH_FOLLOW) {
vec_to_quat(quat, dir, (short)data->trackflag, (short)data->upflag);
@@ -1392,9 +1387,9 @@ static void rotlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *t
float size[3];
VECCOPY(loc, cob->matrix[3]);
- mat4_to_size( size,cob->matrix);
+ mat4_to_size(size, cob->matrix);
- mat4_to_eulO( eul, cob->rotOrder,cob->matrix);
+ mat4_to_eulO(eul, cob->rotOrder, cob->matrix);
/* constraint data uses radians internally */
@@ -1645,17 +1640,17 @@ static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
float size[3];
VECCOPY(loc, cob->matrix[3]);
- mat4_to_size( size,cob->matrix);
+ mat4_to_size(size, cob->matrix);
/* to allow compatible rotations, must get both rotations in the order of the owner... */
- mat4_to_eulO( eul, cob->rotOrder,ct->matrix);
- mat4_to_eulO( obeul, cob->rotOrder,cob->matrix);
+ mat4_to_eulO(eul, cob->rotOrder, ct->matrix);
+ mat4_to_eulO(obeul, cob->rotOrder, cob->matrix);
if ((data->flag & ROTLIKE_X)==0)
eul[0] = obeul[0];
else {
if (data->flag & ROTLIKE_OFFSET)
- rotate_eulO(eul, cob->rotOrder, 'x', obeul[0]);
+ rotate_eulO(eul, cob->rotOrder, 'X', obeul[0]);
if (data->flag & ROTLIKE_X_INVERT)
eul[0] *= -1;
@@ -1665,7 +1660,7 @@ static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
eul[1] = obeul[1];
else {
if (data->flag & ROTLIKE_OFFSET)
- rotate_eulO(eul, cob->rotOrder, 'y', obeul[1]);
+ rotate_eulO(eul, cob->rotOrder, 'Y', obeul[1]);
if (data->flag & ROTLIKE_Y_INVERT)
eul[1] *= -1;
@@ -1675,7 +1670,7 @@ static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
eul[2] = obeul[2];
else {
if (data->flag & ROTLIKE_OFFSET)
- rotate_eulO(eul, cob->rotOrder, 'z', obeul[2]);
+ rotate_eulO(eul, cob->rotOrder, 'Z', obeul[2]);
if (data->flag & ROTLIKE_Z_INVERT)
eul[2] *= -1;
@@ -1861,6 +1856,63 @@ static bConstraintTypeInfo CTI_TRANSLIKE = {
translike_evaluate /* evaluate */
};
+/* ---------- Maintain Volume ---------- */
+
+static void samevolume_new_data (void *cdata)
+{
+ bSameVolumeConstraint *data= (bSameVolumeConstraint *)cdata;
+
+ data->flag = SAMEVOL_Y;
+ data->volume = 1.0f;
+}
+
+static void samevolume_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bSameVolumeConstraint *data= con->data;
+
+ float volume = data->volume;
+ float fac = 1.0f;
+ float obsize[3];
+
+ mat4_to_size(obsize, cob->matrix);
+
+ /* calculate normalising scale factor for non-essential values */
+ if (obsize[data->flag] != 0)
+ fac = sqrt(volume / obsize[data->flag]) / obsize[data->flag];
+
+ /* apply scaling factor to the channels not being kept */
+ switch (data->flag) {
+ case SAMEVOL_X:
+ mul_v3_fl(cob->matrix[1], fac);
+ mul_v3_fl(cob->matrix[2], fac);
+ break;
+ case SAMEVOL_Y:
+ mul_v3_fl(cob->matrix[0], fac);
+ mul_v3_fl(cob->matrix[2], fac);
+ break;
+ case SAMEVOL_Z:
+ mul_v3_fl(cob->matrix[0], fac);
+ mul_v3_fl(cob->matrix[1], fac);
+ break;
+ }
+}
+
+static bConstraintTypeInfo CTI_SAMEVOL = {
+ CONSTRAINT_TYPE_SAMEVOL, /* type */
+ sizeof(bSameVolumeConstraint), /* size */
+ "Maintain Volume", /* name */
+ "bSameVolumeConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* id looper */
+ NULL, /* copy data */
+ samevolume_new_data, /* new data */
+ NULL, /* get constraint targets */
+ NULL, /* flush constraint targets */
+ NULL, /* get target matrix */
+ samevolume_evaluate /* evaluate */
+};
+
/* ----------- Python Constraint -------------- */
static void pycon_free (bConstraint *con)
@@ -1930,8 +1982,10 @@ static void pycon_id_looper (bConstraint *con, ConstraintIDFunc func, void *user
/* Whether this approach is maintained remains to be seen (aligorith) */
static void pycon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
{
+#ifndef DISABLE_PYTHON
bPythonConstraint *data= con->data;
-
+#endif
+
if (VALID_CONS_TARGET(ct)) {
/* special exception for curves - depsgraph issues */
if (ct->tar->type == OB_CURVE) {
@@ -2718,7 +2772,7 @@ static void stretchto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
float dist;
/* store scaling before destroying obmat */
- mat4_to_size( size,cob->matrix);
+ mat4_to_size(size, cob->matrix);
/* store X orientation before destroying obmat */
xx[0] = cob->matrix[0][0];
@@ -3000,7 +3054,7 @@ static void rbj_new_data (void *cdata)
bRigidBodyJointConstraint *data= (bRigidBodyJointConstraint *)cdata;
// removed code which set target of this constraint
- data->type=1;
+ data->type=1;
}
static void rbj_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
@@ -3210,7 +3264,7 @@ static void clampto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
}
/* 3. position on curve */
- if (where_on_path(ct->tar, curvetime, vec, dir, NULL, NULL) ) {
+ if (where_on_path(ct->tar, curvetime, vec, dir, NULL, NULL, NULL) ) {
unit_m4(totmat);
VECCOPY(totmat[3], vec);
@@ -3301,7 +3355,7 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
mat4_to_size( dvec,ct->matrix);
break;
case 1: /* rotation (convert to degrees first) */
- mat4_to_eulO( dvec, cob->rotOrder,ct->matrix);
+ mat4_to_eulO(dvec, cob->rotOrder, ct->matrix);
for (i=0; i<3; i++)
dvec[i] = (float)(dvec[i] / M_PI * 180);
break;
@@ -3312,8 +3366,8 @@ static void transform_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
/* extract components of owner's matrix */
VECCOPY(loc, cob->matrix[3]);
- mat4_to_eulO( eul, cob->rotOrder,cob->matrix);
- mat4_to_size( size,cob->matrix);
+ mat4_to_eulO(eul, cob->rotOrder, cob->matrix);
+ mat4_to_size(size, cob->matrix);
/* determine where in range current transforms lie */
if (data->expo) {
@@ -3433,73 +3487,73 @@ static void shrinkwrap_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
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) );
-
+ 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
-
+
unit_m4(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 = len_v3v3(co, nearest.co);
interp_v3_v3v3(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_v3(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;
@@ -3508,19 +3562,19 @@ static void shrinkwrap_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
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 */
- mul_v3_m4v3(co, cob->matrix, co);
+ mul_m4_v3(cob->matrix, co);
VECCOPY(ct->matrix[3], co);
}
}
@@ -3652,7 +3706,7 @@ static void damptrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
/* construct rotation matrix from the axis-angle rotation found above
* - this call takes care to make sure that the axis provided is a unit vector first
*/
- axis_angle_to_mat3( rmat,raxis, rangle);
+ axis_angle_to_mat3(rmat, raxis, rangle);
/* rotate the owner in the way defined by this rotation matrix, then reapply the location since
* we may have destroyed that in the process of multiplying the matrix
@@ -3701,6 +3755,13 @@ static void splineik_copy (bConstraint *con, bConstraint *srccon)
dst->points= MEM_dupallocN(src->points);
}
+static void splineik_new_data (void *cdata)
+{
+ bSplineIKConstraint *data= (bSplineIKConstraint *)cdata;
+
+ data->chainlen= 1;
+}
+
static void splineik_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
{
bSplineIKConstraint *data= con->data;
@@ -3765,13 +3826,125 @@ static bConstraintTypeInfo CTI_SPLINEIK = {
NULL, /* relink data */
splineik_id_looper, /* id looper */
splineik_copy, /* copy data */
- NULL, /* new data */
+ splineik_new_data, /* new data */
splineik_get_tars, /* get constraint targets */
splineik_flush_tars, /* flush constraint targets */
splineik_get_tarmat, /* get target matrix */
NULL /* evaluate - solved as separate loop */
};
+/* ----------- Pivot ------------- */
+
+static void pivotcon_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
+{
+ bPivotConstraint *data= con->data;
+
+ /* target only */
+ func(con, (ID**)&data->tar, userdata);
+}
+
+static int pivotcon_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bPivotConstraint *data= con->data;
+ bConstraintTarget *ct;
+
+ /* standard target-getting macro for single-target constraints */
+ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static void pivotcon_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+ if (con && list) {
+ bPivotConstraint *data= con->data;
+ bConstraintTarget *ct= list->first;
+
+ /* the following macro is used for all standard single-target constraints */
+ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, nocopy)
+ }
+}
+
+static void pivotcon_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bPivotConstraint *data= con->data;
+ bConstraintTarget *ct= targets->first;
+
+ float pivot[3], vec[3];
+ float rotMat[3][3];
+
+ /* firstly, check if pivoting should take place based on the current rotation */
+ if (data->rotAxis != PIVOTCON_AXIS_NONE) {
+ float rot[3];
+
+ /* extract euler-rotation of target */
+ mat4_to_eulO(rot, cob->rotOrder, cob->matrix);
+
+ /* check which range might be violated */
+ if (data->rotAxis < PIVOTCON_AXIS_X) {
+ /* negative rotations (data->rotAxis = 0 -> 2) */
+ if (rot[data->rotAxis] > 0.0f)
+ return;
+ }
+ else {
+ /* positive rotations (data->rotAxis = 3 -> 5 */
+ if (rot[data->rotAxis - PIVOTCON_AXIS_X] < 0.0f)
+ return;
+ }
+ }
+
+ /* find the pivot-point to use */
+ if (VALID_CONS_TARGET(ct)) {
+ /* apply offset to target location */
+ add_v3_v3v3(pivot, ct->matrix[3], data->offset);
+ }
+ else {
+ /* no targets to worry about... */
+ if ((data->flag & PIVOTCON_FLAG_OFFSET_ABS) == 0) {
+ /* offset is relative to owner */
+ add_v3_v3v3(pivot, cob->matrix[3], data->offset);
+ }
+ else {
+ /* directly use the 'offset' specified as an absolute position instead */
+ VECCOPY(pivot, data->offset);
+ }
+ }
+
+ /* get rotation matrix representing the rotation of the owner */
+ // TODO: perhaps we might want to include scaling based on the pivot too?
+ copy_m3_m4(rotMat, cob->matrix);
+ normalize_m3(rotMat);
+
+ /* perform the pivoting... */
+ /* 1. take the vector from owner to the pivot */
+ sub_v3_v3v3(vec, pivot, cob->matrix[3]);
+ /* 2. rotate this vector by the rotation of the object... */
+ mul_m3_v3(rotMat, vec);
+ /* 3. make the rotation in terms of the pivot now */
+ add_v3_v3v3(cob->matrix[3], pivot, vec);
+}
+
+
+static bConstraintTypeInfo CTI_PIVOT = {
+ CONSTRAINT_TYPE_PIVOT, /* type */
+ sizeof(bPivotConstraint), /* size */
+ "Pivot", /* name */
+ "bPivotConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ pivotcon_id_looper, /* id looper */
+ NULL, /* copy data */
+ NULL, /* new data */ // XXX: might be needed to get 'normal' pivot behaviour...
+ pivotcon_get_tars, /* get constraint targets */
+ pivotcon_flush_tars, /* flush constraint targets */
+ default_get_tarmat, /* get target matrix */
+ pivotcon_evaluate /* evaluate */
+};
+
/* ************************* Constraints Type-Info *************************** */
/* All of the constraints api functions use bConstraintTypeInfo structs to carry out
* and operations that involve constraint specific code.
@@ -3807,6 +3980,8 @@ static void constraints_init_typeinfo () {
constraintsTypeInfo[21]= &CTI_DAMPTRACK; /* Damped TrackTo Constraint */
constraintsTypeInfo[22]= &CTI_SPLINEIK; /* Spline IK Constraint */
constraintsTypeInfo[23]= &CTI_TRANSLIKE; /* Copy Transforms Constraint */
+ constraintsTypeInfo[24]= &CTI_SAMEVOL; /* Maintain Volume Constraint */
+ constraintsTypeInfo[25]= &CTI_PIVOT; /* Pivot Constraint */
}
/* This function should be used for getting the appropriate type-info when only
@@ -4071,7 +4246,7 @@ static void con_extern_cb(bConstraint *con, ID **idpoin, void *userdata)
}
/* duplicate all of the constraints in a constraint stack */
-void copy_constraints (ListBase *dst, const ListBase *src)
+void copy_constraints (ListBase *dst, const ListBase *src, int do_extern)
{
bConstraint *con, *srccon;
@@ -4090,15 +4265,23 @@ void copy_constraints (ListBase *dst, const ListBase *src)
if (cti->copy_data)
cti->copy_data(con, srccon);
- /* go over used ID-links for this constraint to ensure that they are valid for proxies */
- if (cti->id_looper)
- cti->id_looper(con, con_extern_cb, NULL);
+ /* for proxies we dont want to make extern */
+ if (do_extern) {
+ /* go over used ID-links for this constraint to ensure that they are valid for proxies */
+ if (cti->id_looper)
+ cti->id_looper(con, con_extern_cb, NULL);
+ }
}
}
}
/* ......... */
+bConstraint *constraints_findByName(ListBase *list, const char *name)
+{
+ return BLI_findstring(list, name, offsetof(bConstraint, name));
+}
+
/* finds the 'active' constraint in a constraint stack */
bConstraint *constraints_get_active (ListBase *list)
{
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 26320e2475f..9520df71b60 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -27,8 +27,6 @@
#include "MEM_guardedalloc.h"
-#include "DNA_ID.h"
-#include "DNA_listBase.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
@@ -44,7 +42,6 @@
#include "BKE_context.h"
#include "BKE_main.h"
#include "BKE_screen.h"
-#include "BKE_global.h"
#ifndef DISABLE_PYTHON
#include "BPY_extern.h"
@@ -407,6 +404,7 @@ struct bContextDataResult {
PointerRNA ptr;
ListBase list;
const char **dir;
+ short type; /* 0: normal, 1: seq */
};
static int ctx_data_get(bContext *C, const char *member, bContextDataResult *result)
@@ -551,7 +549,7 @@ ListBase CTX_data_collection_get(const bContext *C, const char *member)
}
/* 1:found, -1:found but not set, 0:not found */
-int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb)
+int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb, short *r_type)
{
bContextDataResult result;
int ret= ctx_data_get((bContext*)C, member, &result);
@@ -559,10 +557,12 @@ int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListB
if(ret==1) {
*r_ptr= result.ptr;
*r_lb= result.list;
+ *r_type= result.type;
}
else {
memset(r_ptr, 0, sizeof(*r_ptr));
memset(r_lb, 0, sizeof(*r_lb));
+ *r_type= 0;
}
return ret;
@@ -685,6 +685,16 @@ void CTX_data_dir_set(bContextDataResult *result, const char **dir)
result->dir= dir;
}
+void CTX_data_type_set(bContextDataResult *result, short type)
+{
+ result->type= type;
+}
+
+short CTX_data_type_get(bContextDataResult *result)
+{
+ return result->type;
+}
+
/* data context */
Main *CTX_data_main(const bContext *C)
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index e10159f5b6a..2f0c83507f0 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -34,20 +34,14 @@
#include <string.h>
#include <stdlib.h>
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "DNA_object_types.h"
#include "DNA_curve_types.h"
#include "DNA_material_types.h"
/* for dereferencing pointers */
-#include "DNA_ID.h"
#include "DNA_key_types.h"
#include "DNA_scene_types.h"
#include "DNA_vfont_types.h"
@@ -62,7 +56,6 @@
#include "BKE_key.h"
#include "BKE_library.h"
#include "BKE_main.h"
-#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_utildefines.h" // VECCOPY
@@ -146,6 +139,7 @@ Curve *add_curve(char *name, int type)
cu->fsize= 1.0;
cu->ulheight = 0.05;
cu->texflag= CU_AUTOSPACE;
+ cu->smallcaps_scale= 0.75f;
cu->twist_mode= CU_TWIST_MINIMUM; // XXX: this one seems to be the best one in most cases, at least for curve deform...
cu->bb= unit_boundbox();
@@ -520,7 +514,47 @@ void minmaxNurb(Nurb *nu, float *min, float *max)
bp++;
}
}
+}
+
+/* be sure to call makeknots after this */
+void addNurbPoints(Nurb *nu, int number)
+{
+ BPoint *tmp= nu->bp;
+ int i;
+ nu->bp= (BPoint *)MEM_mallocN((nu->pntsu + number) * sizeof(BPoint), "rna_Curve_spline_points_add");
+
+ if(tmp) {
+ memmove(nu->bp, tmp, nu->pntsu * sizeof(BPoint));
+ MEM_freeN(tmp);
+ }
+
+ memset(nu->bp + nu->pntsu, 0, number * sizeof(BPoint));
+
+ for(i=0, tmp= nu->bp + nu->pntsu; i < number; i++, tmp++) {
+ tmp->radius= 1.0f;
+ }
+
+ nu->pntsu += number;
+}
+
+void addNurbPointsBezier(Nurb *nu, int number)
+{
+ BezTriple *tmp= nu->bezt;
+ int i;
+ nu->bezt= (BezTriple *)MEM_mallocN((nu->pntsu + number) * sizeof(BezTriple), "rna_Curve_spline_points_add");
+
+ if(tmp) {
+ memmove(nu->bezt, tmp, nu->pntsu * sizeof(BezTriple));
+ MEM_freeN(tmp);
+ }
+ memset(nu->bezt + nu->pntsu, 0, number * sizeof(BezTriple));
+
+ for(i=0, tmp= nu->bezt + nu->pntsu; i < number; i++, tmp++) {
+ tmp->radius= 1.0f;
+ }
+
+ nu->pntsu += number;
}
/* ~~~~~~~~~~~~~~~~~~~~Non Uniform Rational B Spline calculations ~~~~~~~~~~~ */
@@ -533,7 +567,7 @@ static void calcknots(float *knots, short aantal, short order, short type)
float k;
int a, t;
- t = aantal+order;
+ t = aantal+order;
if(type==0) {
for(a=0;a<t;a++) {
@@ -588,7 +622,7 @@ static void makecyclicknots(float *knots, short pnts, short order)
}
b= order;
- c=pnts + order + order2;
+ c=pnts + order + order2;
for(a=pnts+order2; a<c; a++) {
knots[a]= knots[a-1]+ (knots[b]-knots[b-1]);
b--;
@@ -604,7 +638,7 @@ void makeknots(Nurb *nu, short uv)
if(nu->knotsu) MEM_freeN(nu->knotsu);
if(check_valid_nurb_u(nu)) {
nu->knotsu= MEM_callocN(4+sizeof(float)*KNOTSU(nu), "makeknots");
- if(nu->flagu & CU_CYCLIC) {
+ if(nu->flagu & CU_NURB_CYCLIC) {
calcknots(nu->knotsu, nu->pntsu, nu->orderu, 0); /* cyclic should be uniform */
makecyclicknots(nu->knotsu, nu->pntsu, nu->orderu);
} else {
@@ -617,7 +651,7 @@ void makeknots(Nurb *nu, short uv)
if(nu->knotsv) MEM_freeN(nu->knotsv);
if(check_valid_nurb_v(nu)) {
nu->knotsv= MEM_callocN(4+sizeof(float)*KNOTSV(nu), "makeknots");
- if(nu->flagv & CU_CYCLIC) {
+ if(nu->flagv & CU_NURB_CYCLIC) {
calcknots(nu->knotsv, nu->pntsv, nu->orderv, 0); /* cyclic should be uniform */
makecyclicknots(nu->knotsv, nu->pntsv, nu->orderv);
} else {
@@ -635,14 +669,14 @@ static void basisNurb(float t, short order, short pnts, float *knots, float *bas
int i, i1 = 0, i2 = 0 ,j, orderpluspnts, opp2, o2;
orderpluspnts= order+pnts;
- opp2 = orderpluspnts-1;
+ opp2 = orderpluspnts-1;
/* this is for float inaccuracy */
if(t < knots[0]) t= knots[0];
else if(t > knots[opp2]) t= knots[opp2];
/* this part is order '1' */
- o2 = order + 1;
+ o2 = order + 1;
for(i=0;i<opp2;i++) {
if(knots[i]!=knots[i+1] && t>= knots[i] && t<=knots[i+1]) {
basis[i]= 1.0;
@@ -735,18 +769,18 @@ void makeNurbfaces(Nurb *nu, float *coord_array, int rowstride)
fp= nu->knotsu;
ustart= fp[nu->orderu-1];
- if(nu->flagu & CU_CYCLIC) uend= fp[nu->pntsu+nu->orderu-1];
+ if(nu->flagu & CU_NURB_CYCLIC) uend= fp[nu->pntsu+nu->orderu-1];
else uend= fp[nu->pntsu];
- ustep= (uend-ustart)/((nu->flagu & CU_CYCLIC) ? totu : totu - 1);
+ ustep= (uend-ustart)/((nu->flagu & CU_NURB_CYCLIC) ? totu : totu - 1);
basisu= (float *)MEM_mallocN(sizeof(float)*KNOTSU(nu), "makeNurbfaces3");
fp= nu->knotsv;
vstart= fp[nu->orderv-1];
- if(nu->flagv & CU_CYCLIC) vend= fp[nu->pntsv+nu->orderv-1];
+ if(nu->flagv & CU_NURB_CYCLIC) vend= fp[nu->pntsv+nu->orderv-1];
else vend= fp[nu->pntsv];
- vstep= (vend-vstart)/((nu->flagv & CU_CYCLIC) ? totv : totv - 1);
+ vstep= (vend-vstart)/((nu->flagv & CU_NURB_CYCLIC) ? totv : totv - 1);
len= KNOTSV(nu);
basisv= (float *)MEM_mallocN(sizeof(float)*len*totv, "makeNurbfaces3");
@@ -754,7 +788,7 @@ void makeNurbfaces(Nurb *nu, float *coord_array, int rowstride)
jend= (int *)MEM_mallocN(sizeof(float)*totv, "makeNurbfaces5");
/* precalculation of basisv and jstart,jend */
- if(nu->flagv & CU_CYCLIC) cycl= nu->orderv-1;
+ if(nu->flagv & CU_NURB_CYCLIC) cycl= nu->orderv-1;
else cycl= 0;
v= vstart;
basis= basisv;
@@ -765,7 +799,7 @@ void makeNurbfaces(Nurb *nu, float *coord_array, int rowstride)
v+= vstep;
}
- if(nu->flagu & CU_CYCLIC) cycl= nu->orderu-1;
+ if(nu->flagu & CU_NURB_CYCLIC) cycl= nu->orderu-1;
else cycl= 0;
in= coord_array;
u= ustart;
@@ -855,14 +889,14 @@ void makeNurbfaces(Nurb *nu, float *coord_array, int rowstride)
MEM_freeN(jend);
}
-void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, int resolu, int stride)
+void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, float *weight_array, int resolu, int stride)
/* coord_array has to be 3*4*pntsu*resolu in size and zero-ed
* tilt_array and radius_array will be written to if valid */
{
BPoint *bp;
float u, ustart, uend, ustep, sumdiv;
float *basisu, *sum, *fp;
- float *coord_fp= coord_array, *tilt_fp= tilt_array, *radius_fp= radius_array;
+ float *coord_fp= coord_array, *tilt_fp= tilt_array, *radius_fp= radius_array, *weight_fp= weight_array;
int i, len, istart, iend, cycl;
if(nu->knotsu==NULL) return;
@@ -883,13 +917,13 @@ void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radiu
fp= nu->knotsu;
ustart= fp[nu->orderu-1];
- if(nu->flagu & CU_CYCLIC) uend= fp[nu->pntsu+nu->orderu-1];
+ if(nu->flagu & CU_NURB_CYCLIC) uend= fp[nu->pntsu+nu->orderu-1];
else uend= fp[nu->pntsu];
- ustep= (uend-ustart)/(resolu - ((nu->flagu & CU_CYCLIC) ? 0 : 1));
+ ustep= (uend-ustart)/(resolu - ((nu->flagu & CU_NURB_CYCLIC) ? 0 : 1));
basisu= (float *)MEM_mallocN(sizeof(float)*KNOTSU(nu), "makeNurbcurve3");
- if(nu->flagu & CU_CYCLIC) cycl= nu->orderu-1;
+ if(nu->flagu & CU_NURB_CYCLIC) cycl= nu->orderu-1;
else cycl= 0;
u= ustart;
@@ -935,6 +969,9 @@ void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radiu
if (radius_fp)
(*radius_fp) += (*fp) * bp->radius;
+
+ if (weight_fp)
+ (*weight_fp) += (*fp) * bp->weight;
}
}
@@ -943,6 +980,7 @@ void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radiu
if (tilt_fp) tilt_fp = (float *)(((char *)tilt_fp) + stride);
if (radius_fp) radius_fp = (float *)(((char *)radius_fp) + stride);
+ if (weight_fp) weight_fp = (float *)(((char *)weight_fp) + stride);
u+= ustep;
}
@@ -966,18 +1004,18 @@ void forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int i
f*= it;
rt3= (q3-q0+3.0f*(q1-q2))/f;
- q0= rt0;
+ q0= rt0;
q1= rt1+rt2+rt3;
q2= 2*rt2+6*rt3;
q3= 6*rt3;
- for(a=0; a<=it; a++) {
+ for(a=0; a<=it; a++) {
*p= q0;
p = (float *)(((char *)p)+stride);
q0+= q1;
- q1+= q2;
- q2+= q3;
- }
+ q1+= q2;
+ q2+= q3;
+ }
}
static void forward_diff_bezier_cotangent(float *p0, float *p1, float *p2, float *p3, float *p, int it, int stride)
@@ -987,7 +1025,7 @@ static void forward_diff_bezier_cotangent(float *p0, float *p1, float *p2, float
*
* This could also be optimized like forward_diff_bezier */
int a;
- for(a=0; a<=it; a++) {
+ for(a=0; a<=it; a++) {
float t = (float)a / (float)it;
int i;
@@ -996,7 +1034,7 @@ static void forward_diff_bezier_cotangent(float *p0, float *p1, float *p2, float
}
normalize_v3(p);
p = (float *)(((char *)p)+stride);
- }
+ }
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
@@ -1023,9 +1061,9 @@ float *make_orco_surf(Object *ob)
sizeu = nu->pntsu*nu->resolu;
sizev = nu->pntsv*nu->resolv;
- if (nu->flagu & CU_CYCLIC) sizeu++;
- if (nu->flagv & CU_CYCLIC) sizev++;
- if(nu->pntsv>1) tot+= sizeu * sizev;
+ if (nu->flagu & CU_NURB_CYCLIC) sizeu++;
+ if (nu->flagv & CU_NURB_CYCLIC) sizev++;
+ if(nu->pntsv>1) tot+= sizeu * sizev;
nu= nu->next;
}
@@ -1037,8 +1075,8 @@ float *make_orco_surf(Object *ob)
if(nu->pntsv>1) {
sizeu = nu->pntsu*nu->resolu;
sizev = nu->pntsv*nu->resolv;
- if (nu->flagu & CU_CYCLIC) sizeu++;
- if (nu->flagv & CU_CYCLIC) sizev++;
+ if (nu->flagu & CU_NURB_CYCLIC) sizeu++;
+ if (nu->flagv & CU_NURB_CYCLIC) sizev++;
if(cu->flag & CU_UV_ORCO) {
for(b=0; b< sizeu; b++) {
@@ -1064,12 +1102,12 @@ float *make_orco_surf(Object *ob)
for(b=0; b<sizeu; b++) {
int use_b= b;
- if (b==sizeu-1 && (nu->flagu & CU_CYCLIC))
+ if (b==sizeu-1 && (nu->flagu & CU_NURB_CYCLIC))
use_b= 0;
for(a=0; a<sizev; a++) {
int use_a= a;
- if (a==sizev-1 && (nu->flagv & CU_CYCLIC))
+ if (a==sizev-1 && (nu->flagv & CU_NURB_CYCLIC))
use_a= 0;
tdata = _tdata + 3 * (use_b * (nu->pntsv*nu->resolv) + use_a);
@@ -1100,17 +1138,12 @@ float *make_orco_curve(Scene *scene, Object *ob)
DispList *dl;
int u, v, numVerts;
float *fp, *coord_array;
- int remakeDisp = 0;
+ ListBase disp = {NULL, NULL};
- if (!(cu->flag&CU_UV_ORCO) && cu->key && cu->key->block.first) {
- makeDispListCurveTypes(scene, ob, 1);
- remakeDisp = 1;
- }
-
- /* Assumes displist has been built */
+ makeDispListCurveTypes_forOrco(scene, ob, &disp);
numVerts = 0;
- for (dl=cu->disp.first; dl; dl=dl->next) {
+ for (dl=disp.first; dl; dl=dl->next) {
if (dl->type==DL_INDEX3) {
numVerts += dl->nr;
} else if (dl->type==DL_SURF) {
@@ -1127,7 +1160,7 @@ float *make_orco_curve(Scene *scene, Object *ob)
}
fp= coord_array= MEM_mallocN(3*sizeof(float)*numVerts, "cu_orco");
- for (dl=cu->disp.first; dl; dl=dl->next) {
+ for (dl=disp.first; dl; dl=dl->next) {
if (dl->type==DL_INDEX3) {
for (u=0; u<dl->nr; u++, fp+=3) {
if (cu->flag & CU_UV_ORCO) {
@@ -1175,9 +1208,7 @@ float *make_orco_curve(Scene *scene, Object *ob)
}
}
- if (remakeDisp) {
- makeDispListCurveTypes(scene, ob, 0);
- }
+ freedisplist(&disp);
return coord_array;
}
@@ -1185,7 +1216,7 @@ float *make_orco_curve(Scene *scene, Object *ob)
/* ***************** BEVEL ****************** */
-void makebevelcurve(Scene *scene, Object *ob, ListBase *disp)
+void makebevelcurve(Scene *scene, Object *ob, ListBase *disp, int forRender)
{
DispList *dl, *dlnew;
Curve *bevcu, *cu;
@@ -1198,40 +1229,47 @@ void makebevelcurve(Scene *scene, Object *ob, ListBase *disp)
/* if a font object is being edited, then do nothing */
// XXX if( ob == obedit && ob->type == OB_FONT ) return;
- if(cu->bevobj && cu->bevobj!=ob) {
- if(cu->bevobj->type==OB_CURVE) {
- bevcu= cu->bevobj->data;
- if(bevcu->ext1==0.0 && bevcu->ext2==0.0) {
- facx= cu->bevobj->size[0];
- facy= cu->bevobj->size[1];
+ if(cu->bevobj) {
+ bevcu= cu->bevobj->data;
+ if(bevcu->ext1==0.0 && bevcu->ext2==0.0) {
+ ListBase bevdisp= {NULL, NULL};
+ facx= cu->bevobj->size[0];
+ facy= cu->bevobj->size[1];
+ if (forRender) {
+ makeDispListCurveTypes_forRender(scene, cu->bevobj, &bevdisp, NULL, 0);
+ dl= bevdisp.first;
+ } else {
dl= bevcu->disp.first;
if(dl==0) {
makeDispListCurveTypes(scene, cu->bevobj, 0);
dl= bevcu->disp.first;
}
- while(dl) {
- if ELEM(dl->type, DL_POLY, DL_SEGM) {
- dlnew= MEM_mallocN(sizeof(DispList), "makebevelcurve1");
- *dlnew= *dl;
- dlnew->verts= MEM_mallocN(3*sizeof(float)*dl->parts*dl->nr, "makebevelcurve1");
- memcpy(dlnew->verts, dl->verts, 3*sizeof(float)*dl->parts*dl->nr);
-
- if(dlnew->type==DL_SEGM) dlnew->flag |= (DL_FRONT_CURVE|DL_BACK_CURVE);
-
- BLI_addtail(disp, dlnew);
- fp= dlnew->verts;
- nr= dlnew->parts*dlnew->nr;
- while(nr--) {
- fp[2]= fp[1]*facy;
- fp[1]= -fp[0]*facx;
- fp[0]= 0.0;
- fp+= 3;
- }
+ }
+
+ while(dl) {
+ if ELEM(dl->type, DL_POLY, DL_SEGM) {
+ dlnew= MEM_mallocN(sizeof(DispList), "makebevelcurve1");
+ *dlnew= *dl;
+ dlnew->verts= MEM_mallocN(3*sizeof(float)*dl->parts*dl->nr, "makebevelcurve1");
+ memcpy(dlnew->verts, dl->verts, 3*sizeof(float)*dl->parts*dl->nr);
+
+ if(dlnew->type==DL_SEGM) dlnew->flag |= (DL_FRONT_CURVE|DL_BACK_CURVE);
+
+ BLI_addtail(disp, dlnew);
+ fp= dlnew->verts;
+ nr= dlnew->parts*dlnew->nr;
+ while(nr--) {
+ fp[2]= fp[1]*facy;
+ fp[1]= -fp[0]*facx;
+ fp[0]= 0.0;
+ fp+= 3;
}
- dl= dl->next;
}
+ dl= dl->next;
}
+
+ freedisplist(&bevdisp);
}
}
else if(cu->ext1==0.0 && cu->ext2==0.0) {
@@ -1281,30 +1319,33 @@ void makebevelcurve(Scene *scene, Object *ob, ListBase *disp)
short dnr;
/* bevel now in three parts, for proper vertex normals */
- /* part 1 */
- dnr= nr= 2+ cu->bevresol;
- if( (cu->flag & (CU_FRONT|CU_BACK))==0)
- nr= 3+ 2*cu->bevresol;
-
- dl= MEM_callocN(sizeof(DispList), "makebevelcurve p1");
- dl->verts= MEM_mallocN(nr*3*sizeof(float), "makebevelcurve p1");
- BLI_addtail(disp, dl);
- dl->type= DL_SEGM;
- dl->parts= 1;
- dl->flag= DL_BACK_CURVE;
- dl->nr= nr;
+ /* part 1, back */
- /* half a circle */
- fp= dl->verts;
- dangle= (0.5*M_PI/(dnr-1));
- angle= -(nr-1)*dangle;
-
- for(a=0; a<nr; a++) {
- fp[0]= 0.0;
- fp[1]= (float)(cos(angle)*(cu->ext2));
- fp[2]= (float)(sin(angle)*(cu->ext2)) - cu->ext1;
- angle+= dangle;
- fp+= 3;
+ if((cu->flag & CU_BACK) || !(cu->flag & CU_FRONT)) {
+ dnr= nr= 2+ cu->bevresol;
+ if( (cu->flag & (CU_FRONT|CU_BACK))==0)
+ nr= 3+ 2*cu->bevresol;
+
+ dl= MEM_callocN(sizeof(DispList), "makebevelcurve p1");
+ dl->verts= MEM_mallocN(nr*3*sizeof(float), "makebevelcurve p1");
+ BLI_addtail(disp, dl);
+ dl->type= DL_SEGM;
+ dl->parts= 1;
+ dl->flag= DL_BACK_CURVE;
+ dl->nr= nr;
+
+ /* half a circle */
+ fp= dl->verts;
+ dangle= (0.5*M_PI/(dnr-1));
+ angle= -(nr-1)*dangle;
+
+ for(a=0; a<nr; a++) {
+ fp[0]= 0.0;
+ fp[1]= (float)(cos(angle)*(cu->ext2));
+ fp[2]= (float)(sin(angle)*(cu->ext2)) - cu->ext1;
+ angle+= dangle;
+ fp+= 3;
+ }
}
/* part 2, sidefaces */
@@ -1337,30 +1378,32 @@ void makebevelcurve(Scene *scene, Object *ob, ListBase *disp)
}
}
- /* part 3 */
- dnr= nr= 2+ cu->bevresol;
- if( (cu->flag & (CU_FRONT|CU_BACK))==0)
- nr= 3+ 2*cu->bevresol;
-
- dl= MEM_callocN(sizeof(DispList), "makebevelcurve p3");
- dl->verts= MEM_mallocN(nr*3*sizeof(float), "makebevelcurve p3");
- BLI_addtail(disp, dl);
- dl->type= DL_SEGM;
- dl->flag= DL_FRONT_CURVE;
- dl->parts= 1;
- dl->nr= nr;
-
- /* half a circle */
- fp= dl->verts;
- angle= 0.0;
- dangle= (0.5*M_PI/(dnr-1));
-
- for(a=0; a<nr; a++) {
- fp[0]= 0.0;
- fp[1]= (float)(cos(angle)*(cu->ext2));
- fp[2]= (float)(sin(angle)*(cu->ext2)) + cu->ext1;
- angle+= dangle;
- fp+= 3;
+ /* part 3, front */
+ if((cu->flag & CU_FRONT) || !(cu->flag & CU_BACK)) {
+ dnr= nr= 2+ cu->bevresol;
+ if( (cu->flag & (CU_FRONT|CU_BACK))==0)
+ nr= 3+ 2*cu->bevresol;
+
+ dl= MEM_callocN(sizeof(DispList), "makebevelcurve p3");
+ dl->verts= MEM_mallocN(nr*3*sizeof(float), "makebevelcurve p3");
+ BLI_addtail(disp, dl);
+ dl->type= DL_SEGM;
+ dl->flag= DL_FRONT_CURVE;
+ dl->parts= 1;
+ dl->nr= nr;
+
+ /* half a circle */
+ fp= dl->verts;
+ angle= 0.0;
+ dangle= (0.5*M_PI/(dnr-1));
+
+ for(a=0; a<nr; a++) {
+ fp[0]= 0.0;
+ fp[1]= (float)(cos(angle)*(cu->ext2));
+ fp[2]= (float)(sin(angle)*(cu->ext2)) + cu->ext1;
+ angle+= dangle;
+ fp+= 3;
+ }
}
}
}
@@ -1435,7 +1478,7 @@ static short bevelinside(BevList *bl1,BevList *bl2)
/* there's a transition, calc intersection point */
mode= cu_isectLL(prevbevp->vec, bevp->vec, hvec1, hvec2, 0, 1, &lab, &mu, vec);
/* if lab==0.0 or lab==1.0 then the edge intersects exactly a transition
- only allow for one situation: we choose lab= 1.0
+ only allow for one situation: we choose lab= 1.0
*/
if(mode>=0 && lab!=0.0) {
if(vec[0]<hvec1[0]) links++;
@@ -1506,7 +1549,7 @@ static void calc_bevel_sin_cos(float x1, float y1, float x2, float y2, float *si
}
-static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *tilt_array, float *radius_array, int resolu, int stride)
+static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *tilt_array, float *radius_array, float *weight_array, int resolu, int stride)
{
BezTriple *pprev, *next, *last;
float fac, dfac, t[4];
@@ -1519,14 +1562,14 @@ static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *
/* returns a point */
if(prevbezt==nu->bezt) {
- if(nu->flagu & CU_CYCLIC) pprev= last;
+ if(nu->flagu & CU_NURB_CYCLIC) pprev= last;
else pprev= prevbezt;
}
else pprev= prevbezt-1;
/* next point */
if(bezt==last) {
- if(nu->flagu & CU_CYCLIC) next= nu->bezt;
+ if(nu->flagu & CU_NURB_CYCLIC) next= nu->bezt;
else next= bezt;
}
else next= bezt+1;
@@ -1563,6 +1606,13 @@ static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *
radius_array = (float *)(((char *)radius_array) + stride);
}
+
+ if(weight_array) {
+ /* basic interpolation for now, could copy tilt interp too */
+ *weight_array = prevbezt->weight + (bezt->weight - prevbezt->weight)*(3.0f*fac*fac - 2.0f*fac*fac*fac);
+
+ weight_array = (float *)(((char *)weight_array) + stride);
+ }
}
}
@@ -1948,7 +1998,7 @@ void makeBevelList(Object *ob)
float min, inp, x1, x2, y1, y2;
struct bevelsort *sortdata, *sd, *sd1;
int a, b, nr, poly, resolu = 0, len = 0;
- int do_tilt, do_radius;
+ int do_tilt, do_radius, do_weight;
/* this function needs an object, because of tflag and upflag */
cu= ob->data;
@@ -1967,6 +2017,7 @@ void makeBevelList(Object *ob)
/* check if we will calculate tilt data */
do_tilt = CU_DO_TILT(cu, nu);
do_radius = CU_DO_RADIUS(cu, nu); /* normal display uses the radius, better just to calculate them */
+ do_weight = 1;
/* 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 */
@@ -1985,7 +2036,7 @@ void makeBevelList(Object *ob)
bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelList2");
BLI_addtail(&(cu->bev), bl);
- if(nu->flagu & CU_CYCLIC) bl->poly= 0;
+ if(nu->flagu & CU_NURB_CYCLIC) bl->poly= 0;
else bl->poly= -1;
bl->nr= len;
bl->dupe_nr= 0;
@@ -1996,6 +2047,7 @@ void makeBevelList(Object *ob)
VECCOPY(bevp->vec, bp->vec);
bevp->alfa= bp->alfa;
bevp->radius= bp->radius;
+ bevp->weight= bp->weight;
bevp->split_tag= TRUE;
bevp++;
bp++;
@@ -2003,17 +2055,17 @@ void makeBevelList(Object *ob)
}
else if(nu->type == CU_BEZIER) {
- len= resolu*(nu->pntsu+ (nu->flagu & CU_CYCLIC) -1)+1; /* in case last point is not cyclic */
+ len= resolu*(nu->pntsu+ (nu->flagu & CU_NURB_CYCLIC) -1)+1; /* in case last point is not cyclic */
bl= MEM_callocN(sizeof(BevList)+len*sizeof(BevPoint), "makeBevelBPoints");
BLI_addtail(&(cu->bev), bl);
- if(nu->flagu & CU_CYCLIC) bl->poly= 0;
+ if(nu->flagu & CU_NURB_CYCLIC) bl->poly= 0;
else bl->poly= -1;
bevp= (BevPoint *)(bl+1);
a= nu->pntsu-1;
bezt= nu->bezt;
- if(nu->flagu & CU_CYCLIC) {
+ if(nu->flagu & CU_NURB_CYCLIC) {
a++;
prevbezt= nu->bezt+(nu->pntsu-1);
}
@@ -2028,6 +2080,7 @@ void makeBevelList(Object *ob)
VECCOPY(bevp->vec, prevbezt->vec[1]);
bevp->alfa= prevbezt->alfa;
bevp->radius= prevbezt->radius;
+ bevp->weight= prevbezt->weight;
bevp->split_tag= TRUE;
bevp->dupe_tag= FALSE;
bevp++;
@@ -2049,6 +2102,7 @@ void makeBevelList(Object *ob)
alfa_bezpart( prevbezt, bezt, nu,
do_tilt ? &bevp->alfa : NULL,
do_radius ? &bevp->radius : NULL,
+ do_weight ? &bevp->weight : NULL,
resolu, sizeof(BevPoint));
@@ -2074,10 +2128,11 @@ void makeBevelList(Object *ob)
bezt++;
}
- if((nu->flagu & CU_CYCLIC)==0) { /* not cyclic: endpoint */
+ if((nu->flagu & CU_NURB_CYCLIC)==0) { /* not cyclic: endpoint */
VECCOPY(bevp->vec, prevbezt->vec[1]);
bevp->alfa= prevbezt->alfa;
bevp->radius= prevbezt->radius;
+ bevp->weight= prevbezt->weight;
bl->nr++;
}
}
@@ -2089,13 +2144,14 @@ void makeBevelList(Object *ob)
BLI_addtail(&(cu->bev), bl);
bl->nr= len;
bl->dupe_nr= 0;
- if(nu->flagu & CU_CYCLIC) bl->poly= 0;
+ if(nu->flagu & CU_NURB_CYCLIC) bl->poly= 0;
else bl->poly= -1;
bevp= (BevPoint *)(bl+1);
makeNurbcurve( nu, &bevp->vec[0],
do_tilt ? &bevp->alfa : NULL,
do_radius ? &bevp->radius : NULL,
+ do_weight ? &bevp->weight : NULL,
resolu, sizeof(BevPoint));
}
}
@@ -2529,7 +2585,7 @@ void calchandlesNurb(Nurb *nu) /* first, if needed, set handle flags */
a= nu->pntsu;
bezt= nu->bezt;
- if(nu->flagu & CU_CYCLIC) prev= bezt+(a-1);
+ if(nu->flagu & CU_NURB_CYCLIC) prev= bezt+(a-1);
else prev= 0;
next= bezt+1;
@@ -2537,7 +2593,7 @@ void calchandlesNurb(Nurb *nu) /* first, if needed, set handle flags */
calchandleNurb(bezt, prev, next, 0);
prev= bezt;
if(a==1) {
- if(nu->flagu & CU_CYCLIC) next= nu->bezt;
+ if(nu->flagu & CU_NURB_CYCLIC) next= nu->bezt;
else next= 0;
}
else next++;
@@ -2549,13 +2605,13 @@ void calchandlesNurb(Nurb *nu) /* first, if needed, set handle flags */
void testhandlesNurb(Nurb *nu)
{
- /* use when something has changed with handles.
- it treats all BezTriples with the following rules:
- PHASE 1: do types have to be altered?
- Auto handles: become aligned when selection status is NOT(000 || 111)
- Vector handles: become 'nothing' when (one half selected AND other not)
- PHASE 2: recalculate handles
- */
+ /* use when something has changed with handles.
+ it treats all BezTriples with the following rules:
+ PHASE 1: do types have to be altered?
+ Auto handles: become aligned when selection status is NOT(000 || 111)
+ Vector handles: become 'nothing' when (one half selected AND other not)
+ PHASE 2: recalculate handles
+ */
BezTriple *bezt;
short flag, a;
@@ -2994,7 +3050,7 @@ int check_valid_nurb_u( struct Nurb *nu )
if (nu->type != CU_NURBS) return 1; /* not a nurb, lets assume its valid */
if (nu->pntsu < nu->orderu) return 0;
- if (((nu->flag & CU_CYCLIC)==0) && ((nu->flagu>>1) & 2)) { /* Bezier U Endpoints */
+ if (((nu->flag & CU_NURB_CYCLIC)==0) && (nu->flagu & CU_NURB_BEZIER)) { /* Bezier U Endpoints */
if (nu->orderu==4) {
if (nu->pntsu < 5) return 0; /* bezier with 4 orderu needs 5 points */
} else if (nu->orderu != 3) return 0; /* order must be 3 or 4 */
@@ -3008,7 +3064,7 @@ int check_valid_nurb_v( struct Nurb *nu)
if (nu->type != CU_NURBS) return 1; /* not a nurb, lets assume its valid */
if (nu->pntsv < nu->orderv) return 0;
- if (((nu->flag & CU_CYCLIC)==0) && ((nu->flagv>>1) & 2)) { /* Bezier V Endpoints */
+ if (((nu->flag & CU_NURB_CYCLIC)==0) && (nu->flagv & CU_NURB_BEZIER)) { /* Bezier V Endpoints */
if (nu->orderv==4) {
if (nu->pntsv < 5) return 0; /* bezier with 4 orderu needs 5 points */
} else if (nu->orderv != 3) return 0; /* order must be 3 or 4 */
@@ -3023,7 +3079,7 @@ int clamp_nurb_order_u( struct Nurb *nu )
nu->orderu= nu->pntsu;
change= 1;
}
- if(((nu->flag & CU_CYCLIC)==0) && (nu->flagu>>1)&2) {
+ if(((nu->flag & CU_NURB_CYCLIC)==0) && (nu->flagu & CU_NURB_BEZIER)) {
CLAMP(nu->orderu, 3,4);
change= 1;
}
@@ -3037,7 +3093,7 @@ int clamp_nurb_order_v( struct Nurb *nu)
nu->orderv= nu->pntsv;
change= 1;
}
- if(((nu->flag & CU_CYCLIC)==0) && (nu->flagv>>1)&2) {
+ if(((nu->flag & CU_NURB_CYCLIC)==0) && (nu->flagv & CU_NURB_BEZIER)) {
CLAMP(nu->orderv, 3,4);
change= 1;
}
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 1cf8be330e6..d029573b2e9 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -38,16 +38,12 @@
#include "MEM_guardedalloc.h"
-#include "DNA_customdata_types.h"
-#include "DNA_listBase.h"
#include "DNA_meshdata_types.h"
#include "DNA_ID.h"
#include "BLI_blenlib.h"
#include "BLI_linklist.h"
-#include "BLI_math.h"
#include "BLI_mempool.h"
-#include "BLI_string.h"
#include "BKE_customdata.h"
#include "BKE_customdata_file.h"
@@ -92,12 +88,12 @@ typedef struct LayerTypeInfo {
* count gives the number of elements in sources
*/
void (*interp)(void **sources, float *weights, float *sub_weights,
- int count, void *dest);
+ int count, void *dest);
- /* a function to swap the data in corners of the element */
- void (*swap)(void *data, int *corner_indices);
+ /* a function to swap the data in corners of the element */
+ void (*swap)(void *data, const int *corner_indices);
- /* a function to set a layer's data to default values. if NULL, the
+ /* a function to set a layer's data to default values. if NULL, the
default is assumed to be all zeros */
void (*set_default)(void *data, int count);
@@ -109,18 +105,18 @@ typedef struct LayerTypeInfo {
void (*dominmax)(void *data1, void *min, void *max);
void (*copyvalue)(void *source, void *dest);
- /* a function to read data from a cdf file */
+ /* a function to read data from a cdf file */
int (*read)(CDataFile *cdf, void *data, int count);
- /* a function to write data to a cdf file */
+ /* a function to write data to a cdf file */
int (*write)(CDataFile *cdf, void *data, int count);
- /* a function to determine file size */
+ /* a function to determine file size */
size_t (*filesize)(CDataFile *cdf, void *data, int count);
} LayerTypeInfo;
static void layerCopy_mdeformvert(const void *source, void *dest,
- int count)
+ int count)
{
int i, size = sizeof(MDeformVert);
@@ -162,7 +158,7 @@ static void linklist_free_simple(void *link)
}
static void layerInterp_mdeformvert(void **sources, float *weights,
- float *sub_weights, int count, void *dest)
+ float *sub_weights, int count, void *dest)
{
MDeformVert *dvert = dest;
LinkNode *dest_dw = NULL; /* a list of lists of MDeformWeight pointers */
@@ -192,7 +188,7 @@ static void layerInterp_mdeformvert(void **sources, float *weights,
/* if this def_nr is not in the list, add it */
if(!node) {
MDeformWeight *tmp_dw = BLI_cellalloc_calloc(sizeof(*tmp_dw),
- "layerInterp_mdeformvert tmp_dw");
+ "layerInterp_mdeformvert tmp_dw");
tmp_dw->def_nr = dw->def_nr;
tmp_dw->weight = dw->weight * interp_weight;
BLI_linklist_prepend(&dest_dw, tmp_dw);
@@ -206,7 +202,7 @@ static void layerInterp_mdeformvert(void **sources, float *weights,
if(totweight) {
dvert->dw = BLI_cellalloc_calloc(sizeof(*dvert->dw) * totweight,
- "layerInterp_mdeformvert dvert->dw");
+ "layerInterp_mdeformvert dvert->dw");
dvert->totweight = totweight;
for(i = 0, node = dest_dw; node; node = node->next, ++i)
@@ -220,7 +216,7 @@ static void layerInterp_mdeformvert(void **sources, float *weights,
static void layerInterp_msticky(void **sources, float *weights,
- float *sub_weights, int count, void *dest)
+ float *sub_weights, int count, void *dest)
{
float co[2], w;
MSticky *mst;
@@ -252,7 +248,7 @@ static void layerCopy_tface(const void *source, void *dest, int count)
}
static void layerInterp_tface(void **sources, float *weights,
- float *sub_weights, int count, void *dest)
+ float *sub_weights, int count, void *dest)
{
MTFace *tf = dest;
int i, j, k;
@@ -292,14 +288,14 @@ static void layerInterp_tface(void **sources, float *weights,
}
}
-static void layerSwap_tface(void *data, int *corner_indices)
+static void layerSwap_tface(void *data, const int *corner_indices)
{
MTFace *tf = data;
float uv[4][2];
static const short pin_flags[4] =
- { TF_PIN1, TF_PIN2, TF_PIN3, TF_PIN4 };
+ { TF_PIN1, TF_PIN2, TF_PIN3, TF_PIN4 };
static const char sel_flags[4] =
- { TF_SEL1, TF_SEL2, TF_SEL3, TF_SEL4 };
+ { TF_SEL1, TF_SEL2, TF_SEL3, TF_SEL4 };
short unwrap = tf->unwrap & ~(TF_PIN1 | TF_PIN2 | TF_PIN3 | TF_PIN4);
char flag = tf->flag & ~(TF_SEL1 | TF_SEL2 | TF_SEL3 | TF_SEL4);
int j;
@@ -329,7 +325,7 @@ static void layerSwap_tface(void *data, int *corner_indices)
static void layerDefault_tface(void *data, int count)
{
static MTFace default_tf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}, NULL,
- 0, 0, TF_DYNAMIC, 0, 0};
+ 0, 0, TF_DYNAMIC, 0, 0};
MTFace *tf = (MTFace*)data;
int i;
@@ -387,7 +383,7 @@ static void layerInterp_origspace_face(void **sources, float *weights,
}
}
-static void layerSwap_origspace_face(void *data, int *corner_indices)
+static void layerSwap_origspace_face(void *data, const int *corner_indices)
{
OrigSpaceFace *osf = data;
float uv[4][2];
@@ -464,7 +460,7 @@ static int mdisp_corners(MDisps *s)
return (s->totdisp % (3*3) == 0)? 3: 4;
}
-static void layerSwap_mdisps(void *data, int *ci)
+static void layerSwap_mdisps(void *data, const int *ci)
{
MDisps *s = data;
float (*d)[3] = NULL;
@@ -485,7 +481,7 @@ static void layerSwap_mdisps(void *data, int *ci)
}
static void layerInterp_mdisps(void **sources, float *weights, float *sub_weights,
- int count, void *dest)
+ int count, void *dest)
{
// XXX
#if 0
@@ -578,7 +574,7 @@ static int layerRead_mdisps(CDataFile *cdf, void *data, int count)
d[i].disps = MEM_callocN(sizeof(float)*3*d[i].totdisp, "mdisps read");
if(!cdf_read_data(cdf, d[i].totdisp*3*sizeof(float), d[i].disps)) {
- printf("failed to read %d/%d %d\n", i, count, d[i].totdisp);
+ printf("failed to read multires displacement %d/%d %d\n", i, count, d[i].totdisp);
return 0;
}
}
@@ -593,7 +589,7 @@ static int layerWrite_mdisps(CDataFile *cdf, void *data, int count)
for(i = 0; i < count; ++i) {
if(!cdf_write_data(cdf, d[i].totdisp*3*sizeof(float), d[i].disps)) {
- printf("failed to write %d/%d %d\n", i, count, d[i].totdisp);
+ printf("failed to write multires displacement %d/%d %d\n", i, count, d[i].totdisp);
return 0;
}
}
@@ -823,7 +819,7 @@ static void layerInterp_mloopuv(void **sources, float *weights,
}
static void layerInterp_mcol(void **sources, float *weights,
- float *sub_weights, int count, void *dest)
+ float *sub_weights, int count, void *dest)
{
MCol *mc = dest;
int i, j, k;
@@ -878,7 +874,7 @@ static void layerInterp_mcol(void **sources, float *weights,
}
}
-static void layerSwap_mcol(void *data, int *corner_indices)
+static void layerSwap_mcol(void *data, const int *corner_indices)
{
MCol *mcol = data;
MCol col[4];
@@ -979,9 +975,7 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
layerSwap_mcol, layerDefault_mcol},
{sizeof(MPoly), "MPoly", 1, "NGon Face", NULL, NULL, NULL, NULL, NULL},
{sizeof(MLoop), "MLoop", 1, "NGon Face-Vertex", NULL, NULL, NULL, NULL, NULL},
- {sizeof(MLoopCol), "MLoopCol", 1, "WeightLoopCol", NULL, NULL, layerInterp_mloopcol, NULL,
- layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol,
- layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol},
+ {sizeof(float)*3, "", 0, "ClothOrco", NULL, NULL, layerInterp_shapekey},
{sizeof(MCol)*4, "MCol", 4, "IDCol", NULL, NULL, layerInterp_mcol,
layerSwap_mcol, layerDefault_mcol},
{sizeof(MCol)*4, "MCol", 4, "TextureCol", NULL, NULL, layerInterp_mcol,
@@ -990,6 +984,9 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(float)*3, "", 0, "ShapeKey", NULL, NULL, layerInterp_shapekey},
{sizeof(float), "", 0, "BevelWeight", NULL, NULL, layerInterp_bweight},
{sizeof(float), "", 0, "SubSurfCrease", NULL, NULL, layerInterp_bweight},
+ {sizeof(MLoopCol), "MLoopCol", 1, "WeightLoopCol", NULL, NULL, layerInterp_mloopcol, NULL,
+ layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol,
+ layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol},
};
const char *LAYERTYPENAMES[CD_NUMTYPES] = {
@@ -997,7 +994,10 @@ const char *LAYERTYPENAMES[CD_NUMTYPES] = {
"CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty",
"CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV",
"CDMloopCol", "CDTangent", "CDMDisps", "CDWeightMCol", "CDMPoly",
- "CDMLoop", "CDMLoopCol", "CDIDCol", "CDTextureCol", "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight", "CDSubSurfCrease"};
+ "CDMLoop", "CDMClothOrco", "CDMLoopCol", "CDIDCol", "CDTextureCol",
+ "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight", "CDSubSurfCrease"
+};
+
const CustomDataMask CD_MASK_BAREMESH =
CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE | CD_MASK_MLOOP | CD_MASK_MPOLY | CD_MASK_BWEIGHT;
@@ -1014,7 +1014,7 @@ const CustomDataMask CD_MASK_EDITMESH =
CD_MASK_MDISPS | CD_MASK_SHAPEKEY;
const CustomDataMask CD_MASK_DERIVEDMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
- CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
+ CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO |
CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_WEIGHT_MLOOPCOL |
CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT |
CD_MASK_WEIGHT_MCOL | CD_MASK_NORMAL;
@@ -1062,11 +1062,11 @@ void customData_update_typemap(CustomData *data)
}
void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
- CustomDataMask mask, int alloctype, int totelem)
+ CustomDataMask mask, int alloctype, int totelem)
{
const LayerTypeInfo *typeInfo;
CustomDataLayer *layer, *newlayer;
- int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0;
+ int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0, lastflag = 0;
for(i = 0; i < source->totlayer; ++i) {
layer = &source->layers[i];
@@ -1081,15 +1081,16 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
lastclone = layer->active_clone;
lastmask = layer->active_mask;
lasttype = type;
+ lastflag = layer->flag;
}
else
number++;
- if(layer->flag & CD_FLAG_NOCOPY) continue;
+ if(lastflag & CD_FLAG_NOCOPY) continue;
else if(!((int)mask & (int)(1 << (int)type))) continue;
else if(number+1 < CustomData_number_of_layers(dest, type)) continue;
- if((alloctype == CD_ASSIGN) && (layer->flag & CD_FLAG_NOFREE))
+ if((alloctype == CD_ASSIGN) && (lastflag & CD_FLAG_NOFREE))
newlayer = customData_add_layer__internal(dest, type, CD_REFERENCE,
layer->data, totelem, layer->name);
else
@@ -1101,6 +1102,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
newlayer->active_rnd = lastrender;
newlayer->active_clone = lastclone;
newlayer->active_mask = lastmask;
+ newlayer->flag |= lastflag & (CD_FLAG_EXTERNAL|CD_FLAG_IN_MEMORY);
}
}
@@ -1108,10 +1110,13 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
}
void CustomData_copy(const struct CustomData *source, struct CustomData *dest,
- CustomDataMask mask, int alloctype, int totelem)
+ CustomDataMask mask, int alloctype, int totelem)
{
memset(dest, 0, sizeof(*dest));
+ if(source->external)
+ dest->external= MEM_dupallocN(source->external);
+
CustomData_merge(source, dest, mask, alloctype, totelem);
}
@@ -1375,7 +1380,7 @@ void CustomData_set_layer_flag(struct CustomData *data, int type, int flag)
static int customData_resize(CustomData *data, int amount)
{
CustomDataLayer *tmp = MEM_callocN(sizeof(*tmp)*(data->maxlayer + amount),
- "CustomData->layers");
+ "CustomData->layers");
if(!tmp) return 0;
data->maxlayer += amount;
@@ -1463,13 +1468,13 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
}
void *CustomData_add_layer(CustomData *data, int type, int alloctype,
- void *layerdata, int totelem)
+ void *layerdata, int totelem)
{
CustomDataLayer *layer;
const LayerTypeInfo *typeInfo= layerType_getInfo(type);
layer = customData_add_layer__internal(data, type, alloctype, layerdata,
- totelem, typeInfo->defaultname);
+ totelem, typeInfo->defaultname);
customData_update_typemap(data);
if(layer)
@@ -1480,12 +1485,12 @@ void *CustomData_add_layer(CustomData *data, int type, int alloctype,
/*same as above but accepts a name*/
void *CustomData_add_layer_named(CustomData *data, int type, int alloctype,
- void *layerdata, int totelem, char *name)
+ void *layerdata, int totelem, char *name)
{
CustomDataLayer *layer;
layer = customData_add_layer__internal(data, type, alloctype, layerdata,
- totelem, name);
+ totelem, name);
customData_update_typemap(data);
if(layer)
@@ -1581,7 +1586,7 @@ void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type)
}
void *CustomData_duplicate_referenced_layer_named(struct CustomData *data,
- int type, char *name)
+ int type, char *name)
{
CustomDataLayer *layer;
int layer_index;
@@ -1626,7 +1631,7 @@ void CustomData_free_temporary(CustomData *data, int totelem)
}
void CustomData_set_only_copy(const struct CustomData *data,
- CustomDataMask mask)
+ CustomDataMask mask)
{
int i;
@@ -1646,7 +1651,7 @@ void CustomData_copy_elements(int type, void *source, void *dest, int count)
}
void CustomData_copy_data(const CustomData *source, CustomData *dest,
- int source_index, int dest_index, int count)
+ int source_index, int dest_index, int count)
{
const LayerTypeInfo *typeInfo;
int src_i, dest_i;
@@ -1661,7 +1666,7 @@ void CustomData_copy_data(const CustomData *source, CustomData *dest,
* (this should work because layers are ordered by type)
*/
while(dest_i < dest->totlayer
- && dest->layers[dest_i].type < source->layers[src_i].type)
+ && dest->layers[dest_i].type < source->layers[src_i].type)
++dest_i;
/* if there are no more dest layers, we're done */
@@ -1679,12 +1684,12 @@ void CustomData_copy_data(const CustomData *source, CustomData *dest,
if(typeInfo->copy)
typeInfo->copy(src_data + src_offset,
- dest_data + dest_offset,
- count);
+ dest_data + dest_offset,
+ count);
else
memcpy(dest_data + dest_offset,
- src_data + src_offset,
- count * typeInfo->size);
+ src_data + src_offset,
+ count * typeInfo->size);
/* if there are multiple source & dest layers of the same type,
* we don't want to copy all source layers to the same dest, so
@@ -1708,7 +1713,7 @@ void CustomData_free_elem(CustomData *data, int index, int count)
int offset = typeInfo->size * index;
typeInfo->free((char *)data->layers[i].data + offset,
- count, typeInfo->size);
+ count, typeInfo->size);
}
}
}
@@ -1717,8 +1722,8 @@ void CustomData_free_elem(CustomData *data, int index, int count)
#define SOURCE_BUF_SIZE 100
void CustomData_interp(const CustomData *source, CustomData *dest,
- int *src_indices, float *weights, float *sub_weights,
- int count, int dest_index)
+ int *src_indices, float *weights, float *sub_weights,
+ int count, int dest_index)
{
int src_i, dest_i;
int dest_offset;
@@ -1731,7 +1736,7 @@ void CustomData_interp(const CustomData *source, CustomData *dest,
*/
if(count > SOURCE_BUF_SIZE)
sources = MEM_callocN(sizeof(*sources) * count,
- "CustomData_interp sources");
+ "CustomData_interp sources");
/* interpolates a layer at a time */
dest_i = 0;
@@ -1743,7 +1748,7 @@ void CustomData_interp(const CustomData *source, CustomData *dest,
* (this should work because layers are ordered by type)
*/
while(dest_i < dest->totlayer
- && dest->layers[dest_i].type < source->layers[src_i].type)
+ && dest->layers[dest_i].type < source->layers[src_i].type)
++dest_i;
/* if there are no more dest layers, we're done */
@@ -1773,7 +1778,7 @@ void CustomData_interp(const CustomData *source, CustomData *dest,
if(count > SOURCE_BUF_SIZE) MEM_freeN(sources);
}
-void CustomData_swap(struct CustomData *data, int index, int *corner_indices)
+void CustomData_swap(struct CustomData *data, int index, const int *corner_indices)
{
const LayerTypeInfo *typeInfo;
int i;
@@ -1836,7 +1841,7 @@ void *CustomData_get_layer_n(const CustomData *data, int type, int n)
}
void *CustomData_get_layer_named(const struct CustomData *data, int type,
- char *name)
+ char *name)
{
int layer_index = CustomData_get_named_layer_index(data, type, name);
if(layer_index < 0) return NULL;
@@ -1884,21 +1889,21 @@ void CustomData_set(const CustomData *data, int index, int type, void *source)
void CustomData_em_free_block(CustomData *data, void **block)
{
- const LayerTypeInfo *typeInfo;
- int i;
+ const LayerTypeInfo *typeInfo;
+ int i;
if(!*block) return;
- for(i = 0; i < data->totlayer; ++i) {
- if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
- typeInfo = layerType_getInfo(data->layers[i].type);
+ for(i = 0; i < data->totlayer; ++i) {
+ if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
+ typeInfo = layerType_getInfo(data->layers[i].type);
- if(typeInfo->free) {
+ if(typeInfo->free) {
int offset = data->layers[i].offset;
- typeInfo->free((char*)*block + offset, 1, typeInfo->size);
+ typeInfo->free((char*)*block + offset, 1, typeInfo->size);
}
- }
- }
+ }
+ }
MEM_freeN(*block);
*block = NULL;
@@ -1918,7 +1923,7 @@ static void CustomData_em_alloc_block(CustomData *data, void **block)
}
void CustomData_em_copy_data(const CustomData *source, CustomData *dest,
- void *src_block, void **dest_block)
+ void *src_block, void **dest_block)
{
const LayerTypeInfo *typeInfo;
int dest_i, src_i;
@@ -1934,7 +1939,7 @@ void CustomData_em_copy_data(const CustomData *source, CustomData *dest,
* (this should work because layers are ordered by type)
*/
while(dest_i < dest->totlayer
- && dest->layers[dest_i].type < source->layers[src_i].type)
+ && dest->layers[dest_i].type < source->layers[src_i].type)
++dest_i;
/* if there are no more dest layers, we're done */
@@ -2011,7 +2016,7 @@ void CustomData_em_set_n(CustomData *data, void *block, int type, int n, void *s
}
void CustomData_em_interp(CustomData *data, void **src_blocks, float *weights,
- float *sub_weights, int count, void *dest_block)
+ float *sub_weights, int count, void *dest_block)
{
int i, j;
void *source_buf[SOURCE_BUF_SIZE];
@@ -2022,7 +2027,7 @@ void CustomData_em_interp(CustomData *data, void **src_blocks, float *weights,
*/
if(count > SOURCE_BUF_SIZE)
sources = MEM_callocN(sizeof(*sources) * count,
- "CustomData_interp sources");
+ "CustomData_interp sources");
/* interpolates a layer at a time */
for(i = 0; i < data->totlayer; ++i) {
@@ -2034,7 +2039,7 @@ void CustomData_em_interp(CustomData *data, void **src_blocks, float *weights,
sources[j] = (char *)src_blocks[j] + layer->offset;
typeInfo->interp(sources, weights, sub_weights, count,
- (char *)dest_block + layer->offset);
+ (char *)dest_block + layer->offset);
}
}
@@ -2060,7 +2065,7 @@ void CustomData_em_set_default(CustomData *data, void **block)
}
void CustomData_to_em_block(const CustomData *source, CustomData *dest,
- int src_index, void **dest_block)
+ int src_index, void **dest_block)
{
const LayerTypeInfo *typeInfo;
int dest_i, src_i, src_offset;
@@ -2076,7 +2081,7 @@ void CustomData_to_em_block(const CustomData *source, CustomData *dest,
* (this should work because layers are ordered by type)
*/
while(dest_i < dest->totlayer
- && dest->layers[dest_i].type < source->layers[src_i].type)
+ && dest->layers[dest_i].type < source->layers[src_i].type)
++dest_i;
/* if there are no more dest layers, we're done */
@@ -2106,7 +2111,7 @@ void CustomData_to_em_block(const CustomData *source, CustomData *dest,
}
void CustomData_from_em_block(const CustomData *source, CustomData *dest,
- void *src_block, int dest_index)
+ void *src_block, int dest_index)
{
const LayerTypeInfo *typeInfo;
int dest_i, src_i, dest_offset;
@@ -2119,7 +2124,7 @@ void CustomData_from_em_block(const CustomData *source, CustomData *dest,
* (this should work because layers are ordered by type)
*/
while(dest_i < dest->totlayer
- && dest->layers[dest_i].type < source->layers[src_i].type)
+ && dest->layers[dest_i].type < source->layers[src_i].type)
++dest_i;
/* if there are no more dest layers, we're done */
@@ -2233,20 +2238,20 @@ void CustomData_bmesh_merge(CustomData *source, CustomData *dest,
void CustomData_bmesh_free_block(CustomData *data, void **block)
{
- const LayerTypeInfo *typeInfo;
- int i;
+ const LayerTypeInfo *typeInfo;
+ int i;
if(!*block) return;
- for(i = 0; i < data->totlayer; ++i) {
- if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
- typeInfo = layerType_getInfo(data->layers[i].type);
+ for(i = 0; i < data->totlayer; ++i) {
+ if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
+ typeInfo = layerType_getInfo(data->layers[i].type);
- if(typeInfo->free) {
+ if(typeInfo->free) {
int offset = data->layers[i].offset;
typeInfo->free((char*)*block + offset, 1, typeInfo->size);
}
- }
- }
+ }
+ }
if (data->totsize)
BLI_mempool_free(data->pool, *block);
@@ -2267,7 +2272,7 @@ static void CustomData_bmesh_alloc_block(CustomData *data, void **block)
}
void CustomData_bmesh_copy_data(const CustomData *source, CustomData *dest,
- void *src_block, void **dest_block)
+ void *src_block, void **dest_block)
{
const LayerTypeInfo *typeInfo;
int dest_i, src_i;
@@ -2283,7 +2288,7 @@ void CustomData_bmesh_copy_data(const CustomData *source, CustomData *dest,
* (this should work because layers are ordered by type)
*/
while(dest_i < dest->totlayer
- && dest->layers[dest_i].type < source->layers[src_i].type)
+ && dest->layers[dest_i].type < source->layers[src_i].type)
++dest_i;
/* if there are no more dest layers, we're done */
@@ -2450,7 +2455,7 @@ void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, void *so
}
void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights,
- float *sub_weights, int count, void *dest_block)
+ float *sub_weights, int count, void *dest_block)
{
int i, j;
void *source_buf[SOURCE_BUF_SIZE];
@@ -2461,7 +2466,7 @@ void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights
*/
if(count > SOURCE_BUF_SIZE)
sources = MEM_callocN(sizeof(*sources) * count,
- "CustomData_interp sources");
+ "CustomData_interp sources");
/* interpolates a layer at a time */
for(i = 0; i < data->totlayer; ++i) {
@@ -2472,7 +2477,7 @@ void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights
sources[j] = (char *)src_blocks[j] + layer->offset;
typeInfo->interp(sources, weights, sub_weights, count,
- (char *)dest_block + layer->offset);
+ (char *)dest_block + layer->offset);
}
}
@@ -2499,7 +2504,7 @@ void CustomData_bmesh_set_default(CustomData *data, void **block)
}
void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
- int src_index, void **dest_block)
+ int src_index, void **dest_block)
{
const LayerTypeInfo *typeInfo;
int dest_i, src_i, src_offset;
@@ -2515,7 +2520,7 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
* (this should work because layers are ordered by type)
*/
while(dest_i < dest->totlayer
- && dest->layers[dest_i].type < source->layers[src_i].type)
+ && dest->layers[dest_i].type < source->layers[src_i].type)
++dest_i;
/* if there are no more dest layers, we're done */
@@ -2545,7 +2550,7 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
}
void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest,
- void *src_block, int dest_index)
+ void *src_block, int dest_index)
{
const LayerTypeInfo *typeInfo;
int dest_i, src_i, dest_offset;
@@ -2558,7 +2563,7 @@ void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest,
* (this should work because layers are ordered by type)
*/
while(dest_i < dest->totlayer
- && dest->layers[dest_i].type < source->layers[src_i].type)
+ && dest->layers[dest_i].type < source->layers[src_i].type)
++dest_i;
/* if there are no more dest layers, we're done */
@@ -2698,8 +2703,8 @@ int CustomData_verify_versions(struct CustomData *data, int index)
}
if (!keeplayer) {
- for (i=index+1; i < data->totlayer; ++i)
- data->layers[i-1] = data->layers[i];
+ for (i=index+1; i < data->totlayer; ++i)
+ data->layers[i-1] = data->layers[i];
data->totlayer--;
}
@@ -2710,10 +2715,29 @@ int CustomData_verify_versions(struct CustomData *data, int index)
static void customdata_external_filename(char filename[FILE_MAX], ID *id, CustomDataExternal *external)
{
- char *path = (id->lib)? id->lib->filename: G.sce;
+ char *path = (id->lib)? id->lib->filepath: G.sce;
BLI_strncpy(filename, external->filename, FILE_MAX);
- BLI_convertstringcode(filename, path);
+ BLI_path_abs(filename, path);
+}
+
+void CustomData_external_reload(CustomData *data, ID *id, CustomDataMask mask, int totelem)
+{
+ CustomDataLayer *layer;
+ const LayerTypeInfo *typeInfo;
+ int i;
+
+ for(i=0; i<data->totlayer; i++) {
+ layer = &data->layers[i];
+ typeInfo = layerType_getInfo(layer->type);
+
+ if(!(mask & (1<<layer->type)));
+ else if((layer->flag & CD_FLAG_EXTERNAL) && (layer->flag & CD_FLAG_IN_MEMORY)) {
+ if(typeInfo->free)
+ typeInfo->free(layer->data, totelem, typeInfo->size);
+ layer->flag &= ~CD_FLAG_IN_MEMORY;
+ }
+ }
}
void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int totelem)
@@ -2883,9 +2907,9 @@ void CustomData_external_add(CustomData *data, ID *id, int type, int totelem, co
if(!external) {
external= MEM_callocN(sizeof(CustomDataExternal), "CustomDataExternal");
- BLI_strncpy(external->filename, filename, sizeof(external->filename));
data->external= external;
}
+ BLI_strncpy(external->filename, filename, sizeof(external->filename));
layer->flag |= CD_FLAG_EXTERNAL|CD_FLAG_IN_MEMORY;
}
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 06b5ba84433..1ab0cb8d29d 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -38,35 +38,14 @@
#include "MEM_guardedalloc.h"
-#include "DNA_curve_types.h"
-#include "DNA_effect_types.h"
-#include "DNA_lattice_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "DNA_object_force.h"
-#include "DNA_scene_types.h"
-#include "BKE_curve.h"
#include "BKE_deform.h"
-#include "BKE_displist.h"
-#include "BKE_effect.h"
-#include "BKE_global.h"
-#include "BKE_key.h"
-#include "BKE_lattice.h"
-#include "BKE_object.h"
-#include "BKE_softbody.h"
-#include "BKE_utildefines.h"
-#include "BKE_mesh.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_cellalloc.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
void defgroup_copy_list (ListBase *outbase, ListBase *inbase)
{
@@ -223,7 +202,7 @@ int defgroup_name_index (Object *ob, const char *name)
bDeformGroup *curdef;
int def_nr;
- if(name[0] != '\0') {
+ if(name && name[0] != '\0') {
for (curdef=ob->defbase.first, def_nr=0; curdef; curdef=curdef->next, def_nr++) {
if (!strcmp(curdef->name, name))
return def_nr;
@@ -386,10 +365,10 @@ void defgroup_unique_name (bDeformGroup *dg, Object *ob)
void flip_side_name (char *name, const char *from_name, int strip_number)
{
int len;
- char prefix[sizeof((bDeformGroup *)NULL)->name]={""}; /* The part before the facing */
- char suffix[sizeof((bDeformGroup *)NULL)->name]={""}; /* The part after the facing */
- char replace[sizeof((bDeformGroup *)NULL)->name]={""}; /* The replacement string */
- char number[sizeof((bDeformGroup *)NULL)->name]={""}; /* The number extension string */
+ char prefix[sizeof(((bDeformGroup *)NULL)->name)]= {""}; /* The part before the facing */
+ char suffix[sizeof(((bDeformGroup *)NULL)->name)]= {""}; /* The part after the facing */
+ char replace[sizeof(((bDeformGroup *)NULL)->name)]= {""}; /* The replacement string */
+ char number[sizeof(((bDeformGroup *)NULL)->name)]= {""}; /* The number extension string */
char *index=NULL;
len= strlen(from_name);
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 0c9248c1eb9..142f80a350e 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -29,35 +29,16 @@
#include <string.h>
#include <math.h>
-#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_winstuff.h"
#include "DNA_anim_types.h"
-#include "DNA_action_types.h"
-#include "DNA_armature_types.h"
-#include "DNA_boid_types.h"
-#include "DNA_curve_types.h"
#include "DNA_camera_types.h"
-#include "DNA_ID.h"
-#include "DNA_effect_types.h"
#include "DNA_group_types.h"
#include "DNA_lattice_types.h"
-#include "DNA_lamp_types.h"
#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_nla_types.h"
-#include "DNA_object_types.h"
-#include "DNA_object_force.h"
-#include "DNA_object_fluidsim.h"
-#include "DNA_outliner_types.h"
-#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
-#include "DNA_view2d_types.h"
-#include "DNA_view3d_types.h"
#include "DNA_windowmanager_types.h"
#include "BLI_ghash.h"
@@ -75,7 +56,6 @@
#include "BKE_object.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
-#include "BKE_utildefines.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
@@ -488,11 +468,6 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
addtoroot = 0;
}
- if (ob->track) {
- node2 = dag_get_node(dag,ob->track);
- dag_add_relation(dag,node2,node,DAG_RL_OB_OB, "Track To");
- addtoroot = 0;
- }
if (ob->proxy) {
node2 = dag_get_node(dag, ob->proxy);
dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA|DAG_RL_OB_OB, "Proxy");
@@ -828,7 +803,7 @@ DagNode * dag_add_node (DagForest *forest, void * fob)
}
if(!forest->nodeHash)
- forest->nodeHash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+ forest->nodeHash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "dag_add_node gh");
BLI_ghash_insert(forest->nodeHash, fob, node);
}
@@ -971,7 +946,7 @@ static void dag_node_print_dependency_cycle(DagForest *dag, DagNode *startnode,
{
DagNode *node;
- for(node = dag->DagNode.first; node; node= node->next)
+ for(node = dag->DagNode.first; node; node= node->next)
node->color= DAG_WHITE;
printf(" %s depends on %s through %s.\n", dag_node_name(endnode), dag_node_name(startnode), name);
@@ -1553,7 +1528,7 @@ int is_acyclic( DagForest *dag) {
void set_node_xy(DagNode *node, float x, float y)
{
- node->x = x;
+ node->x = x;
node->y = y;
}
@@ -1779,8 +1754,8 @@ static void flush_update_node(DagNode *node, unsigned int layer, int curtime)
node->lasttime= curtime;
ob= node->ob;
- if(ob && (ob->recalc & OB_RECALC)) {
- all_layer= ob->lay;
+ if(ob && (ob->recalc & OB_RECALC_ALL)) {
+ all_layer= node->scelay;
/* got an object node that changes, now check relations */
for(itA = node->child; itA; itA= itA->next) {
@@ -1822,7 +1797,7 @@ static void flush_update_node(DagNode *node, unsigned int layer, int curtime)
if(ob->recalc & OB_RECALC_DATA)
object_free_display(ob);
- ob->recalc &= ~OB_RECALC;
+ ob->recalc &= ~OB_RECALC_ALL;
}
}
@@ -1835,7 +1810,7 @@ static void flush_update_node(DagNode *node, unsigned int layer, int curtime)
if(itA->node->type==ID_OB) {
obc= itA->node->ob;
/* child moves */
- if((obc->recalc & OB_RECALC)==OB_RECALC_OB) {
+ if((obc->recalc & OB_RECALC_ALL)==OB_RECALC_OB) {
/* parent has deforming info */
if(itA->type & (DAG_RL_OB_DATA|DAG_RL_DATA_DATA)) {
// printf("parent %s changes ob %s\n", ob->id.name, obc->id.name);
@@ -1889,7 +1864,7 @@ static void flush_pointcache_reset(Scene *scene, DagNode *node, int curtime, int
if(itA->node->lasttime!=curtime) {
ob= (Object*)(node->ob);
- if(reset || (ob->recalc & OB_RECALC)) {
+ if(reset || (ob->recalc & OB_RECALC_ALL)) {
if(BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH))
ob->recalc |= OB_RECALC_DATA;
@@ -1902,42 +1877,72 @@ static void flush_pointcache_reset(Scene *scene, DagNode *node, int curtime, int
}
}
-/* flushes all recalc flags in objects down the dependency tree */
-void DAG_scene_flush_update(Scene *sce, unsigned int lay, int time)
+/* flush layer flags to dependencies */
+static void dag_scene_flush_layers(Scene *sce, int lay)
{
- DagNode *firstnode, *node;
+ DagNode *node, *firstnode;
DagAdjList *itA;
- Object *ob;
Base *base;
int lasttime;
-
- if(sce->theDag==NULL) {
- printf("DAG zero... not allowed to happen!\n");
- DAG_scene_sort(sce);
- }
-
+
firstnode= sce->theDag->DagNode.first; // always scene node
for(itA = firstnode->child; itA; itA= itA->next)
itA->lay= 0;
-
- /* first we flush the layer flags */
+
sce->theDag->time++; // so we know which nodes were accessed
lasttime= sce->theDag->time;
-
+ /* update layer flags in nodes */
for(base= sce->base.first; base; base= base->next) {
node= dag_get_node(sce->theDag, base->object);
- if(node)
- node->scelay= base->object->lay;
- else
- node->scelay= 0;
+ node->scelay= base->object->lay;
+ }
+
+ /* ensure cameras are set as if they are on a visible layer, because
+ they ared still used for rendering or setting the camera view */
+ if(sce->camera) {
+ node= dag_get_node(sce->theDag, sce->camera);
+ node->scelay |= lay;
+ }
+
+#ifdef DURIAN_CAMERA_SWITCH
+ {
+ TimeMarker *m;
+
+ for(m= sce->markers.first; m; m= m->next) {
+ if(m->camera) {
+ node= dag_get_node(sce->theDag, m->camera);
+ node->scelay |= lay;
+ }
+ }
}
+#endif
+ /* flush layer nodes to dependencies */
for(itA = firstnode->child; itA; itA= itA->next)
if(itA->node->lasttime!=lasttime && itA->node->type==ID_OB)
flush_layer_node(sce, itA->node, lasttime);
+}
+
+/* flushes all recalc flags in objects down the dependency tree */
+void DAG_scene_flush_update(Scene *sce, unsigned int lay, int time)
+{
+ DagNode *firstnode;
+ DagAdjList *itA;
+ Object *ob;
+ int lasttime;
+
+ if(sce->theDag==NULL) {
+ printf("DAG zero... not allowed to happen!\n");
+ DAG_scene_sort(sce);
+ }
+ firstnode= sce->theDag->DagNode.first; // always scene node
+
+ /* first we flush the layer flags */
+ dag_scene_flush_layers(sce, lay);
+
/* then we use the relationships + layer info to flush update events */
sce->theDag->time++; // so we know which nodes were accessed
lasttime= sce->theDag->time;
@@ -1953,7 +1958,7 @@ void DAG_scene_flush_update(Scene *sce, unsigned int lay, int time)
if(itA->node->lasttime!=lasttime && itA->node->type==ID_OB) {
ob= (Object*)(itA->node->ob);
- if(ob->recalc & OB_RECALC) {
+ if(ob->recalc & OB_RECALC_ALL) {
if(BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH))
ob->recalc |= OB_RECALC_DATA;
@@ -1969,11 +1974,30 @@ void DAG_scene_flush_update(Scene *sce, unsigned int lay, int time)
static int object_modifiers_use_time(Object *ob)
{
ModifierData *md;
-
+
+ /* check if a modifier in modifier stack needs time input */
for (md=ob->modifiers.first; md; md=md->next)
if (modifier_dependsOnTime(md))
return 1;
-
+
+ /* check whether any modifiers are animated */
+ if (ob->adt) {
+ AnimData *adt = ob->adt;
+
+ /* action - check for F-Curves with paths containing 'modifiers[' */
+ if (adt->action) {
+ FCurve *fcu;
+
+ for (fcu = adt->action->curves.first; fcu; fcu = fcu->next) {
+ if (fcu->rna_path && strstr(fcu->rna_path, "modifiers["))
+ return 1;
+ }
+ }
+
+ // XXX: also, should check NLA strips, though for now assume that nobody uses
+ // that and we can omit that for performance reasons...
+ }
+
return 0;
}
@@ -2033,14 +2057,14 @@ static void dag_object_time_update_flags(Object *ob)
/* this case is for groups with nla, whilst nla target has no action or nla */
for(strip= ob->nlastrips.first; strip; strip= strip->next) {
if(strip->object)
- strip->object->recalc |= OB_RECALC;
+ strip->object->recalc |= OB_RECALC_ALL;
}
}
}
#endif // XXX old animation system
if(animdata_use_time(ob->adt)) {
- ob->recalc |= OB_RECALC;
+ ob->recalc |= OB_RECALC_OB;
ob->adt->recalc |= ADT_RECALC_ANIM;
}
@@ -2193,7 +2217,7 @@ static void dag_current_scene_layers(Main *bmain, Scene **sce, unsigned int *lay
*sce= bmain->scene.first;
if(*sce) *lay= (*sce)->lay;
- /* XXX for background mode, we should get the scen
+ /* XXX for background mode, we should get the scene
from somewhere, for the -S option, but it's in
the context, how to get it here? */
}
@@ -2219,19 +2243,24 @@ void DAG_on_load_update(void)
Object *ob;
Group *group;
GroupObject *go;
- unsigned int lay;
+ DagNode *node;
+ unsigned int lay, oblay;
dag_current_scene_layers(bmain, &scene, &lay);
- if(scene) {
+ if(scene && scene->theDag) {
/* derivedmeshes and displists are not saved to file so need to be
remade, tag them so they get remade in the scene update loop,
note armature poses or object matrices are preserved and do not
require updates, so we skip those */
+ dag_scene_flush_layers(scene, lay);
+
for(SETLOOPER(scene, base)) {
ob= base->object;
+ node= (sce->theDag)? dag_get_node(sce->theDag, ob): NULL;
+ oblay= (node)? node->lay: ob->lay;
- if(base->lay & lay) {
+ if(oblay & lay) {
if(ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL))
ob->recalc |= OB_RECALC_DATA;
if(ob->dup_group)
@@ -2244,6 +2273,8 @@ void DAG_on_load_update(void)
for(go= group->gobject.first; go; go= go->next) {
if(ELEM5(go->ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL))
go->ob->recalc |= OB_RECALC_DATA;
+ if(go->ob->proxy_from)
+ go->ob->recalc |= OB_RECALC_OB;
}
group->id.flag &= ~LIB_DOIT;
@@ -2255,6 +2286,16 @@ void DAG_on_load_update(void)
}
}
+static void dag_id_flush_update__isDependentTexture(void *userData, Object *ob, ID **idpoin)
+{
+ struct { ID *id; int is_dependent; } *data = userData;
+
+ if(*idpoin && GS((*idpoin)->name)==ID_TE) {
+ if (data->id == (*idpoin))
+ data->is_dependent = 1;
+ }
+}
+
void DAG_id_flush_update(ID *id, short flag)
{
Main *bmain= G.main;
@@ -2271,7 +2312,7 @@ void DAG_id_flush_update(ID *id, short flag)
/* set flags & pointcache for object */
if(GS(id->name) == ID_OB) {
ob= (Object*)id;
- ob->recalc |= (flag & OB_RECALC);
+ ob->recalc |= (flag & OB_RECALC_ALL);
BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH);
if(flag & OB_RECALC_DATA) {
@@ -2279,15 +2320,10 @@ void DAG_id_flush_update(ID *id, short flag)
id= ob->data;
/* no point in trying in this cases */
- if(!id || id->us <= 1)
- id= NULL;
- /* curves and surfaces only need to mark one object, since
- otherwise cu->displist would be computed multiple times */
- else if(ob->type==OB_CURVE || ob->type==OB_SURF)
- id= NULL;
- /* also for locked shape keys we make an exception */
- else if(ob_get_key(ob) && (ob->shapeflag & OB_SHAPE_LOCK))
+ if(id && id->us <= 1) {
+ dag_editors_update(bmain, id);
id= NULL;
+ }
}
}
@@ -2296,25 +2332,44 @@ void DAG_id_flush_update(ID *id, short flag)
idtype= GS(id->name);
if(ELEM7(idtype, ID_ME, ID_CU, ID_MB, ID_LA, ID_LT, ID_CA, ID_AR)) {
+ int first_ob= 1;
for(obt=bmain->object.first; obt; obt= obt->id.next) {
if(!(ob && obt == ob) && obt->data == id) {
+
+ /* try to avoid displist recalculation for linked curves */
+ if (!first_ob && ELEM(obt->type, OB_CURVE, OB_SURF)) {
+ /* if curve object has got derivedFinal it means this
+ object has got constructive modifiers and object
+ should be recalculated anyhow */
+ if (!obt->derivedFinal)
+ continue;
+ }
+
obt->recalc |= OB_RECALC_DATA;
BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
- /* for these we only flag one object, otherwise cu->displist
- would be computed multiple times */
- if(obt->type==OB_CURVE || obt->type==OB_SURF)
- break;
+ first_ob= 0;
}
}
}
+ /* set flags based on textures - can influence depgraph via modifiers */
+ if(idtype == ID_TE) {
+ for(obt=bmain->object.first; obt; obt= obt->id.next) {
+ struct { ID *id; int is_dependent; } data = {id, 0};
+
+ modifiers_foreachIDLink(obt, dag_id_flush_update__isDependentTexture, &data);
+ if (data.is_dependent)
+ obt->recalc |= OB_RECALC_DATA;
+ }
+ }
+
/* set flags based on ShapeKey */
if(idtype == ID_KE) {
for(obt=bmain->object.first; obt; obt= obt->id.next) {
Key *key= ob_get_key(obt);
if(!(ob && obt == ob) && ((ID *)key == id)) {
- obt->flag |= (OB_RECALC|OB_RECALC_DATA);
+ obt->flag |= (OB_RECALC_OB|OB_RECALC_DATA);
BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
}
}
@@ -2327,7 +2382,7 @@ void DAG_id_flush_update(ID *id, short flag)
for(psys=obt->particlesystem.first; psys; psys=psys->next) {
if(&psys->part->id == id) {
BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
- obt->recalc |= (flag & OB_RECALC);
+ obt->recalc |= (flag & OB_RECALC_ALL);
psys->recalc |= (flag & PSYS_RECALC);
}
}
@@ -2407,7 +2462,7 @@ void DAG_id_update_flags(ID *id)
GroupObject *go;
/* primitive; tag all... this call helps building groups for particles */
for(go= group->gobject.first; go; go= go->next)
- go->ob->recalc= OB_RECALC;
+ go->ob->recalc= OB_RECALC_ALL;
}
}
else {
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index c1fcf4f13f4..15e561cfc45 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -35,54 +35,28 @@
#include "MEM_guardedalloc.h"
-#include "IMB_imbuf_types.h"
-#include "DNA_texture_types.h"
-#include "DNA_meta_types.h"
#include "DNA_curve_types.h"
-#include "DNA_effect_types.h"
-#include "DNA_listBase.h"
-#include "DNA_lamp_types.h"
-#include "DNA_object_types.h"
-#include "DNA_object_force.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
#include "DNA_scene_types.h"
-#include "DNA_image_types.h"
#include "DNA_material_types.h"
-#include "DNA_view3d_types.h"
-#include "DNA_lattice_types.h"
-#include "DNA_key_types.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_editVert.h"
-#include "BLI_edgehash.h"
-#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BKE_displist.h"
-#include "BKE_deform.h"
-#include "BKE_DerivedMesh.h"
+#include "BKE_cdderivedmesh.h"
#include "BKE_object.h"
-#include "BKE_world.h"
-#include "BKE_mesh.h"
-#include "BKE_effect.h"
#include "BKE_mball.h"
#include "BKE_material.h"
#include "BKE_curve.h"
#include "BKE_key.h"
#include "BKE_anim.h"
-#include "BKE_screen.h"
-#include "BKE_texture.h"
-#include "BKE_library.h"
#include "BKE_font.h"
#include "BKE_lattice.h"
-#include "BKE_scene.h"
-#include "BKE_subsurf.h"
#include "BKE_modifier.h"
-#include "BKE_customdata.h"
#include "RE_pipeline.h"
#include "RE_shader_ext.h"
@@ -222,10 +196,10 @@ void addnormalsDispList(Object *ob, ListBase *lb)
normal_quad_v3( nor,v1, v3, v4, v2);
- add_v3_v3v3(n1, n1, nor);
- add_v3_v3v3(n2, n2, nor);
- add_v3_v3v3(n3, n3, nor);
- add_v3_v3v3(n4, n4, nor);
+ add_v3_v3(n1, nor);
+ add_v3_v3(n2, nor);
+ add_v3_v3(n3, nor);
+ add_v3_v3(n4, nor);
v2= v1; v1+= 3;
v4= v3; v3+= 3;
@@ -321,9 +295,9 @@ static Render *fastshade_get_render(Scene *scene)
/* XXX ugly global still, but we can't do preview while rendering */
if(G.rendering==0) {
- Render *re= RE_GetRender("_Shade View_", RE_SLOT_DEFAULT);
+ Render *re= RE_GetRender("_Shade View_");
if(re==NULL) {
- re= RE_NewRender("_Shade View_", RE_SLOT_DEFAULT);
+ re= RE_NewRender("_Shade View_");
RE_Database_Baking(re, scene, 0, 0); /* 0= no faces */
}
@@ -337,7 +311,7 @@ static Render *fastshade_get_render(Scene *scene)
/* called on file reading */
void fastshade_free_render(void)
{
- Render *re= RE_GetRender("_Shade View_", RE_SLOT_DEFAULT);
+ Render *re= RE_GetRender("_Shade View_");
if(re) {
RE_Database_Free(re);
@@ -516,7 +490,7 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un
float *orco, *vnors, *nors, imat[3][3], mat[4][4], vec[3];
int a, i, need_orco, totface, totvert;
CustomDataMask dataMask = CD_MASK_BAREMESH | CD_MASK_MCOL
- | CD_MASK_MTFACE | CD_MASK_NORMAL;
+ | CD_MASK_MTFACE | CD_MASK_NORMAL;
init_fastshade_for_ob(re, ob, &need_orco, mat, imat);
@@ -601,9 +575,9 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un
char *col1= (char*)&col1base[j*4];
char *col2= (char*)(col2base?&col2base[j*4]:NULL);
float *vn = (mf->flag & ME_SMOOTH)?&vnors[3*vidx[j]]:n1;
-
- VECCOPY(vec, mv->co);
- mul_m4_v3(mat, vec);
+
+ mul_v3_m4v3(vec, mat, mv->co);
+
vec[0]+= 0.001*vn[0];
vec[1]+= 0.001*vn[1];
vec[2]+= 0.001*vn[2];
@@ -714,8 +688,7 @@ void shadeDispList(Scene *scene, Base *base)
a= dl->nr;
while(a--) {
- VECCOPY(vec, fp);
- mul_m4_v3(mat, vec);
+ mul_v3_m4v3(vec, mat, fp);
fastshade(vec, n1, fp, ma, (char *)col1, NULL);
@@ -730,8 +703,7 @@ void shadeDispList(Scene *scene, Base *base)
nor= dl->nors;
while(a--) {
- VECCOPY(vec, fp);
- mul_m4_v3(mat, vec);
+ mul_v3_m4v3(vec, mat, fp);
n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
@@ -768,8 +740,7 @@ void shadeDispList(Scene *scene, Base *base)
a= dl->nr;
while(a--) {
- VECCOPY(vec, fp);
- mul_m4_v3(mat, vec);
+ mul_v3_m4v3(vec, mat, fp);
/* transpose ! */
n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
@@ -839,17 +810,17 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
/* count */
len= 0;
a= nu->pntsu-1;
- if(nu->flagu & CU_CYCLIC) a++;
+ if(nu->flagu & CU_NURB_CYCLIC) a++;
prevbezt= nu->bezt;
bezt= prevbezt+1;
while(a--) {
- if(a==0 && (nu->flagu & CU_CYCLIC)) bezt= nu->bezt;
+ if(a==0 && (nu->flagu & CU_NURB_CYCLIC)) bezt= nu->bezt;
if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) len++;
else len+= resolu;
- if(a==0 && (nu->flagu & CU_CYCLIC)==0) len++;
+ if(a==0 && (nu->flagu & CU_NURB_CYCLIC)==0) len++;
prevbezt= bezt;
bezt++;
@@ -866,7 +837,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
data= dl->verts;
- if(nu->flagu & CU_CYCLIC) {
+ if(nu->flagu & CU_NURB_CYCLIC) {
dl->type= DL_POLY;
a= nu->pntsu;
}
@@ -919,9 +890,9 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
dl->charidx = nu->charidx;
data= dl->verts;
- if(nu->flagu & CU_CYCLIC) dl->type= DL_POLY;
+ if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY;
else dl->type= DL_SEGM;
- makeNurbcurve(nu, data, NULL, NULL, resolu, 3*sizeof(float));
+ makeNurbcurve(nu, data, NULL, NULL, NULL, resolu, 3*sizeof(float));
}
else if(nu->type == CU_POLY) {
len= nu->pntsu;
@@ -934,7 +905,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
dl->charidx = nu->charidx;
data= dl->verts;
- if(nu->flagu & CU_CYCLIC) dl->type= DL_POLY;
+ if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY;
else dl->type= DL_SEGM;
a= len;
@@ -951,7 +922,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
}
-void filldisplist(ListBase *dispbase, ListBase *to)
+void filldisplist(ListBase *dispbase, ListBase *to, int flipnormal)
{
EditVert *eve, *v1, *vlast;
EditFace *efa;
@@ -1045,6 +1016,9 @@ void filldisplist(ListBase *dispbase, ListBase *to)
index[0]= (intptr_t)efa->v1->tmp.l;
index[1]= (intptr_t)efa->v2->tmp.l;
index[2]= (intptr_t)efa->v3->tmp.l;
+
+ if(flipnormal)
+ SWAP(int, index[0], index[2]);
index+= 3;
efa= efa->next;
@@ -1121,13 +1095,13 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase)
dl= dl->next;
}
- filldisplist(&front, dispbase);
- filldisplist(&back, dispbase);
+ filldisplist(&front, dispbase, 1);
+ filldisplist(&back, dispbase, 0);
freedisplist(&front);
freedisplist(&back);
- filldisplist(dispbase, dispbase);
+ filldisplist(dispbase, dispbase, 0);
}
@@ -1139,7 +1113,7 @@ static void curve_to_filledpoly(Curve *cu, ListBase *nurb, ListBase *dispbase)
bevels_to_filledpoly(cu, dispbase);
}
else {
- filldisplist(dispbase, dispbase);
+ filldisplist(dispbase, dispbase, 0);
}
}
@@ -1195,21 +1169,31 @@ void makeDispListMBall(Scene *scene, Object *ob)
{
if(!ob || ob->type!=OB_MBALL) return;
+ // XXX: mball stuff uses plenty of global variables
+ // while this is unchanged updating during render is unsafe
+ if(G.rendering) return;
+
freedisplist(&(ob->disp));
-
+
if(ob->type==OB_MBALL) {
if(ob==find_basis_mball(scene, ob)) {
- metaball_polygonize(scene, ob);
+ metaball_polygonize(scene, ob, &ob->disp);
tex_space_mball(ob);
- object_deform_mball(ob);
+ object_deform_mball(ob, &ob->disp);
}
}
boundbox_displist(ob);
}
-static ModifierData *curve_get_tesselate_point(Object *ob, int forRender, int editmode)
+void makeDispListMBall_forRender(Scene *scene, Object *ob, ListBase *dispbase)
+{
+ metaball_polygonize(scene, ob, dispbase);
+ object_deform_mball(ob, dispbase);
+}
+
+static ModifierData *curve_get_tesselate_point(Scene *scene, Object *ob, int forRender, int editmode)
{
ModifierData *md = modifiers_getVirtualModifierList(ob);
ModifierData *preTesselatePoint;
@@ -1222,10 +1206,7 @@ static ModifierData *curve_get_tesselate_point(Object *ob, int forRender, int ed
preTesselatePoint = NULL;
for (; md; md=md->next) {
- ModifierTypeInfo *mti = modifierType_getInfo(md->type);
-
- if ((md->mode & required_mode) != required_mode) continue;
- if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
+ if (!modifier_isEnabled(scene, md, required_mode)) continue;
if (ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) {
preTesselatePoint = md;
@@ -1251,7 +1232,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
if(forRender) required_mode = eModifierMode_Render;
else required_mode = eModifierMode_Realtime;
- preTesselatePoint = curve_get_tesselate_point(ob, forRender, editmode);
+ preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);
if(editmode) required_mode |= eModifierMode_Editmode;
@@ -1282,7 +1263,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
deformedVerts = curve_getVertexCos(cu, nurb, &numVerts);
originalVerts = MEM_dupallocN(deformedVerts);
}
-
+
mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, forRender, editmode);
if (md==preTesselatePoint)
@@ -1294,7 +1275,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
curve_applyVertexCos(cu, nurb, deformedVerts);
if (keyVerts) /* these are not passed through modifier stack */
curve_applyKeyVertexTilts(cu, nurb, keyVerts);
-
+
if(keyVerts)
MEM_freeN(keyVerts);
@@ -1303,20 +1284,56 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
*numVerts_r = numVerts;
}
-static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispbase, int forRender, float (*originalVerts)[3], float (*deformedVerts)[3])
+static float (*displist_get_allverts (ListBase *dispbase, int *totvert))[3]
+{
+ DispList *dl;
+ float (*allverts)[3], *fp;
+
+ *totvert= 0;
+
+ for (dl=dispbase->first; dl; dl=dl->next)
+ *totvert+= (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr;
+
+ allverts= MEM_mallocN((*totvert)*sizeof(float)*3, "displist_get_allverts allverts");
+ fp= (float*)allverts;
+ for (dl=dispbase->first; dl; dl=dl->next) {
+ int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
+ memcpy(fp, dl->verts, sizeof(float) * offs);
+ fp+= offs;
+ }
+
+ return allverts;
+}
+
+static void displist_apply_allverts(ListBase *dispbase, float (*allverts)[3])
+{
+ DispList *dl;
+ float *fp;
+
+ fp= (float*)allverts;
+ for (dl=dispbase->first; dl; dl=dl->next) {
+ int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
+ memcpy(dl->verts, fp, sizeof(float) * offs);
+ fp+= offs;
+ }
+}
+
+static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispbase,
+ DerivedMesh **derivedFinal, int forRender, float (*originalVerts)[3], float (*deformedVerts)[3])
{
ModifierData *md = modifiers_getVirtualModifierList(ob);
ModifierData *preTesselatePoint;
Curve *cu= ob->data;
ListBase *nurb= cu->editnurb?cu->editnurb:&cu->nurb;
- DispList *dl;
- int required_mode;
+ int required_mode, totvert = 0;
int editmode = (!forRender && cu->editnurb);
+ DerivedMesh *dm= NULL, *ndm;
+ float (*vertCos)[3] = NULL;
if(forRender) required_mode = eModifierMode_Render;
else required_mode = eModifierMode_Realtime;
- preTesselatePoint = curve_get_tesselate_point(ob, forRender, editmode);
+ preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);
if(editmode) required_mode |= eModifierMode_Editmode;
@@ -1324,47 +1341,104 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
md = preTesselatePoint->next;
}
+ if (derivedFinal && *derivedFinal) {
+ (*derivedFinal)->release (*derivedFinal);
+ }
+
for (; md; md=md->next) {
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
-
+
md->scene= scene;
-
+
if ((md->mode & required_mode) != required_mode) continue;
if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
- if (mti->type!=eModifierTypeType_OnlyDeform && mti->type!=eModifierTypeType_DeformOrConstruct) continue;
- /* need to put all verts in 1 block for curve deform */
- if(md->type==eModifierType_Curve) {
- float *allverts, *fp;
- int totvert= 0;
-
- for (dl=dispbase->first; dl; dl=dl->next)
- totvert+= (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr;
-
- fp= allverts= MEM_mallocN(totvert*sizeof(float)*3, "temp vert");
- for (dl=dispbase->first; dl; dl=dl->next) {
- int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
- memcpy(fp, dl->verts, sizeof(float) * offs);
- fp+= offs;
+ if (mti->type == eModifierTypeType_OnlyDeform ||
+ (mti->type == eModifierTypeType_DeformOrConstruct && !dm)) {
+ if (dm) {
+ if (!vertCos) {
+ totvert = dm->getNumVerts(dm);
+ vertCos = MEM_mallocN(sizeof(*vertCos) * totvert, "dfmv");
+ dm->getVertCos(dm, vertCos);
+ }
+
+ mti->deformVerts(md, ob, dm, vertCos, totvert, forRender, editmode);
+ } else {
+ if (!vertCos) {
+ vertCos= displist_get_allverts(dispbase, &totvert);
+ }
+
+ mti->deformVerts(md, ob, NULL, vertCos, totvert, forRender, editmode);
}
-
- mti->deformVerts(md, ob, NULL, (float(*)[3]) allverts, totvert, forRender, editmode);
-
- fp= allverts;
- for (dl=dispbase->first; dl; dl=dl->next) {
- int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
- memcpy(dl->verts, fp, sizeof(float) * offs);
- fp+= offs;
+ } else {
+ if (!derivedFinal) {
+ /* makeDisplistCurveTypes could be used for beveling, where derived mesh */
+ /* is totally unnecessary, so we could stop modifiers applying */
+ /* when we found constructive modifier but derived mesh is unwanted result */
+ break;
}
- MEM_freeN(allverts);
- }
- else {
- for (dl=dispbase->first; dl; dl=dl->next) {
- mti->deformVerts(md, ob, NULL, (float(*)[3]) dl->verts, (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr, forRender, editmode);
+
+ if (dm) {
+ if (vertCos) {
+ DerivedMesh *tdm = CDDM_copy(dm, 0);
+ dm->release(dm);
+ dm = tdm;
+
+ CDDM_apply_vert_coords(dm, vertCos);
+ CDDM_calc_normals(dm);
+ }
+ } else {
+ if (vertCos) {
+ displist_apply_allverts(dispbase, vertCos);
+ }
+
+ if (ELEM(ob->type, OB_CURVE, OB_FONT) && (cu->flag & CU_DEFORM_FILL)) {
+ curve_to_filledpoly(cu, nurb, dispbase);
+ }
+
+ dm= CDDM_from_curve_customDB(ob, dispbase);
+
+ CDDM_calc_normals(dm);
+ }
+
+ if (vertCos) {
+ /* Vertex coordinates were applied to necessary data, could free it */
+ MEM_freeN(vertCos);
+ vertCos= NULL;
+ }
+
+ ndm = mti->applyModifier(md, ob, dm, forRender, editmode);
+
+ if (ndm) {
+ /* Modifier returned a new derived mesh */
+
+ if (dm && dm != ndm) /* Modifier */
+ dm->release (dm);
+ dm = ndm;
}
}
}
+ if (vertCos) {
+ if (dm) {
+ DerivedMesh *tdm = CDDM_copy(dm, 0);
+ dm->release(dm);
+ dm = tdm;
+
+ CDDM_apply_vert_coords(dm, vertCos);
+ CDDM_calc_normals(dm);
+ MEM_freeN(vertCos);
+ } else {
+ displist_apply_allverts(dispbase, vertCos);
+ MEM_freeN(vertCos);
+ vertCos= NULL;
+ }
+ }
+
+ if (derivedFinal) {
+ (*derivedFinal) = dm;
+ }
+
if (deformedVerts) {
curve_applyVertexCos(ob->data, nurb, originalVerts);
MEM_freeN(originalVerts);
@@ -1402,7 +1476,110 @@ static void displist_surf_indices(DispList *dl)
}
-void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, int forRender, int forOrco)
+static DerivedMesh *create_orco_dm(Scene *scene, Object *ob)
+{
+ DerivedMesh *dm;
+ ListBase disp= {NULL, NULL};
+
+ /* OrcoDM should be created from underformed disp lists */
+ makeDispListCurveTypes_forOrco(scene, ob, &disp);
+ dm= CDDM_from_curve_customDB(ob, &disp);
+
+ freedisplist(&disp);
+
+ return dm;
+}
+
+static void add_orco_dm(Scene *scene, Object *ob, DerivedMesh *dm, DerivedMesh *orcodm)
+{
+ float (*orco)[3], (*layerorco)[3];
+ int totvert, a;
+ Curve *cu= ob->data;
+
+ totvert= dm->getNumVerts(dm);
+
+ if(orcodm) {
+ orco= MEM_callocN(sizeof(float)*3*totvert, "dm orco");
+
+ if(orcodm->getNumVerts(orcodm) == totvert)
+ orcodm->getVertCos(orcodm, orco);
+ else
+ dm->getVertCos(dm, orco);
+ }
+ else {
+ orco= (float(*)[3])make_orco_curve(scene, ob);
+ }
+
+ for(a=0; a<totvert; a++) {
+ float *co = orco[a];
+ co[0] = (co[0]-cu->loc[0])/cu->size[0];
+ co[1] = (co[1]-cu->loc[1])/cu->size[1];
+ co[2] = (co[2]-cu->loc[2])/cu->size[2];
+ }
+
+ if((layerorco = DM_get_vert_data_layer(dm, CD_ORCO))) {
+ memcpy(layerorco, orco, sizeof(float)*totvert);
+ MEM_freeN(orco);
+ }
+ else
+ DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco);
+}
+
+static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender)
+{
+ /* this function represents logic of mesh's orcodm calculation */
+ /* for displist-based objects */
+
+ ModifierData *md = modifiers_getVirtualModifierList(ob);
+ ModifierData *preTesselatePoint;
+ Curve *cu= ob->data;
+ int required_mode;
+ int editmode = (!forRender && cu->editnurb);
+ DerivedMesh *ndm, *orcodm= NULL;
+
+ if(forRender) required_mode = eModifierMode_Render;
+ else required_mode = eModifierMode_Realtime;
+
+ preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);
+
+ if(editmode) required_mode |= eModifierMode_Editmode;
+
+ if (preTesselatePoint) {
+ md = preTesselatePoint->next;
+ }
+
+ for (; md; md=md->next) {
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+
+ md->scene= scene;
+
+ if ((md->mode & required_mode) != required_mode) continue;
+ if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
+ if (mti->type!=eModifierTypeType_Constructive) continue;
+
+ if(!orcodm)
+ orcodm= create_orco_dm(scene, ob);
+
+ ndm = mti->applyModifier(md, ob, orcodm, forRender, 0);
+
+ if(ndm) {
+ /* if the modifier returned a new dm, release the old one */
+ if(orcodm && orcodm != ndm) {
+ orcodm->release(orcodm);
+ }
+ orcodm = ndm;
+ }
+ }
+
+ /* add an orco layer if needed */
+ add_orco_dm(scene, ob, derivedFinal, orcodm);
+
+ if(orcodm)
+ orcodm->release(orcodm);
+}
+
+void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase,
+ DerivedMesh **derivedFinal, int forRender, int forOrco)
{
ListBase *nubase;
Nurb *nu;
@@ -1426,22 +1603,25 @@ void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, int forRende
if(forRender || nu->hide==0) {
if(nu->pntsv==1) {
len= SEGMENTSU(nu)*nu->resolu;
-
+
dl= MEM_callocN(sizeof(DispList), "makeDispListsurf");
dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts");
-
+
BLI_addtail(dispbase, dl);
dl->parts= 1;
dl->nr= len;
dl->col= nu->mat_nr;
dl->charidx= nu->charidx;
- dl->rt= nu->flag;
-
+
+ /* dl->rt will be used as flag for render face and */
+ /* CU_2D conflicts with R_NOPUNOFLIP */
+ dl->rt= nu->flag & ~CU_2D;
+
data= dl->verts;
- if(nu->flagu & CU_CYCLIC) dl->type= DL_POLY;
+ if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY;
else dl->type= DL_SEGM;
-
- makeNurbcurve(nu, data, NULL, NULL, nu->resolu, 3*sizeof(float));
+
+ makeNurbcurve(nu, data, NULL, NULL, NULL, nu->resolu, 3*sizeof(float));
}
else {
len= (nu->pntsu*nu->resolu) * (nu->pntsv*nu->resolv);
@@ -1452,15 +1632,18 @@ void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, int forRende
dl->col= nu->mat_nr;
dl->charidx= nu->charidx;
- dl->rt= nu->flag;
-
+
+ /* dl->rt will be used as flag for render face and */
+ /* CU_2D conflicts with R_NOPUNOFLIP */
+ dl->rt= nu->flag & ~CU_2D;
+
data= dl->verts;
dl->type= DL_SURF;
-
+
dl->parts= (nu->pntsu*nu->resolu); /* in reverse, because makeNurbfaces works that way */
dl->nr= (nu->pntsv*nu->resolv);
- if(nu->flagv & CU_CYCLIC) dl->flag|= DL_CYCL_U; /* reverse too! */
- if(nu->flagu & CU_CYCLIC) dl->flag|= DL_CYCL_V;
+ if(nu->flagv & CU_NURB_CYCLIC) dl->flag|= DL_CYCL_U; /* reverse too! */
+ if(nu->flagu & CU_NURB_CYCLIC) dl->flag|= DL_CYCL_V;
makeNurbfaces(nu, data, 0);
@@ -1475,23 +1658,20 @@ void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, int forRende
}
if(!forOrco)
- curve_calc_modifiers_post(scene, ob, dispbase, forRender, originalVerts, deformedVerts);
+ curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal,
+ forRender, originalVerts, deformedVerts);
}
-void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
+static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispbase,
+ DerivedMesh **derivedFinal, int forRender, int forOrco)
{
Curve *cu = ob->data;
- ListBase *dispbase;
-
+
/* we do allow duplis... this is only displist on curve level */
if(!ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) return;
- freedisplist(&(ob->disp));
- dispbase= &(cu->disp);
- freedisplist(dispbase);
-
if(ob->type==OB_SURF) {
- makeDispListSurf(scene, ob, dispbase, 0, forOrco);
+ makeDispListSurf(scene, ob, dispbase, derivedFinal, forRender, forOrco);
}
else if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
ListBase dlbev;
@@ -1500,24 +1680,33 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
float (*deformedVerts)[3];
int numVerts;
+ /* Bevel and taper objects should always be curves */
+ if (cu->bevobj && cu->bevobj->type != OB_CURVE) {
+ cu->bevobj = NULL;
+ }
+
+ if (cu->taperobj && cu->taperobj->type != OB_CURVE) {
+ cu->taperobj = NULL;
+ }
+
if(cu->editnurb)
nubase= cu->editnurb;
else
nubase= &cu->nurb;
-
+
BLI_freelistN(&(cu->bev));
-
+
if(cu->path) free_path(cu->path);
cu->path= NULL;
-
+
if(ob->type==OB_FONT) BKE_text_to_curve(scene, ob, 0);
-
- if(!forOrco) curve_calc_modifiers_pre(scene, ob, 0, &originalVerts, &deformedVerts, &numVerts);
+
+ if(!forOrco) curve_calc_modifiers_pre(scene, ob, forRender, &originalVerts, &deformedVerts, &numVerts);
makeBevelList(ob);
/* If curve has no bevel will return nothing */
- makebevelcurve(scene, ob, &dlbev);
+ makebevelcurve(scene, ob, &dlbev, forRender);
/* no bevel or extrude, and no width correction? */
if (!dlbev.first && cu->width==1.0f) {
@@ -1532,26 +1721,29 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
float *fp1, *data;
BevPoint *bevp;
int a,b;
-
+
if (bl->nr) { /* blank bevel lists can happen */
-
+
/* exception handling; curve without bevel or extrude, with width correction */
if(dlbev.first==NULL) {
dl= MEM_callocN(sizeof(DispList), "makeDispListbev");
dl->verts= MEM_callocN(3*sizeof(float)*bl->nr, "dlverts");
BLI_addtail(dispbase, dl);
-
+
if(bl->poly!= -1) dl->type= DL_POLY;
else dl->type= DL_SEGM;
-
+
if(dl->type==DL_SEGM) dl->flag = (DL_FRONT_CURVE|DL_BACK_CURVE);
-
+
dl->parts= 1;
dl->nr= bl->nr;
dl->col= nu->mat_nr;
dl->charidx= nu->charidx;
- dl->rt= nu->flag;
-
+
+ /* dl->rt will be used as flag for render face and */
+ /* CU_2D conflicts with R_NOPUNOFLIP */
+ dl->rt= nu->flag & ~CU_2D;
+
a= dl->nr;
bevp= (BevPoint *)(bl+1);
data= dl->verts;
@@ -1565,10 +1757,10 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
}
else {
DispList *dlb;
-
+
for (dlb=dlbev.first; dlb; dlb=dlb->next) {
- /* for each part of the bevel use a separate displblock */
+ /* for each part of the bevel use a separate displblock */
dl= MEM_callocN(sizeof(DispList), "makeDispListbev1");
dl->verts= data= MEM_callocN(3*sizeof(float)*dlb->nr*bl->nr, "dlverts");
BLI_addtail(dispbase, dl);
@@ -1583,11 +1775,15 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
dl->nr= dlb->nr;
dl->col= nu->mat_nr;
dl->charidx= nu->charidx;
- dl->rt= nu->flag;
+
+ /* dl->rt will be used as flag for render face and */
+ /* CU_2D conflicts with R_NOPUNOFLIP */
+ dl->rt= nu->flag & ~CU_2D;
+
dl->bevelSplitFlag= MEM_callocN(sizeof(*dl->col2)*((bl->nr+0x1F)>>5), "col2");
bevp= (BevPoint *)(bl+1);
- /* for each point of poly make a bevel piece */
+ /* for each point of poly make a bevel piece */
bevp= (BevPoint *)(bl+1);
for(a=0; a<bl->nr; a++,bevp++) {
float fac=1.0;
@@ -1597,7 +1793,7 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
} else {
fac = calc_taper(scene, cu->taperobj, a, bl->nr);
}
-
+
if (bevp->split_tag) {
dl->bevelSplitFlag[a>>5] |= 1<<(a&0x1F);
}
@@ -1611,9 +1807,9 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
vec[0]= fp1[1]+widfac;
vec[1]= fp1[2];
vec[2]= 0.0;
-
+
mul_qt_v3(bevp->quat, vec);
-
+
data[0]= bevp->vec[0] + fac*vec[0];
data[1]= bevp->vec[1] + fac*vec[1];
data[2]= bevp->vec[2] + fac*vec[2];
@@ -1636,15 +1832,77 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
freedisplist(&dlbev);
}
- curve_to_filledpoly(cu, nubase, dispbase);
+ if (!(cu->flag & CU_DEFORM_FILL)) {
+ curve_to_filledpoly(cu, nubase, dispbase);
+ }
if(cu->flag & CU_PATH) calc_curvepath(ob);
- if(!forOrco) curve_calc_modifiers_post(scene, ob, &cu->disp, 0, originalVerts, deformedVerts);
- tex_space_curve(cu);
+ if (!forRender) {
+ tex_space_curve(cu);
+ }
+
+ if(!forOrco) curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal, forRender, originalVerts, deformedVerts);
+
+ if (cu->flag & CU_DEFORM_FILL && !ob->derivedFinal) {
+ curve_to_filledpoly(cu, nubase, dispbase);
+ }
}
-
- boundbox_displist(ob);
+}
+
+void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
+{
+ Curve *cu = ob->data;
+ ListBase *dispbase;
+
+ freedisplist(&(ob->disp));
+ dispbase= &(cu->disp);
+ freedisplist(dispbase);
+
+ do_makeDispListCurveTypes(scene, ob, dispbase, &ob->derivedFinal, 0, forOrco);
+
+ if (ob->derivedFinal) {
+ DM_set_object_boundbox (ob, ob->derivedFinal);
+ } else {
+ boundbox_displist (ob);
+
+ /* if there is no derivedMesh, object's boundbox is unneeded */
+ if (ob->bb) {
+ MEM_freeN(ob->bb);
+ ob->bb= NULL;
+ }
+ }
+}
+
+void makeDispListCurveTypes_forRender(Scene *scene, Object *ob, ListBase *dispbase,
+ DerivedMesh **derivedFinal, int forOrco)
+{
+ do_makeDispListCurveTypes(scene, ob, dispbase, derivedFinal, 1, forOrco);
+}
+
+void makeDispListCurveTypes_forOrco(struct Scene *scene, struct Object *ob, struct ListBase *dispbase)
+{
+ do_makeDispListCurveTypes(scene, ob, dispbase, NULL, 1, 1);
+}
+
+/* add Orco layer to the displist object which has got derived mesh and return orco */
+float *makeOrcoDispList(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender) {
+ float *orco;
+
+ if (derivedFinal == NULL)
+ derivedFinal= ob->derivedFinal;
+
+ if (!derivedFinal->getVertDataArray(derivedFinal, CD_ORCO)) {
+ curve_calc_orcodm(scene, ob, derivedFinal, forRender);
+ }
+
+ orco= derivedFinal->getVertDataArray(derivedFinal, CD_ORCO);
+
+ if(orco) {
+ orco= MEM_dupallocN(orco);
+ }
+
+ return orco;
}
void imagestodisplist(void)
@@ -1667,7 +1925,7 @@ static void boundbox_displist(Object *ob)
Curve *cu= ob->data;
int doit= 0;
- if(cu->bb==0) cu->bb= MEM_callocN(sizeof(BoundBox), "boundbox");
+ if(cu->bb==0) cu->bb= MEM_callocN(sizeof(BoundBox), "boundbox");
bb= cu->bb;
dl= cu->disp.first;
diff --git a/source/blender/blenkernel/intern/editderivedbmesh.c b/source/blender/blenkernel/intern/editderivedbmesh.c
index 3063d42cbe5..168e0e566de 100644
--- a/source/blender/blenkernel/intern/editderivedbmesh.c
+++ b/source/blender/blenkernel/intern/editderivedbmesh.c
@@ -129,7 +129,7 @@ static void BMEdit_RecalcTesselation_intern(BMEditMesh *tm)
BMIter iter, liter;
BMFace *f;
BMLoop *l;
- int i = 0, j, a, b;
+ int i = 0, j;
if (tm->looptris) MEM_freeN(tm->looptris);
@@ -354,9 +354,9 @@ static void bmdm_recalc_lookups(EditDerivedBMesh *bmdm)
if (bmdm->ehash) BLI_ghash_free(bmdm->ehash, NULL, NULL);
if (bmdm->fhash) BLI_ghash_free(bmdm->fhash, NULL, NULL);
- bmdm->vhash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
- bmdm->ehash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
- bmdm->fhash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+ bmdm->vhash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "bmesh derived");
+ bmdm->ehash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "bmesh derived");
+ bmdm->fhash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "bmesh derived");
if (bmdm->vtable) MEM_freeN(bmdm->vtable);
if (bmdm->etable) MEM_freeN(bmdm->etable);
@@ -398,7 +398,7 @@ static void bmdm_recalc_lookups(EditDerivedBMesh *bmdm)
static void bmDM_recalcTesselation(DerivedMesh *dm)
{
- EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
+ //EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
//bmdm_recalc_lookups(bmdm);
}
@@ -1166,13 +1166,13 @@ static int bmvert_to_mvert(BMesh *bm, BMVert *ev, MVert *vert_r)
if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
vert_r->bweight = (unsigned char) (BM_GetCDf(&bm->vdata, ev, CD_BWEIGHT)*255.0f);
}
+
+ return 1;
}
static void bmDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
{
BMVert *ev;
- BMIter iter;
- int i;
if (index < 0 || index >= ((EditDerivedBMesh *)dm)->tv) {
printf("error in bmDM_getVert.\n");
@@ -1188,9 +1188,6 @@ static void bmDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
BMEdge *e;
- BMVert *ev, *v1, *v2;
- BMIter iter;
- int i;
if (index < 0 || index >= ((EditDerivedBMesh *)dm)->te) {
printf("error in bmDM_getEdge.\n");
@@ -1221,11 +1218,8 @@ static void bmDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
static void bmDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r)
{
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
- BMesh *bm = bmdm->tc->bm;
BMFace *ef;
- BMIter iter;
BMLoop **l;
- int i;
if (index < 0 || index >= ((EditDerivedBMesh *)dm)->tf) {
printf("error in bmDM_getTessFace.\n");
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index f8193a3a7b0..b1182cfcec3 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -222,7 +222,7 @@ static void precalculate_effector(EffectorCache *eff)
makeDispListCurveTypes(eff->scene, eff->ob, 0);
if(cu->path && cu->path->data) {
- where_on_path(eff->ob, 0.0, eff->guide_loc, eff->guide_dir, NULL, &eff->guide_radius);
+ where_on_path(eff->ob, 0.0, eff->guide_loc, eff->guide_dir, NULL, &eff->guide_radius, NULL);
mul_m4_v3(eff->ob->obmat, eff->guide_loc);
mul_mat3_m4_v3(eff->ob->obmat, eff->guide_dir);
}
@@ -429,7 +429,7 @@ static float eff_calc_visibility(ListBase *colliders, EffectorCache *eff, Effect
return visibility;
if(!colls)
- colls = get_collider_cache(eff->scene, NULL);
+ colls = get_collider_cache(eff->scene, NULL, NULL);
if(!colls)
return visibility;
@@ -576,10 +576,10 @@ int closest_point_on_surface(SurfaceModifierData *surmd, float *co, float *surfa
MFace *mface = CDDM_get_tessface(surmd->dm, nearest.index);
VECCOPY(surface_vel, surmd->v[mface->v1].co);
- add_v3_v3v3(surface_vel, surface_vel, surmd->v[mface->v2].co);
- add_v3_v3v3(surface_vel, surface_vel, surmd->v[mface->v3].co);
+ add_v3_v3(surface_vel, surmd->v[mface->v2].co);
+ add_v3_v3(surface_vel, surmd->v[mface->v3].co);
if(mface->v4)
- add_v3_v3v3(surface_vel, surface_vel, surmd->v[mface->v4].co);
+ add_v3_v3(surface_vel, surmd->v[mface->v4].co);
mul_v3_fl(surface_vel, mface->v4 ? 0.25f : 0.333f);
}
@@ -600,7 +600,7 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin
/* using velocity corrected location allows for easier sliding over effector surface */
copy_v3_v3(vec, point->vel);
mul_v3_fl(vec, point->vel_to_frame);
- add_v3_v3v3(vec, vec, point->loc);
+ add_v3_v3(vec, point->loc);
ret = closest_point_on_surface(eff->surmd, vec, efd->loc, efd->nor, real_velocity ? efd->vel : NULL);
@@ -777,10 +777,10 @@ static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedP
}
if(eff->pd->flag & PFIELD_TEX_OBJECT) {
- mul_mat3_m4_v3(eff->ob->obmat, tex_co);
+ mul_m4_v3(eff->ob->obmat, tex_co);
}
- hasrgb = multitex_ext(eff->pd->tex, tex_co, NULL,NULL, 1, result);
+ hasrgb = multitex_ext(eff->pd->tex, tex_co, NULL,NULL, 0, result);
if(hasrgb && mode==PFIELD_TEX_RGB) {
force[0] = (0.5f - result->tr) * strength;
@@ -791,15 +791,15 @@ static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedP
strength/=nabla;
tex_co[0] += nabla;
- multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 1, result+1);
+ multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+1);
tex_co[0] -= nabla;
tex_co[1] += nabla;
- multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 1, result+2);
+ multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+2);
tex_co[1] -= nabla;
tex_co[2] += nabla;
- multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 1, result+3);
+ multitex_ext(eff->pd->tex, tex_co, NULL, NULL, 0, result+3);
if(mode == PFIELD_TEX_GRAD || !hasrgb) { /* if we dont have rgb fall back to grad */
force[0] = (result[0].tin - result[1].tin) * strength;
@@ -827,7 +827,7 @@ static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedP
VECADDFAC(force, force, efd->nor, fac);
}
- add_v3_v3v3(total_force, total_force, force);
+ add_v3_v3(total_force, force);
}
void do_physical_effector(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, float *total_force)
{
@@ -874,7 +874,7 @@ void do_physical_effector(EffectorCache *eff, EffectorData *efd, EffectedPoint *
mul_v3_fl(force, strength * efd->falloff);
VECADDFAC(temp, temp, point->vel, -point->vel_to_sec);
- add_v3_v3v3(force, force, temp);
+ add_v3_v3(force, temp);
}
break;
case PFIELD_MAGNET:
@@ -893,7 +893,7 @@ void do_physical_effector(EffectorCache *eff, EffectorData *efd, EffectedPoint *
mul_v3_fl(force, -strength * efd->falloff);
copy_v3_v3(temp, point->vel);
mul_v3_fl(temp, -damp * 2.0f * (float)sqrt(fabs(strength)) * point->vel_to_sec);
- add_v3_v3v3(force, force, temp);
+ add_v3_v3(force, temp);
break;
case PFIELD_CHARGE:
mul_v3_fl(force, point->charge * strength * efd->falloff);
@@ -950,20 +950,20 @@ void do_physical_effector(EffectorCache *eff, EffectorData *efd, EffectedPoint *
if(pd->f_flow != 0.0f) {
VECADDFAC(dave, dave, point->ave, -pd->f_flow * efd->falloff);
}
- add_v3_v3v3(point->ave, point->ave, dave);
+ add_v3_v3(point->ave, dave);
}
}
/* -------- pdDoEffectors() --------
- generic force/speed system, now used for particles and softbodies
- scene = scene where it runs in, for time and stuff
+ generic force/speed system, now used for particles and softbodies
+ scene = scene where it runs in, for time and stuff
lb = listbase with objects that take part in effecting
opco = global coord, as input
- force = force accumulator
- speed = actual current speed which can be altered
+ force = force accumulator
+ speed = actual current speed which can be altered
cur_time = "external" time in frames, is constant for static particles
loc_time = "local" time in frames, range <0-1> for the lifetime of particle
- par_layer = layer the caller is in
+ par_layer = layer the caller is in
flags = only used for softbody wind now
guide = old speed of particle
diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c
index cc42b0754a5..deae6d2808b 100644
--- a/source/blender/blenkernel/intern/exotic.c
+++ b/source/blender/blenkernel/intern/exotic.c
@@ -55,35 +55,26 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_material_types.h"
-#include "DNA_lamp_types.h"
#include "DNA_curve_types.h"
-#include "DNA_image_types.h"
#include "DNA_camera_types.h"
#include "DNA_scene_types.h"
-#include "DNA_view3d_types.h"
-#include "DNA_userdef_types.h"
#include "BKE_utildefines.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_editVert.h"
#include "BKE_blender.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_library.h"
-#include "BKE_global.h"
#include "BKE_object.h"
#include "BKE_material.h"
-#include "BKE_exotic.h"
#include "BKE_report.h"
-#include "BKE_screen.h"
#include "BKE_displist.h"
#include "BKE_DerivedMesh.h"
#include "BKE_curve.h"
-#include "BKE_customdata.h"
#ifndef DISABLE_PYTHON
#include "BPY_extern.h"
@@ -138,19 +129,19 @@ static int is_stl(char *str)
#define READSTLVERT { \
if (fread(mvert->co, sizeof(float), 3, fpSTL) != 3) { \
- char error_msg[255]; \
- MEM_freeN(vertdata); \
- MEM_freeN(facedata); \
- fclose(fpSTL); \
- sprintf(error_msg, "Problems reading face %d!", i); \
- return; \
+ char error_msg[255]; \
+ MEM_freeN(vertdata); \
+ MEM_freeN(facedata); \
+ fclose(fpSTL); \
+ sprintf(error_msg, "Problems reading face %d!", i); \
+ return; \
} \
else { \
- if (ENDIAN_ORDER==B_ENDIAN) { \
- SWITCH_INT(mvert->co[0]); \
- SWITCH_INT(mvert->co[1]); \
- SWITCH_INT(mvert->co[2]); \
- } \
+ if (ENDIAN_ORDER==B_ENDIAN) { \
+ SWITCH_INT(mvert->co[0]); \
+ SWITCH_INT(mvert->co[1]); \
+ SWITCH_INT(mvert->co[2]); \
+ } \
} \
}
@@ -276,9 +267,9 @@ static void read_stl_mesh_binary(Scene *scene, char *str)
me->totvert = totvert;
me->totface = totface;
me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN,
- vertdata, totvert);
+ vertdata, totvert);
me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN,
- facedata, totface);
+ facedata, totface);
mesh_add_normals_flags(me);
make_edges(me, 0);
@@ -419,9 +410,9 @@ static void read_stl_mesh_ascii(Scene *scene, char *str)
me->totface = totface;
me->totvert = totvert;
me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC,
- NULL, totvert);
+ NULL, totvert);
me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC,
- NULL, totface);
+ NULL, totface);
/* Copy vert coords and create topology */
mvert = me->mvert;
@@ -871,7 +862,7 @@ static void read_inventor(Scene *scene, char *str, struct ListBase *listb)
/* count the nr of lines */
tot= 0;
index= iv->data[0];
- lll = iv->datalen[0]-1;
+ lll = iv->datalen[0]-1;
for(a=0; a<lll; a++) {
if(index[0]!= -1 && index[1]!= -1) tot++;
index++;
@@ -1018,7 +1009,7 @@ static void read_inventor(Scene *scene, char *str, struct ListBase *listb)
}
/* indices */
- lll = index[0] - 2;
+ lll = index[0] - 2;
for(b=0; b<lll; b++) {
idata[0]= first;
idata[1]= first+1;
@@ -1054,7 +1045,7 @@ static void read_inventor(Scene *scene, char *str, struct ListBase *listb)
/* count triangles */
face= 0;
index= iv->data[0];
- lll = iv->datalen[0]-2;
+ lll = iv->datalen[0]-2;
for(a=0; a<lll; a++) {
if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) face++;
index++;
@@ -1132,7 +1123,7 @@ static void read_inventor(Scene *scene, char *str, struct ListBase *listb)
/* count triangles */
face= 0;
index= iv->data[0];
- lll=iv->datalen[0]-2;
+ lll=iv->datalen[0]-2;
for(a=0; a<lll; a++) {
if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) face++;
index++;
@@ -1164,7 +1155,7 @@ static void read_inventor(Scene *scene, char *str, struct ListBase *listb)
index= iv->data[0];
idata= dl->index;
- lll=iv->datalen[0]-2;
+ lll=iv->datalen[0]-2;
for(a=lll; a>0; a--) {
if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) {
@@ -1485,9 +1476,9 @@ static void displist_to_mesh(Scene *scene, DispList *dlfirst)
me->totvert= totvert;
me->totface= totface;
me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC,
- NULL, me->totvert);
+ NULL, me->totvert);
me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC,
- NULL, me->totface);
+ NULL, me->totface);
maxvertidx= totvert-1;
mvert= me->mvert;
@@ -1965,8 +1956,8 @@ void write_stl(Scene *scene, char *str)
fseek(fpSTL, 80, SEEK_SET);
if (ENDIAN_ORDER==B_ENDIAN) {
- SWITCH_INT(numfacets);
- }
+ SWITCH_INT(numfacets);
+ }
fwrite(&numfacets, 4*sizeof(char), 1, fpSTL);
fclose(fpSTL);
@@ -2583,13 +2574,13 @@ void write_dxf(struct Scene *scene, char *str)
/* The header part of the DXF */
write_group(0, "SECTION");
- write_group(2, "HEADER");
+ write_group(2, "HEADER");
write_group(0, "ENDSEC");
/* The blocks part of the DXF */
write_group(0, "SECTION");
- write_group(2, "BLOCKS");
+ write_group(2, "BLOCKS");
/* only write meshes we're using in this scene */
@@ -2613,7 +2604,7 @@ void write_dxf(struct Scene *scene, char *str)
/* The entities part of the DXF */
write_group(0, "SECTION");
- write_group(2, "ENTITIES");
+ write_group(2, "ENTITIES");
/* Write all the mesh objects */
base= scene->base.first;
@@ -3065,7 +3056,7 @@ static void dxf_read_line(Scene *scene, int noob) {
hasbumped=1;
}
- /* 2D Polyline state vars */
+ /* 2D Polyline state vars */
static Object *p2dhold=NULL;
static Mesh *p2dmhold=NULL;
static char oldplay[32];
@@ -3140,35 +3131,35 @@ static void dxf_read_ellipse(Scene *scene, int noob)
read_group(id, val);
while(id!=0) {
if (id==8) {
- BLI_strncpy(layname, val, sizeof(layname));
+ BLI_strncpy(layname, val, sizeof(layname));
} else if (id==10) {
- center[0]= (float) atof(val);
+ center[0]= (float) atof(val);
} else if (id==20) {
- center[1]= (float) atof(val);
+ center[1]= (float) atof(val);
} else if (id==30) {
- center[2]= (float) atof(val);
+ center[2]= (float) atof(val);
} else if (id==11) {
- axis_endpoint[0]= (float) atof(val);
+ axis_endpoint[0]= (float) atof(val);
} else if (id==21) {
- axis_endpoint[1]= (float) atof(val);
+ axis_endpoint[1]= (float) atof(val);
} else if (id==31) {
- axis_endpoint[2]= (float) atof(val);
+ axis_endpoint[2]= (float) atof(val);
} else if (id==40) {
- axis_ratio = (float) atof(val);
+ axis_ratio = (float) atof(val);
} else if (id==41) {
printf("dxf: start = %f", atof(val) * 180/M_PI);
- start_angle = -atof(val) + M_PI_2;
+ start_angle = -atof(val) + M_PI_2;
} else if (id==42) {
printf("dxf: end = %f", atof(val) * 180/M_PI);
end_angle = -atof(val) + M_PI_2;
} else if (id==62) {
- int colorid= atoi(val);
- CLAMP(colorid, 1, 255);
- dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
+ int colorid= atoi(val);
+ CLAMP(colorid, 1, 255);
+ dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
} else if (id==67) {
- vspace= atoi(val);
+ vspace= atoi(val);
} else if (id==100) {
- isArc = 1;
+ isArc = 1;
} else if (id==210) {
extrusion[0] = atof(val);
} else if (id==220) {
@@ -3299,28 +3290,28 @@ static void dxf_read_arc(Scene *scene, int noob)
read_group(id, val);
while(id!=0) {
if (id==8) {
- BLI_strncpy(layname, val, sizeof(layname));
+ BLI_strncpy(layname, val, sizeof(layname));
} else if (id==10) {
- center[0]= (float) atof(val);
+ center[0]= (float) atof(val);
} else if (id==20) {
- center[1]= (float) atof(val);
+ center[1]= (float) atof(val);
} else if (id==30) {
- center[2]= (float) atof(val);
+ center[2]= (float) atof(val);
} else if (id==40) {
- dia = (float) atof(val);
+ dia = (float) atof(val);
} else if (id==62) {
- int colorid= atoi(val);
+ int colorid= atoi(val);
- CLAMP(colorid, 1, 255);
- dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
+ CLAMP(colorid, 1, 255);
+ dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
} else if (id==67) {
- vspace= atoi(val);
+ vspace= atoi(val);
} else if (id==100) {
- isArc = 1;
+ isArc = 1;
} else if (id==50) {
- start_angle = (90 - atoi(val)) * M_PI/180.0;
+ start_angle = (90 - atoi(val)) * M_PI/180.0;
} else if (id==51) {
- end_angle = (90 - atoi(val)) * M_PI/180.0;
+ end_angle = (90 - atoi(val)) * M_PI/180.0;
} else if (id==210) {
extrusion[0] = atof(val);
} else if (id==220) {
@@ -4080,7 +4071,7 @@ static void dxf_read(Scene *scene, char *filename)
ob->dupon= 1; ob->dupoff= 0;
ob->dupsta= 1; ob->dupend= 100;
- ob->recalc= OB_RECALC; /* needed because of weird way of adding libdata directly */
+ ob->recalc= OB_RECALC_ALL; /* needed because of weird way of adding libdata directly */
ob->data= obdata;
((ID*)ob->data)->us++;
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 807a723685a..43f01199b69 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -34,10 +34,6 @@
#include <string.h>
#include <float.h>
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
@@ -45,7 +41,6 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_noise.h"
#include "BKE_fcurve.h"
#include "BKE_animsys.h"
@@ -53,12 +48,10 @@
#include "BKE_armature.h"
#include "BKE_curve.h"
#include "BKE_global.h"
-#include "BKE_idprop.h"
#include "BKE_object.h"
#include "BKE_utildefines.h"
#include "RNA_access.h"
-#include "RNA_types.h"
#ifndef DISABLE_PYTHON
#include "BPY_extern.h"
@@ -237,6 +230,27 @@ FCurve *list_find_fcurve (ListBase *list, const char rna_path[], const int array
return NULL;
}
+/* quick way to loop over all fcurves of a given 'path' */
+FCurve *iter_step_fcurve (FCurve *fcu_iter, const char rna_path[])
+{
+ FCurve *fcu;
+
+ /* sanity checks */
+ if (ELEM(NULL, fcu_iter, rna_path))
+ return NULL;
+
+ /* check paths of curves, then array indices... */
+ for (fcu= fcu_iter; fcu; fcu= fcu->next) {
+ /* simple string-compare (this assumes that they have the same root...) */
+ if (fcu->rna_path && !strcmp(fcu->rna_path, rna_path)) {
+ return fcu;
+ }
+ }
+
+ /* return */
+ return NULL;
+}
+
/* Get list of LinkData's containing pointers to the F-Curves which control the types of data indicated
* Lists...
* - dst: list of LinkData's matching the criteria returned.
@@ -1404,7 +1418,7 @@ static float evaluate_driver (ChannelDriver *driver, float evaltime)
/* this evaluates the expression using Python,and returns its result:
* - on errors it reports, then returns 0.0f
*/
- driver->curval= BPY_pydriver_eval(driver);
+ driver->curval= BPY_eval_driver(driver);
}
#endif /* DISABLE_PYTHON*/
}
diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c
index 592119ce099..a0906a67be0 100644
--- a/source/blender/blenkernel/intern/fluidsim.c
+++ b/source/blender/blenkernel/intern/fluidsim.c
@@ -62,557 +62,14 @@
/* ************************* fluidsim bobj file handling **************************** */
-// -----------------------------------------
-// forward decleration
-// -----------------------------------------
-
-// -----------------------------------------
-
-void fluidsim_init(FluidsimModifierData *fluidmd)
-{
-#ifndef DISABLE_ELBEEM
- if(fluidmd)
- {
- FluidsimSettings *fss = MEM_callocN(sizeof(FluidsimSettings), "fluidsimsettings");
-
- fluidmd->fss = fss;
-
- if(!fss)
- return;
-
- fss->fmd = fluidmd;
- fss->type = OB_FLUIDSIM_ENABLE;
- fss->show_advancedoptions = 0;
-
- fss->resolutionxyz = 65;
- fss->previewresxyz = 45;
- fss->realsize = 0.5;
- fss->guiDisplayMode = 2; // preview
- fss->renderDisplayMode = 3; // render
-
- fss->viscosityMode = 2; // default to water
- fss->viscosityValue = 1.0;
- fss->viscosityExponent = 6;
-
- // dg TODO: change this to []
- fss->gravx = 0.0;
- fss->gravy = 0.0;
- fss->gravz = -9.81;
- fss->animStart = 0.0;
- fss->animEnd = 4.0;
- fss->gstar = 0.005; // used as normgstar
- fss->maxRefine = -1;
- // maxRefine is set according to resolutionxyz during bake
-
- // fluid/inflow settings
- // fss->iniVel --> automatically set to 0
-
- /* elubie: changed this to default to the same dir as the render output
- to prevent saving to C:\ on Windows */
- BLI_strncpy(fss->surfdataPath, btempdir, FILE_MAX);
-
- // first init of bounding box
- // no bounding box needed
-
- // todo - reuse default init from elbeem!
- fss->typeFlags = OB_FSBND_PARTSLIP;
- fss->domainNovecgen = 0;
- fss->volumeInitType = 1; // volume
- fss->partSlipValue = 0.2;
-
- fss->generateTracers = 0;
- fss->generateParticles = 0.0;
- fss->surfaceSmoothing = 1.0;
- fss->surfaceSubdivs = 0.0;
- fss->particleInfSize = 0.0;
- fss->particleInfAlpha = 0.0;
-
- // init fluid control settings
- fss->attractforceStrength = 0.2;
- fss->attractforceRadius = 0.75;
- fss->velocityforceStrength = 0.2;
- fss->velocityforceRadius = 0.75;
- fss->cpsTimeStart = fss->animStart;
- fss->cpsTimeEnd = fss->animEnd;
- fss->cpsQuality = 10.0; // 1.0 / 10.0 => means 0.1 width
-
- /*
- BAD TODO: this is done in buttons_object.c in the moment
- Mesh *mesh = ob->data;
- // calculate bounding box
- fluid_get_bb(mesh->mvert, mesh->totvert, ob->obmat, fss->bbStart, fss->bbSize);
- */
-
- // (ab)used to store velocities
- fss->meshSurfNormals = NULL;
-
- fss->lastgoodframe = -1;
-
- fss->flag = 0;
-
- }
-#endif
- return;
-}
-
-void fluidsim_free(FluidsimModifierData *fluidmd)
-{
-#ifndef DISABLE_ELBEEM
- if(fluidmd)
- {
- if(fluidmd->fss->meshSurfNormals)
- {
- MEM_freeN(fluidmd->fss->meshSurfNormals);
- fluidmd->fss->meshSurfNormals = NULL;
- }
- MEM_freeN(fluidmd->fss);
- }
-#endif
- return;
-}
-
-DerivedMesh *fluidsimModifier_do(FluidsimModifierData *fluidmd, Scene *scene, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
-{
-#ifndef DISABLE_ELBEEM
- DerivedMesh *result = NULL;
- int framenr;
- FluidsimSettings *fss = NULL;
-
- framenr= (int)scene->r.cfra;
-
- // only handle fluidsim domains
- if(fluidmd && fluidmd->fss && (fluidmd->fss->type != OB_FLUIDSIM_DOMAIN))
- return dm;
-
- // sanity check
- if(!fluidmd || (fluidmd && !fluidmd->fss))
- return dm;
-
- fss = fluidmd->fss;
-
- // timescale not supported yet
- // clmd->sim_parms->timescale= timescale;
-
- // support reversing of baked fluid frames here
- if((fss->flag & OB_FLUIDSIM_REVERSE) && (fss->lastgoodframe >= 0))
- {
- framenr = fss->lastgoodframe - framenr + 1;
- CLAMP(framenr, 1, fss->lastgoodframe);
- }
-
- /* try to read from cache */
- if(((fss->lastgoodframe >= framenr) || (fss->lastgoodframe < 0)) && (result = fluidsim_read_cache(ob, dm, fluidmd, framenr, useRenderParams)))
- {
- // fss->lastgoodframe = framenr; // set also in src/fluidsim.c
- return result;
- }
- else
- {
- // display last known good frame
- if(fss->lastgoodframe >= 0)
- {
- if((result = fluidsim_read_cache(ob, dm, fluidmd, fss->lastgoodframe, useRenderParams)))
- {
- return result;
- }
-
- // it was supposed to be a valid frame but it isn't!
- fss->lastgoodframe = framenr - 1;
-
-
- // this could be likely the case when you load an old fluidsim
- if((result = fluidsim_read_cache(ob, dm, fluidmd, fss->lastgoodframe, useRenderParams)))
- {
- return result;
- }
- }
-
- result = CDDM_copy(dm, 0);
-
- if(result)
- {
- return result;
- }
- }
-
- return dm;
-#else
- return NULL;
-#endif
-}
-
-#ifndef DISABLE_ELBEEM
-/* read .bobj.gz file into a fluidsimDerivedMesh struct */
-static DerivedMesh *fluidsim_read_obj(char *filename)
-{
- int wri,i,j;
- float wrf;
- int gotBytes;
- gzFile gzf;
- int numverts = 0, numfaces = 0;
- DerivedMesh *dm = NULL;
- MFace *mface;
- MVert *mvert;
- short *normals;
-
- // ------------------------------------------------
- // get numverts + numfaces first
- // ------------------------------------------------
- gzf = gzopen(filename, "rb");
- if (!gzf)
- {
- return NULL;
- }
-
- // read numverts
- gotBytes = gzread(gzf, &wri, sizeof(wri));
- numverts = wri;
-
- // skip verts
- for(i=0; i<numverts*3; i++)
- {
- gotBytes = gzread(gzf, &wrf, sizeof( wrf ));
- }
-
- // read number of normals
- gotBytes = gzread(gzf, &wri, sizeof(wri));
-
- // skip normals
- for(i=0; i<numverts*3; i++)
- {
- gotBytes = gzread(gzf, &wrf, sizeof( wrf ));
- }
-
- /* get no. of triangles */
- gotBytes = gzread(gzf, &wri, sizeof(wri));
- numfaces = wri;
-
- gzclose( gzf );
- // ------------------------------------------------
-
- if(!numfaces || !numverts)
- return NULL;
-
- gzf = gzopen(filename, "rb");
- if (!gzf)
- {
- return NULL;
- }
-
- dm = CDDM_new(numverts, 0, numfaces, 0, 0);
-
- if(!dm)
- {
- gzclose( gzf );
- return NULL;
- }
-
- // read numverts
- gotBytes = gzread(gzf, &wri, sizeof(wri));
-
- // read vertex position from file
- mvert = CDDM_get_verts(dm);
- for(i=0; i<numverts; i++)
- {
- MVert *mv = &mvert[i];
-
- for(j=0; j<3; j++)
- {
- gotBytes = gzread(gzf, &wrf, sizeof( wrf ));
- mv->co[j] = wrf;
- }
- }
-
- // should be the same as numverts
- gotBytes = gzread(gzf, &wri, sizeof(wri));
- if(wri != numverts)
- {
- if(dm)
- dm->release(dm);
- gzclose( gzf );
- return NULL;
- }
-
- normals = MEM_callocN(sizeof(short) * numverts * 3, "fluid_tmp_normals" );
- if(!normals)
- {
- if(dm)
- dm->release(dm);
- gzclose( gzf );
- return NULL;
- }
-
- // read normals from file (but don't save them yet)
- for(i=0; i<numverts*3; i++)
- {
- gotBytes = gzread(gzf, &wrf, sizeof( wrf ));
- normals[i] = (short)(wrf*32767.0f);
- }
-
- /* read no. of triangles */
- gotBytes = gzread(gzf, &wri, sizeof(wri));
-
- if(wri!=numfaces)
- printf("Fluidsim: error in reading data from file.\n");
-
- // read triangles from file
- mface = CDDM_get_tessfaces(dm);
- for(i=0; i<numfaces; i++)
- {
- int face[4];
- MFace *mf = &mface[i];
-
- gotBytes = gzread(gzf, &(face[0]), sizeof( face[0] ));
- gotBytes = gzread(gzf, &(face[1]), sizeof( face[1] ));
- gotBytes = gzread(gzf, &(face[2]), sizeof( face[2] ));
- face[3] = 0;
-
- // check if 3rd vertex has index 0 (not allowed in blender)
- if(face[2])
- {
- mf->v1 = face[0];
- mf->v2 = face[1];
- mf->v3 = face[2];
- }
- else
- {
- mf->v1 = face[1];
- mf->v2 = face[2];
- mf->v3 = face[0];
- }
- mf->v4 = face[3];
-
- test_index_face(mf, NULL, 0, 3);
- }
-
- gzclose( gzf );
-
- CDDM_calc_edges(dm);
-
- CDDM_apply_vert_normals(dm, (short (*)[3])normals);
- MEM_freeN(normals);
-
- CDDM_tessfaces_to_faces(dm);
- // CDDM_calc_normals(result);
-
- return dm;
-}
-
-DerivedMesh *fluidsim_read_cache(Object *ob, DerivedMesh *orgdm, FluidsimModifierData *fluidmd, int framenr, int useRenderParams)
-{
- int displaymode = 0;
- int curFrame = framenr - 1 /*scene->r.sfra*/; /* start with 0 at start frame */
- char targetDir[FILE_MAXFILE+FILE_MAXDIR], targetFile[FILE_MAXFILE+FILE_MAXDIR];
- FluidsimSettings *fss = fluidmd->fss;
- DerivedMesh *dm = NULL;
- MFace *mface;
- int numfaces;
- int mat_nr, flag, i;
-
- if(!useRenderParams) {
- displaymode = fss->guiDisplayMode;
- } else {
- displaymode = fss->renderDisplayMode;
- }
-
- strncpy(targetDir, fss->surfdataPath, FILE_MAXDIR);
-
- // use preview or final mesh?
- if(displaymode==1)
- {
- // just display original object
- return NULL;
- }
- else if(displaymode==2)
- {
- strcat(targetDir,"fluidsurface_preview_####");
- }
- else
- { // 3
- strcat(targetDir,"fluidsurface_final_####");
- }
-
- BLI_convertstringcode(targetDir, G.sce);
- BLI_convertstringframe(targetDir, curFrame, 0); // fixed #frame-no
-
- strcpy(targetFile,targetDir);
- strcat(targetFile, ".bobj.gz");
-
- dm = fluidsim_read_obj(targetFile);
-
- if(!dm)
- {
- // switch, abort background rendering when fluidsim mesh is missing
- const char *strEnvName2 = "BLENDER_ELBEEMBOBJABORT"; // from blendercall.cpp
-
- if(G.background==1) {
- if(getenv(strEnvName2)) {
- int elevel = atoi(getenv(strEnvName2));
- if(elevel>0) {
- printf("Env. var %s set, fluid sim mesh '%s' not found, aborting render...\n",strEnvName2, targetFile);
- exit(1);
- }
- }
- }
-
- // display org. object upon failure which is in dm
- return NULL;
- }
-
- // assign material + flags to new dm
- mface = orgdm->getTessFaceArray(orgdm);
- mat_nr = mface[0].mat_nr;
- flag = mface[0].flag;
-
- mface = dm->getTessFaceArray(dm);
- numfaces = dm->getNumTessFaces(dm);
- for(i=0; i<numfaces; i++)
- {
- mface[i].mat_nr = mat_nr;
- mface[i].flag = flag;
- }
-
- // load vertex velocities, if they exist...
- // TODO? use generate flag as loading flag as well?
- // warning, needs original .bobj.gz mesh loading filename
- if(displaymode==3)
- {
- fluidsim_read_vel_cache(fluidmd, dm, targetFile);
- }
- else
- {
- if(fss->meshSurfNormals)
- MEM_freeN(fss->meshSurfNormals);
-
- fss->meshSurfNormals = NULL;
- }
-
- return dm;
-}
-
-
-/* read zipped fluidsim velocities into the co's of the fluidsimsettings normals struct */
-void fluidsim_read_vel_cache(FluidsimModifierData *fluidmd, DerivedMesh *dm, char *filename)
-{
- int wri, i, j;
- float wrf;
- gzFile gzf;
- FluidsimSettings *fss = fluidmd->fss;
- int len = strlen(filename);
- int totvert = dm->getNumVerts(dm);
- float *velarray = NULL;
-
- // mesh and vverts have to be valid from loading...
-
- if(fss->meshSurfNormals)
- MEM_freeN(fss->meshSurfNormals);
-
- if(len<7)
- {
- return;
- }
-
- if(fss->domainNovecgen>0) return;
-
- // abusing pointer to hold an array of 3d-velocities
- fss->meshSurfNormals = MEM_callocN(sizeof(float)*3*dm->getNumVerts(dm), "Fluidsim_velocities");
- // abusing pointer to hold an INT
- fss->meshSurface = SET_INT_IN_POINTER(totvert);
-
- velarray = (float *)fss->meshSurfNormals;
-
- // .bobj.gz , correct filename
- // 87654321
- filename[len-6] = 'v';
- filename[len-5] = 'e';
- filename[len-4] = 'l';
-
- gzf = gzopen(filename, "rb");
- if (!gzf)
- {
- MEM_freeN(fss->meshSurfNormals);
- fss->meshSurfNormals = NULL;
- return;
- }
-
- gzread(gzf, &wri, sizeof( wri ));
- if(wri != totvert)
- {
- MEM_freeN(fss->meshSurfNormals);
- fss->meshSurfNormals = NULL;
- return;
- }
-
- for(i=0; i<totvert;i++)
- {
- for(j=0; j<3; j++)
- {
- gzread(gzf, &wrf, sizeof( wrf ));
- velarray[3*i + j] = wrf;
- }
- }
-
- gzclose(gzf);
-}
-
-void fluid_get_bb(MVert *mvert, int totvert, float obmat[][4],
- /*RET*/ float start[3], /*RET*/ float size[3] )
-{
- float bbsx=0.0, bbsy=0.0, bbsz=0.0;
- float bbex=1.0, bbey=1.0, bbez=1.0;
- int i;
- float vec[3];
-
- if(totvert == 0) {
- zero_v3(start);
- zero_v3(size);
- return;
- }
-
- VECCOPY(vec, mvert[0].co);
- mul_m4_v3(obmat, vec);
- bbsx = vec[0]; bbsy = vec[1]; bbsz = vec[2];
- bbex = vec[0]; bbey = vec[1]; bbez = vec[2];
-
- for(i = 1; i < totvert; i++) {
- VECCOPY(vec, mvert[i].co);
- mul_m4_v3(obmat, vec);
-
- if(vec[0] < bbsx){ bbsx= vec[0]; }
- if(vec[1] < bbsy){ bbsy= vec[1]; }
- if(vec[2] < bbsz){ bbsz= vec[2]; }
- if(vec[0] > bbex){ bbex= vec[0]; }
- if(vec[1] > bbey){ bbey= vec[1]; }
- if(vec[2] > bbez){ bbez= vec[2]; }
- }
-
- // return values...
- if(start) {
- start[0] = bbsx;
- start[1] = bbsy;
- start[2] = bbsz;
- }
- if(size) {
- size[0] = bbex-bbsx;
- size[1] = bbey-bbsy;
- size[2] = bbez-bbsz;
- }
-}
-
-//-------------------------------------------------------------------------------
-// old interface
-//-------------------------------------------------------------------------------
-
-
-
//-------------------------------------------------------------------------------
// file handling
//-------------------------------------------------------------------------------
-void initElbeemMesh(struct Scene *scene, struct Object *ob,
- int *numVertices, float **vertices,
- int *numTriangles, int **triangles,
- int useGlobalCoords, int modifierIndex)
+void initElbeemMesh(struct Scene *scene, struct Object *ob,
+ int *numVertices, float **vertices,
+ int *numTriangles, int **triangles,
+ int useGlobalCoords, int modifierIndex)
{
DerivedMesh *dm = NULL;
MVert *mvert;
@@ -651,14 +108,14 @@ void initElbeemMesh(struct Scene *scene, struct Object *ob,
face[2] = mface[i].v3;
face[3] = mface[i].v4;
- tris[countTris*3+0] = face[0];
- tris[countTris*3+1] = face[1];
- tris[countTris*3+2] = face[2];
+ tris[countTris*3+0] = face[0];
+ tris[countTris*3+1] = face[1];
+ tris[countTris*3+2] = face[2];
countTris++;
- if(face[3]) {
- tris[countTris*3+0] = face[0];
- tris[countTris*3+1] = face[2];
- tris[countTris*3+2] = face[3];
+ if(face[3]) {
+ tris[countTris*3+0] = face[0];
+ tris[countTris*3+1] = face[2];
+ tris[countTris*3+2] = face[3];
countTris++;
}
}
@@ -666,21 +123,3 @@ void initElbeemMesh(struct Scene *scene, struct Object *ob,
dm->release(dm);
}
-
-void fluid_estimate_memory(Object *ob, FluidsimSettings *fss, char *value)
-{
- Mesh *mesh;
-
- value[0]= '\0';
-
- if(ob->type == OB_MESH) {
- /* use mesh bounding box and object scaling */
- mesh= ob->data;
-
- fluid_get_bb(mesh->mvert, mesh->totvert, ob->obmat, fss->bbStart, fss->bbSize);
- elbeemEstimateMemreq(fss->resolutionxyz, fss->bbSize[0],fss->bbSize[1],fss->bbSize[2], fss->maxRefine, value);
- }
-}
-
-#endif // DISABLE_ELBEEM
-
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index cee6d59488f..5829d462011 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -32,29 +32,19 @@
#include <string.h>
#include <float.h>
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
-#include "BLI_noise.h"
+#include "BLI_math.h" /* windows needs for M_PI */
#include "BKE_fcurve.h"
-#include "BKE_curve.h"
-#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_utildefines.h"
-#include "RNA_access.h"
-#include "RNA_types.h"
-
#ifndef DISABLE_PYTHON
-#include "BPY_extern.h" /* for BPY_pydriver_eval() */
+#include "BPY_extern.h" /* for BPY_eval_driver() */
#endif
#define SMALL -1.0e-10
@@ -311,10 +301,10 @@ static void fcm_fn_generator_new_data (void *mdata)
*/
static double sinc (double x)
{
- if (fabs(x) < 0.0001)
- return 1.0;
- else
- return sin(M_PI * x) / (M_PI * x);
+ if (fabs(x) < 0.0001)
+ return 1.0;
+ else
+ return sin(M_PI * x) / (M_PI * x);
}
static void fcm_fn_generator_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime)
@@ -871,6 +861,59 @@ static FModifierTypeInfo FMI_LIMITS = {
fcm_limits_evaluate /* evaluate */
};
+/* Stepped F-Curve Modifier --------------------------- */
+
+static void fcm_stepped_new_data (void *mdata)
+{
+ FMod_Stepped *data= (FMod_Stepped *)mdata;
+
+ /* just need to set the step-size to 2-frames by default */
+ // XXX: or would 5 be more normal?
+ data->step_size = 2.0f;
+}
+
+static float fcm_stepped_time (FCurve *fcu, FModifier *fcm, float cvalue, float evaltime)
+{
+ FMod_Stepped *data= (FMod_Stepped *)fcm->data;
+ int snapblock;
+
+ /* check range clamping to see if we should alter the timing to achieve the desired results */
+ if (data->flag & FCM_STEPPED_NO_BEFORE) {
+ if (evaltime < data->start_frame)
+ return evaltime;
+ }
+ if (data->flag & FCM_STEPPED_NO_AFTER) {
+ if (evaltime > data->end_frame)
+ return evaltime;
+ }
+
+ /* we snap to the start of the previous closest block of 'step_size' frames
+ * after the start offset has been discarded
+ * - i.e. round down
+ */
+ snapblock = (int)((evaltime - data->offset) / data->step_size);
+
+ /* reapply the offset, and multiple the snapblock by the size of the steps to get
+ * the new time to evaluate at
+ */
+ return ((float)snapblock * data->step_size) + data->offset;
+}
+
+static FModifierTypeInfo FMI_STEPPED = {
+ FMODIFIER_TYPE_STEPPED, /* type */
+ sizeof(FMod_Limits), /* size */
+ FMI_TYPE_GENERATE_CURVE, /* action type */ /* XXX... err... */
+ FMI_REQUIRES_RUNTIME_CHECK, /* requirements */
+ "Stepped", /* name */
+ "FMod_Stepped", /* struct name */
+ NULL, /* free data */
+ NULL, /* copy data */
+ fcm_stepped_new_data, /* new data */
+ NULL, /* verify */
+ fcm_stepped_time, /* evaluate time */
+ NULL /* evaluate */
+};
+
/* F-Curve Modifier API --------------------------- */
/* All of the F-Curve Modifier api functions use FModifierTypeInfo structs to carry out
* and operations that involve F-Curve modifier specific code.
@@ -892,6 +935,7 @@ static void fmods_init_typeinfo ()
fmodifiersTypeInfo[6]= NULL/*&FMI_FILTER*/; /* Filter F-Curve Modifier */ // XXX unimplemented
fmodifiersTypeInfo[7]= &FMI_PYTHON; /* Custom Python F-Curve Modifier */
fmodifiersTypeInfo[8]= &FMI_LIMITS; /* Limits F-Curve Modifier */
+ fmodifiersTypeInfo[9]= &FMI_STEPPED; /* Stepped F-Curve Modifier */
}
/* This function should be used for getting the appropriate type-info when only
@@ -968,6 +1012,31 @@ FModifier *add_fmodifier (ListBase *modifiers, int type)
return fcm;
}
+/* Make a copy of the specified F-Modifier */
+FModifier *copy_fmodifier (FModifier *src)
+{
+ FModifierTypeInfo *fmi= fmodifier_get_typeinfo(src);
+ FModifier *dst;
+
+ /* sanity check */
+ if (src == NULL)
+ return NULL;
+
+ /* copy the base data, clearing the links */
+ dst = MEM_dupallocN(src);
+ dst->next = dst->prev = NULL;
+
+ /* make a new copy of the F-Modifier's data */
+ dst->data = MEM_dupallocN(src->data);
+
+ /* only do specific constraints if required */
+ if (fmi && fmi->copy_data)
+ fmi->copy_data(dst, src);
+
+ /* return the new modifier */
+ return dst;
+}
+
/* Duplicate all of the F-Modifiers in the Modifier stacks */
void copy_fmodifiers (ListBase *dst, ListBase *src)
{
@@ -1132,14 +1201,20 @@ short list_has_suitable_fmodifier (ListBase *modifiers, int mtype, short acttype
float evaluate_time_fmodifiers (ListBase *modifiers, FCurve *fcu, float cvalue, float evaltime)
{
FModifier *fcm;
- float m_evaltime= evaltime;
/* sanity checks */
if ELEM(NULL, modifiers, modifiers->last)
return evaltime;
- /* find the first modifier from end of stack that modifies time, and calculate the time the modifier
- * would calculate time at
+ /* Starting from the end of the stack, calculate the time effects of various stacked modifiers
+ * on the time the F-Curve should be evaluated at.
+ *
+ * This is done in reverse order to standard evaluation, as when this is done in standard
+ * order, each modifier would cause jumps to other points in the curve, forcing all
+ * previous ones to be evaluated again for them to be correct. However, if we did in the
+ * reverse order as we have here, we can consider them a macro to micro type of waterfall
+ * effect, which should get us the desired effects when using layered time manipulations
+ * (such as multiple 'stepped' modifiers in sequence, causing different stepping rates)
*/
for (fcm= modifiers->last; fcm; fcm= fcm->prev) {
FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
@@ -1148,13 +1223,12 @@ float evaluate_time_fmodifiers (ListBase *modifiers, FCurve *fcu, float cvalue,
// TODO: implement the 'influence' control feature...
if (fmi && fmi->evaluate_modifier_time) {
if ((fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED)) == 0)
- m_evaltime= fmi->evaluate_modifier_time(fcu, fcm, cvalue, evaltime);
- break;
+ evaltime= fmi->evaluate_modifier_time(fcu, fcm, cvalue, evaltime);
}
}
/* return the modified evaltime */
- return m_evaltime;
+ return evaltime;
}
/* Evalautes the given set of F-Curve Modifiers using the given data
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 36bb031744e..a99f2599f66 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -1,4 +1,4 @@
-/* font.c
+/* font.c
*
*
* $Id$
@@ -34,10 +34,7 @@
#include <math.h>
#include <stdlib.h>
#include <wchar.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include <wctype.h>
#include "MEM_guardedalloc.h"
@@ -47,8 +44,6 @@
#include "DNA_packedFile_types.h"
#include "DNA_curve_types.h"
-#include "DNA_object_types.h"
-#include "DNA_view3d_types.h"
#include "DNA_vfont_types.h"
#include "DNA_scene_types.h"
@@ -60,7 +55,6 @@
#include "BKE_font.h"
#include "BKE_global.h"
#include "BKE_main.h"
-#include "BKE_screen.h"
#include "BKE_anim.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
@@ -163,7 +157,7 @@ According to RFC 3629 "UTF-8, a transformation format of ISO 10646"
(http://tools.ietf.org/html/rfc3629), the valid UTF-8 encoding are:
Char. number range | UTF-8 octet sequence
- (hexadecimal) | (binary)
+ (hexadecimal) | (binary)
--------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
@@ -205,7 +199,7 @@ int utf8towchar(wchar_t *w, char *c)
*w = '?';
}
} else
- *w=(c[0] & 0x7f);
+ *w=(c[0] & 0x7f);
c++;
w++;
@@ -433,12 +427,12 @@ VFont *load_vfont(char *name)
static VFont *which_vfont(Curve *cu, CharInfo *info)
{
- switch(info->flag & CU_STYLE) {
- case CU_BOLD:
+ switch(info->flag & (CU_CHINFO_BOLD|CU_CHINFO_ITALIC)) {
+ case CU_CHINFO_BOLD:
if (cu->vfontb) return(cu->vfontb); else return(cu->vfont);
- case CU_ITALIC:
+ case CU_CHINFO_ITALIC:
if (cu->vfonti) return(cu->vfonti); else return(cu->vfont);
- case (CU_BOLD|CU_ITALIC):
+ case (CU_CHINFO_BOLD|CU_CHINFO_ITALIC):
if (cu->vfontbi) return(cu->vfontbi); else return(cu->vfont);
default:
return(cu->vfont);
@@ -456,6 +450,17 @@ VFont *get_builtin_font(void)
return load_vfont("<builtin>");
}
+static VChar *find_vfont_char(VFontData *vfd, intptr_t character)
+{
+ VChar *che= NULL;
+
+ for(che = vfd->characters.first; che; che = che->next) {
+ if(che->index == character)
+ break;
+ }
+ return che; /* NULL if not found */
+}
+
static void build_underline(Curve *cu, float x1, float y1, float x2, float y2, int charidx, short mat_nr)
{
Nurb *nu2;
@@ -473,7 +478,7 @@ static void build_underline(Curve *cu, float x1, float y1, float x2, float y2, i
nu2->pntsv = 1;
nu2->orderu = 4;
nu2->orderv = 1;
- nu2->flagu = CU_CYCLIC;
+ nu2->flagu = CU_NURB_CYCLIC;
bp = (BPoint*)MEM_callocN(4 * sizeof(BPoint),"underline_bp");
if (bp == 0){
@@ -530,14 +535,7 @@ static void buildchar(Curve *cu, unsigned long character, CharInfo *info, float
si= (float)sin(rot);
co= (float)cos(rot);
- // Find the correct character from the font
- che = vfd->characters.first;
- while(che)
- {
- if(che->index == character)
- break;
- che = che->next;
- }
+ che= find_vfont_char(vfd, character);
// Select the glyph data
if(che)
@@ -604,9 +602,23 @@ static void buildchar(Curve *cu, unsigned long character, CharInfo *info, float
}
bezt2 = nu2->bezt;
+ if(info->flag & CU_CHINFO_SMALLCAPS_CHECK) {
+ const float sca= cu->smallcaps_scale;
+ for (i= nu2->pntsu; i > 0; i--) {
+ fp= bezt2->vec[0];
+ fp[0] *= sca;
+ fp[1] *= sca;
+ fp[3] *= sca;
+ fp[4] *= sca;
+ fp[6] *= sca;
+ fp[7] *= sca;
+ bezt2++;
+ }
+ }
+ bezt2 = nu2->bezt;
+
for (i= nu2->pntsu; i > 0; i--) {
fp= bezt2->vec[0];
-
fp[0]= (fp[0]+ofsx)*fsize;
fp[1]= (fp[1]+ofsy)*fsize;
fp[3]= (fp[3]+ofsx)*fsize;
@@ -642,6 +654,20 @@ int BKE_font_getselection(Object *ob, int *start, int *end)
}
}
+static float char_width(Curve *cu, VChar *che, CharInfo *info)
+{
+ // The character wasn't found, propably ascii = 0, then the width shall be 0 as well
+ if(che == NULL) {
+ return 0.0f;
+ }
+ else if(info->flag & CU_CHINFO_SMALLCAPS_CHECK) {
+ return che->width * cu->smallcaps_scale;
+ }
+ else {
+ return che->width;
+ }
+}
+
struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
{
VFont *vfont, *oldvfont;
@@ -723,7 +749,7 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
oldvfont = NULL;
- for (i=0; i<slen; i++) custrinfo[i].flag &= ~CU_WRAP;
+ for (i=0; i<slen; i++) custrinfo[i].flag &= ~(CU_CHINFO_WRAP|CU_CHINFO_SMALLCAPS_CHECK);
if (cu->selboxes) MEM_freeN(cu->selboxes);
cu->selboxes = NULL;
@@ -736,18 +762,21 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
makebreak:
// Characters in the list
che = vfd->characters.first;
- ascii = mem[i];
info = &(custrinfo[i]);
+ ascii = mem[i];
+ if(info->flag & CU_CHINFO_SMALLCAPS) {
+ ascii = towupper(ascii);
+ if(mem[i] != ascii) {
+ mem[i]= ascii;
+ info->flag |= CU_CHINFO_SMALLCAPS_CHECK;
+ }
+ }
+
vfont = which_vfont(cu, info);
if(vfont==NULL) break;
-
- // Find the character
- while(che) {
- if(che->index == ascii)
- break;
- che = che->next;
- }
+
+ che= find_vfont_char(vfd, ascii);
/*
* The character wasn't in the current curve base so load it
@@ -759,12 +788,7 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
}
/* Try getting the character again from the list */
- che = vfd->characters.first;
- while(che) {
- if(che->index == ascii)
- break;
- che = che->next;
- }
+ che= find_vfont_char(vfd, ascii);
/* No VFont found */
if (vfont==0) {
@@ -787,11 +811,7 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
return 0;
}
- // The character wasn't found, propably ascii = 0, then the width shall be 0 as well
- if(!che)
- twidth = 0;
- else
- twidth = che->width;
+ twidth = char_width(cu, che, info);
// Calculate positions
if((tb->w != 0.0) && (ct->dobreak==0) && ((xof-(tb->x/cu->fsize)+twidth)*cu->fsize) > tb->w) {
@@ -805,13 +825,13 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
i = j-1;
xof = ct->xof;
ct[1].dobreak = 1;
- custrinfo[i+1].flag |= CU_WRAP;
+ custrinfo[i+1].flag |= CU_CHINFO_WRAP;
goto makebreak;
}
if (chartransdata[j].dobreak) {
// fprintf(stderr, "word too long: %c%c%c...\n", mem[j], mem[j+1], mem[j+2]);
ct->dobreak= 1;
- custrinfo[i+1].flag |= CU_WRAP;
+ custrinfo[i+1].flag |= CU_CHINFO_WRAP;
ct -= 1;
cnr -= 1;
i--;
@@ -835,8 +855,8 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
linedata4[lnr]= wsnr;
if ( (tb->h != 0.0) &&
- ((-(yof-(tb->y/cu->fsize))) > ((tb->h/cu->fsize)-(linedist*cu->fsize))) &&
- (cu->totbox > (curbox+1)) ) {
+ ((-(yof-(tb->y/cu->fsize))) > ((tb->h/cu->fsize)-(linedist*cu->fsize))) &&
+ (cu->totbox > (curbox+1)) ) {
maxlen= 0;
tb++;
curbox++;
@@ -888,10 +908,7 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
else wsfac = 1.0;
// Set the width of the character
- if(!che)
- twidth = 0;
- else
- twidth = che->width;
+ twidth = char_width(cu, che, info);
xof += (twidth*wsfac*(1.0+(info->kern/40.0)) ) + xtrax;
@@ -930,13 +947,13 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
ct++;
}
} else if((cu->spacemode==CU_FLUSH) &&
- (cu->tb[0].w != 0.0)) {
+ (cu->tb[0].w != 0.0)) {
for(i=0;i<lnr;i++)
if(linedata2[i]>1)
linedata[i]= (linedata3[i]-linedata[i])/(linedata2[i]-1);
for (i=0; i<=slen; i++) {
for (j=i; (mem[j]) && (mem[j]!='\n') &&
- (mem[j]!='\r') && (chartransdata[j].dobreak==0) && (j<slen); j++);
+ (mem[j]!='\r') && (chartransdata[j].dobreak==0) && (j<slen); j++);
// if ((mem[j]!='\r') && (mem[j]!='\n') && (mem[j])) {
ct->xof+= ct->charnr*linedata[ct->linenr];
// }
@@ -947,10 +964,10 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
float curofs= 0.0f;
for (i=0; i<=slen; i++) {
for (j=i; (mem[j]) && (mem[j]!='\n') &&
- (mem[j]!='\r') && (chartransdata[j].dobreak==0) && (j<slen); j++);
+ (mem[j]!='\r') && (chartransdata[j].dobreak==0) && (j<slen); j++);
if ((mem[j]!='\r') && (mem[j]!='\n') &&
- ((chartransdata[j].dobreak!=0))) {
- if (mem[i]==' ') curofs += (linedata3[ct->linenr]-linedata[ct->linenr])/linedata4[ct->linenr];
+ ((chartransdata[j].dobreak!=0))) {
+ if (mem[i]==' ') curofs += (linedata3[ct->linenr]-linedata[ct->linenr])/linedata4[ct->linenr];
ct->xof+= curofs;
}
if (mem[i]=='\n' || mem[i]=='\r' || chartransdata[i].dobreak) curofs= 0;
@@ -960,7 +977,8 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
}
/* TEXT ON CURVE */
- if(cu->textoncurve) {
+ /* Note: Only OB_CURVE objects could have a path */
+ if(cu->textoncurve && cu->textoncurve->type==OB_CURVE) {
Curve *cucu= cu->textoncurve->data;
int oldflag= cucu->flag;
@@ -1021,19 +1039,10 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
/* rotate around center character */
ascii = mem[i];
-
- // Find the character
- che = vfd->characters.first;
- while(che) {
- if(che->index == ascii)
- break;
- che = che->next;
- }
+
+ che= find_vfont_char(vfd, ascii);
- if(che)
- twidth = che->width;
- else
- twidth = 0;
+ twidth = char_width(cu, che, info);
dtime= distfac*0.35f*twidth; /* why not 0.5? */
dtime= distfac*0.5f*twidth; /* why not 0.5? */
@@ -1043,8 +1052,8 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
/* calc the right loc AND the right rot separately */
/* vec, tvec need 4 items */
- where_on_path(cu->textoncurve, ctime, vec, tvec, NULL, NULL);
- where_on_path(cu->textoncurve, ctime+dtime, tvec, rotvec, NULL, NULL);
+ where_on_path(cu->textoncurve, ctime, vec, tvec, NULL, NULL, NULL);
+ where_on_path(cu->textoncurve, ctime+dtime, tvec, rotvec, NULL, NULL, NULL);
mul_v3_fl(vec, sizefac);
@@ -1157,24 +1166,19 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
if(cha != '\n' && cha != '\r')
buildchar(cu, cha, info, ct->xof, ct->yof, ct->rot, i);
- if ((info->flag & CU_UNDERLINE) && (cu->textoncurve == NULL) && (cha != '\n') && (cha != '\r')) {
+ if ((info->flag & CU_CHINFO_UNDERLINE) && (cu->textoncurve == NULL) && (cha != '\n') && (cha != '\r')) {
float ulwidth, uloverlap= 0.0f;
if ( (i<(slen-1)) && (mem[i+1] != '\n') && (mem[i+1] != '\r') &&
- ((mem[i+1] != ' ') || (custrinfo[i+1].flag & CU_UNDERLINE)) && ((custrinfo[i+1].flag & CU_WRAP)==0)
+ ((mem[i+1] != ' ') || (custrinfo[i+1].flag & CU_CHINFO_UNDERLINE)) && ((custrinfo[i+1].flag & CU_CHINFO_WRAP)==0)
) {
uloverlap = xtrax + 0.1;
}
// Find the character, the characters has to be in the memory already
// since character checking has been done earlier already.
- che = vfd->characters.first;
- while(che) {
- if(che->index == cha)
- break;
- che = che->next;
- }
-
- if(!che) twidth =0; else twidth=che->width;
+ che= find_vfont_char(vfd, cha);
+
+ twidth = char_width(cu, che, info);
ulwidth = cu->fsize * ((twidth* (1.0+(info->kern/40.0)))+uloverlap);
build_underline(cu, ct->xof*cu->fsize, ct->yof*cu->fsize + (cu->ulpos-0.05)*cu->fsize,
ct->xof*cu->fsize + ulwidth,
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index c65961d0953..5612d69ed76 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -33,27 +33,13 @@
#include "MEM_guardedalloc.h"
-#include "IMB_imbuf.h"
-#include "IMB_imbuf_types.h"
-#include "BLI_math.h"
#include "BLI_blenlib.h"
-#include "DNA_listBase.h"
#include "DNA_gpencil_types.h"
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
-#include "DNA_userdef_types.h"
-#include "DNA_vec_types.h"
-#include "BKE_blender.h"
-#include "BKE_context.h"
-#include "BKE_curve.h"
#include "BKE_global.h"
#include "BKE_gpencil.h"
-#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_utildefines.h"
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index 4f768bbad23..6377a6f6ccd 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -29,14 +29,11 @@
#include <stdio.h>
#include <string.h>
+#include <math.h>
#include "MEM_guardedalloc.h"
-#include "DNA_action_types.h"
-#include "DNA_effect_types.h"
#include "DNA_group_types.h"
-#include "DNA_ID.h"
-#include "DNA_ipo_types.h"
#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "DNA_nla_types.h"
@@ -47,16 +44,11 @@
#include "BKE_global.h"
#include "BKE_group.h"
-#include "BKE_ipo.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_object.h"
#include "BKE_scene.h" /* object_in_scene */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
static void free_group_object(GroupObject *go)
{
MEM_freeN(go);
@@ -288,6 +280,7 @@ int group_is_animated(Object *parent, Group *group)
return 0;
}
+#if 0 // add back when timeoffset & animsys work again
/* only replaces object strips or action when parent nla instructs it */
/* keep checking nla.c though, in case internal structure of strip changes */
static void group_replaces_nla(Object *parent, Object *target, char mode)
@@ -327,6 +320,7 @@ static void group_replaces_nla(Object *parent, Object *target, char mode)
}
}
}
+#endif
/* puts all group members in local timing system, after this call
you can draw everything, leaves tags in objects to signal it needs further updating */
@@ -336,13 +330,18 @@ void group_handle_recalc_and_update(Scene *scene, Object *parent, Group *group)
{
GroupObject *go;
+#if 0 /* warning, isnt clearing the recalc flag on the object which causes it to run all the time,
+ * not just on frame change.
+ * This isnt working because the animation data is only re-evalyated on frame change so commenting for now
+ * but when its enabled at some point it will need to be changed so as not to update so much - campbell */
+
/* if animated group... */
if(give_timeoffset(parent) != 0.0f || parent->nlastrips.first) {
int cfrao;
/* switch to local time */
cfrao= scene->r.cfra;
- scene->r.cfra -= (int)give_timeoffset(parent);
+ scene->r.cfra -= (int)floor(give_timeoffset(parent) + 0.5f);
/* we need a DAG per group... */
for(go= group->gobject.first; go; go= go->next) {
@@ -361,7 +360,9 @@ void group_handle_recalc_and_update(Scene *scene, Object *parent, Group *group)
/* restore */
scene->r.cfra= cfrao;
}
- else {
+ else
+#endif
+ {
/* only do existing tags, as set by regular depsgraph */
for(go= group->gobject.first; go; go= go->next) {
if(go->ob) {
diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c
index 1f22e8c1e3f..ad2c857be75 100644
--- a/source/blender/blenkernel/intern/icons.c
+++ b/source/blender/blenkernel/intern/icons.c
@@ -32,23 +32,17 @@
#include <stdlib.h>
#include <string.h>
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include "MEM_guardedalloc.h"
-#include "DNA_ID.h"
-#include "DNA_image_types.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_texture_types.h"
#include "DNA_world_types.h"
+#include "DNA_brush_types.h"
#include "BLI_ghash.h"
#include "BKE_icons.h"
-#include "BKE_utildefines.h"
#include "BKE_global.h" /* only for G.background test */
#include "BLO_sys_types.h" // for intptr_t support
@@ -108,7 +102,7 @@ void BKE_icons_init(int first_dyn_id)
gFirstIconId = first_dyn_id;
if (!gIcons)
- gIcons = BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp);
+ gIcons = BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "icons_init gh");
}
void BKE_icons_free()
@@ -127,6 +121,7 @@ struct PreviewImage* BKE_previewimg_create()
for (i=0; i<PREVIEW_MIPMAPS; ++i) {
prv_img->changed[i] = 1;
+ prv_img->changed_timestamp[i] = 0;
}
return prv_img;
}
@@ -209,7 +204,7 @@ PreviewImage* BKE_previewimg_get(ID *id)
Image *img = (Image*)id;
if (!img->preview) img->preview = BKE_previewimg_create();
prv_img = img->preview;
- }
+ }
return prv_img;
}
@@ -231,6 +226,7 @@ void BKE_icon_changed(int id)
int i;
for (i=0; i<PREVIEW_MIPMAPS; ++i) {
prv->changed[i] = 1;
+ prv->changed_timestamp[i]++;
}
}
}
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 37aee8fb4aa..2ccb33b088a 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -1,5 +1,5 @@
/**
- * $Id: idprop.c
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -29,13 +29,8 @@
#include <stdlib.h>
#include <string.h>
-#include "DNA_listBase.h"
-#include "DNA_ID.h"
-
#include "BKE_idprop.h"
-#include "BKE_global.h"
#include "BKE_library.h"
-#include "BKE_utildefines.h"
#include "BLI_blenlib.h"
@@ -294,16 +289,44 @@ IDProperty *IDP_CopyArray(IDProperty *prop)
/*taken from readfile.c*/
#define SWITCH_LONGINT(a) { \
- char s_i, *p_i; \
- p_i= (char *)&(a); \
- s_i=p_i[0]; p_i[0]=p_i[7]; p_i[7]=s_i; \
- s_i=p_i[1]; p_i[1]=p_i[6]; p_i[6]=s_i; \
- s_i=p_i[2]; p_i[2]=p_i[5]; p_i[5]=s_i; \
- s_i=p_i[3]; p_i[3]=p_i[4]; p_i[4]=s_i; }
+ char s_i, *p_i; \
+ p_i= (char *)&(a); \
+ s_i=p_i[0]; p_i[0]=p_i[7]; p_i[7]=s_i; \
+ s_i=p_i[1]; p_i[1]=p_i[6]; p_i[6]=s_i; \
+ s_i=p_i[2]; p_i[2]=p_i[5]; p_i[5]=s_i; \
+ s_i=p_i[3]; p_i[3]=p_i[4]; p_i[4]=s_i; }
/* ---------- String Type ------------ */
+IDProperty *IDP_NewString(const char *st, const char *name, int maxlen)
+{
+ IDProperty *prop = MEM_callocN(sizeof(IDProperty), "IDProperty string");
+
+ if (st == NULL) {
+ prop->data.pointer = MEM_callocN(DEFAULT_ALLOC_FOR_NULL_STRINGS, "id property string 1");
+ prop->totallen = DEFAULT_ALLOC_FOR_NULL_STRINGS;
+ prop->len = 1; /*NULL string, has len of 1 to account for null byte.*/
+ }
+ else {
+ int stlen = strlen(st);
+
+ if(maxlen > 0 && maxlen < stlen)
+ stlen = maxlen;
+
+ stlen++; /* null terminator '\0' */
+
+ prop->data.pointer = MEM_callocN(stlen, "id property string 2");
+ prop->len = prop->totallen = stlen;
+ BLI_strncpy(prop->data.pointer, st, stlen);
+ }
+
+ prop->type = IDP_STRING;
+ BLI_strncpy(prop->name, name, MAX_IDPROP_NAME);
+
+ return prop;
+}
+
IDProperty *IDP_CopyString(IDProperty *prop)
{
IDProperty *newp = idp_generic_copy(prop);
@@ -317,14 +340,19 @@ IDProperty *IDP_CopyString(IDProperty *prop)
}
-void IDP_AssignString(IDProperty *prop, char *st)
+void IDP_AssignString(IDProperty *prop, char *st, int maxlen)
{
int stlen;
stlen = strlen(st);
- IDP_ResizeArray(prop, stlen+1); /*make room for null byte :) */
- strcpy(prop->data.pointer, st);
+ if(maxlen > 0 && maxlen < stlen)
+ stlen= maxlen;
+
+ stlen++; /* make room for null byte */
+
+ IDP_ResizeArray(prop, stlen);
+ BLI_strncpy(prop->data.pointer, st, stlen);
}
void IDP_ConcatStringC(IDProperty *prop, char *st)
@@ -714,9 +742,6 @@ IDProperty *IDP_New(int type, IDPropertyTemplate val, const char *name)
prop->type = type;
BLI_strncpy(prop->name, name, MAX_IDPROP_NAME);
- /*security null byte*/
- prop->name[MAX_IDPROP_NAME-1] = 0;
-
return prop;
}
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index accadb3d434..b66b5c60916 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -1,4 +1,4 @@
-/* image.c
+/* image.c
*
* $Id$
*
@@ -52,16 +52,12 @@
#include "intern/openexr/openexr_multi.h"
#endif
-#include "DNA_image_types.h"
#include "DNA_packedFile_types.h"
#include "DNA_scene_types.h"
#include "DNA_camera_types.h"
#include "DNA_sequence_types.h"
-#include "DNA_texture_types.h"
-#include "DNA_sequence_types.h"
#include "DNA_userdef_types.h"
-#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_threads.h"
@@ -73,8 +69,6 @@
#include "BKE_main.h"
#include "BKE_packedFile.h"
#include "BKE_scene.h"
-#include "BKE_texture.h"
-#include "BKE_utildefines.h"
//XXX #include "BIF_editseq.h"
@@ -84,7 +78,6 @@
#include "RE_pipeline.h"
-#include "GPU_extensions.h"
#include "GPU_draw.h"
#include "BLO_sys_types.h" // for intptr_t support
@@ -99,58 +92,6 @@
/* ******** IMAGE PROCESSING ************* */
-/* used by sequencer and image premul option - IMA_DO_PREMUL */
-void converttopremul(struct ImBuf *ibuf)
-{
- int x, y;
-
- if(ibuf==0) return;
- if (ibuf->rect) {
- int val;
- char *cp;
- if(ibuf->depth==24) { /* put alpha at 255 */
- cp= (char *)(ibuf->rect);
- for(y=0; y<ibuf->y; y++) {
- for(x=0; x<ibuf->x; x++, cp+=4) {
- cp[3]= 255;
- }
- }
- } else {
- cp= (char *)(ibuf->rect);
- for(y=0; y<ibuf->y; y++) {
- for(x=0; x<ibuf->x; x++, cp+=4) {
- val= cp[3];
- cp[0]= (cp[0]*val)>>8;
- cp[1]= (cp[1]*val)>>8;
- cp[2]= (cp[2]*val)>>8;
- }
- }
- }
- }
- if (ibuf->rect_float) {
- float val;
- float *cp;
- if(ibuf->depth==24) { /* put alpha at 1.0 */
- cp= ibuf->rect_float;;
- for(y=0; y<ibuf->y; y++) {
- for(x=0; x<ibuf->x; x++, cp+=4) {
- cp[3]= 1.0;
- }
- }
- } else {
- cp= ibuf->rect_float;
- for(y=0; y<ibuf->y; y++) {
- for(x=0; x<ibuf->x; x++, cp+=4) {
- val= cp[3];
- cp[0]= cp[0]*val;
- cp[1]= cp[1]*val;
- cp[2]= cp[2]*val;
- }
- }
- }
- }
-}
-
static void de_interlace_ng(struct ImBuf *ibuf) /* neogeo fields */
{
struct ImBuf * tbuf1, * tbuf2;
@@ -236,7 +177,7 @@ static void image_free_buffers(Image *ima)
if(ima->anim) IMB_free_anim(ima->anim);
ima->anim= NULL;
-
+
if(ima->rr) {
RE_FreeRenderResult(ima->rr);
ima->rr= NULL;
@@ -250,6 +191,8 @@ static void image_free_buffers(Image *ima)
/* called by library too, do not free ima itself */
void free_image(Image *ima)
{
+ int a;
+
image_free_buffers(ima);
if (ima->packedfile) {
freePackedFile(ima->packedfile);
@@ -257,12 +200,14 @@ void free_image(Image *ima)
}
BKE_icon_delete(&ima->id);
ima->id.icon_id = 0;
- if (ima->preview) {
- BKE_previewimg_free(&ima->preview);
- }
- if (ima->render_text) {
- MEM_freeN(ima->render_text);
- ima->render_text= NULL;
+
+ BKE_previewimg_free(&ima->preview);
+
+ for(a=0; a<IMA_MAX_RENDER_SLOT; a++) {
+ if(ima->renders[a]) {
+ RE_FreeRenderResult(ima->renders[a]);
+ ima->renders[a]= NULL;
+ }
}
}
@@ -383,15 +328,8 @@ Image *BKE_add_image_file(const char *name, int frame)
const char *libname;
char str[FILE_MAX], strtest[FILE_MAX];
- /* escape when name is directory */
- len= strlen(name);
- if(len) {
- if(name[len-1]=='/' || name[len-1]=='\\')
- return NULL;
- }
-
BLI_strncpy(str, name, sizeof(str));
- BLI_convertstringcode(str, G.sce);
+ BLI_path_abs(str, G.sce);
/* exists? */
file= open(str, O_BINARY|O_RDONLY);
@@ -402,7 +340,7 @@ Image *BKE_add_image_file(const char *name, int frame)
for(ima= G.main->image.first; ima; ima= ima->id.next) {
if(ima->source!=IMA_SRC_VIEWER && ima->source!=IMA_SRC_GENERATED) {
BLI_strncpy(strtest, ima->name, sizeof(ima->name));
- BLI_convertstringcode(strtest, G.sce);
+ BLI_path_abs(strtest, G.sce);
if( strcmp(strtest, str)==0 ) {
if(ima->anim==NULL || ima->id.us==0) {
@@ -435,138 +373,43 @@ Image *BKE_add_image_file(const char *name, int frame)
return ima;
}
-static ImBuf *add_ibuf_size(int width, int height, char *name, int floatbuf, short uvtestgrid, float color[4])
+static ImBuf *add_ibuf_size(int width, int height, char *name, int depth, int floatbuf, short uvtestgrid, float color[4])
{
ImBuf *ibuf;
- float h=0.0, hoffs=0.0, hue=0.0, s=0.9, v=0.9, r, g, b;
unsigned char *rect= NULL;
float *rect_float= NULL;
- int x, y;
- int checkerwidth=32, dark=1;
if (floatbuf) {
- ibuf= IMB_allocImBuf(width, height, 24, IB_rectfloat, 0);
+ ibuf= IMB_allocImBuf(width, height, depth, IB_rectfloat, 0);
rect_float= (float*)ibuf->rect_float;
}
else {
- ibuf= IMB_allocImBuf(width, height, 24, IB_rect, 0);
+ ibuf= IMB_allocImBuf(width, height, depth, IB_rect, 0);
rect= (unsigned char*)ibuf->rect;
}
strcpy(ibuf->name, "//Untitled");
ibuf->userflags |= IB_BITMAPDIRTY;
- if (uvtestgrid) {
- /* these two passes could be combined into one, but it's more readable and
- * easy to tweak like this, speed isn't really that much of an issue in this situation... */
-
- /* checkers */
- for(y=0; y<height; y++) {
- dark = powf(-1.0f, floorf(y / checkerwidth));
-
- for(x=0; x<width; x++) {
- if (x % checkerwidth == 0) dark *= -1;
-
- if (floatbuf) {
- if (dark > 0) {
- rect_float[0] = rect_float[1] = rect_float[2] = 0.25f;
- rect_float[3] = 1.0f;
- } else {
- rect_float[0] = rect_float[1] = rect_float[2] = 0.58f;
- rect_float[3] = 1.0f;
- }
- rect_float+=4;
- }
- else {
- if (dark > 0) {
- rect[0] = rect[1] = rect[2] = 64;
- rect[3] = 255;
- } else {
- rect[0] = rect[1] = rect[2] = 150;
- rect[3] = 255;
- }
- rect += 4;
- }
- }
- }
-
- /* 2nd pass, colored + */
- if (floatbuf) rect_float= (float*)ibuf->rect_float;
- else rect= (unsigned char*)ibuf->rect;
-
- for(y=0; y<height; y++) {
- hoffs = 0.125f * floorf(y / checkerwidth);
-
- for(x=0; x<width; x++) {
- h = 0.125f * floorf(x / checkerwidth);
-
- if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 4) &&
- (fabs((y % checkerwidth) - (checkerwidth / 2)) < 4)) {
-
- if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 1) ||
- (fabs((y % checkerwidth) - (checkerwidth / 2)) < 1)) {
-
- hue = fmodf(fabs(h-hoffs), 1.0f);
- hsv_to_rgb(hue, s, v, &r, &g, &b);
-
- if (floatbuf) {
- rect_float[0]= r;
- rect_float[1]= g;
- rect_float[2]= b;
- rect_float[3]= 1.0f;
- }
- else {
- rect[0]= (char)(r * 255.0f);
- rect[1]= (char)(g * 255.0f);
- rect[2]= (char)(b * 255.0f);
- rect[3]= 255;
- }
- }
- }
-
- if (floatbuf)
- rect_float+=4;
- else
- rect+=4;
- }
- }
- } else { /* blank image */
- char ccol[4];
-
- ccol[0]= (char)(color[0]*255.0f);
- ccol[1]= (char)(color[1]*255.0f);
- ccol[2]= (char)(color[2]*255.0f);
- ccol[3]= (char)(color[3]*255.0f);
-
- for(y=0; y<height; y++) {
- for(x=0; x<width; x++) {
- if (floatbuf) {
- rect_float[0]= color[0];
- rect_float[1]= color[1];
- rect_float[2]= color[2];
- rect_float[3]= color[3];
- rect_float+=4;
- }
- else {
- rect[0]= ccol[0];
- rect[1]= ccol[1];
- rect[2]= ccol[2];
- rect[3]= ccol[3];
- rect+=4;
- }
- }
- }
+ switch(uvtestgrid) {
+ case 1:
+ BKE_image_buf_fill_checker(rect, rect_float, width, height);
+ break;
+ case 2:
+ BKE_image_buf_fill_checker_color(rect, rect_float, width, height);
+ break;
+ default:
+ BKE_image_buf_fill_color(rect, rect_float, width, height, color);
}
+
return ibuf;
}
/* adds new image block, creates ImBuf and initializes color */
-Image *BKE_add_image_size(int width, int height, char *name, int floatbuf, short uvtestgrid, float color[4])
+Image *BKE_add_image_size(int width, int height, char *name, int depth, int floatbuf, short uvtestgrid, float color[4])
{
- Image *ima;
-
/* on save, type is changed to FILE in editsima.c */
- ima= image_alloc(name, IMA_SRC_GENERATED, IMA_TYPE_UV_TEST);
+ Image *ima= image_alloc(name, IMA_SRC_GENERATED, IMA_TYPE_UV_TEST);
if (ima) {
ImBuf *ibuf;
@@ -576,7 +419,7 @@ Image *BKE_add_image_size(int width, int height, char *name, int floatbuf, short
ima->gen_y= height;
ima->gen_type= uvtestgrid;
- ibuf= add_ibuf_size(width, height, name, floatbuf, uvtestgrid, color);
+ ibuf= add_ibuf_size(width, height, name, depth, floatbuf, uvtestgrid, color);
image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
ima->ok= IMA_OK_LOADED;
@@ -585,6 +428,23 @@ Image *BKE_add_image_size(int width, int height, char *name, int floatbuf, short
return ima;
}
+/* creates an image image owns the imbuf passed */
+Image *BKE_add_image_imbuf(ImBuf *ibuf)
+{
+ /* on save, type is changed to FILE in editsima.c */
+ Image *ima;
+
+ ima= image_alloc(BLI_path_basename(ibuf->name), IMA_SRC_FILE, IMA_TYPE_IMAGE);
+
+ if (ima) {
+ BLI_strncpy(ima->name, ibuf->name, FILE_MAX);
+ image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
+ ima->ok= IMA_OK_LOADED;
+ }
+
+ return ima;
+}
+
/* packs rect from memory as PNG */
void BKE_image_memorypack(Image *ima)
{
@@ -814,8 +674,6 @@ int BKE_imtype_to_ftype(int imtype)
return TGA;
else if(imtype==R_RAWTGA)
return RAWTGA;
- else if(imtype==R_HAMX)
- return AN_hamx;
#ifdef WITH_OPENJPEG
else if(imtype==R_JP2)
return JP2;
@@ -852,8 +710,6 @@ int BKE_ftype_to_imtype(int ftype)
return R_TARGA;
else if(ftype & RAWTGA)
return R_RAWTGA;
- else if(ftype == AN_hamx)
- return R_HAMX;
#ifdef WITH_OPENJPEG
else if(ftype & JP2)
return R_JP2;
@@ -866,7 +722,6 @@ int BKE_ftype_to_imtype(int ftype)
int BKE_imtype_is_movie(int imtype)
{
switch(imtype) {
- case R_MOVIE:
case R_AVIRAW:
case R_AVIJPEG:
case R_AVICODEC:
@@ -915,10 +770,12 @@ void BKE_add_image_extension(char *string, int imtype)
if(!BLI_testextensie(string, ".bmp"))
extension= ".bmp";
}
- else if(G.have_libtiff && (imtype==R_TIFF)) {
+#ifdef WITH_TIFF
+ else if(imtype==R_TIFF) {
if(!BLI_testextensie(string, ".tif") &&
!BLI_testextensie(string, ".tiff")) extension= ".tif";
}
+#endif
#ifdef WITH_OPENEXR
else if( ELEM(imtype, R_OPENEXR, R_MULTILAYER)) {
if(!BLI_testextensie(string, ".exr"))
@@ -943,7 +800,7 @@ void BKE_add_image_extension(char *string, int imtype)
extension= ".jp2";
}
#endif
- else { // R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90, R_QUICKTIME etc
+ else { // R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90, R_QUICKTIME etc
if(!( BLI_testextensie(string, ".jpg") || BLI_testextensie(string, ".jpeg")))
extension= ".jpg";
}
@@ -968,14 +825,9 @@ typedef struct StampData {
static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix)
{
char text[256];
-
-#ifndef WIN32
struct tm *tl;
time_t t;
-#else
- char sdate[9];
-#endif /* WIN32 */
-
+
if (scene->r.stamp & R_STAMP_FILENAME) {
if (G.relbase_valid) {
if (do_prefix) sprintf(stamp_data->file, "File %s", G.sce);
@@ -996,14 +848,11 @@ static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix)
}
if (scene->r.stamp & R_STAMP_DATE) {
-#ifdef WIN32
- _strdate (sdate);
- sprintf (text, "%s", sdate);
-#else
+
t = time (NULL);
tl = localtime (&t);
- sprintf (text, "%04d-%02d-%02d", tl->tm_year+1900, tl->tm_mon+1, tl->tm_mday);
-#endif /* WIN32 */
+ sprintf (text, "%04d/%02d/%02d %02d:%02d:%02d", tl->tm_year+1900, tl->tm_mon+1, tl->tm_mday, tl->tm_hour, tl->tm_min, tl->tm_sec);
+
if (do_prefix) sprintf(stamp_data->date, "Date %s", text);
else sprintf(stamp_data->date, "%s", text);
} else {
@@ -1088,7 +937,7 @@ static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix)
}
{
- Render *re= RE_GetRender(scene->id.name, RE_SLOT_RENDERING);
+ Render *re= RE_GetRender(scene->id.name);
RenderStats *stats= re ? RE_GetStats(re):NULL;
if (stats && (scene->r.stamp & R_STAMP_RENDERTIME)) {
@@ -1106,17 +955,17 @@ static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix)
extern int datatoc_bmonofont_ttf_size;
extern char datatoc_bmonofont_ttf[];
-// XXX - copied from text_font_begin
-static void stamp_font_begin(int size)
-{
- static int mono= -1;
+// XXX - copied from text_font_begin ! Change all the BLF_* here
+static int mono= -1;
+int stamp_font_begin(int size)
+{
if (mono == -1)
- mono= BLF_load_mem("monospace", (unsigned char *)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size);
+ mono= BLF_load_mem_unique("monospace", (unsigned char *)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size);
- BLF_set(mono);
- BLF_aspect(1.0);
- BLF_size(size, 72);
+ BLF_aspect(mono, 1.0);
+ BLF_size(mono, size, 72);
+ return(mono); // XXX This is for image_gen.c!!
}
void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, int height, int channels)
@@ -1124,6 +973,7 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i
struct StampData stamp_data;
float w, h, pad;
int x, y;
+ float h_fixed;
if (!rect && !rectf)
return;
@@ -1136,24 +986,32 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i
stamp_font_begin(scene->r.stamp_font_id);
- BLF_buffer(rectf, rect, width, height, channels);
- BLF_buffer_col(scene->r.fg_stamp[0], scene->r.fg_stamp[1], scene->r.fg_stamp[2], 1.0);
- pad= BLF_width("--");
+ BLF_buffer(mono, rectf, rect, width, height, channels);
+ BLF_buffer_col(mono, scene->r.fg_stamp[0], scene->r.fg_stamp[1], scene->r.fg_stamp[2], 1.0);
+ pad= BLF_width(mono, "--");
+
+ /* use 'h_fixed' rather then 'h', aligns better */
+ // BLF_width_and_height(mono, "^|/_AgPpJjlYy", &w, &h_fixed);
+ {
+ rctf box;
+ BLF_boundbox(mono, "^|/_AgPpJjlYy", &box);
+ h_fixed= box.ymax - box.ymin;
+ }
x= 0;
y= height;
if (stamp_data.file[0]) {
/* Top left corner */
- BLF_width_and_height(stamp_data.file, &w, &h);
+ BLF_width_and_height(mono, stamp_data.file, &w, &h); h= h_fixed;
y -= h;
/* also a little of space to the background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y-3, w+3, y+h+3);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y-3, w+3, y+h+2);
/* and draw the text. */
- BLF_position(x, y, 0.0);
- BLF_draw_buffer(stamp_data.file);
+ BLF_position(mono, x, y, 0.0);
+ BLF_draw_buffer(mono, stamp_data.file);
/* the extra pixel for background. */
y -= 4;
@@ -1161,14 +1019,14 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i
/* Top left corner, below File */
if (stamp_data.note[0]) {
- BLF_width_and_height(stamp_data.note, &w, &h);
+ BLF_width_and_height(mono, stamp_data.note, &w, &h); h= h_fixed;
y -= h;
/* and space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-2, w+3, y+h+2);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-3, w+3, y+h+2);
- BLF_position(x, y+1, 0.0);
- BLF_draw_buffer(stamp_data.note);
+ BLF_position(mono, x, y+1, 0.0);
+ BLF_draw_buffer(mono, stamp_data.note);
/* the extra pixel for background. */
y -= 4;
@@ -1176,14 +1034,14 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i
/* Top left corner, below File (or Note) */
if (stamp_data.date[0]) {
- BLF_width_and_height(stamp_data.date, &w, &h);
+ BLF_width_and_height(mono, stamp_data.date, &w, &h); h= h_fixed;
y -= h;
/* and space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-3, w+3, y+h+3);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-3, w+3, y+h+2);
- BLF_position(x, y, 0.0);
- BLF_draw_buffer(stamp_data.date);
+ BLF_position(mono, x, y, 0.0);
+ BLF_draw_buffer(mono, stamp_data.date);
/* the extra pixel for background. */
y -= 4;
@@ -1191,14 +1049,14 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i
/* Top left corner, below File, Date or Note */
if (stamp_data.rendertime[0]) {
- BLF_width_and_height(stamp_data.rendertime, &w, &h);
+ BLF_width_and_height(mono, stamp_data.rendertime, &w, &h); h= h_fixed;
y -= h;
/* and space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-3, w+3, y+h+3);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-3, w+3, y+h+2);
- BLF_position(x, y, 0.0);
- BLF_draw_buffer(stamp_data.rendertime);
+ BLF_position(mono, x, y, 0.0);
+ BLF_draw_buffer(mono, stamp_data.rendertime);
}
x= 0;
@@ -1206,14 +1064,14 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i
/* Bottom left corner, leaving space for timing */
if (stamp_data.marker[0]) {
- BLF_width_and_height(stamp_data.marker, &w, &h);
+ BLF_width_and_height(mono, stamp_data.marker, &w, &h); h= h_fixed;
/* extra space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, w+2, y+h+3);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, w+2, y+h+2);
/* and pad the text. */
- BLF_position(x, y+3, 0.0);
- BLF_draw_buffer(stamp_data.marker);
+ BLF_position(mono, x, y+3, 0.0);
+ BLF_draw_buffer(mono, stamp_data.marker);
/* space width. */
x += w + pad;
@@ -1221,73 +1079,72 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i
/* Left bottom corner */
if (stamp_data.time[0]) {
- BLF_width_and_height(stamp_data.time, &w, &h);
+ BLF_width_and_height(mono, stamp_data.time, &w, &h); h= h_fixed;
/* extra space for background */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+2, y+h+3);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+2, y+h+2);
/* and pad the text. */
- BLF_position(x, y+3, 0.0);
- BLF_draw_buffer(stamp_data.time);
+ BLF_position(mono, x, y+3, 0.0);
+ BLF_draw_buffer(mono, stamp_data.time);
/* space width. */
x += w + pad;
}
if (stamp_data.frame[0]) {
- BLF_width_and_height(stamp_data.frame, &w, &h);
+ BLF_width_and_height(mono, stamp_data.frame, &w, &h); h= h_fixed;
/* extra space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+2, y+h+3);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+2, y+h+2);
/* and pad the text. */
- BLF_position(x, y+3, 0.0);
-
- BLF_draw_buffer(stamp_data.frame);
+ BLF_position(mono, x, y+3, 0.0);
+ BLF_draw_buffer(mono, stamp_data.frame);
/* space width. */
x += w + pad;
}
if (stamp_data.camera[0]) {
- BLF_width_and_height(stamp_data.camera, &w, &h);
+ BLF_width_and_height(mono, stamp_data.camera, &w, &h); h= h_fixed;
/* extra space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+2, y+h+3);
- BLF_position(x, y+3, 0.0);
- BLF_draw_buffer(stamp_data.camera);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+2, y+h+2);
+ BLF_position(mono, x, y+3, 0.0);
+ BLF_draw_buffer(mono, stamp_data.camera);
}
if (stamp_data.scene[0]) {
- BLF_width_and_height(stamp_data.scene, &w, &h);
+ BLF_width_and_height(mono, stamp_data.scene, &w, &h); h= h_fixed;
/* Bottom right corner, with an extra space because blenfont is too strict! */
x= width - w - 2;
/* extra space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+3, y+h+3);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+3, y+h+2);
/* and pad the text. */
- BLF_position(x, y+3, 0.0);
- BLF_draw_buffer(stamp_data.scene);
+ BLF_position(mono, x, y+3, 0.0);
+ BLF_draw_buffer(mono, stamp_data.scene);
}
if (stamp_data.strip[0]) {
- BLF_width_and_height(stamp_data.scene, &w, &h);
+ BLF_width_and_height(mono, stamp_data.scene, &w, &h); h= h_fixed;
/* Top right corner, with an extra space because blenfont is too strict! */
x= width - w - pad;
y= height - h;
/* extra space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y-3, x+w+pad, y+h+3);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y-3, x+w+pad, y+h+2);
- BLF_position(x, y, 0.0);
- BLF_draw_buffer(stamp_data.strip);
+ BLF_position(mono, x, y, 0.0);
+ BLF_draw_buffer(mono, stamp_data.strip);
}
/* cleanup the buffer. */
- BLF_buffer(NULL, NULL, 0, 0, 0);
+ BLF_buffer(mono, NULL, NULL, 0, 0, 0);
}
void BKE_stamp_info(Scene *scene, struct ImBuf *ibuf)
@@ -1299,15 +1156,16 @@ void BKE_stamp_info(Scene *scene, struct ImBuf *ibuf)
/* fill all the data values, no prefix */
stampdata(scene, &stamp_data, 0);
- if (stamp_data.file[0]) IMB_imginfo_change_field (ibuf, "File", stamp_data.file);
- if (stamp_data.note[0]) IMB_imginfo_change_field (ibuf, "Note", stamp_data.note);
- if (stamp_data.date[0]) IMB_imginfo_change_field (ibuf, "Date", stamp_data.date);
- if (stamp_data.marker[0]) IMB_imginfo_change_field (ibuf, "Marker", stamp_data.marker);
- if (stamp_data.time[0]) IMB_imginfo_change_field (ibuf, "Time", stamp_data.time);
- if (stamp_data.frame[0]) IMB_imginfo_change_field (ibuf, "Frame", stamp_data.frame);
- if (stamp_data.camera[0]) IMB_imginfo_change_field (ibuf, "Camera", stamp_data.camera);
- if (stamp_data.scene[0]) IMB_imginfo_change_field (ibuf, "Scene", stamp_data.scene);
- if (stamp_data.strip[0]) IMB_imginfo_change_field (ibuf, "Strip", stamp_data.strip);
+ if (stamp_data.file[0]) IMB_metadata_change_field (ibuf, "File", stamp_data.file);
+ if (stamp_data.note[0]) IMB_metadata_change_field (ibuf, "Note", stamp_data.note);
+ if (stamp_data.date[0]) IMB_metadata_change_field (ibuf, "Date", stamp_data.date);
+ if (stamp_data.marker[0]) IMB_metadata_change_field (ibuf, "Marker", stamp_data.marker);
+ if (stamp_data.time[0]) IMB_metadata_change_field (ibuf, "Time", stamp_data.time);
+ if (stamp_data.frame[0]) IMB_metadata_change_field (ibuf, "Frame", stamp_data.frame);
+ if (stamp_data.camera[0]) IMB_metadata_change_field (ibuf, "Camera", stamp_data.camera);
+ if (stamp_data.scene[0]) IMB_metadata_change_field (ibuf, "Scene", stamp_data.scene);
+ if (stamp_data.strip[0]) IMB_metadata_change_field (ibuf, "Strip", stamp_data.strip);
+ if (stamp_data.rendertime[0]) IMB_metadata_change_field (ibuf, "RenderTime", stamp_data.rendertime);
}
int BKE_write_ibuf(Scene *scene, ImBuf *ibuf, char *name, int imtype, int subimtype, int quality)
@@ -1331,12 +1189,14 @@ int BKE_write_ibuf(Scene *scene, ImBuf *ibuf, char *name, int imtype, int subimt
else if ((imtype==R_BMP)) {
ibuf->ftype= BMP;
}
- else if ((G.have_libtiff) && (imtype==R_TIFF)) {
+#ifdef WITH_TIFF
+ else if (imtype==R_TIFF) {
ibuf->ftype= TIF;
if(subimtype & R_TIFF_16BIT)
ibuf->ftype |= TIF_16BIT;
}
+#endif
#ifdef WITH_OPENEXR
else if (imtype==R_OPENEXR || imtype==R_MULTILAYER) {
ibuf->ftype= OPENEXR;
@@ -1361,9 +1221,6 @@ int BKE_write_ibuf(Scene *scene, ImBuf *ibuf, char *name, int imtype, int subimt
else if(imtype==R_RAWTGA) {
ibuf->ftype= RAWTGA;
}
- else if(imtype==R_HAMX) {
- ibuf->ftype= AN_hamx;
- }
#ifdef WITH_OPENJPEG
else if(imtype==R_JP2) {
if(quality < 10) quality= 90;
@@ -1387,7 +1244,7 @@ int BKE_write_ibuf(Scene *scene, ImBuf *ibuf, char *name, int imtype, int subimt
}
#endif
else {
- /* R_JPEG90, R_MOVIE, etc. default we save jpegs */
+ /* R_JPEG90, etc. default we save jpegs */
if(quality < 10) quality= 90;
ibuf->ftype= JPG|quality;
if(ibuf->depth==32) ibuf->depth= 24; /* unsupported feature only confuses other s/w */
@@ -1411,8 +1268,8 @@ void BKE_makepicstring(char *string, char *base, int frame, int imtype, int use_
{
if (string==NULL) return;
BLI_strncpy(string, base, FILE_MAX - 10); /* weak assumption */
- BLI_convertstringcode(string, G.sce);
- BLI_convertstringframe(string, frame, 4);
+ BLI_path_abs(string, G.sce);
+ BLI_path_frame(string, frame, 4);
if(use_ext)
BKE_add_image_extension(string, imtype);
@@ -1594,20 +1451,48 @@ RenderPass *BKE_image_multilayer_index(RenderResult *rr, ImageUser *iuser)
return rpass;
}
-RenderResult *BKE_image_acquire_renderresult(struct Scene *scene, Image *ima)
+RenderResult *BKE_image_acquire_renderresult(Scene *scene, Image *ima)
{
- if(ima->rr)
+ if(ima->rr) {
return ima->rr;
- else if(ima->type==IMA_TYPE_R_RESULT)
- return RE_AcquireResultRead(RE_GetRender(scene->id.name, RE_SLOT_VIEW));
- return NULL;
+ }
+ else if(ima->type==IMA_TYPE_R_RESULT) {
+ if(ima->render_slot == ima->last_render_slot)
+ return RE_AcquireResultRead(RE_GetRender(scene->id.name));
+ else
+ return ima->renders[ima->render_slot];
+ }
+ else
+ return NULL;
}
-void BKE_image_release_renderresult(struct Scene *scene, Image *ima)
+void BKE_image_release_renderresult(Scene *scene, Image *ima)
{
if(ima->rr);
- else if(ima->type==IMA_TYPE_R_RESULT)
- RE_ReleaseResult(RE_GetRender(scene->id.name, RE_SLOT_VIEW));
+ else if(ima->type==IMA_TYPE_R_RESULT) {
+ if(ima->render_slot == ima->last_render_slot)
+ RE_ReleaseResult(RE_GetRender(scene->id.name));
+ }
+}
+
+void BKE_image_backup_render(Scene *scene, Image *ima)
+{
+ /* called right before rendering, ima->renders contains render
+ result pointers for everything but the current render */
+ Render *re= RE_GetRender(scene->id.name);
+ int slot= ima->render_slot, last= ima->last_render_slot;
+
+ if(slot != last) {
+ if(ima->renders[slot]) {
+ RE_FreeRenderResult(ima->renders[slot]);
+ ima->renders[slot]= NULL;
+ }
+
+ ima->renders[last]= NULL;
+ RE_SwapResult(re, &ima->renders[last]);
+ }
+
+ ima->last_render_slot= slot;
}
/* after imbuf load, openexr type can return with a exrhandle open */
@@ -1655,6 +1540,7 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
struct ImBuf *ibuf;
unsigned short numlen;
char name[FILE_MAX], head[FILE_MAX], tail[FILE_MAX];
+ int flag;
/* XXX temp stuff? */
if(ima->lastframe != frame)
@@ -1667,12 +1553,16 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
BLI_strncpy(name, ima->name, sizeof(name));
if(ima->id.lib)
- BLI_convertstringcode(name, ima->id.lib->filename);
+ BLI_path_abs(name, ima->id.lib->filepath);
else
- BLI_convertstringcode(name, G.sce);
+ BLI_path_abs(name, G.sce);
+ flag= IB_rect|IB_multilayer;
+ if(ima->flag & IMA_DO_PREMUL)
+ flag |= IB_premul;
+
/* read ibuf */
- ibuf = IMB_loadiffname(name, IB_rect|IB_multilayer);
+ ibuf = IMB_loadiffname(name, flag);
if(G.f & G_DEBUG) printf("loaded %s\n", name);
if (ibuf) {
@@ -1692,10 +1582,6 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
image_initialize_after_load(ima, ibuf);
image_assign_ibuf(ima, ibuf, 0, frame);
#endif
-
- if(ima->flag & IMA_DO_PREMUL)
- converttopremul(ibuf);
-
}
else
ima->ok= 0;
@@ -1774,11 +1660,11 @@ static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame)
BLI_strncpy(str, ima->name, FILE_MAX);
if(ima->id.lib)
- BLI_convertstringcode(str, ima->id.lib->filename);
+ BLI_path_abs(str, ima->id.lib->filepath);
else
- BLI_convertstringcode(str, G.sce);
+ BLI_path_abs(str, G.sce);
- ima->anim = openanim(str, IB_cmap | IB_rect);
+ ima->anim = openanim(str, IB_rect);
/* let's initialize this user */
if(ima->anim && iuser && iuser->frames==0)
@@ -1809,33 +1695,40 @@ static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame)
return ibuf;
}
-/* cfra used for # code, Image can only have this # for all its users */
+/* cfra used for # code, Image can only have this # for all its users
+ * warning, 'iuser' can be NULL */
static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
{
struct ImBuf *ibuf;
char str[FILE_MAX];
- int assign = 0;
+ int assign = 0, flag;
/* always ensure clean ima */
image_free_buffers(ima);
/* is there a PackedFile with this image ? */
if (ima->packedfile) {
- ibuf = IMB_ibImageFromMemory((int *) ima->packedfile->data, ima->packedfile->size, IB_rect|IB_multilayer);
+ flag = IB_rect|IB_multilayer;
+ if(ima->flag & IMA_DO_PREMUL) flag |= IB_premul;
+
+ ibuf = IMB_ibImageFromMemory((unsigned char*)ima->packedfile->data, ima->packedfile->size, flag);
}
else {
+ flag= IB_rect|IB_multilayer|IB_metadata;
+ if(ima->flag & IMA_DO_PREMUL)
+ flag |= IB_premul;
/* get the right string */
BLI_strncpy(str, ima->name, sizeof(str));
if(ima->id.lib)
- BLI_convertstringcode(str, ima->id.lib->filename);
+ BLI_path_abs(str, ima->id.lib->filepath);
else
- BLI_convertstringcode(str, G.sce);
+ BLI_path_abs(str, G.sce);
- BLI_convertstringframe(str, cfra, 0);
+ BLI_path_frame(str, cfra, 0);
/* read ibuf */
- ibuf = IMB_loadiffname(str, IB_rect|IB_multilayer|IB_imginfo);
+ ibuf = IMB_loadiffname(str, flag);
}
if (ibuf) {
@@ -1857,9 +1750,6 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
if ((ima->packedfile == NULL) && (G.fileflags & G_AUTOPACK))
ima->packedfile = newPackedFile(NULL, str);
}
-
- if(ima->flag & IMA_DO_PREMUL)
- converttopremul(ibuf);
}
else
ima->ok= 0;
@@ -1915,113 +1805,123 @@ static ImBuf *image_get_ibuf_multilayer(Image *ima, ImageUser *iuser)
/* always returns a single ibuf, also during render progress */
static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_r)
{
- Render *re= NULL;
- RenderResult *rr= NULL;
-
+ Render *re;
+ RenderResult rres;
+ float *rectf, *rectz;
+ unsigned int *rect;
+ float dither;
+ int channels, layer, pass;
+ ImBuf *ibuf;
+ int from_render= (ima->render_slot == ima->last_render_slot);
+
+ if(!(iuser && iuser->scene))
+ return NULL;
+
/* if we the caller is not going to release the lock, don't give the image */
if(!lock_r)
return NULL;
- if(iuser && iuser->scene) {
- re= RE_GetRender(iuser->scene->id.name, RE_SLOT_VIEW);
- rr= RE_AcquireResultRead(re);
+ re= RE_GetRender(iuser->scene->id.name);
- /* release is done in BKE_image_release_ibuf using lock_r */
- *lock_r= re;
- }
+ channels= 4;
+ layer= (iuser)? iuser->layer: 0;
+ pass= (iuser)? iuser->pass: 0;
- if(rr==NULL)
- return NULL;
+ if(from_render) {
+ RE_AcquireResultImage(re, &rres);
+ }
+ else if(ima->renders[ima->render_slot]) {
+ rres= *(ima->renders[ima->render_slot]);
+ rres.have_combined= rres.rectf != NULL;
+ }
+ else
+ memset(&rres, 0, sizeof(RenderResult));
- if(RE_RenderInProgress(re)) {
- ImBuf *ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
-
- /* make ibuf if needed, and initialize it */
- /* this only gets called when mutex locked */
- if(ibuf==NULL) {
- ibuf= IMB_allocImBuf(rr->rectx, rr->recty, 32, IB_rect, 0);
- image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
- }
+ if(!(rres.rectx > 0 && rres.recty > 0)) {
+ if(from_render)
+ RE_ReleaseResultImage(re);
+ return NULL;
+ }
- return ibuf;
+ /* release is done in BKE_image_release_ibuf using lock_r */
+ if(from_render) {
+ BLI_lock_thread(LOCK_VIEWER);
+ *lock_r= re;
}
- else {
- RenderResult rres;
- float *rectf, *rectz;
- unsigned int *rect;
- float dither;
- int channels, layer, pass;
-
- channels= 4;
- layer= (iuser)? iuser->layer: 0;
- pass= (iuser)? iuser->pass: 0;
-
- /* this gives active layer, composite or seqence result */
- RE_AcquireResultImage(RE_GetRender(iuser->scene->id.name, RE_SLOT_VIEW), &rres);
- rect= (unsigned int *)rres.rect32;
- rectf= rres.rectf;
- rectz= rres.rectz;
- dither= iuser->scene->r.dither_intensity;
-
- /* get compo/seq result by default */
- if(rr->rectf && layer==0);
- else if(rr->layers.first) {
- RenderLayer *rl= BLI_findlink(&rr->layers, layer-(rr->rectf?1:0));
- if(rl) {
- RenderPass *rpass;
-
- /* there's no combined pass, is in renderlayer itself */
- if(pass==0) {
- rectf= rl->rectf;
- }
- else {
- rpass= BLI_findlink(&rl->passes, pass-1);
- if(rpass) {
- channels= rpass->channels;
- rectf= rpass->rect;
- dither= 0.0f; /* don't dither passes */
- }
- }
- for(rpass= rl->passes.first; rpass; rpass= rpass->next)
- if(rpass->passtype == SCE_PASS_Z)
- rectz= rpass->rect;
- }
- }
-
- if(rectf || rect) {
- ImBuf *ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
+ /* this gives active layer, composite or seqence result */
+ rect= (unsigned int *)rres.rect32;
+ rectf= rres.rectf;
+ rectz= rres.rectz;
+ dither= iuser->scene->r.dither_intensity;
- /* make ibuf if needed, and initialize it */
- if(ibuf==NULL) {
- ibuf= IMB_allocImBuf(rr->rectx, rr->recty, 32, 0, 0);
- image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
- }
- ibuf->x= rr->rectx;
- ibuf->y= rr->recty;
-
- if(ibuf->rect_float!=rectf || rect) /* ensure correct redraw */
- imb_freerectImBuf(ibuf);
- if(rect)
- ibuf->rect= rect;
-
- ibuf->rect_float= rectf;
- ibuf->flags |= IB_rectfloat;
- ibuf->channels= channels;
- ibuf->zbuf_float= rectz;
- ibuf->flags |= IB_zbuffloat;
- ibuf->dither= dither;
+ /* combined layer gets added as first layer */
+ if(rres.have_combined && layer==0);
+ else if(rres.layers.first) {
+ RenderLayer *rl= BLI_findlink(&rres.layers, layer-(rres.have_combined?1:0));
+ if(rl) {
+ RenderPass *rpass;
- RE_ReleaseResultImage(re);
+ /* there's no combined pass, is in renderlayer itself */
+ if(pass==0) {
+ rectf= rl->rectf;
+ }
+ else {
+ rpass= BLI_findlink(&rl->passes, pass-1);
+ if(rpass) {
+ channels= rpass->channels;
+ rectf= rpass->rect;
+ dither= 0.0f; /* don't dither passes */
+ }
+ }
- ima->ok= IMA_OK_LOADED;
- return ibuf;
+ for(rpass= rl->passes.first; rpass; rpass= rpass->next)
+ if(rpass->passtype == SCE_PASS_Z)
+ rectz= rpass->rect;
}
+ }
- RE_ReleaseResultImage(re);
+ ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
+
+ /* make ibuf if needed, and initialize it */
+ if(ibuf==NULL) {
+ ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, 0, 0);
+ image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
}
+
+ ibuf->x= rres.rectx;
+ ibuf->y= rres.recty;
- return NULL;
+ if(ibuf->rect_float!=rectf || rect) /* ensure correct redraw */
+ imb_freerectImBuf(ibuf);
+
+ if(rect)
+ ibuf->rect= rect;
+
+ if(rectf) {
+ ibuf->rect_float= rectf;
+ ibuf->flags |= IB_rectfloat;
+ ibuf->channels= channels;
+ }
+ else {
+ ibuf->rect_float= NULL;
+ ibuf->flags &= ~IB_rectfloat;
+ }
+
+ if(rectz) {
+ ibuf->zbuf_float= rectz;
+ ibuf->flags |= IB_zbuffloat;
+ }
+ else {
+ ibuf->zbuf_float= NULL;
+ ibuf->flags &= ~IB_zbuffloat;
+ }
+
+ ibuf->dither= dither;
+
+ ima->ok= IMA_OK_LOADED;
+
+ return ibuf;
}
static ImBuf *image_get_ibuf_threadsafe(Image *ima, ImageUser *iuser, int *frame_r, int *index_r)
@@ -2047,7 +1947,7 @@ static ImBuf *image_get_ibuf_threadsafe(Image *ima, ImageUser *iuser, int *frame
if(ima->lastframe != frame)
ima->tpageflag |= IMA_TPAGE_REFRESH;
ima->lastframe = frame;
- }
+ }
else if(ima->type==IMA_TYPE_MULTILAYER) {
frame= iuser?iuser->framenr:ima->lastframe;
index= iuser?iuser->multi_index:IMA_NO_INDEX;
@@ -2171,7 +2071,7 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
/* UV testgrid or black or solid etc */
if(ima->gen_x==0) ima->gen_x= 1024;
if(ima->gen_y==0) ima->gen_y= 1024;
- ibuf= add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, 0, ima->gen_type, color);
+ ibuf= add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, 24, 0, ima->gen_type, color);
image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
ima->ok= IMA_OK_LOADED;
}
@@ -2182,10 +2082,17 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
ibuf= image_get_render_result(ima, iuser, lock_r);
}
else if(ima->type==IMA_TYPE_COMPOSITE) {
- /* Composite Viewer, all handled in compositor */
- /* fake ibuf, will be filled in compositor */
- ibuf= IMB_allocImBuf(256, 256, 32, IB_rect, 0);
- image_assign_ibuf(ima, ibuf, 0, frame);
+ /* requires lock/unlock, otherwise don't return image */
+ if(lock_r) {
+ /* unlock in BKE_image_release_ibuf */
+ BLI_lock_thread(LOCK_VIEWER);
+ *lock_r= ima;
+
+ /* Composite Viewer, all handled in compositor */
+ /* fake ibuf, will be filled in compositor */
+ ibuf= IMB_allocImBuf(256, 256, 32, IB_rect, 0);
+ image_assign_ibuf(ima, ibuf, 0, frame);
+ }
}
}
}
@@ -2203,9 +2110,14 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
void BKE_image_release_ibuf(Image *ima, void *lock)
{
- /* for getting image during threaded render, need to release */
- if(lock)
- RE_ReleaseResult(lock);
+ /* for getting image during threaded render / compositing, need to release */
+ if(lock == ima) {
+ BLI_unlock_thread(LOCK_VIEWER); /* viewer image */
+ }
+ else if(lock) {
+ RE_ReleaseResultImage(lock); /* render result */
+ BLI_unlock_thread(LOCK_VIEWER); /* view image imbuf */
+ }
}
ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
diff --git a/source/blender/blenkernel/intern/image_gen.c b/source/blender/blenkernel/intern/image_gen.c
new file mode 100644
index 00000000000..9248ce69280
--- /dev/null
+++ b/source/blender/blenkernel/intern/image_gen.c
@@ -0,0 +1,367 @@
+/* image_gen.c
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Matt Ebb, Campbell Barton, Shuvro Sarker
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include "BLI_math_color.h"
+#include "BLF_api.h"
+
+void BKE_image_buf_fill_color(unsigned char *rect, float *rect_float, int width, int height, float color[4])
+{
+ int x, y;
+
+ /* blank image */
+ if(rect_float) {
+ for(y= 0; y<height; y++) {
+ for(x= 0; x<width; x++) {
+ rect_float[0]= color[0];
+ rect_float[1]= color[1];
+ rect_float[2]= color[2];
+ rect_float[3]= color[3];
+ rect_float+= 4;
+ }
+ }
+ }
+
+ if(rect) {
+ char ccol[4];
+
+ ccol[0]= (char)(color[0]*255.0f);
+ ccol[1]= (char)(color[1]*255.0f);
+ ccol[2]= (char)(color[2]*255.0f);
+ ccol[3]= (char)(color[3]*255.0f);
+ for(y= 0; y<height; y++) {
+ for(x= 0; x<width; x++) {
+
+ rect[0]= ccol[0];
+ rect[1]= ccol[1];
+ rect[2]= ccol[2];
+ rect[3]= ccol[3];
+ rect+= 4;
+ }
+ }
+ }
+}
+
+
+void BKE_image_buf_fill_checker(unsigned char *rect, float *rect_float, int width, int height)
+{
+ /* these two passes could be combined into one, but it's more readable and
+ * easy to tweak like this, speed isn't really that much of an issue in this situation... */
+
+ int checkerwidth= 32, dark= 1;
+ int x, y;
+
+ unsigned char *rect_orig= rect;
+ float *rect_float_orig= rect_float;
+
+
+ float h=0.0, hoffs=0.0, hue=0.0, s=0.9, v=0.9, r, g, b;
+
+ /* checkers */
+ for(y= 0; y<height; y++) {
+ dark= powf(-1.0f, floorf(y / checkerwidth));
+
+ for(x= 0; x<width; x++) {
+ if (x % checkerwidth == 0) dark= -dark;
+
+ if (rect_float) {
+ if (dark > 0) {
+ rect_float[0]= rect_float[1]= rect_float[2]= 0.25f;
+ rect_float[3]= 1.0f;
+ } else {
+ rect_float[0]= rect_float[1]= rect_float[2]= 0.58f;
+ rect_float[3]= 1.0f;
+ }
+ rect_float+= 4;
+ }
+ else {
+ if (dark > 0) {
+ rect[0]= rect[1]= rect[2]= 64;
+ rect[3]= 255;
+ } else {
+ rect[0]= rect[1]= rect[2]= 150;
+ rect[3]= 255;
+ }
+ rect+= 4;
+ }
+ }
+ }
+
+ rect= rect_orig;
+ rect_float= rect_float_orig;
+
+ /* 2nd pass, colored + */
+ for(y= 0; y<height; y++) {
+ hoffs= 0.125f * floorf(y / checkerwidth);
+
+ for(x= 0; x<width; x++) {
+ h= 0.125f * floorf(x / checkerwidth);
+
+ if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 4) &&
+ (fabs((y % checkerwidth) - (checkerwidth / 2)) < 4)) {
+
+ if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 1) ||
+ (fabs((y % checkerwidth) - (checkerwidth / 2)) < 1)) {
+
+ hue= fmodf(fabs(h-hoffs), 1.0f);
+ hsv_to_rgb(hue, s, v, &r, &g, &b);
+
+ if (rect) {
+ rect[0]= (char)(r * 255.0f);
+ rect[1]= (char)(g * 255.0f);
+ rect[2]= (char)(b * 255.0f);
+ rect[3]= 255;
+ }
+
+ if (rect_float) {
+ rect_float[0]= r;
+ rect_float[1]= g;
+ rect_float[2]= b;
+ rect_float[3]= 1.0f;
+ }
+ }
+ }
+
+ if (rect_float) rect_float+= 4;
+ if (rect) rect+= 4;
+ }
+ }
+}
+
+
+/* Utility functions for BKE_image_buf_fill_checker_color */
+
+#define BLEND_FLOAT(real, add) (real+add <= 1.0) ? (real+add) : 1.0
+#define BLEND_CHAR(real, add) ((real + (char)(add * 255.0)) <= 255) ? (real + (char)(add * 255.0)) : 255
+
+static int is_pow2(int n)
+{
+ return ((n)&(n-1))==0;
+}
+static int larger_pow2(int n)
+{
+ if (is_pow2(n))
+ return n;
+
+ while(!is_pow2(n))
+ n= n&(n-1);
+
+ return n*2;
+}
+
+static void checker_board_color_fill(unsigned char *rect, float *rect_float, int width, int height)
+{
+ int hue_step, y, x;
+ float hue, val, sat, r, g, b;
+
+ sat= 1.0;
+
+ hue_step= larger_pow2(width / 8);
+ if(hue_step < 8) hue_step= 8;
+
+ for(y= 0; y < height; y++)
+ {
+
+ val= 0.1 + (y * (0.4 / height)); /* use a number lower then 1.0 else its too bright */
+ for(x= 0; x < width; x++)
+ {
+ hue= (float)((double)(x/hue_step) * 1.0 / width * hue_step);
+ hsv_to_rgb(hue, sat, val, &r, &g, &b);
+
+ if (rect) {
+ rect[0]= (char)(r * 255.0f);
+ rect[1]= (char)(g * 255.0f);
+ rect[2]= (char)(b * 255.0f);
+ rect[3]= 255;
+
+ rect += 4;
+ }
+
+ if (rect_float) {
+ rect_float[0]= r;
+ rect_float[1]= g;
+ rect_float[2]= b;
+ rect_float[3]= 1.0f;
+
+ rect_float += 4;
+ }
+ }
+ }
+}
+
+static void checker_board_color_tint(unsigned char *rect, float *rect_float, int width, int height, int size, float blend)
+{
+ int x, y;
+ float blend_half= blend * 0.5f;
+
+ for(y= 0; y < height; y++)
+ {
+ for(x= 0; x < width; x++)
+ {
+ if( ( (y/size)%2 == 1 && (x/size)%2 == 1 ) || ( (y/size)%2 == 0 && (x/size)%2 == 0 ) )
+ {
+ if (rect) {
+ rect[0]= (char)BLEND_CHAR(rect[0], blend);
+ rect[1]= (char)BLEND_CHAR(rect[1], blend);
+ rect[2]= (char)BLEND_CHAR(rect[2], blend);
+ rect[3]= 255;
+
+ rect += 4;
+ }
+ if (rect_float) {
+ rect_float[0]= BLEND_FLOAT(rect_float[0], blend);
+ rect_float[1]= BLEND_FLOAT(rect_float[1], blend);
+ rect_float[2]= BLEND_FLOAT(rect_float[2], blend);
+ rect_float[3]= 1.0f;
+
+ rect_float += 4;
+ }
+ }
+ else {
+ if (rect) {
+ rect[0]= (char)BLEND_CHAR(rect[0], blend_half);
+ rect[1]= (char)BLEND_CHAR(rect[1], blend_half);
+ rect[2]= (char)BLEND_CHAR(rect[2], blend_half);
+ rect[3]= 255;
+
+ rect += 4;
+ }
+ if (rect_float) {
+ rect_float[0]= BLEND_FLOAT(rect_float[0], blend_half);
+ rect_float[1]= BLEND_FLOAT(rect_float[1], blend_half);
+ rect_float[2]= BLEND_FLOAT(rect_float[2], blend_half);
+ rect_float[3]= 1.0f;
+
+ rect_float += 4;
+ }
+ }
+
+ }
+ }
+}
+
+static void checker_board_grid_fill(unsigned char *rect, float *rect_float, int width, int height, float blend)
+{
+ int x, y;
+ for(y= 0; y < height; y++)
+ {
+ for(x= 0; x < width; x++)
+ {
+ if( ((y % 32) == 0) || ((x % 32) == 0) || x == 0 )
+ {
+ if (rect) {
+ rect[0]= BLEND_CHAR(rect[0], blend);
+ rect[1]= BLEND_CHAR(rect[1], blend);
+ rect[2]= BLEND_CHAR(rect[2], blend);
+ rect[3]= 255;
+
+ rect += 4;
+ }
+ if (rect_float) {
+ rect_float[0]= BLEND_FLOAT(rect_float[0], blend);
+ rect_float[1]= BLEND_FLOAT(rect_float[1], blend);
+ rect_float[2]= BLEND_FLOAT(rect_float[2], blend);
+ rect_float[3]= 1.0f;
+
+ rect_float += 4;
+ }
+ }
+ else {
+ if(rect_float) rect_float += 4;
+ if(rect) rect += 4;
+ }
+ }
+ }
+}
+
+/* defined in image.c */
+extern int stamp_font_begin(int size);
+
+static void checker_board_text(unsigned char *rect, float *rect_float, int width, int height, int step, int outline)
+{
+ int x, y, mono;
+ int pen_x, pen_y;
+ char text[3]= {'A', '1', '\0'};
+
+ /* hard coded size! */
+ mono= stamp_font_begin(54);
+ BLF_buffer(mono, rect_float, rect, width, height, 4);
+
+ for(y= 0; y < height; y+=step)
+ {
+ text[1]= '1';
+
+ for(x= 0; x < width; x+=step)
+ {
+ /* hard coded offset */
+ pen_x = x + 33;
+ pen_y = y + 44;
+
+ /* terribly crappy outline font! */
+ BLF_buffer_col(mono, 1.0, 1.0, 1.0, 1.0);
+
+ BLF_position(mono, pen_x-outline, pen_y, 0.0);
+ BLF_draw_buffer(mono, text);
+ BLF_position(mono, pen_x+outline, pen_y, 0.0);
+ BLF_draw_buffer(mono, text);
+ BLF_position(mono, pen_x, pen_y-outline, 0.0);
+ BLF_draw_buffer(mono, text);
+ BLF_position(mono, pen_x, pen_y+outline, 0.0);
+ BLF_draw_buffer(mono, text);
+
+ BLF_position(mono, pen_x-outline, pen_y-outline, 0.0);
+ BLF_draw_buffer(mono, text);
+ BLF_position(mono, pen_x+outline, pen_y+outline, 0.0);
+ BLF_draw_buffer(mono, text);
+ BLF_position(mono, pen_x-outline, pen_y+outline, 0.0);
+ BLF_draw_buffer(mono, text);
+ BLF_position(mono, pen_x+outline, pen_y-outline, 0.0);
+ BLF_draw_buffer(mono, text);
+
+ BLF_buffer_col(mono, 0.0, 0.0, 0.0, 1.0);
+ BLF_position(mono, pen_x, pen_y, 0.0);
+ BLF_draw_buffer(mono, text);
+
+ text[1]++;
+ }
+ text[0]++;
+ }
+
+ /* cleanup the buffer. */
+ BLF_buffer(mono, NULL, NULL, 0, 0, 0);
+}
+
+void BKE_image_buf_fill_checker_color(unsigned char *rect, float *rect_float, int width, int height)
+{
+ checker_board_color_fill(rect, rect_float, width, height);
+ checker_board_color_tint(rect, rect_float, width, height, 1, 0.03f);
+ checker_board_color_tint(rect, rect_float, width, height, 4, 0.05f);
+ checker_board_color_tint(rect, rect_float, width, height, 32, 0.07f);
+ checker_board_color_tint(rect, rect_float, width, height, 128, 0.15f);
+ checker_board_grid_fill(rect, rect_float, width, height, 1.0f/4.0f);
+
+ checker_board_text(rect, rect_float, width, height, 128, 2);
+}
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index 6912a65886a..902965bd2f6 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -31,15 +31,16 @@
#include "BKE_cloth.h"
-#include "DNA_cloth_types.h"
-#include "DNA_scene_types.h"
#include "DNA_object_force.h"
#include "BKE_effect.h"
#include "BKE_global.h"
-#include "BKE_cloth.h"
#include "BKE_utildefines.h"
+#include "BLI_threads.h"
+
+#define CLOTH_OPENMP_LIMIT 25
+
#ifdef _WIN32
#include <windows.h>
static LARGE_INTEGER _itstart, _itend;
@@ -233,8 +234,11 @@ DO_INLINE float dot_lfvector(float (*fLongVectorA)[3], float (*fLongVectorB)[3],
{
long i = 0;
float temp = 0.0;
+// XXX brecht, disabled this for now (first schedule line was already disabled),
+// due to non-commutative nature of floating point ops this makes the sim give
+// different results each time you run it!
// schedule(guided, 2)
-#pragma omp parallel for reduction(+: temp)
+//#pragma omp parallel for reduction(+: temp) if(verts > CLOTH_OPENMP_LIMIT)
for(i = 0; i < (long)verts; i++)
{
temp += INPR(fLongVectorA[i], fLongVectorB[i]);
@@ -580,11 +584,12 @@ DO_INLINE void mul_bfmatrix_S(fmatrix3x3 *matrix, float scalar)
DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector)
{
unsigned int i = 0;
- lfVector *temp = create_lfvector(from[0].vcount);
+ unsigned int vcount = from[0].vcount;
+ lfVector *temp = create_lfvector(vcount);
- zero_lfvector(to, from[0].vcount);
+ zero_lfvector(to, vcount);
-#pragma omp parallel sections private(i)
+#pragma omp parallel sections private(i) if(vcount > CLOTH_OPENMP_LIMIT)
{
#pragma omp section
{
@@ -965,7 +970,7 @@ DO_INLINE void BuildPPinv(fmatrix3x3 *lA, fmatrix3x3 *P, fmatrix3x3 *Pinv)
unsigned int i = 0;
// Take only the diagonal blocks of A
-// #pragma omp parallel for private(i)
+// #pragma omp parallel for private(i) if(lA[0].vcount > CLOTH_OPENMP_LIMIT)
for(i = 0; i<lA[0].vcount; i++)
{
// block diagonalizer
@@ -1425,7 +1430,7 @@ static void hair_velocity_smoothing(ClothModifierData *clmd, lfVector *lF, lfVec
/* 10x10x10 grid gives nice initial results */
HairGridVert grid[10][10][10];
HairGridVert colg[10][10][10];
- ListBase *colliders = get_collider_cache(clmd->scene, NULL);
+ ListBase *colliders = get_collider_cache(clmd->scene, NULL, NULL);
ColliderCache *col = NULL;
float gmin[3], gmax[3], density;
/* 2.0f is an experimental value that seems to give good results */
@@ -1463,6 +1468,8 @@ static void hair_velocity_smoothing(ClothModifierData *clmd, lfVector *lF, lfVec
i = HAIR_GRID_INDEX(lX[v], gmin, gmax, 0);
j = HAIR_GRID_INDEX(lX[v], gmin, gmax, 1);
k = HAIR_GRID_INDEX(lX[v], gmin, gmax, 2);
+ if (i < 0 || j < 0 || k < 0 || i > 10 || j >= 10 || k >= 10)
+ continue;
grid[i][j][k].velocity[0] += lV[v][0];
grid[i][j][k].velocity[1] += lV[v][1];
@@ -1526,6 +1533,8 @@ static void hair_velocity_smoothing(ClothModifierData *clmd, lfVector *lF, lfVec
i = HAIR_GRID_INDEX(lX[v], gmin, gmax, 0);
j = HAIR_GRID_INDEX(lX[v], gmin, gmax, 1);
k = HAIR_GRID_INDEX(lX[v], gmin, gmax, 2);
+ if (i < 0 || j < 0 || k < 0 || i > 10 || j >= 10 || k >= 10)
+ continue;
lF[v][0] += smoothfac * (grid[i][j][k].velocity[0] - lV[v][0]);
lF[v][1] += smoothfac * (grid[i][j][k].velocity[1] - lV[v][1]);
@@ -1540,6 +1549,7 @@ static void hair_velocity_smoothing(ClothModifierData *clmd, lfVector *lF, lfVec
free_collider_cache(&colliders);
}
+
static void cloth_calc_force(ClothModifierData *clmd, float frame, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time, fmatrix3x3 *M)
{
/* Collect forces and derivatives: F,dFdX,dFdV */
@@ -1734,9 +1744,10 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
ClothVertex *verts = cloth->verts;
unsigned int numverts = cloth->numverts;
float dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame;
+ float spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
Implicit_Data *id = cloth->implicit;
- int result = 0;
-
+ int do_extra_solve;
+
if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) /* do goal stuff */
{
for(i = 0; i < numverts; i++)
@@ -1781,60 +1792,50 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
if(clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED && clmd->clothObject->bvhtree)
{
- float temp = clmd->sim_parms->stepsPerFrame;
- /* not too nice hack, but collisions need this correction -jahka */
- clmd->sim_parms->stepsPerFrame /= clmd->sim_parms->timescale;
-
// collisions
// itstart();
// update verts to current positions
for(i = 0; i < numverts; i++)
- {
+ {
VECCOPY(verts[i].tx, id->Xnew[i]);
-
+
VECSUB(verts[i].tv, verts[i].tx, verts[i].txold);
VECCOPY(verts[i].v, verts[i].tv);
}
-
+
// call collision function
// TODO: check if "step" or "step+dt" is correct - dg
- result = cloth_bvh_objcollision(ob, clmd, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);
-
- // correct velocity again, just to be sure we had to change it due to adaptive collisions
- for(i = 0; i < numverts; i++)
- {
- VECSUB(verts[i].tv, verts[i].tx, id->X[i]);
- }
+ do_extra_solve = cloth_bvh_objcollision(ob, clmd, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);
// copy corrected positions back to simulation
for(i = 0; i < numverts; i++)
{
- if(result)
+ // correct velocity again, just to be sure we had to change it due to adaptive collisions
+ VECSUB(verts[i].tv, verts[i].tx, id->X[i]);
+
+ if(do_extra_solve)
{
if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (verts [i].flags & CLOTH_VERT_FLAG_PINNED))
continue;
-
+
VECCOPY(id->Xnew[i], verts[i].tx);
VECCOPY(id->Vnew[i], verts[i].tv);
- mul_v3_fl(id->Vnew[i], clmd->sim_parms->stepsPerFrame);
+ mul_v3_fl(id->Vnew[i], spf);
}
}
- /* restore original stepsPerFrame */
- clmd->sim_parms->stepsPerFrame = temp;
-
// X = Xnew;
cp_lfvector(id->X, id->Xnew, numverts);
-
+
// if there were collisions, advance the velocity from v_n+1/2 to v_n+1
- if(result)
+ if(do_extra_solve)
{
// V = Vnew;
cp_lfvector(id->V, id->Vnew, numverts);
-
+
// calculate
cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step+dt, id->M);
@@ -1854,7 +1855,6 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
cp_lfvector(id->V, id->Vnew, numverts);
step += dt;
-
}
for(i = 0; i < numverts; i++)
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index dbde6403226..cd8ab8290e5 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -41,54 +41,33 @@
#include <string.h>
#include <stddef.h>
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
-#include "DNA_action_types.h"
-#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
-#include "DNA_curve_types.h"
#include "DNA_camera_types.h"
#include "DNA_lamp_types.h"
#include "DNA_ipo_types.h"
#include "DNA_key_types.h"
#include "DNA_material_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_nla_types.h"
-#include "DNA_object_types.h"
-#include "DNA_object_force.h"
-#include "DNA_particle_types.h"
#include "DNA_sequence_types.h"
#include "DNA_scene_types.h"
-#include "DNA_sound_types.h"
-#include "DNA_texture_types.h"
-#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
+#include "BLI_math.h" /* windows needs for M_PI */
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_dynstr.h"
#include "BKE_utildefines.h"
#include "BKE_animsys.h"
#include "BKE_action.h"
-#include "BKE_blender.h"
-#include "BKE_curve.h"
-#include "BKE_constraint.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
-#include "BKE_ipo.h"
-#include "BKE_library.h"
#include "BKE_main.h"
-#include "BKE_mesh.h"
#include "BKE_nla.h"
-#include "BKE_object.h"
-
+#include "BKE_sequencer.h"
/* *************************************************** */
@@ -813,12 +792,12 @@ static char *particle_adrcodes_to_paths (int adrcode, int *array_index)
/* Allocate memory for RNA-path for some property given a blocktype, adrcode, and 'root' parts of path
* Input:
* - blocktype, adrcode - determines setting to get
- * - actname, constname - used to build path
+ * - actname, constname,seq - used to build path
* Output:
* - array_index - index in property's array (if applicable) to use
* - return - the allocated path...
*/
-static char *get_rna_access (int blocktype, int adrcode, char actname[], char constname[], int *array_index)
+static char *get_rna_access (int blocktype, int adrcode, char actname[], char constname[], Sequence * seq, int *array_index)
{
DynStr *path= BLI_dynstr_new();
char *propname=NULL, *rpath=NULL;
@@ -870,19 +849,19 @@ static char *get_rna_access (int blocktype, int adrcode, char actname[], char co
case ID_WO: /* world */
propname= world_adrcodes_to_paths(adrcode, &dummy_index);
break;
-
+
case ID_PA: /* particle */
propname= particle_adrcodes_to_paths(adrcode, &dummy_index);
break;
- /* XXX problematic blocktypes */
case ID_CU: /* curve */
/* this used to be a 'dummy' curve which got evaluated on the fly...
* now we've got real var for this!
*/
propname= "eval_time";
break;
-
+
+ /* XXX problematic blocktypes */
case ID_SEQ: /* sequencer strip */
//SEQ_FAC1:
switch (adrcode) {
@@ -940,6 +919,11 @@ static char *get_rna_access (int blocktype, int adrcode, char actname[], char co
/* Constraint in Object */
sprintf(buf, "constraints[\"%s\"]", constname);
}
+ else if (seq) {
+ /* Sequence names in Scene */
+ sprintf(buf, "sequence_editor.sequences_all[\"%s\"]",
+ seq->name+2);
+ }
else
strcpy(buf, ""); /* empty string */
BLI_dynstr_append(path, buf);
@@ -1051,6 +1035,7 @@ static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver)
if (idriver->name[0])
BLI_strncpy(dtar->pchan_name, idriver->name, 32);
dtar->transChan= adrcode_to_dtar_transchan(idriver->adrcode);
+ dtar->flag |= DTAR_FLAG_LOCALSPACE; /* old drivers took local space */
}
}
else { /* Object */
@@ -1083,7 +1068,7 @@ static void fcurve_add_to_list (ListBase *groups, ListBase *list, FCurve *fcu, c
bActionGroup *agrp= NULL;
/* init the temp action */
- //memset(&tmp_act, 0, sizeof(bAction)); // XXX only enable this line if we get errors
+ memset(&tmp_act, 0, sizeof(bAction)); // XXX only enable this line if we get errors
tmp_act.groups.first= groups->first;
tmp_act.groups.last= groups->last;
tmp_act.curves.first= list->first;
@@ -1099,8 +1084,8 @@ static void fcurve_add_to_list (ListBase *groups, ListBase *list, FCurve *fcu, c
agrp= MEM_callocN(sizeof(bActionGroup), "bActionGroup");
agrp->flag = AGRP_SELECTED;
- if(muteipo) agrp->flag |= AGRP_MUTED;
-
+ if (muteipo) agrp->flag |= AGRP_MUTED;
+
strncpy(agrp->name, grpname, sizeof(agrp->name));
BLI_addtail(&tmp_act.groups, agrp);
@@ -1112,9 +1097,9 @@ static void fcurve_add_to_list (ListBase *groups, ListBase *list, FCurve *fcu, c
/* WARNING: this func should only need to look at the stuff we initialised, if not, things may crash */
action_groups_add_channel(&tmp_act, agrp, fcu);
- if(agrp->flag & AGRP_MUTED) /* flush down */
+ if (agrp->flag & AGRP_MUTED) /* flush down */
fcu->flag |= FCURVE_MUTED;
-
+
/* set the output lists based on the ones in the temp action */
groups->first= tmp_act.groups.first;
groups->last= tmp_act.groups.last;
@@ -1131,8 +1116,9 @@ static void fcurve_add_to_list (ListBase *groups, ListBase *list, FCurve *fcu, c
* is not relevant, BUT do not free the IPO-Curve itself...
* actname: name of Action-Channel (if applicable) that IPO-Curve's IPO-block belonged to
* constname: name of Constraint-Channel (if applicable) that IPO-Curve's IPO-block belonged to
+ * seq: sequencer-strip (if applicable) that IPO-Curve's IPO-block belonged to
*/
-static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, char *actname, char *constname, int muteipo)
+static void icu_to_fcurves (ID *id, ListBase *groups, ListBase *list, IpoCurve *icu, char *actname, char *constname, Sequence * seq, int muteipo)
{
AdrBit2Path *abp;
FCurve *fcu;
@@ -1255,7 +1241,7 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
/* get rna-path
* - we will need to set the 'disabled' flag if no path is able to be made (for now)
*/
- fcu->rna_path= get_rna_access(icu->blocktype, icu->adrcode, actname, constname, &fcu->array_index);
+ fcu->rna_path= get_rna_access(icu->blocktype, icu->adrcode, actname, constname, seq, &fcu->array_index);
if (fcu->rna_path == NULL)
fcu->flag |= FCURVE_DISABLED;
@@ -1297,6 +1283,20 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
dst->vec[2][1] *= fac;
}
+ /* correct values for path speed curves
+ * - their values were 0-1
+ * - we now need as 'frames'
+ */
+ if ( (id) && (icu->blocktype == GS(id->name)) &&
+ (fcu->rna_path && strcmp(fcu->rna_path, "eval_time")==0) )
+ {
+ Curve *cu = (Curve *)id;
+
+ dst->vec[0][1] *= cu->pathlen;
+ dst->vec[1][1] *= cu->pathlen;
+ dst->vec[2][1] *= cu->pathlen;
+ }
+
/* correct times for rotation drivers
* - need to go from degrees to radians...
* - there's only really 1 target to worry about
@@ -1313,6 +1313,24 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
dst->vec[2][0] *= fac;
}
}
+
+ /* correct values for sequencer curves,
+ that were not locked to frame */
+
+ if (seq &&
+ (seq->flag & SEQ_IPO_FRAME_LOCKED) == 0) {
+ double mul= (seq->enddisp-seq->startdisp)/100.0f;
+ double offset= seq->startdisp;
+
+ dst->vec[0][0] *= mul;
+ dst->vec[0][0] += offset;
+
+ dst->vec[1][0] *= mul;
+ dst->vec[1][0] += offset;
+
+ dst->vec[2][0] *= mul;
+ dst->vec[2][0] += offset;
+ }
}
}
else if (icu->bp) {
@@ -1332,7 +1350,7 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
* This does not assume that any ID or AnimData uses it, but does assume that
* it is given two lists, which it will perform driver/animation-data separation.
*/
-static void ipo_to_animato (Ipo *ipo, char actname[], char constname[], ListBase *animgroups, ListBase *anim, ListBase *drivers)
+static void ipo_to_animato (ID *id, Ipo *ipo, char actname[], char constname[], Sequence * seq, ListBase *animgroups, ListBase *anim, ListBase *drivers)
{
IpoCurve *icu;
@@ -1363,7 +1381,7 @@ static void ipo_to_animato (Ipo *ipo, char actname[], char constname[], ListBase
if (icu->driver) {
/* Blender 2.4x allowed empty drivers, but we don't now, since they cause more trouble than they're worth */
if ((icu->driver->ob) || (icu->driver->type == IPO_DRIVER_TYPE_PYTHON)) {
- icu_to_fcurves(NULL, drivers, icu, actname, constname, ipo->muteipo);
+ icu_to_fcurves(id, NULL, drivers, icu, actname, constname, seq, ipo->muteipo);
}
else {
MEM_freeN(icu->driver);
@@ -1371,7 +1389,7 @@ static void ipo_to_animato (Ipo *ipo, char actname[], char constname[], ListBase
}
}
else
- icu_to_fcurves(animgroups, anim, icu, actname, constname, ipo->muteipo);
+ icu_to_fcurves(id, animgroups, anim, icu, actname, constname, seq, ipo->muteipo);
}
/* if this IPO block doesn't have any users after this one, free... */
@@ -1402,7 +1420,7 @@ static void ipo_to_animato (Ipo *ipo, char actname[], char constname[], ListBase
* to Objects, where ob->ipo and ob->action need to be combined).
* NOTE: we need to be careful here, as same data-structs are used for new system too!
*/
-static void action_to_animato (bAction *act, ListBase *groups, ListBase *curves, ListBase *drivers)
+static void action_to_animato (ID *id, bAction *act, ListBase *groups, ListBase *curves, ListBase *drivers)
{
bActionChannel *achan, *achann;
bConstraintChannel *conchan, *conchann;
@@ -1423,7 +1441,7 @@ static void action_to_animato (bAction *act, ListBase *groups, ListBase *curves,
/* convert Action Channel's IPO data */
if (achan->ipo) {
- ipo_to_animato(achan->ipo, achan->name, NULL, groups, curves, drivers);
+ ipo_to_animato(id, achan->ipo, achan->name, NULL, NULL, groups, curves, drivers);
achan->ipo->id.us--;
achan->ipo= NULL;
}
@@ -1435,7 +1453,7 @@ static void action_to_animato (bAction *act, ListBase *groups, ListBase *curves,
/* convert Constraint Channel's IPO data */
if (conchan->ipo) {
- ipo_to_animato(conchan->ipo, achan->name, conchan->name, groups, curves, drivers);
+ ipo_to_animato(id, conchan->ipo, achan->name, conchan->name, NULL, groups, curves, drivers);
conchan->ipo->id.us--;
conchan->ipo= NULL;
}
@@ -1456,7 +1474,7 @@ static void action_to_animato (bAction *act, ListBase *groups, ListBase *curves,
* This assumes that AnimData has been added already. Separation of drivers
* from animation data is accomplished here too...
*/
-static void ipo_to_animdata (ID *id, Ipo *ipo, char actname[], char constname[])
+static void ipo_to_animdata (ID *id, Ipo *ipo, char actname[], char constname[], Sequence * seq)
{
AnimData *adt= BKE_animdata_from_id(id);
ListBase anim = {NULL, NULL};
@@ -1471,8 +1489,8 @@ static void ipo_to_animdata (ID *id, Ipo *ipo, char actname[], char constname[])
}
if (G.f & G_DEBUG) {
- printf("ipo to animdata - ID:%s, IPO:%s, actname:%s constname:%s curves:%d \n",
- id->name+2, ipo->id.name+2, (actname)?actname:"<None>", (constname)?constname:"<None>",
+ printf("ipo to animdata - ID:%s, IPO:%s, actname:%s constname:%s seqname:%s curves:%d \n",
+ id->name+2, ipo->id.name+2, (actname)?actname:"<None>", (constname)?constname:"<None>", (seq)?(seq->name+2):"<None>",
BLI_countlist(&ipo->curve));
}
@@ -1480,7 +1498,7 @@ static void ipo_to_animdata (ID *id, Ipo *ipo, char actname[], char constname[])
* and the try to put these lists in the right places, but do not free the lists here
*/
// XXX there shouldn't be any need for the groups, so don't supply pointer for that now...
- ipo_to_animato(ipo, actname, constname, NULL, &anim, &drivers);
+ ipo_to_animato(id, ipo, actname, constname, seq, NULL, &anim, &drivers);
/* deal with animation first */
if (anim.first) {
@@ -1522,7 +1540,7 @@ static void action_to_animdata (ID *id, bAction *act)
}
/* convert Action data */
- action_to_animato(act, &adt->action->groups, &adt->action->curves, &adt->drivers);
+ action_to_animato(id, act, &adt->action->groups, &adt->action->curves, &adt->drivers);
}
/* ------------------------- */
@@ -1546,7 +1564,7 @@ static void nlastrips_to_animdata (ID *id, ListBase *strips)
/* this old strip is only worth something if it had an action... */
if (as->act) {
/* convert Action data (if not yet converted), storing the results in the same Action */
- action_to_animato(as->act, &as->act->groups, &as->act->curves, &adt->drivers);
+ action_to_animato(id, as->act, &as->act->groups, &as->act->curves, &adt->drivers);
/* create a new-style NLA-strip which references this Action, then copy over relevant settings */
{
@@ -1625,7 +1643,6 @@ void do_versions_ipos_to_animato(Main *main)
ListBase drivers = {NULL, NULL};
ID *id;
AnimData *adt;
- Scene *scene;
if (main == NULL) {
printf("Argh! Main is NULL in do_versions_ipos_to_animato() \n");
@@ -1633,13 +1650,12 @@ void do_versions_ipos_to_animato(Main *main)
}
/* only convert if version is right */
- // XXX???
if (main->versionfile >= 250) {
printf("WARNING: Animation data too new to convert (Version %d) \n", main->versionfile);
return;
}
- else
- printf("INFO: Converting to Animato... \n"); // xxx debug
+ else if (G.f & G_DEBUG)
+ printf("INFO: Converting to Animato... \n");
/* ----------- Animation Attached to Data -------------- */
@@ -1659,7 +1675,7 @@ void do_versions_ipos_to_animato(Main *main)
/* IPO first to take into any non-NLA'd Object Animation */
if (ob->ipo) {
- ipo_to_animdata(id, ob->ipo, NULL, NULL);
+ ipo_to_animdata(id, ob->ipo, NULL, NULL, NULL);
ob->ipo->id.us--;
ob->ipo= NULL;
@@ -1693,7 +1709,7 @@ void do_versions_ipos_to_animato(Main *main)
/* IPO second... */
if (ob->ipo) {
- ipo_to_animdata(id, ob->ipo, NULL, NULL);
+ ipo_to_animdata(id, ob->ipo, NULL, NULL, NULL);
ob->ipo->id.us--;
ob->ipo= NULL;
}
@@ -1713,7 +1729,7 @@ void do_versions_ipos_to_animato(Main *main)
/* although this was the constraint's local IPO, we still need to provide pchan + con
* so that drivers can be added properly...
*/
- ipo_to_animdata(id, con->ipo, pchan->name, con->name);
+ ipo_to_animdata(id, con->ipo, pchan->name, con->name, NULL);
con->ipo->id.us--;
con->ipo= NULL;
}
@@ -1733,7 +1749,7 @@ void do_versions_ipos_to_animato(Main *main)
/* although this was the constraint's local IPO, we still need to provide con
* so that drivers can be added properly...
*/
- ipo_to_animdata(id, con->ipo, NULL, con->name);
+ ipo_to_animdata(id, con->ipo, NULL, con->name, NULL);
con->ipo->id.us--;
con->ipo= NULL;
}
@@ -1753,7 +1769,7 @@ void do_versions_ipos_to_animato(Main *main)
/* convert Constraint Channel's IPO data */
if (conchan->ipo) {
- ipo_to_animdata(id, conchan->ipo, NULL, conchan->name);
+ ipo_to_animdata(id, conchan->ipo, NULL, conchan->name, NULL);
conchan->ipo->id.us--;
conchan->ipo= NULL;
}
@@ -1779,7 +1795,7 @@ void do_versions_ipos_to_animato(Main *main)
adt= BKE_id_add_animdata(id);
/* Convert Shapekey data... */
- ipo_to_animdata(id, key->ipo, NULL, NULL);
+ ipo_to_animdata(id, key->ipo, NULL, NULL, NULL);
key->ipo->id.us--;
key->ipo= NULL;
}
@@ -1797,7 +1813,7 @@ void do_versions_ipos_to_animato(Main *main)
adt= BKE_id_add_animdata(id);
/* Convert Material data... */
- ipo_to_animdata(id, ma->ipo, NULL, NULL);
+ ipo_to_animdata(id, ma->ipo, NULL, NULL, NULL);
ma->ipo->id.us--;
ma->ipo= NULL;
}
@@ -1815,27 +1831,30 @@ void do_versions_ipos_to_animato(Main *main)
adt= BKE_id_add_animdata(id);
/* Convert World data... */
- ipo_to_animdata(id, wo->ipo, NULL, NULL);
+ ipo_to_animdata(id, wo->ipo, NULL, NULL, NULL);
wo->ipo->id.us--;
wo->ipo= NULL;
}
}
/* sequence strips */
- for(scene = main->scene.first; scene; scene = scene->id.next) {
- if(scene->ed && scene->ed->seqbasep) {
+ for (id= main->scene.first; id; id= id->next) {
+ Scene *scene = (Scene *)id;
+ Editing * ed = scene->ed;
+ if (ed && ed->seqbasep) {
Sequence * seq;
- for(seq = scene->ed->seqbasep->first;
- seq; seq = seq->next) {
+ adt= BKE_id_add_animdata(id);
+
+ SEQ_BEGIN(ed, seq) {
+ IpoCurve *icu = (seq->ipo) ? seq->ipo->curve.first : NULL;
short adrcode = SEQ_FAC1;
if (G.f & G_DEBUG)
printf("\tconverting sequence strip %s \n", seq->name+2);
- if (!seq->ipo || !seq->ipo->curve.first) {
- seq->flag |=
- SEQ_USE_EFFECT_DEFAULT_FADE;
+ if (ELEM(NULL, seq->ipo, icu)) {
+ seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE;
continue;
}
@@ -1844,24 +1863,25 @@ void do_versions_ipos_to_animato(Main *main)
(semi-hack (tm) )
*/
switch(seq->type) {
- case SEQ_IMAGE:
- case SEQ_META:
- case SEQ_SCENE:
- case SEQ_MOVIE:
- case SEQ_COLOR:
- adrcode = SEQ_FAC_OPACITY;
- break;
- case SEQ_SPEED:
- adrcode = SEQ_FAC_SPEED;
- break;
+ case SEQ_IMAGE:
+ case SEQ_META:
+ case SEQ_SCENE:
+ case SEQ_MOVIE:
+ case SEQ_COLOR:
+ adrcode = SEQ_FAC_OPACITY;
+ break;
+ case SEQ_SPEED:
+ adrcode = SEQ_FAC_SPEED;
+ break;
}
- ((IpoCurve*) seq->ipo->curve.first)
- ->adrcode = adrcode;
- ipo_to_animdata((ID*) seq, seq->ipo,
- NULL, NULL);
+ icu->adrcode = adrcode;
+
+ /* convert IPO */
+ ipo_to_animdata((ID *)scene, seq->ipo, NULL, NULL, seq);
seq->ipo->id.us--;
seq->ipo = NULL;
}
+ SEQ_END
}
}
@@ -1878,7 +1898,7 @@ void do_versions_ipos_to_animato(Main *main)
adt= BKE_id_add_animdata(id);
/* Convert Texture data... */
- ipo_to_animdata(id, te->ipo, NULL, NULL);
+ ipo_to_animdata(id, te->ipo, NULL, NULL, NULL);
te->ipo->id.us--;
te->ipo= NULL;
}
@@ -1896,7 +1916,7 @@ void do_versions_ipos_to_animato(Main *main)
adt= BKE_id_add_animdata(id);
/* Convert Camera data... */
- ipo_to_animdata(id, ca->ipo, NULL, NULL);
+ ipo_to_animdata(id, ca->ipo, NULL, NULL, NULL);
ca->ipo->id.us--;
ca->ipo= NULL;
}
@@ -1914,12 +1934,30 @@ void do_versions_ipos_to_animato(Main *main)
adt= BKE_id_add_animdata(id);
/* Convert Lamp data... */
- ipo_to_animdata(id, la->ipo, NULL, NULL);
+ ipo_to_animdata(id, la->ipo, NULL, NULL, NULL);
la->ipo->id.us--;
la->ipo= NULL;
}
}
+ /* curves */
+ for (id= main->curve.first; id; id= id->next) {
+ Curve *cu= (Curve *)id;
+
+ if (G.f & G_DEBUG) printf("\tconverting curve %s \n", id->name+2);
+
+ /* we're only interested in the IPO */
+ if (cu->ipo) {
+ /* Add AnimData block */
+ adt= BKE_id_add_animdata(id);
+
+ /* Convert Curve data... */
+ ipo_to_animdata(id, cu->ipo, NULL, NULL, NULL);
+ cu->ipo->id.us--;
+ cu->ipo= NULL;
+ }
+ }
+
/* --------- Unconverted Animation Data ------------------ */
/* For Animation data which may not be directly connected (i.e. not linked) to any other
* data, we need to perform a separate pass to make sure that they are converted to standalone
@@ -1938,7 +1976,7 @@ void do_versions_ipos_to_animato(Main *main)
if (G.f & G_DEBUG) printf("\tconverting action %s \n", id->name+2);
/* be careful! some of the actions we encounter will be converted ones... */
- action_to_animato(act, &act->groups, &act->curves, &drivers);
+ action_to_animato(NULL, act, &act->groups, &act->curves, &drivers);
}
/* ipo's */
@@ -1953,7 +1991,7 @@ void do_versions_ipos_to_animato(Main *main)
/* add a new action for this, and convert all data into that action */
new_act= add_empty_action("ConvIPO_Action"); // XXX need a better name...
- ipo_to_animato(ipo, NULL, NULL, NULL, &new_act->curves, &drivers);
+ ipo_to_animato(NULL, ipo, NULL, NULL, NULL, NULL, &new_act->curves, &drivers);
}
/* clear fake-users, and set user-count to zero to make sure it is cleared on file-save */
@@ -1964,6 +2002,7 @@ void do_versions_ipos_to_animato(Main *main)
/* free unused drivers from actions + ipos */
free_fcurves(&drivers);
- printf("INFO: Animato convert done \n"); // xxx debug
+ if (G.f & G_DEBUG)
+ printf("INFO: Animato convert done \n");
}
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index c32b2d81513..efbc09692a9 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -38,26 +38,22 @@
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
+#include "BLI_math_vector.h"
#include "DNA_anim_types.h"
-#include "DNA_curve_types.h"
#include "DNA_key_types.h"
#include "DNA_lattice_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "BKE_animsys.h"
-#include "BKE_action.h"
-#include "BKE_blender.h"
#include "BKE_curve.h"
#include "BKE_customdata.h"
#include "BKE_global.h"
#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_library.h"
-#include "BKE_mesh.h"
#include "BKE_tessmesh.h"
#include "BKE_main.h"
#include "BKE_object.h"
@@ -67,10 +63,6 @@
#include "BLI_cellalloc.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#define KEY_BPOINT 1
#define KEY_BEZTRIPLE 2
@@ -227,11 +219,11 @@ Key *copy_key_nolib(Key *key)
void make_local_key(Key *key)
{
- /* - only lib users: do nothing
- * - only local users: set flag
- * - mixed: make copy
- */
- if(key==0) return;
+ /* - only lib users: do nothing
+ * - only local users: set flag
+ * - mixed: make copy
+ */
+ if(key==0) return;
key->id.lib= 0;
new_id(0, (ID *)key, 0);
@@ -1778,3 +1770,202 @@ void key_to_mesh(KeyBlock *kb, Mesh *me)
VECCOPY(mvert->co, fp);
}
}
+
+/************************* vert coords ************************/
+float (*key_to_vertcos(Object *ob, KeyBlock *kb))[3]
+{
+ float (*vertCos)[3], *co;
+ float *fp= kb->data;
+ int tot= 0, a;
+
+ /* Count of vertex coords in array */
+ if(ob->type == OB_MESH) {
+ Mesh *me= (Mesh*)ob->data;
+ tot= me->totvert;
+ } else if(ob->type == OB_LATTICE) {
+ Lattice *lt= (Lattice*)ob->data;
+ tot= lt->pntsu*lt->pntsv*lt->pntsw;
+ } else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ Curve *cu= (Curve*)ob->data;
+ tot= count_curveverts(&cu->nurb);
+ }
+
+ if (tot == 0) return NULL;
+
+ vertCos= MEM_callocN(tot*sizeof(*vertCos), "key_to_vertcos vertCos");
+
+ /* Copy coords to array */
+ co= (float*)vertCos;
+
+ if(ELEM(ob->type, OB_MESH, OB_LATTICE)) {
+ for (a= 0; a<tot; a++, fp+=3, co+=3) {
+ copy_v3_v3(co, fp);
+ }
+ } else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ Curve *cu= (Curve*)ob->data;
+ Nurb *nu= cu->nurb.first;
+ BezTriple *bezt;
+ BPoint *bp;
+
+ while (nu) {
+ if(nu->bezt) {
+ int i;
+ bezt= nu->bezt;
+ a= nu->pntsu;
+
+ while (a--) {
+ for (i= 0; i<3; i++) {
+ copy_v3_v3(co, fp);
+ fp+= 3; co+= 3;
+ }
+
+ fp+= 3; /* skip alphas */
+
+ bezt++;
+ }
+ }
+ else {
+ bp= nu->bp;
+ a= nu->pntsu*nu->pntsv;
+
+ while (a--) {
+ copy_v3_v3(co, fp);
+
+ fp+= 4;
+ co+= 3;
+
+ bp++;
+ }
+ }
+
+ nu= nu->next;
+ }
+ }
+
+ return vertCos;
+}
+
+void vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3])
+{
+ float *co= (float*)vertCos, *fp;
+ int tot= 0, a, elemsize;
+
+ if (kb->data) MEM_freeN(kb->data);
+
+ /* Count of vertex coords in array */
+ if(ob->type == OB_MESH) {
+ Mesh *me= (Mesh*)ob->data;
+ tot= me->totvert;
+ elemsize= me->key->elemsize;
+ } else if(ob->type == OB_LATTICE) {
+ Lattice *lt= (Lattice*)ob->data;
+ tot= lt->pntsu*lt->pntsv*lt->pntsw;
+ elemsize= lt->key->elemsize;
+ } else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ Curve *cu= (Curve*)ob->data;
+ elemsize= cu->key->elemsize;
+ tot= count_curveverts(&cu->nurb);
+ }
+
+ fp= kb->data= MEM_callocN(tot*elemsize, "key_to_vertcos vertCos");
+
+ if (tot == 0) return;
+
+ /* Copy coords to keyblock */
+
+ if(ELEM(ob->type, OB_MESH, OB_LATTICE)) {
+ for (a= 0; a<tot; a++, fp+=3, co+=3) {
+ copy_v3_v3(fp, co);
+ }
+ } else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ Curve *cu= (Curve*)ob->data;
+ Nurb *nu= cu->nurb.first;
+ BezTriple *bezt;
+ BPoint *bp;
+
+ while (nu) {
+ if(nu->bezt) {
+ int i;
+ bezt= nu->bezt;
+ a= nu->pntsu;
+
+ while (a--) {
+ for (i= 0; i<3; i++) {
+ copy_v3_v3(fp, co);
+ fp+= 3; co+= 3;
+ }
+
+ fp+= 3; /* skip alphas */
+
+ bezt++;
+ }
+ }
+ else {
+ bp= nu->bp;
+ a= nu->pntsu*nu->pntsv;
+
+ while (a--) {
+ copy_v3_v3(fp, co);
+
+ fp+= 4;
+ co+= 3;
+
+ bp++;
+ }
+ }
+
+ nu= nu->next;
+ }
+ }
+}
+
+void offset_to_key(Object *ob, KeyBlock *kb, float (*ofs)[3])
+{
+ int a;
+ float *co= (float*)ofs, *fp= kb->data;
+
+ if(ELEM(ob->type, OB_MESH, OB_LATTICE)) {
+ for (a= 0; a<kb->totelem; a++, fp+=3, co+=3) {
+ add_v3_v3(fp, co);
+ }
+ } else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
+ Curve *cu= (Curve*)ob->data;
+ Nurb *nu= cu->nurb.first;
+ BezTriple *bezt;
+ BPoint *bp;
+
+ while (nu) {
+ if(nu->bezt) {
+ int i;
+ bezt= nu->bezt;
+ a= nu->pntsu;
+
+ while (a--) {
+ for (i= 0; i<3; i++) {
+ add_v3_v3(fp, co);
+ fp+= 3; co+= 3;
+ }
+
+ fp+= 3; /* skip alphas */
+
+ bezt++;
+ }
+ }
+ else {
+ bp= nu->bp;
+ a= nu->pntsu*nu->pntsv;
+
+ while (a--) {
+ add_v3_v3(fp, co);
+
+ fp+= 4;
+ co+= 3;
+
+ bp++;
+ }
+ }
+
+ nu= nu->next;
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 211f3d07cf4..55934c0af5c 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -42,22 +42,15 @@
#include "BLI_math.h"
#include "BLI_cellalloc.h"
-#include "DNA_armature_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_lattice_types.h"
#include "DNA_curve_types.h"
#include "DNA_key_types.h"
#include "BKE_anim.h"
-#include "BKE_armature.h"
-#include "BKE_curve.h"
#include "BKE_cdderivedmesh.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_deform.h"
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_key.h"
@@ -66,9 +59,8 @@
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
-#include "BKE_object.h"
-#include "BKE_screen.h"
#include "BKE_utildefines.h"
+#include "BKE_deform.h"
//XXX #include "BIF_editdeform.h"
@@ -348,19 +340,29 @@ void calc_latt_deform(Object *ob, float *co, float weight)
{
Lattice *lt= ob->data;
float u, v, w, tu[4], tv[4], tw[4];
- float *fpw, *fpv, *fpu, vec[3];
+ float vec[3];
+ int idx_w, idx_v, idx_u;
int ui, vi, wi, uu, vv, ww;
-
+
+ /* vgroup influence */
+ int defgroup_nr= -1;
+ float co_prev[3], weight_blend= 0.0f;
+ MDeformVert *dvert= lattice_get_deform_verts(ob);
+
+
if(lt->editlatt) lt= lt->editlatt;
if(lt->latticedata==NULL) return;
-
+
+ if(lt->vgroup[0] && dvert) {
+ defgroup_nr= defgroup_name_index(ob, lt->vgroup);
+ copy_v3_v3(co_prev, co);
+ }
+
/* co is in local coords, treat with latmat */
-
- VECCOPY(vec, co);
- mul_m4_v3(lt->latmat, vec);
-
+ mul_v3_m4v3(vec, lt->latmat, co);
+
/* u v w coords */
-
+
if(lt->pntsu>1) {
u= (vec[0]-lt->fu)/lt->du;
ui= (int)floor(u);
@@ -371,7 +373,7 @@ void calc_latt_deform(Object *ob, float *co, float weight)
tu[0]= tu[2]= tu[3]= 0.0; tu[1]= 1.0;
ui= 0;
}
-
+
if(lt->pntsv>1) {
v= (vec[1]-lt->fv)/lt->dv;
vi= (int)floor(v);
@@ -382,7 +384,7 @@ void calc_latt_deform(Object *ob, float *co, float weight)
tv[0]= tv[2]= tv[3]= 0.0; tv[1]= 1.0;
vi= 0;
}
-
+
if(lt->pntsw>1) {
w= (vec[2]-lt->fw)/lt->dw;
wi= (int)floor(w);
@@ -393,46 +395,51 @@ void calc_latt_deform(Object *ob, float *co, float weight)
tw[0]= tw[2]= tw[3]= 0.0; tw[1]= 1.0;
wi= 0;
}
-
+
for(ww= wi-1; ww<=wi+2; ww++) {
w= tw[ww-wi+1];
-
+
if(w!=0.0) {
if(ww>0) {
- if(ww<lt->pntsw) fpw= lt->latticedata + 3*ww*lt->pntsu*lt->pntsv;
- else fpw= lt->latticedata + 3*(lt->pntsw-1)*lt->pntsu*lt->pntsv;
+ if(ww<lt->pntsw) idx_w= ww*lt->pntsu*lt->pntsv;
+ else idx_w= (lt->pntsw-1)*lt->pntsu*lt->pntsv;
}
- else fpw= lt->latticedata;
-
+ else idx_w= 0;
+
for(vv= vi-1; vv<=vi+2; vv++) {
v= w*tv[vv-vi+1];
-
+
if(v!=0.0) {
if(vv>0) {
- if(vv<lt->pntsv) fpv= fpw + 3*vv*lt->pntsu;
- else fpv= fpw + 3*(lt->pntsv-1)*lt->pntsu;
+ if(vv<lt->pntsv) idx_v= idx_w + vv*lt->pntsu;
+ else idx_v= idx_w + (lt->pntsv-1)*lt->pntsu;
}
- else fpv= fpw;
-
+ else idx_v= idx_w;
+
for(uu= ui-1; uu<=ui+2; uu++) {
u= weight*v*tu[uu-ui+1];
-
+
if(u!=0.0) {
if(uu>0) {
- if(uu<lt->pntsu) fpu= fpv + 3*uu;
- else fpu= fpv + 3*(lt->pntsu-1);
+ if(uu<lt->pntsu) idx_u= idx_v + uu;
+ else idx_u= idx_v + (lt->pntsu-1);
}
- else fpu= fpv;
-
- co[0]+= u*fpu[0];
- co[1]+= u*fpu[1];
- co[2]+= u*fpu[2];
+ else idx_u= idx_v;
+
+ madd_v3_v3fl(co, &lt->latticedata[idx_u * 3], u);
+
+ if(defgroup_nr != -1)
+ weight_blend += (u * defvert_find_weight(dvert + idx_u, defgroup_nr));
}
}
}
}
}
}
+
+ if(defgroup_nr != -1)
+ interp_v3_v3v3(co, co_prev, co, weight_blend);
+
}
void end_latt_deform(Object *ob)
@@ -491,7 +498,7 @@ static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir,
else ctime1= ctime;
/* vec needs 4 items */
- if(where_on_path(ob, ctime1, vec, dir, quat, radius)) {
+ if(where_on_path(ob, ctime1, vec, dir, quat, radius, NULL)) {
if(cycl==0) {
Path *path= cu->path;
@@ -510,6 +517,7 @@ static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir,
VECADD(vec, vec, dvec);
if(quat) QUATCOPY(quat, path->data[path->len-1].quat);
if(radius) *radius= path->data[path->len-1].radius;
+ /* weight - not used but could be added */
}
}
return 1;
@@ -724,7 +732,7 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target, DerivedMesh
/* find the group (weak loop-in-loop) */
for(index = 0, curdef = target->defbase.first; curdef;
- curdef = curdef->next, index++)
+ curdef = curdef->next, index++)
if (!strcmp(curdef->name, vgroup))
break;
@@ -756,7 +764,7 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target, DerivedMesh
VECCOPY(vec, vertexCos[a]);
calc_curve_deform(scene, cuOb, vec, defaxis, &cd, NULL);
interp_v3_v3v3(vertexCos[a], vertexCos[a], vec,
- dvert->dw[j].weight);
+ dvert->dw[j].weight);
mul_m4_v3(cd.objectspace, vertexCos[a]);
break;
}
@@ -814,7 +822,7 @@ void curve_deform_vector(Scene *scene, Object *cuOb, Object *target, float *orco
}
void lattice_deform_verts(Object *laOb, Object *target, DerivedMesh *dm,
- float (*vertexCos)[3], int numVerts, char *vgroup)
+ float (*vertexCos)[3], int numVerts, char *vgroup)
{
int a;
int use_vgroups;
@@ -838,26 +846,20 @@ void lattice_deform_verts(Object *laOb, Object *target, DerivedMesh *dm,
use_vgroups = 0;
if(vgroup && vgroup[0] && use_vgroups) {
- bDeformGroup *curdef;
Mesh *me = target->data;
- int index = 0;
-
- /* find the group (weak loop-in-loop) */
- for(curdef = target->defbase.first; curdef;
- curdef = curdef->next, index++)
- if(!strcmp(curdef->name, vgroup)) break;
+ int index = defgroup_name_index(target, vgroup);
+ float weight;
- if(curdef && (me->dvert || dm)) {
+ if(index >= 0 && (me->dvert || dm)) {
MDeformVert *dvert = me->dvert;
- int j;
for(a = 0; a < numVerts; a++, dvert++) {
if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
- for(j = 0; j < dvert->totweight; j++) {
- if (dvert->dw[j].def_nr == index) {
- calc_latt_deform(laOb, vertexCos[a], dvert->dw[j].weight);
- }
- }
+
+ weight= defvert_find_weight(dvert, index);
+
+ if(weight > 0.0f)
+ calc_latt_deform(laOb, vertexCos[a], weight);
}
}
} else {
@@ -868,14 +870,14 @@ void lattice_deform_verts(Object *laOb, Object *target, DerivedMesh *dm,
end_latt_deform(laOb);
}
-int object_deform_mball(Object *ob)
+int object_deform_mball(Object *ob, ListBase *dispbase)
{
if(ob->parent && ob->parent->type==OB_LATTICE && ob->partype==PARSKEL) {
DispList *dl;
- for (dl=ob->disp.first; dl; dl=dl->next) {
+ for (dl=dispbase->first; dl; dl=dl->next) {
lattice_deform_verts(ob->parent, ob, NULL,
- (float(*)[3]) dl->verts, dl->nr, NULL);
+ (float(*)[3]) dl->verts, dl->nr, NULL);
}
return 1;
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index a7cafd1e0b4..d6a3dc8d983 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -40,24 +40,14 @@
#include <stdlib.h>
#include <stddef.h>
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include "MEM_guardedalloc.h"
/* all types are needed here, in order to do memory operations */
-#include "DNA_ID.h"
-#include "DNA_listBase.h"
#include "DNA_scene_types.h"
-#include "DNA_object_types.h"
#include "DNA_mesh_types.h"
#include "DNA_lattice_types.h"
-#include "DNA_curve_types.h"
#include "DNA_meta_types.h"
#include "DNA_material_types.h"
-#include "DNA_texture_types.h"
-#include "DNA_image_types.h"
#include "DNA_wave_types.h"
#include "DNA_lamp_types.h"
#include "DNA_camera_types.h"
@@ -70,17 +60,10 @@
#include "DNA_sound_types.h"
#include "DNA_group_types.h"
#include "DNA_armature_types.h"
-#include "DNA_action_types.h"
-#include "DNA_userdef_types.h"
#include "DNA_node_types.h"
#include "DNA_nla_types.h"
-#include "DNA_effect_types.h"
-#include "DNA_brush_types.h"
-#include "DNA_particle_types.h"
-#include "DNA_space_types.h"
#include "DNA_windowmanager_types.h"
#include "DNA_anim_types.h"
-#include "DNA_gpencil_types.h"
#include "BLI_blenlib.h"
#include "BLI_dynstr.h"
@@ -93,7 +76,6 @@
#include "BKE_sound.h"
#include "BKE_object.h"
#include "BKE_screen.h"
-#include "BKE_script.h"
#include "BKE_mesh.h"
#include "BKE_material.h"
#include "BKE_curve.h"
@@ -112,7 +94,6 @@
#include "BKE_armature.h"
#include "BKE_action.h"
#include "BKE_node.h"
-#include "BKE_effect.h"
#include "BKE_brush.h"
#include "BKE_idprop.h"
#include "BKE_particle.h"
@@ -362,7 +343,7 @@ int id_unlink(ID *id, int test)
if(id->us == 0) {
if(test) return 1;
- lb= wich_libbase(mainlib, GS(id->name));
+ lb= which_libbase(mainlib, GS(id->name));
free_libblock(lb, id);
return 1;
@@ -371,7 +352,7 @@ int id_unlink(ID *id, int test)
return 0;
}
-ListBase *wich_libbase(Main *mainlib, short type)
+ListBase *which_libbase(Main *mainlib, short type)
{
switch( type ) {
case ID_SCE:
@@ -464,7 +445,7 @@ void recalc_all_library_objects(Main *main)
/* flag for full recalc */
for(ob=main->object.first; ob; ob=ob->id.next)
if(ob->id.lib)
- ob->recalc |= OB_RECALC;
+ ob->recalc |= OB_RECALC_ALL;
}
/* note: MAX_LIBARRAY define should match this code */
@@ -613,10 +594,10 @@ static ID *alloc_libblock_notest(short type)
break;
case ID_PA:
id = MEM_callocN(sizeof(ParticleSettings), "ParticleSettings");
- break;
+ break;
case ID_WM:
id = MEM_callocN(sizeof(wmWindowManager), "Window manager");
- break;
+ break;
case ID_GD:
id = MEM_callocN(sizeof(bGPdata), "Grease Pencil");
break;
@@ -669,11 +650,11 @@ void *copy_libblock(void *rt)
ID *idn, *id;
ListBase *lb;
char *cp, *cpn;
- int idn_len;
+ size_t idn_len;
id= rt;
- lb= wich_libbase(G.main, GS(id->name));
+ lb= which_libbase(G.main, GS(id->name));
idn= alloc_libblock(lb, GS(id->name), id->name+2);
if(idn==NULL) {
@@ -697,7 +678,7 @@ void *copy_libblock(void *rt)
static void free_library(Library *lib)
{
- /* no freeing needed for libraries yet */
+ /* no freeing needed for libraries yet */
}
static void (*free_windowmanager_cb)(bContext *, wmWindowManager *)= NULL;
@@ -882,7 +863,7 @@ void free_main(Main *mainvar)
ID *find_id(char *type, char *name) /* type: "OB" or "MA" etc */
{
- ListBase *lb= wich_libbase(G.main, GS(type));
+ ListBase *lb= which_libbase(G.main, GS(type));
return BLI_findstring(lb, name, offsetof(ID, name) + 2);
}
@@ -1093,15 +1074,16 @@ static ID *is_dupid(ListBase *lb, ID *id, char *name)
* id is NULL;
*/
-int check_for_dupid(ListBase *lb, ID *id, char *name)
+static int check_for_dupid(ListBase *lb, ID *id, char *name)
{
ID *idtest;
int nr= 0, nrtest, a;
const int maxtest=32;
char left[32], leftest[32], in_use[32];
-
+
/* make sure input name is terminated properly */
- if( strlen(name) > 21 ) name[21]= 0;
+ /* if( strlen(name) > 21 ) name[21]= 0; */
+ /* removed since this is only ever called from one place - campbell */
while (1) {
@@ -1184,27 +1166,29 @@ int new_id(ListBase *lb, ID *id, const char *tname)
{
int result;
char name[22];
-
+
/* if library, don't rename */
if(id->lib) return 0;
/* if no libdata given, look up based on ID */
- if(lb==NULL) lb= wich_libbase(G.main, GS(id->name));
+ if(lb==NULL) lb= which_libbase(G.main, GS(id->name));
- if(tname==0) { /* if no name given, use name of current ID */
- strncpy(name, id->name+2, 21);
- result= strlen(id->name+2);
- }
- else { /* else make a copy (tname args can be const) */
- strncpy(name, tname, 21);
- result= strlen(tname);
- }
+ /* if no name given, use name of current ID
+ * else make a copy (tname args can be const) */
+ if(tname==NULL)
+ tname= id->name+2;
- /* if result > 21, strncpy don't put the final '\0' to name. */
- if( result >= 21 ) name[21]= 0;
+ strncpy(name, tname, sizeof(name)-1);
- result = check_for_dupid( lb, id, name );
- strcpy( id->name+2, name );
+ /* if result > 21, strncpy don't put the final '\0' to name.
+ * easier to assign each time then to check if its needed */
+ name[sizeof(name)-1]= 0;
+
+ if(name[0] == '\0')
+ strcpy(name, ID_FALLBACK_NAME);
+
+ result = check_for_dupid(lb, id, name);
+ strcpy(id->name+2, name);
/* This was in 2.43 and previous releases
* however all data in blender should be sorted, not just duplicate names
@@ -1241,18 +1225,24 @@ static void image_fix_relative_path(Image *ima)
{
if(ima->id.lib==NULL) return;
if(strncmp(ima->name, "//", 2)==0) {
- BLI_convertstringcode(ima->name, ima->id.lib->filename);
- BLI_makestringcode(G.sce, ima->name);
+ BLI_path_abs(ima->name, ima->id.lib->filepath);
+ BLI_path_rel(ima->name, G.sce);
}
}
#define LIBTAG(a) if(a && a->id.lib) {a->id.flag &=~LIB_INDIRECT; a->id.flag |= LIB_EXTERN;}
-static void lib_indirect_test_id(ID *id)
+static void lib_indirect_test_id(ID *id, Library *lib)
{
- if(id->lib)
+ if(id->lib) {
+ /* datablocks that were indirectly related are now direct links
+ * without this, appending data that has a link to other data will fail to write */
+ if(lib && id->lib->parent == lib) {
+ id_lib_extern(id);
+ }
return;
+ }
if(GS(id->name)==ID_OB) {
Object *ob= (Object *)id;
@@ -1348,7 +1338,7 @@ void all_local(Library *lib, int untagged_only)
a= set_listbasepointers(G.main, lbarray);
while(a--) {
for(id= lbarray[a]->first; id; id=id->next)
- lib_indirect_test_id(id);
+ lib_indirect_test_id(id, lib);
}
}
@@ -1360,7 +1350,7 @@ void test_idbutton(char *name)
ID *idtest;
- lb= wich_libbase(G.main, GS(name-2) );
+ lb= which_libbase(G.main, GS(name-2) );
if(lb==0) return;
/* search for id */
@@ -1374,17 +1364,17 @@ void text_idbutton(struct ID *id, char *text)
if(id) {
if(GS(id->name)==ID_SCE)
strcpy(text, "SCE: ");
- else if(GS(id->name)==ID_SCE)
+ else if(GS(id->name)==ID_SCE)
strcpy(text, "SCR: ");
- else if(GS(id->name)==ID_MA && ((Material*)id)->use_nodes)
+ else if(GS(id->name)==ID_MA && ((Material*)id)->use_nodes)
strcpy(text, "NT: ");
- else {
+ else {
text[0]= id->name[0];
text[1]= id->name[1];
text[2]= ':';
text[3]= ' ';
text[4]= 0;
- }
+ }
}
else
strcpy(text, "");
@@ -1393,9 +1383,9 @@ void text_idbutton(struct ID *id, char *text)
void rename_id(ID *id, char *name)
{
ListBase *lb;
-
+
strncpy(id->name+2, name, 21);
- lb= wich_libbase(G.main, GS(id->name) );
+ lb= which_libbase(G.main, GS(id->name) );
new_id(lb, id, name);
}
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 27b46c40d28..11c96e9a347 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -42,14 +42,10 @@
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "DNA_texture_types.h"
-#include "DNA_userdef_types.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BKE_animsys.h"
-#include "BKE_blender.h"
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_icons.h"
@@ -214,7 +210,7 @@ Material *copy_material(Material *ma)
#if 0 // XXX old animation system
id_us_plus((ID *)man->ipo);
#endif // XXX old animation system
- id_us_plus((ID *)man->group);
+ id_lib_extern((ID *)man->group);
for(a=0; a<MAX_MTEX; a++) {
if(ma->mtex[a]) {
@@ -248,9 +244,9 @@ void make_local_material(Material *ma)
int a, local=0, lib=0;
/* - only lib users: do nothing
- * - only local users: set flag
- * - mixed: make copy
- */
+ * - only local users: set flag
+ * - mixed: make copy
+ */
if(ma->id.lib==0) return;
if(ma->id.us==1) {
@@ -455,7 +451,7 @@ Material *give_current_material(Object *ob, int act)
if(act>ob->totcol) act= ob->totcol;
else if(act<=0) act= 1;
- if(ob->matbits[act-1]) { /* in object */
+ if(ob->matbits && ob->matbits[act-1]) { /* in object */
ma= ob->mat[act-1];
}
else { /* in data */
@@ -734,7 +730,7 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb)
/* since the raytracer doesnt recalc O structs for each ray, we have to preset them all */
if(r_mode & R_RAYTRACE) {
- if((ma->mode & (MA_RAYMIRROR|MA_SHADOW_TRA)) || ((ma->mode && MA_TRANSP) && (ma->mode & MA_RAYTRANSP))) {
+ if((ma->mode & (MA_RAYMIRROR|MA_SHADOW_TRA)) || ((ma->mode & MA_TRANSP) && (ma->mode & MA_RAYTRANSP))) {
ma->texco |= NEED_UV|TEXCO_ORCO|TEXCO_REFL|TEXCO_NORM;
if(r_mode & R_OSA) ma->texco |= TEXCO_OSA;
}
@@ -1068,15 +1064,15 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col)
}
break;
case MA_RAMP_DARK:
- tmp=col[0]+((1-col[0])*facm);
- if(tmp < *r) *r= tmp;
- if(g) {
- tmp=col[1]+((1-col[1])*facm);
- if(tmp < *g) *g= tmp;
- tmp=col[2]+((1-col[2])*facm);
- if(tmp < *b) *b= tmp;
- }
- break;
+ tmp=col[0]+((1-col[0])*facm);
+ if(tmp < *r) *r= tmp;
+ if(g) {
+ tmp=col[1]+((1-col[1])*facm);
+ if(tmp < *g) *g= tmp;
+ tmp=col[2]+((1-col[2])*facm);
+ if(tmp < *b) *b= tmp;
+ }
+ break;
case MA_RAMP_LIGHT:
tmp= fac*col[0];
if(tmp > *r) *r= tmp;
@@ -1128,7 +1124,7 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col)
if(tmp <= 0.0f)
*r = 0.0f;
else if (( tmp = (1.0f - (1.0f - (*r)) / tmp )) < 0.0f)
- *r = 0.0f;
+ *r = 0.0f;
else if (tmp > 1.0f)
*r=1.0f;
else
@@ -1139,17 +1135,17 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col)
if(tmp <= 0.0f)
*g = 0.0f;
else if (( tmp = (1.0f - (1.0f - (*g)) / tmp )) < 0.0f )
- *g = 0.0f;
+ *g = 0.0f;
else if(tmp >1.0f)
*g=1.0f;
else
*g = tmp;
- tmp = facm + fac*col[2];
- if(tmp <= 0.0f)
+ tmp = facm + fac*col[2];
+ if(tmp <= 0.0f)
*b = 0.0f;
else if (( tmp = (1.0f - (1.0f - (*b)) / tmp )) < 0.0f )
- *b = 0.0f;
+ *b = 0.0f;
else if(tmp >1.0f)
*b= 1.0f;
else
@@ -1206,36 +1202,36 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col)
}
}
break;
- case MA_RAMP_SOFT:
- if (g){
- float scr, scg, scb;
+ case MA_RAMP_SOFT:
+ if (g){
+ float scr, scg, scb;
- /* first calculate non-fac based Screen mix */
- scr = 1.0f - (1.0f - col[0]) * (1.0f - *r);
- scg = 1.0f - (1.0f - col[1]) * (1.0f - *g);
- scb = 1.0f - (1.0f - col[2]) * (1.0f - *b);
+ /* first calculate non-fac based Screen mix */
+ scr = 1.0f - (1.0f - col[0]) * (1.0f - *r);
+ scg = 1.0f - (1.0f - col[1]) * (1.0f - *g);
+ scb = 1.0f - (1.0f - col[2]) * (1.0f - *b);
- *r = facm*(*r) + fac*(((1.0f - *r) * col[0] * (*r)) + (*r * scr));
- *g = facm*(*g) + fac*(((1.0f - *g) * col[1] * (*g)) + (*g * scg));
- *b = facm*(*b) + fac*(((1.0f - *b) * col[2] * (*b)) + (*b * scb));
- }
- break;
- case MA_RAMP_LINEAR:
- if (col[0] > 0.5f)
- *r = *r + fac*(2.0f*(col[0]-0.5f));
- else
- *r = *r + fac*(2.0f*(col[0]) - 1.0f);
- if (g){
- if (col[1] > 0.5f)
- *g = *g + fac*(2.0f*(col[1]-0.5f));
- else
- *g = *g + fac*(2.0f*(col[1]) -1.0f);
- if (col[2] > 0.5f)
- *b = *b + fac*(2.0f*(col[2]-0.5f));
- else
- *b = *b + fac*(2.0f*(col[2]) - 1.0f);
- }
- break;
+ *r = facm*(*r) + fac*(((1.0f - *r) * col[0] * (*r)) + (*r * scr));
+ *g = facm*(*g) + fac*(((1.0f - *g) * col[1] * (*g)) + (*g * scg));
+ *b = facm*(*b) + fac*(((1.0f - *b) * col[2] * (*b)) + (*b * scb));
+ }
+ break;
+ case MA_RAMP_LINEAR:
+ if (col[0] > 0.5f)
+ *r = *r + fac*(2.0f*(col[0]-0.5f));
+ else
+ *r = *r + fac*(2.0f*(col[0]) - 1.0f);
+ if (g){
+ if (col[1] > 0.5f)
+ *g = *g + fac*(2.0f*(col[1]-0.5f));
+ else
+ *g = *g + fac*(2.0f*(col[1]) -1.0f);
+ if (col[2] > 0.5f)
+ *b = *b + fac*(2.0f*(col[2]-0.5f));
+ else
+ *b = *b + fac*(2.0f*(col[2]) - 1.0f);
+ }
+ break;
}
}
@@ -1247,6 +1243,7 @@ static short matcopied=0;
void clear_matcopybuf(void)
{
memset(&matcopybuf, 0, sizeof(Material));
+ matcopied= 0;
}
void free_matcopybuf(void)
@@ -1273,6 +1270,8 @@ void free_matcopybuf(void)
matcopybuf.nodetree= NULL;
}
// default_mtex(&mtexcopybuf);
+
+ matcopied= 0;
}
void copy_matcopybuf(Material *ma)
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 24eeb1ab43f..e35d8bce886 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -57,16 +57,11 @@
/* #include "BKE_object.h" */
#include "BKE_animsys.h"
#include "BKE_scene.h"
-#include "BKE_blender.h"
#include "BKE_library.h"
#include "BKE_displist.h"
#include "BKE_mball.h"
#include "BKE_object.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
/* Global variables */
static float thresh= 0.6f;
@@ -231,7 +226,7 @@ void tex_space_mball(Object *ob)
boundbox_set_from_min_max(bb, min, max);
}
-float *make_orco_mball(Object *ob)
+float *make_orco_mball(Object *ob, ListBase *dispbase)
{
BoundBox *bb;
DispList *dl;
@@ -248,7 +243,7 @@ float *make_orco_mball(Object *ob)
loc[2]= (bb->vec[0][2]+bb->vec[1][2])/2.0f;
size[2]= bb->vec[1][2]-loc[2];
- dl= ob->disp.first;
+ dl= dispbase->first;
orcodata= MEM_mallocN(sizeof(float)*3*dl->nr, "MballOrco");
data= dl->verts;
@@ -280,6 +275,19 @@ int is_basis_mball(Object *ob)
return 1;
}
+/* return nonzero if ob1 is a basis mball for ob */
+int is_mball_basis_for(Object *ob1, Object *ob2)
+{
+ int basis1nr, basis2nr;
+ char basis1name[32], basis2name[32];
+
+ splitIDname(ob1->id.name+2, basis1name, &basis1nr);
+ splitIDname(ob2->id.name+2, basis2name, &basis2nr);
+
+ if(!strcmp(basis1name, basis2name)) return is_basis_mball(ob1);
+ else return 0;
+}
+
/* \brief copy some properties from object to other metaball object with same base name
*
* When some properties (wiresize, threshold, update flags) of metaball are changed, then this properties
@@ -288,6 +296,7 @@ int is_basis_mball(Object *ob)
* because this metaball influence polygonisation of metaballs. */
void copy_mball_properties(Scene *scene, Object *active_object)
{
+ Scene *sce_iter= scene;
Base *base;
Object *ob;
MetaBall *active_mball = (MetaBall*)active_object->data;
@@ -297,10 +306,10 @@ void copy_mball_properties(Scene *scene, Object *active_object)
splitIDname(active_object->id.name+2, basisname, &basisnr);
/* XXX recursion check, see scene.c, just too simple code this next_object() */
- if(F_ERROR==next_object(scene, 0, 0, 0))
+ if(F_ERROR==next_object(&sce_iter, 0, 0, 0))
return;
- while(next_object(scene, 1, &base, &ob)) {
+ while(next_object(&sce_iter, 1, &base, &ob)) {
if (ob->type==OB_MBALL) {
if(ob!=active_object){
splitIDname(ob->id.name+2, obname, &obnr);
@@ -330,6 +339,7 @@ void copy_mball_properties(Scene *scene, Object *active_object)
*/
Object *find_basis_mball(Scene *scene, Object *basis)
{
+ Scene *sce_iter= scene;
Base *base;
Object *ob,*bob= basis;
MetaElem *ml=NULL;
@@ -340,10 +350,10 @@ Object *find_basis_mball(Scene *scene, Object *basis)
totelem= 0;
/* XXX recursion check, see scene.c, just too simple code this next_object() */
- if(F_ERROR==next_object(scene, 0, 0, 0))
+ if(F_ERROR==next_object(&sce_iter, 0, 0, 0))
return NULL;
- while(next_object(scene, 1, &base, &ob)) {
+ while(next_object(&sce_iter, 1, &base, &ob)) {
if (ob->type==OB_MBALL) {
if(ob==bob){
@@ -687,7 +697,7 @@ void *new_pgn_element(int size)
if(cur) {
if(size+offs < blocksize) {
adr= (void *) (cur->data+offs);
- offs+= size;
+ offs+= size;
return adr;
}
}
@@ -1092,7 +1102,7 @@ int getedge (EDGELIST *table[],
q = table[HASH(i1, j1, k1)+HASH(i2, j2, k2)];
for (; q != NULL; q = q->next)
if (q->i1 == i1 && q->j1 == j1 && q->k1 == k1 &&
- q->i2 == i2 && q->j2 == j2 && q->k2 == k2)
+ q->i2 == i2 && q->j2 == j2 && q->k2 == k2)
return q->vid;
return -1;
}
@@ -1241,7 +1251,7 @@ void converge (MB_POINT *p1, MB_POINT *p2, float v1, float v2,
p->z = neg.z;
return;
}
- if((dx == 0.0f) && (dz == 0.0f)){
+ if((dx == 0.0f) && (dz == 0.0f)){
p->x = neg.x;
p->y = neg.y - negative*dy/(positive-negative);
p->z = neg.z;
@@ -1273,7 +1283,7 @@ void converge (MB_POINT *p1, MB_POINT *p2, float v1, float v2,
p->y = 0.5f*(pos.y + neg.y);
if ((function(p->x,p->y,p->z)) > 0.0) pos.y = p->y; else neg.y = p->y;
}
- }
+ }
if((dx == 0.0f) && (dy == 0.0f)){
p->x = neg.x;
@@ -1499,6 +1509,7 @@ void polygonize(PROCESS *mbproc, MetaBall *mb)
float init_meta(Scene *scene, Object *ob) /* return totsize */
{
+ Scene *sce_iter= scene;
Base *base;
Object *bob;
MetaBall *mb;
@@ -1515,9 +1526,8 @@ float init_meta(Scene *scene, Object *ob) /* return totsize */
splitIDname(ob->id.name+2, obname, &obnr);
/* make main array */
-
- next_object(scene, 0, 0, 0);
- while(next_object(scene, 1, &base, &bob)) {
+ next_object(&sce_iter, 0, 0, 0);
+ while(next_object(&sce_iter, 1, &base, &bob)) {
if(bob->type==OB_MBALL) {
zero_size= 0;
@@ -1581,7 +1591,7 @@ float init_meta(Scene *scene, Object *ob) /* return totsize */
if(ml->s > 10.0) ml->s = 10.0;
/* Rotation of MetaElem is stored in quat */
- quat_to_mat4( temp3,ml->quat);
+ quat_to_mat4( temp3,ml->quat);
/* Translation of MetaElem */
unit_m4(temp2);
@@ -2080,21 +2090,20 @@ void init_metaball_octal_tree(int depth)
subdivide_metaball_octal_node(node, size[0], size[1], size[2], metaball_tree->depth);
}
-void metaball_polygonize(Scene *scene, Object *ob)
+void metaball_polygonize(Scene *scene, Object *ob, ListBase *dispbase)
{
PROCESS mbproc;
MetaBall *mb;
DispList *dl;
int a, nr_cubes;
float *ve, *no, totsize, width;
-
+
mb= ob->data;
if(totelem==0) return;
if(!(G.rendering) && (mb->flag==MB_UPDATE_NEVER)) return;
if(G.moving && mb->flag==MB_UPDATE_FAST) return;
- freedisplist(&ob->disp);
curindex= totindex= 0;
indices= 0;
thresh= mb->thresh;
@@ -2118,13 +2127,22 @@ void metaball_polygonize(Scene *scene, Object *ob)
if((totelem > 512) && (totelem <= 1024)) init_metaball_octal_tree(4);
if(totelem > 1024) init_metaball_octal_tree(5);
- /* don't polygonize metaballs with too high resolution (base mball to small) */
+ /* don't polygonize metaballs with too high resolution (base mball to small)
+ * note: Eps was 0.0001f but this was giving problems for blood animation for durian, using 0.00001f */
if(metaball_tree) {
- if(ob->size[0]<=0.0001f*(metaball_tree->first->x_max - metaball_tree->first->x_min) ||
- ob->size[1]<=0.0001f*(metaball_tree->first->y_max - metaball_tree->first->y_min) ||
- ob->size[2]<=0.0001f*(metaball_tree->first->z_max - metaball_tree->first->z_min))
+ if( ob->size[0] <= 0.00001f * (metaball_tree->first->x_max - metaball_tree->first->x_min) ||
+ ob->size[1] <= 0.00001f * (metaball_tree->first->y_max - metaball_tree->first->y_min) ||
+ ob->size[2] <= 0.00001f * (metaball_tree->first->z_max - metaball_tree->first->z_min))
{
+ new_pgn_element(-1); /* free values created by init_meta */
+
MEM_freeN(mainb);
+
+ /* free tree */
+ free_metaball_octal_node(metaball_tree->first);
+ MEM_freeN(metaball_tree);
+ metaball_tree= NULL;
+
return;
}
}
@@ -2157,9 +2175,8 @@ void metaball_polygonize(Scene *scene, Object *ob)
}
if(curindex) {
-
dl= MEM_callocN(sizeof(DispList), "mbaldisp");
- BLI_addtail(&ob->disp, dl);
+ BLI_addtail(dispbase, dl);
dl->type= DL_INDEX4;
dl->nr= mbproc.vertices.count;
dl->parts= curindex;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index c7b76941793..956fe10ee4b 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -29,10 +29,6 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
@@ -40,26 +36,18 @@
#include "MEM_guardedalloc.h"
-#include "DNA_ID.h"
-#include "DNA_anim_types.h"
-#include "DNA_curve_types.h"
#include "DNA_scene_types.h"
#include "DNA_material_types.h"
#include "DNA_object_types.h"
-#include "DNA_image_types.h"
#include "DNA_key_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_ipo_types.h"
#include "BKE_animsys.h"
-#include "BKE_customdata.h"
-#include "BKE_depsgraph.h"
#include "BKE_main.h"
#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
-#include "BKE_subsurf.h"
#include "BKE_displist.h"
#include "BKE_library.h"
#include "BKE_material.h"
@@ -187,7 +175,7 @@ void unlink_mesh(Mesh *me)
}
if(me->key) {
- me->key->id.us--;
+ me->key->id.us--;
if (me->key->id.us == 0 && me->key->ipo )
me->key->ipo->id.us--;
}
@@ -401,9 +389,9 @@ void make_local_mesh(Mesh *me)
int local=0, lib=0;
/* - only lib users: do nothing
- * - only local users: set flag
- * - mixed: make copy
- */
+ * - only local users: set flag
+ * - mixed: make copy
+ */
if(me->id.lib==0) return;
if(me->id.us==1) {
@@ -682,31 +670,49 @@ static int vergedgesort(const void *v1, const void *v2)
return 0;
}
-void make_edges(Mesh *me, int old)
+static void mfaces_strip_loose(MFace *mface, int *totface)
+{
+ int a,b;
+
+ for (a=b=0; a<*totface; a++) {
+ if (mface[a].v3) {
+ if (a!=b) {
+ memcpy(&mface[b],&mface[a],sizeof(mface[b]));
+ }
+ b++;
+ }
+ }
+
+ *totface= b;
+}
+
+/* Create edges based on known verts and faces */
+static void make_edges_mdata(MVert *allvert, MFace *allface, int totvert, int totface,
+ int old, MEdge **alledge, int *_totedge)
{
MFace *mface;
MEdge *medge;
struct edgesort *edsort, *ed;
int a, totedge=0, final=0;
-
+
/* we put all edges in array, sort them, and detect doubles that way */
-
- for(a= me->totface, mface= me->mface; a>0; a--, mface++) {
+
+ for(a= totface, mface= allface; a>0; a--, mface++) {
if(mface->v4) totedge+=4;
else if(mface->v3) totedge+=3;
else totedge+=1;
}
-
+
if(totedge==0) {
/* flag that mesh has edges */
- me->medge = MEM_callocN(0, "make mesh edges");
- me->totedge = 0;
+ (*alledge)= MEM_callocN(0, "make mesh edges");
+ (*_totedge) = 0;
return;
}
-
+
ed= edsort= MEM_mallocN(totedge*sizeof(struct edgesort), "edgesort");
-
- for(a= me->totface, mface= me->mface; a>0; a--, mface++) {
+
+ for(a= totface, mface= allface; a>0; a--, mface++) {
to_edgesort(ed++, mface->v1, mface->v2, !mface->v3, mface->edcode & ME_V1V2);
if(mface->v4) {
to_edgesort(ed++, mface->v2, mface->v3, 0, mface->edcode & ME_V2V3);
@@ -718,21 +724,19 @@ void make_edges(Mesh *me, int old)
to_edgesort(ed++, mface->v3, mface->v1, 0, mface->edcode & ME_V3V1);
}
}
-
+
qsort(edsort, totedge, sizeof(struct edgesort), vergedgesort);
-
+
/* count final amount */
for(a=totedge, ed=edsort; a>1; a--, ed++) {
/* edge is unique when it differs from next edge, or is last */
if(ed->v1 != (ed+1)->v1 || ed->v2 != (ed+1)->v2) final++;
}
final++;
-
- medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, final);
- me->medge= medge;
- me->totedge= final;
-
+ (*alledge)= medge= MEM_callocN(sizeof (MEdge) * final, "make_edges mdge");
+ (*_totedge)= final;
+
for(a=totedge, ed=edsort; a>1; a--, ed++) {
/* edge is unique when it differs from next edge, or is last */
if(ed->v1 != (ed+1)->v1 || ed->v2 != (ed+1)->v2) {
@@ -740,6 +744,12 @@ void make_edges(Mesh *me, int old)
medge->v2= ed->v2;
if(old==0 || ed->is_draw) medge->flag= ME_EDGEDRAW|ME_EDGERENDER;
if(ed->is_loose) medge->flag|= ME_LOOSEEDGE;
+
+ /* order is swapped so extruding this edge as a surface wont flip face normals
+ * with cyclic curves */
+ if(ed->v1+1 != ed->v2) {
+ SWAP(int, medge->v1, medge->v2);
+ }
medge++;
}
else {
@@ -755,6 +765,24 @@ void make_edges(Mesh *me, int old)
medge->flag |= ME_EDGERENDER;
MEM_freeN(edsort);
+}
+
+void make_edges(Mesh *me, int old)
+{
+ MEdge *medge;
+ int totedge=0;
+
+ make_edges_mdata(me->mvert, me->mface, me->totvert, me->totface, old, &medge, &totedge);
+ if(totedge==0) {
+ /* flag that mesh has edges */
+ me->medge = medge;
+ me->totedge = 0;
+ return;
+ }
+
+ medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, totedge);
+ me->medge= medge;
+ me->totedge= totedge;
mesh_strip_loose_faces(me);
}
@@ -776,7 +804,6 @@ void mesh_strip_loose_faces(Mesh *me)
me->totface = b;
}
-
void mball_to_mesh(ListBase *lb, Mesh *me)
{
DispList *dl;
@@ -830,12 +857,21 @@ void mball_to_mesh(ListBase *lb, Mesh *me)
}
}
-/* this may fail replacing ob->data, be sure to check ob->type */
-void nurbs_to_mesh(Object *ob)
+/* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */
+/* return non-zero on error */
+int nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert,
+ MEdge **alledge, int *totedge, MFace **allface, int *totface)
+{
+ return nurbs_to_mdata_customdb(ob, &((Curve *)ob->data)->disp,
+ allvert, totvert, alledge, totedge, allface, totface);
+}
+
+/* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */
+/* use specified dispbase */
+int nurbs_to_mdata_customdb(Object *ob, ListBase *dispbase, MVert **allvert, int *_totvert,
+ MEdge **alledge, int *_totedge, MFace **allface, int *_totface)
{
- Object *ob1;
DispList *dl;
- Mesh *me;
Curve *cu;
MVert *mvert;
MFace *mface;
@@ -846,18 +882,15 @@ void nurbs_to_mesh(Object *ob)
cu= ob->data;
/* count */
- dl= cu->disp.first;
+ dl= dispbase->first;
while(dl) {
if(dl->type==DL_SEGM) {
totvert+= dl->parts*dl->nr;
totvlak+= dl->parts*(dl->nr-1);
}
else if(dl->type==DL_POLY) {
- /* cyclic polys are filled. except when 3D */
- if(cu->flag & CU_3D) {
- totvert+= dl->parts*dl->nr;
- totvlak+= dl->parts*dl->nr;
- }
+ totvert+= dl->parts*dl->nr;
+ totvlak+= dl->parts*dl->nr;
}
else if(dl->type==DL_SURF) {
totvert+= dl->parts*dl->nr;
@@ -869,34 +902,23 @@ void nurbs_to_mesh(Object *ob)
}
dl= dl->next;
}
+
if(totvert==0) {
/* error("can't convert"); */
/* Make Sure you check ob->data is a curve */
- return;
+ return -1;
}
- /* make mesh */
- me= add_mesh("Mesh");
- me->totvert= totvert;
- me->totface= totvlak;
-
- me->totcol= cu->totcol;
- me->mat= cu->mat;
- cu->mat= 0;
- cu->totcol= 0;
-
- mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert);
- mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface);
- me->mvert= mvert;
- me->mface= mface;
+ *allvert= mvert= MEM_callocN(sizeof (MVert) * totvert, "nurbs_init mvert");
+ *allface= mface= MEM_callocN(sizeof (MVert) * totvert, "nurbs_init mface");
/* verts and faces */
vertcount= 0;
- dl= cu->disp.first;
+ dl= dispbase->first;
while(dl) {
int smooth= dl->rt & CU_SMOOTH ? 1 : 0;
-
+
if(dl->type==DL_SEGM) {
startvert= vertcount;
a= dl->parts*dl->nr;
@@ -920,27 +942,24 @@ void nurbs_to_mesh(Object *ob)
}
else if(dl->type==DL_POLY) {
- /* 3d polys are not filled */
- if(cu->flag & CU_3D) {
- startvert= vertcount;
- a= dl->parts*dl->nr;
- data= dl->verts;
- while(a--) {
- VECCOPY(mvert->co, data);
- data+=3;
- vertcount++;
- mvert++;
- }
-
- for(a=0; a<dl->parts; a++) {
- ofs= a*dl->nr;
- for(b=0; b<dl->nr; b++) {
- mface->v1= startvert+ofs+b;
- if(b==dl->nr-1) mface->v2= startvert+ofs;
- else mface->v2= startvert+ofs+b+1;
- if(smooth) mface->flag |= ME_SMOOTH;
- mface++;
- }
+ startvert= vertcount;
+ a= dl->parts*dl->nr;
+ data= dl->verts;
+ while(a--) {
+ VECCOPY(mvert->co, data);
+ data+=3;
+ vertcount++;
+ mvert++;
+ }
+
+ for(a=0; a<dl->parts; a++) {
+ ofs= a*dl->nr;
+ for(b=0; b<dl->nr; b++) {
+ mface->v1= startvert+ofs+b;
+ if(b==dl->nr-1) mface->v2= startvert+ofs;
+ else mface->v2= startvert+ofs+b+1;
+ if(smooth) mface->flag |= ME_SMOOTH;
+ mface++;
}
}
}
@@ -963,13 +982,13 @@ void nurbs_to_mesh(Object *ob)
mface->v3= startvert+index[1];
mface->v4= 0;
test_index_face(mface, NULL, 0, 3);
-
+
if(smooth) mface->flag |= ME_SMOOTH;
mface++;
index+= 3;
}
-
-
+
+
}
else if(dl->type==DL_SURF) {
startvert= vertcount;
@@ -1012,13 +1031,13 @@ void nurbs_to_mesh(Object *ob)
mface->v4= p2;
mface->mat_nr= (unsigned char)dl->col;
test_index_face(mface, NULL, 0, 4);
-
+
if(smooth) mface->flag |= ME_SMOOTH;
mface++;
- p4= p3;
+ p4= p3;
p3++;
- p2= p1;
+ p2= p1;
p1++;
}
}
@@ -1028,15 +1047,65 @@ void nurbs_to_mesh(Object *ob)
dl= dl->next;
}
- make_edges(me, 0); // all edges
- mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
+ *_totvert= totvert;
+ *_totface= totvlak;
+
+ make_edges_mdata(*allvert, *allface, totvert, totvlak, 0, alledge, _totedge);
+ mfaces_strip_loose(*allface, _totface);
+
+ return 0;
+}
+
+/* this may fail replacing ob->data, be sure to check ob->type */
+void nurbs_to_mesh(Object *ob)
+{
+ Object *ob1;
+ DerivedMesh *dm= ob->derivedFinal;
+ Mesh *me;
+ Curve *cu;
+ MVert *allvert= NULL;
+ MEdge *alledge= NULL;
+ MFace *allface= NULL;
+ int totvert, totedge, totface;
+
+ cu= ob->data;
+
+ if (dm == NULL) {
+ if (nurbs_to_mdata (ob, &allvert, &totvert, &alledge, &totedge, &allface, &totface) != 0) {
+ /* Error initializing */
+ return;
+ }
+
+ /* make mesh */
+ me= add_mesh("Mesh");
+ me->totvert= totvert;
+ me->totface= totface;
+ me->totedge= totedge;
+
+ me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, allvert, me->totvert);
+ me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, allface, me->totface);
+ me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, alledge, me->totedge);
+
+ mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
+ } else {
+ me= add_mesh("Mesh");
+ DM_to_mesh(dm, me);
+ }
+
+ me->totcol= cu->totcol;
+ me->mat= cu->mat;
+
+ tex_space_mesh(me);
+
+ cu->mat= 0;
+ cu->totcol= 0;
if(ob->data) {
free_libblock(&G.main->curve, ob->data);
}
ob->data= me;
ob->type= OB_MESH;
-
+
/* other users */
ob1= G.main->object.first;
while(ob1) {
@@ -1048,7 +1117,6 @@ void nurbs_to_mesh(Object *ob)
}
ob1= ob1->id.next;
}
-
}
typedef struct EdgeLink {
@@ -1087,7 +1155,7 @@ void mesh_to_curve(Scene *scene, Object *ob)
int totedge = dm->getNumEdges(dm);
int totface = dm->getNumTessFaces(dm);
int totedges = 0;
- int i;
+ int i, needsFree = 0;
/* only to detect edge polylines */
EdgeHash *eh = BLI_edgehash_new();
@@ -1204,7 +1272,7 @@ void mesh_to_curve(Scene *scene, Object *ob)
nu->pntsu= totpoly;
nu->pntsv= 1;
nu->orderu= 4;
- nu->flagu= 2 | (closed ? CU_CYCLIC:0); /* endpoint */
+ nu->flagu= CU_NURB_ENDPOINT | (closed ? CU_NURB_CYCLIC:0); /* endpoint */
nu->resolu= 12;
nu->bp= (BPoint *)MEM_callocN(sizeof(BPoint)*totpoly, "bpoints");
@@ -1227,9 +1295,23 @@ void mesh_to_curve(Scene *scene, Object *ob)
((Mesh *)ob->data)->id.us--;
ob->data= cu;
ob->type= OB_CURVE;
+
+ /* curve objects can't contain DM in usual cases, we could free memory */
+ needsFree= 1;
}
+ dm->needsFree = needsFree;
dm->release(dm);
+
+ if (needsFree) {
+ ob->derivedFinal = NULL;
+
+ /* curve object could have got bounding box only in special cases */
+ if(ob->bb) {
+ MEM_freeN(ob->bb);
+ ob->bb= NULL;
+ }
+ }
}
void mesh_delete_material_index(Mesh *me, int index)
@@ -1276,11 +1358,11 @@ void mesh_calc_normals(MVert *mverts, int numVerts, MFace *mfaces, int numFaces,
else
normal_tri_v3( f_no,mverts[mf->v1].co, mverts[mf->v2].co, mverts[mf->v3].co);
- add_v3_v3v3(tnorms[mf->v1], tnorms[mf->v1], f_no);
- add_v3_v3v3(tnorms[mf->v2], tnorms[mf->v2], f_no);
- add_v3_v3v3(tnorms[mf->v3], tnorms[mf->v3], f_no);
+ add_v3_v3(tnorms[mf->v1], f_no);
+ add_v3_v3(tnorms[mf->v2], f_no);
+ add_v3_v3(tnorms[mf->v3], f_no);
if (mf->v4)
- add_v3_v3v3(tnorms[mf->v4], tnorms[mf->v4], f_no);
+ add_v3_v3(tnorms[mf->v4], f_no);
}
for (i=0; i<numVerts; i++) {
MVert *mv= &mverts[i];
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 20e8542fb56..858e9d6c6d9 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -24,8 +24,7 @@
* Ton Roosendaal,
* Ben Batt,
* Brecht Van Lommel,
-* Campbell Barton,
-* Joseph Eagar
+* Campbell Barton
*
* ***** END GPL LICENSE BLOCK *****
*
@@ -41,8133 +40,29 @@
#include "math.h"
#include "float.h"
-#include "BLI_math.h"
-#include "BLI_blenlib.h"
-#include "BLI_kdopbvh.h"
-#include "BLI_kdtree.h"
-#include "BLI_linklist.h"
-#include "BLI_rand.h"
-#include "BLI_edgehash.h"
-#include "BLI_ghash.h"
-#include "BLI_memarena.h"
-#include "BLI_cellalloc.h"
-#include "BLI_mempool.h"
-#include "BLI_array.h"
-
-#include "MEM_guardedalloc.h"
-
-#include "DNA_action_types.h"
#include "DNA_armature_types.h"
-#include "DNA_camera_types.h"
-#include "DNA_cloth_types.h"
-#include "DNA_curve_types.h"
-#include "DNA_effect_types.h"
-#include "DNA_group_types.h"
-#include "DNA_key_types.h"
-#include "DNA_material_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_object_types.h"
-#include "DNA_object_fluidsim.h"
-#include "DNA_object_force.h"
-#include "DNA_particle_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_smoke_types.h"
-#include "DNA_texture_types.h"
-
-#include "BLI_editVert.h"
-
-
-
-#include "BKE_main.h"
-#include "BKE_anim.h"
-#include "BKE_action.h"
#include "BKE_bmesh.h"
-#include "BKE_booleanops.h"
#include "BKE_cloth.h"
-#include "BKE_collision.h"
-#include "BKE_cdderivedmesh.h"
-#include "BKE_curve.h"
-#include "BKE_customdata.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_displist.h"
-#include "BKE_fluidsim.h"
-#include "BKE_global.h"
-#include "BKE_multires.h"
#include "BKE_key.h"
-#include "BKE_lattice.h"
-#include "BKE_library.h"
-#include "BKE_material.h"
-#include "BKE_mesh.h"
-#include "BKE_modifier.h"
-#include "BKE_object.h"
-#include "BKE_particle.h"
-#include "BKE_pointcache.h"
-#include "BKE_scene.h"
-#include "BKE_smoke.h"
-#include "BKE_softbody.h"
-#include "BKE_subsurf.h"
-#include "BKE_texture.h"
-#include "BKE_utildefines.h"
-#include "BKE_tessmesh.h"
-
-#include "depsgraph_private.h"
-#include "BKE_deform.h"
-#include "BKE_shrinkwrap.h"
-#include "BKE_simple_deform.h"
-
-#include "LOD_decimation.h"
-
-#include "CCGSubSurf.h"
-
-#include "RE_shader_ext.h"
-
-/* Utility */
-
-static int is_last_displist(Object *ob)
-{
- Curve *cu = ob->data;
- static int curvecount=0, totcurve=0;
-
- if(curvecount == 0){
- DispList *dl;
-
- totcurve = 0;
- for(dl=cu->disp.first; dl; dl=dl->next)
- totcurve++;
- }
-
- curvecount++;
-
- if(curvecount == totcurve){
- curvecount = 0;
- return 1;
- }
-
- return 0;
-}
-
-/* returns a derived mesh if dm == NULL, for deforming modifiers that need it */
-static DerivedMesh *get_dm(Scene *scene, Object *ob, BMEditMesh *em, DerivedMesh *dm, float (*vertexCos)[3], int orco)
-{
- if(dm)
- return dm;
-
- if(ob->type==OB_MESH) {
- if(em) dm= CDDM_from_BMEditMesh(em, ob->data);
- else dm = CDDM_from_mesh((Mesh*)(ob->data), ob);
-
- if(vertexCos) {
- CDDM_apply_vert_coords(dm, vertexCos);
- //CDDM_calc_normals(dm);
- }
-
- if(orco)
- DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob));
- }
- else if(ELEM3(ob->type,OB_FONT,OB_CURVE,OB_SURF)) {
- Object *tmpobj;
- Curve *tmpcu;
-
- if(is_last_displist(ob)) {
- /* copies object and modifiers (but not the data) */
- tmpobj= copy_object(ob);
- tmpcu = (Curve *)tmpobj->data;
- tmpcu->id.us--;
-
- /* copies the data */
- tmpobj->data = copy_curve((Curve *) ob->data);
-
- makeDispListCurveTypes(scene, tmpobj, 1);
- nurbs_to_mesh(tmpobj);
-
- dm = CDDM_from_mesh((Mesh*)(tmpobj->data), tmpobj);
- //CDDM_calc_normals(dm);
-
- free_libblock_us(&G.main->object, tmpobj);
- }
- }
-
- return dm;
-}
-
-/* returns a cdderivedmesh if dm == NULL or is another type of derivedmesh */
-static DerivedMesh *get_cddm(Scene *scene, Object *ob, BMEditMesh *em, DerivedMesh *dm, float (*vertexCos)[3])
-{
- if(dm && dm->type == DM_TYPE_CDDM)
- return dm;
-
- if(!dm) {
- dm= get_dm(scene, ob, em, dm, vertexCos, 0);
- }
- else {
- dm= CDDM_copy(dm, 0);
- CDDM_apply_vert_coords(dm, vertexCos);
- }
-
- if(dm)
- CDDM_calc_normals(dm);
-
- return dm;
-}
-
-/***/
-
-static int noneModifier_isDisabled(ModifierData *md, int userRenderParams)
-{
- return 1;
-}
-
-/* Curve */
-
-static void curveModifier_initData(ModifierData *md)
-{
- CurveModifierData *cmd = (CurveModifierData*) md;
-
- cmd->defaxis = MOD_CURVE_POSX;
-}
-
-static void curveModifier_copyData(ModifierData *md, ModifierData *target)
-{
- CurveModifierData *cmd = (CurveModifierData*) md;
- CurveModifierData *tcmd = (CurveModifierData*) target;
-
- tcmd->defaxis = cmd->defaxis;
- tcmd->object = cmd->object;
- strncpy(tcmd->name, cmd->name, 32);
-}
-
-static CustomDataMask curveModifier_requiredDataMask(Object *ob, ModifierData *md)
-{
- CurveModifierData *cmd = (CurveModifierData *)md;
- CustomDataMask dataMask = 0;
-
- /* ask for vertexgroups if we need them */
- if(cmd->name[0]) dataMask |= (1 << CD_MDEFORMVERT);
-
- return dataMask;
-}
-
-static int curveModifier_isDisabled(ModifierData *md, int userRenderParams)
-{
- CurveModifierData *cmd = (CurveModifierData*) md;
-
- return !cmd->object;
-}
-
-static void curveModifier_foreachObjectLink(
- ModifierData *md, Object *ob,
- void (*walk)(void *userData, Object *ob, Object **obpoin),
- void *userData)
-{
- CurveModifierData *cmd = (CurveModifierData*) md;
-
- walk(userData, ob, &cmd->object);
-}
-
-static void curveModifier_updateDepgraph(
- ModifierData *md, DagForest *forest, Scene *scene,
- Object *ob, DagNode *obNode)
-{
- CurveModifierData *cmd = (CurveModifierData*) md;
-
- if (cmd->object) {
- DagNode *curNode = dag_get_node(forest, cmd->object);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Curve Modifier");
- }
-}
-
-static void curveModifier_deformVerts(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
-{
- CurveModifierData *cmd = (CurveModifierData*) md;
-
- curve_deform_verts(md->scene, cmd->object, ob, derivedData, vertexCos, numVerts,
- cmd->name, cmd->defaxis);
-}
-
-static void curveModifier_deformVertsEM(
- ModifierData *md, Object *ob, BMEditMesh *editData,
- DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
-{
- DerivedMesh *dm = derivedData;
-
- if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data);
-
- curveModifier_deformVerts(md, ob, dm, vertexCos, numVerts, 0, 0);
-
- if(!derivedData) dm->release(dm);
-}
-
-/* Lattice */
-
-static void latticeModifier_copyData(ModifierData *md, ModifierData *target)
-{
- LatticeModifierData *lmd = (LatticeModifierData*) md;
- LatticeModifierData *tlmd = (LatticeModifierData*) target;
-
- tlmd->object = lmd->object;
- strncpy(tlmd->name, lmd->name, 32);
-}
-
-static CustomDataMask latticeModifier_requiredDataMask(Object *ob, ModifierData *md)
-{
- LatticeModifierData *lmd = (LatticeModifierData *)md;
- CustomDataMask dataMask = 0;
-
- /* ask for vertexgroups if we need them */
- if(lmd->name[0]) dataMask |= (1 << CD_MDEFORMVERT);
-
- return dataMask;
-}
-
-static int latticeModifier_isDisabled(ModifierData *md, int userRenderParams)
-{
- LatticeModifierData *lmd = (LatticeModifierData*) md;
-
- return !lmd->object;
-}
-
-static void latticeModifier_foreachObjectLink(
- ModifierData *md, Object *ob,
- void (*walk)(void *userData, Object *ob, Object **obpoin),
- void *userData)
-{
- LatticeModifierData *lmd = (LatticeModifierData*) md;
-
- walk(userData, ob, &lmd->object);
-}
-
-static void latticeModifier_updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene,
- Object *ob, DagNode *obNode)
-{
- LatticeModifierData *lmd = (LatticeModifierData*) md;
-
- if(lmd->object) {
- DagNode *latNode = dag_get_node(forest, lmd->object);
-
- dag_add_relation(forest, latNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Lattice Modifier");
- }
-}
-
-static void modifier_vgroup_cache(ModifierData *md, float (*vertexCos)[3])
-{
- while((md=md->next) && md->type==eModifierType_Armature) {
- ArmatureModifierData *amd = (ArmatureModifierData*) md;
- if(amd->multi && amd->prevCos==NULL)
- amd->prevCos= MEM_dupallocN(vertexCos);
- else
- break;
- }
- /* lattice/mesh modifier too */
-}
-
-
-static void latticeModifier_deformVerts(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
-{
- LatticeModifierData *lmd = (LatticeModifierData*) md;
-
-
- modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
-
- lattice_deform_verts(lmd->object, ob, derivedData,
- vertexCos, numVerts, lmd->name);
-}
-
-static void latticeModifier_deformVertsEM(
- ModifierData *md, Object *ob, BMEditMesh *editData,
- DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
-{
- DerivedMesh *dm = derivedData;
-
- if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data);
-
- latticeModifier_deformVerts(md, ob, dm, vertexCos, numVerts, 0, 0);
-
- if(!derivedData) dm->release(dm);
-}
-
-/* Subsurf */
-
-static void subsurfModifier_initData(ModifierData *md)
-{
- SubsurfModifierData *smd = (SubsurfModifierData*) md;
-
- smd->levels = 1;
- smd->renderLevels = 2;
- smd->flags |= eSubsurfModifierFlag_SubsurfUv;
-}
-
-static void subsurfModifier_copyData(ModifierData *md, ModifierData *target)
-{
- SubsurfModifierData *smd = (SubsurfModifierData*) md;
- SubsurfModifierData *tsmd = (SubsurfModifierData*) target;
-
- tsmd->flags = smd->flags;
- tsmd->levels = smd->levels;
- tsmd->renderLevels = smd->renderLevels;
- tsmd->subdivType = smd->subdivType;
-}
-
-static void subsurfModifier_freeData(ModifierData *md)
-{
- SubsurfModifierData *smd = (SubsurfModifierData*) md;
-
- if(smd->mCache) {
- ccgSubSurf_free(smd->mCache);
- }
- if(smd->emCache) {
- ccgSubSurf_free(smd->emCache);
- }
-}
-
-static int subsurfModifier_isDisabled(ModifierData *md, int useRenderParams)
-{
- SubsurfModifierData *smd = (SubsurfModifierData*) md;
- int levels= (useRenderParams)? smd->renderLevels: smd->levels;
-
- return get_render_subsurf_level(&md->scene->r, levels) == 0;
-}
-
-static DerivedMesh *subsurfModifier_applyModifier(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- int useRenderParams, int isFinalCalc)
-{
- SubsurfModifierData *smd = (SubsurfModifierData*) md;
- DerivedMesh *result;
-
- result = subsurf_make_derived_from_derived(derivedData, smd,
- useRenderParams, NULL, isFinalCalc, 0);
-
- if(useRenderParams || !isFinalCalc) {
- DerivedMesh *cddm= CDDM_copy(result, 1);
- result->release(result);
- result= cddm;
- }
-
- return result;
-}
-
-static DerivedMesh *subsurfModifier_applyModifierEM(
- ModifierData *md, Object *ob, BMEditMesh *editData,
- DerivedMesh *derivedData)
-{
- SubsurfModifierData *smd = (SubsurfModifierData*) md;
- DerivedMesh *result;
-
- result = subsurf_make_derived_from_derived(derivedData, smd, 0,
- NULL, 0, 1);
-
- return result;
-}
-
-/* Build */
-
-static void buildModifier_initData(ModifierData *md)
-{
- BuildModifierData *bmd = (BuildModifierData*) md;
-
- bmd->start = 1.0;
- bmd->length = 100.0;
-}
-
-static void buildModifier_copyData(ModifierData *md, ModifierData *target)
-{
- BuildModifierData *bmd = (BuildModifierData*) md;
- BuildModifierData *tbmd = (BuildModifierData*) target;
-
- tbmd->start = bmd->start;
- tbmd->length = bmd->length;
- tbmd->randomize = bmd->randomize;
- tbmd->seed = bmd->seed;
-}
-
-static int buildModifier_dependsOnTime(ModifierData *md)
-{
- return 1;
-}
-
-static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
- DerivedMesh *derivedData,
- int useRenderParams, int isFinalCalc)
-{
- DerivedMesh *dm = derivedData;
- DerivedMesh *result;
- BuildModifierData *bmd = (BuildModifierData*) md;
- int i;
- int numFaces, numEdges;
- int maxVerts, maxEdges, maxFaces;
- int *vertMap, *edgeMap, *faceMap;
- float frac;
- GHashIterator *hashIter;
- /* maps vert indices in old mesh to indices in new mesh */
- GHash *vertHash = BLI_ghash_new(BLI_ghashutil_inthash,
- BLI_ghashutil_intcmp);
- /* maps edge indices in new mesh to indices in old mesh */
- GHash *edgeHash = BLI_ghash_new(BLI_ghashutil_inthash,
- BLI_ghashutil_intcmp);
-
- maxVerts = dm->getNumVerts(dm);
- vertMap = MEM_callocN(sizeof(*vertMap) * maxVerts,
- "build modifier vertMap");
- for(i = 0; i < maxVerts; ++i) vertMap[i] = i;
-
- maxEdges = dm->getNumEdges(dm);
- edgeMap = MEM_callocN(sizeof(*edgeMap) * maxEdges,
- "build modifier edgeMap");
- for(i = 0; i < maxEdges; ++i) edgeMap[i] = i;
-
- maxFaces = dm->getNumTessFaces(dm);
- faceMap = MEM_callocN(sizeof(*faceMap) * maxFaces,
- "build modifier faceMap");
- for(i = 0; i < maxFaces; ++i) faceMap[i] = i;
-
- if (ob) {
- frac = bsystem_time(md->scene, ob, md->scene->r.cfra,
- bmd->start - 1.0f) / bmd->length;
- } else {
- frac = md->scene->r.cfra - bmd->start / bmd->length;
- }
- CLAMP(frac, 0.0, 1.0);
-
- numFaces = dm->getNumTessFaces(dm) * frac;
- numEdges = dm->getNumEdges(dm) * frac;
-
- /* if there's at least one face, build based on faces */
- if(numFaces) {
- int maxEdges;
-
- if(bmd->randomize)
- BLI_array_randomize(faceMap, sizeof(*faceMap),
- maxFaces, bmd->seed);
-
- /* get the set of all vert indices that will be in the final mesh,
- * mapped to the new indices
- */
- for(i = 0; i < numFaces; ++i) {
- MFace mf;
- dm->getTessFace(dm, faceMap[i], &mf);
-
- if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1)))
- BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v1),
- SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
- if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v2)))
- BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v2),
- SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
- if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v3)))
- BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v3),
- SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
- if(mf.v4 && !BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v4)))
- BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v4),
- SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
- }
-
- /* get the set of edges that will be in the new mesh (i.e. all edges
- * that have both verts in the new mesh)
- */
- maxEdges = dm->getNumEdges(dm);
- for(i = 0; i < maxEdges; ++i) {
- MEdge me;
- dm->getEdge(dm, i, &me);
-
- if(BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1))
- && BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2)))
- BLI_ghash_insert(edgeHash,
- SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), SET_INT_IN_POINTER(i));
- }
- } else if(numEdges) {
- if(bmd->randomize)
- BLI_array_randomize(edgeMap, sizeof(*edgeMap),
- maxEdges, bmd->seed);
-
- /* get the set of all vert indices that will be in the final mesh,
- * mapped to the new indices
- */
- for(i = 0; i < numEdges; ++i) {
- MEdge me;
- dm->getEdge(dm, edgeMap[i], &me);
-
- if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)))
- BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v1),
- SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
- if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2)))
- BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v2),
- SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
- }
-
- /* get the set of edges that will be in the new mesh
- */
- for(i = 0; i < numEdges; ++i) {
- MEdge me;
- dm->getEdge(dm, edgeMap[i], &me);
-
- BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)),
- SET_INT_IN_POINTER(edgeMap[i]));
- }
- } else {
- int numVerts = dm->getNumVerts(dm) * frac;
-
- if(bmd->randomize)
- BLI_array_randomize(vertMap, sizeof(*vertMap),
- maxVerts, bmd->seed);
-
- /* get the set of all vert indices that will be in the final mesh,
- * mapped to the new indices
- */
- for(i = 0; i < numVerts; ++i)
- BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(vertMap[i]), SET_INT_IN_POINTER(i));
- }
-
- /* now we know the number of verts, edges and faces, we can create
- * the mesh
- */
- result = CDDM_from_template(dm, BLI_ghash_size(vertHash),
- BLI_ghash_size(edgeHash), numFaces, 0, 0);
-
- /* copy the vertices across */
- for(hashIter = BLI_ghashIterator_new(vertHash);
- !BLI_ghashIterator_isDone(hashIter);
- BLI_ghashIterator_step(hashIter)) {
- MVert source;
- MVert *dest;
- int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
- int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
-
- dm->getVert(dm, oldIndex, &source);
- dest = CDDM_get_vert(result, newIndex);
-
- DM_copy_vert_data(dm, result, oldIndex, newIndex, 1);
- *dest = source;
- }
- BLI_ghashIterator_free(hashIter);
-
- /* copy the edges across, remapping indices */
- for(i = 0; i < BLI_ghash_size(edgeHash); ++i) {
- MEdge source;
- MEdge *dest;
- int oldIndex = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(i)));
-
- dm->getEdge(dm, oldIndex, &source);
- dest = CDDM_get_edge(result, i);
-
- source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
- source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
-
- DM_copy_edge_data(dm, result, oldIndex, i, 1);
- *dest = source;
- }
-
- /* copy the faces across, remapping indices */
- for(i = 0; i < numFaces; ++i) {
- MFace source;
- MFace *dest;
- int orig_v4;
-
- dm->getTessFace(dm, faceMap[i], &source);
- dest = CDDM_get_tessface(result, i);
-
- orig_v4 = source.v4;
-
- source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
- source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
- source.v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v3)));
- if(source.v4)
- source.v4 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v4)));
-
- DM_copy_tessface_data(dm, result, faceMap[i], i, 1);
- *dest = source;
-
- test_index_face(dest, &result->faceData, i, (orig_v4 ? 4 : 3));
- }
-
- CDDM_calc_normals(result);
- CDDM_tessfaces_to_faces(result);
-
- BLI_ghash_free(vertHash, NULL, NULL);
- BLI_ghash_free(edgeHash, NULL, NULL);
-
- MEM_freeN(vertMap);
- MEM_freeN(edgeMap);
- MEM_freeN(faceMap);
-
- return result;
-}
-
-/* Mask */
-
-static void maskModifier_copyData(ModifierData *md, ModifierData *target)
-{
- MaskModifierData *mmd = (MaskModifierData*) md;
- MaskModifierData *tmmd = (MaskModifierData*) target;
-
- strcpy(tmmd->vgroup, mmd->vgroup);
-}
-
-static CustomDataMask maskModifier_requiredDataMask(Object *ob, ModifierData *md)
-{
- return (1 << CD_MDEFORMVERT);
-}
-
-static void maskModifier_foreachObjectLink(
- ModifierData *md, Object *ob,
- void (*walk)(void *userData, Object *ob, Object **obpoin),
- void *userData)
-{
- MaskModifierData *mmd = (MaskModifierData *)md;
- walk(userData, ob, &mmd->ob_arm);
-}
-
-static void maskModifier_updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene,
- Object *ob, DagNode *obNode)
-{
- MaskModifierData *mmd = (MaskModifierData *)md;
-
- if (mmd->ob_arm)
- {
- DagNode *armNode = dag_get_node(forest, mmd->ob_arm);
-
- dag_add_relation(forest, armNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Mask Modifier");
- }
-}
-
-static DerivedMesh *maskModifier_applyModifier(ModifierData *md, Object *ob,
- DerivedMesh *derivedData,
- int useRenderParams, int isFinalCalc)
-{
- MaskModifierData *mmd= (MaskModifierData *)md;
- DerivedMesh *dm= derivedData, *result= NULL;
- GHash *vertHash=NULL, *edgeHash, *faceHash;
- GHashIterator *hashIter;
- MDeformVert *dvert= NULL;
- int numFaces=0, numEdges=0, numVerts=0;
- int maxVerts, maxEdges, maxFaces;
- int i;
-
- /* Overview of Method:
- * 1. Get the vertices that are in the vertexgroup of interest
- * 2. Filter out unwanted geometry (i.e. not in vertexgroup), by populating mappings with new vs old indices
- * 3. Make a new mesh containing only the mapping data
- */
-
- /* get original number of verts, edges, and faces */
- maxVerts= dm->getNumVerts(dm);
- maxEdges= dm->getNumEdges(dm);
- maxFaces= dm->getNumTessFaces(dm);
-
- /* check if we can just return the original mesh
- * - must have verts and therefore verts assigned to vgroups to do anything useful
- */
- if ( !(ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP)) ||
- (maxVerts == 0) || (ob->defbase.first == NULL) )
- {
- return derivedData;
- }
-
- /* if mode is to use selected armature bones, aggregate the bone groups */
- if (mmd->mode == MOD_MASK_MODE_ARM) /* --- using selected bones --- */
- {
- GHash *vgroupHash, *boneHash;
- Object *oba= mmd->ob_arm;
- bPoseChannel *pchan;
- bDeformGroup *def;
-
- /* check that there is armature object with bones to use, otherwise return original mesh */
- if (ELEM(NULL, mmd->ob_arm, mmd->ob_arm->pose))
- return derivedData;
-
- /* hashes for finding mapping of:
- * - vgroups to indicies -> vgroupHash (string, int)
- * - bones to vgroup indices -> boneHash (index of vgroup, dummy)
- */
- vgroupHash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp);
- boneHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp);
-
- /* build mapping of names of vertex groups to indices */
- for (i = 0, def = ob->defbase.first; def; def = def->next, i++)
- BLI_ghash_insert(vgroupHash, def->name, SET_INT_IN_POINTER(i));
-
- /* get selected-posechannel <-> vertexgroup index mapping */
- for (pchan= oba->pose->chanbase.first; pchan; pchan= pchan->next)
- {
- /* check if bone is selected */
- // TODO: include checks for visibility too?
- // FIXME: the depsgraph needs extensions to make this work in realtime...
- if ( (pchan->bone) && (pchan->bone->flag & BONE_SELECTED) )
- {
- /* check if hash has group for this bone */
- if (BLI_ghash_haskey(vgroupHash, pchan->name))
- {
- int defgrp_index= GET_INT_FROM_POINTER(BLI_ghash_lookup(vgroupHash, pchan->name));
-
- /* add index to hash (store under key only) */
- BLI_ghash_insert(boneHash, SET_INT_IN_POINTER(defgrp_index), pchan);
- }
- }
- }
-
- /* if no bones selected, free hashes and return original mesh */
- if (BLI_ghash_size(boneHash) == 0)
- {
- BLI_ghash_free(vgroupHash, NULL, NULL);
- BLI_ghash_free(boneHash, NULL, NULL);
-
- return derivedData;
- }
-
- /* repeat the previous check, but for dverts */
- dvert= dm->getVertDataArray(dm, CD_MDEFORMVERT);
- if (dvert == NULL)
- {
- BLI_ghash_free(vgroupHash, NULL, NULL);
- BLI_ghash_free(boneHash, NULL, NULL);
-
- return derivedData;
- }
-
- /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
- vertHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp);
-
- /* add vertices which exist in vertexgroups into vertHash for filtering */
- for (i = 0; i < maxVerts; i++)
- {
- MDeformWeight *def_weight = NULL;
- int j;
-
- for (j= 0; j < dvert[i].totweight; j++)
- {
- if (BLI_ghash_haskey(boneHash, SET_INT_IN_POINTER(dvert[i].dw[j].def_nr)))
- {
- def_weight = &dvert[i].dw[j];
- break;
- }
- }
-
- /* check if include vert in vertHash */
- if (mmd->flag & MOD_MASK_INV) {
- /* if this vert is in the vgroup, don't include it in vertHash */
- if (def_weight) continue;
- }
- else {
- /* if this vert isn't in the vgroup, don't include it in vertHash */
- if (!def_weight) continue;
- }
-
- /* add to ghash for verts (numVerts acts as counter for mapping) */
- BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numVerts));
- numVerts++;
- }
-
- /* free temp hashes */
- BLI_ghash_free(vgroupHash, NULL, NULL);
- BLI_ghash_free(boneHash, NULL, NULL);
- }
- else /* --- Using Nominated VertexGroup only --- */
- {
- int defgrp_index = defgroup_name_index(ob, mmd->vgroup);
-
- /* get dverts */
- if (defgrp_index >= 0)
- dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
-
- /* if no vgroup (i.e. dverts) found, return the initial mesh */
- if ((defgrp_index < 0) || (dvert == NULL))
- return dm;
-
- /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
- vertHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp);
-
- /* add vertices which exist in vertexgroup into ghash for filtering */
- for (i = 0; i < maxVerts; i++)
- {
- MDeformWeight *def_weight = NULL;
- int j;
-
- for (j= 0; j < dvert[i].totweight; j++)
- {
- if (dvert[i].dw[j].def_nr == defgrp_index)
- {
- def_weight = &dvert[i].dw[j];
- break;
- }
- }
-
- /* check if include vert in vertHash */
- if (mmd->flag & MOD_MASK_INV) {
- /* if this vert is in the vgroup, don't include it in vertHash */
- if (def_weight) continue;
- }
- else {
- /* if this vert isn't in the vgroup, don't include it in vertHash */
- if (!def_weight) continue;
- }
-
- /* add to ghash for verts (numVerts acts as counter for mapping) */
- BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numVerts));
- numVerts++;
- }
- }
-
- /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
- edgeHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp);
- faceHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp);
-
- /* loop over edges and faces, and do the same thing to
- * ensure that they only reference existing verts
- */
- for (i = 0; i < maxEdges; i++)
- {
- MEdge me;
- dm->getEdge(dm, i, &me);
-
- /* only add if both verts will be in new mesh */
- if ( BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)) &&
- BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2)) )
- {
- BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numEdges));
- numEdges++;
- }
- }
- for (i = 0; i < maxFaces; i++)
- {
- MFace mf;
- dm->getTessFace(dm, i, &mf);
-
- /* all verts must be available */
- if ( BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1)) &&
- BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v2)) &&
- BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v3)) &&
- (mf.v4==0 || BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v4))) )
- {
- BLI_ghash_insert(faceHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numFaces));
- numFaces++;
- }
- }
-
-
- /* now we know the number of verts, edges and faces,
- * we can create the new (reduced) mesh
- */
- result = CDDM_from_template(dm, numVerts, numEdges, numFaces, 0, 0);
-
-
- /* using ghash-iterators, map data into new mesh */
- /* vertices */
- for ( hashIter = BLI_ghashIterator_new(vertHash);
- !BLI_ghashIterator_isDone(hashIter);
- BLI_ghashIterator_step(hashIter) )
- {
- MVert source;
- MVert *dest;
- int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
- int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
-
- dm->getVert(dm, oldIndex, &source);
- dest = CDDM_get_vert(result, newIndex);
-
- DM_copy_vert_data(dm, result, oldIndex, newIndex, 1);
- *dest = source;
- }
- BLI_ghashIterator_free(hashIter);
-
- /* edges */
- for ( hashIter = BLI_ghashIterator_new(edgeHash);
- !BLI_ghashIterator_isDone(hashIter);
- BLI_ghashIterator_step(hashIter) )
- {
- MEdge source;
- MEdge *dest;
- int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
- int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
-
- dm->getEdge(dm, oldIndex, &source);
- dest = CDDM_get_edge(result, newIndex);
-
- source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
- source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
-
- DM_copy_edge_data(dm, result, oldIndex, newIndex, 1);
- *dest = source;
- }
- BLI_ghashIterator_free(hashIter);
-
- /* faces */
- for ( hashIter = BLI_ghashIterator_new(faceHash);
- !BLI_ghashIterator_isDone(hashIter);
- BLI_ghashIterator_step(hashIter) )
- {
- MFace source;
- MFace *dest;
- int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
- int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
- int orig_v4;
-
- dm->getTessFace(dm, oldIndex, &source);
- dest = CDDM_get_tessface(result, newIndex);
-
- orig_v4 = source.v4;
-
- source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
- source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
- source.v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v3)));
- if (source.v4)
- source.v4 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v4)));
-
- DM_copy_tessface_data(dm, result, oldIndex, newIndex, 1);
- *dest = source;
-
- test_index_face(dest, &result->faceData, newIndex, (orig_v4 ? 4 : 3));
- }
- BLI_ghashIterator_free(hashIter);
-
- /* recalculate normals */
- CDDM_calc_normals(result);
-
- /* free hashes */
- BLI_ghash_free(vertHash, NULL, NULL);
- BLI_ghash_free(edgeHash, NULL, NULL);
- BLI_ghash_free(faceHash, NULL, NULL);
-
- CDDM_tessfaces_to_faces(result);
-
- /* return the new mesh */
- return result;
-}
-
-/* Array */
-/* Array modifier: duplicates the object multiple times along an axis
-*/
-
-static void arrayModifier_initData(ModifierData *md)
-{
- ArrayModifierData *amd = (ArrayModifierData*) md;
-
- /* default to 2 duplicates distributed along the x-axis by an
- offset of 1 object-width
- */
- amd->start_cap = amd->end_cap = amd->curve_ob = amd->offset_ob = NULL;
- amd->count = 2;
- amd->offset[0] = amd->offset[1] = amd->offset[2] = 0;
- amd->scale[0] = 1;
- amd->scale[1] = amd->scale[2] = 0;
- amd->length = 0;
- amd->merge_dist = 0.01;
- amd->fit_type = MOD_ARR_FIXEDCOUNT;
- amd->offset_type = MOD_ARR_OFF_RELATIVE;
- amd->flags = 0;
-}
-
-static void arrayModifier_copyData(ModifierData *md, ModifierData *target)
-{
- ArrayModifierData *amd = (ArrayModifierData*) md;
- ArrayModifierData *tamd = (ArrayModifierData*) target;
-
- tamd->start_cap = amd->start_cap;
- tamd->end_cap = amd->end_cap;
- tamd->curve_ob = amd->curve_ob;
- tamd->offset_ob = amd->offset_ob;
- tamd->count = amd->count;
- VECCOPY(tamd->offset, amd->offset);
- VECCOPY(tamd->scale, amd->scale);
- tamd->length = amd->length;
- tamd->merge_dist = amd->merge_dist;
- tamd->fit_type = amd->fit_type;
- tamd->offset_type = amd->offset_type;
- tamd->flags = amd->flags;
-}
-
-static void arrayModifier_foreachObjectLink(
- ModifierData *md, Object *ob,
- void (*walk)(void *userData, Object *ob, Object **obpoin),
- void *userData)
-{
- ArrayModifierData *amd = (ArrayModifierData*) md;
-
- walk(userData, ob, &amd->start_cap);
- walk(userData, ob, &amd->end_cap);
- walk(userData, ob, &amd->curve_ob);
- walk(userData, ob, &amd->offset_ob);
-}
-
-static void arrayModifier_updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene,
- Object *ob, DagNode *obNode)
-{
- ArrayModifierData *amd = (ArrayModifierData*) md;
-
- if (amd->start_cap) {
- DagNode *curNode = dag_get_node(forest, amd->start_cap);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
- }
- if (amd->end_cap) {
- DagNode *curNode = dag_get_node(forest, amd->end_cap);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
- }
- if (amd->curve_ob) {
- DagNode *curNode = dag_get_node(forest, amd->curve_ob);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
- }
- if (amd->offset_ob) {
- DagNode *curNode = dag_get_node(forest, amd->offset_ob);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
- }
-}
-
-static float vertarray_size(MVert *mvert, int numVerts, int axis)
-{
- int i;
- float min_co, max_co;
-
- /* if there are no vertices, width is 0 */
- if(numVerts == 0) return 0;
-
- /* find the minimum and maximum coordinates on the desired axis */
- min_co = max_co = mvert->co[axis];
- ++mvert;
- for(i = 1; i < numVerts; ++i, ++mvert) {
- if(mvert->co[axis] < min_co) min_co = mvert->co[axis];
- if(mvert->co[axis] > max_co) max_co = mvert->co[axis];
- }
-
- return max_co - min_co;
-}
-
-typedef struct IndexMapEntry {
- /* the new vert index that this old vert index maps to */
- int new;
- /* -1 if this vert isn't merged, otherwise the old vert index it
- * should be replaced with
- */
- int merge;
- /* 1 if this vert's first copy is merged with the last copy of its
- * merge target, otherwise 0
- */
- short merge_final;
-} IndexMapEntry;
-
-/* indexMap - an array of IndexMap entries
- * oldIndex - the old index to map
- * copyNum - the copy number to map to (original = 0, first copy = 1, etc.)
- */
-static int calc_mapping(IndexMapEntry *indexMap, int oldIndex, int copyNum)
-{
- if(indexMap[oldIndex].merge < 0) {
- /* vert wasn't merged, so use copy of this vert */
- return indexMap[oldIndex].new + copyNum;
- } else if(indexMap[oldIndex].merge == oldIndex) {
- /* vert was merged with itself */
- return indexMap[oldIndex].new;
- } else {
- /* vert was merged with another vert */
- /* follow the chain of merges to the end, or until we've passed
- * a number of vertices equal to the copy number
- */
- if(copyNum <= 0)
- return indexMap[oldIndex].new;
- else
- return calc_mapping(indexMap, indexMap[oldIndex].merge,
- copyNum - 1);
- }
-}
-
-#if 0
-static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
- Scene *scene, Object *ob, DerivedMesh *dm,
- int initFlags)
-{
- int i, j;
- /* offset matrix */
- float offset[4][4];
- float final_offset[4][4];
- float tmp_mat[4][4];
- float length = amd->length;
- int count = amd->count;
- int numVerts, numEdges, numFaces;
- int maxVerts, maxEdges, maxFaces;
- int finalVerts, finalEdges, finalFaces;
- DerivedMesh *result, *start_cap = NULL, *end_cap = NULL;
- MVert *mvert, *src_mvert;
- MEdge *medge;
- MFace *mface;
-
- IndexMapEntry *indexMap;
-
- EdgeHash *edges;
-
- /* need to avoid infinite recursion here */
- if(amd->start_cap && amd->start_cap != ob)
- start_cap = amd->start_cap->derivedFinal;
- if(amd->end_cap && amd->end_cap != ob)
- end_cap = amd->end_cap->derivedFinal;
-
- unit_m4(offset);
-
- indexMap = MEM_callocN(sizeof(*indexMap) * dm->getNumVerts(dm),
- "indexmap");
-
- src_mvert = dm->getVertArray(dm);
-
- maxVerts = dm->getNumVerts(dm);
-
- if(amd->offset_type & MOD_ARR_OFF_CONST)
- add_v3_v3v3(offset[3], offset[3], amd->offset);
- if(amd->offset_type & MOD_ARR_OFF_RELATIVE) {
- for(j = 0; j < 3; j++)
- offset[3][j] += amd->scale[j] * vertarray_size(src_mvert,
- maxVerts, j);
- }
-
- if((amd->offset_type & MOD_ARR_OFF_OBJ) && (amd->offset_ob)) {
- float obinv[4][4];
- float result_mat[4][4];
-
- if(ob)
- invert_m4_m4(obinv, ob->obmat);
- else
- unit_m4(obinv);
-
- mul_serie_m4(result_mat, offset,
- obinv, amd->offset_ob->obmat,
- NULL, NULL, NULL, NULL, NULL);
- copy_m4_m4(offset, result_mat);
- }
-
- if(amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob) {
- Curve *cu = amd->curve_ob->data;
- if(cu) {
- float tmp_mat[3][3];
- float scale;
-
- object_to_mat3(amd->curve_ob, tmp_mat);
- scale = mat3_to_scale(tmp_mat);
-
- if(!cu->path) {
- cu->flag |= CU_PATH; // needed for path & bevlist
- makeDispListCurveTypes(scene, amd->curve_ob, 0);
- }
- if(cu->path)
- length = scale*cu->path->totdist;
- }
- }
-
- /* calculate the maximum number of copies which will fit within the
- prescribed length */
- if(amd->fit_type == MOD_ARR_FITLENGTH
- || amd->fit_type == MOD_ARR_FITCURVE) {
- float dist = sqrt(dot_v3v3(offset[3], offset[3]));
-
- if(dist > 1e-6f)
- /* this gives length = first copy start to last copy end
- add a tiny offset for floating point rounding errors */
- count = (length + 1e-6f) / dist;
- else
- /* if the offset has no translation, just make one copy */
- count = 1;
- }
-
- if(count < 1)
- count = 1;
-
- /* allocate memory for count duplicates (including original) plus
- * start and end caps
- */
- finalVerts = dm->getNumVerts(dm) * count;
- finalEdges = dm->getNumEdges(dm) * count;
- finalFaces = dm->getNumTessFaces(dm) * count;
- if(start_cap) {
- finalVerts += start_cap->getNumVerts(start_cap);
- finalEdges += start_cap->getNumEdges(start_cap);
- finalFaces += start_cap->getNumTessFaces(start_cap);
- }
- if(end_cap) {
- finalVerts += end_cap->getNumVerts(end_cap);
- finalEdges += end_cap->getNumEdges(end_cap);
- finalFaces += end_cap->getNumTessFaces(end_cap);
- }
- result = CDDM_from_template(dm, finalVerts, finalEdges, finalFaces, 0, 0);
-
- /* calculate the offset matrix of the final copy (for merging) */
- unit_m4(final_offset);
-
- for(j=0; j < count - 1; j++) {
- mul_m4_m4m4(tmp_mat, final_offset, offset);
- copy_m4_m4(final_offset, tmp_mat);
- }
-
- numVerts = numEdges = numFaces = 0;
- mvert = CDDM_get_verts(result);
-
- for (i = 0; i < maxVerts; i++) {
- indexMap[i].merge = -1; /* default to no merge */
- indexMap[i].merge_final = 0; /* default to no merge */
- }
-
- for (i = 0; i < maxVerts; i++) {
- MVert *inMV;
- MVert *mv = &mvert[numVerts];
- MVert *mv2;
- float co[3];
-
- inMV = &src_mvert[i];
-
- DM_copy_vert_data(dm, result, i, numVerts, 1);
- *mv = *inMV;
- numVerts++;
-
- indexMap[i].new = numVerts - 1;
-
- VECCOPY(co, mv->co);
-
- /* Attempts to merge verts from one duplicate with verts from the
- * next duplicate which are closer than amd->merge_dist.
- * Only the first such vert pair is merged.
- * If verts are merged in the first duplicate pair, they are merged
- * in all pairs.
- */
- if((count > 1) && (amd->flags & MOD_ARR_MERGE)) {
- float tmp_co[3];
- VECCOPY(tmp_co, mv->co);
- mul_m4_v3(offset, tmp_co);
-
- for(j = 0; j < maxVerts; j++) {
- /* if vertex already merged, don't use it */
- if( indexMap[j].merge != -1 ) continue;
-
- inMV = &src_mvert[j];
- /* if this vert is within merge limit, merge */
- if(compare_len_v3v3(tmp_co, inMV->co, amd->merge_dist)) {
- indexMap[i].merge = j;
-
- /* test for merging with final copy of merge target */
- if(amd->flags & MOD_ARR_MERGEFINAL) {
- VECCOPY(tmp_co, inMV->co);
- inMV = &src_mvert[i];
- mul_m4_v3(final_offset, tmp_co);
- if(compare_len_v3v3(tmp_co, inMV->co, amd->merge_dist))
- indexMap[i].merge_final = 1;
- }
- break;
- }
- }
- }
-
- /* if no merging, generate copies of this vert */
- if(indexMap[i].merge < 0) {
- for(j=0; j < count - 1; j++) {
- mv2 = &mvert[numVerts];
-
- DM_copy_vert_data(result, result, numVerts - 1, numVerts, 1);
- *mv2 = *mv;
- numVerts++;
-
- mul_m4_v3(offset, co);
- VECCOPY(mv2->co, co);
- }
- } else if(indexMap[i].merge != i && indexMap[i].merge_final) {
- /* if this vert is not merging with itself, and it is merging
- * with the final copy of its merge target, remove the first copy
- */
- numVerts--;
- DM_free_vert_data(result, numVerts, 1);
- }
- }
-
- /* make a hashtable so we can avoid duplicate edges from merging */
- edges = BLI_edgehash_new();
-
- maxEdges = dm->getNumEdges(dm);
- medge = CDDM_get_edges(result);
- for(i = 0; i < maxEdges; i++) {
- MEdge inMED;
- MEdge med;
- MEdge *med2;
- int vert1, vert2;
-
- dm->getEdge(dm, i, &inMED);
-
- med = inMED;
- med.v1 = indexMap[inMED.v1].new;
- med.v2 = indexMap[inMED.v2].new;
-
- /* if vertices are to be merged with the final copies of their
- * merge targets, calculate that final copy
- */
- if(indexMap[inMED.v1].merge_final) {
- med.v1 = calc_mapping(indexMap, indexMap[inMED.v1].merge,
- count - 1);
- }
- if(indexMap[inMED.v2].merge_final) {
- med.v2 = calc_mapping(indexMap, indexMap[inMED.v2].merge,
- count - 1);
- }
-
- if(med.v1 == med.v2) continue;
-
- if (initFlags) {
- med.flag |= ME_EDGEDRAW | ME_EDGERENDER;
- }
-
- if(!BLI_edgehash_haskey(edges, med.v1, med.v2)) {
- DM_copy_edge_data(dm, result, i, numEdges, 1);
- medge[numEdges] = med;
- numEdges++;
-
- BLI_edgehash_insert(edges, med.v1, med.v2, NULL);
- }
-
- for(j = 1; j < count; j++)
- {
- vert1 = calc_mapping(indexMap, inMED.v1, j);
- vert2 = calc_mapping(indexMap, inMED.v2, j);
- /* avoid duplicate edges */
- if(!BLI_edgehash_haskey(edges, vert1, vert2)) {
- med2 = &medge[numEdges];
-
- DM_copy_edge_data(dm, result, i, numEdges, 1);
- *med2 = med;
- numEdges++;
-
- med2->v1 = vert1;
- med2->v2 = vert2;
-
- BLI_edgehash_insert(edges, med2->v1, med2->v2, NULL);
- }
- }
- }
-
- maxFaces = dm->getNumTessFaces(dm);
- mface = CDDM_get_tessfaces(result);
- for (i=0; i < maxFaces; i++) {
- MFace inMF;
- MFace *mf = &mface[numFaces];
-
- dm->getTessFace(dm, i, &inMF);
-
- DM_copy_tessface_data(dm, result, i, numFaces, 1);
- *mf = inMF;
-
- mf->v1 = indexMap[inMF.v1].new;
- mf->v2 = indexMap[inMF.v2].new;
- mf->v3 = indexMap[inMF.v3].new;
- if(inMF.v4)
- mf->v4 = indexMap[inMF.v4].new;
-
- /* if vertices are to be merged with the final copies of their
- * merge targets, calculate that final copy
- */
- if(indexMap[inMF.v1].merge_final)
- mf->v1 = calc_mapping(indexMap, indexMap[inMF.v1].merge, count-1);
- if(indexMap[inMF.v2].merge_final)
- mf->v2 = calc_mapping(indexMap, indexMap[inMF.v2].merge, count-1);
- if(indexMap[inMF.v3].merge_final)
- mf->v3 = calc_mapping(indexMap, indexMap[inMF.v3].merge, count-1);
- if(inMF.v4 && indexMap[inMF.v4].merge_final)
- mf->v4 = calc_mapping(indexMap, indexMap[inMF.v4].merge, count-1);
-
- if(test_index_face(mf, &result->faceData, numFaces, inMF.v4?4:3) < 3)
- continue;
-
- numFaces++;
-
- /* if the face has fewer than 3 vertices, don't create it */
- if(mf->v3 == 0 || (mf->v1 && (mf->v1 == mf->v3 || mf->v1 == mf->v4))) {
- numFaces--;
- DM_free_face_data(result, numFaces, 1);
- }
-
- for(j = 1; j < count; j++)
- {
- MFace *mf2 = &mface[numFaces];
-
- DM_copy_tessface_data(dm, result, i, numFaces, 1);
- *mf2 = *mf;
-
- mf2->v1 = calc_mapping(indexMap, inMF.v1, j);
- mf2->v2 = calc_mapping(indexMap, inMF.v2, j);
- mf2->v3 = calc_mapping(indexMap, inMF.v3, j);
- if (inMF.v4)
- mf2->v4 = calc_mapping(indexMap, inMF.v4, j);
-
- test_index_face(mf2, &result->faceData, numFaces, inMF.v4?4:3);
- numFaces++;
-
- /* if the face has fewer than 3 vertices, don't create it */
- if(mf2->v3 == 0 || (mf2->v1 && (mf2->v1 == mf2->v3 || mf2->v1 ==
- mf2->v4))) {
- numFaces--;
- DM_free_face_data(result, numFaces, 1);
- }
- }
- }
-
- /* add start and end caps */
- if(start_cap) {
- float startoffset[4][4];
- MVert *cap_mvert;
- MEdge *cap_medge;
- MFace *cap_mface;
- int *origindex;
- int *vert_map;
- int capVerts, capEdges, capFaces;
-
- capVerts = start_cap->getNumVerts(start_cap);
- capEdges = start_cap->getNumEdges(start_cap);
- capFaces = start_cap->getNumTessFaces(start_cap);
- cap_mvert = start_cap->getVertArray(start_cap);
- cap_medge = start_cap->getEdgeArray(start_cap);
- cap_mface = start_cap->getTessFaceArray(start_cap);
-
- invert_m4_m4(startoffset, offset);
-
- vert_map = MEM_callocN(sizeof(*vert_map) * capVerts,
- "arrayModifier_doArray vert_map");
-
- origindex = result->getVertDataArray(result, CD_ORIGINDEX);
- for(i = 0; i < capVerts; i++) {
- MVert *mv = &cap_mvert[i];
- short merged = 0;
-
- if(amd->flags & MOD_ARR_MERGE) {
- float tmp_co[3];
- MVert *in_mv;
- int j;
-
- VECCOPY(tmp_co, mv->co);
- mul_m4_v3(startoffset, tmp_co);
-
- for(j = 0; j < maxVerts; j++) {
- in_mv = &src_mvert[j];
- /* if this vert is within merge limit, merge */
- if(compare_len_v3v3(tmp_co, in_mv->co, amd->merge_dist)) {
- vert_map[i] = calc_mapping(indexMap, j, 0);
- merged = 1;
- break;
- }
- }
- }
-
- if(!merged) {
- DM_copy_vert_data(start_cap, result, i, numVerts, 1);
- mvert[numVerts] = *mv;
- mul_m4_v3(startoffset, mvert[numVerts].co);
- origindex[numVerts] = ORIGINDEX_NONE;
-
- vert_map[i] = numVerts;
-
- numVerts++;
- }
- }
- origindex = result->getEdgeDataArray(result, CD_ORIGINDEX);
- for(i = 0; i < capEdges; i++) {
- int v1, v2;
-
- v1 = vert_map[cap_medge[i].v1];
- v2 = vert_map[cap_medge[i].v2];
-
- if(!BLI_edgehash_haskey(edges, v1, v2)) {
- DM_copy_edge_data(start_cap, result, i, numEdges, 1);
- medge[numEdges] = cap_medge[i];
- medge[numEdges].v1 = v1;
- medge[numEdges].v2 = v2;
- origindex[numEdges] = ORIGINDEX_NONE;
-
- numEdges++;
- }
- }
- origindex = result->getTessFaceDataArray(result, CD_ORIGINDEX);
- for(i = 0; i < capFaces; i++) {
- DM_copy_tessface_data(start_cap, result, i, numFaces, 1);
- mface[numFaces] = cap_mface[i];
- mface[numFaces].v1 = vert_map[mface[numFaces].v1];
- mface[numFaces].v2 = vert_map[mface[numFaces].v2];
- mface[numFaces].v3 = vert_map[mface[numFaces].v3];
- if(mface[numFaces].v4) {
- mface[numFaces].v4 = vert_map[mface[numFaces].v4];
-
- test_index_face(&mface[numFaces], &result->faceData,
- numFaces, 4);
- }
- else
- {
- test_index_face(&mface[numFaces], &result->faceData,
- numFaces, 3);
- }
-
- origindex[numFaces] = ORIGINDEX_NONE;
-
- numFaces++;
- }
-
- MEM_freeN(vert_map);
- start_cap->release(start_cap);
- }
-
- if(end_cap) {
- float endoffset[4][4];
- MVert *cap_mvert;
- MEdge *cap_medge;
- MFace *cap_mface;
- int *origindex;
- int *vert_map;
- int capVerts, capEdges, capFaces;
-
- capVerts = end_cap->getNumVerts(end_cap);
- capEdges = end_cap->getNumEdges(end_cap);
- capFaces = end_cap->getNumTessFaces(end_cap);
- cap_mvert = end_cap->getVertArray(end_cap);
- cap_medge = end_cap->getEdgeArray(end_cap);
- cap_mface = end_cap->getTessFaceArray(end_cap);
-
- mul_m4_m4m4(endoffset, final_offset, offset);
-
- vert_map = MEM_callocN(sizeof(*vert_map) * capVerts,
- "arrayModifier_doArray vert_map");
-
- origindex = result->getVertDataArray(result, CD_ORIGINDEX);
- for(i = 0; i < capVerts; i++) {
- MVert *mv = &cap_mvert[i];
- short merged = 0;
-
- if(amd->flags & MOD_ARR_MERGE) {
- float tmp_co[3];
- MVert *in_mv;
- int j;
-
- VECCOPY(tmp_co, mv->co);
- mul_m4_v3(offset, tmp_co);
-
- for(j = 0; j < maxVerts; j++) {
- in_mv = &src_mvert[j];
- /* if this vert is within merge limit, merge */
- if(compare_len_v3v3(tmp_co, in_mv->co, amd->merge_dist)) {
- vert_map[i] = calc_mapping(indexMap, j, count - 1);
- merged = 1;
- break;
- }
- }
- }
-
- if(!merged) {
- DM_copy_vert_data(end_cap, result, i, numVerts, 1);
- mvert[numVerts] = *mv;
- mul_m4_v3(endoffset, mvert[numVerts].co);
- origindex[numVerts] = ORIGINDEX_NONE;
-
- vert_map[i] = numVerts;
-
- numVerts++;
- }
- }
- origindex = result->getEdgeDataArray(result, CD_ORIGINDEX);
- for(i = 0; i < capEdges; i++) {
- int v1, v2;
-
- v1 = vert_map[cap_medge[i].v1];
- v2 = vert_map[cap_medge[i].v2];
-
- if(!BLI_edgehash_haskey(edges, v1, v2)) {
- DM_copy_edge_data(end_cap, result, i, numEdges, 1);
- medge[numEdges] = cap_medge[i];
- medge[numEdges].v1 = v1;
- medge[numEdges].v2 = v2;
- origindex[numEdges] = ORIGINDEX_NONE;
-
- numEdges++;
- }
- }
- origindex = result->getTessFaceDataArray(result, CD_ORIGINDEX);
- for(i = 0; i < capFaces; i++) {
- DM_copy_tessface_data(end_cap, result, i, numFaces, 1);
- mface[numFaces] = cap_mface[i];
- mface[numFaces].v1 = vert_map[mface[numFaces].v1];
- mface[numFaces].v2 = vert_map[mface[numFaces].v2];
- mface[numFaces].v3 = vert_map[mface[numFaces].v3];
- if(mface[numFaces].v4) {
- mface[numFaces].v4 = vert_map[mface[numFaces].v4];
-
- test_index_face(&mface[numFaces], &result->faceData,
- numFaces, 4);
- }
- else
- {
- test_index_face(&mface[numFaces], &result->faceData,
- numFaces, 3);
- }
- origindex[numFaces] = ORIGINDEX_NONE;
-
- numFaces++;
- }
-
- MEM_freeN(vert_map);
- end_cap->release(end_cap);
- }
-
- BLI_edgehash_free(edges, NULL);
- MEM_freeN(indexMap);
-
- CDDM_lower_num_verts(result, numVerts);
- CDDM_lower_num_edges(result, numEdges);
- CDDM_lower_num_faces(result, numFaces);
-
- CDDM_tessfaces_to_faces(result);
-
- return result;
-}
-
-static DerivedMesh *arrayModifier_applyModifier(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- int useRenderParams, int isFinalCalc)
-{
- DerivedMesh *result;
- ArrayModifierData *amd = (ArrayModifierData*) md;
-
- result = arrayModifier_doArray(amd, md->scene, ob, derivedData, 0);
-
- if(result != derivedData)
- CDDM_calc_normals(result);
-
- return result;
-}
-
-static DerivedMesh *arrayModifier_applyModifierEM(
- ModifierData *md, Object *ob, BMEditMesh *editData,
- DerivedMesh *derivedData)
-{
- return arrayModifier_applyModifier(md, ob, derivedData, 0, 1);
-}
-#endif
-
-DerivedMesh *arrayModifier_applyModifier(ModifierData *md, Object *ob,
- DerivedMesh *derivedData,
- int useRenderParams, int isFinalCalc);
-DerivedMesh *arrayModifier_applyModifierEM(ModifierData *md, Object *ob,
- BMEditMesh *editData,
- DerivedMesh *derivedData);
-
-/* Mirror */
-
-static void mirrorModifier_initData(ModifierData *md)
-{
- MirrorModifierData *mmd = (MirrorModifierData*) md;
-
- mmd->flag |= (MOD_MIR_AXIS_X | MOD_MIR_VGROUP);
- mmd->tolerance = 0.001;
- mmd->mirror_ob = NULL;
-}
-
-static void mirrorModifier_copyData(ModifierData *md, ModifierData *target)
-{
- MirrorModifierData *mmd = (MirrorModifierData*) md;
- MirrorModifierData *tmmd = (MirrorModifierData*) target;
-
- tmmd->axis = mmd->axis;
- tmmd->flag = mmd->flag;
- tmmd->tolerance = mmd->tolerance;
- tmmd->mirror_ob = mmd->mirror_ob;;
-}
-
-static void mirrorModifier_foreachObjectLink(
- ModifierData *md, Object *ob,
- void (*walk)(void *userData, Object *ob, Object **obpoin),
- void *userData)
-{
- MirrorModifierData *mmd = (MirrorModifierData*) md;
-
- walk(userData, ob, &mmd->mirror_ob);
-}
-
-static void mirrorModifier_updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene,
- Object *ob, DagNode *obNode)
-{
- MirrorModifierData *mmd = (MirrorModifierData*) md;
-
- if(mmd->mirror_ob) {
- DagNode *latNode = dag_get_node(forest, mmd->mirror_ob);
-
- dag_add_relation(forest, latNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Mirror Modifier");
- }
-}
-
-#if 0
-static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
- Object *ob,
- DerivedMesh *dm,
- int initFlags,
- int axis)
-{
- int i;
- float tolerance = mmd->tolerance;
- DerivedMesh *result;
- int numVerts, numEdges, numFaces;
- int maxVerts = dm->getNumVerts(dm);
- int maxEdges = dm->getNumEdges(dm);
- int maxFaces = dm->getNumTessFaces(dm);
- int *flip_map= NULL;
- int do_vgroup_mirr= (mmd->flag & MOD_MIR_VGROUP);
- int (*indexMap)[2];
- float mtx[4][4], imtx[4][4];
-
- numVerts = numEdges = numFaces = 0;
-
- indexMap = MEM_mallocN(sizeof(*indexMap) * maxVerts, "indexmap");
-
- result = CDDM_from_template(dm, maxVerts * 2, maxEdges * 2, maxFaces * 2, 0, 0);
-
-
- if (do_vgroup_mirr) {
- flip_map= defgroup_flip_map(ob, 0);
- if(flip_map == NULL)
- do_vgroup_mirr= 0;
- }
-
- if (mmd->mirror_ob) {
- float obinv[4][4];
-
- invert_m4_m4(obinv, mmd->mirror_ob->obmat);
- mul_m4_m4m4(mtx, ob->obmat, obinv);
- invert_m4_m4(imtx, mtx);
- }
-
- for(i = 0; i < maxVerts; i++) {
- MVert inMV;
- MVert *mv = CDDM_get_vert(result, numVerts);
- int isShared;
- float co[3];
-
- dm->getVert(dm, i, &inMV);
-
- copy_v3_v3(co, inMV.co);
-
- if (mmd->mirror_ob) {
- mul_v3_m4v3(co, mtx, co);
- }
- isShared = ABS(co[axis])<=tolerance;
-
- /* Because the topology result (# of vertices) must be the same if
- * the mesh data is overridden by vertex cos, have to calc sharedness
- * based on original coordinates. This is why we test before copy.
- */
- DM_copy_vert_data(dm, result, i, numVerts, 1);
- *mv = inMV;
- numVerts++;
-
- indexMap[i][0] = numVerts - 1;
- indexMap[i][1] = !isShared;
-
- if(isShared) {
- co[axis] = 0;
- if (mmd->mirror_ob) {
- mul_v3_m4v3(co, imtx, co);
- }
- copy_v3_v3(mv->co, co);
-
- mv->flag |= ME_VERT_MERGED;
- } else {
- MVert *mv2 = CDDM_get_vert(result, numVerts);
-
- DM_copy_vert_data(dm, result, i, numVerts, 1);
- *mv2 = *mv;
-
- co[axis] = -co[axis];
- if (mmd->mirror_ob) {
- mul_v3_m4v3(co, imtx, co);
- }
- copy_v3_v3(mv2->co, co);
-
- if (do_vgroup_mirr) {
- MDeformVert *dvert= DM_get_vert_data(result, numVerts, CD_MDEFORMVERT);
- if(dvert) {
- defvert_flip(dvert, flip_map);
- }
- }
-
- numVerts++;
- }
- }
-
- for(i = 0; i < maxEdges; i++) {
- MEdge inMED;
- MEdge *med = CDDM_get_edge(result, numEdges);
-
- dm->getEdge(dm, i, &inMED);
-
- DM_copy_edge_data(dm, result, i, numEdges, 1);
- *med = inMED;
- numEdges++;
-
- med->v1 = indexMap[inMED.v1][0];
- med->v2 = indexMap[inMED.v2][0];
- if(initFlags)
- med->flag |= ME_EDGEDRAW | ME_EDGERENDER;
-
- if(indexMap[inMED.v1][1] || indexMap[inMED.v2][1]) {
- MEdge *med2 = CDDM_get_edge(result, numEdges);
-
- DM_copy_edge_data(dm, result, i, numEdges, 1);
- *med2 = *med;
- numEdges++;
-
- med2->v1 += indexMap[inMED.v1][1];
- med2->v2 += indexMap[inMED.v2][1];
- }
- }
-
- for(i = 0; i < maxFaces; i++) {
- MFace inMF;
- MFace *mf = CDDM_get_tessface(result, numFaces);
-
- dm->getTessFace(dm, i, &inMF);
-
- DM_copy_tessface_data(dm, result, i, numFaces, 1);
- *mf = inMF;
- numFaces++;
-
- mf->v1 = indexMap[inMF.v1][0];
- mf->v2 = indexMap[inMF.v2][0];
- mf->v3 = indexMap[inMF.v3][0];
- mf->v4 = indexMap[inMF.v4][0];
-
- if(indexMap[inMF.v1][1]
- || indexMap[inMF.v2][1]
- || indexMap[inMF.v3][1]
- || (mf->v4 && indexMap[inMF.v4][1])) {
- MFace *mf2 = CDDM_get_tessface(result, numFaces);
- static int corner_indices[4] = {2, 1, 0, 3};
-
- DM_copy_tessface_data(dm, result, i, numFaces, 1);
- *mf2 = *mf;
-
- mf2->v1 += indexMap[inMF.v1][1];
- mf2->v2 += indexMap[inMF.v2][1];
- mf2->v3 += indexMap[inMF.v3][1];
- if(inMF.v4) mf2->v4 += indexMap[inMF.v4][1];
-
- /* mirror UVs if enabled */
- if(mmd->flag & (MOD_MIR_MIRROR_U | MOD_MIR_MIRROR_V)) {
- MTFace *tf = result->getTessFaceData(result, numFaces, CD_MTFACE);
- if(tf) {
- int j;
- for(j = 0; j < 4; ++j) {
- if(mmd->flag & MOD_MIR_MIRROR_U)
- tf->uv[j][0] = 1.0f - tf->uv[j][0];
- if(mmd->flag & MOD_MIR_MIRROR_V)
- tf->uv[j][1] = 1.0f - tf->uv[j][1];
- }
- }
- }
-
- /* Flip face normal */
- SWAP(int, mf2->v1, mf2->v3);
- DM_swap_tessface_data(result, numFaces, corner_indices);
-
- test_index_face(mf2, &result->faceData, numFaces, inMF.v4?4:3);
- numFaces++;
- }
- }
-
- if (flip_map) MEM_freeN(flip_map);
-
- MEM_freeN(indexMap);
-
- CDDM_lower_num_verts(result, numVerts);
- CDDM_lower_num_edges(result, numEdges);
- CDDM_lower_num_faces(result, numFaces);
-
- CDDM_tessfaces_to_faces(result);
-
- return result;
-}
-#endif
-
-DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
- Object *ob,
- DerivedMesh *dm,
- int initFlags,
- int axis);
-static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd,
- Object *ob, DerivedMesh *dm,
- int initFlags)
-{
- DerivedMesh *result = dm;
-
- /* check which axes have been toggled and mirror accordingly */
- if(mmd->flag & MOD_MIR_AXIS_X) {
- result = doMirrorOnAxis(mmd, ob, result, initFlags, 0);
- }
- if(mmd->flag & MOD_MIR_AXIS_Y) {
- DerivedMesh *tmp = result;
- result = doMirrorOnAxis(mmd, ob, result, initFlags, 1);
- if(tmp != dm) tmp->release(tmp); /* free intermediate results */
- }
- if(mmd->flag & MOD_MIR_AXIS_Z) {
- DerivedMesh *tmp = result;
- result = doMirrorOnAxis(mmd, ob, result, initFlags, 2);
- if(tmp != dm) tmp->release(tmp); /* free intermediate results */
- }
-
- return result;
-}
-
-static DerivedMesh *mirrorModifier_applyModifier(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- int useRenderParams, int isFinalCalc)
-{
- DerivedMesh *result;
- MirrorModifierData *mmd = (MirrorModifierData*) md;
-
- result = mirrorModifier__doMirror(mmd, ob, derivedData, 0);
-
- if(result != derivedData)
- CDDM_calc_normals(result);
-
- return result;
-}
-
-static DerivedMesh *mirrorModifier_applyModifierEM(
- ModifierData *md, Object *ob, BMEditMesh *editData,
- DerivedMesh *derivedData)
-{
- return mirrorModifier_applyModifier(md, ob, derivedData, 0, 1);
-}
-
-/* EdgeSplit */
-/* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag
- * or edge angle (can be used to achieve autosmoothing)
-*/
-
-/*new cddm-based edge split code*/
-typedef struct VertUser {
- int ov, v, done;
- ListBase users;
-} VertUser;
-
-typedef struct EdgeNode {
- struct EdgeNode *next, *prev;
- struct EdgeData *edge;
-} EdgeNode;
-
-typedef struct EdgeData {
- EdgeNode v1node, v2node;
- VertUser *v1user, *v2user;
- float fno[3]; /*used to calculate face angles*/
- int has_fno;
- int tag;
- int v1, v2;
- int used;
-} EdgeData;
-
-typedef struct MemBase {
- BLI_mempool *vertuserpool;
-} MemBase;
-
-BM_INLINE EdgeData *edge_get_next(EdgeData *e, int ov) {
- if (ov == e->v1)
- return e->v1node.next ? e->v1node.next->edge : NULL;
- else return e->v2node.next ? e->v2node.next->edge : NULL;
-}
-
-BM_INLINE EdgeNode *edge_get_node(EdgeData *e, int ov)
-{
- if (ov == e->v1)
- return &e->v1node;
- else return &e->v2node;
-}
-
-BM_INLINE VertUser *edge_get_vuser(MemBase *b, EdgeData *edge, int ov)
-{
- if (ov == edge->v1)
- return edge->v1user;
- else if (ov == edge->v2)
- return edge->v2user;
- else {
- printf("yeek!!\n");
- return NULL;
- }
-}
-
-BM_INLINE void edge_set_vuser(MemBase *b, EdgeData *e, int ov, VertUser *vu)
-
-{
- VertUser *olduser = edge_get_vuser(b, e, ov);
-
- if (vu == olduser)
- return;
-
- if (olduser)
- BLI_remlink(&olduser->users, ov==e->v1 ? &e->v1node : &e->v2node);
- BLI_addtail(&vu->users, ov==e->v1 ? &e->v1node : &e->v2node);
-
- if (ov == e->v1)
- e->v1user = vu;
- else e->v2user = vu;
-}
-
-BM_INLINE VertUser *new_vuser(MemBase *base)
-{
- VertUser *vusr = BLI_mempool_calloc(base->vertuserpool);
-
- return vusr;
-}
-
-BM_INLINE MemBase *new_membase(void)
-{
- MemBase *b = MEM_callocN(sizeof(MemBase), "MemBase for edgesplit in modifier.c");
- b->vertuserpool = BLI_mempool_create(sizeof(VertUser), 1, 2048, 1, 0);
-
- return b;
-}
-
-BM_INLINE void free_membase(MemBase *b)
-{
- BLI_mempool_destroy(b->vertuserpool);
- MEM_freeN(b);
-}
-
-BM_INLINE EdgeData *edge_get_first(VertUser *vu)
-{
- return vu->users.first ? ((EdgeNode*)vu->users.first)->edge : NULL;
-}
-
-DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd)
-{
- DerivedMesh *cddm = CDDM_copy(dm, 0);
- MEdge *medge;
- BLI_array_declare(medge);
- MLoop *mloop, *ml, *prevl;
- MPoly *mpoly, *mp;
- MVert *mvert;
- BLI_array_declare(mvert);
- EdgeData *etags, *e, *enext;
- BLI_array_declare(etags);
- VertUser *vu, *vu2;
- MemBase *membase;
- CustomData edata, vdata;
- int i, j, curv, cure;
- float threshold = cos((emd->split_angle + 0.00001) * M_PI / 180.0);
- float no[3], edge_angle_cos;
-
- if (!cddm->numVertData || !cddm->numEdgeData)
- return cddm;
-
- membase = new_membase();
-
- etags = MEM_callocN(sizeof(EdgeData)*cddm->numEdgeData, "edgedata tag thingies");
- BLI_array_set_length(etags, cddm->numEdgeData);
-
- mvert = cddm->getVertArray(cddm);
- BLI_array_set_length(mvert, cddm->numVertData);
- medge = cddm->getEdgeArray(cddm);
- BLI_array_set_length(medge, cddm->numEdgeData);
- mloop = CustomData_get_layer(&cddm->loopData, CD_MLOOP);
- mpoly = CustomData_get_layer(&cddm->polyData, CD_MPOLY);
-
- for (i=0; i<cddm->numEdgeData; i++) {
- etags[i].v1 = medge[i].v1;
- etags[i].v2 = medge[i].v2;
-
- etags[i].tag = (medge[i].flag & ME_SHARP) != 0;
-
- etags[i].v1node.edge = etags+i;
- etags[i].v2node.edge = etags+i;
- }
-
- if (emd->flags & MOD_EDGESPLIT_FROMANGLE) {
- mp = mpoly;
- for (i=0; i<cddm->numPolyData; i++, mp++) {
- mesh_calc_poly_normal(mp, mloop+mp->loopstart, mvert, no);
-
- ml = mloop + mp->loopstart;
- for (j=0; j<mp->totloop; j++, ml++) {
- if (!etags[ml->e].has_fno) {
- VECCOPY(etags[ml->e].fno, no);
- etags[ml->e].has_fno = 1;
- } else if (!etags[ml->e].tag) {
- edge_angle_cos = INPR(etags[ml->e].fno, no);
- if (edge_angle_cos < threshold) {
- etags[ml->e].tag = 1;
- }
- }
- }
- }
- }
-
- mp = mpoly;
- for (i=0; i<cddm->numPolyData; i++, mp++) {
- ml = mloop + mp->loopstart;
- for (j=0; j<mp->totloop; j++, ml++) {
- if (etags[ml->e].tag)
- continue;
-
- prevl = mloop + mp->loopstart + ((j-1)+mp->totloop) % mp->totloop;
-
- if (!edge_get_vuser(membase, etags+prevl->e, ml->v)) {
- vu = new_vuser(membase);
- vu->ov = vu->v = ml->v;
- edge_set_vuser(membase, etags+prevl->e, ml->v, vu);
- }
-
- if (!edge_get_vuser(membase, etags+ml->e, ml->v)) {
- vu = new_vuser(membase);
- vu->ov = vu->v = ml->v;
- edge_set_vuser(membase, etags+ml->e, ml->v, vu);
- }
-
- /*continue if previous edge is tagged*/
- if (etags[prevl->e].tag)
- continue;
-
- /*merge together adjacent split vert users*/
- if (edge_get_vuser(membase, etags+prevl->e, ml->v)
- != edge_get_vuser(membase, etags+ml->e, ml->v))
- {
- vu = edge_get_vuser(membase, etags+prevl->e, ml->v);
- vu2 = edge_get_vuser(membase, etags+ml->e, ml->v);
-
- /*remove from vu2's users list and add to vu's*/
- for (e=edge_get_first(vu2); e; e=enext) {
- enext = edge_get_next(e, ml->v);
- edge_set_vuser(membase, e, ml->v, vu);
- }
- }
- }
- }
-
- mp = mpoly;
- for (i=0; i<cddm->numPolyData; i++, mp++) {
- ml = mloop + mp->loopstart;
- for (j=0; j<mp->totloop; j++, ml++) {
- if (!etags[ml->e].tag)
- continue;
-
- prevl = mloop + mp->loopstart + ((j-1)+mp->totloop) % mp->totloop;
-
- if (!etags[prevl->e].tag) {
- vu = edge_get_vuser(membase, etags+prevl->e, ml->v);
- if (!vu) {
- vu = new_vuser(membase);
- vu->ov = vu->v = ml->v;
- edge_set_vuser(membase, etags+prevl->e, ml->v, vu);
- }
-
- edge_set_vuser(membase, etags+ml->e, ml->v, vu);
- } else {
- vu = new_vuser(membase);
- vu->ov = vu->v = ml->v;
- edge_set_vuser(membase, etags+ml->e, ml->v, vu);
- }
- }
- }
-
- curv = cddm->numVertData;
- cure = cddm->numEdgeData;
- mp = mpoly;
- for (i=0; i<cddm->numPolyData; i++, mp++) {
- ml = mloop + mp->loopstart;
- for (j=0; j<mp->totloop; j++, ml++) {
- e = etags + ml->e;
- if (e->v1user && !e->v1user->done) {
- e->v1user->done = 1;
- BLI_array_growone(mvert);
-
- mvert[curv] = mvert[e->v1user->ov];
- e->v1user->v = curv;
-
- curv++;
- }
-
- if (e->v2user && !e->v2user->done) {
- e->v2user->done = 1;
- BLI_array_growone(mvert);
-
- mvert[curv] = mvert[e->v2user->ov];
- e->v2user->v = curv;
-
- curv++;
- }
-
- vu = edge_get_vuser(membase, e, ml->v);
- if (!vu)
- continue;
- ml->v = vu->v;
-
-#if 0 //BMESH_TODO should really handle edges here, but for now use cddm_calc_edges
- /*ok, now we have to deal with edges. . .*/
- if (etags[ml->e].tag) {
- if (etags[ml->e].used) {
- BLI_array_growone(medge);
- BLI_array_growone(etags);
- medge[cure] = medge[ml->e];
-
- ml->e = cure;
- etags[cure].used = 1;
- cure++;
- }
-
- vu = etags[ml->e].v1user;
- vu2 = etags[ml->e].v2user;
-
- if (vu)
- medge[ml->e].v1 = vu->v;
- if (vu2)
- medge[ml->e].v2 = vu2->v;
- } else {
- etags[ml->e].used = 1;
-
- if (vu->ov == etags[ml->e].v1)
- medge[ml->e].v1 = vu->v;
- else if (vu->ov == etags[ml->e].v2)
- medge[ml->e].v2 = vu->v;
- }
-#endif
- }
- }
-
-
- /*resize customdata arrays and add new medge/mvert arrays*/
- vdata = cddm->vertData;
- edata = cddm->edgeData;
-
- /*make sure we don't copy over mvert/medge layers*/
- CustomData_set_layer(&vdata, CD_MVERT, NULL);
- CustomData_set_layer(&edata, CD_MEDGE, NULL);
- CustomData_free_layer_active(&vdata, CD_MVERT, cddm->numVertData);
- CustomData_free_layer_active(&edata, CD_MEDGE, cddm->numEdgeData);
-
- memset(&cddm->vertData, 0, sizeof(CustomData));
- memset(&cddm->edgeData, 0, sizeof(CustomData));
-
- CustomData_copy(&vdata, &cddm->vertData, CD_MASK_DERIVEDMESH, CD_CALLOC, curv);
- CustomData_copy_data(&vdata, &cddm->vertData, 0, 0, cddm->numVertData);
- CustomData_free(&vdata, cddm->numVertData);
- cddm->numVertData = curv;
-
- CustomData_copy(&edata, &cddm->edgeData, CD_MASK_DERIVEDMESH, CD_CALLOC, cure);
- CustomData_copy_data(&edata, &cddm->edgeData, 0, 0, cddm->numEdgeData);
- CustomData_free(&edata, cddm->numEdgeData);
- cddm->numEdgeData = cure;
-
- CDDM_set_mvert(cddm, mvert);
- CDDM_set_medge(cddm, medge);
-
- free_membase(membase);
- MEM_freeN(etags);
-
- /*edge calculation isn't working correctly, so just brute force it*/
- cddm->numEdgeData = 0;
- CDDM_calc_edges_poly(cddm);
-
- cddm->numFaceData = mesh_recalcTesselation(&cddm->faceData,
- &cddm->loopData, &cddm->polyData,
- mvert, cddm->numFaceData,
- cddm->numLoopData, cddm->numPolyData, 1, 0);
-
- CDDM_set_mface(cddm, DM_get_tessface_data_layer(cddm, CD_MFACE));
- CDDM_calc_normals(cddm);
-
- return cddm;
-}
-
-
-static void edgesplitModifier_initData(ModifierData *md)
-{
- EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md;
-
- /* default to 30-degree split angle, sharpness from both angle & flag
- */
- emd->split_angle = 30;
- emd->flags = MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG;
-}
-
-static void edgesplitModifier_copyData(ModifierData *md, ModifierData *target)
-{
- EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md;
- EdgeSplitModifierData *temd = (EdgeSplitModifierData*) target;
-
- temd->split_angle = emd->split_angle;
- temd->flags = emd->flags;
-}
-
-static DerivedMesh *edgesplitModifier_do(EdgeSplitModifierData *emd,
- Object *ob, DerivedMesh *dm)
-{
- if(!(emd->flags & (MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG)))
- return dm;
-
- return doEdgeSplit(dm, emd);
-}
-
-static DerivedMesh *edgesplitModifier_applyModifier(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- int useRenderParams, int isFinalCalc)
-{
- DerivedMesh *result;
- EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md;
-
- result = edgesplitModifier_do(emd, ob, derivedData);
-
- if(result != derivedData)
- CDDM_calc_normals(result);
-
- return result;
-}
-
-static DerivedMesh *edgesplitModifier_applyModifierEM(
- ModifierData *md, Object *ob, BMEditMesh *editData,
- DerivedMesh *derivedData)
-{
- return edgesplitModifier_applyModifier(md, ob, derivedData, 0, 1);
-}
-
-/* Bevel */
-
-static void bevelModifier_initData(ModifierData *md)
-{
- BevelModifierData *bmd = (BevelModifierData*) md;
-
- bmd->value = 0.1f;
- bmd->res = 1;
- bmd->flags = 0;
- bmd->val_flags = 0;
- bmd->lim_flags = 0;
- bmd->e_flags = 0;
- bmd->bevel_angle = 30;
- bmd->defgrp_name[0] = '\0';
-}
-
-static void bevelModifier_copyData(ModifierData *md, ModifierData *target)
-{
- BevelModifierData *bmd = (BevelModifierData*) md;
- BevelModifierData *tbmd = (BevelModifierData*) target;
-
- tbmd->value = bmd->value;
- tbmd->res = bmd->res;
- tbmd->flags = bmd->flags;
- tbmd->val_flags = bmd->val_flags;
- tbmd->lim_flags = bmd->lim_flags;
- tbmd->e_flags = bmd->e_flags;
- tbmd->bevel_angle = bmd->bevel_angle;
- strncpy(tbmd->defgrp_name, bmd->defgrp_name, 32);
-}
-
-static CustomDataMask bevelModifier_requiredDataMask(Object *ob, ModifierData *md)
-{
- BevelModifierData *bmd = (BevelModifierData *)md;
- CustomDataMask dataMask = 0;
-
- /* ask for vertexgroups if we need them */
- if(bmd->defgrp_name[0]) dataMask |= (1 << CD_MDEFORMVERT);
-
- return dataMask;
-}
-
-static DerivedMesh *bevelModifier_applyModifier(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- int useRenderParams, int isFinalCalc)
-{
- DerivedMesh *result;
- //BME_Mesh *bm;
-
- /*bDeformGroup *def;*/
- int /*i,*/ options, defgrp_index = -1;
- BevelModifierData *bmd = (BevelModifierData*) md;
-
- options = bmd->flags|bmd->val_flags|bmd->lim_flags|bmd->e_flags;
-
- /*if ((options & BME_BEVEL_VWEIGHT) && bmd->defgrp_name[0]) {
- defgrp_index = defgroup_name_index(ob, bmd->defgrp_name);
- if (defgrp_index < 0) {
- options &= ~BME_BEVEL_VWEIGHT;
- }
- }*/
-/*
- bm = BME_derivedmesh_to_bmesh(derivedData);
- BME_bevel(bm,bmd->value,bmd->res,options,defgrp_index,bmd->bevel_angle,NULL);
- result = BME_bmesh_to_derivedmesh(bm,derivedData);
- BME_free_mesh(bm);
-
- CDDM_calc_normals(result);
-*/
- result = derivedData;
- return result;
-}
-
-static DerivedMesh *bevelModifier_applyModifierEM(
- ModifierData *md, Object *ob, BMEditMesh *editData,
- DerivedMesh *derivedData)
-{
- return bevelModifier_applyModifier(md, ob, derivedData, 0, 1);
-}
-
-/* Displace */
-
-static void displaceModifier_initData(ModifierData *md)
-{
- DisplaceModifierData *dmd = (DisplaceModifierData*) md;
-
- dmd->texture = NULL;
- dmd->strength = 1;
- dmd->direction = MOD_DISP_DIR_NOR;
- dmd->midlevel = 0.5;
-}
-
-static void displaceModifier_copyData(ModifierData *md, ModifierData *target)
-{
- DisplaceModifierData *dmd = (DisplaceModifierData*) md;
- DisplaceModifierData *tdmd = (DisplaceModifierData*) target;
-
- tdmd->texture = dmd->texture;
- tdmd->strength = dmd->strength;
- tdmd->direction = dmd->direction;
- strncpy(tdmd->defgrp_name, dmd->defgrp_name, 32);
- tdmd->midlevel = dmd->midlevel;
- tdmd->texmapping = dmd->texmapping;
- tdmd->map_object = dmd->map_object;
- strncpy(tdmd->uvlayer_name, dmd->uvlayer_name, 32);
-}
-
-static CustomDataMask displaceModifier_requiredDataMask(Object *ob, ModifierData *md)
-{
- DisplaceModifierData *dmd = (DisplaceModifierData *)md;
- CustomDataMask dataMask = 0;
-
- /* ask for vertexgroups if we need them */
- if(dmd->defgrp_name[0]) dataMask |= (1 << CD_MDEFORMVERT);
-
- /* ask for UV coordinates if we need them */
- if(dmd->texmapping == MOD_DISP_MAP_UV) dataMask |= (1 << CD_MTFACE);
-
- return dataMask;
-}
-
-static int displaceModifier_dependsOnTime(ModifierData *md)
-{
- DisplaceModifierData *dmd = (DisplaceModifierData *)md;
-
- if(dmd->texture)
- {
- return BKE_texture_dependsOnTime(dmd->texture);
- }
- else
- {
- return 0;
- }
-}
-static void displaceModifier_foreachObjectLink(ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
-{
- DisplaceModifierData *dmd = (DisplaceModifierData*) md;
-
- walk(userData, ob, &dmd->map_object);
-}
-
-static void displaceModifier_foreachIDLink(ModifierData *md, Object *ob,
- IDWalkFunc walk, void *userData)
-{
- DisplaceModifierData *dmd = (DisplaceModifierData*) md;
-
- walk(userData, ob, (ID **)&dmd->texture);
-
- displaceModifier_foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
-}
-
-static int displaceModifier_isDisabled(ModifierData *md, int useRenderParams)
-{
- DisplaceModifierData *dmd = (DisplaceModifierData*) md;
-
- return !dmd->texture;
-}
-
-static void displaceModifier_updateDepgraph(
- ModifierData *md, DagForest *forest, Scene *scene,
- Object *ob, DagNode *obNode)
-{
- DisplaceModifierData *dmd = (DisplaceModifierData*) md;
-
- if(dmd->map_object) {
- DagNode *curNode = dag_get_node(forest, dmd->map_object);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Displace Modifier");
- }
-}
-
-static void validate_layer_name(const CustomData *data, int type, char *name, char *outname)
-{
- int index = -1;
-
- /* if a layer name was given, try to find that layer */
- if(name[0])
- index = CustomData_get_named_layer_index(data, CD_MTFACE, name);
-
- if(index < 0) {
- /* either no layer was specified, or the layer we want has been
- * deleted, so assign the active layer to name
- */
- index = CustomData_get_active_layer_index(data, CD_MTFACE);
- strcpy(outname, data->layers[index].name);
- }
- else
- strcpy(outname, name);
-}
-
-static void get_texture_coords(DisplaceModifierData *dmd, Object *ob,
- DerivedMesh *dm,
- float (*co)[3], float (*texco)[3],
- int numVerts)
-{
- int i;
- int texmapping = dmd->texmapping;
- float mapob_imat[4][4];
-
- if(texmapping == MOD_DISP_MAP_OBJECT) {
- if(dmd->map_object)
- invert_m4_m4(mapob_imat, dmd->map_object->obmat);
- else /* if there is no map object, default to local */
- texmapping = MOD_DISP_MAP_LOCAL;
- }
-
- /* UVs need special handling, since they come from faces */
- if(texmapping == MOD_DISP_MAP_UV) {
- if(CustomData_has_layer(&dm->faceData, CD_MTFACE)) {
- MFace *mface = dm->getTessFaceArray(dm);
- MFace *mf;
- char *done = MEM_callocN(sizeof(*done) * numVerts,
- "get_texture_coords done");
- int numFaces = dm->getNumTessFaces(dm);
- char uvname[32];
- MTFace *tf;
-
- validate_layer_name(&dm->faceData, CD_MTFACE, dmd->uvlayer_name, uvname);
- tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
-
- /* verts are given the UV from the first face that uses them */
- for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
- if(!done[mf->v1]) {
- texco[mf->v1][0] = tf->uv[0][0];
- texco[mf->v1][1] = tf->uv[0][1];
- texco[mf->v1][2] = 0;
- done[mf->v1] = 1;
- }
- if(!done[mf->v2]) {
- texco[mf->v2][0] = tf->uv[1][0];
- texco[mf->v2][1] = tf->uv[1][1];
- texco[mf->v2][2] = 0;
- done[mf->v2] = 1;
- }
- if(!done[mf->v3]) {
- texco[mf->v3][0] = tf->uv[2][0];
- texco[mf->v3][1] = tf->uv[2][1];
- texco[mf->v3][2] = 0;
- done[mf->v3] = 1;
- }
- if(!done[mf->v4]) {
- texco[mf->v4][0] = tf->uv[3][0];
- texco[mf->v4][1] = tf->uv[3][1];
- texco[mf->v4][2] = 0;
- done[mf->v4] = 1;
- }
- }
-
- /* remap UVs from [0, 1] to [-1, 1] */
- for(i = 0; i < numVerts; ++i) {
- texco[i][0] = texco[i][0] * 2 - 1;
- texco[i][1] = texco[i][1] * 2 - 1;
- }
-
- MEM_freeN(done);
- return;
- } else /* if there are no UVs, default to local */
- texmapping = MOD_DISP_MAP_LOCAL;
- }
-
- for(i = 0; i < numVerts; ++i, ++co, ++texco) {
- switch(texmapping) {
- case MOD_DISP_MAP_LOCAL:
- VECCOPY(*texco, *co);
- break;
- case MOD_DISP_MAP_GLOBAL:
- VECCOPY(*texco, *co);
- mul_m4_v3(ob->obmat, *texco);
- break;
- case MOD_DISP_MAP_OBJECT:
- VECCOPY(*texco, *co);
- mul_m4_v3(ob->obmat, *texco);
- mul_m4_v3(mapob_imat, *texco);
- break;
- }
- }
-}
-
-static void get_texture_value(Tex *texture, float *tex_co, TexResult *texres)
-{
- int result_type;
-
- result_type = multitex_ext(texture, tex_co, NULL,
- NULL, 1, texres);
-
- /* if the texture gave an RGB value, we assume it didn't give a valid
- * intensity, so calculate one (formula from do_material_tex).
- * if the texture didn't give an RGB value, copy the intensity across
- */
- if(result_type & TEX_RGB)
- texres->tin = (0.35f * texres->tr + 0.45f * texres->tg
- + 0.2f * texres->tb);
- else
- texres->tr = texres->tg = texres->tb = texres->tin;
-}
-
-/* dm must be a CDDerivedMesh */
-static void displaceModifier_do(
- DisplaceModifierData *dmd, Object *ob,
- DerivedMesh *dm, float (*vertexCos)[3], int numVerts)
-{
- int i;
- MVert *mvert;
- MDeformVert *dvert = NULL;
- int defgrp_index;
- float (*tex_co)[3];
-
- if(!dmd->texture) return;
-
- defgrp_index = defgroup_name_index(ob, dmd->defgrp_name);
-
- mvert = CDDM_get_verts(dm);
- if(defgrp_index >= 0)
- dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
-
- tex_co = MEM_callocN(sizeof(*tex_co) * numVerts,
- "displaceModifier_do tex_co");
- get_texture_coords(dmd, ob, dm, vertexCos, tex_co, numVerts);
-
- for(i = 0; i < numVerts; ++i) {
- TexResult texres;
- float delta = 0, strength = dmd->strength;
- MDeformWeight *def_weight = NULL;
-
- if(dvert) {
- int j;
- for(j = 0; j < dvert[i].totweight; ++j) {
- if(dvert[i].dw[j].def_nr == defgrp_index) {
- def_weight = &dvert[i].dw[j];
- break;
- }
- }
- if(!def_weight) continue;
- }
-
- texres.nor = NULL;
- get_texture_value(dmd->texture, tex_co[i], &texres);
-
- delta = texres.tin - dmd->midlevel;
-
- if(def_weight) strength *= def_weight->weight;
-
- delta *= strength;
-
- switch(dmd->direction) {
- case MOD_DISP_DIR_X:
- vertexCos[i][0] += delta;
- break;
- case MOD_DISP_DIR_Y:
- vertexCos[i][1] += delta;
- break;
- case MOD_DISP_DIR_Z:
- vertexCos[i][2] += delta;
- break;
- case MOD_DISP_DIR_RGB_XYZ:
- vertexCos[i][0] += (texres.tr - dmd->midlevel) * strength;
- vertexCos[i][1] += (texres.tg - dmd->midlevel) * strength;
- vertexCos[i][2] += (texres.tb - dmd->midlevel) * strength;
- break;
- case MOD_DISP_DIR_NOR:
- vertexCos[i][0] += delta * mvert[i].no[0] / 32767.0f;
- vertexCos[i][1] += delta * mvert[i].no[1] / 32767.0f;
- vertexCos[i][2] += delta * mvert[i].no[2] / 32767.0f;
- break;
- }
- }
-
- MEM_freeN(tex_co);
-}
-
-static void displaceModifier_deformVerts(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
-{
- DerivedMesh *dm= get_cddm(md->scene, ob, NULL, derivedData, vertexCos);
-
- displaceModifier_do((DisplaceModifierData *)md, ob, dm,
- vertexCos, numVerts);
-
- if(dm != derivedData)
- dm->release(dm);
-}
-
-static void displaceModifier_deformVertsEM(
- ModifierData *md, Object *ob, BMEditMesh *editData,
- DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
-{
- DerivedMesh *dm= get_cddm(md->scene, ob, editData, derivedData, vertexCos);
-
- displaceModifier_do((DisplaceModifierData *)md, ob, dm,
- vertexCos, numVerts);
+#include "MOD_modifiertypes.h"
- if(dm != derivedData)
- dm->release(dm);
-}
-
-/* UVProject */
-/* UV Project modifier: Generates UVs projected from an object
-*/
-
-static void uvprojectModifier_initData(ModifierData *md)
-{
- UVProjectModifierData *umd = (UVProjectModifierData*) md;
- int i;
-
- for(i = 0; i < MOD_UVPROJECT_MAXPROJECTORS; ++i)
- umd->projectors[i] = NULL;
- umd->image = NULL;
- umd->flags = 0;
- umd->num_projectors = 1;
- umd->aspectx = umd->aspecty = 1.0f;
-}
-
-static void uvprojectModifier_copyData(ModifierData *md, ModifierData *target)
-{
- UVProjectModifierData *umd = (UVProjectModifierData*) md;
- UVProjectModifierData *tumd = (UVProjectModifierData*) target;
- int i;
-
- for(i = 0; i < MOD_UVPROJECT_MAXPROJECTORS; ++i)
- tumd->projectors[i] = umd->projectors[i];
- tumd->image = umd->image;
- tumd->flags = umd->flags;
- tumd->num_projectors = umd->num_projectors;
- tumd->aspectx = umd->aspectx;
- tumd->aspecty = umd->aspecty;
-}
-
-static CustomDataMask uvprojectModifier_requiredDataMask(Object *ob, ModifierData *md)
-{
- CustomDataMask dataMask = 0;
-
- /* ask for UV coordinates */
- dataMask |= (1 << CD_MTFACE);
-
- return dataMask;
-}
-
-static void uvprojectModifier_foreachObjectLink(ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
-{
- UVProjectModifierData *umd = (UVProjectModifierData*) md;
- int i;
-
- for(i = 0; i < MOD_UVPROJECT_MAXPROJECTORS; ++i)
- walk(userData, ob, &umd->projectors[i]);
-}
-
-static void uvprojectModifier_foreachIDLink(ModifierData *md, Object *ob,
- IDWalkFunc walk, void *userData)
-{
- UVProjectModifierData *umd = (UVProjectModifierData*) md;
-
- walk(userData, ob, (ID **)&umd->image);
-
- uvprojectModifier_foreachObjectLink(md, ob, (ObjectWalkFunc)walk,
- userData);
-}
-
-static void uvprojectModifier_updateDepgraph(ModifierData *md,
- DagForest *forest, Scene *scene, Object *ob, DagNode *obNode)
-{
- UVProjectModifierData *umd = (UVProjectModifierData*) md;
- int i;
-
- for(i = 0; i < umd->num_projectors; ++i) {
- if(umd->projectors[i]) {
- DagNode *curNode = dag_get_node(forest, umd->projectors[i]);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "UV Project Modifier");
- }
- }
-}
-
-typedef struct Projector {
- Object *ob; /* object this projector is derived from */
- float projmat[4][4]; /* projection matrix */
- float normal[3]; /* projector normal in world space */
-} Projector;
-
-static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
- Object *ob, DerivedMesh *dm)
-{
- float (*coords)[3], (*co)[3];
- MTFace *tface;
- int i, numVerts, numFaces;
- Image *image = umd->image;
- MFace *mface, *mf;
- int override_image = ((umd->flags & MOD_UVPROJECT_OVERRIDEIMAGE) != 0);
- Projector projectors[MOD_UVPROJECT_MAXPROJECTORS];
- int num_projectors = 0;
- float aspect;
- char uvname[32];
-
- if(umd->aspecty != 0) aspect = umd->aspectx / umd->aspecty;
- else aspect = 1.0f;
-
- for(i = 0; i < umd->num_projectors; ++i)
- if(umd->projectors[i])
- projectors[num_projectors++].ob = umd->projectors[i];
-
- if(num_projectors == 0) return dm;
-
- /* make sure there are UV layers available */
- if(!CustomData_has_layer(&dm->faceData, CD_MTFACE)) return dm;
-
- /* make sure we're using an existing layer */
- validate_layer_name(&dm->faceData, CD_MTFACE, umd->uvlayer_name, uvname);
-
- /* make sure we are not modifying the original UV layer */
- tface = CustomData_duplicate_referenced_layer_named(&dm->faceData,
- CD_MTFACE, uvname);
-
- numVerts = dm->getNumVerts(dm);
-
- coords = MEM_callocN(sizeof(*coords) * numVerts,
- "uvprojectModifier_do coords");
- dm->getVertCos(dm, coords);
-
- /* convert coords to world space */
- for(i = 0, co = coords; i < numVerts; ++i, ++co)
- mul_m4_v3(ob->obmat, *co);
-
- /* calculate a projection matrix and normal for each projector */
- for(i = 0; i < num_projectors; ++i) {
- float tmpmat[4][4];
- float offsetmat[4][4];
- Camera *cam = NULL;
- /* calculate projection matrix */
- invert_m4_m4(projectors[i].projmat, projectors[i].ob->obmat);
-
- if(projectors[i].ob->type == OB_CAMERA) {
- cam = (Camera *)projectors[i].ob->data;
- if(cam->type == CAM_PERSP) {
- float perspmat[4][4];
- float xmax;
- float xmin;
- float ymax;
- float ymin;
- float pixsize = cam->clipsta * 32.0 / cam->lens;
-
- if(aspect > 1.0f) {
- xmax = 0.5f * pixsize;
- ymax = xmax / aspect;
- } else {
- ymax = 0.5f * pixsize;
- xmax = ymax * aspect;
- }
- xmin = -xmax;
- ymin = -ymax;
-
- perspective_m4( perspmat,xmin, xmax, ymin, ymax, cam->clipsta, cam->clipend);
- mul_m4_m4m4(tmpmat, projectors[i].projmat, perspmat);
- } else if(cam->type == CAM_ORTHO) {
- float orthomat[4][4];
- float xmax;
- float xmin;
- float ymax;
- float ymin;
-
- if(aspect > 1.0f) {
- xmax = 0.5f * cam->ortho_scale;
- ymax = xmax / aspect;
- } else {
- ymax = 0.5f * cam->ortho_scale;
- xmax = ymax * aspect;
- }
- xmin = -xmax;
- ymin = -ymax;
-
- orthographic_m4( orthomat,xmin, xmax, ymin, ymax, cam->clipsta, cam->clipend);
- mul_m4_m4m4(tmpmat, projectors[i].projmat, orthomat);
- }
- } else {
- copy_m4_m4(tmpmat, projectors[i].projmat);
- }
-
- unit_m4(offsetmat);
- mul_mat3_m4_fl(offsetmat, 0.5);
- offsetmat[3][0] = offsetmat[3][1] = offsetmat[3][2] = 0.5;
-
- if (cam) {
- if (umd->aspectx == umd->aspecty) {
- offsetmat[3][0] -= cam->shiftx;
- offsetmat[3][1] -= cam->shifty;
- } else if (umd->aspectx < umd->aspecty) {
- offsetmat[3][0] -=(cam->shiftx * umd->aspecty/umd->aspectx);
- offsetmat[3][1] -= cam->shifty;
- } else {
- offsetmat[3][0] -= cam->shiftx;
- offsetmat[3][1] -=(cam->shifty * umd->aspectx/umd->aspecty);
- }
- }
-
- mul_m4_m4m4(projectors[i].projmat, tmpmat, offsetmat);
-
- /* calculate worldspace projector normal (for best projector test) */
- projectors[i].normal[0] = 0;
- projectors[i].normal[1] = 0;
- projectors[i].normal[2] = 1;
- mul_mat3_m4_v3(projectors[i].ob->obmat, projectors[i].normal);
- }
-
- /* if only one projector, project coords to UVs */
- if(num_projectors == 1)
- for(i = 0, co = coords; i < numVerts; ++i, ++co)
- mul_project_m4_v4(projectors[0].projmat, *co);
-
- mface = dm->getTessFaceArray(dm);
- numFaces = dm->getNumTessFaces(dm);
-
- /* apply coords as UVs, and apply image if tfaces are new */
- for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tface) {
- if(override_image || !image || tface->tpage == image) {
- if(num_projectors == 1) {
- /* apply transformed coords as UVs */
- tface->uv[0][0] = coords[mf->v1][0];
- tface->uv[0][1] = coords[mf->v1][1];
- tface->uv[1][0] = coords[mf->v2][0];
- tface->uv[1][1] = coords[mf->v2][1];
- tface->uv[2][0] = coords[mf->v3][0];
- tface->uv[2][1] = coords[mf->v3][1];
- if(mf->v4) {
- tface->uv[3][0] = coords[mf->v4][0];
- tface->uv[3][1] = coords[mf->v4][1];
- }
- } else {
- /* multiple projectors, select the closest to face normal
- * direction
- */
- float co1[3], co2[3], co3[3], co4[3];
- float face_no[3];
- int j;
- Projector *best_projector;
- float best_dot;
-
- VECCOPY(co1, coords[mf->v1]);
- VECCOPY(co2, coords[mf->v2]);
- VECCOPY(co3, coords[mf->v3]);
-
- /* get the untransformed face normal */
- if(mf->v4) {
- VECCOPY(co4, coords[mf->v4]);
- normal_quad_v3( face_no,co1, co2, co3, co4);
- } else {
- normal_tri_v3( face_no,co1, co2, co3);
- }
-
- /* find the projector which the face points at most directly
- * (projector normal with largest dot product is best)
- */
- best_dot = dot_v3v3(projectors[0].normal, face_no);
- best_projector = &projectors[0];
-
- for(j = 1; j < num_projectors; ++j) {
- float tmp_dot = dot_v3v3(projectors[j].normal,
- face_no);
- if(tmp_dot > best_dot) {
- best_dot = tmp_dot;
- best_projector = &projectors[j];
- }
- }
-
- mul_project_m4_v4(best_projector->projmat, co1);
- mul_project_m4_v4(best_projector->projmat, co2);
- mul_project_m4_v4(best_projector->projmat, co3);
- if(mf->v4)
- mul_project_m4_v4(best_projector->projmat, co4);
-
- /* apply transformed coords as UVs */
- tface->uv[0][0] = co1[0];
- tface->uv[0][1] = co1[1];
- tface->uv[1][0] = co2[0];
- tface->uv[1][1] = co2[1];
- tface->uv[2][0] = co3[0];
- tface->uv[2][1] = co3[1];
- if(mf->v4) {
- tface->uv[3][0] = co4[0];
- tface->uv[3][1] = co4[1];
- }
- }
- }
-
- if(override_image) {
- tface->mode = TF_TEX;
- tface->tpage = image;
- }
- }
-
- MEM_freeN(coords);
-
- return dm;
-}
-
-static DerivedMesh *uvprojectModifier_applyModifier(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- int useRenderParams, int isFinalCalc)
-{
- DerivedMesh *result;
- UVProjectModifierData *umd = (UVProjectModifierData*) md;
-
- result = uvprojectModifier_do(umd, ob, derivedData);
-
- return result;
-}
-
-static DerivedMesh *uvprojectModifier_applyModifierEM(
- ModifierData *md, Object *ob, BMEditMesh *editData,
- DerivedMesh *derivedData)
-{
- return uvprojectModifier_applyModifier(md, ob, derivedData, 0, 1);
-}
-
-/* Decimate */
-
-static void decimateModifier_initData(ModifierData *md)
-{
- DecimateModifierData *dmd = (DecimateModifierData*) md;
-
- dmd->percent = 1.0;
-}
-
-static void decimateModifier_copyData(ModifierData *md, ModifierData *target)
-{
- DecimateModifierData *dmd = (DecimateModifierData*) md;
- DecimateModifierData *tdmd = (DecimateModifierData*) target;
-
- tdmd->percent = dmd->percent;
-}
-
-static DerivedMesh *decimateModifier_applyModifier(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- int useRenderParams, int isFinalCalc)
-{
- DecimateModifierData *dmd = (DecimateModifierData*) md;
- DerivedMesh *dm = derivedData, *result = NULL;
- MVert *mvert;
- MFace *mface;
- LOD_Decimation_Info lod;
- int totvert, totface;
- int a, numTris;
-
- mvert = dm->getVertArray(dm);
- mface = dm->getTessFaceArray(dm);
- totvert = dm->getNumVerts(dm);
- totface = dm->getNumTessFaces(dm);
-
- numTris = 0;
- for (a=0; a<totface; a++) {
- MFace *mf = &mface[a];
- numTris++;
- if (mf->v4) numTris++;
- }
-
- if(numTris<3) {
- modifier_setError(md,
- "Modifier requires more than 3 input faces (triangles).");
- goto exit;
- }
-
- lod.vertex_buffer= MEM_mallocN(3*sizeof(float)*totvert, "vertices");
- lod.vertex_normal_buffer= MEM_mallocN(3*sizeof(float)*totvert, "normals");
- lod.triangle_index_buffer= MEM_mallocN(3*sizeof(int)*numTris, "trias");
- lod.vertex_num= totvert;
- lod.face_num= numTris;
-
- for(a=0; a<totvert; a++) {
- MVert *mv = &mvert[a];
- float *vbCo = &lod.vertex_buffer[a*3];
- float *vbNo = &lod.vertex_normal_buffer[a*3];
-
- VECCOPY(vbCo, mv->co);
-
- vbNo[0] = mv->no[0]/32767.0f;
- vbNo[1] = mv->no[1]/32767.0f;
- vbNo[2] = mv->no[2]/32767.0f;
- }
-
- numTris = 0;
- for(a=0; a<totface; a++) {
- MFace *mf = &mface[a];
- int *tri = &lod.triangle_index_buffer[3*numTris++];
- tri[0]= mf->v1;
- tri[1]= mf->v2;
- tri[2]= mf->v3;
-
- if(mf->v4) {
- tri = &lod.triangle_index_buffer[3*numTris++];
- tri[0]= mf->v1;
- tri[1]= mf->v3;
- tri[2]= mf->v4;
- }
- }
-
- dmd->faceCount = 0;
- if(LOD_LoadMesh(&lod) ) {
- if( LOD_PreprocessMesh(&lod) ) {
- /* we assume the decim_faces tells how much to reduce */
-
- while(lod.face_num > numTris*dmd->percent) {
- if( LOD_CollapseEdge(&lod)==0) break;
- }
-
- if(lod.vertex_num>2) {
- result = CDDM_new(lod.vertex_num, 0, lod.face_num, 0, 0);
- dmd->faceCount = lod.face_num;
- }
- else
- result = CDDM_new(lod.vertex_num, 0, 0, 0, 0);
-
- mvert = CDDM_get_verts(result);
- for(a=0; a<lod.vertex_num; a++) {
- MVert *mv = &mvert[a];
- float *vbCo = &lod.vertex_buffer[a*3];
-
- VECCOPY(mv->co, vbCo);
- }
-
- if(lod.vertex_num>2) {
- mface = CDDM_get_tessfaces(result);
- for(a=0; a<lod.face_num; a++) {
- MFace *mf = &mface[a];
- int *tri = &lod.triangle_index_buffer[a*3];
- mf->v1 = tri[0];
- mf->v2 = tri[1];
- mf->v3 = tri[2];
- test_index_face(mf, NULL, 0, 3);
- }
- }
-
- CDDM_calc_edges(result);
- CDDM_calc_normals(result);
- CDDM_tessfaces_to_faces(result);
- }
- else
- modifier_setError(md, "Out of memory.");
-
- LOD_FreeDecimationData(&lod);
- }
- else
- modifier_setError(md, "Non-manifold mesh as input.");
-
- MEM_freeN(lod.vertex_buffer);
- MEM_freeN(lod.vertex_normal_buffer);
- MEM_freeN(lod.triangle_index_buffer);
-
-exit:
- return result;
-}
-
-/* Smooth */
-
-static void smoothModifier_initData(ModifierData *md)
-{
- SmoothModifierData *smd = (SmoothModifierData*) md;
-
- smd->fac = 0.5f;
- smd->repeat = 1;
- smd->flag = MOD_SMOOTH_X | MOD_SMOOTH_Y | MOD_SMOOTH_Z;
- smd->defgrp_name[0] = '\0';
-}
-
-static void smoothModifier_copyData(ModifierData *md, ModifierData *target)
-{
- SmoothModifierData *smd = (SmoothModifierData*) md;
- SmoothModifierData *tsmd = (SmoothModifierData*) target;
-
- tsmd->fac = smd->fac;
- tsmd->repeat = smd->repeat;
- tsmd->flag = smd->flag;
- strncpy(tsmd->defgrp_name, smd->defgrp_name, 32);
-}
-
-static int smoothModifier_isDisabled(ModifierData *md, int useRenderParams)
-{
- SmoothModifierData *smd = (SmoothModifierData*) md;
- short flag;
-
- flag = smd->flag & (MOD_SMOOTH_X|MOD_SMOOTH_Y|MOD_SMOOTH_Z);
-
- /* disable if modifier is off for X, Y and Z or if factor is 0 */
- if((smd->fac == 0.0f) || flag == 0) return 1;
-
- return 0;
-}
-
-static CustomDataMask smoothModifier_requiredDataMask(Object *ob, ModifierData *md)
-{
- SmoothModifierData *smd = (SmoothModifierData *)md;
- CustomDataMask dataMask = 0;
-
- /* ask for vertexgroups if we need them */
- if(smd->defgrp_name[0]) dataMask |= (1 << CD_MDEFORMVERT);
-
- return dataMask;
-}
-
-static void smoothModifier_do(
- SmoothModifierData *smd, Object *ob, DerivedMesh *dm,
- float (*vertexCos)[3], int numVerts)
-{
- MDeformVert *dvert = NULL;
- MEdge *medges = NULL;
-
- int i, j, numDMEdges, defgrp_index;
- unsigned char *uctmp;
- float *ftmp, fac, facm;
-
- ftmp = (float*)MEM_callocN(3*sizeof(float)*numVerts,
- "smoothmodifier_f");
- if (!ftmp) return;
- uctmp = (unsigned char*)MEM_callocN(sizeof(unsigned char)*numVerts,
- "smoothmodifier_uc");
- if (!uctmp) {
- if (ftmp) MEM_freeN(ftmp);
- return;
- }
-
- fac = smd->fac;
- facm = 1 - fac;
-
- medges = dm->getEdgeArray(dm);
- numDMEdges = dm->getNumEdges(dm);
-
- defgrp_index = defgroup_name_index(ob, smd->defgrp_name);
-
- if (defgrp_index >= 0)
- dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
-
- /* NOTICE: this can be optimized a little bit by moving the
- * if (dvert) out of the loop, if needed */
- for (j = 0; j < smd->repeat; j++) {
- for (i = 0; i < numDMEdges; i++) {
- float fvec[3];
- float *v1, *v2;
- unsigned int idx1, idx2;
-
- idx1 = medges[i].v1;
- idx2 = medges[i].v2;
-
- v1 = vertexCos[idx1];
- v2 = vertexCos[idx2];
-
- fvec[0] = (v1[0] + v2[0]) / 2.0;
- fvec[1] = (v1[1] + v2[1]) / 2.0;
- fvec[2] = (v1[2] + v2[2]) / 2.0;
-
- v1 = &ftmp[idx1*3];
- v2 = &ftmp[idx2*3];
-
- if (uctmp[idx1] < 255) {
- uctmp[idx1]++;
- add_v3_v3v3(v1, v1, fvec);
- }
- if (uctmp[idx2] < 255) {
- uctmp[idx2]++;
- add_v3_v3v3(v2, v2, fvec);
- }
- }
-
- if (dvert) {
- for (i = 0; i < numVerts; i++) {
- MDeformWeight *dw = NULL;
- float f, fm, facw, *fp, *v;
- int k;
- short flag = smd->flag;
-
- v = vertexCos[i];
- fp = &ftmp[i*3];
-
- for (k = 0; k < dvert[i].totweight; ++k) {
- if(dvert[i].dw[k].def_nr == defgrp_index) {
- dw = &dvert[i].dw[k];
- break;
- }
- }
- if (!dw) continue;
-
- f = fac * dw->weight;
- fm = 1.0f - f;
-
- /* fp is the sum of uctmp[i] verts, so must be averaged */
- facw = 0.0f;
- if (uctmp[i])
- facw = f / (float)uctmp[i];
-
- if (flag & MOD_SMOOTH_X)
- v[0] = fm * v[0] + facw * fp[0];
- if (flag & MOD_SMOOTH_Y)
- v[1] = fm * v[1] + facw * fp[1];
- if (flag & MOD_SMOOTH_Z)
- v[2] = fm * v[2] + facw * fp[2];
- }
- }
- else { /* no vertex group */
- for (i = 0; i < numVerts; i++) {
- float facw, *fp, *v;
- short flag = smd->flag;
-
- v = vertexCos[i];
- fp = &ftmp[i*3];
-
- /* fp is the sum of uctmp[i] verts, so must be averaged */
- facw = 0.0f;
- if (uctmp[i])
- facw = fac / (float)uctmp[i];
-
- if (flag & MOD_SMOOTH_X)
- v[0] = facm * v[0] + facw * fp[0];
- if (flag & MOD_SMOOTH_Y)
- v[1] = facm * v[1] + facw * fp[1];
- if (flag & MOD_SMOOTH_Z)
- v[2] = facm * v[2] + facw * fp[2];
- }
-
- }
-
- memset(ftmp, 0, 3*sizeof(float)*numVerts);
- memset(uctmp, 0, sizeof(unsigned char)*numVerts);
- }
-
- MEM_freeN(ftmp);
- MEM_freeN(uctmp);
-}
-
-static void smoothModifier_deformVerts(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
-{
- DerivedMesh *dm= get_dm(md->scene, ob, NULL, derivedData, NULL, 0);
-
- smoothModifier_do((SmoothModifierData *)md, ob, dm,
- vertexCos, numVerts);
-
- if(dm != derivedData)
- dm->release(dm);
-}
-
-static void smoothModifier_deformVertsEM(
- ModifierData *md, Object *ob, BMEditMesh *editData,
- DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
-{
- DerivedMesh *dm= get_dm(md->scene, ob, editData, derivedData, NULL, 0);
-
- smoothModifier_do((SmoothModifierData *)md, ob, dm,
- vertexCos, numVerts);
-
- if(dm != derivedData)
- dm->release(dm);
-}
-
-/* Cast */
-
-static void castModifier_initData(ModifierData *md)
-{
- CastModifierData *cmd = (CastModifierData*) md;
-
- cmd->fac = 0.5f;
- cmd->radius = 0.0f;
- cmd->size = 0.0f;
- cmd->flag = MOD_CAST_X | MOD_CAST_Y | MOD_CAST_Z
- | MOD_CAST_SIZE_FROM_RADIUS;
- cmd->type = MOD_CAST_TYPE_SPHERE;
- cmd->defgrp_name[0] = '\0';
- cmd->object = NULL;
-}
-
-
-static void castModifier_copyData(ModifierData *md, ModifierData *target)
-{
- CastModifierData *cmd = (CastModifierData*) md;
- CastModifierData *tcmd = (CastModifierData*) target;
-
- tcmd->fac = cmd->fac;
- tcmd->radius = cmd->radius;
- tcmd->size = cmd->size;
- tcmd->flag = cmd->flag;
- tcmd->type = cmd->type;
- tcmd->object = cmd->object;
- strncpy(tcmd->defgrp_name, cmd->defgrp_name, 32);
-}
-
-static int castModifier_isDisabled(ModifierData *md, int useRenderParams)
-{
- CastModifierData *cmd = (CastModifierData*) md;
- short flag;
-
- flag = cmd->flag & (MOD_CAST_X|MOD_CAST_Y|MOD_CAST_Z);
-
- if((cmd->fac == 0.0f) || flag == 0) return 1;
-
- return 0;
-}
-
-static CustomDataMask castModifier_requiredDataMask(Object *ob, ModifierData *md)
-{
- CastModifierData *cmd = (CastModifierData *)md;
- CustomDataMask dataMask = 0;
-
- /* ask for vertexgroups if we need them */
- if(cmd->defgrp_name[0]) dataMask |= (1 << CD_MDEFORMVERT);
-
- return dataMask;
-}
-
-static void castModifier_foreachObjectLink(
- ModifierData *md, Object *ob,
- void (*walk)(void *userData, Object *ob, Object **obpoin),
- void *userData)
-{
- CastModifierData *cmd = (CastModifierData*) md;
-
- walk (userData, ob, &cmd->object);
-}
-
-static void castModifier_updateDepgraph(
- ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
- DagNode *obNode)
-{
- CastModifierData *cmd = (CastModifierData*) md;
-
- if (cmd->object) {
- DagNode *curNode = dag_get_node(forest, cmd->object);
-
- dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA,
- "Cast Modifier");
- }
-}
-
-static void castModifier_sphere_do(
- CastModifierData *cmd, Object *ob, DerivedMesh *dm,
- float (*vertexCos)[3], int numVerts)
-{
- MDeformVert *dvert = NULL;
-
- Object *ctrl_ob = NULL;
-
- int i, defgrp_index;
- int has_radius = 0;
- short flag, type;
- float fac, facm, len = 0.0f;
- float vec[3], center[3] = {0.0f, 0.0f, 0.0f};
- float mat[4][4], imat[4][4];
-
- fac = cmd->fac;
- facm = 1.0f - fac;
-
- flag = cmd->flag;
- type = cmd->type; /* projection type: sphere or cylinder */
-
- if (type == MOD_CAST_TYPE_CYLINDER)
- flag &= ~MOD_CAST_Z;
-
- ctrl_ob = cmd->object;
-
- /* spherify's center is {0, 0, 0} (the ob's own center in its local
- * space), by default, but if the user defined a control object,
- * we use its location, transformed to ob's local space */
- if (ctrl_ob) {
- if(flag & MOD_CAST_USE_OB_TRANSFORM) {
- invert_m4_m4(ctrl_ob->imat, ctrl_ob->obmat);
- mul_m4_m4m4(mat, ob->obmat, ctrl_ob->imat);
- invert_m4_m4(imat, mat);
- }
-
- invert_m4_m4(ob->imat, ob->obmat);
- VECCOPY(center, ctrl_ob->obmat[3]);
- mul_m4_v3(ob->imat, center);
- }
-
- /* now we check which options the user wants */
-
- /* 1) (flag was checked in the "if (ctrl_ob)" block above) */
- /* 2) cmd->radius > 0.0f: only the vertices within this radius from
- * the center of the effect should be deformed */
- if (cmd->radius > FLT_EPSILON) has_radius = 1;
-
- /* 3) if we were given a vertex group name,
- * only those vertices should be affected */
- defgrp_index = defgroup_name_index(ob, cmd->defgrp_name);
-
- if ((ob->type == OB_MESH) && dm && defgrp_index >= 0)
- dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
-
- if(flag & MOD_CAST_SIZE_FROM_RADIUS) {
- len = cmd->radius;
- }
- else {
- len = cmd->size;
- }
-
- if(len <= 0) {
- for (i = 0; i < numVerts; i++) {
- len += len_v3v3(center, vertexCos[i]);
- }
- len /= numVerts;
-
- if (len == 0.0f) len = 10.0f;
- }
-
- /* ready to apply the effect, one vertex at a time;
- * tiny optimization: the code is separated (with parts repeated)
- * in two possible cases:
- * with or w/o a vgroup. With lots of if's in the code below,
- * further optimizations are possible, if needed */
- if (dvert) { /* with a vgroup */
- float fac_orig = fac;
- for (i = 0; i < numVerts; i++) {
- MDeformWeight *dw = NULL;
- int j;
- float tmp_co[3];
-
- VECCOPY(tmp_co, vertexCos[i]);
- if(ctrl_ob) {
- if(flag & MOD_CAST_USE_OB_TRANSFORM) {
- mul_m4_v3(mat, tmp_co);
- } else {
- sub_v3_v3v3(tmp_co, tmp_co, center);
- }
- }
-
- VECCOPY(vec, tmp_co);
-
- if (type == MOD_CAST_TYPE_CYLINDER)
- vec[2] = 0.0f;
-
- if (has_radius) {
- if (len_v3(vec) > cmd->radius) continue;
- }
-
- for (j = 0; j < dvert[i].totweight; ++j) {
- if(dvert[i].dw[j].def_nr == defgrp_index) {
- dw = &dvert[i].dw[j];
- break;
- }
- }
- if (!dw) continue;
-
- fac = fac_orig * dw->weight;
- facm = 1.0f - fac;
-
- normalize_v3(vec);
-
- if (flag & MOD_CAST_X)
- tmp_co[0] = fac*vec[0]*len + facm*tmp_co[0];
- if (flag & MOD_CAST_Y)
- tmp_co[1] = fac*vec[1]*len + facm*tmp_co[1];
- if (flag & MOD_CAST_Z)
- tmp_co[2] = fac*vec[2]*len + facm*tmp_co[2];
-
- if(ctrl_ob) {
- if(flag & MOD_CAST_USE_OB_TRANSFORM) {
- mul_m4_v3(imat, tmp_co);
- } else {
- add_v3_v3v3(tmp_co, tmp_co, center);
- }
- }
-
- VECCOPY(vertexCos[i], tmp_co);
- }
- return;
- }
-
- /* no vgroup */
- for (i = 0; i < numVerts; i++) {
- float tmp_co[3];
-
- VECCOPY(tmp_co, vertexCos[i]);
- if(ctrl_ob) {
- if(flag & MOD_CAST_USE_OB_TRANSFORM) {
- mul_m4_v3(mat, tmp_co);
- } else {
- sub_v3_v3v3(tmp_co, tmp_co, center);
- }
- }
-
- VECCOPY(vec, tmp_co);
-
- if (type == MOD_CAST_TYPE_CYLINDER)
- vec[2] = 0.0f;
-
- if (has_radius) {
- if (len_v3(vec) > cmd->radius) continue;
- }
-
- normalize_v3(vec);
-
- if (flag & MOD_CAST_X)
- tmp_co[0] = fac*vec[0]*len + facm*tmp_co[0];
- if (flag & MOD_CAST_Y)
- tmp_co[1] = fac*vec[1]*len + facm*tmp_co[1];
- if (flag & MOD_CAST_Z)
- tmp_co[2] = fac*vec[2]*len + facm*tmp_co[2];
-
- if(ctrl_ob) {
- if(flag & MOD_CAST_USE_OB_TRANSFORM) {
- mul_m4_v3(imat, tmp_co);
- } else {
- add_v3_v3v3(tmp_co, tmp_co, center);
- }
- }
-
- VECCOPY(vertexCos[i], tmp_co);
- }
-}
-
-static void castModifier_cuboid_do(
- CastModifierData *cmd, Object *ob, DerivedMesh *dm,
- float (*vertexCos)[3], int numVerts)
-{
- MDeformVert *dvert = NULL;
- Object *ctrl_ob = NULL;
-
- int i, defgrp_index;
- int has_radius = 0;
- short flag;
- float fac, facm;
- float min[3], max[3], bb[8][3];
- float center[3] = {0.0f, 0.0f, 0.0f};
- float mat[4][4], imat[4][4];
-
- fac = cmd->fac;
- facm = 1.0f - fac;
-
- flag = cmd->flag;
-
- ctrl_ob = cmd->object;
-
- /* now we check which options the user wants */
-
- /* 1) (flag was checked in the "if (ctrl_ob)" block above) */
- /* 2) cmd->radius > 0.0f: only the vertices within this radius from
- * the center of the effect should be deformed */
- if (cmd->radius > FLT_EPSILON) has_radius = 1;
-
- /* 3) if we were given a vertex group name,
- * only those vertices should be affected */
- defgrp_index = defgroup_name_index(ob, cmd->defgrp_name);
-
- if ((ob->type == OB_MESH) && dm && defgrp_index >= 0)
- dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
-
- if (ctrl_ob) {
- if(flag & MOD_CAST_USE_OB_TRANSFORM) {
- invert_m4_m4(ctrl_ob->imat, ctrl_ob->obmat);
- mul_m4_m4m4(mat, ob->obmat, ctrl_ob->imat);
- invert_m4_m4(imat, mat);
- }
-
- invert_m4_m4(ob->imat, ob->obmat);
- VECCOPY(center, ctrl_ob->obmat[3]);
- mul_m4_v3(ob->imat, center);
- }
-
- if((flag & MOD_CAST_SIZE_FROM_RADIUS) && has_radius) {
- for(i = 0; i < 3; i++) {
- min[i] = -cmd->radius;
- max[i] = cmd->radius;
- }
- } else if(!(flag & MOD_CAST_SIZE_FROM_RADIUS) && cmd->size > 0) {
- for(i = 0; i < 3; i++) {
- min[i] = -cmd->size;
- max[i] = cmd->size;
- }
- } else {
- /* get bound box */
- /* We can't use the object's bound box because other modifiers
- * may have changed the vertex data. */
- INIT_MINMAX(min, max);
-
- /* Cast's center is the ob's own center in its local space,
- * by default, but if the user defined a control object, we use
- * its location, transformed to ob's local space. */
- if (ctrl_ob) {
- float vec[3];
-
- /* let the center of the ctrl_ob be part of the bound box: */
- DO_MINMAX(center, min, max);
-
- for (i = 0; i < numVerts; i++) {
- sub_v3_v3v3(vec, vertexCos[i], center);
- DO_MINMAX(vec, min, max);
- }
- }
- else {
- for (i = 0; i < numVerts; i++) {
- DO_MINMAX(vertexCos[i], min, max);
- }
- }
-
- /* we want a symmetric bound box around the origin */
- if (fabs(min[0]) > fabs(max[0])) max[0] = fabs(min[0]);
- if (fabs(min[1]) > fabs(max[1])) max[1] = fabs(min[1]);
- if (fabs(min[2]) > fabs(max[2])) max[2] = fabs(min[2]);
- min[0] = -max[0];
- min[1] = -max[1];
- min[2] = -max[2];
- }
-
- /* building our custom bounding box */
- bb[0][0] = bb[2][0] = bb[4][0] = bb[6][0] = min[0];
- bb[1][0] = bb[3][0] = bb[5][0] = bb[7][0] = max[0];
- bb[0][1] = bb[1][1] = bb[4][1] = bb[5][1] = min[1];
- bb[2][1] = bb[3][1] = bb[6][1] = bb[7][1] = max[1];
- bb[0][2] = bb[1][2] = bb[2][2] = bb[3][2] = min[2];
- bb[4][2] = bb[5][2] = bb[6][2] = bb[7][2] = max[2];
-
- /* ready to apply the effect, one vertex at a time;
- * tiny optimization: the code is separated (with parts repeated)
- * in two possible cases:
- * with or w/o a vgroup. With lots of if's in the code below,
- * further optimizations are possible, if needed */
- if (dvert) { /* with a vgroup */
- float fac_orig = fac;
- for (i = 0; i < numVerts; i++) {
- MDeformWeight *dw = NULL;
- int j, octant, coord;
- float d[3], dmax, apex[3], fbb;
- float tmp_co[3];
-
- VECCOPY(tmp_co, vertexCos[i]);
- if(ctrl_ob) {
- if(flag & MOD_CAST_USE_OB_TRANSFORM) {
- mul_m4_v3(mat, tmp_co);
- } else {
- sub_v3_v3v3(tmp_co, tmp_co, center);
- }
- }
-
- if (has_radius) {
- if (fabs(tmp_co[0]) > cmd->radius ||
- fabs(tmp_co[1]) > cmd->radius ||
- fabs(tmp_co[2]) > cmd->radius) continue;
- }
-
- for (j = 0; j < dvert[i].totweight; ++j) {
- if(dvert[i].dw[j].def_nr == defgrp_index) {
- dw = &dvert[i].dw[j];
- break;
- }
- }
- if (!dw) continue;
-
- fac = fac_orig * dw->weight;
- facm = 1.0f - fac;
-
- /* The algo used to project the vertices to their
- * bounding box (bb) is pretty simple:
- * for each vertex v:
- * 1) find in which octant v is in;
- * 2) find which outer "wall" of that octant is closer to v;
- * 3) calculate factor (var fbb) to project v to that wall;
- * 4) project. */
-
- /* find in which octant this vertex is in */
- octant = 0;
- if (tmp_co[0] > 0.0f) octant += 1;
- if (tmp_co[1] > 0.0f) octant += 2;
- if (tmp_co[2] > 0.0f) octant += 4;
-
- /* apex is the bb's vertex at the chosen octant */
- copy_v3_v3(apex, bb[octant]);
-
- /* find which bb plane is closest to this vertex ... */
- d[0] = tmp_co[0] / apex[0];
- d[1] = tmp_co[1] / apex[1];
- d[2] = tmp_co[2] / apex[2];
-
- /* ... (the closest has the higher (closer to 1) d value) */
- dmax = d[0];
- coord = 0;
- if (d[1] > dmax) {
- dmax = d[1];
- coord = 1;
- }
- if (d[2] > dmax) {
- /* dmax = d[2]; */ /* commented, we don't need it */
- coord = 2;
- }
-
- /* ok, now we know which coordinate of the vertex to use */
-
- if (fabs(tmp_co[coord]) < FLT_EPSILON) /* avoid division by zero */
- continue;
-
- /* finally, this is the factor we wanted, to project the vertex
- * to its bounding box (bb) */
- fbb = apex[coord] / tmp_co[coord];
-
- /* calculate the new vertex position */
- if (flag & MOD_CAST_X)
- tmp_co[0] = facm * tmp_co[0] + fac * tmp_co[0] * fbb;
- if (flag & MOD_CAST_Y)
- tmp_co[1] = facm * tmp_co[1] + fac * tmp_co[1] * fbb;
- if (flag & MOD_CAST_Z)
- tmp_co[2] = facm * tmp_co[2] + fac * tmp_co[2] * fbb;
-
- if(ctrl_ob) {
- if(flag & MOD_CAST_USE_OB_TRANSFORM) {
- mul_m4_v3(imat, tmp_co);
- } else {
- add_v3_v3v3(tmp_co, tmp_co, center);
- }
- }
-
- VECCOPY(vertexCos[i], tmp_co);
- }
- return;
- }
-
- /* no vgroup (check previous case for comments about the code) */
- for (i = 0; i < numVerts; i++) {
- int octant, coord;
- float d[3], dmax, fbb, apex[3];
- float tmp_co[3];
-
- VECCOPY(tmp_co, vertexCos[i]);
- if(ctrl_ob) {
- if(flag & MOD_CAST_USE_OB_TRANSFORM) {
- mul_m4_v3(mat, tmp_co);
- } else {
- sub_v3_v3v3(tmp_co, tmp_co, center);
- }
- }
-
- if (has_radius) {
- if (fabs(tmp_co[0]) > cmd->radius ||
- fabs(tmp_co[1]) > cmd->radius ||
- fabs(tmp_co[2]) > cmd->radius) continue;
- }
-
- octant = 0;
- if (tmp_co[0] > 0.0f) octant += 1;
- if (tmp_co[1] > 0.0f) octant += 2;
- if (tmp_co[2] > 0.0f) octant += 4;
-
- copy_v3_v3(apex, bb[octant]);
-
- d[0] = tmp_co[0] / apex[0];
- d[1] = tmp_co[1] / apex[1];
- d[2] = tmp_co[2] / apex[2];
-
- dmax = d[0];
- coord = 0;
- if (d[1] > dmax) {
- dmax = d[1];
- coord = 1;
- }
- if (d[2] > dmax) {
- /* dmax = d[2]; */ /* commented, we don't need it */
- coord = 2;
- }
-
- if (fabs(tmp_co[coord]) < FLT_EPSILON)
- continue;
-
- fbb = apex[coord] / tmp_co[coord];
-
- if (flag & MOD_CAST_X)
- tmp_co[0] = facm * tmp_co[0] + fac * tmp_co[0] * fbb;
- if (flag & MOD_CAST_Y)
- tmp_co[1] = facm * tmp_co[1] + fac * tmp_co[1] * fbb;
- if (flag & MOD_CAST_Z)
- tmp_co[2] = facm * tmp_co[2] + fac * tmp_co[2] * fbb;
-
- if(ctrl_ob) {
- if(flag & MOD_CAST_USE_OB_TRANSFORM) {
- mul_m4_v3(imat, tmp_co);
- } else {
- add_v3_v3v3(tmp_co, tmp_co, center);
- }
- }
-
- VECCOPY(vertexCos[i], tmp_co);
- }
-}
-
-static void castModifier_deformVerts(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
-{
- DerivedMesh *dm = NULL;
- CastModifierData *cmd = (CastModifierData *)md;
-
- if (ob->type == OB_MESH) {
- /* DerivedMesh is used only in case object is MESH */
- /* so we could optimize modifier applying by skipping DM creation */
- dm = get_dm(md->scene, ob, NULL, derivedData, NULL, 0);
- }
-
- if (cmd->type == MOD_CAST_TYPE_CUBOID) {
- castModifier_cuboid_do(cmd, ob, dm, vertexCos, numVerts);
- } else { /* MOD_CAST_TYPE_SPHERE or MOD_CAST_TYPE_CYLINDER */
- castModifier_sphere_do(cmd, ob, dm, vertexCos, numVerts);
- }
-
- if(dm != derivedData)
- dm->release(dm);
-}
-
-static void castModifier_deformVertsEM(
- ModifierData *md, Object *ob, BMEditMesh *editData,
- DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
-{
- DerivedMesh *dm = get_dm(md->scene, ob, editData, derivedData, NULL, 0);
- CastModifierData *cmd = (CastModifierData *)md;
-
- if (cmd->type == MOD_CAST_TYPE_CUBOID) {
- castModifier_cuboid_do(cmd, ob, dm, vertexCos, numVerts);
- } else { /* MOD_CAST_TYPE_SPHERE or MOD_CAST_TYPE_CYLINDER */
- castModifier_sphere_do(cmd, ob, dm, vertexCos, numVerts);
- }
-
- if(dm != derivedData)
- dm->release(dm);
-}
-
-/* Wave */
-
-static void waveModifier_initData(ModifierData *md)
-{
- WaveModifierData *wmd = (WaveModifierData*) md; // whadya know, moved here from Iraq
-
- wmd->flag |= (MOD_WAVE_X | MOD_WAVE_Y | MOD_WAVE_CYCL
- | MOD_WAVE_NORM_X | MOD_WAVE_NORM_Y | MOD_WAVE_NORM_Z);
-
- wmd->objectcenter = NULL;
- wmd->texture = NULL;
- wmd->map_object = NULL;
- wmd->height= 0.5f;
- wmd->width= 1.5f;
- wmd->speed= 0.25f;
- wmd->narrow= 1.5f;
- wmd->lifetime= 0.0f;
- wmd->damp= 10.0f;
- wmd->falloff= 0.0f;
- wmd->texmapping = MOD_WAV_MAP_LOCAL;
- wmd->defgrp_name[0] = 0;
-}
-
-static void waveModifier_copyData(ModifierData *md, ModifierData *target)
-{
- WaveModifierData *wmd = (WaveModifierData*) md;
- WaveModifierData *twmd = (WaveModifierData*) target;
-
- twmd->damp = wmd->damp;
- twmd->flag = wmd->flag;
- twmd->height = wmd->height;
- twmd->lifetime = wmd->lifetime;
- twmd->narrow = wmd->narrow;
- twmd->speed = wmd->speed;
- twmd->startx = wmd->startx;
- twmd->starty = wmd->starty;
- twmd->timeoffs = wmd->timeoffs;
- twmd->width = wmd->width;
- twmd->falloff = wmd->falloff;
- twmd->objectcenter = wmd->objectcenter;
- twmd->texture = wmd->texture;
- twmd->map_object = wmd->map_object;
- twmd->texmapping = wmd->texmapping;
- strncpy(twmd->defgrp_name, wmd->defgrp_name, 32);
-}
-
-static int waveModifier_dependsOnTime(ModifierData *md)
-{
- return 1;
-}
-
-static void waveModifier_foreachObjectLink(
- ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
-{
- WaveModifierData *wmd = (WaveModifierData*) md;
-
- walk(userData, ob, &wmd->objectcenter);
- walk(userData, ob, &wmd->map_object);
-}
-
-static void waveModifier_foreachIDLink(ModifierData *md, Object *ob,
- IDWalkFunc walk, void *userData)
-{
- WaveModifierData *wmd = (WaveModifierData*) md;
-
- walk(userData, ob, (ID **)&wmd->texture);
-
- waveModifier_foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData);
-}
-
-static void waveModifier_updateDepgraph(
- ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
- DagNode *obNode)
-{
- WaveModifierData *wmd = (WaveModifierData*) md;
-
- if(wmd->objectcenter) {
- DagNode *curNode = dag_get_node(forest, wmd->objectcenter);
-
- dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA,
- "Wave Modifier");
- }
-
- if(wmd->map_object) {
- DagNode *curNode = dag_get_node(forest, wmd->map_object);
-
- dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA,
- "Wave Modifer");
- }
-}
-
-static CustomDataMask waveModifier_requiredDataMask(Object *ob, ModifierData *md)
-{
- WaveModifierData *wmd = (WaveModifierData *)md;
- CustomDataMask dataMask = 0;
-
-
- /* ask for UV coordinates if we need them */
- if(wmd->texture && wmd->texmapping == MOD_WAV_MAP_UV)
- dataMask |= (1 << CD_MTFACE);
-
- /* ask for vertexgroups if we need them */
- if(wmd->defgrp_name[0])
- dataMask |= (1 << CD_MDEFORMVERT);
-
- return dataMask;
-}
-
-static void wavemod_get_texture_coords(WaveModifierData *wmd, Object *ob,
- DerivedMesh *dm,
- float (*co)[3], float (*texco)[3],
- int numVerts)
-{
- int i;
- int texmapping = wmd->texmapping;
-
- if(texmapping == MOD_WAV_MAP_OBJECT) {
- if(wmd->map_object)
- invert_m4_m4(wmd->map_object->imat, wmd->map_object->obmat);
- else /* if there is no map object, default to local */
- texmapping = MOD_WAV_MAP_LOCAL;
- }
-
- /* UVs need special handling, since they come from faces */
- if(texmapping == MOD_WAV_MAP_UV) {
- if(CustomData_has_layer(&dm->faceData, CD_MTFACE)) {
- MFace *mface = dm->getTessFaceArray(dm);
- MFace *mf;
- char *done = MEM_callocN(sizeof(*done) * numVerts,
- "get_texture_coords done");
- int numFaces = dm->getNumTessFaces(dm);
- char uvname[32];
- MTFace *tf;
-
- validate_layer_name(&dm->faceData, CD_MTFACE, wmd->uvlayer_name, uvname);
- tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
-
- /* verts are given the UV from the first face that uses them */
- for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
- if(!done[mf->v1]) {
- texco[mf->v1][0] = tf->uv[0][0];
- texco[mf->v1][1] = tf->uv[0][1];
- texco[mf->v1][2] = 0;
- done[mf->v1] = 1;
- }
- if(!done[mf->v2]) {
- texco[mf->v2][0] = tf->uv[1][0];
- texco[mf->v2][1] = tf->uv[1][1];
- texco[mf->v2][2] = 0;
- done[mf->v2] = 1;
- }
- if(!done[mf->v3]) {
- texco[mf->v3][0] = tf->uv[2][0];
- texco[mf->v3][1] = tf->uv[2][1];
- texco[mf->v3][2] = 0;
- done[mf->v3] = 1;
- }
- if(!done[mf->v4]) {
- texco[mf->v4][0] = tf->uv[3][0];
- texco[mf->v4][1] = tf->uv[3][1];
- texco[mf->v4][2] = 0;
- done[mf->v4] = 1;
- }
- }
-
- /* remap UVs from [0, 1] to [-1, 1] */
- for(i = 0; i < numVerts; ++i) {
- texco[i][0] = texco[i][0] * 2 - 1;
- texco[i][1] = texco[i][1] * 2 - 1;
- }
-
- MEM_freeN(done);
- return;
- } else /* if there are no UVs, default to local */
- texmapping = MOD_WAV_MAP_LOCAL;
- }
-
- for(i = 0; i < numVerts; ++i, ++co, ++texco) {
- switch(texmapping) {
- case MOD_WAV_MAP_LOCAL:
- VECCOPY(*texco, *co);
- break;
- case MOD_WAV_MAP_GLOBAL:
- VECCOPY(*texco, *co);
- mul_m4_v3(ob->obmat, *texco);
- break;
- case MOD_WAV_MAP_OBJECT:
- VECCOPY(*texco, *co);
- mul_m4_v3(ob->obmat, *texco);
- mul_m4_v3(wmd->map_object->imat, *texco);
- break;
- }
- }
-}
-
-static void waveModifier_do(WaveModifierData *md,
- Scene *scene, Object *ob, DerivedMesh *dm,
- float (*vertexCos)[3], int numVerts)
-{
- WaveModifierData *wmd = (WaveModifierData*) md;
- MVert *mvert = NULL;
- MDeformVert *dvert = NULL;
- int defgrp_index;
- float ctime = bsystem_time(scene, ob, (float)scene->r.cfra, 0.0);
- float minfac =
- (float)(1.0 / exp(wmd->width * wmd->narrow * wmd->width * wmd->narrow));
- float lifefac = wmd->height;
- float (*tex_co)[3] = NULL;
-
- if(wmd->flag & MOD_WAVE_NORM && ob->type == OB_MESH)
- mvert = dm->getVertArray(dm);
-
- if(wmd->objectcenter){
- float mat[4][4];
- /* get the control object's location in local coordinates */
- invert_m4_m4(ob->imat, ob->obmat);
- mul_m4_m4m4(mat, wmd->objectcenter->obmat, ob->imat);
-
- wmd->startx = mat[3][0];
- wmd->starty = mat[3][1];
- }
-
- /* get the index of the deform group */
- defgrp_index = defgroup_name_index(ob, wmd->defgrp_name);
-
- if(defgrp_index >= 0){
- dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
- }
-
- if(wmd->damp == 0) wmd->damp = 10.0f;
-
- if(wmd->lifetime != 0.0) {
- float x = ctime - wmd->timeoffs;
-
- if(x > wmd->lifetime) {
- lifefac = x - wmd->lifetime;
-
- if(lifefac > wmd->damp) lifefac = 0.0;
- else lifefac =
- (float)(wmd->height * (1.0 - sqrt(lifefac / wmd->damp)));
- }
- }
-
- if(wmd->texture) {
- tex_co = MEM_mallocN(sizeof(*tex_co) * numVerts,
- "waveModifier_do tex_co");
- wavemod_get_texture_coords(wmd, ob, dm, vertexCos, tex_co, numVerts);
- }
-
- if(lifefac != 0.0) {
- int i;
-
- for(i = 0; i < numVerts; i++) {
- float *co = vertexCos[i];
- float x = co[0] - wmd->startx;
- float y = co[1] - wmd->starty;
- float amplit= 0.0f;
- float dist = 0.0f;
- float falloff_fac = 0.0f;
- TexResult texres;
- MDeformWeight *def_weight = NULL;
-
- /* get weights */
- if(dvert) {
- int j;
- for(j = 0; j < dvert[i].totweight; ++j) {
- if(dvert[i].dw[j].def_nr == defgrp_index) {
- def_weight = &dvert[i].dw[j];
- break;
- }
- }
-
- /* if this vert isn't in the vgroup, don't deform it */
- if(!def_weight) continue;
- }
-
- if(wmd->texture) {
- texres.nor = NULL;
- get_texture_value(wmd->texture, tex_co[i], &texres);
- }
-
- /*get dist*/
- if(wmd->flag & MOD_WAVE_X) {
- if(wmd->flag & MOD_WAVE_Y){
- dist = (float)sqrt(x*x + y*y);
- }
- else{
- dist = fabs(x);
- }
- }
- else if(wmd->flag & MOD_WAVE_Y) {
- dist = fabs(y);
- }
-
- falloff_fac = (1.0-(dist / wmd->falloff));
- CLAMP(falloff_fac,0,1);
-
- if(wmd->flag & MOD_WAVE_X) {
- if(wmd->flag & MOD_WAVE_Y) amplit = (float)sqrt(x*x + y*y);
- else amplit = x;
- }
- else if(wmd->flag & MOD_WAVE_Y)
- amplit= y;
-
- /* this way it makes nice circles */
- amplit -= (ctime - wmd->timeoffs) * wmd->speed;
-
- if(wmd->flag & MOD_WAVE_CYCL) {
- amplit = (float)fmod(amplit - wmd->width, 2.0 * wmd->width)
- + wmd->width;
- }
-
- /* GAUSSIAN */
- if(amplit > -wmd->width && amplit < wmd->width) {
- amplit = amplit * wmd->narrow;
- amplit = (float)(1.0 / exp(amplit * amplit) - minfac);
-
- /*apply texture*/
- if(wmd->texture)
- amplit = amplit * texres.tin;
-
- /*apply weight*/
- if(def_weight)
- amplit = amplit * def_weight->weight;
-
- /*apply falloff*/
- if (wmd->falloff > 0)
- amplit = amplit * falloff_fac;
-
- if(mvert) {
- /* move along normals */
- if(wmd->flag & MOD_WAVE_NORM_X) {
- co[0] += (lifefac * amplit) * mvert[i].no[0] / 32767.0f;
- }
- if(wmd->flag & MOD_WAVE_NORM_Y) {
- co[1] += (lifefac * amplit) * mvert[i].no[1] / 32767.0f;
- }
- if(wmd->flag & MOD_WAVE_NORM_Z) {
- co[2] += (lifefac * amplit) * mvert[i].no[2] / 32767.0f;
- }
- }
- else {
- /* move along local z axis */
- co[2] += lifefac * amplit;
- }
- }
- }
- }
-
- if(wmd->texture) MEM_freeN(tex_co);
-}
-
-static void waveModifier_deformVerts(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
-{
- DerivedMesh *dm= derivedData;
- WaveModifierData *wmd = (WaveModifierData *)md;
-
- if(wmd->flag & MOD_WAVE_NORM)
- dm= get_cddm(md->scene, ob, NULL, dm, vertexCos);
- else if(wmd->texture || wmd->defgrp_name[0])
- dm= get_dm(md->scene, ob, NULL, dm, NULL, 0);
-
- waveModifier_do(wmd, md->scene, ob, dm, vertexCos, numVerts);
-
- if(dm != derivedData)
- dm->release(dm);
-}
-
-static void waveModifier_deformVertsEM(
- ModifierData *md, Object *ob, BMEditMesh *editData,
- DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
-{
- DerivedMesh *dm= derivedData;
- WaveModifierData *wmd = (WaveModifierData *)md;
-
- if(wmd->flag & MOD_WAVE_NORM)
- dm= get_cddm(md->scene, ob, editData, dm, vertexCos);
- else if(wmd->texture || wmd->defgrp_name[0])
- dm= get_dm(md->scene, ob, editData, dm, NULL, 0);
-
- waveModifier_do(wmd, md->scene, ob, dm, vertexCos, numVerts);
-
- if(dm != derivedData)
- dm->release(dm);
-}
-
-/* Armature */
-
-static void armatureModifier_initData(ModifierData *md)
-{
- ArmatureModifierData *amd = (ArmatureModifierData*) md;
-
- amd->deformflag = ARM_DEF_ENVELOPE | ARM_DEF_VGROUP;
-}
-
-static void armatureModifier_copyData(ModifierData *md, ModifierData *target)
-{
- ArmatureModifierData *amd = (ArmatureModifierData*) md;
- ArmatureModifierData *tamd = (ArmatureModifierData*) target;
-
- tamd->object = amd->object;
- tamd->deformflag = amd->deformflag;
- strncpy(tamd->defgrp_name, amd->defgrp_name, 32);
-}
-
-static CustomDataMask armatureModifier_requiredDataMask(Object *ob, ModifierData *md)
-{
- CustomDataMask dataMask = 0;
-
- /* ask for vertexgroups */
- dataMask |= (1 << CD_MDEFORMVERT);
-
- return dataMask;
-}
-
-static int armatureModifier_isDisabled(ModifierData *md, int useRenderParams)
-{
- ArmatureModifierData *amd = (ArmatureModifierData*) md;
-
- return !amd->object;
-}
-
-static void armatureModifier_foreachObjectLink(
- ModifierData *md, Object *ob,
- void (*walk)(void *userData, Object *ob, Object **obpoin),
- void *userData)
-{
- ArmatureModifierData *amd = (ArmatureModifierData*) md;
-
- walk(userData, ob, &amd->object);
-}
-
-static void armatureModifier_updateDepgraph(
- ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
- DagNode *obNode)
-{
- ArmatureModifierData *amd = (ArmatureModifierData*) md;
-
- if (amd->object) {
- DagNode *curNode = dag_get_node(forest, amd->object);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Armature Modifier");
- }
-}
-
-static void armatureModifier_deformVerts(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
-{
- ArmatureModifierData *amd = (ArmatureModifierData*) md;
-
- modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
-
- armature_deform_verts(amd->object, ob, derivedData, vertexCos, NULL,
- numVerts, amd->deformflag,
- (float(*)[3])amd->prevCos, amd->defgrp_name);
- /* free cache */
- if(amd->prevCos) {
- MEM_freeN(amd->prevCos);
- amd->prevCos= NULL;
- }
-}
-
-static void armatureModifier_deformVertsEM(
- ModifierData *md, Object *ob, BMEditMesh *editData,
- DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
-{
- ArmatureModifierData *amd = (ArmatureModifierData*) md;
- DerivedMesh *dm = derivedData;
-
- if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data);
-
- armature_deform_verts(amd->object, ob, dm, vertexCos, NULL, numVerts,
- amd->deformflag, NULL, amd->defgrp_name);
-
- if(!derivedData) dm->release(dm);
-}
-
-static void armatureModifier_deformMatricesEM(
- ModifierData *md, Object *ob, BMEditMesh *editData,
- DerivedMesh *derivedData, float (*vertexCos)[3],
- float (*defMats)[3][3], int numVerts)
-{
- ArmatureModifierData *amd = (ArmatureModifierData*) md;
- DerivedMesh *dm = derivedData;
-
- if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data);
-
- armature_deform_verts(amd->object, ob, dm, vertexCos, defMats, numVerts,
- amd->deformflag, NULL, amd->defgrp_name);
-
- if(!derivedData) dm->release(dm);
-}
-
-/* Hook */
-
-static void hookModifier_initData(ModifierData *md)
-{
- HookModifierData *hmd = (HookModifierData*) md;
-
- hmd->force= 1.0;
-}
-
-static void hookModifier_copyData(ModifierData *md, ModifierData *target)
-{
- HookModifierData *hmd = (HookModifierData*) md;
- HookModifierData *thmd = (HookModifierData*) target;
-
- VECCOPY(thmd->cent, hmd->cent);
- thmd->falloff = hmd->falloff;
- thmd->force = hmd->force;
- thmd->object = hmd->object;
- thmd->totindex = hmd->totindex;
- thmd->indexar = MEM_dupallocN(hmd->indexar);
- memcpy(thmd->parentinv, hmd->parentinv, sizeof(hmd->parentinv));
- strncpy(thmd->name, hmd->name, 32);
- strncpy(thmd->subtarget, hmd->subtarget, 32);
-}
-
-static CustomDataMask hookModifier_requiredDataMask(Object *ob, ModifierData *md)
-{
- HookModifierData *hmd = (HookModifierData *)md;
- CustomDataMask dataMask = 0;
-
- /* ask for vertexgroups if we need them */
- if(!hmd->indexar && hmd->name[0]) dataMask |= (1 << CD_MDEFORMVERT);
-
- return dataMask;
-}
-
-static void hookModifier_freeData(ModifierData *md)
-{
- HookModifierData *hmd = (HookModifierData*) md;
-
- if (hmd->indexar) MEM_freeN(hmd->indexar);
-}
-
-static int hookModifier_isDisabled(ModifierData *md, int useRenderParams)
-{
- HookModifierData *hmd = (HookModifierData*) md;
-
- return !hmd->object;
-}
-
-static void hookModifier_foreachObjectLink(
- ModifierData *md, Object *ob,
- void (*walk)(void *userData, Object *ob, Object **obpoin),
- void *userData)
-{
- HookModifierData *hmd = (HookModifierData*) md;
-
- walk(userData, ob, &hmd->object);
-}
-
-static void hookModifier_updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene,
- Object *ob, DagNode *obNode)
-{
- HookModifierData *hmd = (HookModifierData*) md;
-
- if (hmd->object) {
- DagNode *curNode = dag_get_node(forest, hmd->object);
-
- if (hmd->subtarget[0])
- dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA|DAG_RL_DATA_DATA, "Hook Modifier");
- else
- dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA, "Hook Modifier");
- }
-}
-
-static void hookModifier_deformVerts(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
-{
- HookModifierData *hmd = (HookModifierData*) md;
- bPoseChannel *pchan= get_pose_channel(hmd->object->pose, hmd->subtarget);
- float vec[3], mat[4][4], dmat[4][4];
- int i;
- DerivedMesh *dm = derivedData;
-
- /* get world-space matrix of target, corrected for the space the verts are in */
- if (hmd->subtarget[0] && pchan) {
- /* bone target if there's a matching pose-channel */
- mul_m4_m4m4(dmat, pchan->pose_mat, hmd->object->obmat);
- }
- else {
- /* just object target */
- copy_m4_m4(dmat, hmd->object->obmat);
- }
- invert_m4_m4(ob->imat, ob->obmat);
- mul_serie_m4(mat, ob->imat, dmat, hmd->parentinv,
- NULL, NULL, NULL, NULL, NULL);
-
- /* vertex indices? */
- if(hmd->indexar) {
- for(i = 0; i < hmd->totindex; i++) {
- int index = hmd->indexar[i];
-
- /* This should always be true and I don't generally like
- * "paranoid" style code like this, but old files can have
- * indices that are out of range because old blender did
- * not correct them on exit editmode. - zr
- */
- if(index < numVerts) {
- float *co = vertexCos[index];
- float fac = hmd->force;
-
- /* if DerivedMesh is present and has original index data,
- * use it
- */
- if(dm && dm->getVertDataArray(dm, CD_ORIGINDEX)) {
- int j;
- int orig_index;
- for(j = 0; j < numVerts; ++j) {
- fac = hmd->force;
- orig_index = *(int *)dm->getVertData(dm, j,
- CD_ORIGINDEX);
- if(orig_index == index) {
- co = vertexCos[j];
- if(hmd->falloff != 0.0) {
- float len = len_v3v3(co, hmd->cent);
- if(len > hmd->falloff) fac = 0.0;
- else if(len > 0.0)
- fac *= sqrt(1.0 - len / hmd->falloff);
- }
-
- if(fac != 0.0) {
- mul_v3_m4v3(vec, mat, co);
- interp_v3_v3v3(co, co, vec, fac);
- }
- }
- }
- } else {
- if(hmd->falloff != 0.0) {
- float len = len_v3v3(co, hmd->cent);
- if(len > hmd->falloff) fac = 0.0;
- else if(len > 0.0)
- fac *= sqrt(1.0 - len / hmd->falloff);
- }
-
- if(fac != 0.0) {
- mul_v3_m4v3(vec, mat, co);
- interp_v3_v3v3(co, co, vec, fac);
- }
- }
- }
- }
- }
- else if(hmd->name[0]) { /* vertex group hook */
- Mesh *me = ob->data;
- int use_dverts = 0;
- int maxVerts = 0;
- int defgrp_index = defgroup_name_index(ob, hmd->name);
-
- if(dm) {
- if(dm->getVertData(dm, 0, CD_MDEFORMVERT)) {
- maxVerts = dm->getNumVerts(dm);
- use_dverts = 1;
- }
- }
- else if(me->dvert) {
- maxVerts = me->totvert;
- use_dverts = 1;
- }
-
- if(defgrp_index >= 0 && use_dverts) {
- MDeformVert *dvert = me->dvert;
- int i, j;
-
- for(i = 0; i < maxVerts; i++, dvert++) {
- if(dm) dvert = dm->getVertData(dm, i, CD_MDEFORMVERT);
- for(j = 0; j < dvert->totweight; j++) {
- if(dvert->dw[j].def_nr == defgrp_index) {
- float fac = hmd->force*dvert->dw[j].weight;
- float *co = vertexCos[i];
-
- if(hmd->falloff != 0.0) {
- float len = len_v3v3(co, hmd->cent);
- if(len > hmd->falloff) fac = 0.0;
- else if(len > 0.0)
- fac *= sqrt(1.0 - len / hmd->falloff);
- }
-
- mul_v3_m4v3(vec, mat, co);
- interp_v3_v3v3(co, co, vec, fac);
- }
- }
- }
- }
- }
-}
-
-static void hookModifier_deformVertsEM(
- ModifierData *md, Object *ob, BMEditMesh *editData,
- DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
-{
- DerivedMesh *dm = derivedData;
-
- if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data);
-
- hookModifier_deformVerts(md, ob, derivedData, vertexCos, numVerts, 0, 0);
-
- if(!derivedData) dm->release(dm);
-}
-
-/* Softbody */
-
-static void softbodyModifier_deformVerts(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
-{
- sbObjectStep(md->scene, ob, (float)md->scene->r.cfra, vertexCos, numVerts);
-}
-
-static int softbodyModifier_dependsOnTime(ModifierData *md)
-{
- return 1;
-}
-
-/* Solidify */
-
-
-typedef struct EdgeFaceRef {
- int f1; /* init as -1 */
- int f2;
-} EdgeFaceRef;
-
-static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3])
-{
- int i, numVerts, numEdges, numFaces;
- MFace *mface, *mf;
- MVert *mvert, *mv;
-
- float (*face_nors)[3];
- float *f_no;
- int calc_face_nors= 0;
-
- numVerts = dm->getNumVerts(dm);
- numEdges = dm->getNumEdges(dm);
- numFaces = dm->getNumFaces(dm);
- mface = dm->getTessFaceArray(dm);
- mvert = dm->getVertArray(dm);
-
- /* we don't want to overwrite any referenced layers */
-
- /*
- Dosnt work here!
- mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
- cddm->mvert = mv;
- */
-
- face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
- if(!face_nors) {
- calc_face_nors = 1;
- face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, numFaces);
- }
-
- mv = mvert;
- mf = mface;
-
- {
- EdgeHash *edge_hash = BLI_edgehash_new();
- EdgeHashIterator *edge_iter;
- int edge_ref_count = 0;
- int ed_v1, ed_v2; /* use when getting the key */
- EdgeFaceRef *edge_ref_array = MEM_callocN(numEdges * sizeof(EdgeFaceRef), "Edge Connectivity");
- EdgeFaceRef *edge_ref;
- float edge_normal[3];
-
- /* This function adds an edge hash if its not there, and adds the face index */
-#define NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(EDV1, EDV2); \
- edge_ref = (EdgeFaceRef *)BLI_edgehash_lookup(edge_hash, EDV1, EDV2); \
- if (!edge_ref) { \
- edge_ref = &edge_ref_array[edge_ref_count]; edge_ref_count++; \
- edge_ref->f1=i; \
- edge_ref->f2=-1; \
- BLI_edgehash_insert(edge_hash, EDV1, EDV2, edge_ref); \
- } else { \
- edge_ref->f2=i; \
- }
-
- for(i = 0; i < numFaces; i++, mf++) {
- f_no = face_nors[i];
-
- if(mf->v4) {
- if(calc_face_nors)
- normal_quad_v3(f_no, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
-
- NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v1, mf->v2);
- NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v2, mf->v3);
- NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v3, mf->v4);
- NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v4, mf->v1);
- } else {
- if(calc_face_nors)
- normal_tri_v3(f_no, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
-
- NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v1, mf->v2);
- NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v2, mf->v3);
- NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v3, mf->v1);
- }
- }
-
- for(edge_iter = BLI_edgehashIterator_new(edge_hash); !BLI_edgehashIterator_isDone(edge_iter); BLI_edgehashIterator_step(edge_iter)) {
- /* Get the edge vert indicies, and edge value (the face indicies that use it)*/
- BLI_edgehashIterator_getKey(edge_iter, (int*)&ed_v1, (int*)&ed_v2);
- edge_ref = BLI_edgehashIterator_getValue(edge_iter);
-
- if (edge_ref->f2 != -1) {
- /* We have 2 faces using this edge, calculate the edges normal
- * using the angle between the 2 faces as a weighting */
- add_v3_v3v3(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]);
- normalize_v3(edge_normal);
- mul_v3_fl(edge_normal, angle_normalized_v3v3(face_nors[edge_ref->f1], face_nors[edge_ref->f2]));
- } else {
- /* only one face attached to that edge */
- /* an edge without another attached- the weight on this is
- * undefined, M_PI/2 is 90d in radians and that seems good enough */
- VECCOPY(edge_normal, face_nors[edge_ref->f1])
- mul_v3_fl(edge_normal, M_PI/2);
- }
- add_v3_v3(temp_nors[ed_v1], edge_normal);
- add_v3_v3(temp_nors[ed_v2], edge_normal);
- }
- BLI_edgehashIterator_free(edge_iter);
- BLI_edgehash_free(edge_hash, NULL);
- MEM_freeN(edge_ref_array);
- }
-
- /* normalize vertex normals and assign */
- for(i = 0; i < numVerts; i++, mv++) {
- if(normalize_v3(temp_nors[i]) == 0.0f) {
- normal_short_to_float_v3(temp_nors[i], mv->no);
- }
- }
-}
-
-static void solidifyModifier_initData(ModifierData *md)
-{
- SolidifyModifierData *smd = (SolidifyModifierData*) md;
- smd->offset = 0.01f;
- smd->flag = MOD_SOLIDIFY_RIM;
-}
-
-static void solidifyModifier_copyData(ModifierData *md, ModifierData *target)
-{
- SolidifyModifierData *smd = (SolidifyModifierData*) md;
- SolidifyModifierData *tsmd = (SolidifyModifierData*) target;
- tsmd->offset = smd->offset;
- tsmd->crease_inner = smd->crease_inner;
- tsmd->crease_outer = smd->crease_outer;
- tsmd->crease_rim = smd->crease_rim;
- strcpy(tsmd->defgrp_name, smd->defgrp_name);
-}
-
-static DerivedMesh *solidifyModifier_applyModifier(ModifierData *md,
- Object *ob,
- DerivedMesh *dm,
- int useRenderParams,
- int isFinalCalc)
+ModifierTypeInfo *modifierType_getInfo(ModifierType type)
{
- int i;
- DerivedMesh *result;
- SolidifyModifierData *smd = (SolidifyModifierData*) md;
-
- MFace *mf, *mface, *orig_mface;
- MEdge *ed, *medge, *orig_medge;
- MVert *mv, *mvert, *orig_mvert;
-
- int numVerts = dm->getNumVerts(dm);
- int numEdges = dm->getNumEdges(dm);
- int numFaces = dm->getNumFaces(dm);
+ static ModifierTypeInfo *types[NUM_MODIFIER_TYPES];
+ static int types_init = 1;
- /* use for edges */
- int *new_vert_arr= NULL;
- int newFaces = 0;
-
- int *new_edge_arr= NULL;
- int newEdges = 0;
-
- int *edge_users= NULL;
- char *edge_order= NULL;
-
- float (*vert_nors)[3]= NULL;
-
- orig_mface = dm->getTessFaceArray(dm);
- orig_medge = dm->getEdgeArray(dm);
- orig_mvert = dm->getVertArray(dm);
-
- if(smd->flag & MOD_SOLIDIFY_RIM) {
- EdgeHash *edgehash = BLI_edgehash_new();
- EdgeHashIterator *ehi;
- int v1, v2;
- int eidx;
-
- for(i=0, mv=orig_mvert; i<numVerts; i++, mv++) {
- mv->flag &= ~ME_VERT_TMP_TAG;
- }
-
- for(i=0, ed=orig_medge; i<numEdges; i++, ed++) {
- BLI_edgehash_insert(edgehash, ed->v1, ed->v2, SET_INT_IN_POINTER(i));
- }
-
-#define INVALID_UNUSED -1
-#define INVALID_PAIR -2
-
-#define ADD_EDGE_USER(_v1, _v2, edge_ord) \
- eidx= GET_INT_FROM_POINTER(BLI_edgehash_lookup(edgehash, _v1, _v2)); \
- if(edge_users[eidx] == INVALID_UNUSED) { \
- edge_users[eidx]= (_v1 < _v2) ? i:(i+numFaces); \
- edge_order[eidx]= edge_ord; \
- } else { \
- edge_users[eidx]= INVALID_PAIR; \
- } \
-
-
- edge_users= MEM_mallocN(sizeof(int) * numEdges, "solid_mod edges");
- edge_order= MEM_mallocN(sizeof(char) * numEdges, "solid_mod eorder");
- memset(edge_users, INVALID_UNUSED, sizeof(int) * numEdges);
-
- for(i=0, mf=orig_mface; i<numFaces; i++, mf++) {
- if(mf->v4) {
- ADD_EDGE_USER(mf->v1, mf->v2, 0);
- ADD_EDGE_USER(mf->v2, mf->v3, 1);
- ADD_EDGE_USER(mf->v3, mf->v4, 2);
- ADD_EDGE_USER(mf->v4, mf->v1, 3);
- }
- else {
- ADD_EDGE_USER(mf->v1, mf->v2, 0);
- ADD_EDGE_USER(mf->v2, mf->v3, 1);
- ADD_EDGE_USER(mf->v3, mf->v1, 2);
- }
- }
-
-#undef ADD_EDGE_USER
-#undef INVALID_UNUSED
-#undef INVALID_PAIR
-
-
- new_edge_arr= MEM_callocN(sizeof(int) * numEdges, "solid_mod arr");
-
- ehi= BLI_edgehashIterator_new(edgehash);
- for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
- int eidx= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
- if(edge_users[eidx] >= 0) {
- BLI_edgehashIterator_getKey(ehi, &v1, &v2);
- orig_mvert[v1].flag |= ME_VERT_TMP_TAG;
- orig_mvert[v2].flag |= ME_VERT_TMP_TAG;
- new_edge_arr[newFaces]= eidx;
- newFaces++;
- }
- }
- BLI_edgehashIterator_free(ehi);
-
-
-
- new_vert_arr= MEM_callocN(sizeof(int) * numVerts, "solid_mod new_varr");
- for(i=0, mv=orig_mvert; i<numVerts; i++, mv++) {
- if(mv->flag & ME_VERT_TMP_TAG) {
- new_vert_arr[newEdges] = i;
- newEdges++;
-
- mv->flag &= ~ME_VERT_TMP_TAG;
- }
- }
-
- BLI_edgehash_free(edgehash, NULL);
+ if (types_init) {
+ modifier_type_init(types, type); /* MOD_utils.c */
+ types_init= 0;
}
- if(smd->flag & MOD_SOLIDIFY_NORMAL_CALC) {
- vert_nors= MEM_callocN(sizeof(float) * numVerts * 3, "mod_solid_vno_hq");
- dm_calc_normal(dm, vert_nors);
- }
-
- result = CDDM_from_template(dm, numVerts * 2, (numEdges * 2) + newEdges, (numFaces * 2) + newFaces, 0, 0);
-
- mface = result->getTessFaceArray(result);
- medge = result->getEdgeArray(result);
- mvert = result->getVertArray(result);
-
- DM_copy_face_data(dm, result, 0, 0, numFaces);
- DM_copy_face_data(dm, result, 0, numFaces, numFaces);
-
- DM_copy_edge_data(dm, result, 0, 0, numEdges);
- DM_copy_edge_data(dm, result, 0, numEdges, numEdges);
-
- DM_copy_vert_data(dm, result, 0, 0, numVerts);
- DM_copy_vert_data(dm, result, 0, numVerts, numVerts);
-
- {
- static int corner_indices[4] = {2, 1, 0, 3};
- int is_quad;
-
- for(i=0, mf=mface+numFaces; i<numFaces; i++, mf++) {
- mf->v1 += numVerts;
- mf->v2 += numVerts;
- mf->v3 += numVerts;
- if(mf->v4)
- mf->v4 += numVerts;
-
- /* Flip face normal */
- {
- is_quad = mf->v4;
- SWAP(int, mf->v1, mf->v3);
- DM_swap_tessface_data(result, i+numFaces, corner_indices);
- test_index_face(mf, &result->faceData, numFaces, is_quad ? 4:3);
- }
- }
- }
-
- for(i=0, ed=medge+numEdges; i<numEdges; i++, ed++) {
- ed->v1 += numVerts;
- ed->v2 += numVerts;
- }
-
- if((smd->flag & MOD_SOLIDIFY_EVEN) == 0) {
- /* no even thickness, very simple */
- float scalar_short = smd->offset / 32767.0f;
-
- if(smd->offset < 0.0f) mv= mvert+numVerts;
- else mv= mvert;
-
- for(i=0; i<numVerts; i++, mv++) {
- mv->co[0] += mv->no[0] * scalar_short;
- mv->co[1] += mv->no[1] * scalar_short;
- mv->co[2] += mv->no[2] * scalar_short;
- }
+ if(type >= 0 && type < NUM_MODIFIER_TYPES &&
+ types[type]->name[0] != '\0') {
+ return types[type];
}
else {
- /* make a face normal layer if not present */
- float (*face_nors)[3];
- int face_nors_calc= 0;
-
- /* same as EM_solidify() in editmesh_lib.c */
- float *vert_angles= MEM_callocN(sizeof(float) * numVerts * 2, "mod_solid_pair"); /* 2 in 1 */
- float *vert_accum= vert_angles + numVerts;
- float face_angles[4];
- int i, j, vidx;
-
- face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
- if(!face_nors) {
- face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, dm->numFaceData);
- face_nors_calc= 1;
- }
-
- if(vert_nors==NULL) {
- vert_nors= MEM_mallocN(sizeof(float) * numVerts * 3, "mod_solid_vno");
- for(i=0, mv=mvert; i<numVerts; i++, mv++) {
- normal_short_to_float_v3(vert_nors[i], mv->no);
- }
- }
-
- for(i=0, mf=mface; i<numFaces; i++, mf++) {
-
- /* just added, calc the normal */
- if(face_nors_calc) {
- if(mf->v4)
- normal_quad_v3(face_nors[i], mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
- else
- normal_tri_v3(face_nors[i] , mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co);
- }
-
- if(mf->v4) {
- angle_quad_v3(face_angles, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
- j= 3;
- }
- else {
- angle_tri_v3(face_angles, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co);
- j= 2;
- }
-
- for(; j>=0; j--) {
- vidx = *(&mf->v1 + j);
- vert_accum[vidx] += face_angles[j];
- vert_angles[vidx]+= shell_angle_to_dist(angle_normalized_v3v3(vert_nors[vidx], face_nors[i])) * face_angles[j];
- }
- }
-
- if(smd->offset < 0.0f) mv= mvert+numVerts;
- else mv= mvert;
-
- for(i=0; i<numVerts; i++, mv++) {
- if(vert_accum[i]) { /* zero if unselected */
- madd_v3_v3fl(mv->co, vert_nors[i], smd->offset * (vert_angles[i] / vert_accum[i]));
- }
- }
-
- MEM_freeN(vert_angles);
- }
-
- if(vert_nors)
- MEM_freeN(vert_nors);
-
- if(smd->flag & MOD_SOLIDIFY_RIM) {
-
- static int edge_indices[4][4] = {
- {1, 0, 0, 1},
- {2, 1, 1, 2},
- {3, 2, 2, 3},
- {0, 3, 3, 0}};
-
- /* add faces & edges */
- ed= medge + (numEdges * 2);
- for(i=0; i<newEdges; i++, ed++) {
- ed->v1= new_vert_arr[i];
- ed->v2= new_vert_arr[i] + numVerts;
- ed->flag |= ME_EDGEDRAW;
-
- if(smd->crease_rim)
- ed->crease= smd->crease_rim * 255.0f;
- }
-
- /* faces */
- mf= mface + (numFaces * 2);
- for(i=0; i<newFaces; i++, mf++) {
- int eidx= new_edge_arr[i];
- int fidx= edge_users[eidx];
- int flip;
-
- if(fidx >= numFaces) {
- fidx -= numFaces;
- flip= 1;
- }
- else {
- flip= 0;
- }
-
- ed= medge + eidx;
-
- /* copy most of the face settings */
- DM_copy_face_data(dm, result, fidx, (numFaces * 2) + i, 1);
-
- if(flip) {
- DM_swap_tessface_data(result, (numFaces * 2) + i, edge_indices[edge_order[eidx]]);
-
- mf->v1= ed->v1;
- mf->v2= ed->v2;
- mf->v3= ed->v2 + numVerts;
- mf->v4= ed->v1 + numVerts;
- }
- else {
- DM_swap_tessface_data(result, (numFaces * 2) + i, edge_indices[edge_order[eidx]]);
-
- mf->v1= ed->v2;
- mf->v2= ed->v1;
- mf->v3= ed->v1 + numVerts;
- mf->v4= ed->v2 + numVerts;
-
-
- }
-
- if(smd->crease_outer > 0.0f)
- ed->crease= smd->crease_outer * 255.0f;
-
- if(smd->crease_inner > 0.0f) {
- ed= medge + (numEdges + eidx);
- ed->crease= smd->crease_inner * 255.0f;
- }
- }
-
- MEM_freeN(new_vert_arr);
- MEM_freeN(new_edge_arr);
- MEM_freeN(edge_users);
- MEM_freeN(edge_order);
- }
-
- CDDM_tessfaces_to_faces(result);
-
- return result;
-}
-
-static DerivedMesh *solidifyModifier_applyModifierEM(ModifierData *md,
- Object *ob,
- EditMesh *editData,
- DerivedMesh *derivedData)
-{
- return solidifyModifier_applyModifier(md, ob, derivedData, 0, 1);
-}
-
-/* Smoke */
-
-static void smokeModifier_initData(ModifierData *md)
-{
- SmokeModifierData *smd = (SmokeModifierData*) md;
-
- smd->domain = NULL;
- smd->flow = NULL;
- smd->coll = NULL;
- smd->type = 0;
- smd->time = -1;
-}
-
-static void smokeModifier_freeData(ModifierData *md)
-{
- SmokeModifierData *smd = (SmokeModifierData*) md;
-
- smokeModifier_free (smd);
-}
-
-static void smokeModifier_deformVerts(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
-{
- SmokeModifierData *smd = (SmokeModifierData*) md;
- DerivedMesh *dm = dm= get_cddm(md->scene, ob, NULL, derivedData, vertexCos);
-
- smokeModifier_do(smd, md->scene, ob, dm, useRenderParams, isFinalCalc);
-
- if(dm != derivedData)
- dm->release(dm);
-}
-
-static int smokeModifier_dependsOnTime(ModifierData *md)
-{
- return 1;
-}
-
-static void smokeModifier_updateDepgraph(
- ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
- DagNode *obNode)
-{
- /*SmokeModifierData *smd = (SmokeModifierData *) md;
- if(smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain)
- {
- if(smd->domain->fluid_group)
- {
- GroupObject *go = NULL;
-
- for(go = smd->domain->fluid_group->gobject.first; go; go = go->next)
- {
- if(go->ob)
- {
- SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(go->ob, eModifierType_Smoke);
-
- // check for initialized smoke object
- if(smd2 && (smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow)
- {
- DagNode *curNode = dag_get_node(forest, go->ob);
- dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Smoke Flow");
- }
- }
- }
- }
- }
- */
-}
-
-/* Cloth */
-
-static void clothModifier_initData(ModifierData *md)
-{
- ClothModifierData *clmd = (ClothModifierData*) md;
-
- clmd->sim_parms = MEM_callocN(sizeof(ClothSimSettings), "cloth sim parms");
- clmd->coll_parms = MEM_callocN(sizeof(ClothCollSettings), "cloth coll parms");
- clmd->point_cache = BKE_ptcache_add(&clmd->ptcaches);
-
- /* check for alloc failing */
- if(!clmd->sim_parms || !clmd->coll_parms || !clmd->point_cache)
- return;
-
- cloth_init (clmd);
-}
-
-static DerivedMesh *clothModifier_applyModifier(ModifierData *md, Object *ob,
- DerivedMesh *derivedData, int useRenderParams, int isFinalCalc)
-{
- ClothModifierData *clmd = (ClothModifierData*) md;
- DerivedMesh *result=NULL;
-
- /* check for alloc failing */
- if(!clmd->sim_parms || !clmd->coll_parms)
- {
- clothModifier_initData(md);
-
- if(!clmd->sim_parms || !clmd->coll_parms)
- return derivedData;
- }
-
- result = clothModifier_do(clmd, md->scene, ob, derivedData, useRenderParams, isFinalCalc);
-
- if(result)
- {
- CDDM_calc_normals(result);
- return result;
- }
- return derivedData;
-}
-
-static void clothModifier_updateDepgraph(
- ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
- DagNode *obNode)
-{
- ClothModifierData *clmd = (ClothModifierData*) md;
-
- Base *base;
-
- if(clmd)
- {
- for(base = scene->base.first; base; base= base->next)
- {
- Object *ob1= base->object;
- if(ob1 != ob)
- {
- CollisionModifierData *coll_clmd = (CollisionModifierData *)modifiers_findByType(ob1, eModifierType_Collision);
- if(coll_clmd)
- {
- DagNode *curNode = dag_get_node(forest, ob1);
- dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Cloth Collision");
- }
- }
- }
- }
-}
-
-static CustomDataMask clothModifier_requiredDataMask(Object *ob, ModifierData *md)
-{
- CustomDataMask dataMask = 0;
-
- /* ask for vertexgroups if we need them */
- dataMask |= (1 << CD_MDEFORMVERT);
-
- return dataMask;
-}
-
-static void clothModifier_copyData(ModifierData *md, ModifierData *target)
-{
- ClothModifierData *clmd = (ClothModifierData*) md;
- ClothModifierData *tclmd = (ClothModifierData*) target;
-
- if(tclmd->sim_parms)
- MEM_freeN(tclmd->sim_parms);
- if(tclmd->coll_parms)
- MEM_freeN(tclmd->coll_parms);
-
- BKE_ptcache_free_list(&tclmd->ptcaches);
- tclmd->point_cache = NULL;
-
- tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms);
- if(clmd->sim_parms->effector_weights)
- tclmd->sim_parms->effector_weights = MEM_dupallocN(clmd->sim_parms->effector_weights);
- tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms);
- tclmd->point_cache = BKE_ptcache_copy_list(&tclmd->ptcaches, &clmd->ptcaches);
- tclmd->clothObject = NULL;
-}
-
-static int clothModifier_dependsOnTime(ModifierData *md)
-{
- return 1;
-}
-
-static void clothModifier_freeData(ModifierData *md)
-{
- ClothModifierData *clmd = (ClothModifierData*) md;
-
- if (clmd)
- {
- if(G.rt > 0)
- printf("clothModifier_freeData\n");
-
- cloth_free_modifier_extern (clmd);
-
- if(clmd->sim_parms) {
- if(clmd->sim_parms->effector_weights)
- MEM_freeN(clmd->sim_parms->effector_weights);
- MEM_freeN(clmd->sim_parms);
- }
- if(clmd->coll_parms)
- MEM_freeN(clmd->coll_parms);
-
- BKE_ptcache_free_list(&clmd->ptcaches);
- clmd->point_cache = NULL;
- }
-}
-
-/* Collision */
-
-static void collisionModifier_initData(ModifierData *md)
-{
- CollisionModifierData *collmd = (CollisionModifierData*) md;
-
- collmd->x = NULL;
- collmd->xnew = NULL;
- collmd->current_x = NULL;
- collmd->current_xnew = NULL;
- collmd->current_v = NULL;
- collmd->time = -1000;
- collmd->numverts = 0;
- collmd->bvhtree = NULL;
-}
-
-static void collisionModifier_freeData(ModifierData *md)
-{
- CollisionModifierData *collmd = (CollisionModifierData*) md;
-
- if (collmd)
- {
- if(collmd->bvhtree)
- BLI_bvhtree_free(collmd->bvhtree);
- if(collmd->x)
- MEM_freeN(collmd->x);
- if(collmd->xnew)
- MEM_freeN(collmd->xnew);
- if(collmd->current_x)
- MEM_freeN(collmd->current_x);
- if(collmd->current_xnew)
- MEM_freeN(collmd->current_xnew);
- if(collmd->current_v)
- MEM_freeN(collmd->current_v);
- if(collmd->mfaces)
- MEM_freeN(collmd->mfaces);
-
- collmd->x = NULL;
- collmd->xnew = NULL;
- collmd->current_x = NULL;
- collmd->current_xnew = NULL;
- collmd->current_v = NULL;
- collmd->time = -1000;
- collmd->numverts = 0;
- collmd->bvhtree = NULL;
- collmd->mfaces = NULL;
- }
-}
-
-static int collisionModifier_dependsOnTime(ModifierData *md)
-{
- return 1;
-}
-
-static void collisionModifier_deformVerts(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
-{
- CollisionModifierData *collmd = (CollisionModifierData*) md;
- DerivedMesh *dm = NULL;
- float current_time = 0;
- unsigned int numverts = 0, i = 0;
- MVert *tempVert = NULL;
-
- /* if possible use/create DerivedMesh */
- if(derivedData) dm = CDDM_copy(derivedData, 0);
- else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob);
-
- if(!ob->pd)
- {
- printf("collisionModifier_deformVerts: Should not happen!\n");
- return;
- }
-
- if(dm)
- {
- CDDM_apply_vert_coords(dm, vertexCos);
- CDDM_calc_normals(dm);
-
- current_time = bsystem_time (md->scene, ob, ( float ) md->scene->r.cfra, 0.0 );
-
- if(G.rt > 0)
- printf("current_time %f, collmd->time %f\n", current_time, collmd->time);
-
- numverts = dm->getNumVerts ( dm );
-
- if((current_time > collmd->time)|| (BKE_ptcache_get_continue_physics()))
- {
- // check if mesh has changed
- if(collmd->x && (numverts != collmd->numverts))
- collisionModifier_freeData((ModifierData *)collmd);
-
- if(collmd->time == -1000) // first time
- {
- collmd->x = dm->dupVertArray(dm); // frame start position
-
- for ( i = 0; i < numverts; i++ )
- {
- // we save global positions
- mul_m4_v3( ob->obmat, collmd->x[i].co );
- }
-
- collmd->xnew = MEM_dupallocN(collmd->x); // frame end position
- collmd->current_x = MEM_dupallocN(collmd->x); // inter-frame
- collmd->current_xnew = MEM_dupallocN(collmd->x); // inter-frame
- collmd->current_v = MEM_dupallocN(collmd->x); // inter-frame
-
- collmd->numverts = numverts;
-
- collmd->mfaces = dm->dupTessFaceArray(dm);
- collmd->numfaces = dm->getNumTessFaces(dm);
-
- // create bounding box hierarchy
- collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->x, numverts, ob->pd->pdef_sboft);
-
- collmd->time = current_time;
- }
- else if(numverts == collmd->numverts)
- {
- // put positions to old positions
- tempVert = collmd->x;
- collmd->x = collmd->xnew;
- collmd->xnew = tempVert;
-
- memcpy(collmd->xnew, dm->getVertArray(dm), numverts*sizeof(MVert));
-
- for ( i = 0; i < numverts; i++ )
- {
- // we save global positions
- mul_m4_v3( ob->obmat, collmd->xnew[i].co );
- }
-
- memcpy(collmd->current_xnew, collmd->x, numverts*sizeof(MVert));
- memcpy(collmd->current_x, collmd->x, numverts*sizeof(MVert));
-
- /* check if GUI setting has changed for bvh */
- if(collmd->bvhtree)
- {
- if(ob->pd->pdef_sboft != BLI_bvhtree_getepsilon(collmd->bvhtree))
- {
- BLI_bvhtree_free(collmd->bvhtree);
- collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sboft);
- }
-
- }
-
- /* happens on file load (ONLY when i decomment changes in readfile.c) */
- if(!collmd->bvhtree)
- {
- collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sboft);
- }
- else
- {
- // recalc static bounding boxes
- bvhtree_update_from_mvert ( collmd->bvhtree, collmd->mfaces, collmd->numfaces, collmd->current_x, collmd->current_xnew, collmd->numverts, 1 );
- }
-
- collmd->time = current_time;
- }
- else if(numverts != collmd->numverts)
- {
- collisionModifier_freeData((ModifierData *)collmd);
- }
-
- }
- else if(current_time < collmd->time)
- {
- collisionModifier_freeData((ModifierData *)collmd);
- }
- else
- {
- if(numverts != collmd->numverts)
- {
- collisionModifier_freeData((ModifierData *)collmd);
- }
- }
- }
-
- if(dm)
- dm->release(dm);
-}
-
-
-
-/* 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);
- }
-
- if(surmd->dm)
- surmd->dm->release(surmd->dm);
-
- if(surmd->x)
- MEM_freeN(surmd->x);
-
- if(surmd->v)
- MEM_freeN(surmd->v);
-
- 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, int useRenderParams, int isFinalCalc)
-{
- 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, 0);
- else surmd->dm = get_dm(md->scene, ob, NULL, NULL, NULL, 0);
-
- if(!ob->pd)
- {
- printf("surfaceModifier_deformVerts: Should not happen!\n");
- return;
- }
-
- if(surmd->dm)
- {
- int init = 0;
- float *vec;
- MVert *x, *v;
-
- CDDM_apply_vert_coords(surmd->dm, vertexCos);
- CDDM_calc_normals(surmd->dm);
-
- numverts = surmd->dm->getNumVerts ( surmd->dm );
-
- if(numverts != surmd->numverts || surmd->x == NULL || surmd->v == NULL || md->scene->r.cfra != surmd->cfra+1) {
- if(surmd->x) {
- MEM_freeN(surmd->x);
- surmd->x = NULL;
- }
- if(surmd->v) {
- MEM_freeN(surmd->v);
- surmd->v = NULL;
- }
-
- surmd->x = MEM_callocN(numverts * sizeof(MVert), "MVert");
- surmd->v = MEM_callocN(numverts * sizeof(MVert), "MVert");
-
- surmd->numverts = numverts;
-
- init = 1;
- }
-
- /* convert to global coordinates and calculate velocity */
- for(i = 0, x = surmd->x, v = surmd->v; i<numverts; i++, x++, v++) {
- vec = CDDM_get_vert(surmd->dm, i)->co;
- mul_m4_v3(ob->obmat, vec);
-
- if(init)
- v->co[0] = v->co[1] = v->co[2] = 0.0f;
- else
- sub_v3_v3v3(v->co, vec, x->co);
-
- copy_v3_v3(x->co, vec);
- }
-
- surmd->cfra = md->scene->r.cfra;
-
- if(surmd->bvhtree)
- free_bvhtree_from_mesh(surmd->bvhtree);
- else
- surmd->bvhtree = MEM_callocN(sizeof(BVHTreeFromMesh), "BVHTreeFromMesh");
-
- if(surmd->dm->getNumFaces(surmd->dm))
- bvhtree_from_mesh_faces(surmd->bvhtree, surmd->dm, 0.0, 2, 6);
- else
- bvhtree_from_mesh_edges(surmd->bvhtree, surmd->dm, 0.0, 2, 6);
- }
-}
-
-
-/* Boolean */
-
-static void booleanModifier_copyData(ModifierData *md, ModifierData *target)
-{
- BooleanModifierData *bmd = (BooleanModifierData*) md;
- BooleanModifierData *tbmd = (BooleanModifierData*) target;
-
- tbmd->object = bmd->object;
- tbmd->operation = bmd->operation;
-}
-
-static int booleanModifier_isDisabled(ModifierData *md, int useRenderParams)
-{
- BooleanModifierData *bmd = (BooleanModifierData*) md;
-
- return !bmd->object;
-}
-
-static void booleanModifier_foreachObjectLink(
- ModifierData *md, Object *ob,
- void (*walk)(void *userData, Object *ob, Object **obpoin),
- void *userData)
-{
- BooleanModifierData *bmd = (BooleanModifierData*) md;
-
- walk(userData, ob, &bmd->object);
-}
-
-static void booleanModifier_updateDepgraph(
- ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
- DagNode *obNode)
-{
- BooleanModifierData *bmd = (BooleanModifierData*) md;
-
- if(bmd->object) {
- DagNode *curNode = dag_get_node(forest, bmd->object);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Boolean Modifier");
- }
-}
-
-static DerivedMesh *booleanModifier_applyModifier(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- int useRenderParams, int isFinalCalc)
-{
- BooleanModifierData *bmd = (BooleanModifierData*) md;
- DerivedMesh *dm = bmd->object->derivedFinal;
-
- /* we do a quick sanity check */
- if(dm && (derivedData->getNumTessFaces(derivedData) > 3)
- && bmd->object && dm->getNumTessFaces(dm) > 3) {
- DerivedMesh *result = NewBooleanDerivedMesh(dm, bmd->object, derivedData, ob,
- 1 + bmd->operation);
-
- /* if new mesh returned, return it; otherwise there was
- * an error, so delete the modifier object */
- if(result)
- return result;
- else
- modifier_setError(md, "Can't execute boolean operation.");
- }
-
- return derivedData;
-}
-
-static CustomDataMask booleanModifier_requiredDataMask(Object *ob, ModifierData *md)
-{
- CustomDataMask dataMask = (1 << CD_MTFACE) + (1 << CD_MEDGE);
-
- dataMask |= (1 << CD_MDEFORMVERT);
-
- return dataMask;
-}
-
-/* Particles */
-static void particleSystemModifier_initData(ModifierData *md)
-{
- ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
- psmd->psys= 0;
- psmd->dm=0;
- psmd->totdmvert= psmd->totdmedge= psmd->totdmface= 0;
-}
-static void particleSystemModifier_freeData(ModifierData *md)
-{
- ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
-
- if(psmd->dm){
- psmd->dm->needsFree = 1;
- psmd->dm->release(psmd->dm);
- psmd->dm=0;
- }
-
- /* ED_object_modifier_remove may have freed this first before calling
- * modifier_free (which calls this function) */
- if(psmd->psys)
- psmd->psys->flag |= PSYS_DELETE;
-}
-static void particleSystemModifier_copyData(ModifierData *md, ModifierData *target)
-{
- ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
- ParticleSystemModifierData *tpsmd= (ParticleSystemModifierData*) target;
-
- tpsmd->dm = 0;
- tpsmd->totdmvert = tpsmd->totdmedge = tpsmd->totdmface = 0;
- //tpsmd->facepa = 0;
- tpsmd->flag = psmd->flag;
- /* need to keep this to recognise a bit later in copy_object */
- tpsmd->psys = psmd->psys;
-}
-
-static CustomDataMask particleSystemModifier_requiredDataMask(Object *ob, ModifierData *md)
-{
- ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
- CustomDataMask dataMask = 0;
- Material *ma;
- MTex *mtex;
- int i;
-
- if(!psmd->psys->part)
- return 0;
-
- ma= give_current_material(ob, psmd->psys->part->omat);
- if(ma) {
- for(i=0; i<MAX_MTEX; i++) {
- mtex=ma->mtex[i];
- if(mtex && (ma->septex & (1<<i))==0)
- if(mtex->pmapto && (mtex->texco & TEXCO_UV))
- dataMask |= (1 << CD_MTFACE);
- }
- }
-
- if(psmd->psys->part->tanfac!=0.0)
- dataMask |= (1 << CD_MTFACE);
-
- /* ask for vertexgroups if we need them */
- for(i=0; i<PSYS_TOT_VG; i++){
- if(psmd->psys->vgroup[i]){
- dataMask |= (1 << CD_MDEFORMVERT);
- break;
- }
- }
-
- /* 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;
-}
-
-/* saves the current emitter state for a particle system and calculates particles */
-static void particleSystemModifier_deformVerts(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
-{
- DerivedMesh *dm = derivedData;
- ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
- ParticleSystem * psys=0;
- int needsFree=0;
-
- if(ob->particlesystem.first)
- psys=psmd->psys;
- else
- return;
-
- if(!psys_check_enabled(ob, psys))
- return;
-
- if(dm==0) {
- dm= get_dm(md->scene, ob, NULL, NULL, vertexCos, 1);
-
- if(!dm)
- return;
-
- needsFree= 1;
- }
-
- /* clear old dm */
- if(psmd->dm){
- psmd->dm->needsFree = 1;
- psmd->dm->release(psmd->dm);
- }
-
- /* make new dm */
- psmd->dm=CDDM_copy(dm, 0);
- CDDM_apply_vert_coords(psmd->dm, vertexCos);
- CDDM_calc_normals(psmd->dm);
-
- if(needsFree){
- dm->needsFree = 1;
- dm->release(dm);
- }
-
- /* protect dm */
- psmd->dm->needsFree = 0;
-
- /* report change in mesh structure */
- if(psmd->dm->getNumVerts(psmd->dm)!=psmd->totdmvert ||
- psmd->dm->getNumEdges(psmd->dm)!=psmd->totdmedge ||
- psmd->dm->getNumTessFaces(psmd->dm)!=psmd->totdmface){
- /* in file read dm hasn't really changed but just wasn't saved in file */
-
- psys->recalc |= PSYS_RECALC_RESET;
- psmd->flag |= eParticleSystemFlag_DM_changed;
-
- psmd->totdmvert= psmd->dm->getNumVerts(psmd->dm);
- psmd->totdmedge= psmd->dm->getNumEdges(psmd->dm);
- psmd->totdmface= psmd->dm->getNumTessFaces(psmd->dm);
- }
-
- if(psys) {
- psmd->flag &= ~eParticleSystemFlag_psys_updated;
- particle_system_update(md->scene, ob, psys);
- psmd->flag |= eParticleSystemFlag_psys_updated;
- psmd->flag &= ~eParticleSystemFlag_DM_changed;
- }
-}
-
-/* disabled particles in editmode for now, until support for proper derivedmesh
- * updates is coded */
-#if 0
-static void particleSystemModifier_deformVertsEM(
- ModifierData *md, Object *ob, BMEditMesh *editData,
- DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
-{
- DerivedMesh *dm = derivedData;
-
- if(!derivedData) dm = CDDM_from_BMEditMesh(editData, ob->data);
-
- particleSystemModifier_deformVerts(md, ob, dm, vertexCos, numVerts);
-
- if(!derivedData) dm->release(dm);
-}
-#endif
-
-/* Particle Instance */
-static void particleInstanceModifier_initData(ModifierData *md)
-{
- ParticleInstanceModifierData *pimd= (ParticleInstanceModifierData*) md;
-
- pimd->flag = eParticleInstanceFlag_Parents|eParticleInstanceFlag_Unborn|
- eParticleInstanceFlag_Alive|eParticleInstanceFlag_Dead;
- pimd->psys = 1;
- pimd->position = 1.0f;
- pimd->axis = 2;
-
-}
-static void particleInstanceModifier_copyData(ModifierData *md, ModifierData *target)
-{
- ParticleInstanceModifierData *pimd= (ParticleInstanceModifierData*) md;
- ParticleInstanceModifierData *tpimd= (ParticleInstanceModifierData*) target;
-
- tpimd->ob = pimd->ob;
- tpimd->psys = pimd->psys;
- tpimd->flag = pimd->flag;
- tpimd->axis = pimd->axis;
- tpimd->position = pimd->position;
- tpimd->random_position = pimd->random_position;
-}
-
-static int particleInstanceModifier_dependsOnTime(ModifierData *md)
-{
- return 0;
-}
-static void particleInstanceModifier_updateDepgraph(ModifierData *md, DagForest *forest,
- Scene *scene,Object *ob, DagNode *obNode)
-{
- ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData*) md;
-
- if (pimd->ob) {
- DagNode *curNode = dag_get_node(forest, pimd->ob);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA | DAG_RL_OB_DATA,
- "Particle Instance Modifier");
- }
-}
-
-static void particleInstanceModifier_foreachObjectLink(ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
-{
- ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData*) md;
-
- walk(userData, ob, &pimd->ob);
-}
-
-static DerivedMesh * particleInstanceModifier_applyModifier(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- int useRenderParams, int isFinalCalc)
-{
- DerivedMesh *dm = derivedData, *result;
- ParticleInstanceModifierData *pimd= (ParticleInstanceModifierData*) md;
- ParticleSimulationData sim;
- ParticleSystem * psys=0;
- ParticleData *pa=0, *pars=0;
- MFace *mface, *orig_mface;
- MVert *mvert, *orig_mvert;
- int i,totvert, totpart=0, totface, maxvert, maxface, first_particle=0;
- short track=ob->trackflag%3, trackneg, axis = pimd->axis;
- float max_co=0.0, min_co=0.0, temp_co[3], cross[3];
- float *size=NULL;
-
- trackneg=((ob->trackflag>2)?1:0);
-
- if(pimd->ob==ob){
- pimd->ob=0;
- return derivedData;
- }
-
- if(pimd->ob){
- psys = BLI_findlink(&pimd->ob->particlesystem,pimd->psys-1);
- if(psys==0 || psys->totpart==0)
- return derivedData;
- }
- else return derivedData;
-
- if(pimd->flag & eParticleInstanceFlag_Parents)
- totpart+=psys->totpart;
- if(pimd->flag & eParticleInstanceFlag_Children){
- if(totpart==0)
- first_particle=psys->totpart;
- totpart+=psys->totchild;
- }
-
- if(totpart==0)
- return derivedData;
-
- sim.scene = md->scene;
- sim.ob = pimd->ob;
- sim.psys = psys;
- sim.psmd = psys_get_modifier(pimd->ob, psys);
-
- if(pimd->flag & eParticleInstanceFlag_UseSize) {
- int p;
- float *si;
- si = size = MEM_callocN(totpart * sizeof(float), "particle size array");
-
- if(pimd->flag & eParticleInstanceFlag_Parents) {
- for(p=0, pa= psys->particles; p<psys->totpart; p++, pa++, si++)
- *si = pa->size;
- }
-
- if(pimd->flag & eParticleInstanceFlag_Children) {
- ChildParticle *cpa = psys->child;
-
- for(p=0; p<psys->totchild; p++, cpa++, si++) {
- *si = psys_get_child_size(psys, cpa, 0.0f, NULL);
- }
- }
- }
-
- pars=psys->particles;
-
- totvert=dm->getNumVerts(dm);
- totface=dm->getNumTessFaces(dm);
-
- maxvert=totvert*totpart;
- maxface=totface*totpart;
-
- psys->lattice=psys_get_lattice(&sim);
-
- if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED){
-
- 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];
- }
-
- result = CDDM_from_template(dm, maxvert,dm->getNumEdges(dm)*totpart,maxface, 0, 0);
-
- mvert=result->getVertArray(result);
- orig_mvert=dm->getVertArray(dm);
-
- for(i=0; i<maxvert; i++){
- MVert *inMV;
- MVert *mv = mvert + i;
- ParticleKey state;
-
- inMV = orig_mvert + i%totvert;
- DM_copy_vert_data(dm, result, i%totvert, i, 1);
- *mv = *inMV;
-
- /*change orientation based on object trackflag*/
- VECCOPY(temp_co,mv->co);
- mv->co[axis]=temp_co[track];
- mv->co[(axis+1)%3]=temp_co[(track+1)%3];
- mv->co[(axis+2)%3]=temp_co[(track+2)%3];
-
- if((psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) && pimd->flag & eParticleInstanceFlag_Path){
- float ran = 0.0f;
- if(pimd->random_position != 0.0f) {
- BLI_srandom(psys->seed + (i/totvert)%totpart);
- ran = pimd->random_position * BLI_frand();
- }
-
- if(pimd->flag & eParticleInstanceFlag_KeepShape) {
- state.time = pimd->position * (1.0f - ran);
- }
- else {
- state.time=(mv->co[axis]-min_co)/(max_co-min_co) * pimd->position * (1.0f - ran);
-
- if(trackneg)
- state.time=1.0f-state.time;
-
- mv->co[axis] = 0.0;
- }
-
- psys_get_particle_on_path(&sim, first_particle + i/totvert, &state,1);
-
- normalize_v3(state.vel);
-
- /* TODO: incremental rotations somehow */
- if(state.vel[axis] < -0.9999 || state.vel[axis] > 0.9999) {
- state.rot[0] = 1;
- state.rot[1] = state.rot[2] = state.rot[3] = 0.0f;
- }
- else {
- float temp[3] = {0.0f,0.0f,0.0f};
- temp[axis] = 1.0f;
-
- cross_v3_v3v3(cross, temp, state.vel);
-
- /* state.vel[axis] is the only component surviving from a dot product with the axis */
- axis_angle_to_quat(state.rot,cross,saacos(state.vel[axis]));
- }
-
- }
- else{
- state.time=-1.0;
- psys_get_particle_state(&sim, first_particle + i/totvert, &state,1);
- }
-
- mul_qt_v3(state.rot,mv->co);
- if(pimd->flag & eParticleInstanceFlag_UseSize)
- mul_v3_fl(mv->co, size[i/totvert]);
- VECADD(mv->co,mv->co,state.co);
- }
-
- mface=result->getTessFaceArray(result);
- orig_mface=dm->getTessFaceArray(dm);
-
- for(i=0; i<maxface; i++){
- MFace *inMF;
- MFace *mf = mface + i;
-
- if(pimd->flag & eParticleInstanceFlag_Parents){
- if(i/totface>=psys->totpart){
- if(psys->part->childtype==PART_CHILD_PARTICLES)
- pa=psys->particles+(psys->child+i/totface-psys->totpart)->parent;
- else
- pa=0;
- }
- else
- pa=pars+i/totface;
- }
- else{
- if(psys->part->childtype==PART_CHILD_PARTICLES)
- pa=psys->particles+(psys->child+i/totface)->parent;
- else
- pa=0;
- }
-
- if(pa){
- if(pa->alive==PARS_UNBORN && (pimd->flag&eParticleInstanceFlag_Unborn)==0) continue;
- if(pa->alive==PARS_ALIVE && (pimd->flag&eParticleInstanceFlag_Alive)==0) continue;
- if(pa->alive==PARS_DEAD && (pimd->flag&eParticleInstanceFlag_Dead)==0) continue;
- }
-
- inMF = orig_mface + i%totface;
- DM_copy_tessface_data(dm, result, i%totface, i, 1);
- *mf = *inMF;
-
- mf->v1+=(i/totface)*totvert;
- mf->v2+=(i/totface)*totvert;
- mf->v3+=(i/totface)*totvert;
- if(mf->v4)
- mf->v4+=(i/totface)*totvert;
- }
-
- CDDM_calc_edges(result);
- CDDM_calc_normals(result);
-
- if(psys->lattice){
- end_latt_deform(psys->lattice);
- psys->lattice= NULL;
- }
-
- CDDM_tessfaces_to_faces(result);
- if(size)
- MEM_freeN(size);
-
- return result;
-}
-static DerivedMesh *particleInstanceModifier_applyModifierEM(
- ModifierData *md, Object *ob, BMEditMesh *editData,
- DerivedMesh *derivedData)
-{
- return particleInstanceModifier_applyModifier(md, ob, derivedData, 0, 1);
-}
-
-/* Explode */
-static void explodeModifier_initData(ModifierData *md)
-{
- ExplodeModifierData *emd= (ExplodeModifierData*) md;
-
- emd->facepa=0;
- emd->flag |= eExplodeFlag_Unborn+eExplodeFlag_Alive+eExplodeFlag_Dead;
-}
-static void explodeModifier_freeData(ModifierData *md)
-{
- ExplodeModifierData *emd= (ExplodeModifierData*) md;
-
- if(emd->facepa) MEM_freeN(emd->facepa);
-}
-static void explodeModifier_copyData(ModifierData *md, ModifierData *target)
-{
- ExplodeModifierData *emd= (ExplodeModifierData*) md;
- ExplodeModifierData *temd= (ExplodeModifierData*) target;
-
- temd->facepa = 0;
- temd->flag = emd->flag;
- temd->protect = emd->protect;
- temd->vgroup = emd->vgroup;
-}
-static int explodeModifier_dependsOnTime(ModifierData *md)
-{
- return 1;
-}
-static CustomDataMask explodeModifier_requiredDataMask(Object *ob, ModifierData *md)
-{
- ExplodeModifierData *emd= (ExplodeModifierData*) md;
- CustomDataMask dataMask = 0;
-
- if(emd->vgroup)
- dataMask |= (1 << CD_MDEFORMVERT);
-
- return dataMask;
-}
-
-static void explodeModifier_createFacepa(ExplodeModifierData *emd,
- ParticleSystemModifierData *psmd,
- Object *ob, DerivedMesh *dm)
-{
- ParticleSystem *psys=psmd->psys;
- MFace *fa=0, *mface=0;
- MVert *mvert = 0;
- ParticleData *pa;
- KDTree *tree;
- float center[3], co[3];
- int *facepa=0,*vertpa=0,totvert=0,totface=0,totpart=0;
- int i,p,v1,v2,v3,v4=0;
-
- mvert = dm->getVertArray(dm);
- mface = dm->getTessFaceArray(dm);
- totface= dm->getNumTessFaces(dm);
- totvert= dm->getNumVerts(dm);
- totpart= psmd->psys->totpart;
-
- BLI_srandom(psys->seed);
-
- if(emd->facepa)
- MEM_freeN(emd->facepa);
-
- facepa = emd->facepa = MEM_callocN(sizeof(int)*totface, "explode_facepa");
-
- vertpa = MEM_callocN(sizeof(int)*totvert, "explode_vertpa");
-
- /* initialize all faces & verts to no particle */
- for(i=0; i<totface; i++)
- facepa[i]=totpart;
-
- for (i=0; i<totvert; i++)
- vertpa[i]=totpart;
-
- /* set protected verts */
- if(emd->vgroup){
- MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
- float val;
- if(dvert){
- for(i=0; i<totvert; i++){
- val = BLI_frand();
- val = (1.0f-emd->protect)*val + emd->protect*0.5f;
- if(val < defvert_find_weight(dvert+i,emd->vgroup-1))
- vertpa[i] = -1;
- }
- }
- }
-
- /* make tree of emitter locations */
- tree=BLI_kdtree_new(totpart);
- for(p=0,pa=psys->particles; p<totpart; p++,pa++){
- psys_particle_on_dm(psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,0,0);
- BLI_kdtree_insert(tree, p, co, NULL);
- }
- BLI_kdtree_balance(tree);
-
- /* set face-particle-indexes to nearest particle to face center */
- for(i=0,fa=mface; i<totface; i++,fa++){
- add_v3_v3v3(center,mvert[fa->v1].co,mvert[fa->v2].co);
- add_v3_v3v3(center,center,mvert[fa->v3].co);
- if(fa->v4){
- add_v3_v3v3(center,center,mvert[fa->v4].co);
- mul_v3_fl(center,0.25);
- }
- else
- mul_v3_fl(center,0.3333f);
-
- p= BLI_kdtree_find_nearest(tree,center,NULL,NULL);
-
- v1=vertpa[fa->v1];
- v2=vertpa[fa->v2];
- v3=vertpa[fa->v3];
- if(fa->v4)
- v4=vertpa[fa->v4];
-
- if(v1>=0 && v2>=0 && v3>=0 && (fa->v4==0 || v4>=0))
- facepa[i]=p;
-
- if(v1>=0) vertpa[fa->v1]=p;
- if(v2>=0) vertpa[fa->v2]=p;
- if(v3>=0) vertpa[fa->v3]=p;
- if(fa->v4 && v4>=0) vertpa[fa->v4]=p;
- }
-
- if(vertpa) MEM_freeN(vertpa);
- BLI_kdtree_free(tree);
-}
-
-static int edgesplit_get(EdgeHash *edgehash, int v1, int v2)
-{
- return GET_INT_FROM_POINTER(BLI_edgehash_lookup(edgehash, v1, v2));
-}
-
-static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, DerivedMesh *dm){
- DerivedMesh *splitdm;
- MFace *mf=0,*df1=0,*df2=0,*df3=0;
- MFace *mface=CDDM_get_tessfaces(dm);
- MVert *dupve, *mv;
- EdgeHash *edgehash;
- EdgeHashIterator *ehi;
- int totvert=dm->getNumVerts(dm);
- int totface=dm->getNumTessFaces(dm);
-
- int *facesplit = MEM_callocN(sizeof(int)*totface,"explode_facesplit");
- int *vertpa = MEM_callocN(sizeof(int)*totvert,"explode_vertpa2");
- int *facepa = emd->facepa;
- int *fs, totesplit=0,totfsplit=0,totin=0,curdupvert=0,curdupface=0,curdupin=0;
- int i,j,v1,v2,v3,v4,esplit;
-
- edgehash= BLI_edgehash_new();
-
- /* recreate vertpa from facepa calculation */
- for (i=0,mf=mface; i<totface; i++,mf++) {
- vertpa[mf->v1]=facepa[i];
- vertpa[mf->v2]=facepa[i];
- vertpa[mf->v3]=facepa[i];
- if(mf->v4)
- vertpa[mf->v4]=facepa[i];
- }
-
- /* mark edges for splitting and how to split faces */
- for (i=0,mf=mface,fs=facesplit; i<totface; i++,mf++,fs++) {
- if(mf->v4){
- v1=vertpa[mf->v1];
- v2=vertpa[mf->v2];
- v3=vertpa[mf->v3];
- v4=vertpa[mf->v4];
-
- if(v1!=v2){
- BLI_edgehash_insert(edgehash, mf->v1, mf->v2, NULL);
- (*fs)++;
- }
-
- if(v2!=v3){
- BLI_edgehash_insert(edgehash, mf->v2, mf->v3, NULL);
- (*fs)++;
- }
-
- if(v3!=v4){
- BLI_edgehash_insert(edgehash, mf->v3, mf->v4, NULL);
- (*fs)++;
- }
-
- if(v1!=v4){
- BLI_edgehash_insert(edgehash, mf->v1, mf->v4, NULL);
- (*fs)++;
- }
-
- if(*fs==2){
- if((v1==v2 && v3==v4) || (v1==v4 && v2==v3))
- *fs=1;
- else if(v1!=v2){
- if(v1!=v4)
- BLI_edgehash_insert(edgehash, mf->v2, mf->v3, NULL);
- else
- BLI_edgehash_insert(edgehash, mf->v3, mf->v4, NULL);
- }
- else{
- if(v1!=v4)
- BLI_edgehash_insert(edgehash, mf->v1, mf->v2, NULL);
- else
- BLI_edgehash_insert(edgehash, mf->v1, mf->v4, NULL);
- }
- }
- }
- }
-
- /* count splits & reindex */
- ehi= BLI_edgehashIterator_new(edgehash);
- totesplit=totvert;
- for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
- BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(totesplit));
- totesplit++;
- }
- BLI_edgehashIterator_free(ehi);
-
- /* count new faces due to splitting */
- for(i=0,fs=facesplit; i<totface; i++,fs++){
- if(*fs==1)
- totfsplit+=1;
- else if(*fs==2)
- totfsplit+=2;
- else if(*fs==3)
- totfsplit+=3;
- else if(*fs==4){
- totfsplit+=3;
-
- mf=dm->getTessFaceData(dm,i,CD_MFACE);//CDDM_get_tessface(dm,i);
-
- if(vertpa[mf->v1]!=vertpa[mf->v2] && vertpa[mf->v2]!=vertpa[mf->v3])
- totin++;
- }
- }
-
- splitdm= CDDM_from_template(dm, totesplit+totin, dm->getNumEdges(dm),totface+totfsplit, 0, 0);
-
- /* copy new faces & verts (is it really this painful with custom data??) */
- for(i=0; i<totvert; i++){
- MVert source;
- MVert *dest;
- dm->getVert(dm, i, &source);
- dest = CDDM_get_vert(splitdm, i);
-
- DM_copy_vert_data(dm, splitdm, i, i, 1);
- *dest = source;
- }
- for(i=0; i<totface; i++){
- MFace source;
- MFace *dest;
- dm->getTessFace(dm, i, &source);
- dest = CDDM_get_tessface(splitdm, i);
-
- DM_copy_tessface_data(dm, splitdm, i, i, 1);
- *dest = source;
- }
-
- /* override original facepa (original pointer is saved in caller function) */
- facepa= MEM_callocN(sizeof(int)*(totface+totfsplit),"explode_facepa");
- memcpy(facepa,emd->facepa,totface*sizeof(int));
- emd->facepa=facepa;
-
- /* create new verts */
- curdupvert=totvert;
- ehi= BLI_edgehashIterator_new(edgehash);
- for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
- BLI_edgehashIterator_getKey(ehi, &i, &j);
- esplit= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
- mv=CDDM_get_vert(splitdm,j);
- dupve=CDDM_get_vert(splitdm,esplit);
-
- DM_copy_vert_data(splitdm,splitdm,j,esplit,1);
-
- *dupve=*mv;
-
- mv=CDDM_get_vert(splitdm,i);
-
- VECADD(dupve->co,dupve->co,mv->co);
- mul_v3_fl(dupve->co,0.5);
- }
- BLI_edgehashIterator_free(ehi);
-
- /* create new faces */
- curdupface=totface;
- curdupin=totesplit;
- for(i=0,fs=facesplit; i<totface; i++,fs++){
- if(*fs){
- mf=CDDM_get_tessface(splitdm,i);
-
- v1=vertpa[mf->v1];
- v2=vertpa[mf->v2];
- v3=vertpa[mf->v3];
- v4=vertpa[mf->v4];
- /* ouch! creating new faces & remapping them to new verts is no fun */
- if(*fs==1){
- df1=CDDM_get_tessface(splitdm,curdupface);
- DM_copy_tessface_data(splitdm,splitdm,i,curdupface,1);
- *df1=*mf;
- curdupface++;
-
- if(v1==v2){
- df1->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
- df1->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
- mf->v3=df1->v2;
- mf->v4=df1->v1;
- }
- else{
- df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
- df1->v4=edgesplit_get(edgehash, mf->v3, mf->v4);
- mf->v2=df1->v1;
- mf->v3=df1->v4;
- }
-
- facepa[i]=v1;
- facepa[curdupface-1]=v3;
-
- test_index_face(df1, &splitdm->faceData, curdupface, (df1->v4 ? 4 : 3));
- }
- if(*fs==2){
- df1=CDDM_get_tessface(splitdm,curdupface);
- DM_copy_tessface_data(splitdm,splitdm,i,curdupface,1);
- *df1=*mf;
- curdupface++;
-
- df2=CDDM_get_tessface(splitdm,curdupface);
- DM_copy_tessface_data(splitdm,splitdm,i,curdupface,1);
- *df2=*mf;
- curdupface++;
-
- if(v1!=v2){
- if(v1!=v4){
- df1->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
- df1->v2=edgesplit_get(edgehash, mf->v1, mf->v2);
- df2->v1=df1->v3=mf->v2;
- df2->v3=df1->v4=mf->v4;
- df2->v2=mf->v3;
-
- mf->v2=df1->v2;
- mf->v3=df1->v1;
-
- df2->v4=mf->v4=0;
-
- facepa[i]=v1;
- }
- else{
- df1->v2=edgesplit_get(edgehash, mf->v1, mf->v2);
- df1->v3=edgesplit_get(edgehash, mf->v2, mf->v3);
- df1->v4=mf->v3;
- df2->v2=mf->v3;
- df2->v3=mf->v4;
-
- mf->v1=df1->v2;
- mf->v3=df1->v3;
-
- df2->v4=mf->v4=0;
-
- facepa[i]=v2;
- }
- facepa[curdupface-1]=facepa[curdupface-2]=v3;
- }
- else{
- if(v1!=v4){
- df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
- df1->v4=edgesplit_get(edgehash, mf->v1, mf->v4);
- df1->v2=mf->v3;
-
- mf->v1=df1->v4;
- mf->v2=df1->v3;
- mf->v3=mf->v4;
-
- df2->v4=mf->v4=0;
-
- facepa[i]=v4;
- }
- else{
- df1->v3=edgesplit_get(edgehash, mf->v2, mf->v3);
- df1->v4=edgesplit_get(edgehash, mf->v3, mf->v4);
- df1->v1=mf->v4;
- df1->v2=mf->v2;
- df2->v3=mf->v4;
-
- mf->v1=df1->v4;
- mf->v2=df1->v3;
-
- df2->v4=mf->v4=0;
-
- facepa[i]=v3;
- }
-
- facepa[curdupface-1]=facepa[curdupface-2]=v1;
- }
-
- test_index_face(df1, &splitdm->faceData, curdupface-2, (df1->v4 ? 4 : 3));
- test_index_face(df1, &splitdm->faceData, curdupface-1, (df1->v4 ? 4 : 3));
- }
- else if(*fs==3){
- df1=CDDM_get_tessface(splitdm,curdupface);
- DM_copy_tessface_data(splitdm,splitdm,i,curdupface,1);
- *df1=*mf;
- curdupface++;
-
- df2=CDDM_get_tessface(splitdm,curdupface);
- DM_copy_tessface_data(splitdm,splitdm,i,curdupface,1);
- *df2=*mf;
- curdupface++;
-
- df3=CDDM_get_tessface(splitdm,curdupface);
- DM_copy_tessface_data(splitdm,splitdm,i,curdupface,1);
- *df3=*mf;
- curdupface++;
-
- if(v1==v2){
- df2->v1=df1->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
- df3->v1=df1->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
- df3->v3=df2->v2=df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
- df3->v2=mf->v3;
- df2->v3=mf->v4;
- df1->v4=df2->v4=df3->v4=0;
-
- mf->v3=df1->v2;
- mf->v4=df1->v1;
-
- facepa[i]=facepa[curdupface-3]=v1;
- facepa[curdupface-1]=v3;
- facepa[curdupface-2]=v4;
- }
- else if(v2==v3){
- df3->v1=df2->v3=df1->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
- df2->v2=df1->v2=edgesplit_get(edgehash, mf->v1, mf->v2);
- df3->v2=df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
-
- df3->v3=mf->v4;
- df2->v1=mf->v1;
- df1->v4=df2->v4=df3->v4=0;
-
- mf->v1=df1->v2;
- mf->v4=df1->v3;
-
- facepa[i]=facepa[curdupface-3]=v2;
- facepa[curdupface-1]=v4;
- facepa[curdupface-2]=v1;
- }
- else if(v3==v4){
- df3->v2=df2->v1=df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
- df2->v3=df1->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
- df3->v3=df1->v3=edgesplit_get(edgehash, mf->v1, mf->v4);
-
- df3->v1=mf->v1;
- df2->v2=mf->v2;
- df1->v4=df2->v4=df3->v4=0;
-
- mf->v1=df1->v3;
- mf->v2=df1->v2;
-
- facepa[i]=facepa[curdupface-3]=v3;
- facepa[curdupface-1]=v1;
- facepa[curdupface-2]=v2;
- }
- else{
- df3->v1=df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
- df3->v3=df2->v1=df1->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
- df2->v3=df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
-
- df3->v2=mf->v2;
- df2->v2=mf->v3;
- df1->v4=df2->v4=df3->v4=0;
-
- mf->v2=df1->v1;
- mf->v3=df1->v3;
-
- facepa[i]=facepa[curdupface-3]=v1;
- facepa[curdupface-1]=v2;
- facepa[curdupface-2]=v3;
- }
-
- test_index_face(df1, &splitdm->faceData, curdupface-3, (df1->v4 ? 4 : 3));
- test_index_face(df1, &splitdm->faceData, curdupface-2, (df1->v4 ? 4 : 3));
- test_index_face(df1, &splitdm->faceData, curdupface-1, (df1->v4 ? 4 : 3));
- }
- else if(*fs==4){
- if(v1!=v2 && v2!=v3){
-
- /* set new vert to face center */
- mv=CDDM_get_vert(splitdm,mf->v1);
- dupve=CDDM_get_vert(splitdm,curdupin);
- DM_copy_vert_data(splitdm,splitdm,mf->v1,curdupin,1);
- *dupve=*mv;
-
- mv=CDDM_get_vert(splitdm,mf->v2);
- VECADD(dupve->co,dupve->co,mv->co);
- mv=CDDM_get_vert(splitdm,mf->v3);
- VECADD(dupve->co,dupve->co,mv->co);
- mv=CDDM_get_vert(splitdm,mf->v4);
- VECADD(dupve->co,dupve->co,mv->co);
- mul_v3_fl(dupve->co,0.25);
-
-
- df1=CDDM_get_tessface(splitdm,curdupface);
- DM_copy_tessface_data(splitdm,splitdm,i,curdupface,1);
- *df1=*mf;
- curdupface++;
-
- df2=CDDM_get_tessface(splitdm,curdupface);
- DM_copy_tessface_data(splitdm,splitdm,i,curdupface,1);
- *df2=*mf;
- curdupface++;
-
- df3=CDDM_get_tessface(splitdm,curdupface);
- DM_copy_tessface_data(splitdm,splitdm,i,curdupface,1);
- *df3=*mf;
- curdupface++;
-
- df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
- df3->v2=df1->v3=edgesplit_get(edgehash, mf->v2, mf->v3);
-
- df2->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
- df3->v4=df2->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
-
- df3->v1=df2->v2=df1->v4=curdupin;
-
- mf->v2=df1->v1;
- mf->v3=curdupin;
- mf->v4=df2->v1;
-
- curdupin++;
-
- facepa[i]=v1;
- facepa[curdupface-3]=v2;
- facepa[curdupface-2]=v3;
- facepa[curdupface-1]=v4;
-
- test_index_face(df1, &splitdm->faceData, curdupface-3, (df1->v4 ? 4 : 3));
-
- test_index_face(df1, &splitdm->faceData, curdupface-2, (df1->v4 ? 4 : 3));
- test_index_face(df1, &splitdm->faceData, curdupface-1, (df1->v4 ? 4 : 3));
- }
- else{
- df1=CDDM_get_tessface(splitdm,curdupface);
- DM_copy_tessface_data(splitdm,splitdm,i,curdupface,1);
- *df1=*mf;
- curdupface++;
-
- df2=CDDM_get_tessface(splitdm,curdupface);
- DM_copy_tessface_data(splitdm,splitdm,i,curdupface,1);
- *df2=*mf;
- curdupface++;
-
- df3=CDDM_get_tessface(splitdm,curdupface);
- DM_copy_tessface_data(splitdm,splitdm,i,curdupface,1);
- *df3=*mf;
- curdupface++;
-
- if(v2==v3){
- df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
- df3->v1=df1->v2=df1->v3=edgesplit_get(edgehash, mf->v2, mf->v3);
- df2->v1=df1->v4=edgesplit_get(edgehash, mf->v1, mf->v4);
-
- df3->v3=df2->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
-
- df3->v2=mf->v3;
- df3->v4=0;
-
- mf->v2=df1->v1;
- mf->v3=df1->v4;
- mf->v4=0;
-
- facepa[i]=v1;
- facepa[curdupface-3]=facepa[curdupface-2]=v2;
- facepa[curdupface-1]=v3;
- }
- else{
- df3->v1=df2->v1=df1->v2=edgesplit_get(edgehash, mf->v1, mf->v2);
- df2->v4=df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
- df1->v4=edgesplit_get(edgehash, mf->v1, mf->v4);
-
- df3->v3=df2->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
-
- df3->v4=0;
-
- mf->v1=df1->v4;
- mf->v2=df1->v3;
- mf->v3=mf->v4;
- mf->v4=0;
-
- facepa[i]=v4;
- facepa[curdupface-3]=facepa[curdupface-2]=v1;
- facepa[curdupface-1]=v2;
- }
-
- test_index_face(df1, &splitdm->faceData, curdupface-3, (df1->v4 ? 4 : 3));
- test_index_face(df1, &splitdm->faceData, curdupface-2, (df1->v4 ? 4 : 3));
- test_index_face(df1, &splitdm->faceData, curdupface-1, (df1->v4 ? 4 : 3));
- }
- }
-
- test_index_face(df1, &splitdm->faceData, i, (df1->v4 ? 4 : 3));
- }
- }
-
- BLI_edgehash_free(edgehash, NULL);
- MEM_freeN(facesplit);
- MEM_freeN(vertpa);
-
- CDDM_tessfaces_to_faces(splitdm);
- return splitdm;
-
-}
-static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
- ParticleSystemModifierData *psmd, Scene *scene, Object *ob,
- DerivedMesh *to_explode)
-{
- DerivedMesh *explode, *dm=to_explode;
- MFace *mf=0, *mface;
- ParticleSettings *part=psmd->psys->part;
- ParticleSimulationData sim = {scene, ob, psmd->psys, psmd};
- ParticleData *pa=NULL, *pars=psmd->psys->particles;
- ParticleKey state;
- EdgeHash *vertpahash;
- EdgeHashIterator *ehi;
- float *vertco=0, imat[4][4];
- float loc0[3], nor[3];
- float timestep, cfra;
- int *facepa=emd->facepa;
- int totdup=0,totvert=0,totface=0,totpart=0;
- int i, j, v, mindex=0;
-
- totface= dm->getNumTessFaces(dm);
- totvert= dm->getNumVerts(dm);
- mface= dm->getTessFaceArray(dm);
- totpart= psmd->psys->totpart;
-
- timestep= psys_get_timestep(&sim);
-
- //if(part->flag & PART_GLOB_TIME)
- cfra=bsystem_time(scene, 0,(float)scene->r.cfra,0.0);
- //else
- // cfra=bsystem_time(scene, ob,(float)scene->r.cfra,0.0);
-
- /* hash table for vertice <-> particle relations */
- vertpahash= BLI_edgehash_new();
-
- for (i=0; i<totface; i++) {
- /* do mindex + totvert to ensure the vertex index to be the first
- * with BLI_edgehashIterator_getKey */
- if(facepa[i]==totpart || cfra <= (pars+facepa[i])->time)
- mindex = totvert+totpart;
- else
- mindex = totvert+facepa[i];
-
- mf=CDDM_get_tessface(dm,i);
-
- /* set face vertices to exist in particle group */
- BLI_edgehash_insert(vertpahash, mf->v1, mindex, NULL);
- BLI_edgehash_insert(vertpahash, mf->v2, mindex, NULL);
- BLI_edgehash_insert(vertpahash, mf->v3, mindex, NULL);
- if(mf->v4)
- BLI_edgehash_insert(vertpahash, mf->v4, mindex, NULL);
- }
-
- /* make new vertice indexes & count total vertices after duplication */
- ehi= BLI_edgehashIterator_new(vertpahash);
- for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
- BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(totdup));
- totdup++;
- }
- BLI_edgehashIterator_free(ehi);
-
- /* the final duplicated vertices */
- explode= CDDM_from_template(dm, totdup, 0,totface, 0, 0);
- /*dupvert= CDDM_get_verts(explode);*/
-
- /* getting back to object space */
- invert_m4_m4(imat,ob->obmat);
-
- psmd->psys->lattice = psys_get_lattice(&sim);
-
- /* duplicate & displace vertices */
- ehi= BLI_edgehashIterator_new(vertpahash);
- for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
- MVert source;
- MVert *dest;
-
- /* get particle + vertex from hash */
- BLI_edgehashIterator_getKey(ehi, &j, &i);
- i -= totvert;
- v= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
-
- dm->getVert(dm, j, &source);
- dest = CDDM_get_vert(explode,v);
-
- DM_copy_vert_data(dm,explode,j,v,1);
- *dest = source;
-
- if(i!=totpart) {
- /* get particle */
- pa= pars+i;
-
- /* get particle state */
- psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc0,nor,0,0,0,0);
- mul_m4_v3(ob->obmat,loc0);
-
- state.time=cfra;
- psys_get_particle_state(&sim, i, &state, 1);
-
- vertco=CDDM_get_vert(explode,v)->co;
-
- mul_m4_v3(ob->obmat,vertco);
-
- VECSUB(vertco,vertco,loc0);
-
- /* apply rotation, size & location */
- mul_qt_v3(state.rot,vertco);
- mul_v3_fl(vertco,pa->size);
- VECADD(vertco,vertco,state.co);
-
- mul_m4_v3(imat,vertco);
- }
- }
- BLI_edgehashIterator_free(ehi);
-
- /*map new vertices to faces*/
- for (i=0; i<totface; i++) {
- MFace source;
- int orig_v4;
-
- if(facepa[i]!=totpart)
- {
- pa=pars+facepa[i];
-
- if(pa->alive==PARS_UNBORN && (emd->flag&eExplodeFlag_Unborn)==0) continue;
- if(pa->alive==PARS_ALIVE && (emd->flag&eExplodeFlag_Alive)==0) continue;
- if(pa->alive==PARS_DEAD && (emd->flag&eExplodeFlag_Dead)==0) continue;
- }
-
- dm->getTessFace(dm,i,&source);
- mf=CDDM_get_tessface(explode,i);
-
- orig_v4 = source.v4;
-
- if(facepa[i]!=totpart && cfra <= pa->time)
- mindex = totvert+totpart;
- else
- mindex = totvert+facepa[i];
-
- source.v1 = edgesplit_get(vertpahash, source.v1, mindex);
- source.v2 = edgesplit_get(vertpahash, source.v2, mindex);
- source.v3 = edgesplit_get(vertpahash, source.v3, mindex);
- if(source.v4)
- source.v4 = edgesplit_get(vertpahash, source.v4, mindex);
-
- DM_copy_tessface_data(dm,explode,i,i,1);
-
- *mf = source;
-
- test_index_face(mf, &explode->faceData, i, (orig_v4 ? 4 : 3));
- }
-
- /* cleanup */
- BLI_edgehash_free(vertpahash, NULL);
-
- /* finalization */
- CDDM_calc_edges(explode);
- CDDM_calc_normals(explode);
-
- if(psmd->psys->lattice){
- end_latt_deform(psmd->psys->lattice);
- psmd->psys->lattice= NULL;
- }
-
- CDDM_tessfaces_to_faces(explode);
- return explode;
-}
-
-static ParticleSystemModifierData * explodeModifier_findPrecedingParticlesystem(Object *ob, ModifierData *emd)
-{
- ModifierData *md;
- ParticleSystemModifierData *psmd=0;
-
- for (md=ob->modifiers.first; emd!=md; md=md->next){
- if(md->type==eModifierType_ParticleSystem)
- psmd= (ParticleSystemModifierData*) md;
- }
- return psmd;
-}
-static DerivedMesh * explodeModifier_applyModifier(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- int useRenderParams, int isFinalCalc)
-{
- DerivedMesh *dm = derivedData;
- ExplodeModifierData *emd= (ExplodeModifierData*) md;
- ParticleSystemModifierData *psmd=explodeModifier_findPrecedingParticlesystem(ob,md);
-
- if(psmd){
- ParticleSystem * psys=psmd->psys;
-
- if(psys==0 || psys->totpart==0) return derivedData;
- if(psys->part==0 || psys->particles==0) return derivedData;
- if(psmd->dm==0) return derivedData;
-
- /* 1. find faces to be exploded if needed */
- if(emd->facepa==0
- || psmd->flag&eParticleSystemFlag_Pars
- || emd->flag&eExplodeFlag_CalcFaces
- || MEM_allocN_len(emd->facepa)/sizeof(int) != dm->getNumTessFaces(dm)){
- if(psmd->flag & eParticleSystemFlag_Pars)
- psmd->flag &= ~eParticleSystemFlag_Pars;
-
- if(emd->flag & eExplodeFlag_CalcFaces)
- emd->flag &= ~eExplodeFlag_CalcFaces;
-
- explodeModifier_createFacepa(emd,psmd,ob,derivedData);
- }
-
- /* 2. create new mesh */
- if(emd->flag & eExplodeFlag_EdgeSplit){
- int *facepa = emd->facepa;
- DerivedMesh *splitdm=explodeModifier_splitEdges(emd,dm);
- DerivedMesh *explode=explodeModifier_explodeMesh(emd, psmd, md->scene, ob, splitdm);
-
- MEM_freeN(emd->facepa);
- emd->facepa=facepa;
- splitdm->release(splitdm);
- return explode;
- }
- else
- return explodeModifier_explodeMesh(emd, psmd, md->scene, ob, derivedData);
- }
- return derivedData;
-}
-
-/* Fluidsim */
-static void fluidsimModifier_initData(ModifierData *md)
-{
- FluidsimModifierData *fluidmd= (FluidsimModifierData*) md;
-
- fluidsim_init(fluidmd);
-}
-static void fluidsimModifier_freeData(ModifierData *md)
-{
- FluidsimModifierData *fluidmd= (FluidsimModifierData*) md;
-
- fluidsim_free(fluidmd);
-}
-
-static void fluidsimModifier_copyData(ModifierData *md, ModifierData *target)
-{
- FluidsimModifierData *fluidmd= (FluidsimModifierData*) md;
- FluidsimModifierData *tfluidmd= (FluidsimModifierData*) target;
-
- if(tfluidmd->fss)
- MEM_freeN(tfluidmd->fss);
-
- tfluidmd->fss = MEM_dupallocN(fluidmd->fss);
-}
-
-static DerivedMesh * fluidsimModifier_applyModifier(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- int useRenderParams, int isFinalCalc)
-{
- FluidsimModifierData *fluidmd= (FluidsimModifierData*) md;
- DerivedMesh *result = NULL;
-
- /* check for alloc failing */
- if(!fluidmd->fss)
- {
- fluidsimModifier_initData(md);
-
- if(!fluidmd->fss)
- return derivedData;
- }
-
- result = fluidsimModifier_do(fluidmd, md->scene, ob, derivedData, useRenderParams, isFinalCalc);
-
- if(result)
- {
- return result;
- }
-
- return derivedData;
-}
-
-static void fluidsimModifier_updateDepgraph(
- ModifierData *md, DagForest *forest, Scene *scene,
- Object *ob, DagNode *obNode)
-{
- FluidsimModifierData *fluidmd= (FluidsimModifierData*) md;
- Base *base;
-
- if(fluidmd && fluidmd->fss)
- {
- if(fluidmd->fss->type == OB_FLUIDSIM_DOMAIN)
- {
- for(base = scene->base.first; base; base= base->next)
- {
- Object *ob1= base->object;
- if(ob1 != ob)
- {
- FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(ob1, eModifierType_Fluidsim);
-
- // only put dependancies from NON-DOMAIN fluids in here
- if(fluidmdtmp && fluidmdtmp->fss && (fluidmdtmp->fss->type!=OB_FLUIDSIM_DOMAIN))
- {
- DagNode *curNode = dag_get_node(forest, ob1);
- dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Fluidsim Object");
- }
- }
- }
- }
- }
-}
-
-static int fluidsimModifier_dependsOnTime(ModifierData *md)
-{
- return 1;
-}
-
-/* MeshDeform */
-
-static void meshdeformModifier_initData(ModifierData *md)
-{
- MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
-
- mmd->gridsize= 5;
-}
-
-static void meshdeformModifier_freeData(ModifierData *md)
-{
- MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
-
- if(mmd->bindweights) MEM_freeN(mmd->bindweights);
- if(mmd->bindcos) MEM_freeN(mmd->bindcos);
- if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
- if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
- if(mmd->dynverts) MEM_freeN(mmd->dynverts);
-}
-
-static void meshdeformModifier_copyData(ModifierData *md, ModifierData *target)
-{
- MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
- MeshDeformModifierData *tmmd = (MeshDeformModifierData*) target;
-
- tmmd->gridsize = mmd->gridsize;
- tmmd->object = mmd->object;
-}
-
-static CustomDataMask meshdeformModifier_requiredDataMask(Object *ob, ModifierData *md)
-{
- MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
- CustomDataMask dataMask = 0;
-
- /* ask for vertexgroups if we need them */
- if(mmd->defgrp_name[0]) dataMask |= (1 << CD_MDEFORMVERT);
-
- return dataMask;
-}
-
-static int meshdeformModifier_isDisabled(ModifierData *md, int useRenderParams)
-{
- MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
-
- return !mmd->object;
-}
-
-static void meshdeformModifier_foreachObjectLink(
- ModifierData *md, Object *ob,
- void (*walk)(void *userData, Object *ob, Object **obpoin),
- void *userData)
-{
- MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
-
- walk(userData, ob, &mmd->object);
-}
-
-static void meshdeformModifier_updateDepgraph(
- ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
- DagNode *obNode)
-{
- MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
-
- if (mmd->object) {
- DagNode *curNode = dag_get_node(forest, mmd->object);
-
- dag_add_relation(forest, curNode, obNode,
- DAG_RL_DATA_DATA|DAG_RL_OB_DATA|DAG_RL_DATA_OB|DAG_RL_OB_OB,
- "Mesh Deform Modifier");
- }
-}
-
-static float meshdeform_dynamic_bind(MeshDeformModifierData *mmd, float (*dco)[3], float *vec)
-{
- MDefCell *cell;
- MDefInfluence *inf;
- float gridvec[3], dvec[3], ivec[3], co[3], wx, wy, wz;
- float weight, cageweight, totweight, *cageco;
- int i, j, a, x, y, z, size;
-
- co[0]= co[1]= co[2]= 0.0f;
- totweight= 0.0f;
- size= mmd->dyngridsize;
-
- for(i=0; i<3; i++) {
- gridvec[i]= (vec[i] - mmd->dyncellmin[i] - mmd->dyncellwidth*0.5f)/mmd->dyncellwidth;
- ivec[i]= (int)gridvec[i];
- dvec[i]= gridvec[i] - ivec[i];
- }
-
- for(i=0; i<8; i++) {
- if(i & 1) { x= ivec[0]+1; wx= dvec[0]; }
- else { x= ivec[0]; wx= 1.0f-dvec[0]; }
-
- if(i & 2) { y= ivec[1]+1; wy= dvec[1]; }
- else { y= ivec[1]; wy= 1.0f-dvec[1]; }
-
- if(i & 4) { z= ivec[2]+1; wz= dvec[2]; }
- else { z= ivec[2]; wz= 1.0f-dvec[2]; }
-
- CLAMP(x, 0, size-1);
- CLAMP(y, 0, size-1);
- CLAMP(z, 0, size-1);
-
- a= x + y*size + z*size*size;
- weight= wx*wy*wz;
-
- cell= &mmd->dyngrid[a];
- inf= mmd->dyninfluences + cell->offset;
- for(j=0; j<cell->totinfluence; j++, inf++) {
- cageco= dco[inf->vertex];
- cageweight= weight*inf->weight;
- co[0] += cageweight*cageco[0];
- co[1] += cageweight*cageco[1];
- co[2] += cageweight*cageco[2];
- totweight += cageweight;
- }
- }
-
- VECCOPY(vec, co);
-
- return totweight;
-}
-
-static void meshdeformModifier_do(
- ModifierData *md, Object *ob, DerivedMesh *dm,
- float (*vertexCos)[3], int numVerts)
-{
- MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
- Mesh *me= (mmd->object)? mmd->object->data: NULL;
- BMEditMesh *bem = me->edit_btmesh;
- DerivedMesh *tmpdm, *cagedm;
- MDeformVert *dvert = NULL;
- MDeformWeight *dw;
- MVert *cagemvert;
- float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
- float weight, totweight, fac, co[3], *weights, (*dco)[3], (*bindcos)[3];
- int a, b, totvert, totcagevert, defgrp_index;
-
- if(!mmd->object || (!mmd->bindcos && !mmd->bindfunc))
- return;
-
- /* get cage derivedmesh */
- if(bem) {
- tmpdm= editbmesh_get_derived_cage_and_final(md->scene, ob, bem, &cagedm, 0);
- if(tmpdm)
- tmpdm->release(tmpdm);
- }
- else
- cagedm= mmd->object->derivedFinal;
-
- /* if we don't have one computed, use derivedmesh from data
- * without any modifiers */
- if(!cagedm) {
- cagedm= get_dm(md->scene, mmd->object, NULL, NULL, NULL, 0);
- if(cagedm)
- cagedm->needsFree= 1;
- }
-
- if(!cagedm)
- return;
-
- /* compute matrices to go in and out of cage object space */
- invert_m4_m4(imat, mmd->object->obmat);
- mul_m4_m4m4(cagemat, ob->obmat, imat);
- mul_m4_m4m4(cmat, cagemat, mmd->bindmat);
- invert_m4_m4(iobmat, cmat);
- copy_m3_m4(icagemat, iobmat);
-
- /* bind weights if needed */
- if(!mmd->bindcos) {
- static int recursive = 0;
-
- /* progress bar redraw can make this recursive .. */
- if(!recursive) {
- recursive = 1;
- mmd->bindfunc(md->scene, dm, mmd, (float*)vertexCos, numVerts, cagemat);
- recursive = 0;
- }
- }
-
- /* verify we have compatible weights */
- totvert= numVerts;
- totcagevert= cagedm->getNumVerts(cagedm);
-
- if(mmd->totvert!=totvert || mmd->totcagevert!=totcagevert || !mmd->bindcos) {
- cagedm->release(cagedm);
- return;
- }
-
- /* setup deformation data */
- cagemvert= cagedm->getVertArray(cagedm);
- weights= mmd->bindweights;
- bindcos= (float(*)[3])mmd->bindcos;
-
- dco= MEM_callocN(sizeof(*dco)*totcagevert, "MDefDco");
- for(a=0; a<totcagevert; a++) {
- /* get cage vertex in world space with binding transform */
- VECCOPY(co, cagemvert[a].co);
-
- if(G.rt != 527) {
- mul_m4_v3(mmd->bindmat, co);
- /* compute difference with world space bind coord */
- VECSUB(dco[a], co, bindcos[a]);
- }
- else
- VECCOPY(dco[a], co)
- }
-
- defgrp_index = defgroup_name_index(ob, mmd->defgrp_name);
-
- if (defgrp_index >= 0)
- dvert= dm->getVertDataArray(dm, CD_MDEFORMVERT);
-
- /* do deformation */
- fac= 1.0f;
-
- for(b=0; b<totvert; b++) {
- if(mmd->flag & MOD_MDEF_DYNAMIC_BIND)
- if(!mmd->dynverts[b])
- continue;
-
- if(dvert) {
- for(dw=NULL, a=0; a<dvert[b].totweight; a++) {
- if(dvert[b].dw[a].def_nr == defgrp_index) {
- dw = &dvert[b].dw[a];
- break;
- }
- }
-
- if(mmd->flag & MOD_MDEF_INVERT_VGROUP) {
- if(!dw) fac= 1.0f;
- else if(dw->weight == 1.0f) continue;
- else fac=1.0f-dw->weight;
- }
- else {
- if(!dw) continue;
- else fac= dw->weight;
- }
- }
-
- if(mmd->flag & MOD_MDEF_DYNAMIC_BIND) {
- /* transform coordinate into cage's local space */
- VECCOPY(co, vertexCos[b]);
- mul_m4_v3(cagemat, co);
- totweight= meshdeform_dynamic_bind(mmd, dco, co);
- }
- else {
- totweight= 0.0f;
- co[0]= co[1]= co[2]= 0.0f;
-
- for(a=0; a<totcagevert; a++) {
- weight= weights[a + b*totcagevert];
- co[0]+= weight*dco[a][0];
- co[1]+= weight*dco[a][1];
- co[2]+= weight*dco[a][2];
- totweight += weight;
- }
- }
-
- if(totweight > 0.0f) {
- mul_v3_fl(co, fac/totweight);
- mul_m3_v3(icagemat, co);
- if(G.rt != 527)
- VECADD(vertexCos[b], vertexCos[b], co)
- else
- VECCOPY(vertexCos[b], co)
- }
- }
-
- /* release cage derivedmesh */
- MEM_freeN(dco);
- cagedm->release(cagedm);
-}
-
-static void meshdeformModifier_deformVerts(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
-{
- DerivedMesh *dm= get_dm(md->scene, ob, NULL, derivedData, NULL, 0);;
-
- if(!dm)
- return;
-
- modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
-
- meshdeformModifier_do(md, ob, dm, vertexCos, numVerts);
-
- if(dm != derivedData)
- dm->release(dm);
-}
-
-static void meshdeformModifier_deformVertsEM(
- ModifierData *md, Object *ob, BMEditMesh *editData,
- DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
-{
- DerivedMesh *dm;
-
- if(!derivedData && ob->type == OB_MESH)
- dm = CDDM_from_BMEditMesh(editData, ob->data);
- else
- dm = derivedData;
-
- meshdeformModifier_do(md, ob, dm, vertexCos, numVerts);
-
- if(dm != derivedData)
- dm->release(dm);
-}
-
-/* Multires */
-static void multiresModifier_initData(ModifierData *md)
-{
- MultiresModifierData *mmd = (MultiresModifierData*)md;
-
- mmd->lvl = 0;
- mmd->sculptlvl = 0;
- mmd->renderlvl = 0;
- mmd->totlvl = 0;
-}
-
-static void multiresModifier_copyData(ModifierData *md, ModifierData *target)
-{
- MultiresModifierData *mmd = (MultiresModifierData*) md;
- MultiresModifierData *tmmd = (MultiresModifierData*) target;
-
- tmmd->lvl = mmd->lvl;
- tmmd->sculptlvl = mmd->sculptlvl;
- tmmd->renderlvl = mmd->renderlvl;
- tmmd->totlvl = mmd->totlvl;
-}
-
-static DerivedMesh *multiresModifier_applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm,
- int useRenderParams, int isFinalCalc)
-{
- MultiresModifierData *mmd = (MultiresModifierData*)md;
- DerivedMesh *result;
-
- result = multires_dm_create_from_derived(mmd, 0, dm, ob, useRenderParams, isFinalCalc);
-
- if(result == dm)
- return dm;
-
- if(useRenderParams || !isFinalCalc) {
- DerivedMesh *cddm= CDDM_copy(result, 0);
- result->release(result);
- result= cddm;
- }
- else if(ob->mode & OB_MODE_SCULPT) {
- /* would be created on the fly too, just nicer this
- way on first stroke after e.g. switching levels */
- result->getPBVH(ob, result);
- }
-
- return result;
-}
-
-/* Shrinkwrap */
-
-static void shrinkwrapModifier_initData(ModifierData *md)
-{
- ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
- smd->shrinkType = MOD_SHRINKWRAP_NEAREST_SURFACE;
- smd->shrinkOpts = MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR;
- smd->keepDist = 0.0f;
-
- smd->target = NULL;
- smd->auxTarget = NULL;
-}
-
-static void shrinkwrapModifier_copyData(ModifierData *md, ModifierData *target)
-{
- ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*)md;
- ShrinkwrapModifierData *tsmd = (ShrinkwrapModifierData*)target;
-
- tsmd->target = smd->target;
- tsmd->auxTarget = smd->auxTarget;
-
- strcpy(tsmd->vgroup_name, smd->vgroup_name);
-
- tsmd->keepDist = smd->keepDist;
- tsmd->shrinkType= smd->shrinkType;
- tsmd->shrinkOpts= smd->shrinkOpts;
- tsmd->projAxis = smd->projAxis;
- tsmd->subsurfLevels = smd->subsurfLevels;
-}
-
-static CustomDataMask shrinkwrapModifier_requiredDataMask(Object *ob, ModifierData *md)
-{
- ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
- CustomDataMask dataMask = 0;
-
- /* ask for vertexgroups if we need them */
- if(smd->vgroup_name[0])
- dataMask |= (1 << CD_MDEFORMVERT);
-
- if(smd->shrinkType == MOD_SHRINKWRAP_PROJECT
- && smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL)
- dataMask |= (1 << CD_MVERT);
-
- return dataMask;
-}
-
-static int shrinkwrapModifier_isDisabled(ModifierData *md, int useRenderParams)
-{
- ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
- return !smd->target;
-}
-
-
-static void shrinkwrapModifier_foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
-{
- ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
-
- walk(userData, ob, &smd->target);
- walk(userData, ob, &smd->auxTarget);
-}
-
-static void shrinkwrapModifier_deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
-{
- DerivedMesh *dm = derivedData;
- CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(ob, md);
-
- /* ensure we get a CDDM with applied vertex coords */
- if(dataMask)
- dm= get_cddm(md->scene, ob, NULL, dm, vertexCos);
-
- shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, md->scene, ob, dm, vertexCos, numVerts);
-
- if(dm != derivedData)
- dm->release(dm);
-}
-
-static void shrinkwrapModifier_deformVertsEM(ModifierData *md, Object *ob, BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
-{
- DerivedMesh *dm = derivedData;
- CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(ob, md);
-
- /* ensure we get a CDDM with applied vertex coords */
- if(dataMask)
- dm= get_cddm(md->scene, ob, editData, dm, vertexCos);
-
- shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, md->scene, ob, dm, vertexCos, numVerts);
-
- if(dm != derivedData)
- dm->release(dm);
-}
-
-static void shrinkwrapModifier_updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene, Object *ob, DagNode *obNode)
-{
- ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
-
- if (smd->target)
- dag_add_relation(forest, dag_get_node(forest, smd->target), obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "Shrinkwrap Modifier");
-
- if (smd->auxTarget)
- dag_add_relation(forest, dag_get_node(forest, smd->auxTarget), obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "Shrinkwrap Modifier");
-}
-
-/* SimpleDeform */
-static void simpledeformModifier_initData(ModifierData *md)
-{
- SimpleDeformModifierData *smd = (SimpleDeformModifierData*) md;
-
- smd->mode = MOD_SIMPLEDEFORM_MODE_TWIST;
- smd->axis = 0;
-
- smd->origin = NULL;
- smd->factor = 0.35f;
- smd->limit[0] = 0.0f;
- smd->limit[1] = 1.0f;
-}
-
-static void simpledeformModifier_copyData(ModifierData *md, ModifierData *target)
-{
- SimpleDeformModifierData *smd = (SimpleDeformModifierData*)md;
- SimpleDeformModifierData *tsmd = (SimpleDeformModifierData*)target;
-
- tsmd->mode = smd->mode;
- tsmd->axis = smd->axis;
- tsmd->origin= smd->origin;
- tsmd->factor= smd->factor;
- memcpy(tsmd->limit, smd->limit, sizeof(tsmd->limit));
-}
-
-static CustomDataMask simpledeformModifier_requiredDataMask(Object *ob, ModifierData *md)
-{
- SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md;
- CustomDataMask dataMask = 0;
-
- /* ask for vertexgroups if we need them */
- if(smd->vgroup_name[0])
- dataMask |= (1 << CD_MDEFORMVERT);
-
- return dataMask;
-}
-
-static void simpledeformModifier_foreachObjectLink(ModifierData *md, Object *ob, void (*walk)(void *userData, Object *ob, Object **obpoin), void *userData)
-{
- SimpleDeformModifierData *smd = (SimpleDeformModifierData*)md;
- walk(userData, ob, &smd->origin);
-}
-
-static void simpledeformModifier_updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene, Object *ob, DagNode *obNode)
-{
- SimpleDeformModifierData *smd = (SimpleDeformModifierData*)md;
-
- if (smd->origin)
- dag_add_relation(forest, dag_get_node(forest, smd->origin), obNode, DAG_RL_OB_DATA, "SimpleDeform Modifier");
-}
-
-static void simpledeformModifier_deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
-{
- DerivedMesh *dm = derivedData;
- CustomDataMask dataMask = simpledeformModifier_requiredDataMask(ob, md);
-
- /* we implement requiredDataMask but thats not really usefull since
- mesh_calc_modifiers pass a NULL derivedData */
- if(dataMask)
- dm= get_dm(md->scene, ob, NULL, dm, NULL, 0);
-
- SimpleDeformModifier_do((SimpleDeformModifierData*)md, ob, dm, vertexCos, numVerts);
-
- if(dm != derivedData)
- dm->release(dm);
-}
-
-static void simpledeformModifier_deformVertsEM(ModifierData *md, Object *ob, BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
-{
- DerivedMesh *dm = derivedData;
- CustomDataMask dataMask = simpledeformModifier_requiredDataMask(ob, md);
-
- /* we implement requiredDataMask but thats not really usefull since
- mesh_calc_modifiers pass a NULL derivedData */
- if(dataMask)
- dm= get_dm(md->scene, ob, editData, dm, NULL, 0);
-
- SimpleDeformModifier_do((SimpleDeformModifierData*)md, ob, dm, vertexCos, numVerts);
-
- if(dm != derivedData)
- dm->release(dm);
-}
-
-/* Shape Key */
-
-static void shapekeyModifier_deformVerts(
- ModifierData *md, Object *ob, DerivedMesh *derivedData,
- float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
-{
- KeyBlock *kb= ob_get_keyblock(ob);
- float (*deformedVerts)[3];
-
- if(kb && kb->totelem == numVerts) {
- deformedVerts= (float(*)[3])do_ob_key(md->scene, ob);
- if(deformedVerts) {
- memcpy(vertexCos, deformedVerts, sizeof(float)*3*numVerts);
- MEM_freeN(deformedVerts);
- }
- }
-}
-
-static void shapekeyModifier_deformVertsEM(
- ModifierData *md, Object *ob, EditMesh *editData,
- DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
-{
- Key *key= ob_get_key(ob);
-
- if(key && key->type == KEY_RELATIVE)
- shapekeyModifier_deformVerts(md, ob, derivedData, vertexCos, numVerts, 0, 0);
-}
-
-static void shapekeyModifier_deformMatricesEM(
- ModifierData *md, Object *ob, EditMesh *editData,
- DerivedMesh *derivedData, float (*vertexCos)[3],
- float (*defMats)[3][3], int numVerts)
-{
- Key *key= ob_get_key(ob);
- KeyBlock *kb= ob_get_keyblock(ob);
- float scale[3][3];
- int a;
-
- if(kb && kb->totelem==numVerts && kb!=key->refkey) {
- scale_m3_fl(scale, kb->curval);
-
- for(a=0; a<numVerts; a++)
- copy_m3_m3(defMats[a], scale);
- }
-}
-
-/***/
-
-static ModifierTypeInfo typeArr[NUM_MODIFIER_TYPES];
-static int typeArrInit = 1;
-
-ModifierTypeInfo *modifierType_getInfo(ModifierType type)
-{
- if (typeArrInit) {
- ModifierTypeInfo *mti;
-
- memset(typeArr, 0, sizeof(typeArr));
-
- /* Initialize and return the appropriate type info structure,
- * assumes that modifier has:
- * name == typeName,
- * structName == typeName + 'ModifierData'
- */
-#define INIT_TYPE(typeName) \
- (strcpy(typeArr[eModifierType_##typeName].name, #typeName), \
- strcpy(typeArr[eModifierType_##typeName].structName, \
-#typeName "ModifierData"), \
- typeArr[eModifierType_##typeName].structSize = \
- sizeof(typeName##ModifierData), \
- &typeArr[eModifierType_##typeName])
-
- mti = &typeArr[eModifierType_None];
- strcpy(mti->name, "None");
- strcpy(mti->structName, "ModifierData");
- mti->structSize = sizeof(ModifierData);
- mti->type = eModifierType_None;
- mti->flags = eModifierTypeFlag_AcceptsMesh
- | eModifierTypeFlag_AcceptsCVs;
- mti->isDisabled = noneModifier_isDisabled;
-
- mti = INIT_TYPE(Curve);
- mti->type = eModifierTypeType_OnlyDeform;
- mti->flags = eModifierTypeFlag_AcceptsCVs
- | eModifierTypeFlag_SupportsEditmode;
- mti->initData = curveModifier_initData;
- mti->copyData = curveModifier_copyData;
- mti->requiredDataMask = curveModifier_requiredDataMask;
- mti->isDisabled = curveModifier_isDisabled;
- mti->foreachObjectLink = curveModifier_foreachObjectLink;
- mti->updateDepgraph = curveModifier_updateDepgraph;
- mti->deformVerts = curveModifier_deformVerts;
- mti->deformVertsEM = curveModifier_deformVertsEM;
-
- mti = INIT_TYPE(Lattice);
- mti->type = eModifierTypeType_OnlyDeform;
- mti->flags = eModifierTypeFlag_AcceptsCVs
- | eModifierTypeFlag_SupportsEditmode;
- mti->copyData = latticeModifier_copyData;
- mti->requiredDataMask = latticeModifier_requiredDataMask;
- mti->isDisabled = latticeModifier_isDisabled;
- mti->foreachObjectLink = latticeModifier_foreachObjectLink;
- mti->updateDepgraph = latticeModifier_updateDepgraph;
- mti->deformVerts = latticeModifier_deformVerts;
- mti->deformVertsEM = latticeModifier_deformVertsEM;
-
- mti = INIT_TYPE(Subsurf);
- mti->type = eModifierTypeType_Constructive;
- mti->flags = eModifierTypeFlag_AcceptsMesh
- | eModifierTypeFlag_SupportsMapping
- | eModifierTypeFlag_SupportsEditmode
- | eModifierTypeFlag_EnableInEditmode;
- mti->initData = subsurfModifier_initData;
- mti->copyData = subsurfModifier_copyData;
- mti->freeData = subsurfModifier_freeData;
- mti->isDisabled = subsurfModifier_isDisabled;
- mti->applyModifier = subsurfModifier_applyModifier;
- mti->applyModifierEM = subsurfModifier_applyModifierEM;
-
- mti = INIT_TYPE(Build);
- mti->type = eModifierTypeType_Nonconstructive;
- mti->flags = eModifierTypeFlag_AcceptsMesh;
- mti->initData = buildModifier_initData;
- mti->copyData = buildModifier_copyData;
- mti->dependsOnTime = buildModifier_dependsOnTime;
- mti->applyModifier = buildModifier_applyModifier;
-
- mti = INIT_TYPE(Mask);
- mti->type = eModifierTypeType_Nonconstructive;
- mti->flags = eModifierTypeFlag_AcceptsMesh;
- mti->copyData = maskModifier_copyData;
- mti->requiredDataMask= maskModifier_requiredDataMask;
- mti->foreachObjectLink = maskModifier_foreachObjectLink;
- mti->updateDepgraph = maskModifier_updateDepgraph;
- mti->applyModifier = maskModifier_applyModifier;
-
- mti = INIT_TYPE(Array);
- mti->type = eModifierTypeType_Constructive;
- mti->flags = eModifierTypeFlag_AcceptsMesh
- | eModifierTypeFlag_SupportsMapping
- | eModifierTypeFlag_SupportsEditmode
- | eModifierTypeFlag_EnableInEditmode;
- mti->initData = arrayModifier_initData;
- mti->copyData = arrayModifier_copyData;
- mti->foreachObjectLink = arrayModifier_foreachObjectLink;
- mti->updateDepgraph = arrayModifier_updateDepgraph;
- mti->applyModifier = arrayModifier_applyModifier;
- mti->applyModifierEM = arrayModifier_applyModifierEM;
-
- mti = INIT_TYPE(Mirror);
- mti->type = eModifierTypeType_Constructive;
- mti->flags = eModifierTypeFlag_AcceptsMesh
- | eModifierTypeFlag_SupportsMapping
- | eModifierTypeFlag_SupportsEditmode
- | eModifierTypeFlag_EnableInEditmode;
- mti->initData = mirrorModifier_initData;
- mti->copyData = mirrorModifier_copyData;
- mti->foreachObjectLink = mirrorModifier_foreachObjectLink;
- mti->updateDepgraph = mirrorModifier_updateDepgraph;
- mti->applyModifier = mirrorModifier_applyModifier;
- mti->applyModifierEM = mirrorModifier_applyModifierEM;
-
- mti = INIT_TYPE(EdgeSplit);
- mti->type = eModifierTypeType_Constructive;
- mti->flags = eModifierTypeFlag_AcceptsMesh
- | eModifierTypeFlag_SupportsMapping
- | eModifierTypeFlag_SupportsEditmode
- | eModifierTypeFlag_EnableInEditmode;
- mti->initData = edgesplitModifier_initData;
- mti->copyData = edgesplitModifier_copyData;
- mti->applyModifier = edgesplitModifier_applyModifier;
- mti->applyModifierEM = edgesplitModifier_applyModifierEM;
-
- mti = INIT_TYPE(Bevel);
- mti->type = eModifierTypeType_Constructive;
- mti->flags = eModifierTypeFlag_AcceptsMesh
- | eModifierTypeFlag_SupportsEditmode
- | eModifierTypeFlag_EnableInEditmode;
- mti->initData = bevelModifier_initData;
- mti->copyData = bevelModifier_copyData;
- mti->requiredDataMask = bevelModifier_requiredDataMask;
- mti->applyModifier = bevelModifier_applyModifier;
- mti->applyModifierEM = bevelModifier_applyModifierEM;
-
- mti = INIT_TYPE(Displace);
- mti->type = eModifierTypeType_OnlyDeform;
- mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_SupportsEditmode;
- mti->initData = displaceModifier_initData;
- mti->copyData = displaceModifier_copyData;
- mti->requiredDataMask = displaceModifier_requiredDataMask;
- mti->dependsOnTime = displaceModifier_dependsOnTime;
- mti->foreachObjectLink = displaceModifier_foreachObjectLink;
- mti->foreachIDLink = displaceModifier_foreachIDLink;
- mti->updateDepgraph = displaceModifier_updateDepgraph;
- mti->isDisabled = displaceModifier_isDisabled;
- mti->deformVerts = displaceModifier_deformVerts;
- mti->deformVertsEM = displaceModifier_deformVertsEM;
-
- mti = INIT_TYPE(UVProject);
- mti->type = eModifierTypeType_Nonconstructive;
- mti->flags = eModifierTypeFlag_AcceptsMesh
- | eModifierTypeFlag_SupportsMapping
- | eModifierTypeFlag_SupportsEditmode
- | eModifierTypeFlag_EnableInEditmode;
- mti->initData = uvprojectModifier_initData;
- mti->copyData = uvprojectModifier_copyData;
- mti->requiredDataMask = uvprojectModifier_requiredDataMask;
- mti->foreachObjectLink = uvprojectModifier_foreachObjectLink;
- mti->foreachIDLink = uvprojectModifier_foreachIDLink;
- mti->updateDepgraph = uvprojectModifier_updateDepgraph;
- mti->applyModifier = uvprojectModifier_applyModifier;
- mti->applyModifierEM = uvprojectModifier_applyModifierEM;
-
- mti = INIT_TYPE(Decimate);
- mti->type = eModifierTypeType_Nonconstructive;
- mti->flags = eModifierTypeFlag_AcceptsMesh;
- mti->initData = decimateModifier_initData;
- mti->copyData = decimateModifier_copyData;
- mti->applyModifier = decimateModifier_applyModifier;
-
- mti = INIT_TYPE(Smooth);
- mti->type = eModifierTypeType_OnlyDeform;
- mti->flags = eModifierTypeFlag_AcceptsMesh
- | eModifierTypeFlag_SupportsEditmode;
- mti->initData = smoothModifier_initData;
- mti->copyData = smoothModifier_copyData;
- mti->requiredDataMask = smoothModifier_requiredDataMask;
- mti->isDisabled = smoothModifier_isDisabled;
- mti->deformVerts = smoothModifier_deformVerts;
- mti->deformVertsEM = smoothModifier_deformVertsEM;
-
- mti = INIT_TYPE(Cast);
- mti->type = eModifierTypeType_OnlyDeform;
- mti->flags = eModifierTypeFlag_AcceptsCVs
- | eModifierTypeFlag_SupportsEditmode;
- mti->initData = castModifier_initData;
- mti->copyData = castModifier_copyData;
- mti->requiredDataMask = castModifier_requiredDataMask;
- mti->isDisabled = castModifier_isDisabled;
- mti->foreachObjectLink = castModifier_foreachObjectLink;
- mti->updateDepgraph = castModifier_updateDepgraph;
- mti->deformVerts = castModifier_deformVerts;
- mti->deformVertsEM = castModifier_deformVertsEM;
-
- mti = INIT_TYPE(Wave);
- mti->type = eModifierTypeType_OnlyDeform;
- mti->flags = eModifierTypeFlag_AcceptsCVs
- | eModifierTypeFlag_SupportsEditmode;
- mti->initData = waveModifier_initData;
- mti->copyData = waveModifier_copyData;
- mti->dependsOnTime = waveModifier_dependsOnTime;
- mti->requiredDataMask = waveModifier_requiredDataMask;
- mti->foreachObjectLink = waveModifier_foreachObjectLink;
- mti->foreachIDLink = waveModifier_foreachIDLink;
- mti->updateDepgraph = waveModifier_updateDepgraph;
- mti->deformVerts = waveModifier_deformVerts;
- mti->deformVertsEM = waveModifier_deformVertsEM;
-
- mti = INIT_TYPE(Armature);
- mti->type = eModifierTypeType_OnlyDeform;
- mti->flags = eModifierTypeFlag_AcceptsCVs
- | eModifierTypeFlag_SupportsEditmode;
- mti->initData = armatureModifier_initData;
- mti->copyData = armatureModifier_copyData;
- mti->requiredDataMask = armatureModifier_requiredDataMask;
- mti->isDisabled = armatureModifier_isDisabled;
- mti->foreachObjectLink = armatureModifier_foreachObjectLink;
- mti->updateDepgraph = armatureModifier_updateDepgraph;
- mti->deformVerts = armatureModifier_deformVerts;
- mti->deformVertsEM = armatureModifier_deformVertsEM;
- mti->deformMatricesEM = armatureModifier_deformMatricesEM;
-
- mti = INIT_TYPE(Hook);
- mti->type = eModifierTypeType_OnlyDeform;
- mti->flags = eModifierTypeFlag_AcceptsCVs
- | eModifierTypeFlag_SupportsEditmode;
- mti->initData = hookModifier_initData;
- mti->copyData = hookModifier_copyData;
- mti->requiredDataMask = hookModifier_requiredDataMask;
- mti->freeData = hookModifier_freeData;
- mti->isDisabled = hookModifier_isDisabled;
- mti->foreachObjectLink = hookModifier_foreachObjectLink;
- mti->updateDepgraph = hookModifier_updateDepgraph;
- mti->deformVerts = hookModifier_deformVerts;
- mti->deformVertsEM = hookModifier_deformVertsEM;
-
- mti = INIT_TYPE(Softbody);
- mti->type = eModifierTypeType_OnlyDeform;
- mti->flags = eModifierTypeFlag_AcceptsCVs
- | eModifierTypeFlag_RequiresOriginalData
- | eModifierTypeFlag_Single;
- mti->deformVerts = softbodyModifier_deformVerts;
- mti->dependsOnTime = softbodyModifier_dependsOnTime;
-
- mti = INIT_TYPE(Smoke);
- mti->type = eModifierTypeType_OnlyDeform;
- mti->initData = smokeModifier_initData;
- mti->freeData = smokeModifier_freeData;
- mti->flags = eModifierTypeFlag_AcceptsMesh
- | eModifierTypeFlag_UsesPointCache
- | eModifierTypeFlag_Single;
- mti->deformVerts = smokeModifier_deformVerts;
- mti->dependsOnTime = smokeModifier_dependsOnTime;
- mti->updateDepgraph = smokeModifier_updateDepgraph;
-
- mti = INIT_TYPE(Cloth);
- mti->type = eModifierTypeType_Nonconstructive;
- mti->initData = clothModifier_initData;
- mti->flags = eModifierTypeFlag_AcceptsMesh
- | eModifierTypeFlag_UsesPointCache
- | eModifierTypeFlag_Single;
- mti->dependsOnTime = clothModifier_dependsOnTime;
- mti->freeData = clothModifier_freeData;
- mti->requiredDataMask = clothModifier_requiredDataMask;
- mti->copyData = clothModifier_copyData;
- mti->applyModifier = clothModifier_applyModifier;
- mti->updateDepgraph = clothModifier_updateDepgraph;
-
- mti = INIT_TYPE(Collision);
- mti->type = eModifierTypeType_OnlyDeform;
- mti->initData = collisionModifier_initData;
- mti->flags = eModifierTypeFlag_AcceptsMesh
- | eModifierTypeFlag_Single;
- mti->dependsOnTime = collisionModifier_dependsOnTime;
- mti->freeData = collisionModifier_freeData;
- mti->deformVerts = collisionModifier_deformVerts;
- // mti->copyData = collisionModifier_copyData;
-
- mti = INIT_TYPE(Surface);
- mti->type = eModifierTypeType_OnlyDeform;
- mti->initData = surfaceModifier_initData;
- mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_NoUserAdd;
- 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_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;
- mti->flags = eModifierTypeFlag_AcceptsCVs
- | eModifierTypeFlag_SupportsEditmode;
- mti->initData = meshdeformModifier_initData;
- mti->freeData = meshdeformModifier_freeData;
- mti->copyData = meshdeformModifier_copyData;
- mti->requiredDataMask = meshdeformModifier_requiredDataMask;
- mti->isDisabled = meshdeformModifier_isDisabled;
- mti->foreachObjectLink = meshdeformModifier_foreachObjectLink;
- mti->updateDepgraph = meshdeformModifier_updateDepgraph;
- mti->deformVerts = meshdeformModifier_deformVerts;
- mti->deformVertsEM = meshdeformModifier_deformVertsEM;
-
- mti = INIT_TYPE(ParticleSystem);
- mti->type = eModifierTypeType_OnlyDeform;
- mti->flags = eModifierTypeFlag_AcceptsMesh
- | eModifierTypeFlag_SupportsMapping
- | eModifierTypeFlag_UsesPointCache;
-#if 0
- | eModifierTypeFlag_SupportsEditmode;
- |eModifierTypeFlag_EnableInEditmode;
-#endif
- mti->initData = particleSystemModifier_initData;
- mti->freeData = particleSystemModifier_freeData;
- mti->copyData = particleSystemModifier_copyData;
- mti->deformVerts = particleSystemModifier_deformVerts;
-#if 0
- mti->deformVertsEM = particleSystemModifier_deformVertsEM;
-#endif
- mti->requiredDataMask = particleSystemModifier_requiredDataMask;
-
- mti = INIT_TYPE(ParticleInstance);
- mti->type = eModifierTypeType_Constructive;
- mti->flags = eModifierTypeFlag_AcceptsMesh
- | eModifierTypeFlag_SupportsMapping
- | eModifierTypeFlag_SupportsEditmode
- | eModifierTypeFlag_EnableInEditmode;
- mti->initData = particleInstanceModifier_initData;
- mti->copyData = particleInstanceModifier_copyData;
- mti->dependsOnTime = particleInstanceModifier_dependsOnTime;
- mti->foreachObjectLink = particleInstanceModifier_foreachObjectLink;
- mti->applyModifier = particleInstanceModifier_applyModifier;
- mti->applyModifierEM = particleInstanceModifier_applyModifierEM;
- mti->updateDepgraph = particleInstanceModifier_updateDepgraph;
-
- mti = INIT_TYPE(Explode);
- mti->type = eModifierTypeType_Nonconstructive;
- mti->flags = eModifierTypeFlag_AcceptsMesh;
- mti->initData = explodeModifier_initData;
- mti->freeData = explodeModifier_freeData;
- mti->copyData = explodeModifier_copyData;
- mti->dependsOnTime = explodeModifier_dependsOnTime;
- mti->requiredDataMask = explodeModifier_requiredDataMask;
- mti->applyModifier = explodeModifier_applyModifier;
-
- mti = INIT_TYPE(Fluidsim);
- mti->type = eModifierTypeType_Nonconstructive
- | eModifierTypeFlag_RequiresOriginalData
- | eModifierTypeFlag_Single;
- mti->flags = eModifierTypeFlag_AcceptsMesh;
- mti->initData = fluidsimModifier_initData;
- mti->freeData = fluidsimModifier_freeData;
- mti->copyData = fluidsimModifier_copyData;
- mti->dependsOnTime = fluidsimModifier_dependsOnTime;
- mti->applyModifier = fluidsimModifier_applyModifier;
- mti->updateDepgraph = fluidsimModifier_updateDepgraph;
-
- mti = INIT_TYPE(Shrinkwrap);
- mti->type = eModifierTypeType_OnlyDeform;
- mti->flags = eModifierTypeFlag_AcceptsMesh
- | eModifierTypeFlag_AcceptsCVs
- | eModifierTypeFlag_SupportsEditmode
- | eModifierTypeFlag_EnableInEditmode;
- mti->initData = shrinkwrapModifier_initData;
- mti->copyData = shrinkwrapModifier_copyData;
- mti->requiredDataMask = shrinkwrapModifier_requiredDataMask;
- mti->isDisabled = shrinkwrapModifier_isDisabled;
- mti->foreachObjectLink = shrinkwrapModifier_foreachObjectLink;
- mti->deformVerts = shrinkwrapModifier_deformVerts;
- mti->deformVertsEM = shrinkwrapModifier_deformVertsEM;
- mti->updateDepgraph = shrinkwrapModifier_updateDepgraph;
-
- mti = INIT_TYPE(SimpleDeform);
- mti->type = eModifierTypeType_OnlyDeform;
- mti->flags = eModifierTypeFlag_AcceptsMesh
- | eModifierTypeFlag_AcceptsCVs
- | eModifierTypeFlag_SupportsEditmode
- | eModifierTypeFlag_EnableInEditmode;
- mti->initData = simpledeformModifier_initData;
- mti->copyData = simpledeformModifier_copyData;
- mti->requiredDataMask = simpledeformModifier_requiredDataMask;
- mti->deformVerts = simpledeformModifier_deformVerts;
- mti->deformVertsEM = simpledeformModifier_deformVertsEM;
- mti->foreachObjectLink = simpledeformModifier_foreachObjectLink;
- mti->updateDepgraph = simpledeformModifier_updateDepgraph;
-
- mti = INIT_TYPE(Multires);
- mti->type = eModifierTypeType_Constructive;
- mti->flags = eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_RequiresOriginalData;
- mti->initData = multiresModifier_initData;
- mti->copyData = multiresModifier_copyData;
- mti->applyModifier = multiresModifier_applyModifier;
-
- mti = INIT_TYPE(ShapeKey);
- mti->type = eModifierTypeType_OnlyDeform;
- mti->flags = eModifierTypeFlag_AcceptsCVs
- | eModifierTypeFlag_SupportsEditmode;
- mti->deformVerts = shapekeyModifier_deformVerts;
- mti->deformVertsEM = shapekeyModifier_deformVertsEM;
- mti->deformMatricesEM = shapekeyModifier_deformMatricesEM;
-
- mti = INIT_TYPE(Solidify);
- mti->type = eModifierTypeType_Constructive;
- mti->flags = eModifierTypeFlag_AcceptsMesh
- | eModifierTypeFlag_SupportsMapping
- | eModifierTypeFlag_SupportsEditmode
- | eModifierTypeFlag_EnableInEditmode;
- mti->initData = solidifyModifier_initData;
- mti->copyData = solidifyModifier_copyData;
- mti->applyModifier = solidifyModifier_applyModifier;
- mti->applyModifierEM = solidifyModifier_applyModifierEM;
- typeArrInit = 0;
-#undef INIT_TYPE
- }
-
- if (type>=0 && type<NUM_MODIFIER_TYPES && typeArr[type].name[0]!='\0') {
- return &typeArr[type];
- } else {
return NULL;
}
}
@@ -8239,6 +134,11 @@ ModifierData *modifiers_findByType(Object *ob, ModifierType type)
return md;
}
+ModifierData *modifiers_findByName(Object *ob, const char *name)
+{
+ return BLI_findstring(&(ob->modifiers), name, offsetof(ModifierData, name));
+}
+
void modifiers_clearErrors(Object *ob)
{
ModifierData *md = ob->modifiers.first;
diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c
index 250a272015e..8b437635b2a 100644
--- a/source/blender/blenkernel/intern/modifiers_bmesh.c
+++ b/source/blender/blenkernel/intern/modifiers_bmesh.c
@@ -99,7 +99,6 @@
#include "depsgraph_private.h"
#include "BKE_deform.h"
#include "BKE_shrinkwrap.h"
-#include "BKE_simple_deform.h"
#include "CCGSubSurf.h"
#include "RE_shader_ext.h"
@@ -225,501 +224,3 @@ BMEditMesh *CDDM_To_BMesh(DerivedMesh *dm, BMEditMesh *existing)
return em;
}
-static float vertarray_size(MVert *mvert, int numVerts, int axis)
-{
- int i;
- float min_co, max_co;
-
- /* if there are no vertices, width is 0 */
- if(numVerts == 0) return 0;
-
- /* find the minimum and maximum coordinates on the desired axis */
- min_co = max_co = mvert->co[axis];
- ++mvert;
- for(i = 1; i < numVerts; ++i, ++mvert) {
- if(mvert->co[axis] < min_co) min_co = mvert->co[axis];
- if(mvert->co[axis] > max_co) max_co = mvert->co[axis];
- }
-
- return max_co - min_co;
-}
-
-/* finds the best possible flipped name. For renaming; check for unique names afterwards */
-/* if strip_number: removes number extensions */
-static void vertgroup_flip_name (char *name, int strip_number)
-{
- int len;
- char prefix[128]={""}; /* The part before the facing */
- char suffix[128]={""}; /* The part after the facing */
- char replace[128]={""}; /* The replacement string */
- char number[128]={""}; /* The number extension string */
- char *index=NULL;
-
- len= strlen(name);
- if(len<3) return; // we don't do names like .R or .L
-
- /* We first check the case with a .### extension, let's find the last period */
- if(isdigit(name[len-1])) {
- index= strrchr(name, '.'); // last occurrance
- if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever!
- if(strip_number==0)
- strcpy(number, index);
- *index= 0;
- len= strlen(name);
- }
- }
-
- strcpy (prefix, name);
-
-#define IS_SEPARATOR(a) ((a)=='.' || (a)==' ' || (a)=='-' || (a)=='_')
-
- /* first case; separator . - _ with extensions r R l L */
- if( IS_SEPARATOR(name[len-2]) ) {
- switch(name[len-1]) {
- case 'l':
- prefix[len-1]= 0;
- strcpy(replace, "r");
- break;
- case 'r':
- prefix[len-1]= 0;
- strcpy(replace, "l");
- break;
- case 'L':
- prefix[len-1]= 0;
- strcpy(replace, "R");
- break;
- case 'R':
- prefix[len-1]= 0;
- strcpy(replace, "L");
- break;
- }
- }
- /* case; beginning with r R l L , with separator after it */
- else if( IS_SEPARATOR(name[1]) ) {
- switch(name[0]) {
- case 'l':
- strcpy(replace, "r");
- strcpy(suffix, name+1);
- prefix[0]= 0;
- break;
- case 'r':
- strcpy(replace, "l");
- strcpy(suffix, name+1);
- prefix[0]= 0;
- break;
- case 'L':
- strcpy(replace, "R");
- strcpy(suffix, name+1);
- prefix[0]= 0;
- break;
- case 'R':
- strcpy(replace, "L");
- strcpy(suffix, name+1);
- prefix[0]= 0;
- break;
- }
- }
- else if(len > 5) {
- /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */
- index = BLI_strcasestr(prefix, "right");
- if (index==prefix || index==prefix+len-5) {
- if(index[0]=='r')
- strcpy (replace, "left");
- else {
- if(index[1]=='I')
- strcpy (replace, "LEFT");
- else
- strcpy (replace, "Left");
- }
- *index= 0;
- strcpy (suffix, index+5);
- }
- else {
- index = BLI_strcasestr(prefix, "left");
- if (index==prefix || index==prefix+len-4) {
- if(index[0]=='l')
- strcpy (replace, "right");
- else {
- if(index[1]=='E')
- strcpy (replace, "RIGHT");
- else
- strcpy (replace, "Right");
- }
- *index= 0;
- strcpy (suffix, index+4);
- }
- }
- }
-
-#undef IS_SEPARATOR
-
- sprintf (name, "%s%s%s%s", prefix, replace, suffix, number);
-}
-
-typedef struct IndexMapEntry {
- /* the new vert index that this old vert index maps to */
- int new;
- /* -1 if this vert isn't merged, otherwise the old vert index it
- * should be replaced with
- */
- int merge;
- /* 1 if this vert's first copy is merged with the last copy of its
- * merge target, otherwise 0
- */
- short merge_final;
-} IndexMapEntry;
-
-/* indexMap - an array of IndexMap entries
- * oldIndex - the old index to map
- * copyNum - the copy number to map to (original = 0, first copy = 1, etc.)
- */
-static int calc_mapping(IndexMapEntry *indexMap, int oldIndex, int copyNum)
-{
- if(indexMap[oldIndex].merge < 0) {
- /* vert wasn't merged, so use copy of this vert */
- return indexMap[oldIndex].new + copyNum;
- } else if(indexMap[oldIndex].merge == oldIndex) {
- /* vert was merged with itself */
- return indexMap[oldIndex].new;
- } else {
- /* vert was merged with another vert */
- /* follow the chain of merges to the end, or until we've passed
- * a number of vertices equal to the copy number
- */
- if(copyNum <= 0)
- return indexMap[oldIndex].new;
- else
- return calc_mapping(indexMap, indexMap[oldIndex].merge,
- copyNum - 1);
- }
-}
-
-static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
- Scene *scene, Object *ob, DerivedMesh *dm,
- int initFlags)
-{
- DerivedMesh *cddm = dm; //copying shouldn't be necassary here, as all modifiers return CDDM's
- BMEditMesh *em = CDDM_To_BMesh(cddm, NULL);
- BMOperator op, oldop, weldop;
- int i, j, indexLen;
- /* offset matrix */
- float offset[4][4];
- float final_offset[4][4];
- float tmp_mat[4][4];
- float length = amd->length;
- int count = amd->count, maxVerts;
- int finalVerts, finalEdges, finalFaces;
- int *indexMap = NULL;
- DerivedMesh *start_cap = NULL, *end_cap = NULL;
- MVert *src_mvert;
-
- /* need to avoid infinite recursion here */
- if(amd->start_cap && amd->start_cap != ob)
- start_cap = mesh_get_derived_final(scene, amd->start_cap, CD_MASK_MESH);
- if(amd->end_cap && amd->end_cap != ob)
- end_cap = mesh_get_derived_final(scene, amd->end_cap, CD_MASK_MESH);
-
- unit_m4(offset);
-
- src_mvert = cddm->getVertArray(dm);
- maxVerts = cddm->getNumVerts(dm);
-
- if(amd->offset_type & MOD_ARR_OFF_CONST)
- add_v3_v3v3(offset[3], offset[3], amd->offset);
- if(amd->offset_type & MOD_ARR_OFF_RELATIVE) {
- for(j = 0; j < 3; j++)
- offset[3][j] += amd->scale[j] * vertarray_size(src_mvert,
- maxVerts, j);
- }
-
- if((amd->offset_type & MOD_ARR_OFF_OBJ) && (amd->offset_ob)) {
- float obinv[4][4];
- float result_mat[4][4];
-
- if(ob)
- invert_m4_m4(obinv, ob->obmat);
- else
- unit_m4(obinv);
-
- mul_serie_m4(result_mat, offset,
- obinv, amd->offset_ob->obmat,
- NULL, NULL, NULL, NULL, NULL);
- copy_m4_m4(offset, result_mat);
- }
-
- if(amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob) {
- Curve *cu = amd->curve_ob->data;
- if(cu) {
- float tmp_mat[3][3];
- float scale;
-
- object_to_mat3(amd->curve_ob, tmp_mat);
- scale = mat3_to_scale(tmp_mat);
-
- if(!cu->path) {
- cu->flag |= CU_PATH; // needed for path & bevlist
- makeDispListCurveTypes(scene, amd->curve_ob, 0);
- }
- if(cu->path)
- length = scale*cu->path->totdist;
- }
- }
-
- /* calculate the maximum number of copies which will fit within the
- prescribed length */
- if(amd->fit_type == MOD_ARR_FITLENGTH
- || amd->fit_type == MOD_ARR_FITCURVE)
- {
- float dist = sqrt(INPR(offset[3], offset[3]));
-
- if(dist > 1e-6f)
- /* this gives length = first copy start to last copy end
- add a tiny offset for floating point rounding errors */
- count = (length + 1e-6f) / dist;
- else
- /* if the offset has no translation, just make one copy */
- count = 1;
- }
-
- if(count < 1)
- count = 1;
-
- /* allocate memory for count duplicates (including original) plus
- * start and end caps
- */
- finalVerts = dm->getNumVerts(dm) * count;
- finalEdges = dm->getNumEdges(dm) * count;
- finalFaces = dm->getNumFaces(dm) * count;
- if(start_cap) {
- finalVerts += start_cap->getNumVerts(start_cap);
- finalEdges += start_cap->getNumEdges(start_cap);
- finalFaces += start_cap->getNumFaces(start_cap);
- }
- if(end_cap) {
- finalVerts += end_cap->getNumVerts(end_cap);
- finalEdges += end_cap->getNumEdges(end_cap);
- finalFaces += end_cap->getNumFaces(end_cap);
- }
-
- /* calculate the offset matrix of the final copy (for merging) */
- unit_m4(final_offset);
-
- for(j=0; j < count - 1; j++) {
- mul_m4_m4m4(tmp_mat, final_offset, offset);
- copy_m4_m4(final_offset, tmp_mat);
- }
-
- BMO_Init_Op(&weldop, "weldverts");
- BMO_InitOpf(em->bm, &op, "dupe geom=%avef");
- oldop = op;
- for (j=0; j < count; j++) {
- BMVert *v, *v2;
- BMOpSlot *s1;
- BMOpSlot *s2;
-
- BMO_InitOpf(em->bm, &op, "dupe geom=%s", &oldop, j==0 ? "geom" : "newout");
- BMO_Exec_Op(em->bm, &op);
-
- s1 = BMO_GetSlot(&op, "geom");
- s2 = BMO_GetSlot(&op, "newout");
-
- BMO_CallOpf(em->bm, "transform mat=%m4 verts=%s", offset, &op, "newout");
-
- #define _E(s, i) ((BMVert**)(s)->data.buf)[i]
-
- /*calculate merge mapping*/
- if (j == 0) {
- BMOperator findop;
- BMOIter oiter;
- BMVert *v, *v2;
- BMHeader *h;
-
- BMO_InitOpf(em->bm, &findop,
- "finddoubles verts=%av dist=%f keepverts=%s",
- amd->merge_dist, &op, "geom");
-
- i = 0;
- BMO_ITER(h, &oiter, em->bm, &op, "geom", BM_ALL) {
- BMINDEX_SET(h, i);
- i++;
- }
-
- BMO_ITER(h, &oiter, em->bm, &op, "newout", BM_ALL) {
- BMINDEX_SET(h, i);
- i++;
- }
-
- BMO_Exec_Op(em->bm, &findop);
-
- indexLen = i;
- indexMap = MEM_callocN(sizeof(int)*indexLen, "indexMap");
-
- /*element type argument doesn't do anything here*/
- BMO_ITER(v, &oiter, em->bm, &findop, "targetmapout", 0) {
- v2 = BMO_IterMapValp(&oiter);
-
- indexMap[BMINDEX_GET(v)] = BMINDEX_GET(v2)+1;
- }
-
- BMO_Finish_Op(em->bm, &findop);
- }
-
- /*generate merge mappping using index map. we do this by using the
- operator slots as lookup arrays.*/
- #define E(i) (i) < s1->len ? _E(s1, i) : _E(s2, (i)-s1->len)
-
- for (i=0; i<indexLen; i++) {
- if (!indexMap[i]) continue;
-
- v = E(i);
- v2 = E(indexMap[i]-1);
-
- BMO_Insert_MapPointer(em->bm, &weldop, "targetmap", v, v2);
- }
-
- #undef E
- #undef _E
-
- BMO_Finish_Op(em->bm, &oldop);
- oldop = op;
- }
-
- if (j > 0) BMO_Finish_Op(em->bm, &op);
-
- if (amd->flags & MOD_ARR_MERGE)
- BMO_Exec_Op(em->bm, &weldop);
-
- BMO_Finish_Op(em->bm, &weldop);
-
- BMEdit_RecalcTesselation(em);
- cddm = CDDM_from_BMEditMesh(em, NULL);
-
- BMEdit_Free(em);
- MEM_freeN(indexMap);
-
- return cddm;
-}
-
-DerivedMesh *arrayModifier_applyModifier(ModifierData *md, Object *ob,
- DerivedMesh *derivedData,
- int useRenderParams, int isFinalCalc)
-{
- DerivedMesh *result;
- ArrayModifierData *amd = (ArrayModifierData*) md;
-
- result = arrayModifier_doArray(amd, md->scene, ob, derivedData, 0);
-
- //if(result != derivedData)
- // CDDM_calc_normals(result);
-
- return result;
-}
-
-DerivedMesh *arrayModifier_applyModifierEM(ModifierData *md, Object *ob,
- BMEditMesh *editData,
- DerivedMesh *derivedData)
-{
- return arrayModifier_applyModifier(md, ob, derivedData, 0, 1);
-}
-
-/* Mirror */
-#define VERT_NEW 1
-
-DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
- Object *ob,
- DerivedMesh *dm,
- int initFlags,
- int axis)
-{
- float tolerance = mmd->tolerance;
- DerivedMesh *result, *cddm;
- BMEditMesh *em;
- BMesh *bm;
- BMOIter siter1;
- BMOperator op;
- BMVert *v1;
- int vector_size=0, a, b;
- bDeformGroup *def, *defb;
- bDeformGroup **vector_def = NULL;
- float mtx[4][4], imtx[4][4];
- int j;
-
- cddm = dm; //copying shouldn't be necassary here, as all modifiers return CDDM's
- em = CDDM_To_BMesh(dm, NULL);
-
- /*convienence variable*/
- bm = em->bm;
-
- if (mmd->flag & MOD_MIR_VGROUP) {
- /* calculate the number of deformedGroups */
- for(vector_size = 0, def = ob->defbase.first; def;
- def = def->next, vector_size++);
-
- /* load the deformedGroups for fast access */
- vector_def =
- (bDeformGroup **)MEM_mallocN(sizeof(bDeformGroup*) * vector_size,
- "group_index");
- for(a = 0, def = ob->defbase.first; def; def = def->next, a++) {
- vector_def[a] = def;
- }
- }
-
- if (mmd->mirror_ob) {
- float mtx2[4][4], vec[3];
-
- invert_m4_m4(mtx2, mmd->mirror_ob->obmat);
- mul_m4_m4m4(mtx, ob->obmat, mtx2);
- } else {
- unit_m4(mtx);
- }
-
- BMO_InitOpf(bm, &op, "mirror geom=%avef mat=%m4 mergedist=%f axis=%d",
- mtx, mmd->tolerance, axis);
-
- BMO_Exec_Op(bm, &op);
-
- BMO_CallOpf(bm, "reversefaces faces=%s", &op, "newout");
-
- /*handle vgroup stuff*/
- if (mmd->flag & MOD_MIR_VGROUP) {
- BMO_ITER(v1, &siter1, bm, &op, "newout", BM_VERT) {
- MDeformVert *dvert = CustomData_bmesh_get(&bm->vdata, v1->head.data, CD_MDEFORMVERT);
-
- if (dvert) {
- for(j = 0; j < dvert[0].totweight; ++j) {
- char tmpname[32];
-
- if(dvert->dw[j].def_nr < 0 ||
- dvert->dw[j].def_nr >= vector_size)
- continue;
-
- def = vector_def[dvert->dw[j].def_nr];
- strcpy(tmpname, def->name);
- vertgroup_flip_name(tmpname,0);
-
- for(b = 0, defb = ob->defbase.first; defb;
- defb = defb->next, b++)
- {
- if(!strcmp(defb->name, tmpname))
- {
- dvert->dw[j].def_nr = b;
- break;
- }
- }
- }
- }
- }
- }
-
- BMO_Finish_Op(bm, &op);
-
- BMEdit_RecalcTesselation(em);
- result = CDDM_from_BMEditMesh(em, NULL); //CDDM_copy(getEditDerivedBMesh(em, ob, NULL), 0);
-
- BMEdit_Free(em);
- MEM_freeN(em);
-
- if (vector_def) MEM_freeN(vector_def);
-
- return result;
-}
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 83f04db9cd7..4b54114505e 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -29,27 +29,20 @@
#include "MEM_guardedalloc.h"
-#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "DNA_view3d_types.h"
-#include "BLI_math.h"
#include "BLI_blenlib.h"
+#include "BLI_math.h"
#include "BLI_pbvh.h"
#include "BKE_cdderivedmesh.h"
-#include "BKE_customdata.h"
-#include "BKE_depsgraph.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
-#include "BKE_object.h"
+#include "BKE_paint.h"
#include "BKE_scene.h"
#include "BKE_subsurf.h"
#include "BKE_utildefines.h"
@@ -67,19 +60,33 @@ static const int multires_side_tot[] = {0, 2, 3, 5, 9, 17, 33, 65, 129,
static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert);
static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int add, DMGridData **oldGridData, int totlvl);
-MultiresModifierData *find_multires_modifier(Object *ob)
+DerivedMesh *get_multires_dm(Scene *scene, MultiresModifierData *mmd, Object *ob)
+{
+ ModifierData *md= (ModifierData *)mmd;
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ DerivedMesh *tdm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
+ DerivedMesh *dm;
+
+ dm = mti->applyModifier(md, ob, tdm, 0, 1);
+ if (dm == tdm) {
+ dm = CDDM_copy(tdm, 0);
+ }
+
+ return dm;
+}
+
+MultiresModifierData *find_multires_modifier_before(Scene *scene, ModifierData *lastmd)
{
ModifierData *md;
- MultiresModifierData *mmd = NULL;
- for(md = ob->modifiers.first; md; md = md->next) {
+ for(md = lastmd; md; md = md->prev) {
if(md->type == eModifierType_Multires) {
- mmd = (MultiresModifierData*)md;
- break;
+ if (modifier_isEnabled(scene, md, eModifierMode_Realtime))
+ return (MultiresModifierData*)md;
}
}
- return mmd;
+ return NULL;
}
static int multires_get_level(Object *ob, MultiresModifierData *mmd, int render)
@@ -117,14 +124,27 @@ void multires_mark_as_modified(Object *ob)
void multires_force_update(Object *ob)
{
-
- if(ob && ob->derivedFinal) {
- ob->derivedFinal->needsFree =1;
- ob->derivedFinal->release(ob->derivedFinal);
- ob->derivedFinal = NULL;
+ if(ob) {
+ if(ob->derivedFinal) {
+ ob->derivedFinal->needsFree =1;
+ ob->derivedFinal->release(ob->derivedFinal);
+ ob->derivedFinal = NULL;
+ }
+ if(ob->sculpt && ob->sculpt->pbvh) {
+ BLI_pbvh_free(ob->sculpt->pbvh);
+ ob->sculpt->pbvh= NULL;
+ }
}
}
+void multires_force_external_reload(Object *ob)
+{
+ Mesh *me = get_mesh(ob);
+
+ CustomData_external_reload(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface);
+ multires_force_update(ob);
+}
+
void multires_force_render_update(Object *ob)
{
if(ob && (ob->mode & OB_MODE_SCULPT) && modifiers_findByType(ob, eModifierType_Multires))
@@ -193,24 +213,97 @@ void multiresModifier_join(Object *ob)
}
#endif
-/* Returns 1 on success, 0 if the src's totvert doesn't match */
-int multiresModifier_reshape(MultiresModifierData *mmd, Object *dst, Object *src)
+int multiresModifier_reshapeFromDM(Scene *scene, MultiresModifierData *mmd,
+ Object *ob, DerivedMesh *srcdm)
{
- DerivedMesh *srcdm = src->derivedFinal;
- DerivedMesh *mrdm = dst->derivedFinal;
+ DerivedMesh *mrdm = get_multires_dm (scene, mmd, ob);
if(mrdm && srcdm && mrdm->getNumVerts(mrdm) == srcdm->getNumVerts(srcdm)) {
multires_mvert_to_ss(mrdm, srcdm->getVertArray(srcdm));
multires_dm_mark_as_modified(mrdm);
- multires_force_update(dst);
+ multires_force_update(ob);
+
+ mrdm->release(mrdm);
return 1;
}
+ mrdm->release(mrdm);
+
return 0;
}
+/* Returns 1 on success, 0 if the src's totvert doesn't match */
+int multiresModifier_reshape(Scene *scene, MultiresModifierData *mmd, Object *dst, Object *src)
+{
+ DerivedMesh *srcdm = mesh_get_derived_final(scene, src, CD_MASK_BAREMESH);
+ return multiresModifier_reshapeFromDM(scene, mmd, dst, srcdm);
+}
+
+int multiresModifier_reshapeFromDeformMod(Scene *scene, MultiresModifierData *mmd,
+ Object *ob, ModifierData *md)
+{
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ DerivedMesh *dm, *ndm;
+ int numVerts, result;
+ float (*deformedVerts)[3];
+
+ if(multires_get_level(ob, mmd, 0) == 0)
+ return 0;
+
+ /* Create DerivedMesh for deformation modifier */
+ dm = get_multires_dm(scene, mmd, ob);
+ numVerts= dm->getNumVerts(dm);
+ deformedVerts= MEM_callocN(sizeof(float)*numVerts*3, "multiresReshape_deformVerts");
+
+ dm->getVertCos(dm, deformedVerts);
+ mti->deformVerts(md, ob, dm, deformedVerts, numVerts, 0, 0);
+
+ ndm= CDDM_copy(dm, 0);
+ CDDM_apply_vert_coords(ndm, deformedVerts);
+
+ MEM_freeN(deformedVerts);
+ dm->release(dm);
+
+ /* Reshaping */
+ result= multiresModifier_reshapeFromDM(scene, mmd, ob, ndm);
+
+ /* Cleanup */
+ ndm->release(ndm);
+
+ return result;
+}
+
+static void multires_set_tot_mdisps(Mesh *me, int lvl)
+{
+ MDisps *mdisps= CustomData_get_layer(&me->ldata, CD_MDISPS);
+ int i;
+
+ if(mdisps) {
+ for(i = 0; i < me->totloop; i++, mdisps++) {
+ mdisps->totdisp = multires_grid_tot[lvl];
+ }
+ }
+}
+
+static void multires_reallocate_mdisps(Mesh *me, MDisps *mdisps, int lvl)
+{
+ int i;
+
+ /* reallocate displacements to be filled in */
+ for(i = 0; i < me->totloop; ++i) {
+ int totdisp = multires_grid_tot[lvl];
+ float (*disps)[3] = MEM_callocN(sizeof(float) * 3 * totdisp, "multires disps");
+
+ if(mdisps[i].disps)
+ MEM_freeN(mdisps[i].disps);
+
+ mdisps[i].disps = disps;
+ mdisps[i].totdisp = totdisp;
+ }
+}
+
static void column_vectors_to_mat3(float mat[][3], float v1[3], float v2[3], float v3[3])
{
copy_v3_v3(mat[0], v1);
@@ -266,6 +359,7 @@ void multiresModifier_del_levels(MultiresModifierData *mmd, Object *ob, int dire
int levels = mmd->totlvl - lvl;
MDisps *mdisps;
+ multires_set_tot_mdisps(me, mmd->totlvl);
CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop);
mdisps= CustomData_get_layer(&me->ldata, CD_MDISPS);
@@ -338,23 +432,6 @@ static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl
return subsurf_make_derived_from_derived(dm, &smd, 0, NULL, 0, 0);
}
-static void multires_reallocate_mdisps(Mesh *me, MDisps *mdisps, int lvl)
-{
- int i;
-
- /* reallocate displacements to be filled in */
- for(i = 0; i < me->totloop; ++i) {
- int totdisp = multires_grid_tot[lvl];
- float (*disps)[3] = MEM_callocN(sizeof(float) * 3 * totdisp, "multires disps");
-
- if(mdisps[i].disps)
- MEM_freeN(mdisps[i].disps);
-
- mdisps[i].disps = disps;
- mdisps[i].totdisp = totdisp;
- }
-}
-
void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int updateblock, int simple)
{
Mesh *me = ob->data;
@@ -380,6 +457,7 @@ void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int updat
/* create subsurf DM from original mesh at high level */
cddm = CDDM_from_mesh(me, NULL);
+ DM_set_only_copy(cddm, CD_MASK_BAREMESH);
highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0);
/* create multires DM from original mesh at low level */
@@ -483,7 +561,8 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int
k = 0; /*current loop/mdisp index within the mloop array*/
- #pragma omp parallel for private(i) schedule(static)
+ #pragma omp parallel for private(i) if(me->totloop*gridSize*gridSize >= CCG_OMP_LIMIT)
+
for(i = 0; i < me->totpoly; ++i) {
const int numVerts = mpoly[i].totloop;
int S, x, y, gIndex = gridOffset[i];
@@ -563,6 +642,8 @@ static void multiresModifier_update(DerivedMesh *dm)
ob = ccgdm->multires.ob;
me = ccgdm->multires.ob->data;
mmd = ccgdm->multires.mmd;
+
+ multires_set_tot_mdisps(me, mmd->totlvl);
CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop);
mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
@@ -578,7 +659,10 @@ static void multiresModifier_update(DerivedMesh *dm)
int i, j, numGrids, highGridSize, lowGridSize;
/* create subsurf DM from original mesh at high level */
- cddm = CDDM_from_mesh(me, NULL);
+ if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform, 0);
+ else cddm = CDDM_from_mesh(me, NULL);
+ DM_set_only_copy(cddm, CD_MASK_BAREMESH);
+
highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0);
/* create multires DM from original mesh and displacements */
@@ -629,7 +713,10 @@ static void multiresModifier_update(DerivedMesh *dm)
else {
DerivedMesh *cddm, *subdm;
- cddm = CDDM_from_mesh(me, NULL);
+ if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform, 0);
+ else cddm = CDDM_from_mesh(me, NULL);
+ DM_set_only_copy(cddm, CD_MASK_BAREMESH);
+
subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0);
cddm->release(cddm);
@@ -660,7 +747,7 @@ void multires_stitch_grids(Object *ob)
}
DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, int local_mmd, DerivedMesh *dm, Object *ob,
- int useRenderParams, int isFinalCalc)
+ int useRenderParams, int isFinalCalc)
{
Mesh *me= ob->data;
DerivedMesh *result;
@@ -698,7 +785,10 @@ DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, int loca
memcpy(subGridData[i], gridData[i], sizeof(DMGridData)*gridSize*gridSize);
}
+ multires_set_tot_mdisps(me, mmd->totlvl);
CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop);
+
+ /*run displacement*/
multiresModifier_disp_run(result, ob->data, 0, 0, subGridData, mmd->totlvl);
for(i = 0; i < numGrids; i++)
@@ -868,7 +958,7 @@ void multires_free(Multires *mr)
}
static void create_old_vert_face_map(ListBase **map, IndexNode **mem, const MultiresFace *mface,
- const int totvert, const int totface)
+ const int totvert, const int totface)
{
int i,j;
IndexNode *node = NULL;
@@ -887,7 +977,7 @@ static void create_old_vert_face_map(ListBase **map, IndexNode **mem, const Mult
}
static void create_old_vert_edge_map(ListBase **map, IndexNode **mem, const MultiresEdge *medge,
- const int totvert, const int totedge)
+ const int totvert, const int totedge)
{
int i,j;
IndexNode *node = NULL;
@@ -953,7 +1043,7 @@ static void multires_load_old_edges(ListBase **emap, MultiresLevel *lvl, int *vv
}
static void multires_load_old_faces(ListBase **fmap, ListBase **emap, MultiresLevel *lvl, int *vvmap, int dst,
- int v1, int v2, int v3, int v4, int st2, int st3)
+ int v1, int v2, int v3, int v4, int st2, int st3)
{
int fmid;
int emid13, emid14, emid23, emid24;
@@ -1223,6 +1313,7 @@ void multires_load_old(Object *ob, Mesh *me)
ModifierData *md;
MultiresModifierData *mmd;
DerivedMesh *dm, *orig;
+ CustomDataLayer *l;
int i;
/* Load original level into the mesh */
@@ -1268,6 +1359,14 @@ void multires_load_old(Object *ob, Mesh *me)
dm->release(dm);
orig->release(orig);
+ /* Copy the first-level data to the mesh */
+ for(i = 0, l = me->mr->vdata.layers; i < me->mr->vdata.totlayer; ++i, ++l)
+ CustomData_add_layer(&me->vdata, l->type, CD_REFERENCE, l->data, me->totvert);
+ for(i = 0, l = me->mr->fdata.layers; i < me->mr->fdata.totlayer; ++i, ++l)
+ CustomData_add_layer(&me->fdata, l->type, CD_REFERENCE, l->data, me->totface);
+ memset(&me->mr->vdata, 0, sizeof(CustomData));
+ memset(&me->mr->fdata, 0, sizeof(CustomData));
+
/* Remove the old multires */
multires_free(me->mr);
me->mr= NULL;
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index bbef2b3e0db..8d2ad49e7bf 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -36,29 +36,22 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_ghash.h"
#include "DNA_anim_types.h"
-#include "DNA_action_types.h"
+#include "DNA_scene_types.h"
-#include "BKE_animsys.h"
#include "BKE_action.h"
#include "BKE_fcurve.h"
#include "BKE_nla.h"
-#include "BKE_blender.h"
+#include "BKE_global.h"
#include "BKE_library.h"
-#include "BKE_object.h"
#include "BKE_utildefines.h"
#include "RNA_access.h"
#include "nla_private.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
/* *************************************************** */
/* Data Management */
@@ -833,8 +826,8 @@ void BKE_nlameta_flush_transforms (NlaStrip *mstrip)
strip->end= nEnd;
RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &ptr);
- RNA_float_set(&ptr, "start_frame", nStart);
- RNA_float_set(&ptr, "end_frame", nEnd);
+ RNA_float_set(&ptr, "frame_start", nStart);
+ RNA_float_set(&ptr, "frame_end", nEnd);
}
else {
/* just apply the changes in offset to both ends of the strip */
@@ -961,6 +954,35 @@ short BKE_nlatrack_add_strip (NlaTrack *nlt, NlaStrip *strip)
return BKE_nlastrips_add_strip(&nlt->strips, strip);
}
+/* Get the extents of the given NLA-Track including gaps between strips,
+ * returning whether this succeeded or not
+ */
+short BKE_nlatrack_get_bounds (NlaTrack *nlt, float bounds[2])
+{
+ NlaStrip *strip;
+
+ /* initialise bounds */
+ if (bounds)
+ bounds[0] = bounds[1] = 0.0f;
+ else
+ return 0;
+
+ /* sanity checks */
+ if ELEM(NULL, nlt, nlt->strips.first)
+ return 0;
+
+ /* lower bound is first strip's start frame */
+ strip = nlt->strips.first;
+ bounds[0] = strip->start;
+
+ /* upper bound is last strip's end frame */
+ strip = nlt->strips.last;
+ bounds[1] = strip->end;
+
+ /* done */
+ return 1;
+}
+
/* NLA Strips -------------------------------------- */
/* Find the active NLA-strip within the given track */
@@ -1221,7 +1243,7 @@ void BKE_nlastrip_validate_name (AnimData *adt, NlaStrip *strip)
* - this is easier than iterating over all the tracks+strips hierarchy everytime
* (and probably faster)
*/
- gh= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp);
+ gh= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "nlastrip_validate_name gh");
for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) {
for (tstrip= nlt->strips.first; tstrip; tstrip= tstrip->next) {
@@ -1479,7 +1501,10 @@ short BKE_nla_tweakmode_enter (AnimData *adt)
}
}
if ELEM3(NULL, activeTrack, activeStrip, activeStrip->act) {
- printf("NLA tweakmode enter - neither active requirement found \n");
+ if (G.f & G_DEBUG) {
+ printf("NLA tweakmode enter - neither active requirement found \n");
+ printf("\tactiveTrack = %p, activeStrip = %p \n", activeTrack, activeStrip);
+ }
return 0;
}
@@ -1558,4 +1583,29 @@ void BKE_nla_tweakmode_exit (AnimData *adt)
adt->flag &= ~ADT_NLA_EDIT_ON;
}
+/* Baking Tools ------------------------------------------- */
+
+void BKE_nla_bake (Scene *scene, ID *id, AnimData *adt, int flag)
+{
+
+ /* verify that data is valid
+ * 1) Scene and AnimData must be provided
+ * 2) there must be tracks to merge...
+ */
+ if ELEM3(NULL, scene, adt, adt->nla_tracks.first)
+ return;
+
+ /* if animdata currently has an action, 'push down' this onto the stack first */
+ if (adt->action)
+ BKE_nla_action_pushdown(adt);
+
+ /* get range of motion to bake, and the channels involved... */
+
+ /* temporarily mute the action, and start keying to it */
+
+ /* start keying... */
+
+ /* unmute the action */
+}
+
/* *************************************************** */
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index ced88b7e818..838ec24391c 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -36,42 +36,16 @@
#include <string.h>
#include "DNA_anim_types.h"
-#include "DNA_ID.h"
-#include "DNA_image_types.h"
-#include "DNA_node_types.h"
-#include "DNA_material_types.h"
-#include "DNA_texture_types.h"
-#include "DNA_text_types.h"
-#include "DNA_scene_types.h"
#include "RNA_access.h"
-#include "BKE_blender.h"
-#include "BKE_colortools.h"
#include "BKE_fcurve.h"
-#include "BKE_global.h"
-#include "BKE_image.h"
-#include "BKE_library.h"
-#include "BKE_main.h"
-#include "BKE_node.h"
-#include "BKE_texture.h"
-#include "BKE_text.h"
-#include "BKE_utildefines.h"
#include "BKE_animsys.h" /* BKE_free_animdata only */
-#include "BLI_math.h"
-#include "BLI_blenlib.h"
-#include "BLI_rand.h"
-#include "BLI_threads.h"
#include "PIL_time.h"
#include "MEM_guardedalloc.h"
-#include "IMB_imbuf.h"
-
-#include "RE_pipeline.h"
-#include "RE_shader_ext.h" /* <- TexResult */
-#include "RE_render_ext.h" /* <- ibuf_sample() */
#include "CMP_node.h"
#include "intern/CMP_util.h" /* stupid include path... */
@@ -80,7 +54,6 @@
#include "TEX_node.h"
#include "intern/TEX_util.h"
-#include "GPU_extensions.h"
#include "GPU_material.h"
static ListBase empty_list = {NULL, NULL};
@@ -141,7 +114,8 @@ void ntreeInitTypes(bNodeTree *ntree)
}
}
node->typeinfo= stype;
- node->typeinfo->initfunc(node);
+ if(node->typeinfo)
+ node->typeinfo->initfunc(node);
} else {
node->typeinfo= node_get_type(ntree, node->type, (bNodeTree *)node->id, NULL);
}
@@ -1075,11 +1049,11 @@ bNodeTree *ntreeAddTree(int type)
ntree->alltypes.last = NULL;
/* this helps RNA identify ID pointers as nodetree */
- if(ntree->type==NTREE_SHADER)
+ if(ntree->type==NTREE_SHADER)
BLI_strncpy(ntree->id.name, "NTShader Nodetree", sizeof(ntree->id.name));
- else if(ntree->type==NTREE_COMPOSIT)
+ else if(ntree->type==NTREE_COMPOSIT)
BLI_strncpy(ntree->id.name, "NTCompositing Nodetree", sizeof(ntree->id.name));
- else if(ntree->type==NTREE_TEXTURE)
+ else if(ntree->type==NTREE_TEXTURE)
BLI_strncpy(ntree->id.name, "NTTexture Nodetree", sizeof(ntree->id.name));
ntreeInitTypes(ntree);
@@ -1381,9 +1355,9 @@ void ntreeMakeLocal(bNodeTree *ntree)
int local=0, lib=0;
/* - only lib users: do nothing
- * - only local users: set flag
- * - mixed: make copy
- */
+ * - only local users: set flag
+ * - mixed: make copy
+ */
if(ntree->id.lib==NULL) return;
if(ntree->id.us==1) {
@@ -1574,7 +1548,7 @@ bNode *nodeGetActiveID(bNodeTree *ntree, short idtype)
if(ntree==NULL) return NULL;
/* check for group edit */
- for(node= ntree->nodes.first; node; node= node->next)
+ for(node= ntree->nodes.first; node; node= node->next)
if(node->flag & NODE_GROUP_EDIT)
break;
@@ -1598,7 +1572,7 @@ int nodeSetActiveID(bNodeTree *ntree, short idtype, ID *id)
if(ntree==NULL) return ok;
/* check for group edit */
- for(node= ntree->nodes.first; node; node= node->next)
+ for(node= ntree->nodes.first; node; node= node->next)
if(node->flag & NODE_GROUP_EDIT)
break;
@@ -2460,7 +2434,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
bNode *node;
ListBase threads;
ThreadData thdata;
- int totnode, rendering= 1;
+ int totnode, curnode, rendering= 1;
if(ntree==NULL) return;
@@ -2481,7 +2455,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
BLI_srandom(rd->cfra);
/* sets need_exec tags in nodes */
- totnode= setExecutableNodes(ntree, &thdata);
+ curnode = totnode= setExecutableNodes(ntree, &thdata);
BLI_init_threads(&threads, exec_composite_node, rd->threads);
@@ -2491,14 +2465,14 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
node= getExecutableNode(ntree);
if(node) {
- if(ntree->timecursor)
- ntree->timecursor(ntree->tch, totnode);
+ if(ntree->progress && totnode)
+ ntree->progress(ntree->prh, (1.0 - curnode/(float)totnode));
if(ntree->stats_draw) {
char str[64];
- sprintf(str, "Compositing %d %s", totnode, node->name);
+ sprintf(str, "Compositing %d %s", curnode, node->name);
ntree->stats_draw(ntree->sdh, str);
}
- totnode--;
+ curnode--;
node->threaddata = &thdata;
node->exec= NODE_PROCESSING;
@@ -2546,10 +2520,39 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
/* local tree then owns all compbufs */
bNodeTree *ntreeLocalize(bNodeTree *ntree)
{
- bNodeTree *ltree= ntreeCopyTree(ntree, 0);
+ bNodeTree *ltree;
bNode *node;
bNodeSocket *sock;
+ bAction *action_backup= NULL, *tmpact_backup= NULL;
+
+ /* Workaround for copying an action on each render!
+ * set action to NULL so animdata actions dont get copied */
+ AnimData *adt= BKE_animdata_from_id(&ntree->id);
+
+ if(adt) {
+ action_backup= adt->action;
+ tmpact_backup= adt->tmpact;
+
+ adt->action= NULL;
+ adt->tmpact= NULL;
+ }
+
+ /* node copy func */
+ ltree= ntreeCopyTree(ntree, 0);
+
+ if(adt) {
+ AnimData *ladt= BKE_animdata_from_id(&ltree->id);
+
+ adt->action= ladt->action= action_backup;
+ adt->tmpact= ladt->tmpact= tmpact_backup;
+
+ if(action_backup) action_backup->id.us++;
+ if(tmpact_backup) tmpact_backup->id.us++;
+
+ }
+ /* end animdata uglyness */
+
/* move over the compbufs */
/* right after ntreeCopyTree() oldsock pointers are valid */
for(node= ntree->nodes.first; node; node= node->next) {
@@ -2571,6 +2574,8 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree)
for(sock= node->outputs.first; sock; sock= sock->next) {
sock->new_sock->ns.data= sock->ns.data;
+ compbuf_set_node(sock->new_sock->ns.data, node->new_node);
+
sock->ns.data= NULL;
sock->new_sock->new_sock= sock;
}
@@ -2668,7 +2673,7 @@ static void gpu_from_node_stack(ListBase *sockets, bNodeStack **ns, GPUNodeStack
for (sock=sockets->first, i=0; sock; sock=sock->next, i++) {
memset(&gs[i], 0, sizeof(gs[i]));
- QUATCOPY(gs[i].vec, ns[i]->vec);
+ QUATCOPY(gs[i].vec, ns[i]->vec);
gs[i].link= ns[i]->data;
if (sock->type == SOCK_VALUE)
@@ -2761,7 +2766,7 @@ void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat)
if(node->typeinfo->gpufunc(mat, node, gpuin, gpuout))
data_from_gpu_stack(&node->outputs, nsout, gpuout);
}
- else if(node->type==NODE_GROUP && node->id) {
+ else if(node->type==NODE_GROUP && node->id) {
node_get_stack(node, stack, nsin, nsout);
gpu_node_group_execute(stack, mat, node, nsin, nsout);
}
@@ -2809,12 +2814,16 @@ static void force_hidden_passes(bNode *node, int passflag)
if(!(passflag & SCE_PASS_REFLECT)) sock->flag |= SOCK_UNAVAIL;
sock= BLI_findlink(&node->outputs, RRES_OUT_REFRACT);
if(!(passflag & SCE_PASS_REFRACT)) sock->flag |= SOCK_UNAVAIL;
- sock= BLI_findlink(&node->outputs, RRES_OUT_RADIO);
- if(!(passflag & SCE_PASS_RADIO)) sock->flag |= SOCK_UNAVAIL;
+ sock= BLI_findlink(&node->outputs, RRES_OUT_INDIRECT);
+ if(!(passflag & SCE_PASS_INDIRECT)) sock->flag |= SOCK_UNAVAIL;
sock= BLI_findlink(&node->outputs, RRES_OUT_INDEXOB);
if(!(passflag & SCE_PASS_INDEXOB)) sock->flag |= SOCK_UNAVAIL;
sock= BLI_findlink(&node->outputs, RRES_OUT_MIST);
if(!(passflag & SCE_PASS_MIST)) sock->flag |= SOCK_UNAVAIL;
+ sock= BLI_findlink(&node->outputs, RRES_OUT_EMIT);
+ if(!(passflag & SCE_PASS_EMIT)) sock->flag |= SOCK_UNAVAIL;
+ sock= BLI_findlink(&node->outputs, RRES_OUT_ENV);
+ if(!(passflag & SCE_PASS_ENVIRONMENT)) sock->flag |= SOCK_UNAVAIL;
}
@@ -3017,7 +3026,7 @@ void nodeRegisterType(ListBase *typelist, const bNodeType *ntype)
bNodeType *ntypen= MEM_callocN(sizeof(bNodeType), "node type");
*ntypen= *ntype;
BLI_addtail(typelist, ntypen);
- }
+ }
}
static void registerCompositNodes(ListBase *ntypelist)
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index a83997f1e70..a6565ade028 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -33,46 +33,30 @@
#include <math.h>
#include <stdio.h>
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
-#include "DNA_action_types.h"
#include "DNA_armature_types.h"
-#include "DNA_boid_types.h"
#include "DNA_camera_types.h"
#include "DNA_constraint_types.h"
-#include "DNA_curve_types.h"
#include "DNA_group_types.h"
#include "DNA_key_types.h"
#include "DNA_lamp_types.h"
#include "DNA_lattice_types.h"
#include "DNA_material_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meta_types.h"
-#include "DNA_curve_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_nla_types.h"
-#include "DNA_object_types.h"
-#include "DNA_object_force.h"
-#include "DNA_object_fluidsim.h"
-#include "DNA_outliner_types.h"
-#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
+#include "DNA_sequence_types.h"
#include "DNA_space_types.h"
-#include "DNA_texture_types.h"
-#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
#include "BLI_blenlib.h"
-#include "BLI_math.h"
#include "BLI_editVert.h"
+#include "BLI_math.h"
+#include "BLI_pbvh.h"
#include "BKE_utildefines.h"
@@ -85,10 +69,8 @@
#include "BKE_colortools.h"
#include "BKE_deform.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_nla.h"
#include "BKE_animsys.h"
#include "BKE_anim.h"
-#include "BKE_blender.h"
#include "BKE_constraint.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
@@ -110,7 +92,7 @@
#include "BKE_property.h"
#include "BKE_sca.h"
#include "BKE_scene.h"
-#include "BKE_screen.h"
+#include "BKE_sequencer.h"
#include "BKE_softbody.h"
#include "LBM_fluidsim.h"
@@ -247,23 +229,26 @@ void object_free_display(Object *ob)
freedisplist(&ob->disp);
}
-void free_sculptsession(SculptSession **ssp)
+void free_sculptsession(Object *ob)
{
- if(ssp && *ssp) {
- SculptSession *ss = *ssp;
+ if(ob && ob->sculpt) {
+ SculptSession *ss = ob->sculpt;
+ DerivedMesh *dm= ob->derivedFinal;
+
+ if(ss->pbvh)
+ BLI_pbvh_free(ss->pbvh);
+ if(dm && dm->getPBVH)
+ dm->getPBVH(NULL, dm); /* signal to clear */
if(ss->texcache)
MEM_freeN(ss->texcache);
- if(ss->layer_disps)
- MEM_freeN(ss->layer_disps);
-
if(ss->layer_co)
MEM_freeN(ss->layer_co);
MEM_freeN(ss);
- *ssp = NULL;
+ ob->sculpt = NULL;
}
}
@@ -299,7 +284,6 @@ void free_object(Object *ob)
ob->path= 0;
if(ob->adt) BKE_free_animdata((ID *)ob);
if(ob->poselib) ob->poselib->id.us--;
- if(ob->dup_group) ob->dup_group->id.us--;
if(ob->gpd) ob->gpd->id.us--;
if(ob->defbase.first)
BLI_freelistN(&ob->defbase);
@@ -322,7 +306,7 @@ void free_object(Object *ob)
if(ob->bsoft) bsbFree(ob->bsoft);
if(ob->gpulamp.first) GPU_lamp_free(ob);
- free_sculptsession(&ob->sculpt);
+ free_sculptsession(ob);
if(ob->pc_ids.first) BLI_freelistN(&ob->pc_ids);
}
@@ -333,9 +317,10 @@ static void unlink_object__unlinkModifierLinks(void *userData, Object *ob, Objec
if (*obpoin==unlinkOb) {
*obpoin = NULL;
- ob->recalc |= OB_RECALC;
+ ob->recalc |= OB_RECALC_ALL; // XXX: should this just be OB_RECALC_DATA?
}
}
+
void unlink_object(Scene *scene, Object *ob)
{
Object *obt;
@@ -350,7 +335,9 @@ void unlink_object(Scene *scene, Object *ob)
bConstraint *con;
//bActionStrip *strip; // XXX animsys
ModifierData *md;
- int a;
+ ARegion *ar;
+ RegionView3D *rv3d;
+ int a, found;
unlink_controllers(&ob->controllers);
unlink_actuators(&ob->actuators);
@@ -370,12 +357,7 @@ void unlink_object(Scene *scene, Object *ob)
if(obt->parent==ob) {
obt->parent= NULL;
- obt->recalc |= OB_RECALC;
- }
-
- if(obt->track==ob) {
- obt->track= NULL;
- obt->recalc |= OB_RECALC_OB;
+ obt->recalc |= OB_RECALC_ALL;
}
modifiers_foreachObjectLink(obt, unlink_object__unlinkModifierLinks, ob);
@@ -385,15 +367,15 @@ void unlink_object(Scene *scene, Object *ob)
if(cu->bevobj==ob) {
cu->bevobj= NULL;
- obt->recalc |= OB_RECALC;
+ obt->recalc |= OB_RECALC_ALL;
}
if(cu->taperobj==ob) {
cu->taperobj= NULL;
- obt->recalc |= OB_RECALC;
+ obt->recalc |= OB_RECALC_ALL;
}
if(cu->textoncurve==ob) {
cu->textoncurve= NULL;
- obt->recalc |= OB_RECALC;
+ obt->recalc |= OB_RECALC_ALL;
}
}
else if(obt->type==OB_ARMATURE && obt->pose) {
@@ -422,6 +404,9 @@ void unlink_object(Scene *scene, Object *ob)
if(pchan->custom==ob)
pchan->custom= NULL;
}
+ } else if(ELEM(OB_MBALL, ob->type, obt->type)) {
+ if(is_mball_basis_for(obt, ob))
+ obt->recalc|= OB_RECALC_DATA;
}
sca_remove_ob_poin(obt, ob);
@@ -554,13 +539,7 @@ void unlink_object(Scene *scene, Object *ob)
}
tex= tex->id.next;
}
-
- /* mballs (scene==NULL when called from library.c) */
- if(scene && ob->type==OB_MBALL) {
- obt= find_basis_mball(scene, ob);
- if(obt) freedisplist(&obt->disp);
- }
-
+
/* worlds */
wrld= G.main->world.first;
while(wrld) {
@@ -592,7 +571,16 @@ void unlink_object(Scene *scene, Object *ob)
}
}
#endif
+ if(sce->ed) {
+ Sequence *seq;
+ SEQ_BEGIN(sce->ed, seq)
+ if(seq->scene_camera==ob) {
+ seq->scene_camera= NULL;
+ }
+ SEQ_END
+ }
}
+
sce= sce->id.next;
}
@@ -622,13 +610,32 @@ void unlink_object(Scene *scene, Object *ob)
if(sl->spacetype==SPACE_VIEW3D) {
View3D *v3d= (View3D*) sl;
+ found= 0;
if(v3d->camera==ob) {
v3d->camera= NULL;
- // XXX if(v3d->persp==V3D_CAMOB) v3d->persp= V3D_PERSP;
+ found= 1;
}
if(v3d->localvd && v3d->localvd->camera==ob ) {
v3d->localvd->camera= NULL;
- // XXX if(v3d->localvd->persp==V3D_CAMOB) v3d->localvd->persp= V3D_PERSP;
+ found += 2;
+ }
+
+ if (found) {
+ if (sa->spacetype == SPACE_VIEW3D) {
+ for (ar= sa->regionbase.first; ar; ar= ar->next) {
+ if (ar->regiontype==RGN_TYPE_WINDOW) {
+ rv3d= (RegionView3D *)ar->regiondata;
+ if (found == 1 || found == 3) {
+ if (rv3d->persp == RV3D_CAMOB)
+ rv3d->persp= RV3D_PERSP;
+ }
+ if (found == 2 || found == 3) {
+ if (rv3d->localvd && rv3d->localvd->persp == RV3D_CAMOB)
+ rv3d->localvd->persp= RV3D_PERSP;
+ }
+ }
+ }
+ }
}
}
else if(sl->spacetype==SPACE_OUTLINER) {
@@ -642,6 +649,14 @@ void unlink_object(Scene *scene, Object *ob)
}
}
}
+ else if(sl->spacetype==SPACE_BUTS) {
+ SpaceButs *sbuts= (SpaceButs *)sl;
+
+ if(sbuts->pinid==(ID *)ob) {
+ sbuts->flag&= ~SB_PIN_CONTEXT;
+ sbuts->pinid= NULL;
+ }
+ }
}
sa= sa->next;
@@ -687,13 +702,12 @@ void *add_camera(char *name)
cam= alloc_libblock(&G.main->camera, ID_CA, name);
cam->lens= 35.0f;
- cam->angle= 49.14f;
cam->clipsta= 0.1f;
cam->clipend= 100.0f;
cam->drawsize= 0.5f;
cam->ortho_scale= 6.0;
- cam->flag |= CAM_SHOWTITLESAFE;
- cam->passepartalpha = 0.2f;
+ cam->flag |= CAM_SHOWPASSEPARTOUT;
+ cam->passepartalpha = 0.5f;
return cam;
}
@@ -717,9 +731,9 @@ void make_local_camera(Camera *cam)
int local=0, lib=0;
/* - only lib users: do nothing
- * - only local users: set flag
- * - mixed: make copy
- */
+ * - only local users: set flag
+ * - mixed: make copy
+ */
if(cam->id.lib==0) return;
if(cam->id.us==1) {
@@ -865,9 +879,9 @@ void make_local_lamp(Lamp *la)
int local=0, lib=0;
/* - only lib users: do nothing
- * - only local users: set flag
- * - mixed: make copy
- */
+ * - only local users: set flag
+ * - mixed: make copy
+ */
if(la->id.lib==0) return;
if(la->id.us==1) {
@@ -969,7 +983,7 @@ static char *get_obdata_defname(int type)
case OB_MESH: return "Mesh";
case OB_CURVE: return "Curve";
case OB_SURF: return "Surf";
- case OB_FONT: return "Font";
+ case OB_FONT: return "Text";
case OB_MBALL: return "Mball";
case OB_CAMERA: return "Camera";
case OB_LAMP: return "Lamp";
@@ -1039,6 +1053,8 @@ Object *add_only_object(int type, char *name)
ob->anisotropicFriction[2] = 1.0f;
ob->gameflag= OB_PROP|OB_COLLISION;
ob->margin = 0.0;
+ ob->init_state=1;
+ ob->state=1;
/* ob->pad3 == Contact Processing Threshold */
ob->m_contactProcessingThreshold = 1.;
@@ -1071,7 +1087,7 @@ Object *add_object(struct Scene *scene, int type)
base= scene_add_base(scene, ob);
scene_select_base(scene, base);
- ob->recalc |= OB_RECALC;
+ ob->recalc |= OB_RECALC_ALL;
return ob;
}
@@ -1153,12 +1169,13 @@ ParticleSystem *copy_particlesystem(ParticleSystem *psys)
}
BLI_duplicatelist(&psysn->targets, &psys->targets);
-
+
psysn->pathcache= NULL;
psysn->childcache= NULL;
psysn->edit= NULL;
psysn->frand= NULL;
psysn->pdd= NULL;
+ psysn->effectors= NULL;
psysn->pathcachebufs.first = psysn->pathcachebufs.last = NULL;
psysn->childcachebufs.first = psysn->childcachebufs.last = NULL;
@@ -1277,6 +1294,7 @@ Object *copy_object(Object *ob)
for (md=ob->modifiers.first; md; md=md->next) {
ModifierData *nmd = modifier_new(md->type);
+ BLI_strncpy(nmd->name, md->name, sizeof(nmd->name));
modifier_copyData(md, nmd);
BLI_addtail(&obn->modifiers, nmd);
}
@@ -1295,14 +1313,14 @@ Object *copy_object(Object *ob)
armature_rebuild_pose(obn, obn->data);
}
defgroup_copy_list(&obn->defbase, &ob->defbase);
- copy_constraints(&obn->constraints, &ob->constraints);
+ copy_constraints(&obn->constraints, &ob->constraints, TRUE);
obn->mode = 0;
obn->sculpt = NULL;
/* increase user numbers */
id_us_plus((ID *)obn->data);
- id_us_plus((ID *)obn->dup_group);
+ id_lib_extern((ID *)obn->dup_group);
for(a=0; a<obn->totcol; a++) id_us_plus((ID *)obn->mat[a]);
@@ -1363,9 +1381,9 @@ void make_local_object(Object *ob)
int local=0, lib=0;
/* - only lib users: do nothing
- * - only local users: set flag
- * - mixed: make copy
- */
+ * - only local users: set flag
+ * - mixed: make copy
+ */
if(ob->id.lib==NULL) return;
@@ -1482,10 +1500,16 @@ void object_copy_proxy_drivers(Object *ob, Object *target)
/* all drivers */
DRIVER_TARGETS_LOOPER(dvar)
{
- if ((Object *)dtar->id == target)
- dtar->id= (ID *)ob;
- else
- id_lib_extern((ID *)dtar->id);
+ if(dtar->id) {
+ if ((Object *)dtar->id == target)
+ dtar->id= (ID *)ob;
+ else {
+ /* only on local objects because this causes indirect links a -> b -> c,blend to point directly to a.blend
+ * when a.blend has a proxy thats linked into c.blend */
+ if(ob->id.lib==NULL)
+ id_lib_extern((ID *)dtar->id);
+ }
+ }
}
DRIVER_TARGETS_LOOPER_END
}
@@ -1509,7 +1533,7 @@ void object_make_proxy(Object *ob, Object *target, Object *gob)
ob->proxy_group= gob;
id_lib_extern(&target->id);
- ob->recalc= target->recalc= OB_RECALC;
+ ob->recalc= target->recalc= OB_RECALC_ALL;
/* copy transform */
if(gob) {
@@ -1578,20 +1602,8 @@ void object_make_proxy(Object *ob, Object *target, Object *gob)
/* there is also a timing calculation in drawobject() */
-float bluroffs= 0.0f, fieldoffs= 0.0f;
int no_speed_curve= 0;
-/* ugly calls from render */
-void set_mblur_offs(float blur)
-{
- bluroffs= blur;
-}
-
-void set_field_offs(float field)
-{
- fieldoffs= field;
-}
-
void disable_speed_curve(int val)
{
no_speed_curve= val;
@@ -1601,11 +1613,9 @@ void disable_speed_curve(int val)
/* ob can be NULL */
float bsystem_time(struct Scene *scene, Object *ob, float cfra, float ofs)
{
- /* returns float ( see frame_to_float in ipo.c) */
+ /* returns float ( see BKE_curframe in scene.c) */
+ cfra += scene->r.subframe;
- /* bluroffs and fieldoffs are ugly globals that are set by render */
- cfra+= bluroffs+fieldoffs;
-
/* global time */
if (scene)
cfra*= scene->r.framelen;
@@ -1714,10 +1724,8 @@ void object_to_mat4(Object *ob, float mat[][4])
object_to_mat3(ob, tmat);
copy_m4_m3(mat, tmat);
-
- mat[3][0]= ob->loc[0] + ob->dloc[0];
- mat[3][1]= ob->loc[1] + ob->dloc[1];
- mat[3][2]= ob->loc[2] + ob->dloc[2];
+
+ add_v3_v3v3(mat[3], ob->loc, ob->dloc);
}
int enable_cu_speed= 1;
@@ -1773,7 +1781,7 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4])
/* vec: 4 items! */
- if( where_on_path(par, ctime, vec, dir, NULL, &radius) ) {
+ if( where_on_path(par, ctime, vec, dir, NULL, &radius, NULL) ) {
if(cu->flag & CU_FOLLOW) {
vec_to_quat( quat,dir, ob->trackflag, ob->upflag);
@@ -1826,7 +1834,7 @@ static void ob_parbone(Object *ob, Object *par, float mat[][4])
/* but for backwards compatibility, the child has to move to the tail */
VECCOPY(vec, mat[1]);
mul_v3_fl(vec, pchan->bone->length);
- add_v3_v3v3(mat[3], mat[3], vec);
+ add_v3_v3(mat[3], vec);
}
static void give_parvert(Object *par, int nr, float *vec)
@@ -1866,7 +1874,7 @@ static void give_parvert(Object *par, int nr, float *vec)
vindex= (index)? index[i]: i;
if(vindex == nr) {
- add_v3_v3v3(vec, vec, mvert[i].co);
+ add_v3_v3(vec, mvert[i].co);
count++;
}
}
@@ -1975,7 +1983,7 @@ static void ob_parvert3(Object *ob, Object *par, float mat[][4])
}
else {
add_v3_v3v3(mat[3], v1, v2);
- add_v3_v3v3(mat[3], mat[3], v3);
+ add_v3_v3(mat[3], v3);
mul_v3_fl(mat[3], 0.3333333f);
}
}
@@ -2042,12 +2050,6 @@ void where_is_object_time(Scene *scene, Object *ob, float ctime)
object_to_mat4(ob, ob->obmat);
}
- /* Handle tracking */
- if(ob->track) {
- if( ctime != ob->track->ctime) where_is_object_time(scene, ob->track, ctime);
- solve_tracking (ob, ob->track->obmat);
- }
-
/* solve constraints */
if (ob->constraints.first && !(ob->flag & OB_NO_CONSTRAINTS)) {
bConstraintOb *cob;
@@ -2143,33 +2145,6 @@ static void solve_parenting (Scene *scene, Object *ob, Object *par, float obmat[
}
}
-void solve_tracking (Object *ob, float targetmat[][4])
-{
- float quat[4];
- float vec[3];
- float totmat[3][3];
- float tmat[4][4];
-
- sub_v3_v3v3(vec, ob->obmat[3], targetmat[3]);
- vec_to_quat( quat,vec, ob->trackflag, ob->upflag);
- quat_to_mat3( totmat,quat);
-
- if(ob->parent && (ob->transflag & OB_POWERTRACK)) {
- /* 'temporal' : clear parent info */
- object_to_mat4(ob, tmat);
- tmat[0][3]= ob->obmat[0][3];
- tmat[1][3]= ob->obmat[1][3];
- tmat[2][3]= ob->obmat[2][3];
- tmat[3][0]= ob->obmat[3][0];
- tmat[3][1]= ob->obmat[3][1];
- tmat[3][2]= ob->obmat[3][2];
- tmat[3][3]= ob->obmat[3][3];
- }
- else copy_m4_m4(tmat, ob->obmat);
-
- mul_m4_m3m4(ob->obmat, totmat, tmat);
-
-}
void where_is_object(struct Scene *scene, Object *ob)
{
@@ -2190,12 +2165,6 @@ for a lamp that is the child of another object */
int a;
/* NO TIMEOFFS */
-
- /* no ipo! (because of dloc and realtime-ipos) */
- // XXX old animation system
- //ipo= ob->ipo;
- //ob->ipo= NULL;
-
if(ob->parent) {
par= ob->parent;
@@ -2217,9 +2186,6 @@ for a lamp that is the child of another object */
object_to_mat4(ob, ob->obmat);
}
- if(ob->track)
- solve_tracking(ob, ob->track->obmat);
-
/* solve constraints */
if (ob->constraints.first) {
bConstraintOb *cob;
@@ -2228,10 +2194,6 @@ for a lamp that is the child of another object */
solve_constraints(&ob->constraints, cob, (float)scene->r.cfra);
constraints_clear_evalob(cob);
}
-
- /* WATCH IT!!! */
- // XXX old animation system
- //ob->ipo= ipo;
}
/* for calculation of the inverse parent transform, only used for editor */
@@ -2243,7 +2205,6 @@ void what_does_parent(Scene *scene, Object *ob, Object *workob)
unit_m4(workob->parentinv);
unit_m4(workob->constinv);
workob->parent= ob->parent;
- workob->track= ob->track;
workob->trackflag= ob->trackflag;
workob->upflag= ob->upflag;
@@ -2292,7 +2253,7 @@ BoundBox *object_get_boundbox(Object *ob)
bb = mesh_get_bb(ob);
}
else if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
- bb= ( (Curve *)ob->data )->bb;
+ bb= ob->bb ? ob->bb : ( (Curve *)ob->data )->bb;
}
else if(ob->type==OB_MBALL) {
bb= ob->bb;
@@ -2310,6 +2271,44 @@ void object_boundbox_flag(Object *ob, int flag, int set)
}
}
+void object_get_dimensions(Object *ob, float *value)
+{
+ BoundBox *bb = NULL;
+
+ bb= object_get_boundbox(ob);
+ if (bb) {
+ float scale[3];
+
+ mat4_to_size( scale,ob->obmat);
+
+ value[0] = fabs(scale[0]) * (bb->vec[4][0] - bb->vec[0][0]);
+ value[1] = fabs(scale[1]) * (bb->vec[2][1] - bb->vec[0][1]);
+ value[2] = fabs(scale[2]) * (bb->vec[1][2] - bb->vec[0][2]);
+ } else {
+ value[0] = value[1] = value[2] = 0.f;
+ }
+}
+
+void object_set_dimensions(Object *ob, const float *value)
+{
+ BoundBox *bb = NULL;
+
+ bb= object_get_boundbox(ob);
+ if (bb) {
+ float scale[3], len[3];
+
+ mat4_to_size( scale,ob->obmat);
+
+ len[0] = bb->vec[4][0] - bb->vec[0][0];
+ len[1] = bb->vec[2][1] - bb->vec[0][1];
+ len[2] = bb->vec[1][2] - bb->vec[0][2];
+
+ if (len[0] > 0.f) ob->size[0] = value[0] / len[0];
+ if (len[1] > 0.f) ob->size[1] = value[1] / len[1];
+ if (len[2] > 0.f) ob->size[2] = value[2] / len[2];
+ }
+}
+
void minmax_object(Object *ob, float *min, float *max)
{
BoundBox bb;
@@ -2365,12 +2364,12 @@ void minmax_object(Object *ob, float *min, float *max)
default:
DO_MINMAX(ob->obmat[3], min, max);
- VECCOPY(vec, ob->obmat[3]);
- add_v3_v3v3(vec, vec, ob->size);
+ copy_v3_v3(vec, ob->obmat[3]);
+ add_v3_v3(vec, ob->size);
DO_MINMAX(vec, min, max);
- VECCOPY(vec, ob->obmat[3]);
- sub_v3_v3v3(vec, vec, ob->size);
+ copy_v3_v3(vec, ob->obmat[3]);
+ sub_v3_v3(vec, ob->size);
DO_MINMAX(vec, min, max);
break;
}
@@ -2477,11 +2476,26 @@ void object_tfm_restore(Object *ob, void *obtfm_pt)
/* requires flags to be set! */
void object_handle_update(Scene *scene, Object *ob)
{
- if(ob->recalc & OB_RECALC) {
-
+ if(ob->recalc & OB_RECALC_ALL) {
+ /* speed optimization for animation lookups */
+ if(ob->pose)
+ make_pose_channels_hash(ob->pose);
+
+ if(ob->recalc & OB_RECALC_DATA) {
+ if(ob->type==OB_ARMATURE) {
+ /* this happens for reading old files and to match library armatures
+ with poses we do it ahead of where_is_object to ensure animation
+ is evaluated on the rebuilt pose, otherwise we get incorrect poses
+ on file load */
+ if(ob->pose==NULL || (ob->pose->flag & POSE_RECALC))
+ armature_rebuild_pose(ob, ob->data);
+ }
+ }
+
/* XXX new animsys warning: depsgraph tag OB_RECALC_DATA should not skip drivers,
which is only in where_is_object now */
- if(ob->recalc & OB_RECALC) {
+ // XXX: should this case be OB_RECALC_OB instead?
+ if(ob->recalc & OB_RECALC_ALL) {
if (G.f & G_DEBUG)
printf("recalcob %s\n", ob->id.name+2);
@@ -2505,6 +2519,8 @@ void object_handle_update(Scene *scene, Object *ob)
ID *data_id= (ID *)ob->data;
AnimData *adt= BKE_animdata_from_id(data_id);
float ctime= (float)scene->r.cfra; // XXX this is bad...
+ ListBase pidlist;
+ PTCacheID *pid;
if (G.f & G_DEBUG)
printf("recalcdata %s\n", ob->id.name+2);
@@ -2518,7 +2534,7 @@ void object_handle_update(Scene *scene, Object *ob)
BKE_animsys_evaluate_animdata(data_id, adt, ctime, ADT_RECALC_DRIVERS);
// here was vieweditdatamask? XXX
- if(ob->mode & OB_MODE_EDIT) {
+ if(em) {
makeDerivedMesh(scene, ob, em, CD_MASK_BAREMESH);
} else
makeDerivedMesh(scene, ob, NULL, CD_MASK_BAREMESH);
@@ -2537,11 +2553,6 @@ void object_handle_update(Scene *scene, Object *ob)
lattice_calc_modifiers(scene, ob);
}
else if(ob->type==OB_ARMATURE) {
- /* this happens for reading old files and to match library armatures with poses */
- // XXX this won't screw up the pose set already...
- if(ob->pose==NULL || (ob->pose->flag & POSE_RECALC))
- armature_rebuild_pose(ob, ob->data);
-
/* evaluate drivers */
BKE_animsys_evaluate_animdata(data_id, adt, ctime, ADT_RECALC_DRIVERS);
@@ -2592,6 +2603,24 @@ void object_handle_update(Scene *scene, Object *ob)
psys_get_modifier(ob, psys)->flag &= ~eParticleSystemFlag_psys_updated;
}
}
+
+ /* check if quick cache is needed */
+ BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR);
+
+ for(pid=pidlist.first; pid; pid=pid->next) {
+ if((pid->cache->flag & PTCACHE_BAKED)
+ || (pid->cache->flag & PTCACHE_QUICK_CACHE)==0)
+ continue;
+
+ if(pid->cache->flag & PTCACHE_OUTDATED || (pid->cache->flag & PTCACHE_SIMULATION_VALID)==0) {
+ scene->physics_settings.quick_cache_step =
+ scene->physics_settings.quick_cache_step ?
+ MIN2(scene->physics_settings.quick_cache_step, pid->cache->step) :
+ pid->cache->step;
+ }
+ }
+
+ BLI_freelistN(&pidlist);
}
/* the no-group proxy case, we call update */
@@ -2602,7 +2631,7 @@ void object_handle_update(Scene *scene, Object *ob)
object_handle_update(scene, ob->proxy);
}
- ob->recalc &= ~OB_RECALC;
+ ob->recalc &= ~OB_RECALC_ALL;
}
/* the case when this is a group proxy, object_update is called in group.c */
@@ -2717,6 +2746,117 @@ int object_insert_ptcache(Object *ob)
return i;
}
+/* 'lens' may be set for envmap only */
+void object_camera_matrix(
+ RenderData *rd, Object *camera, int winx, int winy, short field_second,
+ float winmat[][4], rctf *viewplane, float *clipsta, float *clipend, float *lens, float *ycor,
+ float *viewdx, float *viewdy
+) {
+ Camera *cam=NULL;
+ float pixsize;
+ float shiftx=0.0, shifty=0.0, winside, viewfac;
+
+ rd->mode &= ~(R_ORTHO|R_PANORAMA);
+
+ /* question mark */
+ (*ycor)= rd->yasp / rd->xasp;
+ if(rd->mode & R_FIELDS)
+ (*ycor) *= 2.0f;
+
+ if(camera->type==OB_CAMERA) {
+ cam= camera->data;
+
+ if(cam->type==CAM_ORTHO) rd->mode |= R_ORTHO;
+ if(cam->flag & CAM_PANORAMA) rd->mode |= R_PANORAMA;
+
+ /* solve this too... all time depending stuff is in convertblender.c?
+ * Need to update the camera early because it's used for projection matrices
+ * and other stuff BEFORE the animation update loop is done
+ * */
+#if 0 // XXX old animation system
+ if(cam->ipo) {
+ calc_ipo(cam->ipo, frame_to_float(re->scene, re->r.cfra));
+ execute_ipo(&cam->id, cam->ipo);
+ }
+#endif // XXX old animation system
+ shiftx=cam->shiftx;
+ shifty=cam->shifty;
+ (*lens)= cam->lens;
+ (*clipsta)= cam->clipsta;
+ (*clipend)= cam->clipend;
+ }
+ else if(camera->type==OB_LAMP) {
+ Lamp *la= camera->data;
+ float fac= cos( M_PI*la->spotsize/360.0 );
+ float phi= acos(fac);
+
+ (*lens)= 16.0*fac/sin(phi);
+ if((*lens)==0.0f)
+ (*lens)= 35.0;
+ (*clipsta)= la->clipsta;
+ (*clipend)= la->clipend;
+ }
+ else { /* envmap exception... */;
+ if((*lens)==0.0f)
+ (*lens)= 16.0;
+
+ if((*clipsta)==0.0f || (*clipend)==0.0f) {
+ (*clipsta)= 0.1f;
+ (*clipend)= 1000.0f;
+ }
+ }
+
+ /* ortho only with camera available */
+ if(cam && rd->mode & R_ORTHO) {
+ if(rd->xasp*winx >= rd->yasp*winy) {
+ viewfac= winx;
+ }
+ else {
+ viewfac= (*ycor) * winy;
+ }
+ /* ortho_scale == 1.0 means exact 1 to 1 mapping */
+ pixsize= cam->ortho_scale/viewfac;
+ }
+ else {
+ if(rd->xasp*winx >= rd->yasp*winy) viewfac= ((*lens) * winx)/32.0;
+ else viewfac= (*ycor) * ((*lens) * winy)/32.0;
+ pixsize= (*clipsta) / viewfac;
+ }
+
+ /* viewplane fully centered, zbuffer fills in jittered between -.5 and +.5 */
+ winside= MAX2(winx, winy);
+ viewplane->xmin= -0.5f*(float)winx + shiftx*winside;
+ viewplane->ymin= -0.5f*(*ycor)*(float)winy + shifty*winside;
+ viewplane->xmax= 0.5f*(float)winx + shiftx*winside;
+ viewplane->ymax= 0.5f*(*ycor)*(float)winy + shifty*winside;
+
+ if(field_second) {
+ if(rd->mode & R_ODDFIELD) {
+ viewplane->ymin-= 0.5 * (*ycor);
+ viewplane->ymax-= 0.5 * (*ycor);
+ }
+ else {
+ viewplane->ymin+= 0.5 * (*ycor);
+ viewplane->ymax+= 0.5 * (*ycor);
+ }
+ }
+ /* the window matrix is used for clipping, and not changed during OSA steps */
+ /* using an offset of +0.5 here would give clip errors on edges */
+ viewplane->xmin *= pixsize;
+ viewplane->xmax *= pixsize;
+ viewplane->ymin *= pixsize;
+ viewplane->ymax *= pixsize;
+
+ (*viewdx)= pixsize;
+ (*viewdy)= (*ycor) * pixsize;
+
+ if(rd->mode & R_ORTHO)
+ orthographic_m4(winmat, viewplane->xmin, viewplane->xmax, viewplane->ymin, viewplane->ymax, *clipsta, *clipend);
+ else
+ perspective_m4(winmat, viewplane->xmin, viewplane->xmax, viewplane->ymin, viewplane->ymax, *clipsta, *clipend);
+
+}
+
#if 0
static int pc_findindex(ListBase *listbase, int index)
{
@@ -2761,15 +2901,18 @@ static KeyBlock *insert_meshkey(Scene *scene, Object *ob, char *name, int from_m
newkey= 1;
}
- kb= add_keyblock(key, name);
-
if(newkey || from_mix==FALSE) {
/* create from mesh */
+ kb= add_keyblock(key, name);
mesh_to_key(me, kb);
}
else {
/* copy from current values */
- kb->data= do_ob_key(scene, ob);
+ float *data= do_ob_key(scene, ob);
+
+ /* create new block with prepared data */
+ kb= add_keyblock(key, name);
+ kb->data= data;
kb->totelem= me->totvert;
}
@@ -2789,16 +2932,20 @@ static KeyBlock *insert_lattkey(Scene *scene, Object *ob, char *name, int from_m
newkey= 1;
}
- kb= add_keyblock(key, name);
-
if(newkey || from_mix==FALSE) {
+ kb= add_keyblock(key, name);
+
/* create from lattice */
latt_to_key(lt, kb);
}
else {
/* copy from current values */
+ float *data= do_ob_key(scene, ob);
+
+ /* create new block with prepared data */
+ kb= add_keyblock(key, name);
kb->totelem= lt->pntsu*lt->pntsv*lt->pntsw;
- kb->data= do_ob_key(scene, ob);
+ kb->data= data;
}
return kb;
@@ -2818,16 +2965,19 @@ static KeyBlock *insert_curvekey(Scene *scene, Object *ob, char *name, int from_
newkey= 1;
}
- kb= add_keyblock(key, name);
-
if(newkey || from_mix==FALSE) {
/* create from curve */
+ kb= add_keyblock(key, name);
curve_to_key(cu, kb, lb);
}
else {
/* copy from current values */
+ float *data= do_ob_key(scene, ob);
+
+ /* create new block with prepared data */
+ kb= add_keyblock(key, name);
kb->totelem= count_curveverts(lb);
- kb->data= do_ob_key(scene, ob);
+ kb->data= data;
}
return kb;
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index 55f09eede91..b01f570898e 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -33,10 +33,6 @@
#include <fcntl.h>
#include <sys/stat.h>
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#ifndef WIN32
#include <unistd.h>
#else
@@ -49,17 +45,14 @@
#include "DNA_sound_types.h"
#include "DNA_vfont_types.h"
#include "DNA_packedFile_types.h"
-#include "DNA_scene_types.h"
#include "BLI_blenlib.h"
#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BKE_main.h"
-#include "BKE_screen.h"
#include "BKE_sound.h"
#include "BKE_image.h"
-#include "BKE_font.h"
#include "BKE_packedFile.h"
#include "BKE_report.h"
@@ -186,14 +179,14 @@ PackedFile *newPackedFile(ReportList *reports, char *filename)
// convert relative filenames to absolute filenames
strcpy(name, filename);
- BLI_convertstringcode(name, G.sce);
+ BLI_path_abs(name, G.sce);
// open the file
// and create a PackedFile structure
file= open(name, O_BINARY|O_RDONLY);
if (file <= 0) {
- BKE_reportf(reports, RPT_ERROR, "Can't open file: \"%s\"", name);
+ BKE_reportf(reports, RPT_ERROR, "Unable to pack file, source path not found: \"%s\"", name);
} else {
filelen = BLI_filesize(file);
@@ -223,15 +216,15 @@ void packAll(Main *bmain, ReportList *reports)
bSound *sound;
for(ima=bmain->image.first; ima; ima=ima->id.next)
- if(ima->packedfile == NULL)
+ if(ima->packedfile == NULL && ima->id.lib==NULL && ELEM3(ima->source, IMA_SRC_FILE, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE))
ima->packedfile = newPackedFile(reports, ima->name);
for(vf=bmain->vfont.first; vf; vf=vf->id.next)
- if(vf->packedfile == NULL)
+ if(vf->packedfile == NULL && vf->id.lib==NULL)
vf->packedfile = newPackedFile(reports, vf->name);
for(sound=bmain->sound.first; sound; sound=sound->id.next)
- if(sound->packedfile == NULL)
+ if(sound->packedfile == NULL && sound->id.lib==NULL)
sound->packedfile = newPackedFile(reports, sound->name);
}
@@ -271,10 +264,10 @@ int writePackedFile(ReportList *reports, char *filename, PackedFile *pf, int gui
char tempname[FILE_MAXDIR + FILE_MAXFILE];
/* void *data; */
- if (guimode); //XXX waitcursor(1);
+ if (guimode) {} //XXX waitcursor(1);
strcpy(name, filename);
- BLI_convertstringcode(name, G.sce);
+ BLI_path_abs(name, G.sce);
if (BLI_exists(name)) {
for (number = 1; number <= 999; number++) {
@@ -315,7 +308,7 @@ int writePackedFile(ReportList *reports, char *filename, PackedFile *pf, int gui
}
}
- if(guimode); //XXX waitcursor(0);
+ if(guimode) {} //XXX waitcursor(0);
return (ret_value);
}
@@ -339,7 +332,7 @@ int checkPackedFile(char *filename, PackedFile *pf)
char name[FILE_MAXDIR + FILE_MAXFILE];
strcpy(name, filename);
- BLI_convertstringcode(name, G.sce);
+ BLI_path_abs(name, G.sce);
if (stat(name, &st)) {
ret_val = PF_NOFILE;
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 5728c7a1fe0..cf5deb95258 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -27,13 +27,11 @@
#include "MEM_guardedalloc.h"
-#include "DNA_brush_types.h"
#include "DNA_object_types.h"
#include "DNA_mesh_types.h"
#include "DNA_scene_types.h"
#include "BKE_brush.h"
-#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_paint.h"
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 7cee4b1d7bb..4c68c5487c8 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -35,27 +35,15 @@
#include "MEM_guardedalloc.h"
-#include "DNA_boid_types.h"
#include "DNA_curve_types.h"
#include "DNA_group_types.h"
-#include "DNA_ipo_types.h" // XXX old animation system stuff to remove!
#include "DNA_key_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_object_force.h"
-#include "DNA_object_types.h"
#include "DNA_particle_types.h"
-#include "DNA_scene_types.h"
#include "DNA_smoke_types.h"
-#include "DNA_texture_types.h"
-#include "BLI_math.h"
-#include "BLI_blenlib.h"
-#include "BLI_dynstr.h"
#include "BLI_kdtree.h"
-#include "BLI_listbase.h"
#include "BLI_rand.h"
#include "BLI_threads.h"
#include "BLI_cellalloc.h"
@@ -73,9 +61,7 @@
#include "BKE_utildefines.h"
#include "BKE_displist.h"
#include "BKE_particle.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_object.h"
-#include "BKE_cloth.h"
#include "BKE_material.h"
#include "BKE_key.h"
#include "BKE_library.h"
@@ -370,6 +356,12 @@ int psys_uses_gravity(ParticleSimulationData *sim)
/************************************************/
/* Freeing stuff */
/************************************************/
+void fluid_free_settings(SPHFluidSettings *fluid)
+{
+ if(fluid)
+ MEM_freeN(fluid);
+}
+
void psys_free_settings(ParticleSettings *part)
{
BKE_free_animdata(&part->id);
@@ -382,6 +374,7 @@ void psys_free_settings(ParticleSettings *part)
BLI_freelistN(&part->dupliweights);
boid_free_settings(part->boids);
+ fluid_free_settings(part->fluid);
}
void free_hair(Object *ob, ParticleSystem *psys, int dynamics)
@@ -404,7 +397,7 @@ void free_hair(Object *ob, ParticleSystem *psys, int dynamics)
if(dynamics) {
BKE_ptcache_free_list(&psys->ptcaches);
psys->clmd->point_cache = psys->pointcache = NULL;
- psys->clmd->ptcaches.first = psys->clmd->ptcaches.first = NULL;
+ psys->clmd->ptcaches.first = psys->clmd->ptcaches.last = NULL;
modifier_free((ModifierData*)psys->clmd);
@@ -441,7 +434,7 @@ void free_keyed_keys(ParticleSystem *psys)
}
}
}
-static void free_child_path_cache(ParticleSystem *psys)
+void psys_free_child_path_cache(ParticleSystem *psys)
{
psys_free_path_cache_buffers(psys->childcache, &psys->childcachebufs);
psys->childcache = NULL;
@@ -459,7 +452,7 @@ void psys_free_path_cache(ParticleSystem *psys, PTCacheEdit *edit)
psys->pathcache= NULL;
psys->totcached= 0;
- free_child_path_cache(psys);
+ psys_free_child_path_cache(psys);
}
}
void psys_free_children(ParticleSystem *psys)
@@ -470,7 +463,7 @@ void psys_free_children(ParticleSystem *psys)
psys->totchild=0;
}
- free_child_path_cache(psys);
+ psys_free_child_path_cache(psys);
}
void psys_free_particles(ParticleSystem *psys)
{
@@ -1045,6 +1038,7 @@ typedef struct ParticleInterpolationData {
ParticleKey *kkey[2];
PointCache *cache;
+ PTCacheMem *pm;
PTCacheEditPoint *epoint;
PTCacheEditKey *ekey[2];
@@ -1053,31 +1047,74 @@ typedef struct ParticleInterpolationData {
int bspline;
} ParticleInterpolationData;
/* Assumes pointcache->mem_cache exists, so for disk cached particles call psys_make_temp_pointcache() before use */
-static void get_pointcache_keys_for_time(Object *ob, PointCache *cache, int index, float t, ParticleKey *key1, ParticleKey *key2)
+/* It uses ParticleInterpolationData->pm to store the current memory cache frame so it's thread safe. */
+static void get_pointcache_keys_for_time(Object *ob, PointCache *cache, PTCacheMem **cur, int index, float t, ParticleKey *key1, ParticleKey *key2)
{
- static PTCacheMem *pm = NULL; /* not thread safe */
+ static PTCacheMem *pm = NULL;
if(index < 0) { /* initialize */
- pm = cache->mem_cache.first;
+ *cur = cache->mem_cache.first;
- if(pm)
- pm = pm->next;
+ if(*cur)
+ *cur = (*cur)->next;
}
else {
- if(pm) {
- while(pm && pm->next && (float)pm->frame < t)
- pm = pm->next;
+ if(*cur) {
+ while(*cur && (*cur)->next && (float)(*cur)->frame < t)
+ *cur = (*cur)->next;
- BKE_ptcache_make_particle_key(key2, pm->index_array ? pm->index_array[index] : index, pm->data, (float)pm->frame);
- BKE_ptcache_make_particle_key(key1, pm->prev->index_array ? pm->prev->index_array[index] : index, pm->prev->data, (float)pm->prev->frame);
+ pm = *cur;
+
+ BKE_ptcache_make_particle_key(key2, pm->index_array ? pm->index_array[index] - 1 : index, pm->data, (float)pm->frame);
+ if(pm->prev->index_array && pm->prev->index_array[index] == 0)
+ copy_particle_key(key1, key2, 1);
+ else
+ BKE_ptcache_make_particle_key(key1, pm->prev->index_array ? pm->prev->index_array[index] - 1 : index, pm->prev->data, (float)pm->prev->frame);
}
else if(cache->mem_cache.first) {
- PTCacheMem *pm2 = cache->mem_cache.first;
- BKE_ptcache_make_particle_key(key2, pm2->index_array ? pm2->index_array[index] : index, pm2->data, (float)pm2->frame);
+ pm = cache->mem_cache.first;
+ BKE_ptcache_make_particle_key(key2, pm->index_array ? pm->index_array[index] - 1 : index, pm->data, (float)pm->frame);
copy_particle_key(key1, key2, 1);
}
}
}
+static int get_pointcache_times_for_particle(PointCache *cache, int index, float *start, float *end)
+{
+ PTCacheMem *pm;
+ int ret = 0;
+
+ for(pm=cache->mem_cache.first; pm; pm=pm->next) {
+ if(pm->index_array) {
+ if(pm->index_array[index]) {
+ *start = pm->frame;
+ ret++;
+ break;
+ }
+ }
+ else {
+ *start = pm->frame;
+ ret++;
+ break;
+ }
+ }
+
+ for(pm=cache->mem_cache.last; pm; pm=pm->prev) {
+ if(pm->index_array) {
+ if(pm->index_array[index]) {
+ *end = pm->frame;
+ ret++;
+ break;
+ }
+ }
+ else {
+ *end = pm->frame;
+ ret++;
+ break;
+ }
+ }
+
+ return ret == 2;
+}
static void init_particle_interpolation(Object *ob, ParticleSystem *psys, ParticleData *pa, ParticleInterpolationData *pind)
{
@@ -1099,10 +1136,15 @@ static void init_particle_interpolation(Object *ob, ParticleSystem *psys, Partic
pind->dietime = (key + pa->totkey - 1)->time;
}
else if(pind->cache) {
- get_pointcache_keys_for_time(ob, pind->cache, -1, 0.0f, NULL, NULL);
-
+ float start, end;
+ get_pointcache_keys_for_time(ob, pind->cache, &pind->pm, -1, 0.0f, NULL, NULL);
pind->birthtime = pa ? pa->time : pind->cache->startframe;
pind->dietime = pa ? pa->dietime : pind->cache->endframe;
+
+ if(get_pointcache_times_for_particle(pind->cache, pa - psys->particles, &start, &end)) {
+ pind->birthtime = MAX2(pind->birthtime, start);
+ pind->dietime = MIN2(pind->dietime, end);
+ }
}
else {
HairKey *key = pa->hair;
@@ -1145,6 +1187,9 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData
int point_vel = (point && point->keys->vel);
float real_t, dfra, keytime;
+ /* billboards wont fill in all of these, so start cleared */
+ memset(keys, 0, sizeof(keys));
+
/* interpret timing and find keys */
if(point) {
if(result->time < 0.0f)
@@ -1229,7 +1274,7 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData
memcpy(keys + 2, pind->kkey[1], sizeof(ParticleKey));
}
else if(pind->cache) {
- get_pointcache_keys_for_time(NULL, pind->cache, p, real_t, keys+1, keys+2);
+ get_pointcache_keys_for_time(NULL, pind->cache, &pind->pm, p, real_t, keys+1, keys+2);
}
else {
hair_to_particle(keys + 1, pind->hkey[0]);
@@ -1993,7 +2038,7 @@ int do_guides(ListBase *effectors, ParticleKey *state, int index, float time)
float effect[3] = {0.0f, 0.0f, 0.0f}, veffect[3] = {0.0f, 0.0f, 0.0f};
float guidevec[4], guidedir[3], rot2[4], temp[3];
- float guidetime, radius, angle, totstrength = 0.0f;
+ float guidetime, radius, weight, angle, totstrength = 0.0f;
float vec_to_point[3];
if(effectors) for(eff = effectors->first; eff; eff=eff->next) {
@@ -2015,11 +2060,11 @@ int do_guides(ListBase *effectors, ParticleKey *state, int index, float time)
cu = (Curve*)eff->ob->data;
if(pd->flag & PFIELD_GUIDE_PATH_ADD) {
- if(where_on_path(eff->ob, data->strength * guidetime, guidevec, guidedir, NULL, &radius)==0)
+ if(where_on_path(eff->ob, data->strength * guidetime, guidevec, guidedir, NULL, &radius, &weight)==0)
return 0;
}
else {
- if(where_on_path(eff->ob, guidetime, guidevec, guidedir, NULL, &radius)==0)
+ if(where_on_path(eff->ob, guidetime, guidevec, guidedir, NULL, &radius, &weight)==0)
return 0;
}
@@ -2059,10 +2104,14 @@ int do_guides(ListBase *effectors, ParticleKey *state, int index, float time)
VECCOPY(vec_to_point, key.co);
VECADD(vec_to_point, vec_to_point, guidevec);
+
//VECSUB(pa_loc,pa_loc,pa_zero);
VECADDFAC(effect, effect, vec_to_point, data->strength);
VECADDFAC(veffect, veffect, guidedir, data->strength);
totstrength += data->strength;
+
+ if(pd->flag & PFIELD_GUIDE_PATH_WEIGHT)
+ totstrength *= weight;
}
if(totstrength != 0.0){
@@ -2130,7 +2179,7 @@ static void do_path_effectors(ParticleSimulationData *sim, int i, ParticleCacheK
mul_v3_fl(force, effector*pow((float)k / (float)steps, 100.0f * sim->psys->part->eff_hair) / (float)steps);
- add_v3_v3v3(force, force, vec);
+ add_v3_v3(force, vec);
normalize_v3(force);
@@ -2673,7 +2722,7 @@ void psys_cache_child_paths(ParticleSimulationData *sim, float cfra, int editupd
}
else {
/* clear out old and create new empty path cache */
- free_child_path_cache(sim->psys);
+ psys_free_child_path_cache(sim->psys);
sim->psys->childcache= psys_alloc_path_cache_buffers(&sim->psys->childcachebufs, totchild, ctx->steps+1);
sim->psys->totchildcache = totchild;
}
@@ -2744,7 +2793,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
int keyed, baked;
/* we don't have anything valid to create paths from so let's quit here */
- if((psys->flag & PSYS_HAIR_DONE || psys->flag & PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED)==0)
+ if((psys->flag & PSYS_HAIR_DONE || psys->flag & PSYS_KEYED || psys->pointcache)==0)
return;
if(psys_in_edit_mode(sim->scene, psys))
@@ -2754,7 +2803,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
BLI_srandom(psys->seed);
keyed = psys->flag & PSYS_KEYED;
- baked = !hair_dm && psys->pointcache->flag & PTCACHE_BAKED;
+ baked = !hair_dm && psys->pointcache->mem_cache.first;
/* clear out old and create new empty path cache */
psys_free_path_cache(psys, psys->edit);
@@ -2941,7 +2990,7 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
ParticleCacheKey *ca, **cache= edit->pathcache;
ParticleEditSettings *pset = &scene->toolsettings->particle;
- PTCacheEditPoint *point = edit->points;
+ PTCacheEditPoint *point = NULL;
PTCacheEditKey *ekey = NULL;
ParticleSystem *psys = edit->psys;
@@ -2954,9 +3003,9 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
float birthtime = 0.0, dietime = 0.0;
float t, time = 0.0, keytime = 0.0, frs_sec;
float hairmat[4][4], rotmat[3][3], prev_tangent[3];
- int k,i;
+ int k, i;
int steps = (int)pow(2.0, (double)pset->draw_step);
- int totpart = edit->totpoint;
+ int totpart = edit->totpoint, recalc_set=0;
float sel_col[3];
float nosel_col[3];
@@ -2966,6 +3015,11 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
/* clear out old and create new empty path cache */
psys_free_path_cache(edit->psys, edit);
cache= edit->pathcache= psys_alloc_path_cache_buffers(&edit->pathcachebufs, totpart, steps+1);
+
+ /* set flag for update (child particles check this too) */
+ for(i=0, point=edit->points; i<totpart; i++, point++)
+ point->flag |= PEP_EDIT_RECALC;
+ recalc_set = 1;
}
frs_sec = (psys || edit->pid.flag & PTCACHE_VEL_PER_SEC) ? 25.0f : 1.0f;
@@ -2987,7 +3041,7 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
}
/*---first main loop: create all actual particles' paths---*/
- for(i=0; i<totpart; i++, pa+=pa?1:0, point++){
+ for(i=0, point=edit->points; i<totpart; i++, pa+=pa?1:0, point++){
if(edit->totcached && !(point->flag & PEP_EDIT_RECALC))
continue;
@@ -3096,17 +3150,26 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
/* selection coloring in edit mode */
if(pset->brushtype==PE_BRUSH_WEIGHT){
- if(k==0)
+ float t2;
+
+ if(k==0) {
weight_to_rgb(pind.hkey[1]->weight, ca->col, ca->col+1, ca->col+2);
- else if(k >= steps - 1)
- weight_to_rgb(pind.hkey[0]->weight, ca->col, ca->col+1, ca->col+2);
- else
- weight_to_rgb((1.0f - keytime) * pind.hkey[0]->weight + keytime * pind.hkey[1]->weight, ca->col, ca->col+1, ca->col+2);
+ } else {
+ float w1[3], w2[3];
+ keytime = (t - (*pind.ekey[0]->time))/((*pind.ekey[1]->time) - (*pind.ekey[0]->time));
+
+ weight_to_rgb(pind.hkey[0]->weight, w1, w1+1, w1+2);
+ weight_to_rgb(pind.hkey[1]->weight, w2, w2+1, w2+2);
+
+ interp_v3_v3v3(ca->col, w1, w2, keytime);
+ }
/* at the moment this is only used for weight painting.
* will need to move out of this check if its used elsewhere. */
- pind.hkey[0] = pind.hkey[1];
- pind.hkey[1]++;
+ t2 = birthtime + ((float)(k+1)/(float)steps) * (dietime - birthtime);
+
+ while (pind.hkey[1]->time < t2) pind.hkey[1]++;
+ pind.hkey[0] = pind.hkey[1] - 1;
}
else {
if((ekey + (pind.ekey[0] - point->keys))->flag & PEK_SELECT){
@@ -3135,10 +3198,16 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
edit->totcached = totpart;
- if(psys && psys->part->type == PART_HAIR) {
+ if(psys) {
ParticleSimulationData sim = {scene, ob, psys, psys_get_modifier(ob, psys), NULL};
psys_cache_child_paths(&sim, cfra, 1);
}
+
+ /* clear recalc flag if set here */
+ if(recalc_set) {
+ for(i=0, point=edit->points; i<totpart; i++, point++)
+ point->flag &= ~PEP_EDIT_RECALC;
+ }
}
/************************************************/
/* Particle Key handling */
@@ -3468,6 +3537,7 @@ ParticleSettings *psys_copy_settings(ParticleSettings *part)
partn= copy_libblock(part);
if(partn->pd) partn->pd= MEM_dupallocN(part->pd);
if(partn->pd2) partn->pd2= MEM_dupallocN(part->pd2);
+ partn->effector_weights = MEM_dupallocN(part->effector_weights);
partn->boids = boid_copy_settings(part->boids);
@@ -3481,9 +3551,9 @@ void make_local_particlesettings(ParticleSettings *part)
int local=0, lib=0;
/* - only lib users: do nothing
- * - only local users: set flag
- * - mixed: make copy
- */
+ * - only local users: set flag
+ * - mixed: make copy
+ */
if(part->id.lib==0) return;
if(part->id.us==1) {
@@ -4188,8 +4258,13 @@ void psys_get_dupli_texture(Object *ob, ParticleSettings *part, ParticleSystemMo
num= pa->num_dmcache;
if(num == DMCACHE_NOTFOUND)
- if(pa->num < psmd->dm->getNumTessFaces(psmd->dm))
- num= pa->num;
+ num= pa->num;
+
+ if (num >= psmd->dm->getNumFaces(psmd->dm)) {
+ /* happens when simplify is enabled
+ * gives invalid coords but would crash otherwise */
+ num= DMCACHE_NOTFOUND;
+ }
if(mtface && num != DMCACHE_NOTFOUND) {
mface= psmd->dm->getTessFaceData(psmd->dm, num, CD_MFACE);
@@ -4212,18 +4287,11 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa
ParticleSystem *psys = sim->psys;
ParticleSystemModifierData *psmd = sim->psmd;
float loc[3], nor[3], vec[3], side[3], len, obrotmat[4][4], qmat[4][4];
- float xvec[3] = {-1.0, 0.0, 0.0}, q[4];
+ float xvec[3] = {-1.0, 0.0, 0.0}, q[4], nmat[3][3];
sub_v3_v3v3(vec, (cache+cache->steps-1)->co, cache->co);
len= normalize_v3(vec);
- if(pa)
- psys_particle_on_emitter(psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,nor,0,0,0,0);
- else
- psys_particle_on_emitter(psmd,
- (psys->part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE,
- cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,loc,nor,0,0,0,0);
-
if(psys->part->rotmode) {
if(!pa)
pa= psys->particles+cpa->pa[0];
@@ -4236,6 +4304,17 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa
mul_m4_m4m4(mat, obrotmat, qmat);
}
else {
+ if(pa)
+ psys_particle_on_emitter(psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,nor,0,0,0,0);
+ else
+ psys_particle_on_emitter(psmd,
+ (psys->part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE,
+ cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,loc,nor,0,0,0,0);
+
+ copy_m3_m4(nmat, ob->imat);
+ transpose_m3(nmat);
+ mul_m3_v3(nmat, nor);
+
/* make sure that we get a proper side vector */
if(fabs(dot_v3v3(nor,vec))>0.999999) {
if(fabs(dot_v3v3(nor,xvec))>0.999999) {
@@ -4253,7 +4332,7 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa
normalize_v3(side);
cross_v3_v3v3(nor, vec, side);
- unit_m4(mat);
+ unit_m4(mat);
VECCOPY(mat[0], vec);
VECCOPY(mat[1], side);
VECCOPY(mat[2], nor);
@@ -4269,6 +4348,23 @@ void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[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;
+ /* can happen with bad pointcache or physics calculation
+ * since this becomes geometry, nan's and inf's crash raytrace code.
+ * better not allow this. */
+ if( !finite(bb->vec[0]) || !finite(bb->vec[1]) || !finite(bb->vec[2]) ||
+ !finite(bb->vel[0]) || !finite(bb->vel[1]) || !finite(bb->vel[2]) )
+ {
+ zero_v3(bb->vec);
+ zero_v3(bb->vel);
+
+ zero_v3(xvec);
+ zero_v3(yvec);
+ zero_v3(zvec);
+ zero_v3(center);
+
+ return;
+ }
+
if(bb->align < PART_BB_VIEW)
onevec[bb->align]=1.0f;
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index b057976e3b5..a128cfaedf9 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -24,7 +24,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Raul Fernandez Hernandez (Farsthary), Stephen Swhitehorn.
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -159,8 +159,7 @@ void psys_reset(ParticleSystem *psys, int mode)
psys_free_path_cache(psys, psys->edit);
/* reset point cache */
- psys->pointcache->flag &= ~PTCACHE_SIMULATION_VALID;
- psys->pointcache->simframe= 0;
+ BKE_ptcache_invalidate(psys->pointcache);
}
static void realloc_particles(ParticleSimulationData *sim, int new_totpart)
@@ -287,7 +286,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
node: the allocated links - total derived mesh element count
nodearray: the array of nodes aligned with the base mesh's elements, so
- each original elements can reference its derived elements
+ each original elements can reference its derived elements
*/
Mesh *me= (Mesh*)ob->data;
PARTICLE_P;
@@ -512,18 +511,18 @@ static void distribute_particles_in_grid(DerivedMesh *dm, ParticleSystem *psys)
static void hammersley_create(float *out, int n, int seed, float amount)
{
RNG *rng;
- double p, t, offs[2];
- int k, kk;
+ double p, t, offs[2];
+ int k, kk;
rng = rng_new(31415926 + n + seed);
offs[0]= rng_getDouble(rng) + amount;
offs[1]= rng_getDouble(rng) + amount;
rng_free(rng);
- for (k = 0; k < n; k++) {
- t = 0;
- for (p = 0.5, kk = k; kk; p *= 0.5, kk >>= 1)
- if (kk & 1) /* kk mod 2 = 1 */
+ for (k = 0; k < n; k++) {
+ t = 0;
+ for (p = 0.5, kk = k; kk; p *= 0.5, kk >>= 1)
+ if (kk & 1) /* kk mod 2 = 1 */
t += p;
out[2*k + 0]= fmod((double)k/(double)n + offs[0], 1.0);
@@ -546,7 +545,7 @@ static void init_mv_jit(float *jit, int num, int seed2, float amount)
rng = rng_new(31415926 + num + seed2);
x= 0;
- num2 = 2 * num;
+ num2 = 2 * num;
for(i=0; i<num2; i+=2) {
jit[i]= x + amount*rad1*(0.5f - rng_getFloat(rng));
@@ -618,6 +617,10 @@ static int binary_search_distribution(float *sum, int n, float value)
return low;
}
+/* the max number if calls to rng_* funcs within psys_thread_distribute_particle
+ * be sure to keep up to date if this changes */
+#define PSYS_RND_DIST_SKIP 2
+
/* note: this function must be thread safe, for from == PART_FROM_CHILD */
#define ONLY_WORKING_WITH_PA_VERTS 0
static void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, ChildParticle *cpa, int p)
@@ -633,6 +636,7 @@ static void psys_thread_distribute_particle(ParticleThread *thread, ParticleData
int cfrom= ctx->cfrom;
int distr= ctx->distr;
int i, intersect, tot;
+ int rng_skip_tot= PSYS_RND_DIST_SKIP; /* count how many rng_* calls wont need skipping */
if(from == PART_FROM_VERT) {
/* TODO_PARTICLE - use original index */
@@ -670,6 +674,8 @@ static void psys_thread_distribute_particle(ParticleThread *thread, ParticleData
case PART_DISTR_RAND:
randu= rng_getFloat(thread->rng);
randv= rng_getFloat(thread->rng);
+ rng_skip_tot -= 2;
+
psys_uv_to_w(randu, randv, mface->v4, pa->fuv);
break;
}
@@ -752,6 +758,8 @@ static void psys_thread_distribute_particle(ParticleThread *thread, ParticleData
randu= rng_getFloat(thread->rng);
randv= rng_getFloat(thread->rng);
+ rng_skip_tot -= 2;
+
psys_uv_to_w(randu, randv, mf->v4, cpa->fuv);
cpa->num = ctx->index[p];
@@ -860,6 +868,9 @@ static void psys_thread_distribute_particle(ParticleThread *thread, ParticleData
cpa->parent=cpa->pa[0];
}
}
+
+ if(rng_skip_tot > 0) /* should never be below zero */
+ rng_skip(thread->rng, rng_skip_tot);
}
static void *exec_distribution(void *data)
@@ -876,12 +887,12 @@ static void *exec_distribution(void *data)
for(p=0; p<totpart; p++, cpa++) {
if(thread->ctx->skip) /* simplification skip */
- rng_skip(thread->rng, 5*thread->ctx->skip[p]);
+ rng_skip(thread->rng, PSYS_RND_DIST_SKIP * thread->ctx->skip[p]);
if((p+thread->num) % thread->tot == 0)
psys_thread_distribute_particle(thread, NULL, cpa, p);
else /* thread skip */
- rng_skip(thread->rng, 5);
+ rng_skip(thread->rng, PSYS_RND_DIST_SKIP);
}
}
else {
@@ -2215,21 +2226,17 @@ static void set_keyed_keys(ParticleSimulationData *sim)
void psys_make_temp_pointcache(Object *ob, ParticleSystem *psys)
{
PointCache *cache = psys->pointcache;
- PTCacheID pid;
-
- if((cache->flag & PTCACHE_DISK_CACHE)==0 || cache->mem_cache.first)
- return;
- BKE_ptcache_id_from_particles(&pid, ob, psys);
-
- BKE_ptcache_disk_to_mem(&pid);
+ if(cache->flag & PTCACHE_DISK_CACHE && cache->mem_cache.first == NULL) {
+ PTCacheID pid;
+ BKE_ptcache_id_from_particles(&pid, ob, psys);
+ BKE_ptcache_disk_to_mem(&pid);
+ }
}
static void psys_clear_temp_pointcache(ParticleSystem *psys)
{
- if((psys->pointcache->flag & PTCACHE_DISK_CACHE)==0)
- return;
-
- BKE_ptcache_free_mem(&psys->pointcache->mem_cache);
+ if(psys->pointcache->flag & PTCACHE_DISK_CACHE)
+ BKE_ptcache_free_mem(&psys->pointcache->mem_cache);
}
void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra, int *efra)
{
@@ -2275,6 +2282,136 @@ static void psys_update_effectors(ParticleSimulationData *sim)
precalc_guides(sim, sim->psys->effectors);
}
+/*************************************************
+ SPH fluid physics
+
+ In theory, there could be unlimited implementation
+ of SPH simulators
+**************************************************/
+void particle_fluidsim(ParticleSystem *psys, ParticleData *pa, ParticleSettings *part, ParticleSimulationData *sim, float dfra, float cfra, float mass){
+/****************************************************************************************************************
+* This code uses in some parts adapted algorithms from the pseduo code as outlined in the Research paper
+* Titled: Particle-based Viscoelastic Fluid Simulation.
+* Authors: Simon Clavet, Philippe Beaudoin and Pierre Poulin
+*
+* Website: http://www.iro.umontreal.ca/labs/infographie/papers/Clavet-2005-PVFS/
+* Presented at Siggraph, (2005)
+*
+*****************************************************************************************************************/
+ KDTree *tree = psys->tree;
+ KDTreeNearest *ptn = NULL;
+
+ SPHFluidSettings *fluid = part->fluid;
+ ParticleData *second_particle;
+
+ float start[3], end[3], v[3];
+ float temp[3];
+ float q, radius, D;
+ float p, pnear, pressure_near, pressure;
+ float dtime = dfra * psys_get_timestep(sim);
+ float omega = fluid->viscosity_omega;
+ float beta = fluid->viscosity_omega;
+ float massfactor = 1.0f/mass;
+ int n, neighbours;
+
+
+ radius = fluid->radius;
+
+ VECCOPY(start, pa->prev_state.co);
+ VECCOPY(end, pa->state.co);
+
+ VECCOPY(v, pa->state.vel);
+
+ neighbours = BLI_kdtree_range_search(tree, radius, start, NULL, &ptn);
+
+ /* use ptn[n].co to store relative direction */
+ for(n=1; n<neighbours; n++) {
+ sub_v3_v3(ptn[n].co, start);
+ normalize_v3(ptn[n].co);
+ }
+
+ /* Viscosity - Algorithm 5 */
+ if (omega > 0.f || beta > 0.f) {
+ float u, I;
+
+ for(n=1; n<neighbours; n++) {
+ second_particle = psys->particles + ptn[n].index;
+ q = ptn[n].dist/radius;
+
+ sub_v3_v3v3(temp, v, second_particle->prev_state.vel);
+
+ u = dot_v3v3(ptn[n].co, temp);
+
+ if (u > 0){
+ I = dtime * ((1-q) * (omega * u + beta * u*u)) * 0.5f;
+ madd_v3_v3fl(v, ptn[n].co, -I * massfactor);
+ }
+ }
+ }
+
+ /* Hooke's spring force */
+ if (fluid->spring_k > 0.f) {
+ float D, L = fluid->rest_length;
+ for(n=1; n<neighbours; n++) {
+ /* L is a factor of radius */
+ D = dtime * 10.f * fluid->spring_k * (1.f - L) * (L - ptn[n].dist/radius);
+ madd_v3_v3fl(v, ptn[n].co, -D * massfactor);
+ }
+ }
+ /* Update particle position */
+ VECADDFAC(end, start, v, dtime);
+
+ /* Double Density Relaxation - Algorithm 2 */
+ p = 0;
+ pnear = 0;
+ for(n=1; n<neighbours; n++) {
+ q = ptn[n].dist/radius;
+ p += ((1-q)*(1-q));
+ pnear += ((1-q)*(1-q)*(1-q));
+ }
+ p *= part->mass;
+ pnear *= part->mass;
+ pressure = fluid->stiffness_k * (p - fluid->rest_density);
+ pressure_near = fluid->stiffness_knear * pnear;
+
+ for(n=1; n<neighbours; n++) {
+ q = ptn[n].dist/radius;
+
+ D = dtime * dtime * (pressure*(1-q) + pressure_near*(1-q)*(1-q))* 0.5f;
+ madd_v3_v3fl(end, ptn[n].co, -D * massfactor);
+ }
+
+ /* Artificial buoyancy force in negative gravity direction */
+ if (fluid->buoyancy >= 0.f && psys_uses_gravity(sim)) {
+ float B = -dtime * dtime * fluid->buoyancy * (p - fluid->rest_density) * 0.5f;
+ madd_v3_v3fl(end, sim->scene->physics_settings.gravity, -B * massfactor);
+ }
+
+ /* apply final result and recalculate velocity */
+ VECCOPY(pa->state.co, end);
+ sub_v3_v3v3(pa->state.vel, end, start);
+ mul_v3_fl(pa->state.vel, 1.f/dtime);
+
+ if(ptn){ MEM_freeN(ptn); ptn=NULL;}
+}
+
+static void apply_particle_fluidsim(ParticleSystem *psys, ParticleData *pa, ParticleSettings *part, ParticleSimulationData *sim, float dfra, float cfra){
+ ParticleTarget *pt;
+// float dtime = dfra*psys_get_timestep(sim);
+ float particle_mass = part->mass;
+
+ particle_fluidsim(psys, pa, part, sim, dfra, cfra, particle_mass);
+
+ /*----check other SPH systems (Multifluids) , each fluid has its own parameters---*/
+ for(pt=sim->psys->targets.first; pt; pt=pt->next) {
+ ParticleSystem *epsys = psys_get_target_system(sim->ob, pt);
+
+ if(epsys)
+ particle_fluidsim(epsys, pa, epsys->part, sim, dfra, cfra, particle_mass);
+ }
+ /*----------------------------------------------------------------*/
+}
+
/************************************************/
/* Newtonian physics */
/************************************************/
@@ -2720,6 +2857,12 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
VECCOPY(col.co1, pa->prev_state.co);
VECCOPY(col.co2, pa->state.co);
+
+ VECCOPY(col.ve1, pa->prev_state.vel);
+ VECCOPY(col.ve2, pa->state.vel);
+ mul_v3_fl(col.ve1, timestep * dfra);
+ mul_v3_fl(col.ve2, timestep * dfra);
+
col.t = 0.0f;
/* override for boids */
@@ -2765,12 +2908,20 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
int through = (BLI_frand() < pd->pdef_perm) ? 1 : 0;
float co[3]; /* point of collision */
float vec[3]; /* movement through collision */
- float t = hit.dist/col.ray_len; /* time of collision between this iteration */
- float dt = col.t + t * (1.0f - col.t); /* time of collision between frame change*/
-
- interp_v3_v3v3(co, col.co1, col.co2, t);
+ float acc[3]; /* acceleration */
+
+ float x = hit.dist/col.ray_len; /* location of collision between this iteration */
+ float le = len_v3(col.ve1)/col.ray_len;
+ float ac = len_v3(col.ve2)/col.ray_len - le; /* (taking acceleration into account) */
+ float t = (-le + sqrt(le*le + 2*ac*x))/ac; /* time of collision between this iteration */
+ float dt = col.t + x * (1.0f - col.t); /* time of collision between frame change*/
+ float it = 1.0 - t;
+
+ interp_v3_v3v3(co, col.co1, col.co2, x);
VECSUB(vec, col.co2, col.co1);
+ VECSUB(acc, col.ve2, col.ve1);
+
mul_v3_fl(col.vel, 1.0f-col.t);
/* particle dies in collision */
@@ -2790,7 +2941,7 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
deflections=max_deflections;
}
else {
- float nor_vec[3], tan_vec[3], tan_vel[3], vel[3];
+ float nor_vec[3], tan_vec[3], tan_vel[3];
float damp, frict;
float inp, inp_v;
@@ -2867,10 +3018,6 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
/* combine components together again */
VECADD(vec, nor_vec, tan_vec);
- /* calculate velocity from collision vector */
- VECCOPY(vel, vec);
- mul_v3_fl(vel, 1.0f/MAX2((timestep*dfra) * (1.0f - col.t), 0.00001));
-
/* make sure we don't hit the current face again */
VECADDFAC(co, co, col.nor, (through ? -0.0001f : 0.0001f));
@@ -2878,21 +3025,25 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
BoidParticle *bpa = pa->boid;
if(bpa->data.mode == eBoidMode_OnLand || co[2] <= boid_z) {
co[2] = boid_z;
- vel[2] = 0.0f;
+ vec[2] = 0.0f;
}
}
- /* store state for reactors */
- //VECCOPY(reaction_state.co, co);
- //interp_v3_v3v3(reaction_state.vel, pa->prev_state.vel, pa->state.vel, dt);
- //interp_qt_qtqt(reaction_state.rot, pa->prev_state.rot, pa->state.rot, dt);
-
/* set coordinates for next iteration */
+
+ /* apply acceleration to final position, but make sure particle stays above surface */
+ madd_v3_v3v3fl(acc, vec, acc, it);
+ ac = dot_v3v3(acc, col.nor);
+ if((!through && ac < 0.0f) || (through && ac > 0.0f))
+ madd_v3_v3fl(acc, col.nor, -ac);
+
VECCOPY(col.co1, co);
- VECADDFAC(col.co2, co, vec, 1.0f - t);
- col.t = dt;
+ VECADDFAC(col.co2, co, acc, it);
+
+ VECCOPY(col.ve1, vec);
+ VECCOPY(col.ve2, acc);
- if(len_v3(vec) < 0.001 && len_v3(pa->state.vel) < 0.001) {
+ if(len_v3(vec) < 0.001 && len_v3v3(pa->state.co, pa->prev_state.co) < 0.001) {
/* kill speed to stop slipping */
VECCOPY(pa->state.vel,zerovec);
VECCOPY(pa->state.co, co);
@@ -2902,10 +3053,14 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
}
else {
VECCOPY(pa->state.co, col.co2);
+ mul_v3_v3fl(pa->state.vel, acc, 1.0f/MAX2((timestep*dfra) * (1.0f - col.t), 0.00001));
+
/* Stickness to surface */
normalize_v3(nor_vec);
- VECADDFAC(pa->state.vel, vel, nor_vec, -pd->pdef_stickness);
+ madd_v3_v3fl(pa->state.vel, nor_vec, -pd->pdef_stickness);
}
+
+ col.t = dt;
}
deflections++;
@@ -2920,66 +3075,18 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
/* Hair */
/************************************************/
/* check if path cache or children need updating and do it if needed */
-static void psys_update_path_cache(ParticleSimulationData *sim, float cfra)
+void psys_update_path_cache(ParticleSimulationData *sim, float cfra)
{
ParticleSystem *psys = sim->psys;
ParticleSettings *part = psys->part;
- ParticleEditSettings *pset = &sim->scene->toolsettings->particle;
- int distr=0, alloc=0, skip=0;
-
- if((psys->part->childtype && psys->totchild != get_psys_tot_child(sim->scene, psys)) || psys->recalc&PSYS_RECALC_RESET)
- alloc=1;
-
- if(alloc || psys->recalc&PSYS_RECALC_CHILD || (psys->vgroup[PSYS_VG_DENSITY] && (sim->ob && sim->ob->mode & OB_MODE_WEIGHT_PAINT)))
- distr=1;
-
- if(distr){
- if(alloc)
- realloc_particles(sim, sim->psys->totpart);
-
- if(get_psys_tot_child(sim->scene, psys)) {
- /* don't generate children while computing the hair keys */
- if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) {
- distribute_particles(sim, PART_FROM_CHILD);
-
- if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES && part->parents!=0.0)
- psys_find_parents(sim);
- }
- }
- else
- psys_free_children(psys);
- }
-
- if((part->type==PART_HAIR || psys->flag&PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED)==0)
- skip = 1; /* only hair, keyed and baked stuff can have paths */
- else if(part->ren_as != PART_DRAW_PATH && !(part->type==PART_HAIR && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)))
- skip = 1; /* particle visualization must be set as path */
- else if(!psys->renderdata) {
- if(part->draw_as != PART_DRAW_REND)
- skip = 1; /* draw visualization */
- else if(psys->pointcache->flag & PTCACHE_BAKING)
- skip = 1; /* no need to cache paths while baking dynamics */
- else if(psys_in_edit_mode(sim->scene, psys)) {
- if((pset->flag & PE_DRAW_PART)==0)
- skip = 1;
- else if(part->childtype==0 && (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED)==0)
- skip = 1; /* in edit mode paths are needed for child particles and dynamic hair */
- }
- }
-
- if(!skip) {
+
+ /* only hair, keyed and baked stuff can have paths */
+ if(part->type==PART_HAIR || psys->flag&PSYS_KEYED || psys->pointcache->mem_cache.first) {
psys_cache_paths(sim, cfra);
/* for render, child particle paths are computed on the fly */
- if(part->childtype) {
- if(!psys->totchild)
- skip = 1;
- else if((psys->part->type == PART_HAIR && psys->flag & PSYS_HAIR_DONE)==0)
- skip = 1;
-
- if(!skip)
- psys_cache_child_paths(sim, cfra, 0);
- }
+ if(part->childtype && psys->totchild)
+ psys_cache_child_paths(sim, cfra, 0);
}
else if(psys->pathcache)
psys_free_path_cache(psys, NULL);
@@ -3094,6 +3201,8 @@ static void do_hair_dynamics(ParticleSimulationData *sim)
psys->hair_out_dm = clothModifier_do(psys->clmd, sim->scene, sim->ob, dm, 0, 0);
psys->clmd->sim_parms->effector_weights = NULL;
+
+ psys_free_path_cache(psys, NULL);
}
static void hair_step(ParticleSimulationData *sim, float cfra)
{
@@ -3123,8 +3232,8 @@ static void hair_step(ParticleSimulationData *sim, float cfra)
if(psys->part->type==PART_HAIR && psys->flag & PSYS_HAIR_DYNAMICS)
do_hair_dynamics(sim);
+ /* following lines were removed r29079 but cause bug [#22811], see report for details */
psys_update_effectors(sim);
-
psys_update_path_cache(sim, cfra);
psys->flag |= PSYS_HAIR_UPDATED;
@@ -3184,15 +3293,11 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
{
ParticleSystem *psys = sim->psys;
ParticleSettings *part=psys->part;
- KDTree *tree=0;
- //IpoCurve *icu_esize=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
-/* Material *ma=give_current_material(sim->ob, part->omat); */
BoidBrainData bbd;
PARTICLE_P;
float timestep;
- int totpart;
/* current time */
- float ctime, ipotime; // XXX old animation system
+ float ctime;
/* frame & time changes */
float dfra, dtime, pa_dtime, pa_dfra=0.0;
float birthtime, dietime;
@@ -3200,200 +3305,186 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
/* where have we gone in time since last time */
dfra= cfra - psys->cfra;
- totpart=psys->totpart;
-
timestep = psys_get_timestep(sim);
dtime= dfra*timestep;
ctime= cfra*timestep;
- ipotime= cfra; // XXX old animation system
-
-#if 0 // XXX old animation system
- if(part->flag&PART_ABS_TIME && part->ipo){
- calc_ipo(part->ipo, cfra);
- execute_ipo((ID *)part, part->ipo);
- }
-#endif // XXX old animation system
if(dfra<0.0){
- float *vg_size=0;
- //if(part->type==PART_REACTOR)
- // vg_size=psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_SIZE);
-
LOOP_EXISTING_PARTICLES {
- /* set correct ipo timing */
-#if 0 // XXX old animation system
- if((part->flag&PART_ABS_TIME)==0 && part->ipo){
- ipotime=100.0f*(cfra-pa->time)/pa->lifetime;
- calc_ipo(part->ipo, ipotime);
- execute_ipo((ID *)part, part->ipo);
- }
-#endif // XXX old animation system
pa->size = part->size;
if(part->randsize > 0.0)
pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
reset_particle(sim, pa, dtime, cfra);
}
-
- if(vg_size)
- MEM_freeN(vg_size);
+ return;
}
- else{
- BLI_srandom(31415926 + (int)cfra + psys->seed);
- psys_update_effectors(sim);
+ BLI_srandom(31415926 + (int)cfra + psys->seed);
+
+ psys_update_effectors(sim);
- if(part->type != PART_HAIR)
- sim->colliders = get_collider_cache(sim->scene, NULL);
+ if(part->type != PART_HAIR)
+ sim->colliders = get_collider_cache(sim->scene, NULL, NULL);
- if(part->phystype==PART_PHYS_BOIDS){
- ParticleTarget *pt = psys->targets.first;
- bbd.sim = sim;
- bbd.part = part;
- bbd.cfra = cfra;
- bbd.dfra = dfra;
- bbd.timestep = timestep;
+ if(part->phystype==PART_PHYS_BOIDS){
+ ParticleTarget *pt = psys->targets.first;
+ bbd.sim = sim;
+ bbd.part = part;
+ bbd.cfra = cfra;
+ bbd.dfra = dfra;
+ bbd.timestep = timestep;
- psys_update_particle_tree(psys, cfra);
+ psys_update_particle_tree(psys, cfra);
- boids_precalc_rules(part, cfra);
+ boids_precalc_rules(part, cfra);
- for(; pt; pt=pt->next) {
- if(pt->ob)
- psys_update_particle_tree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), cfra);
- }
+ for(; pt; pt=pt->next) {
+ if(pt->ob)
+ psys_update_particle_tree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), cfra);
+ }
+ }
+ else if(part->phystype==PART_PHYS_FLUID){
+ ParticleTarget *pt = psys->targets.first;
+ psys_update_particle_tree(psys, cfra);
+
+ for(; pt; pt=pt->next) { /* Updating others systems particle tree for fluid-fluid interaction */
+ if(pt->ob) psys_update_particle_tree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), cfra);
}
+ }
- /* main loop: calculate physics for all particles */
- LOOP_SHOWN_PARTICLES {
- copy_particle_key(&pa->prev_state,&pa->state,1);
-
- /* set correct ipo timing */
-#if 0 // XXX old animation system
- if((part->flag&PART_ABS_TIME)==0 && part->ipo){
- ipotime=100.0f*(cfra-pa->time)/pa->lifetime;
- calc_ipo(part->ipo, ipotime);
- execute_ipo((ID *)part, part->ipo);
- }
-#endif // XXX old animation system
- //update_particle_settings(psys, part, &tpart, pa);
+ /* main loop: calculate physics for all particles */
+ LOOP_SHOWN_PARTICLES {
+ copy_particle_key(&pa->prev_state,&pa->state,1);
- pa->size = part->size;
- if(part->randsize > 0.0)
- pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
+ pa->size = part->size;
+ if(part->randsize > 0.0)
+ pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
- ///* reactions can change birth time so they need to be checked first */
- //if(psys->reactevents.first && ELEM(pa->alive,PARS_DEAD,PARS_KILLED)==0)
- // react_to_events(psys,p);
+ ///* reactions can change birth time so they need to be checked first */
+ //if(psys->reactevents.first && ELEM(pa->alive,PARS_DEAD,PARS_KILLED)==0)
+ // react_to_events(psys,p);
- birthtime = pa->time;
- dietime = birthtime + pa->lifetime;
+ birthtime = pa->time;
+ dietime = birthtime + pa->lifetime;
- pa_dfra = dfra;
- pa_dtime = dtime;
+ pa_dfra = dfra;
+ pa_dtime = dtime;
- if(dietime <= cfra && psys->cfra < dietime){
- /* particle dies some time between this and last step */
- pa_dfra = dietime - ((birthtime > psys->cfra) ? birthtime : psys->cfra);
- pa_dtime = pa_dfra * timestep;
- pa->alive = PARS_DYING;
- }
- else if(birthtime <= cfra && birthtime >= psys->cfra){
- /* particle is born some time between this and last step*/
- reset_particle(sim, pa, dtime, cfra);
- pa->alive = PARS_ALIVE;
- pa_dfra = cfra - birthtime;
- pa_dtime = pa_dfra*timestep;
- }
- else if(dietime < cfra){
- /* nothing to be done when particle is dead */
- }
+ if(dietime <= cfra && psys->cfra < dietime){
+ /* particle dies some time between this and last step */
+ pa_dfra = dietime - ((birthtime > psys->cfra) ? birthtime : psys->cfra);
+ pa_dtime = pa_dfra * timestep;
+ pa->alive = PARS_DYING;
+ }
+ else if(birthtime <= cfra && birthtime >= psys->cfra){
+ /* particle is born some time between this and last step*/
+ reset_particle(sim, pa, dtime, cfra);
+ pa->alive = PARS_ALIVE;
+ pa_dfra = cfra - birthtime;
+ pa_dtime = pa_dfra*timestep;
+ }
+ else if(dietime < cfra){
+ /* nothing to be done when particle is dead */
+ }
+
+ /* only reset unborn particles if they're shown or if the particle is born soon*/
+ if(pa->alive==PARS_UNBORN
+ && (part->flag & PART_UNBORN || cfra + psys->pointcache->step > pa->time))
+ reset_particle(sim, pa, dtime, cfra);
+ else if(part->phystype == PART_PHYS_NO)
+ reset_particle(sim, pa, dtime, cfra);
+
+ if(dfra>0.0 && ELEM(pa->alive,PARS_ALIVE,PARS_DYING)){
+ switch(part->phystype){
+ case PART_PHYS_NEWTON:
+ /* do global forces & effectors */
+ apply_particle_forces(sim, p, pa_dfra, cfra);
+
+ /* deflection */
+ if(sim->colliders)
+ deflect_particle(sim, p, pa_dfra, cfra);
+
+ /* rotations */
+ rotate_particle(part, pa, pa_dfra, timestep);
+ break;
+ case PART_PHYS_BOIDS:
+ {
+ bbd.goal_ob = NULL;
+ boid_brain(&bbd, p, pa);
+ if(pa->alive != PARS_DYING) {
+ boid_body(&bbd, pa);
- /* only reset unborn particles if they're shown or if the particle is born soon*/
- if(pa->alive==PARS_UNBORN
- && (part->flag & PART_UNBORN || cfra + psys->pointcache->step > pa->time))
- reset_particle(sim, pa, dtime, cfra);
- else if(part->phystype == PART_PHYS_NO)
- reset_particle(sim, pa, dtime, cfra);
-
- if(dfra>0.0 && ELEM(pa->alive,PARS_ALIVE,PARS_DYING)){
- switch(part->phystype){
- case PART_PHYS_NEWTON:
- /* do global forces & effectors */
- apply_particle_forces(sim, p, pa_dfra, cfra);
-
/* deflection */
if(sim->colliders)
deflect_particle(sim, p, pa_dfra, cfra);
-
- /* rotations */
- rotate_particle(part, pa, pa_dfra, timestep);
- break;
- case PART_PHYS_BOIDS:
- {
- bbd.goal_ob = NULL;
- boid_brain(&bbd, p, pa);
- if(pa->alive != PARS_DYING) {
- boid_body(&bbd, pa);
-
- /* deflection */
- if(sim->colliders)
- deflect_particle(sim, p, pa_dfra, cfra);
- }
- break;
}
+ break;
}
+ case PART_PHYS_FLUID:
+ {
+ /* do global forces & effectors */
+ apply_particle_forces(sim, p, pa_dfra, cfra);
+
+ /* do fluid sim */
+ apply_particle_fluidsim(psys, pa, part, sim, pa_dfra, cfra);
+
+ /* deflection */
+ if(sim->colliders)
+ deflect_particle(sim, p, pa_dfra, cfra);
+
+ /* rotations, SPH particles are not physical particles, just interpolation particles, thus rotation has not a direct sense for them */
+ rotate_particle(part, pa, pa_dfra, timestep);
+ break;
+ }
+ }
- if(pa->alive == PARS_DYING){
- //push_reaction(ob,psys,p,PART_EVENT_DEATH,&pa->state);
-
- pa->alive=PARS_DEAD;
- pa->state.time=pa->dietime;
- }
- else
- pa->state.time=cfra;
+ if(pa->alive == PARS_DYING){
+ //push_reaction(ob,psys,p,PART_EVENT_DEATH,&pa->state);
- //push_reaction(ob,psys,p,PART_EVENT_NEAR,&pa->state);
+ pa->alive=PARS_DEAD;
+ pa->state.time=pa->dietime;
}
- }
+ else
+ pa->state.time=cfra;
- free_collider_cache(&sim->colliders);
+ //push_reaction(ob,psys,p,PART_EVENT_NEAR,&pa->state);
+ }
}
- if(tree)
- BLI_kdtree_free(tree);
-}
+ free_collider_cache(&sim->colliders);
+ if(psys->pathcache)
+ psys_free_path_cache(psys, NULL);
+}
+void psys_update_children(ParticleSimulationData *sim)
+{
+ if((sim->psys->part->type == PART_HAIR) && (sim->psys->flag & PSYS_HAIR_DONE)==0)
+ /* don't generate children while growing hair - waste of time */
+ psys_free_children(sim->psys);
+ else if(sim->psys->part->childtype) {
+ if(sim->psys->totchild != get_psys_tot_child(sim->scene, sim->psys))
+ distribute_particles(sim, PART_FROM_CHILD);
+ }
+ else
+ psys_free_children(sim->psys);
+}
/* updates cached particles' alive & other flags etc..*/
static void cached_step(ParticleSimulationData *sim, float cfra)
{
ParticleSystem *psys = sim->psys;
ParticleSettings *part = psys->part;
- //IpoCurve *icu_esize = NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
-/* Material *ma = give_current_material(sim->ob,part->omat); */
PARTICLE_P;
- float disp, birthtime, dietime, *vg_size= NULL; // XXX ipotime=cfra
+ float disp, birthtime, dietime;
BLI_srandom(psys->seed);
- if(part->from!=PART_FROM_PARTICLE)
- vg_size= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_SIZE);
-
psys_update_effectors(sim);
disp= (float)get_current_display_percentage(psys)/100.0f;
LOOP_PARTICLES {
-#if 0 // XXX old animation system
- if((part->flag&PART_ABS_TIME)==0 && part->ipo){
- ipotime=100.0f*(cfra-pa->time)/pa->lifetime;
- calc_ipo(part->ipo, ipotime);
- execute_ipo((ID *)part, part->ipo);
- }
-#endif // XXX old animation system
- //update_settings_with_particle(psys, part, pa);
-
pa->size = part->size;
if(part->randsize > 0.0)
pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
@@ -3409,12 +3500,10 @@ static void cached_step(ParticleSimulationData *sim, float cfra)
if(part->flag & PART_UNBORN && (psys->pointcache->flag & PTCACHE_EXTERNAL) == 0)
reset_particle(sim, pa, 0.0f, cfra);
}
- else if(dietime <= cfra){
+ else if(dietime <= cfra)
pa->alive = PARS_DEAD;
- }
- else{
+ else
pa->alive = PARS_ALIVE;
- }
if(psys->lattice){
end_latt_deform(psys->lattice);
@@ -3426,114 +3515,8 @@ static void cached_step(ParticleSimulationData *sim, float cfra)
else
pa->flag &= ~PARS_NO_DISP;
}
-
- /* make sure that children are up to date */
- if(psys->part->childtype && psys->totchild != get_psys_tot_child(sim->scene, psys)) {
- realloc_particles(sim, psys->totpart);
- distribute_particles(sim, PART_FROM_CHILD);
- }
-
- psys_update_path_cache(sim, cfra);
-
- if(vg_size)
- MEM_freeN(vg_size);
-}
-
-static void psys_changed_type(ParticleSimulationData *sim)
-{
- ParticleSettings *part = sim->psys->part;
- PTCacheID pid;
-
- BKE_ptcache_id_from_particles(&pid, sim->ob, sim->psys);
-
- /* system type has changed so set sensible defaults and clear non applicable flags */
- if(part->from == PART_FROM_PARTICLE) {
- //if(part->type != PART_REACTOR)
- part->from = PART_FROM_FACE;
- if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT)
- part->distr = PART_DISTR_JIT;
- }
-
- if(part->phystype != PART_PHYS_KEYED)
- sim->psys->flag &= ~PSYS_KEYED;
-
- if(part->type == PART_HAIR) {
- if(ELEM4(part->ren_as, PART_DRAW_NOT, PART_DRAW_PATH, PART_DRAW_OB, PART_DRAW_GR)==0)
- part->ren_as = PART_DRAW_PATH;
-
- if(ELEM3(part->draw_as, PART_DRAW_NOT, PART_DRAW_REND, PART_DRAW_PATH)==0)
- part->draw_as = PART_DRAW_REND;
-
- CLAMP(part->path_start, 0.0f, 100.0f);
- CLAMP(part->path_end, 0.0f, 100.0f);
-
- BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
- }
- else {
- free_hair(sim->ob, sim->psys, 1);
-
- CLAMP(part->path_start, 0.0f, MAX2(100.0f, part->end + part->lifetime));
- CLAMP(part->path_end, 0.0f, MAX2(100.0f, part->end + part->lifetime));
- }
-
- psys_reset(sim->psys, PSYS_RESET_ALL);
-}
-void psys_check_boid_data(ParticleSystem *psys)
-{
- BoidParticle *bpa;
- PARTICLE_P;
-
- pa = psys->particles;
-
- if(!pa)
- return;
-
- if(psys->part && psys->part->phystype==PART_PHYS_BOIDS) {
- if(!pa->boid) {
- bpa = MEM_callocN(psys->totpart * sizeof(BoidParticle), "Boid Data");
-
- LOOP_PARTICLES
- pa->boid = bpa++;
- }
- }
- else if(pa->boid){
- MEM_freeN(pa->boid);
- LOOP_PARTICLES
- pa->boid = NULL;
- }
}
-static void psys_changed_physics(ParticleSimulationData *sim)
-{
- ParticleSettings *part = sim->psys->part;
-
- if(ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED)) {
- PTCacheID pid;
- BKE_ptcache_id_from_particles(&pid, sim->ob, sim->psys);
- BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
- }
- else {
- free_keyed_keys(sim->psys);
- sim->psys->flag &= ~PSYS_KEYED;
- }
-
- if(part->phystype == PART_PHYS_BOIDS && part->boids == NULL) {
- BoidState *state;
-
- part->boids = MEM_callocN(sizeof(BoidSettings), "Boid Settings");
- boid_default_settings(part->boids);
-
- state = boid_new_state(part->boids);
- BLI_addtail(&state->rules, boid_new_rule(eBoidRuleType_Separate));
- BLI_addtail(&state->rules, boid_new_rule(eBoidRuleType_Flock));
-
- ((BoidRule*)state->rules.first)->flag |= BOIDRULE_CURRENT;
-
- state->flag |= BOIDSTATE_CURRENT;
- BLI_addtail(&part->boids->states, state);
- }
- psys_check_boid_data(sim->psys);
-}
static void particles_fluid_step(ParticleSimulationData *sim, int cfra)
{
ParticleSystem *psys = sim->psys;
@@ -3567,8 +3550,8 @@ static void particles_fluid_step(ParticleSimulationData *sim, int cfra)
// ok, start loading
strcpy(filename, fss->surfdataPath);
strcat(filename, suffix);
- BLI_convertstringcode(filename, G.sce);
- BLI_convertstringframe(filename, curFrame, 0); // fixed #frame-no
+ BLI_path_abs(filename, G.sce);
+ BLI_path_frame(filename, curFrame, 0); // fixed #frame-no
strcat(filename, suffix2);
gzf = gzopen(filename, "rb");
@@ -3642,200 +3625,127 @@ static void particles_fluid_step(ParticleSimulationData *sim, int cfra)
#endif // DISABLE_ELBEEM
}
-/* Calculates the next state for all particles of the system */
-/* In particles code most fra-ending are frames, time-ending are fra*timestep (seconds)*/
+static int emit_particles(ParticleSimulationData *sim, PTCacheID *pid, float cfra)
+{
+ ParticleSystem *psys = sim->psys;
+ ParticleSettings *part = psys->part;
+ int oldtotpart = psys->totpart;
+ int totpart = oldtotpart;
+
+ if(pid && psys->pointcache->flag & PTCACHE_EXTERNAL)
+ totpart = pid->cache->totpoint;
+ else if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT)
+ totpart = part->grid_res*part->grid_res*part->grid_res;
+ else
+ totpart = psys->part->totpart;
+
+ if(totpart != oldtotpart)
+ realloc_particles(sim, totpart);
+
+ return totpart - oldtotpart;
+}
+/* Calculates the next state for all particles of the system
+ * In particles code most fra-ending are frames, time-ending are fra*timestep (seconds)
+ * 1. Emit particles
+ * 2. Check cache (if used) and return if frame is cached
+ * 3. Do dynamics
+ * 4. Save to cache */
static void system_step(ParticleSimulationData *sim, float cfra)
{
ParticleSystem *psys = sim->psys;
ParticleSettings *part = psys->part;
PointCache *cache = psys->pointcache;
- PTCacheID pid;
+ PTCacheID pid, *use_cache = NULL;
PARTICLE_P;
- int totpart, oldtotpart, totchild, oldtotchild;
- float disp, *vg_vel= 0, *vg_tan= 0, *vg_rot= 0, *vg_size= 0;
- int init= 0, distr= 0, alloc= 0, usecache= 0, only_children_changed= 0;
- int framenr, framedelta, startframe, endframe;
+ int oldtotpart;
+ float disp; /*, *vg_vel= 0, *vg_tan= 0, *vg_rot= 0, *vg_size= 0; */
+ int init= 0, emit= 0; //, only_children_changed= 0;
+ int framenr, framedelta, startframe = 0, endframe = 100;
framenr= (int)sim->scene->r.cfra;
framedelta= framenr - cache->simframe;
- /* set suitable cache range automatically */
- if((cache->flag & (PTCACHE_BAKING|PTCACHE_BAKED))==0 && !(psys->flag & PSYS_HAIR_DYNAMICS))
- psys_get_pointcache_start_end(sim->scene, sim->psys, &cache->startframe, &cache->endframe);
-
- BKE_ptcache_id_from_particles(&pid, sim->ob, psys);
- BKE_ptcache_id_time(&pid, sim->scene, 0.0f, &startframe, &endframe, NULL);
-
- psys_clear_temp_pointcache(sim->psys);
-
- /* update ipo's */
-#if 0 // XXX old animation system
- if((part->flag & PART_ABS_TIME) && part->ipo) {
- calc_ipo(part->ipo, cfra);
- execute_ipo((ID *)part, part->ipo);
+ /* cache shouldn't be used for hair or "continue physics" */
+ if(part->type != PART_HAIR && BKE_ptcache_get_continue_physics() == 0) {
+ BKE_ptcache_id_from_particles(&pid, sim->ob, psys);
+ use_cache = &pid;
}
-#endif // XXX old animation system
- /* hair if it's already done is handled separate */
- if(part->type == PART_HAIR && (psys->flag & PSYS_HAIR_DONE)) {
- hair_step(sim, cfra);
- psys->cfra = cfra;
- psys->recalc = 0;
- return;
- }
- /* fluid is also handled separate */
- else if(part->type == PART_FLUID) {
- particles_fluid_step(sim, framenr);
- psys->cfra = cfra;
- psys->recalc = 0;
- return;
- }
+ if(use_cache) {
+ psys_clear_temp_pointcache(sim->psys);
- /* cache shouldn't be used for hair or "none" or "keyed" physics */
- if(part->type == PART_HAIR || ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED))
- usecache= 0;
- else if(BKE_ptcache_get_continue_physics())
- usecache= 0;
- else
- usecache= 1;
+ /* set suitable cache range automatically */
+ if((cache->flag & (PTCACHE_BAKING|PTCACHE_BAKED))==0)
+ psys_get_pointcache_start_end(sim->scene, sim->psys, &cache->startframe, &cache->endframe);
+
+ BKE_ptcache_id_time(&pid, sim->scene, 0.0f, &startframe, &endframe, NULL);
- if(usecache) {
- /* frame clamping */
+ /* simulation is only active during a specific period */
if(framenr < startframe) {
psys_reset(psys, PSYS_RESET_CACHE_MISS);
- psys->cfra = cfra;
- psys->recalc = 0;
return;
}
else if(framenr > endframe) {
framenr= endframe;
}
-
+
if(framenr == startframe) {
- BKE_ptcache_id_reset(sim->scene, &pid, PTCACHE_RESET_OUTDATED);
- cache->simframe= framenr;
- cache->flag |= PTCACHE_SIMULATION_VALID;
+ BKE_ptcache_id_reset(sim->scene, use_cache, PTCACHE_RESET_OUTDATED);
+ BKE_ptcache_validate(cache, framenr);
cache->flag &= ~PTCACHE_REDO_NEEDED;
}
}
+/* 1. emit particles */
+
/* verify if we need to reallocate */
oldtotpart = psys->totpart;
- oldtotchild = psys->totchild;
-
- if(psys->pointcache->flag & PTCACHE_EXTERNAL)
- totpart = pid.cache->totpoint;
- else if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT)
- totpart = part->grid_res*part->grid_res*part->grid_res;
- else
- totpart = psys->part->totpart;
- totchild = get_psys_tot_child(sim->scene, psys);
- if(oldtotpart != totpart || oldtotchild != totchild) {
- only_children_changed = (oldtotpart == totpart);
- alloc = 1;
- distr= 1;
- init= 1;
- }
-
- if(psys->recalc & PSYS_RECALC_RESET) {
- distr= 1;
- init= 1;
- }
+ emit = emit_particles(sim, use_cache, cfra);
+ if(use_cache && emit > 0)
+ BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, cfra);
+ init = emit*emit + (psys->recalc & PSYS_RECALC_RESET);
if(init) {
- if(distr) {
- if(alloc) {
- realloc_particles(sim, totpart);
-
- if(oldtotpart && usecache && !only_children_changed) {
- BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
- BKE_ptcache_id_from_particles(&pid, sim->ob, psys);
- }
- }
-
- if(!only_children_changed)
- distribute_particles(sim, part->from);
-
- if((psys->part->type == PART_HAIR) && !(psys->flag & PSYS_HAIR_DONE))
- /* don't generate children while growing hair - waste of time */
- psys_free_children(psys);
- else if(get_psys_tot_child(sim->scene, psys))
- distribute_particles(sim, PART_FROM_CHILD);
- }
-
- if(!only_children_changed) {
- free_keyed_keys(psys);
-
- initialize_all_particles(sim);
-
-
- if(alloc) {
- reset_all_particles(sim, 0.0, cfra, oldtotpart);
- }
- }
+ distribute_particles(sim, part->from);
+ initialize_all_particles(sim);
+ reset_all_particles(sim, 0.0, cfra, oldtotpart);
/* flag for possible explode modifiers after this system */
sim->psmd->flag |= eParticleSystemFlag_Pars;
}
- /* try to read from the cache */
- if(usecache) {
- int result = BKE_ptcache_read_cache(&pid, cfra, sim->scene->r.frs_sec);
+/* 2. try to read from the cache */
+ if(use_cache) {
+ int cache_result = BKE_ptcache_read_cache(use_cache, cfra, sim->scene->r.frs_sec);
- if(result == PTCACHE_READ_EXACT || result == PTCACHE_READ_INTERPOLATED) {
+ if(ELEM(cache_result, PTCACHE_READ_EXACT, PTCACHE_READ_INTERPOLATED)) {
cached_step(sim, cfra);
- psys->cfra=cfra;
- psys->recalc = 0;
- cache->simframe= framenr;
- cache->flag |= PTCACHE_SIMULATION_VALID;
+ BKE_ptcache_validate(cache, framenr);
- if(result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED)
- BKE_ptcache_write_cache(&pid, (int)cfra);
+ if(cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED)
+ BKE_ptcache_write_cache(use_cache, framenr);
return;
}
- else if(result==PTCACHE_READ_OLD) {
+ else if(cache_result == PTCACHE_READ_OLD) {
psys->cfra = (float)cache->simframe;
- LOOP_PARTICLES {
- /* update alive status */
- if(pa->time > psys->cfra)
- pa->alive = PARS_UNBORN;
- else if(pa->dietime <= psys->cfra)
- pa->alive = PARS_DEAD;
- else
- pa->alive = PARS_ALIVE;
- }
+ cached_step(sim, psys->cfra);
}
else if(cfra != startframe && ( /*sim->ob->id.lib ||*/ (cache->flag & PTCACHE_BAKED))) { /* 2.4x disabled lib, but this can be used in some cases, testing further - campbell */
psys_reset(psys, PSYS_RESET_CACHE_MISS);
- psys->cfra=cfra;
- psys->recalc = 0;
return;
}
- }
- else {
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
- cache->last_exact= 0;
- }
-
- /* if on second frame, write cache for first frame */
- if(usecache && psys->cfra == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
- BKE_ptcache_write_cache(&pid, startframe);
- if(part->phystype==PART_PHYS_KEYED)
- psys_count_keyed_targets(sim);
-
- /* initialize vertex groups */
- if(part->from!=PART_FROM_PARTICLE) {
- vg_vel= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_VEL);
- vg_tan= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_TAN);
- vg_rot= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_ROT);
- vg_size= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_SIZE);
+ /* if on second frame, write cache for first frame */
+ if(psys->cfra == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
+ BKE_ptcache_write_cache(use_cache, startframe);
}
+ else
+ BKE_ptcache_invalidate(cache);
+/* 3. do dynamics */
/* set particles to be not calculated TODO: can't work with pointcache */
disp= (float)get_current_display_percentage(psys)/100.0f;
@@ -3848,50 +3758,153 @@ static void system_step(ParticleSimulationData *sim, float cfra)
}
if(psys->totpart) {
- int dframe, totframesback = 0;
-
+ int dframe, subframe = 0, totframesback = 0, totsubframe = part->subframes+1;
+ float fraction;
+
/* handle negative frame start at the first frame by doing
* all the steps before the first frame */
if(framenr == startframe && part->sta < startframe)
totframesback = (startframe - (int)part->sta);
-
+
for(dframe=-totframesback; dframe<=0; dframe++) {
/* ok now we're all set so let's go */
- dynamics_step(sim, cfra+dframe);
- psys->cfra = cfra+dframe;
+ for (subframe = 1; subframe <= totsubframe; subframe++) {
+ fraction = (float)subframe/(float)totsubframe;
+ dynamics_step(sim, cfra+dframe+fraction - 1.f);
+ psys->cfra = cfra+dframe+fraction - 1.f;
+ }
}
+
}
- cache->simframe= framenr;
- cache->flag |= PTCACHE_SIMULATION_VALID;
+/* 4. only write cache starting from second frame */
+ if(use_cache) {
+ BKE_ptcache_validate(cache, framenr);
+ if(framenr != startframe)
+ BKE_ptcache_write_cache(use_cache, framenr);
+ }
- psys->recalc = 0;
- psys->cfra = cfra;
+/* cleanup */
+ if(psys->lattice){
+ end_latt_deform(psys->lattice);
+ psys->lattice= NULL;
+ }
+}
- /* only write cache starting from second frame */
- if(usecache && framenr != startframe)
- BKE_ptcache_write_cache(&pid, (int)cfra);
+/* system type has changed so set sensible defaults and clear non applicable flags */
+static void psys_changed_type(ParticleSimulationData *sim)
+{
+ ParticleSettings *part = sim->psys->part;
+ PTCacheID pid;
- /* for keyed particles the path is allways known so it can be drawn */
- if(part->phystype==PART_PHYS_KEYED) {
- set_keyed_keys(sim);
- psys_update_path_cache(sim,(int)cfra);
+ BKE_ptcache_id_from_particles(&pid, sim->ob, sim->psys);
+
+ if(part->from == PART_FROM_PARTICLE) {
+ //if(part->type != PART_REACTOR)
+ part->from = PART_FROM_FACE;
+ if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT)
+ part->distr = PART_DISTR_JIT;
}
- else if(psys->pathcache)
- psys_free_path_cache(psys, NULL);
- /* cleanup */
- if(vg_vel) MEM_freeN(vg_vel);
- if(vg_tan) MEM_freeN(vg_tan);
- if(vg_rot) MEM_freeN(vg_rot);
- if(vg_size) MEM_freeN(vg_size);
+ if(part->phystype != PART_PHYS_KEYED)
+ sim->psys->flag &= ~PSYS_KEYED;
- if(psys->lattice){
- end_latt_deform(psys->lattice);
- psys->lattice= NULL;
+ if(part->type == PART_HAIR) {
+ if(ELEM4(part->ren_as, PART_DRAW_NOT, PART_DRAW_PATH, PART_DRAW_OB, PART_DRAW_GR)==0)
+ part->ren_as = PART_DRAW_PATH;
+
+ if(ELEM3(part->draw_as, PART_DRAW_NOT, PART_DRAW_REND, PART_DRAW_PATH)==0)
+ part->draw_as = PART_DRAW_REND;
+
+ CLAMP(part->path_start, 0.0f, 100.0f);
+ CLAMP(part->path_end, 0.0f, 100.0f);
+
+ BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
+ }
+ else {
+ free_hair(sim->ob, sim->psys, 1);
+
+ CLAMP(part->path_start, 0.0f, MAX2(100.0f, part->end + part->lifetime));
+ CLAMP(part->path_end, 0.0f, MAX2(100.0f, part->end + part->lifetime));
}
+
+ psys_reset(sim->psys, PSYS_RESET_ALL);
+}
+void psys_check_boid_data(ParticleSystem *psys)
+{
+ BoidParticle *bpa;
+ PARTICLE_P;
+
+ pa = psys->particles;
+
+ if(!pa)
+ return;
+
+ if(psys->part && psys->part->phystype==PART_PHYS_BOIDS) {
+ if(!pa->boid) {
+ bpa = MEM_callocN(psys->totpart * sizeof(BoidParticle), "Boid Data");
+
+ LOOP_PARTICLES
+ pa->boid = bpa++;
+ }
+ }
+ else if(pa->boid){
+ MEM_freeN(pa->boid);
+ LOOP_PARTICLES
+ pa->boid = NULL;
+ }
+}
+
+static void fluid_default_settings(ParticleSettings *part){
+ SPHFluidSettings *fluid = part->fluid;
+
+ fluid->radius = 0.5f;
+ fluid->spring_k = 0.f;
+ fluid->rest_length = 0.5f;
+ fluid->viscosity_omega = 2.f;
+ fluid->viscosity_beta = 0.f;
+ fluid->stiffness_k = 0.1f;
+ fluid->stiffness_knear = 0.05f;
+ fluid->rest_density = 10.f;
+ fluid->buoyancy = 0.f;
}
+static void psys_changed_physics(ParticleSimulationData *sim)
+{
+ ParticleSettings *part = sim->psys->part;
+
+ if(ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED)) {
+ PTCacheID pid;
+ BKE_ptcache_id_from_particles(&pid, sim->ob, sim->psys);
+ BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
+ }
+ else {
+ free_keyed_keys(sim->psys);
+ sim->psys->flag &= ~PSYS_KEYED;
+ }
+
+ if(part->phystype == PART_PHYS_BOIDS && part->boids == NULL) {
+ BoidState *state;
+
+ part->boids = MEM_callocN(sizeof(BoidSettings), "Boid Settings");
+ boid_default_settings(part->boids);
+
+ state = boid_new_state(part->boids);
+ BLI_addtail(&state->rules, boid_new_rule(eBoidRuleType_Separate));
+ BLI_addtail(&state->rules, boid_new_rule(eBoidRuleType_Flock));
+
+ ((BoidRule*)state->rules.first)->flag |= BOIDRULE_CURRENT;
+
+ state->flag |= BOIDSTATE_CURRENT;
+ BLI_addtail(&part->boids->states, state);
+ }
+ else if(part->phystype == PART_PHYS_FLUID && part->fluid == NULL) {
+ part->fluid = MEM_callocN(sizeof(SPHFluidSettings), "SPH Fluid Settings");
+ fluid_default_settings(part);
+ }
+
+ psys_check_boid_data(sim->psys);
+}
static int hair_needs_recalc(ParticleSystem *psys)
{
if(!(psys->flag & PSYS_EDITED) && (!psys->edit || !psys->edit->edited) &&
@@ -3902,10 +3915,12 @@ static int hair_needs_recalc(ParticleSystem *psys)
return 0;
}
-/* main particle update call, checks that things are ok on the large scale before actual particle calculations */
+/* main particle update call, checks that things are ok on the large scale and
+ * then advances in to actual particle calculations depending on particle type */
void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
{
ParticleSimulationData sim = {scene, ob, psys, NULL, NULL};
+ ParticleSettings *part = psys->part;
float cfra;
/* drawdata is outdated after ANY change */
@@ -3914,7 +3929,7 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
if(!psys_check_enabled(ob, psys))
return;
- cfra= bsystem_time(scene, ob, (float)scene->r.cfra, 0.0f);
+ cfra= BKE_curframe(scene);
sim.psmd= psys_get_modifier(ob, psys);
/* system was already updated from modifier stack */
@@ -3929,35 +3944,87 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
return;
/* execute drivers only, as animation has already been done */
- BKE_animsys_evaluate_animdata(&psys->part->id, psys->part->adt, cfra, ADT_RECALC_DRIVERS);
+ BKE_animsys_evaluate_animdata(&part->id, part->adt, cfra, ADT_RECALC_DRIVERS);
+
+ /* TODO: only free child paths in case of PSYS_RECALC_CHILD */
+ if(psys->recalc & PSYS_RECALC || ob->recalc & OB_RECALC_ALL)
+ psys_free_path_cache(psys, NULL);
+
+ if(psys->recalc & PSYS_RECALC_CHILD)
+ psys_free_children(psys);
if(psys->recalc & PSYS_RECALC_TYPE)
psys_changed_type(&sim);
else if(psys->recalc & PSYS_RECALC_PHYS)
psys_changed_physics(&sim);
- /* (re-)create hair */
- if(psys->part->type==PART_HAIR && hair_needs_recalc(psys)) {
- float hcfra=0.0f;
- int i;
-
- free_hair(ob, psys, 0);
+ switch(part->type) {
+ case PART_HAIR:
+ {
+ /* (re-)create hair */
+ if(hair_needs_recalc(psys)) {
+ float hcfra=0.0f;
+ int i, recalc = psys->recalc;
+
+ free_hair(ob, psys, 0);
+
+ /* first step is negative so particles get killed and reset */
+ psys->cfra= 1.0f;
+
+ for(i=0; i<=part->hair_step; i++){
+ hcfra=100.0f*(float)i/(float)psys->part->hair_step;
+ BKE_animsys_evaluate_animdata(&part->id, part->adt, hcfra, ADT_RECALC_ANIM);
+ system_step(&sim, hcfra);
+ psys->cfra = hcfra;
+ psys->recalc = 0;
+ save_hair(&sim, hcfra);
+ }
- /* first step is negative so particles get killed and reset */
- psys->cfra= 1.0f;
+ psys->flag |= PSYS_HAIR_DONE;
+ psys->recalc = recalc;
+ }
- for(i=0; i<=psys->part->hair_step; i++){
- hcfra=100.0f*(float)i/(float)psys->part->hair_step;
- BKE_animsys_evaluate_animdata(&psys->part->id, psys->part->adt, hcfra, ADT_RECALC_ANIM);
- system_step(&sim, hcfra);
- save_hair(&sim, hcfra);
+ if(psys->flag & PSYS_HAIR_DONE)
+ hair_step(&sim, cfra);
+ break;
}
+ case PART_FLUID:
+ {
+ particles_fluid_step(&sim, (int)cfra);
+ break;
+ }
+ default:
+ {
+ switch(part->phystype) {
+ case PART_PHYS_NO:
+ case PART_PHYS_KEYED:
+ {
+ if(emit_particles(&sim, NULL, cfra)) {
+ free_keyed_keys(psys);
+ distribute_particles(&sim, part->from);
+ initialize_all_particles(&sim);
+ }
+ reset_all_particles(&sim, 0.0, cfra, 0);
- psys->flag |= PSYS_HAIR_DONE;
+ if(part->phystype == PART_PHYS_KEYED) {
+ psys_count_keyed_targets(&sim);
+ set_keyed_keys(&sim);
+ }
+ break;
+ }
+ default:
+ {
+ /* the main dynamic particle system step */
+ system_step(&sim, cfra);
+ break;
+ }
+ }
+ break;
+ }
}
- /* the main particle system step */
- system_step(&sim, cfra);
+ psys->cfra = cfra;
+ psys->recalc = 0;
/* save matrix for duplicators */
invert_m4_m4(psys->imat, ob->obmat);
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index b1319a81f5d..5295a496d2b 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -48,13 +48,13 @@
#include "WM_api.h"
+#include "BKE_anim.h"
#include "BKE_blender.h"
#include "BKE_cloth.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
-#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
@@ -88,16 +88,12 @@
#include "BLI_winstuff.h"
#endif
-#if defined(__APPLE__) && (PARALLEL == 1) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
-/* ************** libgomp (Apple gcc 4.2.1) TLS bug workaround *************** */
-#include <pthread.h>
-extern pthread_key_t gomp_tls_key;
-static void *thread_tls_data;
-#endif
-
#define PTCACHE_DATA_FROM(data, type, from) if(data[type]) { memcpy(data[type], from, ptcache_data_size[type]); }
#define PTCACHE_DATA_TO(data, type, index, to) if(data[type]) { memcpy(to, (char*)data[type] + (index ? index * ptcache_data_size[type] : 0), ptcache_data_size[type]); }
+/* could be made into a pointcache option */
+#define DURIAN_POINTCACHE_LIB_OK 1
+
int ptcache_data_size[] = {
sizeof(int), // BPHYS_DATA_INDEX
3 * sizeof(float), // BPHYS_DATA_LOCATION:
@@ -135,7 +131,7 @@ static int ptcache_write_basic_header(PTCacheFile *pf)
return 1;
}
/* Softbody functions */
-static int ptcache_write_softbody(int index, void *soft_v, void **data)
+static int ptcache_write_softbody(int index, void *soft_v, void **data, int cfra)
{
SoftBody *soft= soft_v;
BodyPoint *bp = soft->bpoint + index;
@@ -191,13 +187,13 @@ static void ptcache_interpolate_softbody(int index, void *soft_v, void **data, f
VECCOPY(bp->pos, keys->co);
VECCOPY(bp->vec, keys->vel);
}
-static int ptcache_totpoint_softbody(void *soft_v)
+static int ptcache_totpoint_softbody(void *soft_v, int cfra)
{
SoftBody *soft= soft_v;
return soft->totpoint;
}
/* Particle functions */
-static int ptcache_write_particle(int index, void *psys_v, void **data)
+static int ptcache_write_particle(int index, void *psys_v, void **data, int cfra)
{
ParticleSystem *psys= psys_v;
ParticleData *pa = psys->particles + index;
@@ -205,11 +201,9 @@ static int ptcache_write_particle(int index, void *psys_v, void **data)
float times[3] = {pa->time, pa->dietime, pa->lifetime};
int step = psys->pointcache->step;
- if(data[BPHYS_DATA_INDEX]) {
- /* No need to store unborn or died particles */
- if(pa->time - step > pa->state.time || pa->dietime + step < pa->state.time)
- return 0;
- }
+ /* No need to store unborn or died particles outside cache step bounds */
+ if(data[BPHYS_DATA_INDEX] && (cfra < pa->time - step || cfra > pa->dietime + step))
+ return 0;
PTCACHE_DATA_FROM(data, BPHYS_DATA_INDEX, &index);
PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, pa->state.co);
@@ -236,8 +230,14 @@ void BKE_ptcache_make_particle_key(ParticleKey *key, int index, void **data, flo
static void ptcache_read_particle(int index, void *psys_v, void **data, float frs_sec, float cfra, float *old_data)
{
ParticleSystem *psys= psys_v;
- ParticleData *pa = psys->particles + index;
- BoidParticle *boid = (psys->part->phystype == PART_PHYS_BOIDS) ? pa->boid : NULL;
+ ParticleData *pa;
+ BoidParticle *boid;
+
+ if(index >= psys->totpart)
+ return;
+
+ pa = psys->particles + index;
+ boid = (psys->part->phystype == PART_PHYS_BOIDS) ? pa->boid : NULL;
if(cfra > pa->state.time)
memcpy(&pa->prev_state, &pa->state, sizeof(ParticleKey));
@@ -288,10 +288,19 @@ static void ptcache_read_particle(int index, void *psys_v, void **data, float fr
static void ptcache_interpolate_particle(int index, void *psys_v, void **data, float frs_sec, float cfra, float cfra1, float cfra2, float *old_data)
{
ParticleSystem *psys= psys_v;
- ParticleData *pa = psys->particles + index;
+ ParticleData *pa;
ParticleKey keys[4];
float dfra;
+ if(index >= psys->totpart)
+ return;
+
+ pa = psys->particles + index;
+
+ /* particle wasn't read from first cache so can't interpolate */
+ if((int)cfra1 < pa->time - psys->pointcache->step || (int)cfra1 > pa->dietime + psys->pointcache->step)
+ return;
+
cfra = MIN2(cfra, pa->dietime);
cfra1 = MIN2(cfra1, pa->dietime);
cfra2 = MIN2(cfra2, pa->dietime);
@@ -338,26 +347,20 @@ static void ptcache_interpolate_particle(int index, void *psys_v, void **data, f
pa->state.time = cfra;
}
-static int ptcache_totpoint_particle(void *psys_v)
+static int ptcache_totpoint_particle(void *psys_v, int cfra)
{
ParticleSystem *psys = psys_v;
return psys->totpart;
}
-static int ptcache_totwrite_particle(void *psys_v)
+static int ptcache_totwrite_particle(void *psys_v, int cfra)
{
ParticleSystem *psys = psys_v;
+ ParticleData *pa= psys->particles;
+ int p, step = psys->pointcache->step;
int totwrite = 0;
- /* TODO for later */
- //if((psys->part->flag & (PART_UNBORN|PART_DIED))==0) {
- // ParticleData *pa= psys->particles;
- // int p, step = psys->pointcache->step;
-
- // for(p=0; p<psys->totpart; p++,pa++)
- // totwrite += (pa->time - step > pa->state.time || pa->dietime + step > pa->state.time);
- //}
- //else
- totwrite= psys->totpart;
+ for(p=0; p<psys->totpart; p++,pa++)
+ totwrite += (cfra >= pa->time - step && cfra <= pa->dietime + step);
return totwrite;
}
@@ -489,7 +492,7 @@ static int ptcache_totwrite_particle(void *psys_v)
//}
//
/* Cloth functions */
-static int ptcache_write_cloth(int index, void *cloth_v, void **data)
+static int ptcache_write_cloth(int index, void *cloth_v, void **data, int cfra)
{
ClothModifierData *clmd= cloth_v;
Cloth *cloth= clmd->clothObject;
@@ -554,10 +557,10 @@ static void ptcache_interpolate_cloth(int index, void *cloth_v, void **data, flo
/* should vert->xconst be interpolated somehow too? - jahka */
}
-static int ptcache_totpoint_cloth(void *cloth_v)
+static int ptcache_totpoint_cloth(void *cloth_v, int cfra)
{
ClothModifierData *clmd= cloth_v;
- return clmd->clothObject->numverts;
+ return clmd->clothObject ? clmd->clothObject->numverts : 0;
}
/* Creating ID's */
@@ -615,11 +618,7 @@ void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *p
pid->write_header= ptcache_write_basic_header;
pid->read_header= ptcache_read_basic_header;
- pid->data_types= (1<<BPHYS_DATA_LOCATION) | (1<<BPHYS_DATA_VELOCITY);
-
- /* TODO for later */
- //if((psys->part->flag & (PART_UNBORN|PART_DIED))==0)
- // pid->data_types|= (1<<BPHYS_DATA_INDEX);
+ pid->data_types= (1<<BPHYS_DATA_LOCATION) | (1<<BPHYS_DATA_VELOCITY) | (1<<BPHYS_DATA_INDEX);
if(psys->part->phystype == PART_PHYS_BOIDS)
pid->data_types|= (1<<BPHYS_DATA_AVELOCITY) | (1<<BPHYS_DATA_ROTATION) | (1<<BPHYS_DATA_BOIDS);
@@ -635,7 +634,7 @@ void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *p
}
/* Smoke functions */
-static int ptcache_totpoint_smoke(void *smoke_v)
+static int ptcache_totpoint_smoke(void *smoke_v, int cfra)
{
SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
SmokeDomainSettings *sds = smd->domain;
@@ -648,7 +647,7 @@ static int ptcache_totpoint_smoke(void *smoke_v)
}
/* Smoke functions */
-static int ptcache_totpoint_smoke_turbulence(void *smoke_v)
+static int ptcache_totpoint_smoke_turbulence(void *smoke_v, int cfra)
{
SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
SmokeDomainSettings *sds = smd->domain;
@@ -803,31 +802,37 @@ static int ptcache_compress_read(PTCacheFile *pf, unsigned char *result, unsigne
int r = 0;
unsigned char compressed = 0;
unsigned int in_len;
+#ifdef WITH_LZO
unsigned int out_len = len;
+ size_t sizeOfIt = 5;
+#endif
unsigned char *in;
unsigned char *props = MEM_callocN(16*sizeof(char), "tmp");
- size_t sizeOfIt = 5;
ptcache_file_read(pf, &compressed, 1, sizeof(unsigned char));
if(compressed) {
ptcache_file_read(pf, &in_len, 1, sizeof(unsigned int));
- in = (unsigned char *)MEM_callocN(sizeof(unsigned char)*in_len, "pointcache_compressed_buffer");
- ptcache_file_read(pf, in, in_len, sizeof(unsigned char));
-
+ if(in_len==0) {
+ /* do nothing */
+ }
+ else {
+ in = (unsigned char *)MEM_callocN(sizeof(unsigned char)*in_len, "pointcache_compressed_buffer");
+ ptcache_file_read(pf, in, in_len, sizeof(unsigned char));
#ifdef WITH_LZO
- if(compressed == 1)
- r = lzo1x_decompress(in, (lzo_uint)in_len, result, (lzo_uint *)&out_len, NULL);
+ if(compressed == 1)
+ r = lzo1x_decompress_safe(in, (lzo_uint)in_len, result, (lzo_uint *)&out_len, NULL);
#endif
#ifdef WITH_LZMA
- if(compressed == 2)
- {
- size_t leni = in_len, leno = out_len;
- ptcache_file_read(pf, &sizeOfIt, 1, sizeof(unsigned int));
- ptcache_file_read(pf, props, sizeOfIt, sizeof(unsigned char));
- r = LzmaUncompress(result, &leno, in, &leni, props, sizeOfIt);
- }
+ if(compressed == 2)
+ {
+ size_t leni = in_len, leno = out_len;
+ ptcache_file_read(pf, &sizeOfIt, 1, sizeof(unsigned int));
+ ptcache_file_read(pf, props, sizeOfIt, sizeof(unsigned char));
+ r = LzmaUncompress(result, &leno, in, &leni, props, sizeOfIt);
+ }
#endif
- MEM_freeN(in);
+ MEM_freeN(in);
+ }
}
else {
ptcache_file_read(pf, result, len, sizeof(unsigned char));
@@ -987,7 +992,7 @@ void BKE_ptcache_id_from_cloth(PTCacheID *pid, Object *ob, ClothModifierData *cl
pid->info_types= 0;
}
-void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob)
+void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int duplis)
{
PTCacheID *pid;
ParticleSystem *psys;
@@ -1029,6 +1034,23 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob)
}
}
}
+
+ if(scene && (duplis-- > 0) && (ob->transflag & OB_DUPLI)) {
+ ListBase *lb_dupli_ob;
+
+ if((lb_dupli_ob=object_duplilist(scene, ob))) {
+ DupliObject *dob;
+ for(dob= lb_dupli_ob->first; dob; dob= dob->next) {
+ ListBase lb_dupli_pid;
+ BKE_ptcache_ids_from_object(&lb_dupli_pid, dob->ob, scene, duplis);
+ addlisttolist(lb, &lb_dupli_pid);
+ if(lb_dupli_pid.first)
+ printf("Adding Dupli\n");
+ }
+
+ free_object_duplilist(lb_dupli_ob); /* does restore */
+ }
+ }
}
@@ -1045,22 +1067,22 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob)
static int ptcache_path(PTCacheID *pid, char *filename)
{
- Library *lib;
+ Library *lib= (pid)? pid->ob->id.lib: NULL;
+ const char *blendfilename= (lib && (pid->cache->flag & PTCACHE_IGNORE_LIBPATH)==0) ? lib->filepath: G.sce;
size_t i;
- lib= (pid)? pid->ob->id.lib: NULL;
-
if(pid->cache->flag & PTCACHE_EXTERNAL) {
strcpy(filename, pid->cache->path);
+
+ if(strncmp(filename, "//", 2)==0)
+ BLI_path_abs(filename, blendfilename);
+
return BLI_add_slash(filename); /* new strlen() */
}
else if (G.relbase_valid || lib) {
char file[MAX_PTCACHE_PATH]; /* we dont want the dir, only the file */
- char *blendfilename;
-
- blendfilename= (lib)? lib->filename: G.sce;
- BLI_split_dirfile_basic(blendfilename, NULL, file);
+ BLI_split_dirfile(blendfilename, NULL, file);
i = strlen(file);
/* remove .blend */
@@ -1068,7 +1090,7 @@ static int ptcache_path(PTCacheID *pid, char *filename)
file[i-6] = '\0';
snprintf(filename, MAX_PTCACHE_PATH, "//"PTCACHE_PATH"%s", file); /* add blend file name to pointcache dir */
- BLI_convertstringcode(filename, blendfilename);
+ BLI_path_abs(filename, blendfilename);
return BLI_add_slash(filename); /* new strlen() */
}
@@ -1137,10 +1159,11 @@ static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra)
FILE *fp = NULL;
char filename[(FILE_MAXDIR+FILE_MAXFILE)*2];
+#ifndef DURIAN_POINTCACHE_LIB_OK
/* don't allow writing for linked objects */
if(pid->ob->id.lib && mode == PTCACHE_FILE_WRITE)
return NULL;
-
+#endif
if (!G.relbase_valid && (pid->cache->flag & PTCACHE_EXTERNAL)==0) return NULL; /* save blend file before using disk pointcache */
BKE_ptcache_id_filename(pid, filename, cfra, 1, 1);
@@ -1149,7 +1172,7 @@ static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra)
if (!BLI_exists(filename)) {
return NULL;
}
- fp = fopen(filename, "rb");
+ fp = fopen(filename, "rb");
} else if (mode==PTCACHE_FILE_WRITE) {
BLI_make_existing_file(filename); /* will create the dir if needs be, same as //textures is created */
fp = fopen(filename, "wb");
@@ -1158,13 +1181,13 @@ static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra)
fp = fopen(filename, "rb+");
}
- if (!fp)
- return NULL;
+ if (!fp)
+ return NULL;
pf= MEM_mallocN(sizeof(PTCacheFile), "PTCacheFile");
pf->fp= fp;
- return pf;
+ return pf;
}
static void ptcache_file_close(PTCacheFile *pf)
@@ -1266,12 +1289,32 @@ static void ptcache_file_seek_pointers(int index, PTCacheFile *pf)
int i, size=0;
int data_types = pf->data_types;
- for(i=0; i<BPHYS_TOT_DATA; i++)
- size += pf->data_types & (1<<i) ? ptcache_data_size[i] : 0;
+ if(data_types & (1<<BPHYS_DATA_INDEX)) {
+ int totpoint;
+ /* The simplest solution is to just write to the very end. This may cause
+ * some data duplication, but since it's on disk it's not so bad. The correct
+ * thing would be to search through the file for the correct index and only
+ * write to the end if it's not found, but this could be quite slow.
+ */
+ fseek(pf->fp, 8 + sizeof(int), SEEK_SET);
+ fread(&totpoint, sizeof(int), 1, pf->fp);
+
+ totpoint++;
+
+ fseek(pf->fp, 8 + sizeof(int), SEEK_SET);
+ fwrite(&totpoint, sizeof(int), 1, pf->fp);
+
+ fseek(pf->fp, 0, SEEK_END);
+ }
+ else {
+ for(i=0; i<BPHYS_TOT_DATA; i++)
+ size += pf->data_types & (1<<i) ? ptcache_data_size[i] : 0;
+
+ /* size of default header + data up to index */
+ fseek(pf->fp, 8 + 3*sizeof(int) + index * size, SEEK_SET);
+ }
ptcache_file_init_pointers(pf);
- /* size of default header + data up to index */
- fseek(pf->fp, 8 + 3*sizeof(int) + index * size, SEEK_SET);
}
void BKE_ptcache_mem_init_pointers(PTCacheMem *pm)
{
@@ -1291,13 +1334,24 @@ void BKE_ptcache_mem_incr_pointers(PTCacheMem *pm)
pm->cur[i] = (char*)pm->cur[i] + ptcache_data_size[i];
}
}
-void BKE_ptcache_mem_seek_pointers(int index, PTCacheMem *pm)
+int BKE_ptcache_mem_seek_pointers(int point_index, PTCacheMem *pm)
{
int data_types = pm->data_types;
- int i;
+ int i, index = pm->index_array ? pm->index_array[point_index] - 1 : point_index;
+
+ if(index < 0) {
+ /* Can't give proper location without reallocation, so don't give any location.
+ * Some points will be cached improperly, but this only happens with simulation
+ * steps bigger than cache->step, so the cache has to be recalculated anyways
+ * at some point.
+ */
+ return 0;
+ }
for(i=0; i<BPHYS_TOT_DATA; i++)
pm->cur[i] = data_types & (1<<i) ? (char*)pm->data[i] + index * ptcache_data_size[i] : NULL;
+
+ return 1;
}
static void ptcache_alloc_data(PTCacheMem *pm)
{
@@ -1310,20 +1364,28 @@ static void ptcache_alloc_data(PTCacheMem *pm)
pm->data[i] = MEM_callocN(totpoint * ptcache_data_size[i], "PTCache Data");
}
}
-static void ptcache_free_data(void *data[])
+static void ptcache_free_data(PTCacheMem *pm)
{
+ void **data = pm->data;
int i;
for(i=0; i<BPHYS_TOT_DATA; i++) {
if(data[i])
MEM_freeN(data[i]);
}
+
+ if(pm->index_array) {
+ MEM_freeN(pm->index_array);
+ pm->index_array = NULL;
+ }
}
static void ptcache_copy_data(void *from[], void *to[])
{
int i;
for(i=0; i<BPHYS_TOT_DATA; i++) {
- if(from[i])
+ /* note, durian file 03.4b_comp crashes if to[i] is not tested
+ * its NULL, not sure if this should be fixed elsewhere but for now its needed */
+ if(from[i] && to[i])
memcpy(to[i], from[i], ptcache_data_size[i]);
}
}
@@ -1361,7 +1423,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
int ret = 0, error = 0;
/* nothing to read to */
- if(pid->totpoint(pid->calldata) == 0)
+ if(pid->totpoint(pid->calldata, (int)cfra) == 0)
return 0;
if(pid->cache->flag & PTCACHE_READ_INFO) {
@@ -1462,13 +1524,13 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
else if(pid->read_header(pf)) {
ptcache_file_init_pointers(pf);
totpoint = pf->totpoint;
- index = pf->data_types & BPHYS_DATA_INDEX ? &pf->data.index : &i;
+ index = pf->data_types & (1<<BPHYS_DATA_INDEX) ? &pf->data.index : &i;
}
}
else {
/* fall back to old cache file format */
use_old = 1;
- totpoint = pid->totpoint(pid->calldata);
+ totpoint = pid->totpoint(pid->calldata, (int) cfra);
}
}
if(pf2) {
@@ -1481,13 +1543,13 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
else if(pid->read_header(pf2)) {
ptcache_file_init_pointers(pf2);
totpoint2 = pf2->totpoint;
- index2 = pf2->data_types & BPHYS_DATA_INDEX ? &pf2->data.index : &i;
+ index2 = pf2->data_types & (1<<BPHYS_DATA_INDEX) ? &pf2->data.index : &i;
}
}
else {
/* fall back to old cache file format */
use_old = 1;
- totpoint2 = pid->totpoint(pid->calldata);
+ totpoint2 = pid->totpoint(pid->calldata, (int) cfra);
}
}
@@ -1500,7 +1562,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
if(!error)
{
if(pf && pid->read_stream) {
- if(totpoint != pid->totpoint(pid->calldata))
+ if(totpoint != pid->totpoint(pid->calldata, (int) cfra))
error = 1;
else
{
@@ -1510,7 +1572,8 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
}
}
- totpoint = MIN2(totpoint, pid->totpoint(pid->calldata));
+ if((pid->data_types & (1<<BPHYS_DATA_INDEX)) == 0)
+ totpoint = MIN2(totpoint, pid->totpoint(pid->calldata, (int) cfra));
if(!error)
{
@@ -1539,7 +1602,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
if(!error)
{
if(pf2 && pid->read_stream) {
- if(totpoint2 != pid->totpoint(pid->calldata))
+ if(totpoint2 != pid->totpoint(pid->calldata, (int) cfra))
error = 1;
else
{
@@ -1549,7 +1612,8 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
}
}
- totpoint2 = MIN2(totpoint2, pid->totpoint(pid->calldata));
+ if((pid->data_types & (1<<BPHYS_DATA_INDEX)) == 0)
+ totpoint2 = MIN2(totpoint2, pid->totpoint(pid->calldata, (int) cfra));
if(!error)
{
@@ -1621,41 +1685,40 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
return (error ? 0 : ret);
}
/* TODO for later */
-//static void ptcache_make_index_array(PTCacheMem *pm, int totpoint)
-//{
-// int i, *index;
-//
-// if(pm->index_array) {
-// MEM_freeN(pm->index_array);
-// pm->index_array = NULL;
-// }
-//
-// if(!pm->data[BPHYS_DATA_INDEX])
-// return;
-//
-// pm->index_array = MEM_callocN(totpoint * sizeof(int), "PTCacheMem index_array");
-// index = pm->data[BPHYS_DATA_INDEX];
-//
-// for(i=0; i<pm->totpoint; i++, index++)
-// pm->index_array[*index] = i;
-//}
+static void ptcache_make_index_array(PTCacheMem *pm, int totpoint)
+{
+ int i, *index;
+
+ if(pm->index_array) {
+ MEM_freeN(pm->index_array);
+ pm->index_array = NULL;
+ }
+
+ if(!pm->data[BPHYS_DATA_INDEX])
+ return;
+
+ pm->index_array = MEM_callocN(totpoint * sizeof(int), "PTCacheMem index_array");
+ index = pm->data[BPHYS_DATA_INDEX];
+
+ for(i=0; i<pm->totpoint; i++, index++)
+ pm->index_array[*index] = i + 1;
+}
/* writes cache to disk or memory */
int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
{
PointCache *cache = pid->cache;
PTCacheFile *pf= NULL, *pf2= NULL;
int i;
- int totpoint = pid->totpoint(pid->calldata);
+ int totpoint = pid->totpoint(pid->calldata, cfra);
int add = 0, overwrite = 0;
- if(totpoint == 0 || cfra < 0
- || (cfra ? pid->data_types == 0 : pid->info_types == 0))
+ if(totpoint == 0 || (cfra ? pid->data_types == 0 : pid->info_types == 0))
return 0;
if(cache->flag & PTCACHE_DISK_CACHE) {
- int ofra, efra = cache->endframe;
+ int ofra=0, efra = cache->endframe;
- if(cfra==0)
+ if(cfra==0 && cache->startframe > 0)
add = 1;
/* allways start from scratch on the first frame */
else if(cfra == cache->startframe) {
@@ -1690,7 +1753,7 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
return 0;
pf->type = pid->type;
- pf->totpoint = cfra ? totpoint : pid->totwrite(pid->calldata);
+ pf->totpoint = cfra ? pid->totwrite(pid->calldata, cfra) : totpoint;
pf->data_types = cfra ? pid->data_types : pid->info_types;
if(!ptcache_file_write_header_begin(pf) || !pid->write_header(pf)) {
@@ -1707,7 +1770,7 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
else
for(i=0; i<totpoint; i++) {
if(pid->write_elem) {
- int write = pid->write_elem(i, pid->calldata, pf->cur);
+ int write = pid->write_elem(i, pid->calldata, pf->cur, cfra);
if(write) {
if(!ptcache_file_write_data(pf)) {
ptcache_file_close(pf);
@@ -1727,7 +1790,7 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
pf2->data_types = pid->data_types;
}
ptcache_file_seek_pointers(i, pf2);
- pid->write_elem(i, pid->calldata, pf2->cur);
+ pid->write_elem(i, pid->calldata, pf2->cur, cfra);
if(!ptcache_file_write_data(pf2)) {
ptcache_file_close(pf);
ptcache_file_close(pf2);
@@ -1773,7 +1836,7 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
pm = MEM_callocN(sizeof(PTCacheMem), "Pointcache mem");
- pm->totpoint = pid->totwrite(pid->calldata);
+ pm->totpoint = pid->totwrite(pid->calldata, cfra);
pm->data_types = cfra ? pid->data_types : pid->info_types;
ptcache_alloc_data(pm);
@@ -1781,20 +1844,20 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
for(i=0; i<totpoint; i++) {
if(pid->write_elem) {
- int write = pid->write_elem(i, pid->calldata, pm->cur);
+ int write = pid->write_elem(i, pid->calldata, pm->cur, cfra);
if(write) {
BKE_ptcache_mem_incr_pointers(pm);
/* newly born particles have to be copied to previous cached frame */
if(overwrite && write == 2) {
pm2 = cache->mem_cache.last;
- BKE_ptcache_mem_seek_pointers(i, pm2);
- pid->write_elem(i, pid->calldata, pm2->cur);
+ if(BKE_ptcache_mem_seek_pointers(i, pm2))
+ pid->write_elem(i, pid->calldata, pm2->cur, cfra);
}
}
}
}
- //ptcache_make_index_array(pm, pid->totpoint(pid->calldata));
+ ptcache_make_index_array(pm, pid->totpoint(pid->calldata, cfra));
pm->frame = cfra;
BLI_addtail(&cache->mem_cache, pm);
@@ -1839,9 +1902,11 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
if(!pid->cache || pid->cache->flag & PTCACHE_BAKED)
return;
+#ifndef DURIAN_POINTCACHE_LIB_OK
/* don't allow clearing for linked objects */
if(pid->ob->id.lib)
return;
+#endif
/*if (!G.relbase_valid) return; *//* save blend file before using pointcache */
@@ -1865,7 +1930,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
if (strncmp(filename, de->d_name, len ) == 0) { /* do we have the right prefix */
if (mode == PTCACHE_CLEAR_ALL) {
- pid->cache->last_exact = 0;
+ pid->cache->last_exact = MIN2(pid->cache->startframe, 0);
BLI_join_dirfile(path_full, path, de->d_name);
BLI_delete(path_full, 0, 0);
} else {
@@ -1897,17 +1962,18 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
pm= pid->cache->mem_cache.first;
if(mode == PTCACHE_CLEAR_ALL) {
- pid->cache->last_exact = 0;
+ /*we want startframe if the cache starts before zero*/
+ pid->cache->last_exact = MIN2(pid->cache->startframe, 0);
for(; pm; pm=pm->next)
- ptcache_free_data(pm->data);
+ ptcache_free_data(pm);
BLI_freelistN(&pid->cache->mem_cache);
} else {
while(pm) {
if((mode==PTCACHE_CLEAR_BEFORE && pm->frame < cfra) ||
(mode==PTCACHE_CLEAR_AFTER && pm->frame > cfra) ) {
link = pm;
+ ptcache_free_data(pm);
pm = pm->next;
- ptcache_free_data(link->data);
BLI_freelinkN(&pid->cache->mem_cache, link);
}
else
@@ -1929,7 +1995,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
for(; pm; pm=pm->next) {
if(pm->frame == cfra) {
- ptcache_free_data(pm->data);
+ ptcache_free_data(pm);
BLI_freelinkN(&pid->cache->mem_cache, pm);
break;
}
@@ -2047,9 +2113,8 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
}
if(reset) {
- cache->flag &= ~(PTCACHE_REDO_NEEDED|PTCACHE_SIMULATION_VALID);
- cache->simframe= 0;
- cache->last_exact= 0;
+ BKE_ptcache_invalidate(cache);
+ cache->flag &= ~PTCACHE_REDO_NEEDED;
if(pid->type == PTCACHE_TYPE_CLOTH)
cloth_free_modifier(pid->ob, pid->calldata);
@@ -2214,11 +2279,8 @@ void BKE_ptcache_free_mem(ListBase *mem_cache)
PTCacheMem *pm = mem_cache->first;
if(pm) {
- for(; pm; pm=pm->next) {
- ptcache_free_data(pm->data);
- if(pm->index_array)
- MEM_freeN(pm->index_array);
- }
+ for(; pm; pm=pm->next)
+ ptcache_free_data(pm);
BLI_freelistN(mem_cache);
}
@@ -2271,38 +2333,6 @@ PointCache *BKE_ptcache_copy_list(ListBase *ptcaches_new, ListBase *ptcaches_old
/* Baking */
-static int count_quick_cache(Scene *scene, int *quick_step)
-{
- Base *base = scene->base.first;
- PTCacheID *pid;
- ListBase pidlist;
- int autocache_count= 0;
-
- for(base = scene->base.first; base; base = base->next) {
- if(base->object) {
- BKE_ptcache_ids_from_object(&pidlist, base->object);
-
- for(pid=pidlist.first; pid; pid=pid->next) {
- if((pid->cache->flag & PTCACHE_BAKED)
- || (pid->cache->flag & PTCACHE_QUICK_CACHE)==0)
- continue;
-
- if(pid->cache->flag & PTCACHE_OUTDATED || (pid->cache->flag & PTCACHE_SIMULATION_VALID)==0) {
- if(!autocache_count)
- *quick_step = pid->cache->step;
- else
- *quick_step = MIN2(*quick_step, pid->cache->step);
-
- autocache_count++;
- }
- }
-
- BLI_freelistN(&pidlist);
- }
- }
-
- return autocache_count;
-}
void BKE_ptcache_quick_cache_all(Scene *scene)
{
PTCacheBaker baker;
@@ -2317,9 +2347,9 @@ void BKE_ptcache_quick_cache_all(Scene *scene)
baker.render=0;
baker.anim_init = 0;
baker.scene=scene;
+ baker.quick_step=scene->physics_settings.quick_cache_step;
- if(count_quick_cache(scene, &baker.quick_step))
- BKE_ptcache_make_cache(&baker);
+ BKE_ptcache_make_cache(&baker);
}
/* Simulation thread, no need for interlocks as data written in both threads
@@ -2336,13 +2366,12 @@ typedef struct {
static void *ptcache_make_cache_thread(void *ptr) {
ptcache_make_cache_data *data = (ptcache_make_cache_data*)ptr;
-#if defined(__APPLE__) && (PARALLEL == 1) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
- // Workaround for Apple gcc 4.2.1 omp vs background thread bug
- pthread_setspecific (gomp_tls_key, thread_tls_data);
-#endif
-
- for(; (*data->cfra_ptr <= data->endframe) && !data->break_operation; *data->cfra_ptr+=data->step)
+ for(; (*data->cfra_ptr <= data->endframe) && !data->break_operation; *data->cfra_ptr+=data->step) {
scene_update_for_newframe(data->scene, data->scene->lay);
+ if(G.background) {
+ printf("bake: frame %d :: %d\n", (int)*data->cfra_ptr, data->endframe);
+ }
+ }
data->thread_ended = TRUE;
return NULL;
@@ -2352,6 +2381,7 @@ static void *ptcache_make_cache_thread(void *ptr) {
void BKE_ptcache_make_cache(PTCacheBaker* baker)
{
Scene *scene = baker->scene;
+ Scene *sce; /* SETLOOPER macro only */
Base *base;
ListBase pidlist;
PTCacheID *pid = baker->pid;
@@ -2377,13 +2407,18 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
/* cache/bake a single object */
cache = pid->cache;
if((cache->flag & PTCACHE_BAKED)==0) {
- if(pid->type==PTCACHE_TYPE_PARTICLES)
- psys_get_pointcache_start_end(scene, pid->calldata, &cache->startframe, &cache->endframe);
+ if(pid->type==PTCACHE_TYPE_PARTICLES) {
+ ParticleSystem *psys= pid->calldata;
+
+ /* a bit confusing, could make this work better in the UI */
+ if(psys->part->type == PART_EMITTER)
+ psys_get_pointcache_start_end(scene, pid->calldata, &cache->startframe, &cache->endframe);
+ }
else if(pid->type == PTCACHE_TYPE_SMOKE_HIGHRES) {
/* get all pids from the object and search for smoke low res */
ListBase pidlist2;
PTCacheID *pid2;
- BKE_ptcache_ids_from_object(&pidlist2, pid->ob);
+ BKE_ptcache_ids_from_object(&pidlist2, pid->ob, scene, MAX_DUPLI_RECUR);
for(pid2=pidlist2.first; pid2; pid2=pid2->next) {
if(pid2->type == PTCACHE_TYPE_SMOKE_DOMAIN)
{
@@ -2416,9 +2451,9 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
cache->flag &= ~PTCACHE_BAKED;
}
}
- else for(base=scene->base.first; base; base= base->next) {
+ else for(SETLOOPER(scene, base)) {
/* cache/bake everything in the scene */
- BKE_ptcache_ids_from_object(&pidlist, base->object);
+ BKE_ptcache_ids_from_object(&pidlist, base->object, scene, MAX_DUPLI_RECUR);
for(pid=pidlist.first; pid; pid=pid->next) {
cache = pid->cache;
@@ -2458,40 +2493,40 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
thread_data.thread_ended = FALSE;
old_progress = -1;
-#if defined(__APPLE__) && (PARALLEL == 1) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
- // Workaround for Apple gcc 4.2.1 omp vs background thread bug
- thread_tls_data = pthread_getspecific(gomp_tls_key);
-#endif
- BLI_init_threads(&threads, ptcache_make_cache_thread, 1);
- BLI_insert_thread(&threads, (void*)&thread_data);
-
- while (thread_data.thread_ended == FALSE) {
+ if(G.background) {
+ ptcache_make_cache_thread((void*)&thread_data);
+ }
+ else {
+ BLI_init_threads(&threads, ptcache_make_cache_thread, 1);
+ BLI_insert_thread(&threads, (void*)&thread_data);
- if(bake)
- progress = (int)(100.0f * (float)(CFRA - startframe)/(float)(thread_data.endframe-startframe));
- else
- progress = CFRA;
+ while (thread_data.thread_ended == FALSE) {
- /* NOTE: baking should not redraw whole ui as this slows things down */
- if ((baker->progressbar) && (progress != old_progress)) {
- baker->progressbar(baker->progresscontext, progress);
- old_progress = progress;
- }
-
- /* Delay to lessen CPU load from UI thread */
- PIL_sleep_ms(200);
+ if(bake)
+ progress = (int)(100.0f * (float)(CFRA - startframe)/(float)(thread_data.endframe-startframe));
+ else
+ progress = CFRA;
- /* NOTE: breaking baking should leave calculated frames in cache, not clear it */
- if(blender_test_break() && !thread_data.break_operation) {
- thread_data.break_operation = TRUE;
- if (baker->progressend)
- baker->progressend(baker->progresscontext);
- WM_cursor_wait(1);
+ /* NOTE: baking should not redraw whole ui as this slows things down */
+ if ((baker->progressbar) && (progress != old_progress)) {
+ baker->progressbar(baker->progresscontext, progress);
+ old_progress = progress;
+ }
+
+ /* Delay to lessen CPU load from UI thread */
+ PIL_sleep_ms(200);
+
+ /* NOTE: breaking baking should leave calculated frames in cache, not clear it */
+ if(blender_test_break() && !thread_data.break_operation) {
+ thread_data.break_operation = TRUE;
+ if (baker->progressend)
+ baker->progressend(baker->progresscontext);
+ WM_cursor_wait(1);
+ }
}
- }
BLI_end_threads(&threads);
-
+ }
/* clear baking flag */
if(pid) {
cache->flag &= ~(PTCACHE_BAKING|PTCACHE_REDO_NEEDED);
@@ -2503,8 +2538,8 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
BKE_ptcache_write_cache(pid, 0);
}
}
- else for(base=scene->base.first; base; base= base->next) {
- BKE_ptcache_ids_from_object(&pidlist, base->object);
+ else for(SETLOOPER(scene, base)) {
+ BKE_ptcache_ids_from_object(&pidlist, base->object, scene, MAX_DUPLI_RECUR);
for(pid=pidlist.first; pid; pid=pid->next) {
/* skip hair particles */
@@ -2587,7 +2622,7 @@ void BKE_ptcache_disk_to_mem(PTCacheID *pid)
cache->flag |= PTCACHE_DISK_CACHE;
- ptcache_free_data(pm->data);
+ ptcache_free_data(pm);
MEM_freeN(pm);
ptcache_file_close(pf);
@@ -2597,7 +2632,7 @@ void BKE_ptcache_disk_to_mem(PTCacheID *pid)
BKE_ptcache_mem_incr_pointers(pm);
}
- //ptcache_make_index_array(pm, pid->totpoint(pid->calldata));
+ ptcache_make_index_array(pm, pid->totpoint(pid->calldata, cfra));
BLI_addtail(&pid->cache->mem_cache, pm);
@@ -2629,7 +2664,8 @@ void BKE_ptcache_mem_to_disk(PTCacheID *pid)
ptcache_file_init_pointers(pf);
if(!ptcache_file_write_header_begin(pf) || !pid->write_header(pf)) {
- printf("Error writing to disk cache\n");
+ if (G.f & G_DEBUG)
+ printf("Error writing to disk cache\n");
cache->flag &= ~PTCACHE_DISK_CACHE;
ptcache_file_close(pf);
@@ -2639,7 +2675,8 @@ void BKE_ptcache_mem_to_disk(PTCacheID *pid)
for(i=0; i<pm->totpoint; i++) {
ptcache_copy_data(pm->cur, pf->cur);
if(!ptcache_file_write_data(pf)) {
- printf("Error writing to disk cache\n");
+ if (G.f & G_DEBUG)
+ printf("Error writing to disk cache\n");
cache->flag &= ~PTCACHE_DISK_CACHE;
ptcache_file_close(pf);
@@ -2655,7 +2692,8 @@ void BKE_ptcache_mem_to_disk(PTCacheID *pid)
BKE_ptcache_write_cache(pid, 0);
}
else
- printf("Error creating disk cache file\n");
+ if (G.f & G_DEBUG)
+ printf("Error creating disk cache file\n");
}
}
void BKE_ptcache_toggle_disk_cache(PTCacheID *pid)
@@ -2665,7 +2703,8 @@ void BKE_ptcache_toggle_disk_cache(PTCacheID *pid)
if (!G.relbase_valid){
cache->flag &= ~PTCACHE_DISK_CACHE;
- printf("File must be saved before using disk cache!\n");
+ if (G.f & G_DEBUG)
+ printf("File must be saved before using disk cache!\n");
return;
}
@@ -2813,16 +2852,14 @@ void BKE_ptcache_update_info(PTCacheID *pid)
}
else {
PTCacheMem *pm = cache->mem_cache.first;
- float framesize = 0.0f, bytes = 0.0f;
- int mb;
-
- if(pm)
- framesize = (float)ptcache_pid_old_elemsize(pid) * (float)pm->totpoint;
+ float bytes = 0.0f;
+ int i, mb;
- for(; pm; pm=pm->next)
+ for(; pm; pm=pm->next) {
+ for(i=0; i<BPHYS_TOT_DATA; i++)
+ bytes += pm->data[i] ? MEM_allocN_len(pm->data[i]) : 0.0f;
totframes++;
-
- bytes = totframes * framesize;
+ }
mb = (bytes > 1024.0f * 1024.0f);
@@ -2841,3 +2878,16 @@ void BKE_ptcache_update_info(PTCacheID *pid)
else
sprintf(cache->info, "%s.", mem_info);
}
+
+void BKE_ptcache_validate(PointCache *cache, int framenr)
+{
+ cache->flag |= PTCACHE_SIMULATION_VALID;
+ cache->simframe = framenr;
+}
+void BKE_ptcache_invalidate(PointCache *cache)
+{
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe = 0;
+ cache->last_exact = MIN2(cache->startframe, 0);
+}
+
diff --git a/source/blender/blenkernel/intern/property.c b/source/blender/blenkernel/intern/property.c
index d65e3391f04..a2ba7c69b93 100644
--- a/source/blender/blenkernel/intern/property.c
+++ b/source/blender/blenkernel/intern/property.c
@@ -35,18 +35,12 @@
#include <string.h>
#include <ctype.h>
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include "MEM_guardedalloc.h"
#include "DNA_property_types.h"
#include "DNA_object_types.h"
-#include "DNA_listBase.h"
#include "BLI_blenlib.h"
-#include "BKE_property.h"
void free_property(bProperty *prop)
{
diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c
index a2a44ca53a7..173c6c136f2 100644
--- a/source/blender/blenkernel/intern/report.c
+++ b/source/blender/blenkernel/intern/report.c
@@ -27,12 +27,12 @@
#include "MEM_guardedalloc.h"
-#include "DNA_listBase.h"
-
#include "BLI_blenlib.h"
#include "BLI_dynstr.h"
#include "BKE_report.h"
+#include "BKE_global.h" /* G.background only */
+#include "BKE_utildefines.h"
#include <stdarg.h>
#include <stdio.h>
@@ -67,7 +67,7 @@ void BKE_reports_init(ReportList *reports, int flag)
memset(reports, 0, sizeof(ReportList));
reports->storelevel= RPT_INFO;
- reports->printlevel= RPT_INFO;
+ reports->printlevel= RPT_ERROR;
reports->flag= flag;
}
@@ -95,6 +95,10 @@ void BKE_report(ReportList *reports, ReportType type, const char *message)
Report *report;
int len;
+ /* exception, print and return in background, no reason to store a list */
+ if(G.background)
+ reports= NULL;
+
if(!reports || ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))) {
printf("%s: %s\n", report_type_str(type), message);
fflush(stdout); /* this ensures the message is printed before a crash */
@@ -259,3 +263,14 @@ void BKE_reports_print(ReportList *reports, ReportType level)
MEM_freeN(cstring);
}
+Report *BKE_reports_last_displayable(ReportList *reports)
+{
+ Report *report=NULL;
+
+ for (report= (Report *)reports->list.last; report; report=report->prev) {
+ if (ELEM3(report->type, RPT_ERROR, RPT_WARNING, RPT_INFO))
+ return report;
+ }
+
+ return NULL;
+} \ No newline at end of file
diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index 1c727ee1596..61e98ce9d45 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -29,17 +29,12 @@
* all data is 'direct data', not Blender lib data.
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include <stdio.h>
#include <string.h>
#include <float.h>
#include "MEM_guardedalloc.h"
-#include "DNA_text_types.h"
#include "DNA_controller_types.h"
#include "DNA_sensor_types.h"
#include "DNA_actuator_types.h"
@@ -49,7 +44,7 @@
#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BKE_main.h"
-#include "BKE_blender.h"
+#include "BKE_library.h"
#include "BKE_sca.h"
/* ******************* SENSORS ************************ */
@@ -105,6 +100,8 @@ void init_sensor(bSensor *sens)
/* also use when sensor changes type */
bNearSensor *ns;
bMouseSensor *ms;
+ bJoystickSensor *js;
+ bRaySensor *rs;
if(sens->data) MEM_freeN(sens->data);
sens->data= NULL;
@@ -152,12 +149,18 @@ void init_sensor(bSensor *sens)
break;
case SENS_RAY:
sens->data= MEM_callocN(sizeof(bRaySensor), "raysens");
+ rs = sens->data;
+ rs->range = 0.01f;
break;
case SENS_MESSAGE:
sens->data= MEM_callocN(sizeof(bMessageSensor), "messagesens");
break;
case SENS_JOYSTICK:
sens->data= MEM_callocN(sizeof(bJoystickSensor), "joysticksens");
+ js= sens->data;
+ js->hatf = SENS_JOY_HAT_UP;
+ js->axis = 1;
+ js->hat = 1;
break;
default:
; /* this is very severe... I cannot make any memory for this */
@@ -187,26 +190,13 @@ void unlink_controller(bController *cont)
{
bSensor *sens;
Object *ob;
- int a, removed;
/* check for controller pointers in sensors */
ob= G.main->object.first;
while(ob) {
sens= ob->sensors.first;
while(sens) {
- removed= 0;
- for(a=0; a<sens->totlinks; a++) {
- if(removed) (sens->links)[a-1] = (sens->links)[a];
- else if((sens->links)[a] == cont) removed= 1;
- }
- if(removed) {
- sens->totlinks--;
-
- if(sens->totlinks==0) {
- MEM_freeN(sens->links);
- sens->links= NULL;
- }
- }
+ unlink_logicbricks((void **)&cont, (void ***)&(sens->links), &sens->totlinks);
sens= sens->next;
}
ob= ob->id.next;
@@ -311,26 +301,13 @@ void unlink_actuator(bActuator *act)
{
bController *cont;
Object *ob;
- int a, removed;
/* check for actuator pointers in controllers */
ob= G.main->object.first;
while(ob) {
cont= ob->controllers.first;
while(cont) {
- removed= 0;
- for(a=0; a<cont->totlinks; a++) {
- if(removed) (cont->links)[a-1] = (cont->links)[a];
- else if((cont->links)[a] == act) removed= 1;
- }
- if(removed) {
- cont->totlinks--;
-
- if(cont->totlinks==0) {
- MEM_freeN(cont->links);
- cont->links= NULL;
- }
- }
+ unlink_logicbricks((void **)&act, (void ***)&(cont->links), &cont->totlinks);
cont= cont->next;
}
ob= ob->id.next;
@@ -347,7 +324,19 @@ void unlink_actuators(ListBase *lb)
void free_actuator(bActuator *act)
{
- if(act->data) MEM_freeN(act->data);
+ bSoundActuator *sa;
+
+ if(act->data) {
+ switch (act->type) {
+ case ACT_SOUND:
+ sa = (bSoundActuator *) act->data;
+ if(sa->sound)
+ id_us_min((ID *) sa->sound);
+ break;
+ }
+
+ MEM_freeN(act->data);
+ }
MEM_freeN(act);
}
@@ -364,6 +353,7 @@ void free_actuators(ListBase *lb)
bActuator *copy_actuator(bActuator *act)
{
bActuator *actn;
+ bSoundActuator *sa;
act->mynew=actn= MEM_dupallocN(act);
actn->flag |= ACT_NEW;
@@ -371,6 +361,13 @@ bActuator *copy_actuator(bActuator *act)
actn->data= MEM_dupallocN(act->data);
}
+ switch (act->type) {
+ case ACT_SOUND:
+ sa= (bSoundActuator *)act->data;
+ if(sa->sound)
+ id_us_plus((ID *) sa->sound);
+ break;
+ }
return actn;
}
@@ -390,7 +387,9 @@ void copy_actuators(ListBase *lbn, ListBase *lbo)
void init_actuator(bActuator *act)
{
/* also use when actuator changes type */
+ bCameraActuator *ca;
bObjectActuator *oa;
+ bRandomActuator *ra;
bSoundActuator *sa;
if(act->data) MEM_freeN(act->data);
@@ -424,6 +423,8 @@ void init_actuator(bActuator *act)
break;
case ACT_CAMERA:
act->data= MEM_callocN(sizeof(bCameraActuator), "camact");
+ ca = act->data;
+ ca->axis = ACT_CAMERA_X;
break;
case ACT_EDIT_OBJECT:
act->data= MEM_callocN(sizeof(bEditObjectActuator), "editobact");
@@ -439,6 +440,8 @@ void init_actuator(bActuator *act)
break;
case ACT_RANDOM:
act->data= MEM_callocN(sizeof(bRandomActuator), "random act");
+ ra=act->data;
+ ra->float_arg_1 = 0.1f;
break;
case ACT_MESSAGE:
act->data= MEM_callocN(sizeof(bMessageActuator), "message act");
@@ -449,18 +452,18 @@ void init_actuator(bActuator *act)
case ACT_VISIBILITY:
act->data= MEM_callocN(sizeof(bVisibilityActuator), "visibility act");
break;
- case ACT_2DFILTER:
- act->data = MEM_callocN(sizeof( bTwoDFilterActuator ), "2d filter act");
- break;
- case ACT_PARENT:
- act->data = MEM_callocN(sizeof( bParentActuator ), "parent act");
- break;
+ case ACT_2DFILTER:
+ act->data = MEM_callocN(sizeof( bTwoDFilterActuator ), "2d filter act");
+ break;
+ case ACT_PARENT:
+ act->data = MEM_callocN(sizeof( bParentActuator ), "parent act");
+ break;
case ACT_STATE:
- act->data = MEM_callocN(sizeof( bStateActuator ), "state act");
- break;
+ act->data = MEM_callocN(sizeof( bStateActuator ), "state act");
+ break;
case ACT_ARMATURE:
- act->data = MEM_callocN(sizeof( bArmatureActuator ), "armature act");
- break;
+ act->data = MEM_callocN(sizeof( bArmatureActuator ), "armature act");
+ break;
default:
; /* this is very severe... I cannot make any memory for this */
/* logic brick... */
@@ -484,7 +487,6 @@ bActuator *new_actuator(int type)
}
/* ******************** GENERAL ******************* */
-
void clear_sca_new_poins_ob(Object *ob)
{
bSensor *sens;
@@ -655,3 +657,180 @@ void sca_remove_ob_poin(Object *obt, Object *ob)
act= act->next;
}
}
+
+/* ******************** INTERFACE ******************* */
+void sca_move_sensor(bSensor *sens_to_move, Object *ob, int move_up)
+{
+ bSensor *sens, *tmp;
+
+ int val;
+ val = move_up ? 1:2;
+
+ /* make sure this sensor belongs to this object */
+ sens= ob->sensors.first;
+ while(sens) {
+ if(sens == sens_to_move) break;
+ sens= sens->next;
+ }
+ if(!sens) return;
+
+ /* move up */
+ if( val==1 && sens->prev) {
+ for (tmp=sens->prev; tmp; tmp=tmp->prev) {
+ if (tmp->flag & SENS_VISIBLE)
+ break;
+ }
+ if (tmp) {
+ BLI_remlink(&ob->sensors, sens);
+ BLI_insertlinkbefore(&ob->sensors, tmp, sens);
+ }
+ }
+ /* move down */
+ else if( val==2 && sens->next) {
+ for (tmp=sens->next; tmp; tmp=tmp->next) {
+ if (tmp->flag & SENS_VISIBLE)
+ break;
+ }
+ if (tmp) {
+ BLI_remlink(&ob->sensors, sens);
+ BLI_insertlink(&ob->sensors, tmp, sens);
+ }
+ }
+}
+
+void sca_move_controller(bController *cont_to_move, Object *ob, int move_up)
+{
+ bController *cont, *tmp;
+
+ int val;
+ val = move_up ? 1:2;
+
+ /* make sure this controller belongs to this object */
+ cont= ob->controllers.first;
+ while(cont) {
+ if(cont == cont_to_move) break;
+ cont= cont->next;
+ }
+ if(!cont) return;
+
+ /* move up */
+ if( val==1 && cont->prev) {
+ /* locate the controller that has the same state mask but is earlier in the list */
+ tmp = cont->prev;
+ while(tmp) {
+ if(tmp->state_mask & cont->state_mask)
+ break;
+ tmp = tmp->prev;
+ }
+ if (tmp) {
+ BLI_remlink(&ob->controllers, cont);
+ BLI_insertlinkbefore(&ob->controllers, tmp, cont);
+ }
+ }
+
+ /* move down */
+ else if( val==2 && cont->next) {
+ tmp = cont->next;
+ while(tmp) {
+ if(tmp->state_mask & cont->state_mask)
+ break;
+ tmp = tmp->next;
+ }
+ BLI_remlink(&ob->controllers, cont);
+ BLI_insertlink(&ob->controllers, tmp, cont);
+ }
+}
+
+void sca_move_actuator(bActuator *act_to_move, Object *ob, int move_up)
+{
+ bActuator *act, *tmp;
+ int val;
+
+ val = move_up ? 1:2;
+
+ /* make sure this actuator belongs to this object */
+ act= ob->actuators.first;
+ while(act) {
+ if(act == act_to_move) break;
+ act= act->next;
+ }
+ if(!act) return;
+
+ /* move up */
+ if( val==1 && act->prev) {
+ /* locate the first visible actuators before this one */
+ for (tmp = act->prev; tmp; tmp=tmp->prev) {
+ if (tmp->flag & ACT_VISIBLE)
+ break;
+ }
+ if (tmp) {
+ BLI_remlink(&ob->actuators, act);
+ BLI_insertlinkbefore(&ob->actuators, tmp, act);
+ }
+ }
+ /* move down */
+ else if( val==2 && act->next) {
+ /* locate the first visible actuators after this one */
+ for (tmp=act->next; tmp; tmp=tmp->next) {
+ if (tmp->flag & ACT_VISIBLE)
+ break;
+ }
+ if (tmp) {
+ BLI_remlink(&ob->actuators, act);
+ BLI_insertlink(&ob->actuators, tmp, act);
+ }
+ }
+}
+
+void link_logicbricks(void **poin, void ***ppoin, short *tot, short size)
+{
+ void **old_links= NULL;
+
+ int ibrick;
+
+ /* check if the bricks are already linked */
+ for (ibrick=0; ibrick < *tot; ibrick++) {
+ if ((*ppoin)[ibrick] == *poin)
+ return;
+ }
+
+ if (*ppoin) {
+ old_links= *ppoin;
+
+ (*tot) ++;
+ *ppoin = MEM_callocN((*tot)*size, "new link");
+
+ for (ibrick=0; ibrick < *tot - 1; ibrick++) {
+ (*ppoin)[ibrick] = old_links[ibrick];
+ }
+ (*ppoin)[ibrick] = *poin;
+
+ if(old_links) MEM_freeN(old_links);
+ }
+ else {
+ (*tot) = 1;
+ *ppoin = MEM_callocN((*tot)*size, "new link");
+ (*ppoin)[0] = *poin;
+ }
+}
+
+void unlink_logicbricks(void **poin, void ***ppoin, short *tot)
+{
+ int ibrick, removed;
+
+ removed= 0;
+ for (ibrick=0; ibrick < *tot; ibrick++) {
+ if(removed) (*ppoin)[ibrick - removed] = (*ppoin)[ibrick];
+ else if((*ppoin)[ibrick] == *poin) removed = 1;
+ }
+
+ if (removed) {
+ (*tot) --;
+
+ if(*tot == 0) {
+ MEM_freeN(*ppoin);
+ (*ppoin)= NULL;
+ }
+ return;
+ }
+}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 77b1202aa20..fe52375617b 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -33,10 +33,6 @@
#include <stdio.h>
#include <string.h>
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#ifndef WIN32
#include <unistd.h>
#else
@@ -45,34 +41,17 @@
#include "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
-#include "DNA_armature_types.h"
-#include "DNA_color_types.h"
-#include "DNA_constraint_types.h"
-#include "DNA_curve_types.h"
#include "DNA_group_types.h"
-#include "DNA_lamp_types.h"
-#include "DNA_material_types.h"
-#include "DNA_meta_types.h"
-#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
-#include "DNA_texture_types.h"
-#include "DNA_userdef_types.h"
+#include "DNA_sequence_types.h"
-#include "BKE_action.h"
#include "BKE_anim.h"
#include "BKE_animsys.h"
-#include "BKE_armature.h"
-#include "BKE_colortools.h"
-#include "BKE_colortools.h"
-#include "BKE_constraint.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_group.h"
-#include "BKE_ipo.h"
#include "BKE_idprop.h"
-#include "BKE_image.h"
-#include "BKE_key.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_node.h"
@@ -219,20 +198,30 @@ Scene *copy_scene(Main *bmain, Scene *sce, int type)
scen->r.qtcodecdata->cdParms = MEM_dupallocN(scen->r.qtcodecdata->cdParms);
}
+ if(sce->r.ffcodecdata.properties) { /* intentionally check scen not sce. */
+ scen->r.ffcodecdata.properties= IDP_CopyProperty(sce->r.ffcodecdata.properties);
+ }
+
/* NOTE: part of SCE_COPY_LINK_DATA and SCE_COPY_FULL operations
* are done outside of blenkernel with ED_objects_single_users! */
- /* camera */
+ /* camera */
if(type == SCE_COPY_LINK_DATA || type == SCE_COPY_FULL) {
- ID_NEW(scen->camera);
+ ID_NEW(scen->camera);
}
/* world */
if(type == SCE_COPY_FULL) {
- if(scen->world) {
- id_us_plus((ID *)scen->world);
- scen->world= copy_world(scen->world);
- }
+ if(scen->world) {
+ id_us_plus((ID *)scen->world);
+ scen->world= copy_world(scen->world);
+ }
+
+ if(sce->ed) {
+ scen->ed= MEM_callocN( sizeof(Editing), "addseq");
+ scen->ed->seqbasep= &scen->ed->seqbase;
+ seqbase_dupli_recursive(sce, &scen->ed->seqbase, &sce->ed->seqbase, SEQ_DUPE_ALL);
+ }
}
sound_create_scene(scen);
@@ -254,9 +243,9 @@ void free_scene(Scene *sce)
if(sce->gpd) {
#if 0 // removed since this can be invalid memory when freeing everything
- // since the grease pencil data is free'd before the scene.
- // since grease pencil data is not (yet?), shared between objects
- // its probably safe not to do this, some save and reload will free this.
+ // since the grease pencil data is free'd before the scene.
+ // since grease pencil data is not (yet?), shared between objects
+ // its probably safe not to do this, some save and reload will free this.
sce->gpd->id.us--;
#endif
sce->gpd= NULL;
@@ -332,7 +321,7 @@ Scene *add_scene(char *name)
int a;
sce= alloc_libblock(&G.main->scene, ID_SCE, name);
- sce->lay= 1;
+ sce->lay= sce->layact= 1;
sce->r.mode= R_GAMMA|R_OSA|R_SHADOW|R_SSS|R_ENVMAP|R_RAYTRACE;
sce->r.cfra= 1;
@@ -365,7 +354,11 @@ Scene *add_scene(char *name)
sce->r.scemode= R_DOCOMP|R_DOSEQ|R_EXTENSION;
sce->r.stamp= R_STAMP_TIME|R_STAMP_FRAME|R_STAMP_DATE|R_STAMP_SCENE|R_STAMP_CAMERA|R_STAMP_RENDERTIME;
sce->r.stamp_font_id= 12;
-
+
+ sce->r.seq_prev_type= OB_SOLID;
+ sce->r.seq_rend_type= OB_SOLID;
+ sce->r.seq_flag= R_SEQ_GL_PREV;
+
sce->r.threads= 1;
sce->r.simplify_subsurf= 6;
@@ -439,9 +432,10 @@ Scene *add_scene(char *name)
pset->fade_frames= 2;
pset->selectmode= SCE_SELECT_PATH;
for(a=0; a<PE_TOT_BRUSH; a++) {
- pset->brush[a].strength= 50;
+ pset->brush[a].strength= 0.5;
pset->brush[a].size= 50;
pset->brush[a].step= 10;
+ pset->brush[a].count= 10;
}
pset->brush[PE_BRUSH_CUT].strength= 100;
@@ -559,18 +553,17 @@ void set_scene_bg(Scene *scene)
}
/* called from creator.c */
-void set_scene_name(char *name)
+Scene *set_scene_name(char *name)
{
- Scene *sce;
-
- for (sce= G.main->scene.first; sce; sce= sce->id.next) {
- if (BLI_streq(name, sce->id.name+2)) {
- set_scene_bg(sce);
- return;
- }
+ Scene *sce= (Scene *)find_id("SC", name);
+ if(sce) {
+ set_scene_bg(sce);
+ printf("Scene switch: '%s' in file: '%s'\n", name, G.sce);
+ return sce;
}
-
- //XXX error("Can't find scene: %s", name);
+
+ printf("Can't find scene: '%s' in file: '%s'\n", name, G.sce);
+ return NULL;
}
void unlink_scene(Main *bmain, Scene *sce, Scene *newsce)
@@ -600,7 +593,7 @@ void unlink_scene(Main *bmain, Scene *sce, Scene *newsce)
/* used by metaballs
* doesnt return the original duplicated object, only dupli's
*/
-int next_object(Scene *scene, int val, Base **base, Object **ob)
+int next_object(Scene **scene, int val, Base **base, Object **ob)
{
static ListBase *duplilist= NULL;
static DupliObject *dupob;
@@ -629,17 +622,21 @@ int next_object(Scene *scene, int val, Base **base, Object **ob)
/* the first base */
if(fase==F_START) {
- *base= scene->base.first;
+ *base= (*scene)->base.first;
if(*base) {
*ob= (*base)->object;
fase= F_SCENE;
}
else {
- /* exception: empty scene */
- if(scene->set && scene->set->base.first) {
- *base= scene->set->base.first;
- *ob= (*base)->object;
- fase= F_SET;
+ /* exception: empty scene */
+ while((*scene)->set) {
+ (*scene)= (*scene)->set;
+ if((*scene)->base.first) {
+ *base= (*scene)->base.first;
+ *ob= (*base)->object;
+ fase= F_SCENE;
+ break;
+ }
}
}
}
@@ -649,11 +646,14 @@ int next_object(Scene *scene, int val, Base **base, Object **ob)
if(*base) *ob= (*base)->object;
else {
if(fase==F_SCENE) {
- /* scene is finished, now do the set */
- if(scene->set && scene->set->base.first) {
- *base= scene->set->base.first;
- *ob= (*base)->object;
- fase= F_SET;
+ /* (*scene) is finished, now do the set */
+ while((*scene)->set) {
+ (*scene)= (*scene)->set;
+ if((*scene)->base.first) {
+ *base= (*scene)->base.first;
+ *ob= (*base)->object;
+ break;
+ }
}
}
}
@@ -668,7 +668,7 @@ int next_object(Scene *scene, int val, Base **base, Object **ob)
this enters eternal loop because of
makeDispListMBall getting called inside of group_duplilist */
if((*base)->object->dup_group == NULL) {
- duplilist= object_duplilist(scene, (*base)->object);
+ duplilist= object_duplilist((*scene), (*base)->object);
dupob= duplilist->first;
@@ -704,6 +704,10 @@ int next_object(Scene *scene, int val, Base **base, Object **ob)
}
}
+ /* if(ob && *ob) {
+ printf("Scene: '%s', '%s'\n", (*scene)->id.name+2, (*ob)->id.name+2);
+ } */
+
/* reset recursion test */
in_next_object= 0;
@@ -722,7 +726,7 @@ Object *scene_find_camera(Scene *sc)
}
#ifdef DURIAN_CAMERA_SWITCH
-Object *scene_find_camera_switch(Scene *scene)
+Object *scene_camera_switch_find(Scene *scene)
{
TimeMarker *m;
int cfra = scene->r.cfra;
@@ -743,6 +747,18 @@ Object *scene_find_camera_switch(Scene *scene)
}
#endif
+int scene_camera_switch_update(Scene *scene)
+{
+#ifdef DURIAN_CAMERA_SWITCH
+ Object *camera= scene_camera_switch_find(scene);
+ if(camera) {
+ scene->camera= camera;
+ return 1;
+ }
+#endif
+ return 0;
+}
+
char *scene_find_marker_name(Scene *scene, int frame)
{
ListBase *markers= &scene->markers;
@@ -783,6 +799,39 @@ char *scene_find_last_marker_name(Scene *scene, int frame)
return best_marker ? best_marker->name : NULL;
}
+/* markers need transforming from different parts of the code so have
+ * a generic function to do this */
+int scene_marker_tfm_translate(Scene *scene, int delta, int flag)
+{
+ TimeMarker *marker;
+ int tot= 0;
+
+ for (marker= scene->markers.first; marker; marker= marker->next) {
+ if ((marker->flag & flag) == flag) {
+ marker->frame += delta;
+ tot++;
+ }
+ }
+
+ return tot;
+}
+
+int scene_marker_tfm_extend(Scene *scene, int delta, int flag, int frame, char side)
+{
+ TimeMarker *marker;
+ int tot= 0;
+
+ for (marker= scene->markers.first; marker; marker= marker->next) {
+ if ((marker->flag & flag) == flag) {
+ if((side=='L' && marker->frame < frame) || (side=='R' && marker->frame >= frame)) {
+ marker->frame += delta;
+ tot++;
+ }
+ }
+ }
+
+ return tot;
+}
Base *scene_add_base(Scene *sce, Object *ob)
{
@@ -840,73 +889,62 @@ int scene_check_setscene(Scene *sce)
return 1;
}
-/* This (evil) function is needed to cope with two legacy Blender rendering features
-* mblur (motion blur that renders 'subframes' and blurs them together), and fields
-* rendering. Thus, the use of ugly globals from object.c
-*/
-// BAD... EVIL... JUJU...!!!!
-// XXX moved here temporarily
-float frame_to_float (Scene *scene, int cfra) /* see also bsystem_time in object.c */
+/* This function is needed to cope with fractional frames - including two Blender rendering features
+* mblur (motion blur that renders 'subframes' and blurs them together), and fields rendering. */
+
+/* see also bsystem_time in object.c */
+float BKE_curframe(Scene *scene)
{
- extern float bluroffs; /* bad stuff borrowed from object.c */
- extern float fieldoffs;
- float ctime;
-
- ctime= (float)cfra;
- ctime+= bluroffs+fieldoffs;
- ctime*= scene->r.framelen;
-
+ float ctime = scene->r.cfra;
+ ctime+= scene->r.subframe;
+ ctime*= scene->r.framelen;
+
return ctime;
}
-static void scene_update_newframe(Scene *sce, unsigned int lay)
+static void scene_update_tagged_recursive(Scene *scene, Scene *scene_parent)
{
Base *base;
- Object *ob;
-
- for(base= sce->base.first; base; base= base->next) {
- ob= base->object;
-
- object_handle_update(sce, ob); // bke_object.h
-
- /* only update layer when an ipo */
- // XXX old animation system
- //if(ob->ipo && has_ipo_code(ob->ipo, OB_LAY) ) {
- // base->lay= ob->lay;
- //}
+
+ /* sets first, we allow per definition current scene to have
+ dependencies on sets, but not the other way around. */
+ if(scene->set)
+ scene_update_tagged_recursive(scene->set, scene_parent);
+
+ for(base= scene->base.first; base; base= base->next) {
+ Object *ob= base->object;
+
+ object_handle_update(scene_parent, ob);
+
+ if(ob->dup_group && (ob->transflag & OB_DUPLIGROUP))
+ group_handle_recalc_and_update(scene_parent, ob, ob->dup_group);
+
+ /* always update layer, so that animating layers works */
+ base->lay= ob->lay;
}
}
/* this is called in main loop, doing tagged updates before redraw */
void scene_update_tagged(Scene *scene)
{
- Scene *sce;
- Base *base;
- float ctime = frame_to_float(scene, scene->r.cfra);
+ scene->physics_settings.quick_cache_step= 0;
/* update all objects: drivers, matrices, displists, etc. flags set
by depgraph or manual, no layer check here, gets correct flushed */
- /* sets first, we allow per definition current scene to have
- dependencies on sets, but not the other way around. */
- if(scene->set) {
- for(SETLOOPER(scene->set, base))
- object_handle_update(scene, base->object);
- }
-
- for(base= scene->base.first; base; base= base->next) {
- object_handle_update(scene, base->object);
- }
+ scene_update_tagged_recursive(scene, scene);
/* recalc scene animation data here (for sequencer) */
{
+ float ctime = BKE_curframe(scene);
AnimData *adt= BKE_animdata_from_id(&scene->id);
if(adt && (adt->recalc & ADT_RECALC_ANIM))
BKE_animsys_evaluate_animdata(&scene->id, adt, ctime, 0);
}
- BKE_ptcache_quick_cache_all(scene);
+ if(scene->physics_settings.quick_cache_step)
+ BKE_ptcache_quick_cache_all(scene);
/* in the future this should handle updates for all datablocks, not
only objects and scenes. - brecht */
@@ -915,7 +953,7 @@ void scene_update_tagged(Scene *scene)
/* applies changes right away, does all sets too */
void scene_update_for_newframe(Scene *sce, unsigned int lay)
{
- float ctime = frame_to_float(sce, sce->r.cfra);
+ float ctime = BKE_curframe(sce);
Scene *sce_iter;
/* clear animation overrides */
@@ -928,7 +966,7 @@ void scene_update_for_newframe(Scene *sce, unsigned int lay)
/* Following 2 functions are recursive
- * so dont call within 'scene_update_newframe' */
+ * so dont call within 'scene_update_tagged_recursive' */
DAG_scene_update_flags(sce, lay); // only stuff that moves or needs display still
/* All 'standard' (i.e. without any dependencies) animation is handled here,
@@ -940,12 +978,8 @@ void scene_update_for_newframe(Scene *sce, unsigned int lay)
BKE_animsys_evaluate_all_animation(G.main, ctime);
/*...done with recusrive funcs */
-
- /* sets first, we allow per definition current scene to have dependencies on sets */
- for(sce_iter= sce->set; sce_iter; sce_iter= sce_iter->set)
- scene_update_newframe(sce_iter, lay);
-
- scene_update_newframe(sce, lay);
+ /* object_handle_update() on all objects, groups and sets */
+ scene_update_tagged_recursive(sce, sce);
}
/* return default layer, also used to patch old files */
@@ -999,3 +1033,26 @@ float get_render_aosss_error(RenderData *r, float error)
return error;
}
+/* helper function for the SETLOOPER macro */
+Base *_setlooper_base_step(Scene **sce, Base *base)
+{
+ if(base && base->next) {
+ /* common case, step to the next */
+ return base->next;
+ }
+ else if(base==NULL && (*sce)->base.first) {
+ /* first time looping, return the scenes first base */
+ return (Base *)(*sce)->base.first;
+ }
+ else {
+ /* reached the end, get the next base in the set */
+ while((*sce= (*sce)->set)) {
+ base= (Base *)(*sce)->base.first;
+ if(base) {
+ return base;
+ }
+ }
+ }
+
+ return NULL;
+}
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 6d0057ca298..a8140cb815d 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -235,27 +235,6 @@ void BKE_spacedata_copylist(ListBase *lb1, ListBase *lb2)
}
}
-/* lb1 should be empty */
-void BKE_spacedata_copyfirst(ListBase *lb1, ListBase *lb2)
-{
- SpaceLink *sl;
-
- lb1->first= lb1->last= NULL; /* to be sure */
-
- sl= lb2->first;
- if(sl) {
- SpaceType *st= BKE_spacetype_from_id(sl->spacetype);
-
- if(st && st->duplicate) {
- SpaceLink *slnew= st->duplicate(sl);
-
- BLI_addtail(lb1, slnew);
-
- region_copylist(st, &slnew->regionbase, &sl->regionbase);
- }
- }
-}
-
/* not region itself */
void BKE_area_region_free(SpaceType *st, ARegion *ar)
{
@@ -352,3 +331,66 @@ ARegion *BKE_area_find_region_type(ScrArea *sa, int type)
return NULL;
}
+void BKE_screen_view3d_sync(struct View3D *v3d, struct Scene *scene)
+{
+ int bit;
+
+ if(v3d->scenelock && v3d->localvd==NULL) {
+ v3d->lay= scene->lay;
+ v3d->camera= scene->camera;
+
+ if(v3d->camera==NULL) {
+ ARegion *ar;
+
+ for(ar=v3d->regionbase.first; ar; ar= ar->next) {
+ if(ar->regiontype == RGN_TYPE_WINDOW) {
+ RegionView3D *rv3d= ar->regiondata;
+ if(rv3d->persp==RV3D_CAMOB)
+ rv3d->persp= RV3D_PERSP;
+ }
+ }
+ }
+
+ if((v3d->lay & v3d->layact) == 0) {
+ for(bit= 0; bit<32; bit++) {
+ if(v3d->lay & (1<<bit)) {
+ v3d->layact= 1<<bit;
+ break;
+ }
+ }
+ }
+ }
+}
+
+void BKE_screen_view3d_scene_sync(bScreen *sc)
+{
+ /* are there cameras in the views that are not in the scene? */
+ ScrArea *sa;
+ for(sa= sc->areabase.first; sa; sa= sa->next) {
+ SpaceLink *sl;
+ for(sl= sa->spacedata.first; sl; sl= sl->next) {
+ if(sl->spacetype==SPACE_VIEW3D) {
+ View3D *v3d= (View3D*) sl;
+ BKE_screen_view3d_sync(v3d, sc->scene);
+ }
+ }
+ }
+}
+
+void BKE_screen_view3d_main_sync(ListBase *screen_lb, Scene *scene)
+{
+ bScreen *sc;
+ ScrArea *sa;
+ SpaceLink *sl;
+
+ /* from scene copy to the other views */
+ for(sc=screen_lb->first; sc; sc=sc->id.next) {
+ if(sc->scene!=scene)
+ continue;
+
+ for(sa=sc->areabase.first; sa; sa=sa->next)
+ for(sl=sa->spacedata.first; sl; sl=sl->next)
+ if(sl->spacetype==SPACE_VIEW3D)
+ BKE_screen_view3d_sync((View3D*)sl, scene);
+ }
+}
diff --git a/source/blender/blenkernel/intern/script.c b/source/blender/blenkernel/intern/script.c
index 424067a7046..c07032f71d7 100644
--- a/source/blender/blenkernel/intern/script.c
+++ b/source/blender/blenkernel/intern/script.c
@@ -31,17 +31,10 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#include "BKE_script.h"
-#include "DNA_space_types.h"
#include "MEM_guardedalloc.h"
/*
-#include "BLI_blenlib.h"
-#include "BKE_utildefines.h"
-#include "BKE_library.h"
-#include "BKE_global.h"
-#include "BKE_main.h"
#ifndef DISABLE_PYTHON
#include "BPY_extern.h" // Blender Python library
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 770bcddfffd..73c19772c69 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -34,14 +34,12 @@
#include "MEM_guardedalloc.h"
#include "PIL_dynlib.h"
+#include "BLI_math.h" /* windows needs for M_PI */
+
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
#include "DNA_anim_types.h"
-#include "BLI_blenlib.h"
-#include "BLI_math.h"
-
-#include "BKE_global.h"
#include "BKE_fcurve.h"
#include "BKE_plugin_types.h"
#include "BKE_sequencer.h"
@@ -54,7 +52,7 @@
#include "RNA_access.h"
/* **** XXX **** */
-static void error() {}
+static void error(const char *error, ...) {}
#define INT 96
#define FLO 128
@@ -233,6 +231,7 @@ static ImBuf * IMB_cast_away_list(ImBuf * i)
static void do_plugin_effect(Scene *scene, Sequence *seq, int cfra,
float facf0, float facf1, int x, int y,
+ int preview_render_size,
struct ImBuf *ibuf1, struct ImBuf *ibuf2,
struct ImBuf *ibuf3, struct ImBuf *out)
{
@@ -313,7 +312,7 @@ static void do_plugin_effect(Scene *scene, Sequence *seq, int cfra,
IMB_convert_rgba_to_abgr(out);
}
if (seq->plugin->version<=3 && float_rendering) {
- IMB_float_from_rect(out);
+ IMB_float_from_rect_simple(out);
}
if (use_temp_bufs) {
@@ -325,7 +324,7 @@ static void do_plugin_effect(Scene *scene, Sequence *seq, int cfra,
}
static int do_plugin_early_out(struct Sequence *seq,
- float facf0, float facf1)
+ float facf0, float facf1)
{
return 0;
}
@@ -350,7 +349,7 @@ static void init_alpha_over_or_under(Sequence * seq)
}
static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y,
- char * rect1, char *rect2, char *out)
+ char * rect1, char *rect2, char *out)
{
int fac2, mfac, fac, fac4;
int xo, tempc;
@@ -416,7 +415,7 @@ static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y,
}
static void do_alphaover_effect_float(float facf0, float facf1, int x, int y,
- float * rect1, float *rect2, float *out)
+ float * rect1, float *rect2, float *out)
{
float fac2, mfac, fac, fac4;
int xo;
@@ -479,6 +478,7 @@ static void do_alphaover_effect_float(float facf0, float facf1, int x, int y,
static void do_alphaover_effect(Scene *scene, Sequence *seq, int cfra,
float facf0, float facf1, int x, int y,
+ int preview_render_size,
struct ImBuf *ibuf1, struct ImBuf *ibuf2,
struct ImBuf *ibuf3, struct ImBuf *out)
{
@@ -570,8 +570,8 @@ void do_alphaunder_effect_byte(
static void do_alphaunder_effect_float(float facf0, float facf1, int x, int y,
- float *rect1, float *rect2,
- float *out)
+ float *rect1, float *rect2,
+ float *out)
{
float fac2, mfac, fac, fac4;
int xo;
@@ -646,6 +646,7 @@ static void do_alphaunder_effect_float(float facf0, float facf1, int x, int y,
static void do_alphaunder_effect(Scene *scene, Sequence *seq, int cfra,
float facf0, float facf1, int x, int y,
+ int preview_render_size,
struct ImBuf *ibuf1, struct ImBuf *ibuf2,
struct ImBuf *ibuf3, struct ImBuf *out)
{
@@ -766,6 +767,7 @@ void do_cross_effect_float(float facf0, float facf1, int x, int y,
static void do_cross_effect(Scene *scene, Sequence *seq, int cfra,
float facf0, float facf1, int x, int y,
+ int preview_render_size,
struct ImBuf *ibuf1, struct ImBuf *ibuf2,
struct ImBuf *ibuf3, struct ImBuf *out)
{
@@ -856,7 +858,7 @@ static float gammaCorrect(float c)
if (i < 0) res = -pow(abs(c), valid_gamma);
else if (i >= RE_GAMMA_TABLE_SIZE ) res = pow(c, valid_gamma);
else res = gamma_range_table[i] +
- ( (c - color_domain_table[i]) * gamfactor_table[i]);
+ ( (c - color_domain_table[i]) * gamfactor_table[i]);
return res;
} /* end of float gammaCorrect(float col) */
@@ -873,7 +875,7 @@ static float invGammaCorrect(float col)
if (i < 0) res = -pow(abs(col), valid_inv_gamma);
else if (i >= RE_GAMMA_TABLE_SIZE) res = pow(col, valid_inv_gamma);
else res = inv_gamma_range_table[i] +
- ( (col - color_domain_table[i]) * inv_gamfactor_table[i]);
+ ( (col - color_domain_table[i]) * inv_gamfactor_table[i]);
return res;
} /* end of float invGammaCorrect(float col) */
@@ -928,10 +930,10 @@ static void free_gammacross(Sequence * seq)
}
static void do_gammacross_effect_byte(float facf0, float facf1,
- int x, int y,
- unsigned char *rect1,
- unsigned char *rect2,
- unsigned char *out)
+ int x, int y,
+ unsigned char *rect1,
+ unsigned char *rect2,
+ unsigned char *out)
{
int fac1, fac2, col;
int xo;
@@ -984,9 +986,9 @@ static void do_gammacross_effect_byte(float facf0, float facf1,
}
static void do_gammacross_effect_float(float facf0, float facf1,
- int x, int y,
- float *rect1, float *rect2,
- float *out)
+ int x, int y,
+ float *rect1, float *rect2,
+ float *out)
{
float fac1, fac2;
int xo;
@@ -1028,6 +1030,7 @@ static void do_gammacross_effect_float(float facf0, float facf1,
static void do_gammacross_effect(Scene *scene, Sequence *seq, int cfra,
float facf0, float facf1, int x, int y,
+ int preview_render_size,
struct ImBuf *ibuf1, struct ImBuf *ibuf2,
struct ImBuf *ibuf3, struct ImBuf *out)
{
@@ -1052,8 +1055,8 @@ static void do_gammacross_effect(Scene *scene, Sequence *seq, int cfra,
********************************************************************** */
static void do_add_effect_byte(float facf0, float facf1, int x, int y,
- unsigned char *rect1, unsigned char *rect2,
- unsigned char *out)
+ unsigned char *rect1, unsigned char *rect2,
+ unsigned char *out)
{
int col, xo, fac1, fac3;
char *rt1, *rt2, *rt;
@@ -1142,6 +1145,7 @@ static void do_add_effect_float(float facf0, float facf1, int x, int y,
static void do_add_effect(Scene *scene, Sequence *seq, int cfra,
float facf0, float facf1, int x, int y,
+ int preview_render_size,
struct ImBuf *ibuf1, struct ImBuf *ibuf2,
struct ImBuf *ibuf3, struct ImBuf *out)
{
@@ -1164,8 +1168,8 @@ static void do_add_effect(Scene *scene, Sequence *seq, int cfra,
********************************************************************** */
static void do_sub_effect_byte(float facf0, float facf1,
- int x, int y,
- char *rect1, char *rect2, char *out)
+ int x, int y,
+ char *rect1, char *rect2, char *out)
{
int col, xo, fac1, fac3;
char *rt1, *rt2, *rt;
@@ -1253,7 +1257,8 @@ static void do_sub_effect_float(float facf0, float facf1, int x, int y,
}
static void do_sub_effect(Scene *scene, Sequence *seq, int cfra,
- float facf0, float facf1, int x, int y,
+ float facf0, float facf1, int x, int y,
+ int preview_render_size,
struct ImBuf *ibuf1, struct ImBuf *ibuf2,
struct ImBuf *ibuf3, struct ImBuf *out)
{
@@ -1362,6 +1367,7 @@ static void do_drop_effect_float(float facf0, float facf1, int x, int y,
static void do_drop_effect(Scene *scene, Sequence *seq, int cfra,
float facf0, float facf1, int x, int y,
+ int preview_render_size,
struct ImBuf *ibuf1, struct ImBuf *ibuf2,
struct ImBuf * ibuf3,
struct ImBuf *out)
@@ -1384,8 +1390,8 @@ static void do_drop_effect(Scene *scene, Sequence *seq, int cfra,
********************************************************************** */
static void do_mul_effect_byte(float facf0, float facf1, int x, int y,
- unsigned char *rect1, unsigned char *rect2,
- unsigned char *out)
+ unsigned char *rect1, unsigned char *rect2,
+ unsigned char *out)
{
int xo, fac1, fac3;
char *rt1, *rt2, *rt;
@@ -1433,8 +1439,8 @@ static void do_mul_effect_byte(float facf0, float facf1, int x, int y,
}
static void do_mul_effect_float(float facf0, float facf1, int x, int y,
- float *rect1, float *rect2,
- float *out)
+ float *rect1, float *rect2,
+ float *out)
{
int xo;
float fac1, fac3;
@@ -1483,6 +1489,7 @@ static void do_mul_effect_float(float facf0, float facf1, int x, int y,
static void do_mul_effect(Scene *scene, Sequence *seq, int cfra,
float facf0, float facf1, int x, int y,
+ int preview_render_size,
struct ImBuf *ibuf1, struct ImBuf *ibuf2,
struct ImBuf *ibuf3, struct ImBuf *out)
{
@@ -1613,13 +1620,13 @@ float hyp3,hyp4,b4,b5
output = in_band(wipezone,width,hyp,facf0,1,1);
else
output = in_band(wipezone,width,hyp,facf0,0,1);
- }
+ }
else {
if(b1 < b2)
output = in_band(wipezone,width,hyp,facf0,0,1);
else
output = in_band(wipezone,width,hyp,facf0,1,1);
- }
+ }
break;
case DO_DOUBLE_WIPE:
@@ -1659,50 +1666,50 @@ float hyp3,hyp4,b4,b5
if( hyp < hwidth && hyp2 > hwidth )
output = in_band(wipezone,hwidth,hyp,facf0,1,1);
else if( hyp > hwidth && hyp2 < hwidth )
- output = in_band(wipezone,hwidth,hyp2,facf0,1,1);
+ output = in_band(wipezone,hwidth,hyp2,facf0,1,1);
else
- output = in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1);
+ output = in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1);
}
if(!wipe->forward)output = 1-output;
- break;
- case DO_CLOCK_WIPE:
- /*
- temp1: angle of effect center in rads
- temp2: angle of line through (halfx,halfy) and (x,y) in rads
- temp3: angle of low side of blur
- temp4: angle of high side of blur
- */
- output = 1.0f - facf0;
- widthf = wipe->edgeWidth*2.0f*(float)M_PI;
- temp1 = 2.0f * (float)M_PI * facf0;
+ break;
+ case DO_CLOCK_WIPE:
+ /*
+ temp1: angle of effect center in rads
+ temp2: angle of line through (halfx,halfy) and (x,y) in rads
+ temp3: angle of low side of blur
+ temp4: angle of high side of blur
+ */
+ output = 1.0f - facf0;
+ widthf = wipe->edgeWidth*2.0f*(float)M_PI;
+ temp1 = 2.0f * (float)M_PI * facf0;
- if(wipe->forward){
- temp1 = 2.0f*(float)M_PI - temp1;
- }
+ if(wipe->forward){
+ temp1 = 2.0f*(float)M_PI - temp1;
+ }
- x = x - halfx;
- y = y - halfy;
-
- temp2 = asin(abs(y)/sqrt(x*x + y*y));
- if(x <= 0 && y >= 0) temp2 = (float)M_PI - temp2;
- else if(x<=0 && y <= 0) temp2 += (float)M_PI;
- else if(x >= 0 && y <= 0) temp2 = 2.0f*(float)M_PI - temp2;
-
- if(wipe->forward){
- temp3 = temp1-(widthf*0.5f)*facf0;
- temp4 = temp1+(widthf*0.5f)*(1-facf0);
- } else{
- temp3 = temp1-(widthf*0.5f)*(1-facf0);
- temp4 = temp1+(widthf*0.5f)*facf0;
+ x = x - halfx;
+ y = y - halfy;
+
+ temp2 = asin(abs(y)/sqrt(x*x + y*y));
+ if(x <= 0 && y >= 0) temp2 = (float)M_PI - temp2;
+ else if(x<=0 && y <= 0) temp2 += (float)M_PI;
+ else if(x >= 0 && y <= 0) temp2 = 2.0f*(float)M_PI - temp2;
+
+ if(wipe->forward){
+ temp3 = temp1-(widthf*0.5f)*facf0;
+ temp4 = temp1+(widthf*0.5f)*(1-facf0);
+ } else{
+ temp3 = temp1-(widthf*0.5f)*(1-facf0);
+ temp4 = temp1+(widthf*0.5f)*facf0;
}
- if (temp3 < 0) temp3 = 0;
- if (temp4 > 2.0f*(float)M_PI) temp4 = 2.0f*(float)M_PI;
+ if (temp3 < 0) temp3 = 0;
+ if (temp4 > 2.0f*(float)M_PI) temp4 = 2.0f*(float)M_PI;
- if(temp2 < temp3) output = 0;
- else if (temp2 > temp4) output = 1;
- else output = (temp2-temp3)/(temp4-temp3);
- if(x == 0 && y == 0) output = 1;
+ if(temp2 < temp3) output = 0;
+ else if (temp2 > temp4) output = 1;
+ else output = (temp2-temp3)/(temp4-temp3);
+ if(x == 0 && y == 0) output = 1;
if(output != output) output = 1;
if(wipe->forward) output = 1 - output;
break;
@@ -1737,9 +1744,9 @@ float hyp3,hyp4,b4,b5
if( hyp < hwidth && hyp2 > hwidth )
output = in_band(wipezone,hwidth,hyp,facf0,1,1);
else if( hyp > hwidth && hyp2 < hwidth )
- output = in_band(wipezone,hwidth,hyp2,facf0,1,1);
+ output = in_band(wipezone,hwidth,hyp2,facf0,1,1);
else
- output = in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1);
+ output = in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1);
}
if(invert)facf0 = 1-facf0;
@@ -1778,11 +1785,11 @@ float hyp3,hyp4,b4,b5
hwidth = width*0.5f;
temp1 = (halfx-(halfx)*facf0);
- pointdist = sqrt(temp1*temp1 + temp1*temp1);
+ pointdist = sqrt(temp1*temp1 + temp1*temp1);
- temp2 = sqrt((halfx-x)*(halfx-x) + (halfy-y)*(halfy-y));
- if(temp2 > pointdist) output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,0,1);
- else output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,1,1);
+ temp2 = sqrt((halfx-x)*(halfx-x) + (halfy-y)*(halfy-y));
+ if(temp2 > pointdist) output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,0,1);
+ else output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,1,1);
if(!wipe->forward) output = 1-output;
@@ -1933,19 +1940,20 @@ static void do_wipe_effect_float(Sequence *seq, float facf0, float facf1,
static void do_wipe_effect(Scene *scene, Sequence *seq, int cfra,
float facf0, float facf1, int x, int y,
+ int preview_render_size,
struct ImBuf *ibuf1, struct ImBuf *ibuf2,
struct ImBuf *ibuf3, struct ImBuf *out)
{
if (out->rect_float) {
do_wipe_effect_float(seq,
- facf0, facf1, x, y,
- ibuf1->rect_float, ibuf2->rect_float,
- out->rect_float);
+ facf0, facf1, x, y,
+ ibuf1->rect_float, ibuf2->rect_float,
+ out->rect_float);
} else {
do_wipe_effect_byte(seq,
- facf0, facf1, x, y,
- (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect,
- (unsigned char*) out->rect);
+ facf0, facf1, x, y,
+ (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect,
+ (unsigned char*) out->rect);
}
}
/* **********************************************************************
@@ -2077,9 +2085,10 @@ static void do_transform(Scene *scene, Sequence *seq, float facf0, int x, int y,
static void do_transform_effect(Scene *scene, Sequence *seq,int cfra,
- float facf0, float facf1, int x, int y,
- struct ImBuf *ibuf1, struct ImBuf *ibuf2,
- struct ImBuf *ibuf3, struct ImBuf *out)
+ float facf0, float facf1, int x, int y,
+ int preview_render_size,
+ struct ImBuf *ibuf1, struct ImBuf *ibuf2,
+ struct ImBuf *ibuf3, struct ImBuf *out)
{
do_transform(scene, seq, facf0, x, y, ibuf1, out);
}
@@ -2468,8 +2477,8 @@ static void RVAddBitmaps_float (float* a, float* b, float* c,
/* For each pixel whose total luminance exceeds the threshold, */
/* Multiply it's value by BOOST and add it to the output map */
static void RVIsolateHighlights_byte (unsigned char* in, unsigned char* out,
- int width, int height, int threshold,
- float boost, float clamp)
+ int width, int height, int threshold,
+ float boost, float clamp)
{
int x,y,index;
int intensity;
@@ -2477,7 +2486,7 @@ static void RVIsolateHighlights_byte (unsigned char* in, unsigned char* out,
for(y=0;y< height;y++) {
for (x=0;x< width;x++) {
- index= (x+y*width)*4;
+ index= (x+y*width)*4;
/* Isolate the intensity */
intensity=(in[index+GlowR]+in[index+GlowG]+in[index+GlowB]-threshold);
@@ -2497,8 +2506,8 @@ static void RVIsolateHighlights_byte (unsigned char* in, unsigned char* out,
}
static void RVIsolateHighlights_float (float* in, float* out,
- int width, int height, float threshold,
- float boost, float clamp)
+ int width, int height, float threshold,
+ float boost, float clamp)
{
int x,y,index;
float intensity;
@@ -2506,7 +2515,7 @@ static void RVIsolateHighlights_float (float* in, float* out,
for(y=0;y< height;y++) {
for (x=0;x< width;x++) {
- index= (x+y*width)*4;
+ index= (x+y*width)*4;
/* Isolate the intensity */
intensity=(in[index+GlowR]+in[index+GlowG]+in[index+GlowB]-threshold);
@@ -2590,19 +2599,20 @@ static void do_glow_effect_float(Sequence *seq, float facf0, float facf1,
static void do_glow_effect(Scene *scene, Sequence *seq, int cfra,
float facf0, float facf1, int x, int y,
+ int preview_render_size,
struct ImBuf *ibuf1, struct ImBuf *ibuf2,
struct ImBuf *ibuf3, struct ImBuf *out)
{
if (out->rect_float) {
do_glow_effect_float(seq,
- facf0, facf1, x, y,
- ibuf1->rect_float, ibuf2->rect_float,
- out->rect_float);
+ facf0, facf1, x, y,
+ ibuf1->rect_float, ibuf2->rect_float,
+ out->rect_float);
} else {
do_glow_effect_byte(seq,
- facf0, facf1, x, y,
- (char*) ibuf1->rect, (char*) ibuf2->rect,
- (char*) out->rect);
+ facf0, facf1, x, y,
+ (char*) ibuf1->rect, (char*) ibuf2->rect,
+ (char*) out->rect);
}
}
@@ -2645,6 +2655,7 @@ static int early_out_color(struct Sequence *seq,
static void do_solid_color(Scene *scene, Sequence *seq, int cfra,
float facf0, float facf1, int x, int y,
+ int preview_render_size,
struct ImBuf *ibuf1, struct ImBuf *ibuf2,
struct ImBuf *ibuf3, struct ImBuf *out)
{
@@ -2720,6 +2731,64 @@ static void do_solid_color(Scene *scene, Sequence *seq, int cfra,
}
/* **********************************************************************
+ MULTICAM
+ ********************************************************************** */
+
+/* no effect inputs for multicam, we use give_ibuf_seq */
+static int num_inputs_multicam()
+{
+ return 0;
+}
+
+static int early_out_multicam(struct Sequence *seq, float facf0, float facf1)
+{
+ return -1;
+}
+
+static void do_multicam(Scene *scene, Sequence *seq, int cfra,
+ float facf0, float facf1, int x, int y,
+ int preview_render_size,
+ struct ImBuf *ibuf1, struct ImBuf *ibuf2,
+ struct ImBuf *ibuf3, struct ImBuf *out)
+{
+ struct ImBuf * i;
+ Editing * ed;
+ ListBase * seqbasep;
+
+ if (seq->multicam_source == 0 || seq->multicam_source >= seq->machine) {
+ return;
+ }
+
+ ed = scene->ed;
+ if (!ed) {
+ return;
+ }
+ seqbasep = seq_seqbase(&ed->seqbase, seq);
+ if (!seqbasep) {
+ return;
+ }
+
+ i = give_ibuf_seqbase(scene,
+ out->x, out->y, cfra, seq->multicam_source,
+ preview_render_size, seqbasep);
+ if (!i) {
+ return;
+ }
+
+ if (out->rect && i->rect) {
+ memcpy(out->rect, i->rect, out->x * out->y * 4);
+ } else if (out->rect_float && i->rect_float) {
+ memcpy(out->rect_float, i->rect_float, out->x * out->y *4*sizeof(float));
+ } else if (out->rect && i->rect_float) {
+ IMB_rect_from_float(i);
+ memcpy(out->rect, i->rect, out->x * out->y * 4);
+ } else if (out->rect_float && i->rect) {
+ IMB_float_from_rect_simple(i);
+ memcpy(out->rect_float, i->rect_float, out->x * out->y *4*sizeof(float));
+ }
+}
+
+/* **********************************************************************
SPEED
********************************************************************** */
static void init_speed_effect(Sequence *seq)
@@ -2728,12 +2797,12 @@ static void init_speed_effect(Sequence *seq)
if(seq->effectdata) MEM_freeN(seq->effectdata);
seq->effectdata = MEM_callocN(sizeof(struct SpeedControlVars),
- "speedcontrolvars");
+ "speedcontrolvars");
v = (SpeedControlVars *)seq->effectdata;
v->globalSpeed = 1.0;
v->frameMap = 0;
- v->flags = SEQ_SPEED_COMPRESS_IPO_Y;
+ v->flags = 0;
v->length = 0;
}
@@ -2809,7 +2878,7 @@ void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
return;
}
if (!seq->seq1) { /* make coverity happy and check for (CID 598)
- input strip ... */
+ input strip ... */
return;
}
@@ -2856,16 +2925,10 @@ void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
for (cfra = 1; cfra < v->length; cfra++) {
if(fcu) {
- if((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) {
- ctime = seq->startdisp + cfra;
- div = 1.0;
- } else {
- ctime= cfra;
- div= v->length / 100.0f;
- if(div==0.0) return;
- }
-
- facf = evaluate_fcurve(fcu, ctime/div);
+ ctime = seq->startdisp + cfra;
+ div = 1.0;
+
+ facf = evaluate_fcurve(fcu, ctime/div);
} else {
facf = fallback_fac;
}
@@ -2887,19 +2950,13 @@ void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
for (cfra = 0; cfra < v->length; cfra++) {
if(fcu) {
- if((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) {
- ctime = seq->startdisp + cfra;
- div = 1.0;
- } else {
- ctime= cfra;
- div= v->length / 100.0f;
- if(div==0.0) return;
- }
-
- facf = evaluate_fcurve(fcu, ctime / div);
- if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
- facf *= v->length;
- }
+ ctime = seq->startdisp + cfra;
+ div = 1.0;
+
+ facf = evaluate_fcurve(fcu, ctime / div);
+ if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
+ facf *= v->length;
+ }
}
if (!fcu) {
@@ -3008,14 +3065,18 @@ static void get_default_fac_fade(struct Sequence *seq, int cfra,
static void do_overdrop_effect(Scene *scene, Sequence *seq, int cfra,
float fac, float facf,
- int x, int y, struct ImBuf * ibuf1,
+ int x, int y,
+ int preview_render_size,
+ struct ImBuf * ibuf1,
struct ImBuf * ibuf2,
struct ImBuf * ibuf3,
struct ImBuf * out)
{
do_drop_effect(scene, seq, cfra, fac, facf, x, y,
+ preview_render_size,
ibuf1, ibuf2, ibuf3, out);
do_alphaover_effect(scene, seq, cfra, fac, facf, x, y,
+ preview_render_size,
ibuf1, ibuf2, ibuf3, out);
}
@@ -3123,6 +3184,11 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
rval.early_out = do_plugin_early_out;
rval.get_default_fac = get_default_fac_fade;
break;
+ case SEQ_MULTICAM:
+ rval.num_inputs = num_inputs_multicam;
+ rval.early_out = early_out_multicam;
+ rval.execute = do_multicam;
+ break;
}
return rval;
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 98dbf83f032..d97e6151a13 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -35,25 +35,26 @@
#include "MEM_guardedalloc.h"
#include "MEM_CacheLimiterC-Api.h"
-#include "DNA_listBase.h"
#include "DNA_sequence_types.h"
#include "DNA_scene_types.h"
#include "DNA_anim_types.h"
+#include "DNA_object_types.h"
+#include "BKE_animsys.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_sequencer.h"
#include "BKE_fcurve.h"
-#include "BKE_utildefines.h"
+#include "BKE_scene.h"
#include "RNA_access.h"
#include "RE_pipeline.h"
+#include "BLI_math.h"
#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
-#include "BLI_threads.h"
#include <pthread.h>
#include "IMB_imbuf.h"
@@ -70,8 +71,6 @@
#endif
/* **** XXX ******** */
-static int seqrectx= 0; /* bad bad global! */
-static int seqrecty= 0;
//static void waitcursor(int val) {}
//static int blender_test_break() {return 0;}
@@ -79,6 +78,8 @@ static int seqrecty= 0;
#define SELECT 1
ListBase seqbase_clipboard;
int seqbase_clipboard_frame;
+SequencerDrawView sequencer_view3d_cb= NULL; /* NULL in background mode */
+
void printf_strip(Sequence *seq)
{
@@ -87,18 +88,27 @@ void printf_strip(Sequence *seq)
fprintf(stderr, "\tseq_tx_set_final_left: %d %d\n\n", seq_tx_get_final_left(seq, 0), seq_tx_get_final_right(seq, 0));
}
-void seqbase_recursive_apply(ListBase *seqbase, int (*apply_func)(Sequence *seq, void *), void *arg)
+int seqbase_recursive_apply(ListBase *seqbase, int (*apply_func)(Sequence *seq, void *), void *arg)
{
Sequence *iseq;
for(iseq= seqbase->first; iseq; iseq= iseq->next) {
- seq_recursive_apply(iseq, apply_func, arg);
+ if(seq_recursive_apply(iseq, apply_func, arg) == -1)
+ return -1; /* bail out */
}
+ return 1;
}
-void seq_recursive_apply(Sequence *seq, int (*apply_func)(Sequence *, void *), void *arg)
+int seq_recursive_apply(Sequence *seq, int (*apply_func)(Sequence *, void *), void *arg)
{
- if(apply_func(seq, arg) && seq->seqbase.first)
- seqbase_recursive_apply(&seq->seqbase, apply_func, arg);
+ int ret= apply_func(seq, arg);
+
+ if(ret == -1)
+ return -1; /* bail out */
+
+ if(ret && seq->seqbase.first)
+ ret = seqbase_recursive_apply(&seq->seqbase, apply_func, arg);
+
+ return ret;
}
/* **********************************************************************
@@ -214,6 +224,8 @@ void seq_free_strip(Strip *strip)
MEM_freeN(strip);
}
+static void seq_free_animdata(Scene *scene, Sequence *seq);
+
void seq_free_sequence(Scene *scene, Sequence *seq)
{
if(seq->strip) seq_free_strip(seq->strip);
@@ -235,6 +247,8 @@ void seq_free_sequence(Scene *scene, Sequence *seq)
if(seq->scene_sound)
sound_remove_scene_sound(scene, seq->scene_sound);
+
+ seq_free_animdata(scene, seq);
}
MEM_freeN(seq);
@@ -425,7 +439,7 @@ void build_seqar(ListBase *seqbase, Sequence ***seqar, int *totseq)
}
static void do_seq_count_cb(ListBase *seqbase, int *totseq,
- int (*test_func)(Sequence * seq))
+ int (*test_func)(Sequence * seq))
{
Sequence *seq;
@@ -443,7 +457,7 @@ static void do_seq_count_cb(ListBase *seqbase, int *totseq,
}
static void do_build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int depth,
- int (*test_func)(Sequence * seq))
+ int (*test_func)(Sequence * seq))
{
Sequence *seq;
@@ -465,7 +479,7 @@ static void do_build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int depth,
}
void build_seqar_cb(ListBase *seqbase, Sequence ***seqar, int *totseq,
- int (*test_func)(Sequence * seq))
+ int (*test_func)(Sequence * seq))
{
Sequence **tseqar;
@@ -503,6 +517,31 @@ void calc_sequence_disp(Scene *scene, Sequence *seq)
seq_update_sound(scene, seq);
}
+static void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq)
+{
+ Sequence *seq;
+
+ /* for sound we go over full meta tree to update bounds of the sound strips,
+ since sound is played outside of evaluating the imbufs, */
+ for(seq=metaseq->seqbase.first; seq; seq=seq->next) {
+ if(seq->type == SEQ_META) {
+ seq_update_sound_bounds_recursive(scene, seq);
+ }
+ else if((seq->type == SEQ_SOUND) || (seq->type == SEQ_SCENE)) {
+ if(seq->scene_sound) {
+ int startofs = seq->startofs;
+ int endofs = seq->endofs;
+ if(seq->startofs + seq->start < metaseq->start + metaseq->startofs)
+ startofs = metaseq->start + metaseq->startofs - seq->start;
+
+ if(seq->start + seq->len - seq->endofs > metaseq->start + metaseq->len - metaseq->endofs)
+ endofs = seq->start + seq->len - metaseq->start - metaseq->len + metaseq->endofs;
+ sound_move_scene_sound(scene, seq->scene_sound, seq->start + startofs, seq->start+seq->len - endofs, startofs);
+ }
+ }
+ }
+}
+
void calc_sequence(Scene *scene, Sequence *seq)
{
Sequence *seqm;
@@ -546,8 +585,8 @@ void calc_sequence(Scene *scene, Sequence *seq)
if(seq->type==SEQ_META) {
seqm= seq->seqbase.first;
if(seqm) {
- min= 1000000;
- max= -1000000;
+ min= MAXFRAME * 2;
+ max= -MAXFRAME * 2;
while(seqm) {
if(seqm->startdisp < min) min= seqm->startdisp;
if(seqm->enddisp > max) max= seqm->enddisp;
@@ -562,14 +601,18 @@ void calc_sequence(Scene *scene, Sequence *seq)
new_tstripdata(seq);
}
}
+ seq_update_sound_bounds_recursive(scene, seq);
}
calc_sequence_disp(scene, seq);
}
}
-void reload_sequence_new_file(Scene *scene, Sequence * seq)
+/* note: caller should run calc_sequence(scene, seq) after */
+void reload_sequence_new_file(Scene *scene, Sequence * seq, int lock_range)
{
char str[FILE_MAXDIR+FILE_MAXFILE];
+ int prev_startdisp, prev_enddisp;
+ /* note: dont rename the strip, will break animation curves */
if (!(seq->type == SEQ_MOVIE || seq->type == SEQ_IMAGE ||
seq->type == SEQ_SOUND ||
@@ -577,17 +620,26 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq)
return;
}
+ if(lock_range) {
+ /* keep so we dont have to move the actual start and end points (only the data) */
+ calc_sequence_disp(scene, seq);
+ prev_startdisp= seq->startdisp;
+ prev_enddisp= seq->enddisp;
+ }
+
+
new_tstripdata(seq);
if (seq->type != SEQ_SCENE && seq->type != SEQ_META &&
- seq->type != SEQ_IMAGE) {
+ seq->type != SEQ_IMAGE) {
BLI_join_dirfile(str, seq->strip->dir, seq->strip->stripdata->name);
- BLI_convertstringcode(str, G.sce);
+ BLI_path_abs(str, G.sce);
}
if (seq->type == SEQ_IMAGE) {
/* Hack? */
- int olen = MEM_allocN_len(seq->strip->stripdata)/sizeof(struct StripElem);
+ size_t olen = MEM_allocN_len(seq->strip->stripdata)/sizeof(struct StripElem);
+
seq->len = olen;
seq->len -= seq->anim_startofs;
seq->len -= seq->anim_endofs;
@@ -622,6 +674,7 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq)
}
seq->strip->len = seq->len;
} else if (seq->type == SEQ_SCENE) {
+ /* 'seq->scenenr' should be replaced with something more reliable */
Scene * sce = G.main->scene.first;
int nr = 1;
@@ -638,9 +691,6 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq)
} else {
sce = seq->scene;
}
-
- BLI_strncpy(seq->name+2, sce->id.name + 2, SEQ_NAME_MAXSTR-2);
- seqbase_unique_name_recursive(&scene->ed->seqbase, seq);
seq->len= seq->scene->r.efra - seq->scene->r.sfra + 1;
seq->len -= seq->anim_startofs;
@@ -653,6 +703,12 @@ void reload_sequence_new_file(Scene *scene, Sequence * seq)
free_proxy_seq(seq);
+ if(lock_range) {
+ seq_tx_set_final_left(seq, prev_startdisp);
+ seq_tx_set_final_right(seq, prev_enddisp);
+ seq_single_fix(seq);
+ }
+
calc_sequence(scene, seq);
}
@@ -739,7 +795,7 @@ static void seqbase_unique_name(ListBase *seqbasep, SeqUniqueInfo *sui)
Sequence *seq;
for(seq=seqbasep->first; seq; seq= seq->next) {
if (sui->seq != seq && strcmp(sui->name_dest, seq->name+2)==0) {
- sprintf(sui->name_dest, "%.18s.%03d", sui->name_src, sui->count++);
+ sprintf(sui->name_dest, "%.17s.%03d", sui->name_src, sui->count++); /*24 - 2 for prefix, -1 for \0 */
sui->match= 1; /* be sure to re-scan */
}
}
@@ -760,12 +816,17 @@ void seqbase_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq)
strcpy(sui.name_src, seq->name+2);
strcpy(sui.name_dest, seq->name+2);
+ sui.count= 1;
+ sui.match= 1; /* assume the worst to start the loop */
+
/* Strip off the suffix */
- if ((dot=strrchr(sui.name_src, '.')))
+ if ((dot=strrchr(sui.name_src, '.'))) {
*dot= '\0';
+ dot++;
- sui.count= 1;
- sui.match= 1; /* assume the worst to start the loop */
+ if(*dot)
+ sui.count= atoi(dot) + 1;
+ }
while(sui.match) {
sui.match= 0;
@@ -796,6 +857,7 @@ static char *give_seqname_by_type(int type)
case SEQ_GLOW: return "Glow";
case SEQ_TRANSFORM: return "Transform";
case SEQ_COLOR: return "Color";
+ case SEQ_MULTICAM: return "Multicam";
case SEQ_SPEED: return "Speed";
default:
return 0;
@@ -887,7 +949,8 @@ static void multibuf(ImBuf *ibuf, float fmul)
}
}
-static void do_effect(Scene *scene, int cfra, Sequence *seq, TStripElem * se)
+static void do_effect(Scene *scene, int cfra, Sequence *seq, TStripElem * se,
+ int render_size)
{
TStripElem *se1, *se2, *se3;
float fac, facf;
@@ -921,7 +984,7 @@ static void do_effect(Scene *scene, int cfra, Sequence *seq, TStripElem * se)
if (early_out == -1) { /* no input needed */
sh.execute(scene, seq, cfra, fac, facf,
- se->ibuf->x, se->ibuf->y,
+ se->ibuf->x, se->ibuf->y, render_size,
0, 0, 0, se->ibuf);
return;
}
@@ -938,7 +1001,7 @@ static void do_effect(Scene *scene, int cfra, Sequence *seq, TStripElem * se)
se3= se->se3;
if ( (se1==0 || se2==0 || se3==0)
- || (se1->ibuf==0 || se2->ibuf==0 || se3->ibuf==0)) {
+ || (se1->ibuf==0 || se2->ibuf==0 || se3->ibuf==0)) {
make_black_ibuf(se->ibuf);
return;
}
@@ -990,13 +1053,13 @@ static void do_effect(Scene *scene, int cfra, Sequence *seq, TStripElem * se)
y= se2->ibuf->y;
if (!se1->ibuf->rect_float && se->ibuf->rect_float) {
- IMB_float_from_rect(se1->ibuf);
+ IMB_float_from_rect_simple(se1->ibuf);
}
if (!se2->ibuf->rect_float && se->ibuf->rect_float) {
- IMB_float_from_rect(se2->ibuf);
+ IMB_float_from_rect_simple(se2->ibuf);
}
if (!se3->ibuf->rect_float && se->ibuf->rect_float) {
- IMB_float_from_rect(se3->ibuf);
+ IMB_float_from_rect_simple(se3->ibuf);
}
if (!se1->ibuf->rect && !se->ibuf->rect_float) {
@@ -1009,7 +1072,8 @@ static void do_effect(Scene *scene, int cfra, Sequence *seq, TStripElem * se)
IMB_rect_from_float(se3->ibuf);
}
- sh.execute(scene, seq, cfra, fac, facf, x, y, se1->ibuf, se2->ibuf, se3->ibuf,
+ sh.execute(scene, seq, cfra, fac, facf, x, y, render_size,
+ se1->ibuf, se2->ibuf, se3->ibuf,
se->ibuf);
}
@@ -1023,7 +1087,7 @@ static int give_stripelem_index(Sequence *seq, int cfra)
/*reverse frame in this sequence */
if(cfra <= seq->start) nr= seq->len-1;
else if(cfra >= seq->start+seq->len-1) nr= 0;
- else nr= (seq->start + seq->len) - cfra;
+ else nr= (seq->start + seq->len - 1) - cfra;
} else {
if(cfra <= seq->start) nr= 0;
else if(cfra >= seq->start+seq->len-1) nr= seq->len-1;
@@ -1055,7 +1119,7 @@ static TStripElem *give_tstripelem(Sequence *seq, int cfra)
se = seq->strip->tstripdata;
if (se == 0 && seq->len > 0) {
se = seq->strip->tstripdata = alloc_tstripdata(seq->len,
- "tstripelems");
+ "tstripelems");
}
nr = give_stripelem_index(seq, cfra);
@@ -1073,7 +1137,7 @@ static TStripElem *give_tstripelem(Sequence *seq, int cfra)
alpha over mode...
*/
if (seq->blend_mode != SEQ_BLEND_REPLACE ||
- (/*seq->ipo && seq->ipo->curve.first &&*/
+ (/*seq->ipo && seq->ipo->curve.first &&*/
(!(seq->type & SEQ_EFFECT) || !seq->seq1))) {
Strip * s = seq->strip;
if (cfra < seq->start) {
@@ -1230,7 +1294,8 @@ static int seq_proxy_get_fname(Scene *scene, Sequence * seq, int cfra, char * na
return FALSE;
}
- if (seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
+ if ((seq->flag & SEQ_USE_PROXY_CUSTOM_DIR)
+ || (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE)) {
strcpy(dir, seq->strip->proxy->dir);
} else {
if (seq->type == SEQ_IMAGE || seq->type == SEQ_MOVIE) {
@@ -1243,7 +1308,7 @@ static int seq_proxy_get_fname(Scene *scene, Sequence * seq, int cfra, char * na
if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
BLI_join_dirfile(name, dir, seq->strip->proxy->file);
- BLI_convertstringcode(name, G.sce);
+ BLI_path_abs(name, G.sce);
return TRUE;
}
@@ -1272,8 +1337,8 @@ static int seq_proxy_get_fname(Scene *scene, Sequence * seq, int cfra, char * na
render_size);
}
- BLI_convertstringcode(name, G.sce);
- BLI_convertstringframe(name, frameno, 0);
+ BLI_path_abs(name, G.sce);
+ BLI_path_frame(name, frameno, 0);
strcat(name, ".jpg");
@@ -1324,9 +1389,9 @@ static struct ImBuf * seq_proxy_fetch(Scene *scene, Sequence * seq, int cfra, in
#if 0
static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
- int build_proxy_run, int render_size);
+ int build_proxy_run, int render_size);
-static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int render_size)
+static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int render_size, int seqrectx, int seqrecty)
{
char name[PROXY_MAXFILE];
int quality;
@@ -1347,7 +1412,7 @@ static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int re
/* that's why it is called custom... */
if (seq->flag & SEQ_USE_PROXY_CUSTOM_FILE) {
return;
- }
+ }
if (!seq_proxy_get_fname(scene, seq, cfra, name, render_size)) {
return;
@@ -1363,7 +1428,8 @@ static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int re
se->ibuf = 0;
}
- do_build_seq_ibuf(scene, seq, se, cfra, TRUE, render_size);
+ do_build_seq_ibuf(scene, seq, se, cfra, TRUE, render_size,
+ seqrectx, seqrecty);
if (!se->ibuf) {
return;
@@ -1397,7 +1463,8 @@ static void seq_proxy_build_frame(Scene *scene, Sequence * seq, int cfra, int re
se->ibuf = 0;
}
-static void seq_proxy_rebuild(Scene *scene, Sequence * seq)
+static void seq_proxy_rebuild(Scene *scene, Sequence * seq, int seqrectx,
+ int seqrecty)
{
int cfra;
float rsize = seq->strip->proxy->size;
@@ -1424,12 +1491,13 @@ static void seq_proxy_rebuild(Scene *scene, Sequence * seq)
sequential order */
if (seq->flag & SEQ_REVERSE_FRAMES) {
for (cfra = seq->enddisp-seq->endstill-1;
- cfra >= seq->startdisp + seq->startstill; cfra--) {
+ cfra >= seq->startdisp + seq->startstill; cfra--) {
TStripElem * tse = give_tstripelem(seq, cfra);
if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
//XXX set_timecursor(cfra);
- seq_proxy_build_frame(scene, seq, cfra, rsize);
+ seq_proxy_build_frame(scene, seq, cfra, rsize,
+ seqrectx, seqrecty);
tse->flag |= STRIPELEM_PREVIEW_DONE;
}
if (blender_test_break()) {
@@ -1438,12 +1506,13 @@ static void seq_proxy_rebuild(Scene *scene, Sequence * seq)
}
} else {
for (cfra = seq->startdisp + seq->startstill;
- cfra < seq->enddisp - seq->endstill; cfra++) {
+ cfra < seq->enddisp - seq->endstill; cfra++) {
TStripElem * tse = give_tstripelem(seq, cfra);
if (!(tse->flag & STRIPELEM_PREVIEW_DONE)) {
//XXX set_timecursor(cfra);
- seq_proxy_build_frame(scene, seq, cfra, rsize);
+ seq_proxy_build_frame(scene, seq, cfra, rsize,
+ seqrectx, seqrecty);
tse->flag |= STRIPELEM_PREVIEW_DONE;
}
if (blender_test_break()) {
@@ -1465,15 +1534,21 @@ static StripColorBalance calc_cb(StripColorBalance * cb_)
StripColorBalance cb = *cb_;
int c;
- if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
- for (c = 0; c < 3; c++) {
- cb.lift[c] = 1.0 - cb.lift[c];
- }
- } else {
+ for (c = 0; c < 3; c++) {
+ cb.lift[c] = 2.0f - cb.lift[c];
+ }
+
+ if(cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) {
for (c = 0; c < 3; c++) {
- cb.lift[c] = -(1.0 - cb.lift[c]);
+ /* tweak to give more subtle results
+ * values above 1.0 are scaled */
+ if(cb.lift[c] > 1.0f)
+ cb.lift[c] = pow(cb.lift[c] - 1.0f, 2.0f) + 1.0f;
+
+ cb.lift[c] = 2.0f - cb.lift[c];
}
}
+
if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) {
for (c = 0; c < 3; c++) {
if (cb.gain[c] != 0.0) {
@@ -1497,25 +1572,27 @@ static StripColorBalance calc_cb(StripColorBalance * cb_)
return cb;
}
+/* note: lift is actually 2-lift */
+MINLINE float color_balance_fl(float in, const float lift, const float gain, const float gamma, const float mul)
+{
+ float x= (((in - 1.0f) * lift) + 1.0f) * gain;
+
+ /* prevent NaN */
+ if (x < 0.f) x = 0.f;
+
+ return powf(x, gamma) * mul;
+}
+
static void make_cb_table_byte(float lift, float gain, float gamma,
- unsigned char * table, float mul)
+ unsigned char * table, float mul)
{
int y;
for (y = 0; y < 256; y++) {
- float v = 1.0 * y / 255;
- v *= gain;
- v += lift;
- v = pow(v, gamma);
- v *= mul;
- if ( v > 1.0) {
- v = 1.0;
- } else if (v < 0.0) {
- v = 0.0;
- }
+ float v= color_balance_fl((float)y * (1.0 / 255.0f), lift, gain, gamma, mul);
+ CLAMP(v, 0.0f, 1.0f);
table[y] = v * 255;
}
-
}
static void make_cb_table_float(float lift, float gain, float gamma,
@@ -1524,11 +1601,7 @@ static void make_cb_table_float(float lift, float gain, float gamma,
int y;
for (y = 0; y < 256; y++) {
- float v = (float) y * 1.0 / 255.0;
- v *= gain;
- v += lift;
- v = pow(v, gamma);
- v *= mul;
+ float v= color_balance_fl((float)y * (1.0 / 255.0f), lift, gain, gamma, mul);
table[y] = v;
}
}
@@ -1573,7 +1646,7 @@ static void color_balance_byte_float(Sequence * seq, TStripElem* se, float mul)
for (c = 0; c < 3; c++) {
make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c],
- cb_tab[c], mul);
+ cb_tab[c], mul);
}
for (i = 0; i < 256; i++) {
@@ -1599,8 +1672,7 @@ static void color_balance_float_float(Sequence * seq, TStripElem* se, float mul)
while (p < e) {
int c;
for (c = 0; c < 3; c++) {
- p[c] = pow(p[c] * cb.gain[c] + cb.lift[c],
- cb.gamma[c]) * mul;
+ p[c]= color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul);
}
p += 4;
}
@@ -1630,24 +1702,24 @@ static void color_balance(Sequence * seq, TStripElem* se, float mul)
- Flip X + Flip Y (could be done afterwards, backward compatibility)
- Promote image to float data (affects pipeline operations afterwards)
- Color balance (is most efficient in the byte -> float
- (future: half -> float should also work fine!)
- case, if done on load, since we can use lookup tables)
+ (future: half -> float should also work fine!)
+ case, if done on load, since we can use lookup tables)
- Premultiply
*/
-static int input_have_to_preprocess(Scene *scene, Sequence * seq, TStripElem* se, int cfra)
+static int input_have_to_preprocess(Scene *scene, Sequence * seq, TStripElem* se, int cfra, int seqrectx, int seqrecty)
{
float mul;
if ((seq->flag & SEQ_FILTERY) ||
- (seq->flag & SEQ_USE_CROP) ||
- (seq->flag & SEQ_USE_TRANSFORM) ||
- (seq->flag & SEQ_FLIPX) ||
- (seq->flag & SEQ_FLIPY) ||
- (seq->flag & SEQ_USE_COLOR_BALANCE) ||
- (seq->flag & SEQ_MAKE_PREMUL) ||
- (se->ibuf->x != seqrectx || se->ibuf->y != seqrecty)) {
+ (seq->flag & SEQ_USE_CROP) ||
+ (seq->flag & SEQ_USE_TRANSFORM) ||
+ (seq->flag & SEQ_FLIPX) ||
+ (seq->flag & SEQ_FLIPY) ||
+ (seq->flag & SEQ_USE_COLOR_BALANCE) ||
+ (seq->flag & SEQ_MAKE_PREMUL) ||
+ (se->ibuf->x != seqrectx || se->ibuf->y != seqrecty)) {
return TRUE;
}
@@ -1665,7 +1737,7 @@ static int input_have_to_preprocess(Scene *scene, Sequence * seq, TStripElem* se
return FALSE;
}
-static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cfra)
+static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cfra, int seqrectx, int seqrecty)
{
float mul;
@@ -1702,8 +1774,8 @@ static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cf
}
if (c.top + c.bottom >= se->ibuf->y ||
- c.left + c.right >= se->ibuf->x ||
- t.xofs >= dx || t.yofs >= dy) {
+ c.left + c.right >= se->ibuf->x ||
+ t.xofs >= dx || t.yofs >= dy) {
make_black_ibuf(se->ibuf);
} else {
ImBuf * i;
@@ -1715,9 +1787,9 @@ static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cf
}
IMB_rectcpy(i, se->ibuf,
- t.xofs, t.yofs,
- c.left, c.bottom,
- sx, sy);
+ t.xofs, t.yofs,
+ c.left, c.bottom,
+ sx, sy);
IMB_freeImBuf(se->ibuf);
@@ -1728,12 +1800,31 @@ static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cf
if(seq->flag & SEQ_FLIPX) {
IMB_flipx(se->ibuf);
}
- if(seq->flag & SEQ_FLIPY) {
- IMB_flipy(se->ibuf);
- }
- if(seq->mul == 0.0) {
- seq->mul = 1.0;
+ if(seq->sat != 1.0f) {
+ /* inline for now, could become an imbuf function */
+ int i;
+ char *rct= (char *)se->ibuf->rect;
+ float *rctf= se->ibuf->rect_float;
+ const float sat= seq->sat;
+ float hsv[3];
+
+ if(rct) {
+ float rgb[3];
+ for (i = se->ibuf->x * se->ibuf->y; i > 0; i--, rct+=4) {
+ rgb_byte_to_float(rct, rgb);
+ rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
+ hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rgb, rgb+1, rgb+2);
+ rgb_float_to_byte(rgb, rct);
+ }
+ }
+
+ if(rctf) {
+ for (i = se->ibuf->x * se->ibuf->y; i > 0; i--, rctf+=4) {
+ rgb_to_hsv(rctf[0], rctf[1], rctf[2], hsv, hsv+1, hsv+2);
+ hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rctf, rctf+1, rctf+2);
+ }
+ }
}
mul = seq->mul;
@@ -1748,21 +1839,9 @@ static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cf
}
if(seq->flag & SEQ_MAKE_FLOAT) {
- if (!se->ibuf->rect_float) {
- if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) {
- IMB_float_from_rect(se->ibuf);
- } else {
- int profile = IB_PROFILE_NONE;
-
- /* no color management:
- * don't disturb the existing profiles */
- SWAP(int, se->ibuf->profile, profile);
+ if (!se->ibuf->rect_float)
+ IMB_float_from_rect_simple(se->ibuf);
- IMB_float_from_rect(se->ibuf);
-
- SWAP(int, se->ibuf->profile, profile);
- }
- }
if (se->ibuf->rect) {
imb_freerectImBuf(se->ibuf);
}
@@ -1774,7 +1853,7 @@ static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cf
if(seq->flag & SEQ_MAKE_PREMUL) {
if(se->ibuf->depth == 32 && se->ibuf->zbuf == 0) {
- converttopremul(se->ibuf);
+ IMB_premultiply_alpha(se->ibuf);
}
}
@@ -1782,7 +1861,7 @@ static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cf
if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) {
if(scene->r.mode & R_OSA) {
IMB_scaleImBuf(se->ibuf,
- (short)seqrectx, (short)seqrecty);
+ (short)seqrectx, (short)seqrecty);
} else {
IMB_scalefastImBuf(se->ibuf,
(short)seqrectx, (short)seqrecty);
@@ -1792,7 +1871,8 @@ static void input_preprocess(Scene *scene, Sequence *seq, TStripElem *se, int cf
/* test if image too small or discarded from cache: reload */
-static void test_and_auto_discard_ibuf(TStripElem * se)
+static void test_and_auto_discard_ibuf(TStripElem * se,
+ int seqrectx, int seqrecty)
{
if (se->ibuf) {
if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty
@@ -1817,14 +1897,14 @@ static void test_and_auto_discard_ibuf_stills(Strip * strip)
{
if (strip->ibuf_startstill) {
if (!strip->ibuf_startstill->rect &&
- !strip->ibuf_startstill->rect_float) {
+ !strip->ibuf_startstill->rect_float) {
IMB_freeImBuf(strip->ibuf_startstill);
strip->ibuf_startstill = 0;
}
}
if (strip->ibuf_endstill) {
if (!strip->ibuf_endstill->rect &&
- !strip->ibuf_endstill->rect_float) {
+ !strip->ibuf_endstill->rect_float) {
IMB_freeImBuf(strip->ibuf_endstill);
strip->ibuf_endstill = 0;
}
@@ -1840,8 +1920,8 @@ static void copy_from_ibuf_still(Sequence * seq, TStripElem * se)
se->ibuf = IMB_dupImBuf(seq->strip->ibuf_startstill);
}
if (se->nr == seq->len - 1
- && (seq->len != 1)
- && seq->strip->ibuf_endstill) {
+ && (seq->len != 1)
+ && seq->strip->ibuf_endstill) {
IMB_cache_limiter_touch(seq->strip->ibuf_endstill);
se->ibuf = IMB_dupImBuf(seq->strip->ibuf_endstill);
@@ -1933,16 +2013,18 @@ static void check_limiter_refcount_comp(const char * func, TStripElem *se)
}
}
-static TStripElem* do_build_seq_array_recursively(Scene *scene,
- ListBase *seqbasep, int cfra, int chanshown, int render_size);
+static TStripElem* do_build_seq_array_recursively(
+ Scene *scene,
+ ListBase *seqbasep, int cfra, int chanshown, int render_size,
+ int seqrectx, int seqrecty);
static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int cfra,
- int build_proxy_run, int render_size)
+ int build_proxy_run, int render_size, int seqrectx, int seqrecty)
{
char name[FILE_MAXDIR+FILE_MAXFILE];
int use_limiter = TRUE;
- test_and_auto_discard_ibuf(se);
+ test_and_auto_discard_ibuf(se, seqrectx, seqrecty);
test_and_auto_discard_ibuf_stills(seq->strip);
if(seq->type == SEQ_META) {
@@ -1961,7 +2043,7 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
if(!se->ibuf && seq->seqbase.first) {
meta_se = do_build_seq_array_recursively(scene,
&seq->seqbase, seq->start + se->nr, 0,
- render_size);
+ render_size, seqrectx, seqrecty);
check_limiter_refcount("do_build_seq_ibuf: for META", meta_se);
}
@@ -1971,8 +2053,9 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
if(!se->ibuf && meta_se) {
se->ibuf = meta_se->ibuf_comp;
if(se->ibuf &&
- (!input_have_to_preprocess(scene, seq, se, cfra) ||
- build_proxy_run)) {
+ (!input_have_to_preprocess(scene, seq, se, cfra,
+ seqrectx, seqrecty) ||
+ build_proxy_run)) {
IMB_refImBuf(se->ibuf);
if (build_proxy_run) {
IMB_cache_limiter_unref(se->ibuf);
@@ -1996,7 +2079,8 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
}
if (use_preprocess) {
- input_preprocess(scene, seq, se, cfra);
+ input_preprocess(scene, seq, se, cfra, seqrectx,
+ seqrecty);
}
} else if(seq->type & SEQ_EFFECT) {
int use_preprocess = FALSE;
@@ -2018,11 +2102,12 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
else
se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
- do_effect(scene, cfra, seq, se);
- if (input_have_to_preprocess(scene, seq, se, cfra) &&
- !build_proxy_run) {
+ do_effect(scene, cfra, seq, se, render_size);
+ if (input_have_to_preprocess(scene, seq, se, cfra,
+ seqrectx, seqrecty) &&
+ !build_proxy_run) {
if ((se->se1 && (se->ibuf == se->se1->ibuf)) ||
- (se->se2 && (se->ibuf == se->se2->ibuf))) {
+ (se->se2 && (se->ibuf == se->se2->ibuf))) {
struct ImBuf * i
= IMB_dupImBuf(se->ibuf);
@@ -2034,26 +2119,27 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
}
}
if (use_preprocess) {
- input_preprocess(scene, seq, se, cfra);
+ input_preprocess(scene, seq, se, cfra, seqrectx,
+ seqrecty);
}
} else if(seq->type == SEQ_IMAGE) {
if(se->ok == STRIPELEM_OK && se->ibuf == 0) {
StripElem * s_elem = give_stripelem(seq, cfra);
BLI_join_dirfile(name, seq->strip->dir, s_elem->name);
- BLI_convertstringcode(name, G.sce);
+ BLI_path_abs(name, G.sce);
if (!build_proxy_run) {
se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
}
copy_from_ibuf_still(seq, se);
- if (!se->ibuf) {
- se->ibuf= IMB_loadiffname(
- name, IB_rect);
+ if (se->ibuf==NULL && (se->ibuf= IMB_loadiffname(name, IB_rect))) {
/* we don't need both (speed reasons)! */
- if (se->ibuf &&
- se->ibuf->rect_float && se->ibuf->rect) {
+ if (se->ibuf->rect_float && se->ibuf->rect)
imb_freerectImBuf(se->ibuf);
- }
+
+ /* all sequencer color is done in SRGB space, linear gives odd crossfades */
+ if(se->ibuf->profile == IB_PROFILE_LINEAR_RGB)
+ IMB_convert_profile(se->ibuf, IB_PROFILE_NONE);
copy_to_ibuf_still(seq, se);
}
@@ -2061,7 +2147,8 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
if(se->ibuf == 0) {
se->ok = STRIPELEM_FAILED;
} else if (!build_proxy_run) {
- input_preprocess(scene, seq, se, cfra);
+ input_preprocess(scene, seq, se, cfra,
+ seqrectx, seqrecty);
}
}
} else if(seq->type == SEQ_MOVIE) {
@@ -2074,7 +2161,7 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
if (se->ibuf == 0) {
if(seq->anim==0) {
BLI_join_dirfile(name, seq->strip->dir, seq->strip->stripdata->name);
- BLI_convertstringcode(name, G.sce);
+ BLI_path_abs(name, G.sce);
seq->anim = openanim(
name, IB_rect |
@@ -2086,8 +2173,8 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
se->ibuf = IMB_anim_absolute(seq->anim, se->nr + seq->anim_startofs);
/* we don't need both (speed reasons)! */
if (se->ibuf
- && se->ibuf->rect_float
- && se->ibuf->rect) {
+ && se->ibuf->rect_float
+ && se->ibuf->rect) {
imb_freerectImBuf(se->ibuf);
}
@@ -2098,13 +2185,12 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
if(se->ibuf == 0) {
se->ok = STRIPELEM_FAILED;
} else if (!build_proxy_run) {
- input_preprocess(scene, seq, se, cfra);
+ input_preprocess(scene, seq, se, cfra,
+ seqrectx, seqrecty);
}
}
} else if(seq->type == SEQ_SCENE) { // scene can be NULL after deletions
Scene *sce= seq->scene;// *oldsce= scene;
- Render *re;
- RenderResult rres;
int have_seq= FALSE;
int sce_valid= FALSE;
@@ -2116,72 +2202,103 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
if (se->ibuf == NULL && sce_valid && !build_proxy_run) {
se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size);
if (se->ibuf) {
- input_preprocess(scene, seq, se, cfra);
+ input_preprocess(scene, seq, se, cfra,
+ seqrectx, seqrecty);
}
}
if (se->ibuf == NULL && sce_valid) {
copy_from_ibuf_still(seq, se);
if (se->ibuf) {
- input_preprocess(scene, seq, se, cfra);
+ input_preprocess(scene, seq, se, cfra,
+ seqrectx, seqrecty);
}
}
if (!sce_valid) {
se->ok = STRIPELEM_FAILED;
- } else if (se->ibuf==NULL && sce_valid) {
- int oldcfra;
+ }
+ else if (se->ibuf==NULL && sce_valid) {
+ int frame= seq->sfra + se->nr + seq->anim_startofs;
+ int oldcfra = seq->scene->r.cfra;
+ Object *oldcamera= seq->scene->camera;
+ ListBase oldmarkers;
+
/* Hack! This function can be called from do_render_seq(), in that case
- the seq->scene can already have a Render initialized with same name,
+ the seq->scene can already have a Render initialized with same name,
so we have to use a default name. (compositor uses scene name to
find render).
However, when called from within the UI (image preview in sequencer)
we do want to use scene Render, that way the render result is defined
- for display in render/imagewindow
+ for display in render/imagewindow
- Hmm, don't see, why we can't do that all the time,
+ Hmm, don't see, why we can't do that all the time,
and since G.rendering is uhm, gone... (Peter)
*/
- int rendering = 1;
+ int rendering = G.rendering;
int doseq;
+ int doseq_gl= G.rendering ? /*(scene->r.seq_flag & R_SEQ_GL_REND)*/ 0 : (scene->r.seq_flag & R_SEQ_GL_PREV);
- oldcfra = seq->scene->r.cfra;
-
- if(rendering)
- re= RE_NewRender(" do_build_seq_ibuf", RE_SLOT_DEFAULT);
- else
- re= RE_NewRender(sce->id.name, RE_SLOT_VIEW);
-
/* prevent eternal loop */
doseq= scene->r.scemode & R_DOSEQ;
scene->r.scemode &= ~R_DOSEQ;
-
- RE_BlenderFrame(re, sce, NULL,
- seq->sfra+se->nr+seq->anim_startofs);
-
- RE_AcquireResultImage(re, &rres);
-
- if(rres.rectf) {
- se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
- memcpy(se->ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
- if(rres.rectz) {
- addzbuffloatImBuf(se->ibuf);
- memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
- }
- } else if (rres.rect32) {
- se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
- memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
+
+ seq->scene->r.cfra= frame;
+ if(seq->scene_camera) seq->scene->camera= seq->scene_camera;
+ else scene_camera_switch_update(seq->scene);
+
+#ifdef DURIAN_CAMERA_SWITCH
+ /* stooping to new low's in hackyness :( */
+ oldmarkers= seq->scene->markers;
+ seq->scene->markers.first= seq->scene->markers.last= NULL;
+#endif
+
+ if(sequencer_view3d_cb && doseq_gl && (seq->scene == scene || have_seq==0) && seq->scene->camera) {
+ /* opengl offscreen render */
+ scene_update_for_newframe(seq->scene, seq->scene->lay);
+ se->ibuf= sequencer_view3d_cb(seq->scene, seqrectx, seqrecty, scene->r.seq_prev_type);
}
+ else {
+ Render *re;
+ RenderResult rres;
- RE_ReleaseResultImage(re);
-
- // BIF_end_render_callbacks();
+ if(rendering)
+ re= RE_NewRender(" do_build_seq_ibuf");
+ else
+ re= RE_NewRender(sce->id.name);
+
+ RE_BlenderFrame(re, sce, NULL, sce->lay, frame);
+
+ RE_AcquireResultImage(re, &rres);
+
+ if(rres.rectf) {
+ se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat, 0);
+ memcpy(se->ibuf->rect_float, rres.rectf, 4*sizeof(float)*rres.rectx*rres.recty);
+ if(rres.rectz) {
+ addzbuffloatImBuf(se->ibuf);
+ memcpy(se->ibuf->zbuf_float, rres.rectz, sizeof(float)*rres.rectx*rres.recty);
+ }
+ } else if (rres.rect32) {
+ se->ibuf= IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect, 0);
+ memcpy(se->ibuf->rect, rres.rect32, 4*rres.rectx*rres.recty);
+ }
+
+ RE_ReleaseResultImage(re);
+
+ // BIF_end_render_callbacks();
+ }
/* restore */
scene->r.scemode |= doseq;
-
+
seq->scene->r.cfra = oldcfra;
+ seq->scene->camera= oldcamera;
+
+#ifdef DURIAN_CAMERA_SWITCH
+ /* stooping to new low's in hackyness :( */
+ seq->scene->markers= oldmarkers;
+#endif
copy_to_ibuf_still(seq, se);
@@ -2189,7 +2306,8 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
if(se->ibuf == NULL) {
se->ok = STRIPELEM_FAILED;
} else {
- input_preprocess(scene, seq, se, cfra);
+ input_preprocess(scene, seq, se, cfra,
+ seqrectx, seqrecty);
}
}
@@ -2204,9 +2322,9 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
}
}
-static TStripElem* do_build_seq_recursively(Scene *scene, Sequence *seq, int cfra, int render_size);
+static TStripElem* do_build_seq_recursively(Scene *scene, Sequence *seq, int cfra, int render_size, int seqrectx, int seqrecty);
-static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *se, int cfra, int render_size)
+static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *se, int cfra, int render_size, int seqrectx, int seqrecty)
{
float fac, facf;
struct SeqEffectHandle sh = get_sequence_effect(seq);
@@ -2239,22 +2357,22 @@ static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *s
/* no input needed */
break;
case 0:
- se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
- se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
+ se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size, seqrectx, seqrecty);
+ se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size, seqrectx, seqrecty);
if (seq->seq3) {
- se->se3 = do_build_seq_recursively(scene, seq->seq3, cfra, render_size);
+ se->se3 = do_build_seq_recursively(scene, seq->seq3, cfra, render_size, seqrectx, seqrecty);
}
break;
case 1:
- se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size);
+ se->se1 = do_build_seq_recursively(scene, seq->seq1, cfra, render_size, seqrectx, seqrecty);
break;
case 2:
- se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size);
+ se->se2 = do_build_seq_recursively(scene, seq->seq2, cfra, render_size, seqrectx, seqrecty);
break;
}
- do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
+ do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size, seqrectx, seqrecty);
/* children are not needed anymore ... */
@@ -2270,7 +2388,7 @@ static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *s
check_limiter_refcount("do_effect_seq_recursively", se);
}
-static TStripElem* do_build_seq_recursively_impl(Scene *scene, Sequence * seq, int cfra, int render_size)
+static TStripElem* do_build_seq_recursively_impl(Scene *scene, Sequence * seq, int cfra, int render_size, int seqrectx, int seqrecty)
{
TStripElem *se;
@@ -2278,9 +2396,9 @@ static TStripElem* do_build_seq_recursively_impl(Scene *scene, Sequence * seq, i
if(se) {
if (seq->type & SEQ_EFFECT) {
- do_effect_seq_recursively(scene, seq, se, cfra, render_size);
+ do_effect_seq_recursively(scene, seq, se, cfra, render_size, seqrectx, seqrecty);
} else {
- do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size);
+ do_build_seq_ibuf(scene, seq, se, cfra, FALSE, render_size, seqrectx, seqrecty);
}
}
return se;
@@ -2294,7 +2412,7 @@ instead of faking using the blend code below...
*/
-static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra, int render_size)
+static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra, int render_size, int seqrectx, int seqrecty)
{
SpeedControlVars * s = (SpeedControlVars *)seq->effectdata;
int nr = cfra - seq->start;
@@ -2319,11 +2437,11 @@ static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra
}
if (cfra_left == cfra_right ||
- (s->flags & SEQ_SPEED_BLEND) == 0) {
- test_and_auto_discard_ibuf(se);
+ (s->flags & SEQ_SPEED_BLEND) == 0) {
+ test_and_auto_discard_ibuf(se, seqrectx, seqrecty);
if (se->ibuf == NULL) {
- se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
+ se1 = do_build_seq_recursively(scene, seq->seq1, cfra_left, render_size, seqrectx, seqrecty);
if((se1 && se1->ibuf && se1->ibuf->rect_float))
se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
@@ -2355,8 +2473,8 @@ static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra
}
if (se->ibuf == NULL) {
- se1 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_left, render_size);
- se2 = do_build_seq_recursively_impl(scene, seq->seq1, cfra_right, render_size);
+ se1 = do_build_seq_recursively(scene, seq->seq1, cfra_left, render_size, seqrectx, seqrecty);
+ se2 = do_build_seq_recursively(scene, seq->seq1, cfra_right, render_size, seqrectx, seqrecty);
if((se1 && se1->ibuf && se1->ibuf->rect_float))
se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
@@ -2372,6 +2490,7 @@ static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra
f_cfra - (float) cfra_left,
f_cfra - (float) cfra_left,
se->ibuf->x, se->ibuf->y,
+ render_size,
se1->ibuf, se2->ibuf, 0, se->ibuf);
}
}
@@ -2408,13 +2527,18 @@ static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra
*
*/
-static TStripElem* do_build_seq_recursively(Scene *scene, Sequence * seq, int cfra, int render_size)
+static TStripElem* do_build_seq_recursively(Scene *scene, Sequence * seq, int cfra, int render_size, int seqrectx, int seqrecty)
{
TStripElem *se;
+
+ /* BAD HACK! Seperate handling for speed effects needed, since
+ a) you can't just fetch a different cfra within an effect strip
+ b) we have to blend two frames, and CFRA is not float...
+ */
if (seq->type == SEQ_SPEED) {
- se = do_handle_speed_effect(scene, seq, cfra, render_size);
+ se = do_handle_speed_effect(scene, seq, cfra, render_size, seqrectx, seqrecty);
} else {
- se = do_build_seq_recursively_impl(scene, seq, cfra, render_size);
+ se = do_build_seq_recursively_impl(scene, seq, cfra, render_size, seqrectx, seqrecty);
}
check_limiter_refcount("do_build_seq_recursively", se);
@@ -2422,15 +2546,53 @@ static TStripElem* do_build_seq_recursively(Scene *scene, Sequence * seq, int cf
return se;
}
-static TStripElem* do_build_seq_array_recursively(Scene *scene,
- ListBase *seqbasep, int cfra, int chanshown, int render_size)
+static int seq_must_swap_input_in_blend_mode(Sequence * seq)
+{
+ int swap_input = FALSE;
+
+ /* bad hack, to fix crazy input ordering of
+ those two effects */
+
+ if (seq->blend_mode == SEQ_ALPHAOVER ||
+ seq->blend_mode == SEQ_ALPHAUNDER ||
+ seq->blend_mode == SEQ_OVERDROP) {
+ swap_input = TRUE;
+ }
+
+ return swap_input;
+}
+
+static int seq_get_early_out_for_blend_mode(Sequence * seq)
+{
+ struct SeqEffectHandle sh = get_sequence_blend(seq);
+ float facf = seq->blend_opacity / 100.0;
+ int early_out = sh.early_out(seq, facf, facf);
+
+ if (early_out < 1) {
+ return early_out;
+ }
+
+ if (seq_must_swap_input_in_blend_mode(seq)) {
+ if (early_out == 2) {
+ return 1;
+ } else if (early_out == 1) {
+ return 2;
+ }
+ }
+ return early_out;
+}
+
+static TStripElem* do_build_seq_array_recursively(
+ Scene *scene, ListBase *seqbasep, int cfra, int chanshown,
+ int render_size, int seqrectx, int seqrecty)
{
Sequence* seq_arr[MAXSEQ+1];
int count;
int i;
TStripElem* se = 0;
- count = get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr);
+ count = get_shown_sequences(seqbasep, cfra, chanshown,
+ (Sequence **)&seq_arr);
if (!count) {
return 0;
@@ -2442,7 +2604,15 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene,
return 0;
}
- test_and_auto_discard_ibuf(se);
+#if 0 /* commentind since this breaks keyframing, since it resets the value on draw */
+ if(scene->r.cfra != cfra) {
+ // XXX for prefetch and overlay offset!..., very bad!!!
+ AnimData *adt= BKE_animdata_from_id(&scene->id);
+ BKE_animsys_evaluate_animdata(&scene->id, adt, cfra, ADT_RECALC_ANIM);
+ }
+#endif
+
+ test_and_auto_discard_ibuf(se, seqrectx, seqrecty);
if (se->ibuf_comp != 0) {
IMB_cache_limiter_insert(se->ibuf_comp);
@@ -2453,7 +2623,9 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene,
if(count == 1) {
- se = do_build_seq_recursively(scene, seq_arr[0], cfra, render_size);
+ se = do_build_seq_recursively(scene, seq_arr[0],
+ cfra, render_size,
+ seqrectx, seqrecty);
if (se->ibuf) {
se->ibuf_comp = se->ibuf;
IMB_refImBuf(se->ibuf_comp);
@@ -2465,18 +2637,19 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene,
for (i = count - 1; i >= 0; i--) {
int early_out;
Sequence * seq = seq_arr[i];
- struct SeqEffectHandle sh;
- float facf;
se = give_tstripelem(seq, cfra);
- test_and_auto_discard_ibuf(se);
+ test_and_auto_discard_ibuf(se, seqrectx, seqrecty);
if (se->ibuf_comp != 0) {
break;
}
if (seq->blend_mode == SEQ_BLEND_REPLACE) {
- do_build_seq_recursively(scene, seq, cfra, render_size);
+ do_build_seq_recursively(
+ scene, seq, cfra, render_size,
+ seqrectx, seqrecty);
+
if (se->ibuf) {
se->ibuf_comp = se->ibuf;
IMB_refImBuf(se->ibuf);
@@ -2491,16 +2664,15 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene,
break;
}
- sh = get_sequence_blend(seq);
-
- facf = seq->blend_opacity / 100.0;
-
- early_out = sh.early_out(seq, facf, facf);
+ early_out = seq_get_early_out_for_blend_mode(seq);
switch (early_out) {
case -1:
case 2:
- do_build_seq_recursively(scene, seq, cfra, render_size);
+ do_build_seq_recursively(
+ scene, seq, cfra, render_size,
+ seqrectx, seqrecty);
+
if (se->ibuf) {
se->ibuf_comp = se->ibuf;
IMB_refImBuf(se->ibuf_comp);
@@ -2524,7 +2696,10 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene,
}
break;
case 0:
- do_build_seq_recursively(scene, seq, cfra, render_size);
+ do_build_seq_recursively(
+ scene, seq, cfra, render_size,
+ seqrectx, seqrecty);
+
if (!se->ibuf) {
se->ibuf = IMB_allocImBuf(
(short)seqrectx, (short)seqrecty,
@@ -2554,20 +2729,19 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene,
TStripElem* se2 = give_tstripelem(seq_arr[i], cfra);
float facf = seq->blend_opacity / 100.0;
-
- int early_out = sh.early_out(seq, facf, facf);
+ int swap_input = seq_must_swap_input_in_blend_mode(seq);
+ int early_out = seq_get_early_out_for_blend_mode(seq);
switch (early_out) {
case 0: {
int x= se2->ibuf->x;
int y= se2->ibuf->y;
- int swap_input = FALSE;
if(se1->ibuf_comp == NULL)
continue;
if (se1->ibuf_comp->rect_float ||
- se2->ibuf->rect_float) {
+ se2->ibuf->rect_float) {
se2->ibuf_comp = IMB_allocImBuf(
(short)seqrectx, (short)seqrecty,
32, IB_rectfloat, 0);
@@ -2579,40 +2753,31 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene,
if (!se1->ibuf_comp->rect_float &&
- se2->ibuf_comp->rect_float) {
- IMB_float_from_rect(se1->ibuf_comp);
+ se2->ibuf_comp->rect_float) {
+ IMB_float_from_rect_simple(se1->ibuf_comp);
}
if (!se2->ibuf->rect_float &&
- se2->ibuf_comp->rect_float) {
- IMB_float_from_rect(se2->ibuf);
+ se2->ibuf_comp->rect_float) {
+ IMB_float_from_rect_simple(se2->ibuf);
}
if (!se1->ibuf_comp->rect &&
- !se2->ibuf_comp->rect_float) {
+ !se2->ibuf_comp->rect_float) {
IMB_rect_from_float(se1->ibuf_comp);
}
if (!se2->ibuf->rect &&
- !se2->ibuf_comp->rect_float) {
+ !se2->ibuf_comp->rect_float) {
IMB_rect_from_float(se2->ibuf);
}
- /* bad hack, to fix crazy input ordering of
- those two effects */
-
- if (seq->blend_mode == SEQ_ALPHAOVER ||
- seq->blend_mode == SEQ_ALPHAUNDER ||
- seq->blend_mode == SEQ_OVERDROP) {
- swap_input = TRUE;
- }
-
if (swap_input) {
sh.execute(scene, seq, cfra,
- facf, facf, x, y,
+ facf, facf, x, y, render_size,
se2->ibuf, se1->ibuf_comp, 0,
se2->ibuf_comp);
} else {
sh.execute(scene, seq, cfra,
- facf, facf, x, y,
+ facf, facf, x, y, render_size,
se1->ibuf_comp, se2->ibuf, 0,
se2->ibuf_comp);
}
@@ -2627,7 +2792,7 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene,
break;
}
case 1: {
- se2->ibuf_comp = se1->ibuf;
+ se2->ibuf_comp = se1->ibuf_comp;
if(se2->ibuf_comp)
IMB_refImBuf(se2->ibuf_comp);
@@ -2663,10 +2828,7 @@ static ImBuf *give_ibuf_seq_impl(Scene *scene, int rectx, int recty, int cfra, i
seqbasep= ed->seqbasep;
}
- seqrectx= rectx; /* bad bad global! */
- seqrecty= recty;
-
- se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown, render_size);
+ se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown, render_size, rectx, recty);
if(!se) {
return 0;
@@ -2677,14 +2839,31 @@ static ImBuf *give_ibuf_seq_impl(Scene *scene, int rectx, int recty, int cfra, i
return se->ibuf_comp;
}
+ImBuf *give_ibuf_seqbase(struct Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size, ListBase *seqbasep)
+{
+ TStripElem *se;
+
+ se = do_build_seq_array_recursively(scene, seqbasep, cfra, chanshown, render_size, rectx, recty);
+
+ if(!se) {
+ return 0;
+ }
+
+ check_limiter_refcount_comp("give_ibuf_seqbase", se);
+
+ if (se->ibuf_comp) {
+ IMB_cache_limiter_unref(se->ibuf_comp);
+ }
+
+ return se->ibuf_comp;
+}
+
+
ImBuf *give_ibuf_seq_direct(Scene *scene, int rectx, int recty, int cfra, int render_size, Sequence *seq)
{
TStripElem* se;
- seqrectx= rectx; /* bad bad global! */
- seqrecty= recty;
-
- se = do_build_seq_recursively(scene, seq, cfra, render_size);
+ se = do_build_seq_recursively(scene, seq, cfra, render_size, rectx, recty);
if(!se) {
return 0;
@@ -2737,7 +2916,7 @@ static pthread_cond_t wakeup_cond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t frame_done_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t frame_done_cond = PTHREAD_COND_INITIALIZER;
-static volatile int seq_thread_shutdown = FALSE;
+static volatile int seq_thread_shutdown = TRUE;
static volatile int seq_last_given_monoton_cfra = 0;
static int monoton_cfra = 0;
@@ -2888,8 +3067,8 @@ static void seq_stop_threads()
seq_thread_shutdown = TRUE;
- pthread_cond_broadcast(&wakeup_cond);
- pthread_mutex_unlock(&wakeup_lock);
+ pthread_cond_broadcast(&wakeup_cond);
+ pthread_mutex_unlock(&wakeup_lock);
for(tslot = running_threads.first; tslot; tslot= tslot->next) {
pthread_join(tslot->pthread, NULL);
@@ -2987,10 +3166,10 @@ ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int
for (e = prefetch_done.first; e; e = e->next) {
if (cfra == e->cfra &&
- chanshown == e->chanshown &&
- rectx == e->rectx &&
- recty == e->recty &&
- render_size == e->render_size) {
+ chanshown == e->chanshown &&
+ rectx == e->rectx &&
+ recty == e->recty &&
+ render_size == e->render_size) {
success = TRUE;
found_something = TRUE;
break;
@@ -3000,10 +3179,10 @@ ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int
if (!e) {
for (e = prefetch_wait.first; e; e = e->next) {
if (cfra == e->cfra &&
- chanshown == e->chanshown &&
- rectx == e->rectx &&
- recty == e->recty &&
- render_size == e->render_size) {
+ chanshown == e->chanshown &&
+ rectx == e->rectx &&
+ recty == e->recty &&
+ render_size == e->render_size) {
found_something = TRUE;
break;
}
@@ -3014,13 +3193,13 @@ ImBuf *give_ibuf_seq_threaded(Scene *scene, int rectx, int recty, int cfra, int
PrefetchThread *tslot;
for(tslot = running_threads.first;
- tslot; tslot= tslot->next) {
+ tslot; tslot= tslot->next) {
if (tslot->current &&
- cfra == tslot->current->cfra &&
- chanshown == tslot->current->chanshown &&
- rectx == tslot->current->rectx &&
- recty == tslot->current->recty &&
- render_size== tslot->current->render_size){
+ cfra == tslot->current->cfra &&
+ chanshown == tslot->current->chanshown &&
+ rectx == tslot->current->rectx &&
+ recty == tslot->current->recty &&
+ render_size== tslot->current->render_size){
found_something = TRUE;
break;
}
@@ -3092,19 +3271,19 @@ static void free_imbuf_seq_except(Scene *scene, int cfra)
TStripElem * curelem = give_tstripelem(seq, cfra);
for(a = 0, se = seq->strip->tstripdata;
- a < seq->strip->len && se; a++, se++) {
+ a < seq->strip->len && se; a++, se++) {
if(se != curelem) {
free_imbuf_strip_elem(se);
}
}
for(a = 0, se = seq->strip->tstripdata_startstill;
- a < seq->strip->startstill && se; a++, se++) {
+ a < seq->strip->startstill && se; a++, se++) {
if(se != curelem) {
free_imbuf_strip_elem(se);
}
}
for(a = 0, se = seq->strip->tstripdata_endstill;
- a < seq->strip->endstill && se; a++, se++) {
+ a < seq->strip->endstill && se; a++, se++) {
if(se != curelem) {
free_imbuf_strip_elem(se);
}
@@ -3163,15 +3342,15 @@ void free_imbuf_seq(Scene *scene, ListBase * seqbase, int check_mem_usage)
for(seq= seqbase->first; seq; seq= seq->next) {
if(seq->strip) {
for(a = 0, se = seq->strip->tstripdata;
- a < seq->strip->len && se; a++, se++) {
+ a < seq->strip->len && se; a++, se++) {
free_imbuf_strip_elem(se);
}
for(a = 0, se = seq->strip->tstripdata_startstill;
- a < seq->strip->startstill && se; a++, se++) {
+ a < seq->strip->startstill && se; a++, se++) {
free_imbuf_strip_elem(se);
}
for(a = 0, se = seq->strip->tstripdata_endstill;
- a < seq->strip->endstill && se; a++, se++) {
+ a < seq->strip->endstill && se; a++, se++) {
free_imbuf_strip_elem(se);
}
if(seq->strip->ibuf_startstill) {
@@ -3355,7 +3534,8 @@ void seq_tx_set_final_right(Sequence *seq, int val)
since they work a bit differently to normal image seq's (during transform) */
int seq_single_check(Sequence *seq)
{
- if ( seq->len==1 && (seq->type == SEQ_IMAGE || seq->type == SEQ_COLOR))
+ if ( seq->len==1 && (seq->type == SEQ_IMAGE || seq->type == SEQ_COLOR
+ || seq->type == SEQ_MULTICAM))
return 1;
else
return 0;
@@ -3639,7 +3819,7 @@ static void seq_update_muting_recursive(Scene *scene, ListBase *seqbasep, Sequen
seq_update_muting_recursive(scene, &seq->seqbase, metaseq, seqmute);
}
- else if(seq->type == SEQ_SOUND) {
+ else if((seq->type == SEQ_SOUND) || (seq->type == SEQ_SCENE)) {
if(seq->scene_sound) {
sound_mute_scene_sound(scene, seq->scene_sound, seqmute);
}
@@ -3678,6 +3858,57 @@ ListBase *seq_seqbase(ListBase *seqbase, Sequence *seq)
return NULL;
}
+int seq_swap(Sequence *seq_a, Sequence *seq_b)
+{
+ char name[sizeof(seq_a->name)];
+
+ if(seq_a->len != seq_b->len)
+ return 0;
+
+ /* type checking, could be more advanced but disalow sound vs non-sound copy */
+ if(seq_a->type != seq_b->type) {
+ if(seq_a->type == SEQ_SOUND || seq_b->type == SEQ_SOUND) {
+ return 0;
+ }
+
+ /* disallow effects to swap with non-effects strips */
+ if((seq_a->type & SEQ_EFFECT) != (seq_b->type & SEQ_EFFECT)) {
+ return 0;
+ }
+
+ if((seq_a->type & SEQ_EFFECT) && (seq_b->type & SEQ_EFFECT)) {
+ if(get_sequence_effect_num_inputs(seq_a->type) != get_sequence_effect_num_inputs(seq_b->type)) {
+ return 0;
+ }
+ }
+ }
+
+ SWAP(Sequence, *seq_a, *seq_b);
+
+ /* swap back names so animation fcurves dont get swapped */
+ strcpy(name, seq_a->name+2);
+ strcpy(seq_a->name+2, seq_b->name+2);
+ strcpy(seq_b->name+2, name);
+
+ /* swap back opacity, and overlay mode */
+ SWAP(int, seq_a->blend_mode, seq_b->blend_mode);
+ SWAP(float, seq_a->blend_opacity, seq_b->blend_opacity);
+
+
+ SWAP(void *, seq_a->prev, seq_b->prev);
+ SWAP(void *, seq_a->next, seq_b->next);
+ SWAP(int, seq_a->start, seq_b->start);
+ SWAP(int, seq_a->startofs, seq_b->startofs);
+ SWAP(int, seq_a->endofs, seq_b->endofs);
+ SWAP(int, seq_a->startstill, seq_b->startstill);
+ SWAP(int, seq_a->endstill, seq_b->endstill);
+ SWAP(int, seq_a->machine, seq_b->machine);
+ SWAP(int, seq_a->startdisp, seq_b->startdisp);
+ SWAP(int, seq_a->enddisp, seq_b->enddisp);
+
+ return 1;
+}
+
/* XXX - hackish function needed for transforming strips! TODO - have some better solution */
void seq_offset_animdata(Scene *scene, Sequence *seq, int ofs)
{
@@ -3702,6 +3933,62 @@ void seq_offset_animdata(Scene *scene, Sequence *seq, int ofs)
}
}
+void seq_dupe_animdata(Scene *scene, char *name_from, char *name_to)
+{
+ char str_from[32];
+ FCurve *fcu;
+ FCurve *fcu_last;
+ FCurve *fcu_cpy;
+ ListBase lb= {NULL, NULL};
+
+ if(scene->adt==NULL || scene->adt->action==NULL)
+ return;
+
+ sprintf(str_from, "[\"%s\"]", name_from);
+
+ fcu_last= scene->adt->action->curves.last;
+
+ for (fcu= scene->adt->action->curves.first; fcu && fcu->prev != fcu_last; fcu= fcu->next) {
+ if(strstr(fcu->rna_path, "sequence_editor.sequences_all[") && strstr(fcu->rna_path, str_from)) {
+ fcu_cpy= copy_fcurve(fcu);
+ BLI_addtail(&lb, fcu_cpy);
+ }
+ }
+
+ /* notice validate is 0, keep this because the seq may not be added to the scene yet */
+ BKE_animdata_fix_paths_rename(&scene->id, scene->adt, "sequence_editor.sequences_all", name_from, name_to, 0, 0, 0);
+
+ /* add the original fcurves back */
+ addlisttolist(&scene->adt->action->curves, &lb);
+}
+
+/* XXX - hackish function needed to remove all fcurves belonging to a sequencer strip */
+static void seq_free_animdata(Scene *scene, Sequence *seq)
+{
+ char str[32];
+ FCurve *fcu;
+
+ if(scene->adt==NULL || scene->adt->action==NULL)
+ return;
+
+ sprintf(str, "[\"%s\"]", seq->name+2);
+
+ fcu= scene->adt->action->curves.first;
+
+ while (fcu) {
+ if(strstr(fcu->rna_path, "sequence_editor.sequences_all[") && strstr(fcu->rna_path, str)) {
+ FCurve *next_fcu = fcu->next;
+
+ BLI_remlink(&scene->adt->action->curves, fcu);
+ free_fcurve(fcu);
+
+ fcu = next_fcu;
+ } else {
+ fcu = fcu->next;
+ }
+ }
+}
+
Sequence *get_seq_by_name(ListBase *seqbase, const char *name, int recursive)
{
@@ -3720,14 +4007,14 @@ Sequence *get_seq_by_name(ListBase *seqbase, const char *name, int recursive)
}
-Sequence *active_seq_get(Scene *scene)
+Sequence *seq_active_get(Scene *scene)
{
Editing *ed= seq_give_editing(scene, FALSE);
if(ed==NULL) return NULL;
return ed->act_seq;
}
-void active_seq_set(Scene *scene, Sequence *seq)
+void seq_active_set(Scene *scene, Sequence *seq)
{
Editing *ed= seq_give_editing(scene, FALSE);
if(ed==NULL) return;
@@ -3735,12 +4022,41 @@ void active_seq_set(Scene *scene, Sequence *seq)
ed->act_seq= seq;
}
+int seq_active_pair_get(Scene *scene, Sequence **seq_act, Sequence **seq_other)
+{
+ Editing *ed= seq_give_editing(scene, FALSE);
+
+ *seq_act= seq_active_get(scene);
+
+ if(*seq_act == NULL) {
+ return 0;
+ }
+ else {
+ Sequence *seq;
+
+ *seq_other= NULL;
+
+ for(seq= ed->seqbasep->first; seq; seq= seq->next) {
+ if(seq->flag & SELECT && (seq != (*seq_act))) {
+ if(*seq_other) {
+ return 0;
+ }
+ else {
+ *seq_other= seq;
+ }
+ }
+ }
+
+ return (*seq_other != NULL);
+ }
+}
+
/* api like funcs for adding */
void seq_load_apply(Scene *scene, Sequence *seq, SeqLoadInfo *seq_load)
{
if(seq) {
- strcpy(seq->name, seq_load->name);
+ BLI_strncpy(seq->name+2, seq_load->name, sizeof(seq->name)-2);
seqbase_unique_name_recursive(&scene->ed->seqbase, seq);
if(seq_load->flag & SEQ_LOAD_FRAME_ADVANCE) {
@@ -3749,7 +4065,7 @@ void seq_load_apply(Scene *scene, Sequence *seq, SeqLoadInfo *seq_load)
if(seq_load->flag & SEQ_LOAD_REPLACE_SEL) {
seq_load->flag |= SELECT;
- active_seq_set(scene, seq);
+ seq_active_set(scene, seq);
}
if(seq_load->flag & SEQ_LOAD_SOUND_CACHE) {
@@ -3777,6 +4093,7 @@ Sequence *alloc_sequence(ListBase *lb, int cfra, int machine)
seq->flag= SELECT;
seq->start= cfra;
seq->machine= machine;
+ seq->sat= 1.0;
seq->mul= 1.0;
seq->blend_opacity = 100.0;
seq->volume = 1.0f;
@@ -3794,8 +4111,7 @@ Sequence *sequencer_add_image_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
seq = alloc_sequence(seqbasep, seq_load->start_frame, seq_load->channel);
seq->type= SEQ_IMAGE;
- BLI_strncpy(seq->name+2, "Image", SEQ_NAME_MAXSTR-2);
- seqbase_unique_name_recursive(&scene->ed->seqbase, seq);
+ seq->blend_mode= SEQ_CROSS; /* so alpha adjustment fade to the strip below */
/* basic defaults */
seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
@@ -3803,8 +4119,8 @@ Sequence *sequencer_add_image_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
strip->len = seq->len = seq_load->len ? seq_load->len : 1;
strip->us= 1;
strip->stripdata= se= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
- BLI_split_dirfile_basic(seq_load->path, strip->dir, se->name);
-
+ BLI_strncpy(strip->dir, seq_load->path, sizeof(strip->dir));
+
seq_load_apply(scene, seq, seq_load);
return seq;
@@ -3822,7 +4138,7 @@ Sequence *sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
AUD_SoundInfo info;
- sound = sound_new_file(CTX_data_main(C), seq_load->path);
+ sound = sound_new_file(CTX_data_main(C), seq_load->path); /* handles relative paths */
if (sound==NULL || sound->playback_handle == NULL) {
//if(op)
@@ -3853,7 +4169,7 @@ Sequence *sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
strip->stripdata= se= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
- BLI_split_dirfile_basic(seq_load->path, strip->dir, se->name);
+ BLI_split_dirfile(seq_load->path, strip->dir, se->name);
seq->scene_sound = sound_add_scene_sound(scene, seq, seq_load->start_frame, seq_load->start_frame + strip->len, 0);
@@ -3870,6 +4186,7 @@ Sequence *sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
Sequence *sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo *seq_load)
{
Scene *scene= CTX_data_scene(C); /* only for sound */
+ char path[sizeof(seq_load->path)];
Sequence *seq, *soundseq; /* generic strip vars */
Strip *strip;
@@ -3877,14 +4194,18 @@ Sequence *sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
struct anim *an;
- an = openanim(seq_load->path, IB_rect);
+ BLI_strncpy(path, seq_load->path, sizeof(path));
+ BLI_path_abs(path, G.sce);
+
+ an = openanim(path, IB_rect);
if(an==NULL)
return NULL;
seq = alloc_sequence(seqbasep, seq_load->start_frame, seq_load->channel);
-
seq->type= SEQ_MOVIE;
+ seq->blend_mode= SEQ_CROSS; /* so alpha adjustment fade to the strip below */
+
seq->anim= an;
seq->anim_preseek = IMB_anim_get_preseek(an);
BLI_strncpy(seq->name+2, "Movie", SEQ_NAME_MAXSTR-2);
@@ -3897,7 +4218,7 @@ Sequence *sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
strip->stripdata= se= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
- BLI_split_dirfile_basic(seq_load->path, strip->dir, se->name);
+ BLI_split_dirfile(seq_load->path, strip->dir, se->name);
calc_sequence_disp(scene, seq);
@@ -3912,8 +4233,142 @@ Sequence *sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
seq_load->channel--;
}
+ if(seq_load->name[0] == '\0')
+ BLI_strncpy(seq_load->name, se->name, sizeof(seq_load->name));
+
/* can be NULL */
seq_load_apply(scene, seq, seq_load);
return seq;
}
+
+
+static Sequence *seq_dupli(struct Scene *scene, Sequence *seq, int dupe_flag)
+{
+ Sequence *seqn = MEM_dupallocN(seq);
+
+ seq->tmp = seqn;
+ seqn->strip= MEM_dupallocN(seq->strip);
+
+ // XXX: add F-Curve duplication stuff?
+
+ seqn->strip->tstripdata = 0;
+ seqn->strip->tstripdata_startstill = 0;
+ seqn->strip->tstripdata_endstill = 0;
+ seqn->strip->ibuf_startstill = 0;
+ seqn->strip->ibuf_endstill = 0;
+
+ if (seq->strip->crop) {
+ seqn->strip->crop = MEM_dupallocN(seq->strip->crop);
+ }
+
+ if (seq->strip->transform) {
+ seqn->strip->transform = MEM_dupallocN(seq->strip->transform);
+ }
+
+ if (seq->strip->proxy) {
+ seqn->strip->proxy = MEM_dupallocN(seq->strip->proxy);
+ }
+
+ if (seq->strip->color_balance) {
+ seqn->strip->color_balance
+ = MEM_dupallocN(seq->strip->color_balance);
+ }
+
+ if(seq->type==SEQ_META) {
+ seqn->strip->stripdata = 0;
+
+ seqn->seqbase.first= seqn->seqbase.last= 0;
+ /* WATCH OUT!!! - This metastrip is not recursively duplicated here - do this after!!! */
+ /* - seq_dupli_recursive(&seq->seqbase,&seqn->seqbase);*/
+ } else if(seq->type == SEQ_SCENE) {
+ seqn->strip->stripdata = 0;
+ if(seq->scene_sound)
+ seqn->scene_sound = sound_scene_add_scene_sound(scene, seqn, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
+ } else if(seq->type == SEQ_MOVIE) {
+ seqn->strip->stripdata =
+ MEM_dupallocN(seq->strip->stripdata);
+ seqn->anim= 0;
+ } else if(seq->type == SEQ_SOUND) {
+ seqn->strip->stripdata =
+ MEM_dupallocN(seq->strip->stripdata);
+ if(seq->scene_sound)
+ seqn->scene_sound = sound_add_scene_sound(scene, seqn, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
+
+ seqn->sound->id.us++;
+ } else if(seq->type == SEQ_IMAGE) {
+ seqn->strip->stripdata =
+ MEM_dupallocN(seq->strip->stripdata);
+ } else if(seq->type >= SEQ_EFFECT) {
+ if(seq->seq1 && seq->seq1->tmp) seqn->seq1= seq->seq1->tmp;
+ if(seq->seq2 && seq->seq2->tmp) seqn->seq2= seq->seq2->tmp;
+ if(seq->seq3 && seq->seq3->tmp) seqn->seq3= seq->seq3->tmp;
+
+ if (seq->type & SEQ_EFFECT) {
+ struct SeqEffectHandle sh;
+ sh = get_sequence_effect(seq);
+ if(sh.copy)
+ sh.copy(seq, seqn);
+ }
+
+ seqn->strip->stripdata = 0;
+
+ } else {
+ fprintf(stderr, "Aiiiiekkk! sequence type not "
+ "handled in duplicate!\nExpect a crash"
+ " now...\n");
+ }
+
+ if(dupe_flag & SEQ_DUPE_UNIQUE_NAME)
+ seqbase_unique_name_recursive(&scene->ed->seqbase, seqn);
+
+ if(dupe_flag & SEQ_DUPE_ANIM)
+ seq_dupe_animdata(scene, seq->name+2, seqn->name+2);
+
+ return seqn;
+}
+
+Sequence * seq_dupli_recursive(struct Scene *scene, Sequence * seq, int dupe_flag)
+{
+ Sequence * seqn = seq_dupli(scene, seq, dupe_flag);
+ if (seq->type == SEQ_META) {
+ Sequence *s;
+ for(s= seq->seqbase.first; s; s = s->next) {
+ Sequence *n = seq_dupli_recursive(scene, s, dupe_flag);
+ if (n) {
+ BLI_addtail(&seqn->seqbase, n);
+ }
+ }
+ }
+ return seqn;
+}
+
+void seqbase_dupli_recursive(Scene *scene, ListBase *nseqbase, ListBase *seqbase, int dupe_flag)
+{
+ Sequence *seq;
+ Sequence *seqn = 0;
+ Sequence *last_seq = seq_active_get(scene);
+
+ for(seq= seqbase->first; seq; seq= seq->next) {
+ seq->tmp= NULL;
+ if((seq->flag & SELECT) || (dupe_flag & SEQ_DUPE_ALL)) {
+ seqn = seq_dupli(scene, seq, dupe_flag);
+ if (seqn) { /*should never fail */
+ if(dupe_flag & SEQ_DUPE_CONTEXT) {
+ seq->flag &= ~SEQ_ALLSEL;
+ seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL+SEQ_LOCK);
+ }
+
+ BLI_addtail(nseqbase, seqn);
+ if(seq->type==SEQ_META)
+ seqbase_dupli_recursive(scene, &seqn->seqbase, &seq->seqbase, dupe_flag);
+
+ if(dupe_flag & SEQ_DUPE_CONTEXT) {
+ if (seq == last_seq) {
+ seq_active_set(scene, seqn);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index b2dd5bb3d55..b9c033f1809 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -46,23 +46,16 @@
#include "BKE_lattice.h"
#include "BKE_utildefines.h"
#include "BKE_deform.h"
-#include "BKE_cdderivedmesh.h"
-#include "BKE_displist.h"
-#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_subsurf.h"
#include "BKE_mesh.h"
#include "BKE_tessmesh.h"
#include "BLI_math.h"
-#include "BLI_kdtree.h"
-#include "BLI_kdopbvh.h"
#include "BLI_editVert.h"
-#include "RE_raytrace.h"
#include "MEM_guardedalloc.h"
-#include "ED_mesh.h"
/* Util macros */
#define TO_STR(a) #a
@@ -364,11 +357,16 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, struct S
if(calc->vert)
{
- VECCOPY(tmp_co, calc->vert[i].co);
- if(calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL)
+ /* calc->vert contains verts from derivedMesh */
+ /* this coordinated are deformed by vertexCos only for normal projection (to get correct normals) */
+ /* for other cases calc->varts contains undeformed coordinates and vertexCos should be used */
+ if(calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) {
+ VECCOPY(tmp_co, calc->vert[i].co);
normal_short_to_float_v3(tmp_no, calc->vert[i].no);
- else
+ } else {
+ VECCOPY(tmp_co, co);
VECCOPY(tmp_no, proj_axis);
+ }
}
else
{
diff --git a/source/blender/blenkernel/intern/simple_deform.c b/source/blender/blenkernel/intern/simple_deform.c
deleted file mode 100644
index f3984eb1c8b..00000000000
--- a/source/blender/blenkernel/intern/simple_deform.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/**
- * deform_simple.c
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) Blender Foundation.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): André Pinto
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-#include "DNA_object_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_meshdata_types.h"
-
-#include "BKE_simple_deform.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_lattice.h"
-#include "BKE_deform.h"
-#include "BKE_utildefines.h"
-#include "BLI_math.h"
-#include "BKE_shrinkwrap.h"
-
-#include <string.h>
-#include <math.h>
-
-
-//Clamps/Limits the given coordinate to: limits[0] <= co[axis] <= limits[1]
-//The ammount of clamp is saved on dcut
-static void axis_limit(int axis, const float limits[2], float co[3], float dcut[3])
-{
- float val = co[axis];
- if(limits[0] > val) val = limits[0];
- if(limits[1] < val) val = limits[1];
-
- dcut[axis] = co[axis] - val;
- co[axis] = val;
-}
-
-static void simpleDeform_taper(const float factor, const float dcut[3], float *co)
-{
- float x = co[0], y = co[1], z = co[2];
- float scale = z*factor;
-
- co[0] = x + x*scale;
- co[1] = y + y*scale;
- co[2] = z;
-
- if(dcut)
- {
- co[0] += dcut[0];
- co[1] += dcut[1];
- co[2] += dcut[2];
- }
-}
-
-static void simpleDeform_stretch(const float factor, const float dcut[3], float *co)
-{
- float x = co[0], y = co[1], z = co[2];
- float scale;
-
- scale = (z*z*factor-factor + 1.0);
-
- co[0] = x*scale;
- co[1] = y*scale;
- co[2] = z*(1.0+factor);
-
-
- if(dcut)
- {
- co[0] += dcut[0];
- co[1] += dcut[1];
- co[2] += dcut[2];
- }
-}
-
-static void simpleDeform_twist(const float factor, const float *dcut, float *co)
-{
- float x = co[0], y = co[1], z = co[2];
- float theta, sint, cost;
-
- theta = z*factor;
- sint = sin(theta);
- cost = cos(theta);
-
- co[0] = x*cost - y*sint;
- co[1] = x*sint + y*cost;
- co[2] = z;
-
- if(dcut)
- {
- co[0] += dcut[0];
- co[1] += dcut[1];
- co[2] += dcut[2];
- }
-}
-
-static void simpleDeform_bend(const float factor, const float dcut[3], float *co)
-{
- float x = co[0], y = co[1], z = co[2];
- float theta, sint, cost;
-
- theta = x*factor;
- sint = sin(theta);
- cost = cos(theta);
-
- if(fabs(factor) > 1e-7f)
- {
- co[0] = -(y-1.0f/factor)*sint;
- co[1] = (y-1.0f/factor)*cost + 1.0f/factor;
- co[2] = z;
- }
-
-
- if(dcut)
- {
- co[0] += cost*dcut[0];
- co[1] += sint*dcut[0];
- co[2] += dcut[2];
- }
-
-}
-
-
-/* simple deform modifier */
-void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts)
-{
- static const float lock_axis[2] = {0.0f, 0.0f};
-
- int i;
- int limit_axis = 0;
- float smd_limit[2], smd_factor;
- SpaceTransform *transf = NULL, tmp_transf;
- void (*simpleDeform_callback)(const float factor, const float dcut[3], float *co) = NULL; //Mode callback
- int vgroup = defgroup_name_index(ob, smd->vgroup_name);
- MDeformVert *dvert = NULL;
-
- //Safe-check
- if(smd->origin == ob) smd->origin = NULL; //No self references
-
- if(smd->limit[0] < 0.0) smd->limit[0] = 0.0f;
- if(smd->limit[0] > 1.0) smd->limit[0] = 1.0f;
-
- smd->limit[0] = MIN2(smd->limit[0], smd->limit[1]); //Upper limit >= than lower limit
-
- //Calculate matrixs do convert between coordinate spaces
- if(smd->origin)
- {
- transf = &tmp_transf;
-
- if(smd->originOpts & MOD_SIMPLEDEFORM_ORIGIN_LOCAL)
- {
- space_transform_from_matrixs(transf, ob->obmat, smd->origin->obmat);
- }
- else
- {
- copy_m4_m4(transf->local2target, smd->origin->obmat);
- invert_m4_m4(transf->target2local, transf->local2target);
- }
- }
-
- //Setup vars
- limit_axis = (smd->mode == MOD_SIMPLEDEFORM_MODE_BEND) ? 0 : 2; //Bend limits on X.. all other modes limit on Z
-
- //Update limits if needed
- {
- float lower = FLT_MAX;
- float upper = -FLT_MAX;
-
- for(i=0; i<numVerts; i++)
- {
- float tmp[3];
- VECCOPY(tmp, vertexCos[i]);
-
- if(transf) space_transform_apply(transf, tmp);
-
- lower = MIN2(lower, tmp[limit_axis]);
- upper = MAX2(upper, tmp[limit_axis]);
- }
-
-
- //SMD values are normalized to the BV, calculate the absolut values
- smd_limit[1] = lower + (upper-lower)*smd->limit[1];
- smd_limit[0] = lower + (upper-lower)*smd->limit[0];
-
- smd_factor = smd->factor / MAX2(FLT_EPSILON, smd_limit[1]-smd_limit[0]);
- }
-
-
- if(dm)
- {
- dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
- }
- else if(ob->type == OB_LATTICE)
- {
- dvert = lattice_get_deform_verts(ob);
- }
-
-
-
- switch(smd->mode)
- {
- case MOD_SIMPLEDEFORM_MODE_TWIST: simpleDeform_callback = simpleDeform_twist; break;
- case MOD_SIMPLEDEFORM_MODE_BEND: simpleDeform_callback = simpleDeform_bend; break;
- case MOD_SIMPLEDEFORM_MODE_TAPER: simpleDeform_callback = simpleDeform_taper; break;
- case MOD_SIMPLEDEFORM_MODE_STRETCH: simpleDeform_callback = simpleDeform_stretch; break;
- default:
- return; //No simpledeform mode?
- }
-
- for(i=0; i<numVerts; i++)
- {
- float weight = defvert_array_find_weight_safe(dvert, i, vgroup);
-
- if(weight != 0.0f)
- {
- float co[3], dcut[3] = {0.0f, 0.0f, 0.0f};
-
- if(transf) space_transform_apply(transf, vertexCos[i]);
-
- VECCOPY(co, vertexCos[i]);
-
- //Apply axis limits
- if(smd->mode != MOD_SIMPLEDEFORM_MODE_BEND) //Bend mode shoulnt have any lock axis
- {
- if(smd->axis & MOD_SIMPLEDEFORM_LOCK_AXIS_X) axis_limit(0, lock_axis, co, dcut);
- if(smd->axis & MOD_SIMPLEDEFORM_LOCK_AXIS_Y) axis_limit(1, lock_axis, co, dcut);
- }
- axis_limit(limit_axis, smd_limit, co, dcut);
-
- simpleDeform_callback(smd_factor, dcut, co); //Apply deform
- interp_v3_v3v3(vertexCos[i], vertexCos[i], co, weight); //Use vertex weight has coef of linear interpolation
-
- if(transf) space_transform_invert(transf, vertexCos[i]);
- }
- }
-}
-
-
diff --git a/source/blender/blenkernel/intern/sketch.c b/source/blender/blenkernel/intern/sketch.c
index ecafd0881ad..33871f78864 100644
--- a/source/blender/blenkernel/intern/sketch.c
+++ b/source/blender/blenkernel/intern/sketch.c
@@ -260,7 +260,7 @@ void sk_straightenStroke(SK_Stroke *stk, int start, int end, float p_start[3], f
VECCOPY(p, delta_p);
mul_v3_fl(p, delta);
- add_v3_v3v3(p, p, p_start);
+ add_v3_v3(p, p_start);
}
}
@@ -336,8 +336,8 @@ void sk_flattenStroke(SK_Stroke *stk, int start, int end)
VECCOPY(offset, normal);
mul_v3_fl(offset, d);
- sub_v3_v3v3(p, p, distance);
- add_v3_v3v3(p, p, offset);
+ sub_v3_v3(p, distance);
+ add_v3_v3(p, offset);
}
}
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index dd25bfe4ec4..5fa9f3897c2 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -717,7 +717,7 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
smd->domain->strength = 2.0;
smd->domain->noise = MOD_SMOKE_NOISEWAVE;
smd->domain->diss_speed = 5;
- // init 3dview buffer
+ // init view3d buffer
smd->domain->viewsettings = 0;
smd->domain->effector_weights = BKE_add_effector_weights(NULL);
}
@@ -753,6 +753,41 @@ void smokeModifier_createType(struct SmokeModifierData *smd)
}
}
+void smokeModifier_copy(struct SmokeModifierData *smd, struct SmokeModifierData *tsmd)
+{
+ tsmd->type = smd->type;
+ tsmd->time = smd->time;
+
+ smokeModifier_createType(tsmd);
+
+ if (tsmd->domain) {
+ tsmd->domain->maxres = smd->domain->maxres;
+ tsmd->domain->amplify = smd->domain->amplify;
+ tsmd->domain->omega = smd->domain->omega;
+ tsmd->domain->alpha = smd->domain->alpha;
+ tsmd->domain->beta = smd->domain->beta;
+ tsmd->domain->flags = smd->domain->flags;
+ tsmd->domain->strength = smd->domain->strength;
+ tsmd->domain->noise = smd->domain->noise;
+ tsmd->domain->diss_speed = smd->domain->diss_speed;
+ tsmd->domain->viewsettings = smd->domain->viewsettings;
+ tsmd->domain->fluid_group = smd->domain->fluid_group;
+ tsmd->domain->coll_group = smd->domain->coll_group;
+
+ MEM_freeN(tsmd->domain->effector_weights);
+ tsmd->domain->effector_weights = MEM_dupallocN(smd->domain->effector_weights);
+ } else if (tsmd->flow) {
+ tsmd->flow->density = smd->flow->density;
+ tsmd->flow->temp = smd->flow->temp;
+ tsmd->flow->psys = smd->flow->psys;
+ tsmd->flow->type = smd->flow->type;
+ } else if (tsmd->coll) {
+ ;
+ /* leave it as initialised, collision settings is mostly caches */
+ }
+}
+
+
// forward decleration
static void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct);
static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct);
@@ -1156,10 +1191,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
framenr = scene->r.cfra;
- // printf("time: %d\n", scene->r.cfra);
-
- if(framenr == smd->time)
- return;
+ printf("time: %d\n", scene->r.cfra);
cache = sds->point_cache[0];
BKE_ptcache_id_from_smoke(&pid, ob, smd);
@@ -1197,8 +1229,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
if(cache_result == PTCACHE_READ_EXACT)
{
- cache->flag |= PTCACHE_SIMULATION_VALID;
- cache->simframe= framenr;
+ BKE_ptcache_validate(cache, framenr);
if(sds->wt)
{
@@ -1206,13 +1237,24 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
if(cache_result_wt == PTCACHE_READ_EXACT)
{
- cache_wt->flag |= PTCACHE_SIMULATION_VALID;
- cache_wt->simframe= framenr;
+ BKE_ptcache_validate(cache_wt, framenr);
+
+ return;
+ }
+ else
+ {
+ ; /* don't return in the case we only got low res cache but no high res cache */
+ /* we still need to calculate the high res cache */
}
}
- return;
+ else
+ return;
}
+ /* only calculate something when we advanced a frame */
+ if(framenr == smd->time)
+ return;
+
tstart();
smoke_calc_domain(scene, ob, smd);
@@ -1223,8 +1265,6 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
/* do simulation */
// low res
- cache->flag |= PTCACHE_SIMULATION_VALID;
- cache->simframe= framenr;
// simulate the actual smoke (c++ code in intern/smoke)
// DG: interesting commenting this line + deactivating loading of noise files
@@ -1239,6 +1279,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
if(get_lamp(scene, light))
smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx);
+ BKE_ptcache_validate(cache, framenr);
BKE_ptcache_write_cache(&pid, framenr);
if(sds->wt)
@@ -1250,8 +1291,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
smoke_turbulence_step(sds->wt, sds->fluid);
}
- cache_wt->flag |= PTCACHE_SIMULATION_VALID;
- cache_wt->simframe= framenr;
+ BKE_ptcache_validate(cache_wt, framenr);
BKE_ptcache_write_cache(&pid_wt, framenr);
}
@@ -1283,11 +1323,11 @@ long long smoke_get_mem_req(int xres, int yres, int zres, int amplify)
// print out memory requirements
long long int coarseSize = sizeof(float) * totalCells * 22 +
- sizeof(unsigned char) * totalCells;
+ sizeof(unsigned char) * totalCells;
long long int fineSize = sizeof(float) * amplifiedCells * 7 + // big grids
- sizeof(float) * totalCells * 8 + // small grids
- sizeof(float) * 128 * 128 * 128; // noise tile
+ sizeof(float) * totalCells * 8 + // small grids
+ sizeof(float) * 128 * 128 * 128; // noise tile
long long int totalMB = (coarseSize + fineSize) / (1024 * 1024);
@@ -1296,83 +1336,83 @@ long long smoke_get_mem_req(int xres, int yres, int zres, int amplify)
static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, float *tRay, bresenham_callback cb, float *result, float *input, int res[3], float correct)
{
- int dx, dy, dz, i, l, m, n, x_inc, y_inc, z_inc, err_1, err_2, dx2, dy2, dz2;
- int pixel[3];
-
- pixel[0] = x1;
- pixel[1] = y1;
- pixel[2] = z1;
-
- dx = x2 - x1;
- dy = y2 - y1;
- dz = z2 - z1;
-
- x_inc = (dx < 0) ? -1 : 1;
- l = abs(dx);
- y_inc = (dy < 0) ? -1 : 1;
- m = abs(dy);
- z_inc = (dz < 0) ? -1 : 1;
- n = abs(dz);
- dx2 = l << 1;
- dy2 = m << 1;
- dz2 = n << 1;
-
- if ((l >= m) && (l >= n)) {
- err_1 = dy2 - l;
- err_2 = dz2 - l;
- for (i = 0; i < l; i++) {
- if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON)
- break;
- if (err_1 > 0) {
- pixel[1] += y_inc;
- err_1 -= dx2;
- }
- if (err_2 > 0) {
- pixel[2] += z_inc;
- err_2 -= dx2;
- }
- err_1 += dy2;
- err_2 += dz2;
- pixel[0] += x_inc;
- }
- } else if ((m >= l) && (m >= n)) {
- err_1 = dx2 - m;
- err_2 = dz2 - m;
- for (i = 0; i < m; i++) {
- if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON)
- break;
- if (err_1 > 0) {
- pixel[0] += x_inc;
- err_1 -= dy2;
- }
- if (err_2 > 0) {
- pixel[2] += z_inc;
- err_2 -= dy2;
- }
- err_1 += dx2;
- err_2 += dz2;
- pixel[1] += y_inc;
- }
- } else {
- err_1 = dy2 - n;
- err_2 = dx2 - n;
- for (i = 0; i < n; i++) {
- if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON)
- break;
- if (err_1 > 0) {
- pixel[1] += y_inc;
- err_1 -= dz2;
- }
- if (err_2 > 0) {
- pixel[0] += x_inc;
- err_2 -= dz2;
- }
- err_1 += dy2;
- err_2 += dx2;
- pixel[2] += z_inc;
- }
- }
- cb(result, input, res, pixel, tRay, correct);
+ int dx, dy, dz, i, l, m, n, x_inc, y_inc, z_inc, err_1, err_2, dx2, dy2, dz2;
+ int pixel[3];
+
+ pixel[0] = x1;
+ pixel[1] = y1;
+ pixel[2] = z1;
+
+ dx = x2 - x1;
+ dy = y2 - y1;
+ dz = z2 - z1;
+
+ x_inc = (dx < 0) ? -1 : 1;
+ l = abs(dx);
+ y_inc = (dy < 0) ? -1 : 1;
+ m = abs(dy);
+ z_inc = (dz < 0) ? -1 : 1;
+ n = abs(dz);
+ dx2 = l << 1;
+ dy2 = m << 1;
+ dz2 = n << 1;
+
+ if ((l >= m) && (l >= n)) {
+ err_1 = dy2 - l;
+ err_2 = dz2 - l;
+ for (i = 0; i < l; i++) {
+ if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON)
+ break;
+ if (err_1 > 0) {
+ pixel[1] += y_inc;
+ err_1 -= dx2;
+ }
+ if (err_2 > 0) {
+ pixel[2] += z_inc;
+ err_2 -= dx2;
+ }
+ err_1 += dy2;
+ err_2 += dz2;
+ pixel[0] += x_inc;
+ }
+ } else if ((m >= l) && (m >= n)) {
+ err_1 = dx2 - m;
+ err_2 = dz2 - m;
+ for (i = 0; i < m; i++) {
+ if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON)
+ break;
+ if (err_1 > 0) {
+ pixel[0] += x_inc;
+ err_1 -= dy2;
+ }
+ if (err_2 > 0) {
+ pixel[2] += z_inc;
+ err_2 -= dy2;
+ }
+ err_1 += dx2;
+ err_2 += dz2;
+ pixel[1] += y_inc;
+ }
+ } else {
+ err_1 = dy2 - n;
+ err_2 = dx2 - n;
+ for (i = 0; i < n; i++) {
+ if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON)
+ break;
+ if (err_1 > 0) {
+ pixel[1] += y_inc;
+ err_1 -= dz2;
+ }
+ if (err_2 > 0) {
+ pixel[0] += x_inc;
+ err_2 -= dz2;
+ }
+ err_1 += dy2;
+ err_2 += dx2;
+ pixel[2] += z_inc;
+ }
+ }
+ cb(result, input, res, pixel, tRay, correct);
}
static void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int correct)
@@ -1398,11 +1438,12 @@ static void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int
static void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct)
{
- int z;
float bv[6];
- int slabsize=res[0]*res[1];
+ int a, z, slabsize=res[0]*res[1], size= res[0]*res[1]*res[2];
+
+ for(a=0; a<size; a++)
+ result[a]= -1.0f;
- memset(result, -1, sizeof(float)*res[0]*res[1]*res[2]); // x
bv[0] = p0[0];
bv[1] = p1[0];
// y
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 8ca8feead90..70834746027 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -1,5 +1,5 @@
-/* softbody.c
- *
+/* softbody.c
+ *
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
@@ -32,17 +32,17 @@
******
variables on the UI for now
- float mediafrict; friction to env
- float nodemass; softbody mass of *vertex*
- float grav; softbody amount of gravitaion to apply
-
- float goalspring; softbody goal springs
- float goalfrict; softbody goal springs friction
- float mingoal; quick limits for goal
+ float mediafrict; friction to env
+ float nodemass; softbody mass of *vertex*
+ float grav; softbody amount of gravitaion to apply
+
+ float goalspring; softbody goal springs
+ float goalfrict; softbody goal springs friction
+ float mingoal; quick limits for goal
float maxgoal;
- float inspring; softbody inner springs
- float infrict; softbody inner springs friction
+ float inspring; softbody inner springs
+ float infrict; softbody inner springs friction
*****
*/
@@ -56,16 +56,11 @@ variables on the UI for now
/* types */
#include "DNA_curve_types.h"
-#include "DNA_object_types.h"
-#include "DNA_object_force.h" /* here is the softbody struct */
-#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
#include "DNA_lattice_types.h"
#include "DNA_scene_types.h"
-#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_ghash.h"
#include "BLI_threads.h"
@@ -74,13 +69,9 @@ variables on the UI for now
#include "BKE_curve.h"
#include "BKE_effect.h"
#include "BKE_global.h"
-#include "BKE_key.h"
-#include "BKE_object.h"
#include "BKE_softbody.h"
-#include "BKE_utildefines.h"
#include "BKE_DerivedMesh.h"
#include "BKE_pointcache.h"
-#include "BKE_modifier.h"
#include "BKE_deform.h"
//XXX #include "BIF_editdeform.h"
//XXX #include "BIF_graphics.h"
@@ -93,7 +84,7 @@ static int (*SB_localInterruptCallBack)(void) = NULL;
/* ********** soft body engine ******* */
-typedef enum {SB_EDGE=1,SB_BEND=2,SB_STIFFQUAD=3} type_spring;
+typedef enum {SB_EDGE=1,SB_BEND=2,SB_STIFFQUAD=3,SB_HANDLE=4} type_spring;
typedef struct BodySpring {
int v1, v2;
@@ -133,7 +124,7 @@ typedef struct SBScratch {
typedef struct SB_thread_context {
Scene *scene;
- Object *ob;
+ Object *ob;
float forcetime;
float timenow;
int ifirst;
@@ -146,12 +137,12 @@ typedef struct SB_thread_context {
int tot;
}SB_thread_context;
-#define NLF_BUILD 1
-#define NLF_SOLVE 2
+#define NLF_BUILD 1
+#define NLF_SOLVE 2
#define MID_PRESERVE 1
-#define SOFTGOALSNAP 0.999f
+#define SOFTGOALSNAP 0.999f
/* if bp-> goal is above make it a *forced follow original* and skip all ODE stuff for this bp
removes *unnecessary* stiffnes from ODE system
*/
@@ -159,7 +150,11 @@ typedef struct SB_thread_context {
#define BSF_INTERSECT 1 /* edge intersects collider face */
-#define SBF_DOFUZZY 1 /* edge intersects collider face */
+
+/* private definitions for bodypoint states */
+#define SBF_DOFUZZY 1 /* Bodypoint do fuzzy */
+#define SBF_OUTOFCOLLISION 2 /* Bodypoint does not collide */
+
#define BFF_INTERSECT 1 /* collider edge intrudes face */
#define BFF_CLOSEVERT 2 /* collider vertex repulses face */
@@ -197,15 +192,15 @@ static float sb_time_scale(Object *ob)
{
SoftBody *sb= ob->soft; /* is supposed to be there */
if (sb){
- return(sb->physics_speed);
- /*hrms .. this could be IPO as well :)
+ return(sb->physics_speed);
+ /*hrms .. this could be IPO as well :)
estimated range [0.001 sluggish slug - 100.0 very fast (i hope ODE solver can handle that)]
1 approx = a unit 1 pendulum at g = 9.8 [earth conditions] has period 65 frames
- theory would give a 50 frames period .. so there must be something inaccurate .. looking for that (BM)
+ theory would give a 50 frames period .. so there must be something inaccurate .. looking for that (BM)
*/
}
return (1.0f);
- /*
+ /*
this would be frames/sec independant timing assuming 25 fps is default
but does not work very well with NLA
return (25.0f/scene->r.frs_sec)
@@ -213,19 +208,59 @@ static float sb_time_scale(Object *ob)
}
/*--- frame based timing ---*/
+/* helper functions for everything is animatable jow_go_for2_5 +++++++*/
+/* introducing them here, because i know: steps in properties ( at frame timing )
+ will cause unwanted responses of the softbody system (which does inter frame calculations )
+ so first 'cure' would be: interpolate linear in time ..
+ Q: why do i write this?
+ A: because it happend once, that some eger coder 'streamlined' code to fail.
+ We DO linear interpolation for goals .. and i think we should do on animated properties as well
+*/
+
+/* animate sb->maxgoal,sb->mingoal */
+static float _final_goal(Object *ob,BodyPoint *bp)/*jow_go_for2_5 */
+{
+ float f = -1999.99f;
+ if (ob){
+ SoftBody *sb= ob->soft; /* is supposed to be there */
+ if(!(ob->softflag & OB_SB_GOAL)) return (0.0f);
+ if (sb&&bp){
+ if (bp->goal < 0.0f) return (0.0f);
+ f = sb->mingoal + bp->goal*ABS(sb->maxgoal - sb->mingoal);
+ f = pow(f, 4.0f);
+ return (f);
+ }
+ }
+ printf("_final_goal failed! sb or bp ==NULL \n" );
+ return f; /*using crude but spot able values some times helps debuggin */
+}
+
+static float _final_mass(Object *ob,BodyPoint *bp)
+{
+ if (ob){
+ SoftBody *sb= ob->soft; /* is supposed to be there */
+ if (sb&&bp){
+ return(bp->mass*sb->nodemass);
+ }
+ }
+ printf("_final_mass failed! sb or bp ==NULL \n" );
+ return 1.0f;
+}
+/* helper functions for everything is animateble jow_go_for2_5 ------*/
+
/*+++ collider caching and dicing +++*/
/********************
for each target object/face the axis aligned bounding box (AABB) is stored
-faces paralell to global axes
+faces paralell to global axes
so only simple "value" in [min,max] ckecks are used
float operations still
*/
/* just an ID here to reduce the prob for killing objects
** ob->sumohandle points to we should not kill :)
-*/
-const int CCD_SAVETY = 190561;
+*/
+const int CCD_SAVETY = 190561;
typedef struct ccdf_minmax{
float minx,miny,minz,maxx,maxy,maxz;
@@ -250,16 +285,16 @@ typedef struct ccd_Mesh {
static ccd_Mesh *ccd_mesh_make(Object *ob, DerivedMesh *dm)
{
- ccd_Mesh *pccd_M = NULL;
+ ccd_Mesh *pccd_M = NULL;
ccdf_minmax *mima =NULL;
MFace *mface=NULL;
float v[3],hull;
int i;
-
+
/* first some paranoia checks */
if (!dm) return NULL;
if (!dm->getNumVerts(dm) || !dm->getNumTessFaces(dm)) return NULL;
-
+
pccd_M = MEM_mallocN(sizeof(ccd_Mesh),"ccd_Mesh");
pccd_M->totvert = dm->getNumVerts(dm);
pccd_M->totface = dm->getNumTessFaces(dm);
@@ -267,34 +302,34 @@ static ccd_Mesh *ccd_mesh_make(Object *ob, DerivedMesh *dm)
pccd_M->bbmin[0]=pccd_M->bbmin[1]=pccd_M->bbmin[2]=1e30f;
pccd_M->bbmax[0]=pccd_M->bbmax[1]=pccd_M->bbmax[2]=-1e30f;
pccd_M->mprevvert=NULL;
-
-
- /* blow it up with forcefield ranges */
+
+
+ /* blow it up with forcefield ranges */
hull = MAX2(ob->pd->pdef_sbift,ob->pd->pdef_sboft);
-
+
/* alloc and copy verts*/
pccd_M->mvert = dm->dupVertArray(dm);
- /* ah yeah, put the verices to global coords once */
- /* and determine the ortho BB on the fly */
+ /* ah yeah, put the verices to global coords once */
+ /* and determine the ortho BB on the fly */
for(i=0; i < pccd_M->totvert; i++){
mul_m4_v3(ob->obmat, pccd_M->mvert[i].co);
-
- /* evaluate limits */
+
+ /* evaluate limits */
VECCOPY(v,pccd_M->mvert[i].co);
pccd_M->bbmin[0] = MIN2(pccd_M->bbmin[0],v[0]-hull);
pccd_M->bbmin[1] = MIN2(pccd_M->bbmin[1],v[1]-hull);
pccd_M->bbmin[2] = MIN2(pccd_M->bbmin[2],v[2]-hull);
-
+
pccd_M->bbmax[0] = MAX2(pccd_M->bbmax[0],v[0]+hull);
pccd_M->bbmax[1] = MAX2(pccd_M->bbmax[1],v[1]+hull);
pccd_M->bbmax[2] = MAX2(pccd_M->bbmax[2],v[2]+hull);
-
+
}
/* alloc and copy faces*/
pccd_M->mface = dm->dupTessFaceArray(dm);
-
+
/* OBBs for idea1 */
- pccd_M->mima = MEM_mallocN(sizeof(ccdf_minmax)*pccd_M->totface,"ccd_Mesh_Faces_mima");
+ pccd_M->mima = MEM_mallocN(sizeof(ccdf_minmax)*pccd_M->totface,"ccd_Mesh_Faces_mima");
mima = pccd_M->mima;
mface = pccd_M->mface;
@@ -303,23 +338,23 @@ static ccd_Mesh *ccd_mesh_make(Object *ob, DerivedMesh *dm)
for(i=0; i < pccd_M->totface; i++){
mima->minx=mima->miny=mima->minz=1e30f;
mima->maxx=mima->maxy=mima->maxz=-1e30f;
-
- VECCOPY(v,pccd_M->mvert[mface->v1].co);
+
+ VECCOPY(v,pccd_M->mvert[mface->v1].co);
mima->minx = MIN2(mima->minx,v[0]-hull);
mima->miny = MIN2(mima->miny,v[1]-hull);
mima->minz = MIN2(mima->minz,v[2]-hull);
mima->maxx = MAX2(mima->maxx,v[0]+hull);
mima->maxy = MAX2(mima->maxy,v[1]+hull);
mima->maxz = MAX2(mima->maxz,v[2]+hull);
-
- VECCOPY(v,pccd_M->mvert[mface->v2].co);
+
+ VECCOPY(v,pccd_M->mvert[mface->v2].co);
mima->minx = MIN2(mima->minx,v[0]-hull);
mima->miny = MIN2(mima->miny,v[1]-hull);
mima->minz = MIN2(mima->minz,v[2]-hull);
mima->maxx = MAX2(mima->maxx,v[0]+hull);
mima->maxy = MAX2(mima->maxy,v[1]+hull);
mima->maxz = MAX2(mima->maxz,v[2]+hull);
-
+
VECCOPY(v,pccd_M->mvert[mface->v3].co);
mima->minx = MIN2(mima->minx,v[0]-hull);
mima->miny = MIN2(mima->miny,v[1]-hull);
@@ -327,7 +362,7 @@ static ccd_Mesh *ccd_mesh_make(Object *ob, DerivedMesh *dm)
mima->maxx = MAX2(mima->maxx,v[0]+hull);
mima->maxy = MAX2(mima->maxy,v[1]+hull);
mima->maxz = MAX2(mima->maxz,v[2]+hull);
-
+
if(mface->v4){
VECCOPY(v,pccd_M->mvert[mface->v4].co);
mima->minx = MIN2(mima->minx,v[0]-hull);
@@ -338,20 +373,20 @@ static ccd_Mesh *ccd_mesh_make(Object *ob, DerivedMesh *dm)
mima->maxz = MAX2(mima->maxz,v[2]+hull);
}
-
+
mima++;
mface++;
-
+
}
return pccd_M;
}
static void ccd_mesh_update(Object *ob,ccd_Mesh *pccd_M, DerivedMesh *dm)
{
- ccdf_minmax *mima =NULL;
+ ccdf_minmax *mima =NULL;
MFace *mface=NULL;
float v[3],hull;
int i;
-
+
/* first some paranoia checks */
if (!dm) return ;
if (!dm->getNumVerts(dm) || !dm->getNumTessFaces(dm)) return ;
@@ -361,43 +396,43 @@ static void ccd_mesh_update(Object *ob,ccd_Mesh *pccd_M, DerivedMesh *dm)
pccd_M->bbmin[0]=pccd_M->bbmin[1]=pccd_M->bbmin[2]=1e30f;
pccd_M->bbmax[0]=pccd_M->bbmax[1]=pccd_M->bbmax[2]=-1e30f;
-
-
- /* blow it up with forcefield ranges */
+
+
+ /* blow it up with forcefield ranges */
hull = MAX2(ob->pd->pdef_sbift,ob->pd->pdef_sboft);
-
+
/* rotate current to previous */
if(pccd_M->mprevvert) MEM_freeN(pccd_M->mprevvert);
- pccd_M->mprevvert = pccd_M->mvert;
+ pccd_M->mprevvert = pccd_M->mvert;
/* alloc and copy verts*/
- pccd_M->mvert = dm->dupVertArray(dm);
- /* ah yeah, put the verices to global coords once */
- /* and determine the ortho BB on the fly */
+ pccd_M->mvert = dm->dupVertArray(dm);
+ /* ah yeah, put the verices to global coords once */
+ /* and determine the ortho BB on the fly */
for(i=0; i < pccd_M->totvert; i++){
mul_m4_v3(ob->obmat, pccd_M->mvert[i].co);
-
- /* evaluate limits */
+
+ /* evaluate limits */
VECCOPY(v,pccd_M->mvert[i].co);
pccd_M->bbmin[0] = MIN2(pccd_M->bbmin[0],v[0]-hull);
pccd_M->bbmin[1] = MIN2(pccd_M->bbmin[1],v[1]-hull);
pccd_M->bbmin[2] = MIN2(pccd_M->bbmin[2],v[2]-hull);
-
+
pccd_M->bbmax[0] = MAX2(pccd_M->bbmax[0],v[0]+hull);
pccd_M->bbmax[1] = MAX2(pccd_M->bbmax[1],v[1]+hull);
pccd_M->bbmax[2] = MAX2(pccd_M->bbmax[2],v[2]+hull);
- /* evaluate limits */
+ /* evaluate limits */
VECCOPY(v,pccd_M->mprevvert[i].co);
pccd_M->bbmin[0] = MIN2(pccd_M->bbmin[0],v[0]-hull);
pccd_M->bbmin[1] = MIN2(pccd_M->bbmin[1],v[1]-hull);
pccd_M->bbmin[2] = MIN2(pccd_M->bbmin[2],v[2]-hull);
-
+
pccd_M->bbmax[0] = MAX2(pccd_M->bbmax[0],v[0]+hull);
pccd_M->bbmax[1] = MAX2(pccd_M->bbmax[1],v[1]+hull);
pccd_M->bbmax[2] = MAX2(pccd_M->bbmax[2],v[2]+hull);
-
+
}
-
+
mima = pccd_M->mima;
mface = pccd_M->mface;
@@ -406,23 +441,23 @@ static void ccd_mesh_update(Object *ob,ccd_Mesh *pccd_M, DerivedMesh *dm)
for(i=0; i < pccd_M->totface; i++){
mima->minx=mima->miny=mima->minz=1e30f;
mima->maxx=mima->maxy=mima->maxz=-1e30f;
-
- VECCOPY(v,pccd_M->mvert[mface->v1].co);
+
+ VECCOPY(v,pccd_M->mvert[mface->v1].co);
mima->minx = MIN2(mima->minx,v[0]-hull);
mima->miny = MIN2(mima->miny,v[1]-hull);
mima->minz = MIN2(mima->minz,v[2]-hull);
mima->maxx = MAX2(mima->maxx,v[0]+hull);
mima->maxy = MAX2(mima->maxy,v[1]+hull);
mima->maxz = MAX2(mima->maxz,v[2]+hull);
-
- VECCOPY(v,pccd_M->mvert[mface->v2].co);
+
+ VECCOPY(v,pccd_M->mvert[mface->v2].co);
mima->minx = MIN2(mima->minx,v[0]-hull);
mima->miny = MIN2(mima->miny,v[1]-hull);
mima->minz = MIN2(mima->minz,v[2]-hull);
mima->maxx = MAX2(mima->maxx,v[0]+hull);
mima->maxy = MAX2(mima->maxy,v[1]+hull);
mima->maxz = MAX2(mima->maxz,v[2]+hull);
-
+
VECCOPY(v,pccd_M->mvert[mface->v3].co);
mima->minx = MIN2(mima->minx,v[0]-hull);
mima->miny = MIN2(mima->miny,v[1]-hull);
@@ -430,7 +465,7 @@ static void ccd_mesh_update(Object *ob,ccd_Mesh *pccd_M, DerivedMesh *dm)
mima->maxx = MAX2(mima->maxx,v[0]+hull);
mima->maxy = MAX2(mima->maxy,v[1]+hull);
mima->maxz = MAX2(mima->maxz,v[2]+hull);
-
+
if(mface->v4){
VECCOPY(v,pccd_M->mvert[mface->v4].co);
mima->minx = MIN2(mima->minx,v[0]-hull);
@@ -442,22 +477,22 @@ static void ccd_mesh_update(Object *ob,ccd_Mesh *pccd_M, DerivedMesh *dm)
}
- VECCOPY(v,pccd_M->mprevvert[mface->v1].co);
+ VECCOPY(v,pccd_M->mprevvert[mface->v1].co);
mima->minx = MIN2(mima->minx,v[0]-hull);
mima->miny = MIN2(mima->miny,v[1]-hull);
mima->minz = MIN2(mima->minz,v[2]-hull);
mima->maxx = MAX2(mima->maxx,v[0]+hull);
mima->maxy = MAX2(mima->maxy,v[1]+hull);
mima->maxz = MAX2(mima->maxz,v[2]+hull);
-
- VECCOPY(v,pccd_M->mprevvert[mface->v2].co);
+
+ VECCOPY(v,pccd_M->mprevvert[mface->v2].co);
mima->minx = MIN2(mima->minx,v[0]-hull);
mima->miny = MIN2(mima->miny,v[1]-hull);
mima->minz = MIN2(mima->minz,v[2]-hull);
mima->maxx = MAX2(mima->maxx,v[0]+hull);
mima->maxy = MAX2(mima->maxy,v[1]+hull);
mima->maxz = MAX2(mima->maxz,v[2]+hull);
-
+
VECCOPY(v,pccd_M->mprevvert[mface->v3].co);
mima->minx = MIN2(mima->minx,v[0]-hull);
mima->miny = MIN2(mima->miny,v[1]-hull);
@@ -465,7 +500,7 @@ static void ccd_mesh_update(Object *ob,ccd_Mesh *pccd_M, DerivedMesh *dm)
mima->maxx = MAX2(mima->maxx,v[0]+hull);
mima->maxy = MAX2(mima->maxy,v[1]+hull);
mima->maxz = MAX2(mima->maxz,v[2]+hull);
-
+
if(mface->v4){
VECCOPY(v,pccd_M->mprevvert[mface->v4].co);
mima->minx = MIN2(mima->minx,v[0]-hull);
@@ -476,10 +511,10 @@ static void ccd_mesh_update(Object *ob,ccd_Mesh *pccd_M, DerivedMesh *dm)
mima->maxz = MAX2(mima->maxz,v[2]+hull);
}
-
+
mima++;
mface++;
-
+
}
return ;
}
@@ -507,7 +542,7 @@ static void ccd_build_deflector_hash(Scene *scene, Object *vertexowner, GHash *h
if(base->object->type==OB_MESH && (base->lay & vertexowner->lay)) {
ob= base->object;
if((vertexowner) && (ob == vertexowner)) {
- /* if vertexowner is given we don't want to check collision with owner object */
+ /* if vertexowner is given we don't want to check collision with owner object */
base = base->next;
continue;
}
@@ -527,11 +562,11 @@ static void ccd_build_deflector_hash(Scene *scene, Object *vertexowner, GHash *h
/* we did copy & modify all we need so give 'em away again */
dm->release(dm);
-
+
}
}/*--- only with deflecting set */
- }/* mesh && layer*/
+ }/* mesh && layer*/
base = base->next;
} /* while (base) */
}
@@ -546,16 +581,16 @@ static void ccd_update_deflector_hash(Scene *scene, Object *vertexowner, GHash *
/*Only proceed for mesh object in same layer */
if(base->object->type==OB_MESH && (base->lay & vertexowner->lay)) {
ob= base->object;
- if(ob == vertexowner){
- /* if vertexowner is given we don't want to check collision with owner object */
+ if(ob == vertexowner){
+ /* if vertexowner is given we don't want to check collision with owner object */
base = base->next;
- continue;
+ continue;
}
/*+++ only with deflecting set */
if(ob->pd && ob->pd->deflect) {
DerivedMesh *dm= NULL;
-
+
if(ob->softflag & OB_SB_COLLFINAL) { /* so maybe someone wants overkill to collide with subsurfed */
dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
} else {
@@ -571,7 +606,7 @@ static void ccd_update_deflector_hash(Scene *scene, Object *vertexowner, GHash *
}
}/*--- only with deflecting set */
- }/* mesh && layer*/
+ }/* mesh && layer*/
base = base->next;
} /* while (base) */
}
@@ -586,12 +621,12 @@ static int count_mesh_quads(Mesh *me)
{
int a,result = 0;
MFace *mface= me->mface;
-
+
if(mface) {
for(a=me->totface; a>0; a--, mface++) {
if(mface->v4) result++;
}
- }
+ }
return result;
}
@@ -602,21 +637,21 @@ static void add_mesh_quad_diag_springs(Object *ob)
BodyPoint *bp;
BodySpring *bs, *bs_new;
int a ;
-
+
if (ob->soft){
int nofquads;
//float s_shear = ob->soft->shearstiff*ob->soft->shearstiff;
-
+
nofquads = count_mesh_quads(me);
if (nofquads) {
/* resize spring-array to hold additional quad springs */
bs_new= MEM_callocN( (ob->soft->totspring + nofquads *2 )*sizeof(BodySpring), "bodyspring");
memcpy(bs_new,ob->soft->bspring,(ob->soft->totspring )*sizeof(BodySpring));
-
+
if(ob->soft->bspring)
MEM_freeN(ob->soft->bspring); /* do this before reassigning the pointer or have a 1st class memory leak */
- ob->soft->bspring = bs_new;
-
+ ob->soft->bspring = bs_new;
+
/* fill the tail */
a = 0;
bs = bs_new+ob->soft->totspring;
@@ -632,12 +667,12 @@ static void add_mesh_quad_diag_springs(Object *ob)
bs->v2= mface->v4;
bs->springtype =SB_STIFFQUAD;
bs++;
-
+
}
- }
+ }
}
-
- /* now we can announce new springs */
+
+ /* now we can announce new springs */
ob->soft->totspring += nofquads *2;
}
}
@@ -647,7 +682,7 @@ static void add_2nd_order_roller(Object *ob,float stiffness,int *counter, int ad
{
/*assume we have a softbody*/
SoftBody *sb= ob->soft; /* is supposed to be there */
- BodyPoint *bp,*bpo;
+ BodyPoint *bp,*bpo;
BodySpring *bs,*bs2,*bs3= NULL;
int a,b,c,notthis= 0,v0;
if (!sb->bspring){return;} /* we are 2nd order here so 1rst should have been build :) */
@@ -662,7 +697,7 @@ static void add_2nd_order_roller(Object *ob,float stiffness,int *counter, int ad
bs = sb->bspring + bp->springs[b-1];
/*nasty thing here that springs have two ends
so here we have to make sure we examine the other */
- if (( v0 == bs->v1) ){
+ if (( v0 == bs->v1) ){
bpo =sb->bpoint+bs->v2;
notthis = bs->v2;
}
@@ -670,10 +705,10 @@ static void add_2nd_order_roller(Object *ob,float stiffness,int *counter, int ad
if (( v0 == bs->v2) ){
bpo =sb->bpoint+bs->v1;
notthis = bs->v1;
- }
+ }
else {printf("oops we should not get here - add_2nd_order_springs");}
}
- if (bpo){/* so now we have a 2nd order humpdidump */
+ if (bpo){/* so now we have a 2nd order humpdidump */
for(c=bpo->nofsprings;c>0;c--){
bs2 = sb->bspring + bpo->springs[c-1];
if ((bs2->v1 != notthis) && (bs2->v1 > v0)){
@@ -681,7 +716,7 @@ static void add_2nd_order_roller(Object *ob,float stiffness,int *counter, int ad
if (addsprings){
bs3->v1= v0;
bs3->v2= bs2->v1;
- bs3->springtype =SB_BEND;
+ bs3->springtype =SB_BEND;
bs3++;
}
}
@@ -690,15 +725,15 @@ static void add_2nd_order_roller(Object *ob,float stiffness,int *counter, int ad
if (addsprings){
bs3->v1= v0;
bs3->v2= bs2->v2;
- bs3->springtype =SB_BEND;
+ bs3->springtype =SB_BEND;
bs3++;
}
}
}
-
+
}
-
+
}
/*scan for neighborhood done*/
}
@@ -710,17 +745,17 @@ static void add_2nd_order_springs(Object *ob,float stiffness)
int counter = 0;
BodySpring *bs_new;
stiffness *=stiffness;
-
+
add_2nd_order_roller(ob,stiffness,&counter,0); /* counting */
if (counter) {
/* resize spring-array to hold additional springs */
bs_new= MEM_callocN( (ob->soft->totspring + counter )*sizeof(BodySpring), "bodyspring");
memcpy(bs_new,ob->soft->bspring,(ob->soft->totspring )*sizeof(BodySpring));
-
+
if(ob->soft->bspring)
- MEM_freeN(ob->soft->bspring);
- ob->soft->bspring = bs_new;
-
+ MEM_freeN(ob->soft->bspring);
+ ob->soft->bspring = bs_new;
+
add_2nd_order_roller(ob,stiffness,&counter,1); /* adding */
ob->soft->totspring +=counter ;
}
@@ -729,7 +764,7 @@ static void add_2nd_order_springs(Object *ob,float stiffness)
static void add_bp_springlist(BodyPoint *bp,int springID)
{
int *newlist;
-
+
if (bp->springs == NULL) {
bp->springs = MEM_callocN( sizeof(int), "bpsprings");
bp->springs[0] = springID;
@@ -751,35 +786,35 @@ it is O(N^2) so scanning for springs every iteration is too expensive
static void build_bps_springlist(Object *ob)
{
SoftBody *sb= ob->soft; /* is supposed to be there */
- BodyPoint *bp;
- BodySpring *bs;
+ BodyPoint *bp;
+ BodySpring *bs;
int a,b;
-
+
if (sb==NULL) return; /* paranoya check */
-
+
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
/* throw away old list */
if (bp->springs) {
MEM_freeN(bp->springs);
bp->springs=NULL;
}
- /* scan for attached inner springs */
+ /* scan for attached inner springs */
for(b=sb->totspring, bs= sb->bspring; b>0; b--, bs++) {
- if (( (sb->totpoint-a) == bs->v1) ){
+ if (( (sb->totpoint-a) == bs->v1) ){
add_bp_springlist(bp,sb->totspring -b);
}
- if (( (sb->totpoint-a) == bs->v2) ){
+ if (( (sb->totpoint-a) == bs->v2) ){
add_bp_springlist(bp,sb->totspring -b);
}
}/*for springs*/
- }/*for bp*/
+ }/*for bp*/
}
static void calculate_collision_balls(Object *ob)
{
SoftBody *sb= ob->soft; /* is supposed to be there */
- BodyPoint *bp;
- BodySpring *bs;
+ BodyPoint *bp;
+ BodySpring *bs;
int a,b,akku_count;
float min,max,akku;
@@ -820,12 +855,12 @@ static void calculate_collision_balls(Object *ob)
}
}
else bp->colball=0;
- }/*for bp*/
+ }/*for bp*/
}
/* creates new softbody if didn't exist yet, makes new points and springs arrays */
-static void renew_softbody(Scene *scene, Object *ob, int totpoint, int totspring)
+static void renew_softbody(Scene *scene, Object *ob, int totpoint, int totspring)
{
SoftBody *sb;
int i;
@@ -834,36 +869,40 @@ static void renew_softbody(Scene *scene, Object *ob, int totpoint, int totspring
else free_softbody_intern(ob->soft);
sb= ob->soft;
softflag=ob->softflag;
-
+
if(totpoint) {
sb->totpoint= totpoint;
sb->totspring= totspring;
-
+
sb->bpoint= MEM_mallocN( totpoint*sizeof(BodyPoint), "bodypoint");
- if(totspring)
+ if(totspring)
sb->bspring= MEM_mallocN( totspring*sizeof(BodySpring), "bodyspring");
/* initialise BodyPoint array */
for (i=0; i<totpoint; i++) {
BodyPoint *bp = &sb->bpoint[i];
+
+ /* hum as far as i see this is overridden by _final_goal() now jow_go_for2_5 */
+ /* sadly breaks compatibility with older versions */
+ /* but makes goals behave the same for meshes, lattices and curves */
if(softflag & OB_SB_GOAL) {
bp->goal= sb->defgoal;
}
- else {
- bp->goal= 0.0f;
+ else {
+ bp->goal= 0.0f;
/* so this will definily be below SOFTGOALSNAP */
}
-
+
bp->nofsprings= 0;
bp->springs= NULL;
bp->choke = 0.0f;
bp->choke2 = 0.0f;
bp->frozen = 1.0f;
bp->colball = 0.0f;
- bp->flag = 0;
+ bp->loc_flag = 0;
bp->springweight = 1.0f;
- bp->mass = sb->nodemass;
+ bp->mass = 1.0f;
}
}
}
@@ -878,7 +917,7 @@ static void free_softbody_baked(SoftBody *sb)
if(key) MEM_freeN(key);
}
if(sb->keys) MEM_freeN(sb->keys);
-
+
sb->keys= NULL;
sb->totkey= 0;
}
@@ -900,7 +939,7 @@ static void free_scratch(SoftBody *sb)
MEM_freeN(sb->scratch);
sb->scratch = NULL;
}
-
+
}
/* only frees internal data */
@@ -909,19 +948,19 @@ static void free_softbody_intern(SoftBody *sb)
if(sb) {
int a;
BodyPoint *bp;
-
+
if(sb->bpoint){
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
- /* free spring list */
+ /* free spring list */
if (bp->springs != NULL) {
MEM_freeN(bp->springs);
}
}
MEM_freeN(sb->bpoint);
}
-
+
if(sb->bspring) MEM_freeN(sb->bspring);
-
+
sb->totpoint= sb->totspring= 0;
sb->bpoint= NULL;
sb->bspring= NULL;
@@ -934,28 +973,28 @@ static void free_softbody_intern(SoftBody *sb)
/* ************ dynamics ********** */
-/* the most general (micro physics correct) way to do collision
-** (only needs the current particle position)
+/* the most general (micro physics correct) way to do collision
+** (only needs the current particle position)
**
-** it actually checks if the particle intrudes a short range force field generated
+** it actually checks if the particle intrudes a short range force field generated
** by the faces of the target object and returns a force to drive the particel out
** the strenght of the field grows exponetially if the particle is on the 'wrong' side of the face
** 'wrong' side : projection to the face normal is negative (all referred to a vertex in the face)
**
-** flaw of this: 'fast' particles as well as 'fast' colliding faces
-** give a 'tunnel' effect such that the particle passes through the force field
-** without ever 'seeing' it
+** flaw of this: 'fast' particles as well as 'fast' colliding faces
+** give a 'tunnel' effect such that the particle passes through the force field
+** without ever 'seeing' it
** this is fully compliant to heisenberg: h >= fuzzy(location) * fuzzy(time)
** besides our h is way larger than in QM because forces propagate way slower here
** we have to deal with fuzzy(time) in the range of 1/25 seconds (typical frame rate)
-** yup collision targets are not known here any better
+** yup collision targets are not known here any better
** and 1/25 second is looong compared to real collision events
-** Q: why not use 'simple' collision here like bouncing back a particle
+** Q: why not use 'simple' collision here like bouncing back a particle
** --> reverting is velocity on the face normal
-** A: because our particles are not alone here
-** and need to tell their neighbours exactly what happens via spring forces
+** A: because our particles are not alone here
+** and need to tell their neighbours exactly what happens via spring forces
** unless sbObjectStep( .. ) is called on sub frame timing level
-** BTW that also questions the use of a 'implicit' solvers on softbodies
+** BTW that also questions the use of a 'implicit' solvers on softbodies
** since that would only valid for 'slow' moving collision targets and dito particles
*/
@@ -972,10 +1011,10 @@ static void Vec3PlusStVec(float *v, float s, float *v1)
static int are_there_deflectors(Scene *scene, unsigned int layer)
{
Base *base;
-
+
for(base = scene->base.first; base; base= base->next) {
if( (base->lay & layer) && base->object->pd) {
- if(base->object->pd->deflect)
+ if(base->object->pd->deflect)
return 1;
}
}
@@ -1005,7 +1044,7 @@ static int sb_detect_aabb_collisionCached( float force[3], unsigned int par_laye
hash = vertexowner->soft->scratch->colliderhash;
ihash = BLI_ghashIterator_new(hash);
- while (!BLI_ghashIterator_isDone(ihash) ) {
+ while (!BLI_ghashIterator_isDone(ihash) ) {
ccd_Mesh *ccdm = BLI_ghashIterator_getValue (ihash);
ob = BLI_ghashIterator_getKey (ihash);
@@ -1021,20 +1060,20 @@ static int sb_detect_aabb_collisionCached( float force[3], unsigned int par_laye
mprevvert= ccdm->mprevvert;
mima= ccdm->mima;
a = ccdm->totface;
-
- if ((aabbmax[0] < ccdm->bbmin[0]) ||
+
+ if ((aabbmax[0] < ccdm->bbmin[0]) ||
(aabbmax[1] < ccdm->bbmin[1]) ||
(aabbmax[2] < ccdm->bbmin[2]) ||
- (aabbmin[0] > ccdm->bbmax[0]) ||
- (aabbmin[1] > ccdm->bbmax[1]) ||
+ (aabbmin[0] > ccdm->bbmax[0]) ||
+ (aabbmin[1] > ccdm->bbmax[1]) ||
(aabbmin[2] > ccdm->bbmax[2]) ) {
- /* boxes dont intersect */
+ /* boxes dont intersect */
BLI_ghashIterator_step(ihash);
- continue;
- }
+ continue;
+ }
/* so now we have the 2 boxes overlapping */
- /* forces actually not used */
+ /* forces actually not used */
deflected = 2;
}
@@ -1042,19 +1081,19 @@ static int sb_detect_aabb_collisionCached( float force[3], unsigned int par_laye
/*aye that should be cached*/
printf("missing cache error \n");
BLI_ghashIterator_step(ihash);
- continue;
+ continue;
}
} /* if(ob->pd && ob->pd->deflect) */
BLI_ghashIterator_step(ihash);
} /* while () */
BLI_ghashIterator_free(ihash);
- return deflected;
+ return deflected;
}
/* --- the aabb section*/
/* +++ the face external section*/
-static int sb_detect_face_pointCached(float face_v1[3],float face_v2[3],float face_v3[3],float *damp,
+static int sb_detect_face_pointCached(float face_v1[3],float face_v2[3],float face_v3[3],float *damp,
float force[3], unsigned int par_layer,struct Object *vertexowner,float time)
{
Object *ob;
@@ -1080,7 +1119,7 @@ static int sb_detect_face_pointCached(float face_v1[3],float face_v2[3],float fa
hash = vertexowner->soft->scratch->colliderhash;
ihash = BLI_ghashIterator_new(hash);
- while (!BLI_ghashIterator_isDone(ihash) ) {
+ while (!BLI_ghashIterator_isDone(ihash) ) {
ccd_Mesh *ccdm = BLI_ghashIterator_getValue (ihash);
ob = BLI_ghashIterator_getKey (ihash);
@@ -1090,33 +1129,33 @@ static int sb_detect_face_pointCached(float face_v1[3],float face_v2[3],float fa
MVert *mprevvert= NULL;
if(ccdm){
mvert= ccdm->mvert;
- a = ccdm->totvert;
- mprevvert= ccdm->mprevvert;
+ a = ccdm->totvert;
+ mprevvert= ccdm->mprevvert;
outerfacethickness =ob->pd->pdef_sboft;
- if ((aabbmax[0] < ccdm->bbmin[0]) ||
+ if ((aabbmax[0] < ccdm->bbmin[0]) ||
(aabbmax[1] < ccdm->bbmin[1]) ||
(aabbmax[2] < ccdm->bbmin[2]) ||
- (aabbmin[0] > ccdm->bbmax[0]) ||
- (aabbmin[1] > ccdm->bbmax[1]) ||
+ (aabbmin[0] > ccdm->bbmax[0]) ||
+ (aabbmin[1] > ccdm->bbmax[1]) ||
(aabbmin[2] > ccdm->bbmax[2]) ) {
- /* boxes dont intersect */
+ /* boxes dont intersect */
BLI_ghashIterator_step(ihash);
- continue;
- }
+ continue;
+ }
}
else{
/*aye that should be cached*/
printf("missing cache error \n");
BLI_ghashIterator_step(ihash);
- continue;
+ continue;
}
/* use mesh*/
if (mvert) {
while(a){
- VECCOPY(nv1,mvert[a-1].co);
+ VECCOPY(nv1,mvert[a-1].co);
if(mprevvert){
mul_v3_fl(nv1,time);
Vec3PlusStVec(nv1,(1.0f-time),mprevvert[a-1].co);
@@ -1148,11 +1187,11 @@ static int sb_detect_face_pointCached(float face_v1[3],float face_v2[3],float fa
BLI_ghashIterator_step(ihash);
} /* while () */
BLI_ghashIterator_free(ihash);
- return deflected;
+ return deflected;
}
-static int sb_detect_face_collisionCached(float face_v1[3],float face_v2[3],float face_v3[3],float *damp,
+static int sb_detect_face_collisionCached(float face_v1[3],float face_v2[3],float face_v3[3],float *damp,
float force[3], unsigned int par_layer,struct Object *vertexowner,float time)
{
Object *ob;
@@ -1171,7 +1210,7 @@ static int sb_detect_face_collisionCached(float face_v1[3],float face_v2[3],floa
hash = vertexowner->soft->scratch->colliderhash;
ihash = BLI_ghashIterator_new(hash);
- while (!BLI_ghashIterator_isDone(ihash) ) {
+ while (!BLI_ghashIterator_isDone(ihash) ) {
ccd_Mesh *ccdm = BLI_ghashIterator_getValue (ihash);
ob = BLI_ghashIterator_getKey (ihash);
@@ -1187,36 +1226,36 @@ static int sb_detect_face_collisionCached(float face_v1[3],float face_v2[3],floa
mprevvert= ccdm->mprevvert;
mima= ccdm->mima;
a = ccdm->totface;
-
- if ((aabbmax[0] < ccdm->bbmin[0]) ||
+
+ if ((aabbmax[0] < ccdm->bbmin[0]) ||
(aabbmax[1] < ccdm->bbmin[1]) ||
(aabbmax[2] < ccdm->bbmin[2]) ||
- (aabbmin[0] > ccdm->bbmax[0]) ||
- (aabbmin[1] > ccdm->bbmax[1]) ||
+ (aabbmin[0] > ccdm->bbmax[0]) ||
+ (aabbmin[1] > ccdm->bbmax[1]) ||
(aabbmin[2] > ccdm->bbmax[2]) ) {
- /* boxes dont intersect */
+ /* boxes dont intersect */
BLI_ghashIterator_step(ihash);
- continue;
- }
+ continue;
+ }
}
else{
/*aye that should be cached*/
printf("missing cache error \n");
BLI_ghashIterator_step(ihash);
- continue;
+ continue;
}
/* use mesh*/
while (a--) {
if (
- (aabbmax[0] < mima->minx) ||
- (aabbmin[0] > mima->maxx) ||
+ (aabbmax[0] < mima->minx) ||
+ (aabbmin[0] > mima->maxx) ||
(aabbmax[1] < mima->miny) ||
- (aabbmin[1] > mima->maxy) ||
+ (aabbmin[1] > mima->maxy) ||
(aabbmax[2] < mima->minz) ||
- (aabbmin[2] > mima->maxz)
+ (aabbmin[2] > mima->maxz)
) {
mface++;
mima++;
@@ -1226,7 +1265,7 @@ static int sb_detect_face_collisionCached(float face_v1[3],float face_v2[3],floa
if (mvert){
- VECCOPY(nv1,mvert[mface->v1].co);
+ VECCOPY(nv1,mvert[mface->v1].co);
VECCOPY(nv2,mvert[mface->v2].co);
VECCOPY(nv3,mvert[mface->v3].co);
if (mface->v4){
@@ -1235,18 +1274,18 @@ static int sb_detect_face_collisionCached(float face_v1[3],float face_v2[3],floa
if (mprevvert){
mul_v3_fl(nv1,time);
Vec3PlusStVec(nv1,(1.0f-time),mprevvert[mface->v1].co);
-
+
mul_v3_fl(nv2,time);
Vec3PlusStVec(nv2,(1.0f-time),mprevvert[mface->v2].co);
-
+
mul_v3_fl(nv3,time);
Vec3PlusStVec(nv3,(1.0f-time),mprevvert[mface->v3].co);
-
+
if (mface->v4){
mul_v3_fl(nv4,time);
Vec3PlusStVec(nv4,(1.0f-time),mprevvert[mface->v4].co);
}
- }
+ }
}
/* switch origin to be nv2*/
@@ -1254,7 +1293,7 @@ static int sb_detect_face_collisionCached(float face_v1[3],float face_v2[3],floa
VECSUB(edge2, nv3, nv2);
cross_v3_v3v3(d_nvect, edge2, edge1);
normalize_v3(d_nvect);
- if (
+ if (
isect_line_tri_v3(nv1, nv2, face_v1, face_v2, face_v3, &t, NULL) ||
isect_line_tri_v3(nv2, nv3, face_v1, face_v2, face_v3, &t, NULL) ||
isect_line_tri_v3(nv3, nv1, face_v1, face_v2, face_v3, &t, NULL) ){
@@ -1265,10 +1304,10 @@ static int sb_detect_face_collisionCached(float face_v1[3],float face_v2[3],floa
if (mface->v4){ /* quad */
/* switch origin to be nv4 */
VECSUB(edge1, nv3, nv4);
- VECSUB(edge2, nv1, nv4);
+ VECSUB(edge2, nv1, nv4);
cross_v3_v3v3(d_nvect, edge2, edge1);
- normalize_v3(d_nvect);
- if (
+ normalize_v3(d_nvect);
+ if (
/* isect_line_tri_v3(nv1, nv3, face_v1, face_v2, face_v3, &t, NULL) ||
we did that edge already */
isect_line_tri_v3(nv3, nv4, face_v1, face_v2, face_v3, &t, NULL) ||
@@ -1279,13 +1318,13 @@ static int sb_detect_face_collisionCached(float face_v1[3],float face_v2[3],floa
}
}
mface++;
- mima++;
- }/* while a */
+ mima++;
+ }/* while a */
} /* if(ob->pd && ob->pd->deflect) */
BLI_ghashIterator_step(ihash);
} /* while () */
BLI_ghashIterator_free(ihash);
- return deflected;
+ return deflected;
}
@@ -1295,20 +1334,20 @@ static void scan_for_ext_face_forces(Object *ob,float timenow)
SoftBody *sb = ob->soft;
BodyFace *bf;
int a;
- float damp=0.0f,choke=1.0f;
+ float damp=0.0f,choke=1.0f;
float tune = -10.0f;
float feedback[3];
-
+
if (sb && sb->scratch->totface){
-
-
+
+
bf = sb->scratch->bodyface;
for(a=0; a<sb->scratch->totface; a++, bf++) {
- bf->ext_force[0]=bf->ext_force[1]=bf->ext_force[2]=0.0f;
+ bf->ext_force[0]=bf->ext_force[1]=bf->ext_force[2]=0.0f;
/*+++edges intruding*/
- bf->flag &= ~BFF_INTERSECT;
+ bf->flag &= ~BFF_INTERSECT;
feedback[0]=feedback[1]=feedback[2]=0.0f;
- if (sb_detect_face_collisionCached(sb->bpoint[bf->v1].pos,sb->bpoint[bf->v2].pos, sb->bpoint[bf->v3].pos,
+ if (sb_detect_face_collisionCached(sb->bpoint[bf->v1].pos,sb->bpoint[bf->v2].pos, sb->bpoint[bf->v3].pos,
&damp, feedback, ob->lay ,ob , timenow)){
Vec3PlusStVec(sb->bpoint[bf->v1].force,tune,feedback);
Vec3PlusStVec(sb->bpoint[bf->v2].force,tune,feedback);
@@ -1319,7 +1358,7 @@ static void scan_for_ext_face_forces(Object *ob,float timenow)
}
feedback[0]=feedback[1]=feedback[2]=0.0f;
- if ((bf->v4) && (sb_detect_face_collisionCached(sb->bpoint[bf->v1].pos,sb->bpoint[bf->v3].pos, sb->bpoint[bf->v4].pos,
+ if ((bf->v4) && (sb_detect_face_collisionCached(sb->bpoint[bf->v1].pos,sb->bpoint[bf->v3].pos, sb->bpoint[bf->v4].pos,
&damp, feedback, ob->lay ,ob , timenow))){
Vec3PlusStVec(sb->bpoint[bf->v1].force,tune,feedback);
Vec3PlusStVec(sb->bpoint[bf->v3].force,tune,feedback);
@@ -1335,7 +1374,7 @@ static void scan_for_ext_face_forces(Object *ob,float timenow)
bf->flag &= ~BFF_CLOSEVERT;
tune = -1.0f;
feedback[0]=feedback[1]=feedback[2]=0.0f;
- if (sb_detect_face_pointCached(sb->bpoint[bf->v1].pos,sb->bpoint[bf->v2].pos, sb->bpoint[bf->v3].pos,
+ if (sb_detect_face_pointCached(sb->bpoint[bf->v1].pos,sb->bpoint[bf->v2].pos, sb->bpoint[bf->v3].pos,
&damp, feedback, ob->lay ,ob , timenow)){
Vec3PlusStVec(sb->bpoint[bf->v1].force,tune,feedback);
Vec3PlusStVec(sb->bpoint[bf->v2].force,tune,feedback);
@@ -1346,7 +1385,7 @@ static void scan_for_ext_face_forces(Object *ob,float timenow)
}
feedback[0]=feedback[1]=feedback[2]=0.0f;
- if ((bf->v4) && (sb_detect_face_pointCached(sb->bpoint[bf->v1].pos,sb->bpoint[bf->v3].pos, sb->bpoint[bf->v4].pos,
+ if ((bf->v4) && (sb_detect_face_pointCached(sb->bpoint[bf->v1].pos,sb->bpoint[bf->v3].pos, sb->bpoint[bf->v4].pos,
&damp, feedback, ob->lay ,ob , timenow))){
Vec3PlusStVec(sb->bpoint[bf->v1].force,tune,feedback);
Vec3PlusStVec(sb->bpoint[bf->v3].force,tune,feedback);
@@ -1362,13 +1401,13 @@ static void scan_for_ext_face_forces(Object *ob,float timenow)
for(a=0; a<sb->scratch->totface; a++, bf++) {
if (( bf->flag & BFF_INTERSECT) || ( bf->flag & BFF_CLOSEVERT))
{
- sb->bpoint[bf->v1].choke2=MAX2(sb->bpoint[bf->v1].choke2,choke);
- sb->bpoint[bf->v2].choke2=MAX2(sb->bpoint[bf->v2].choke2,choke);
- sb->bpoint[bf->v3].choke2=MAX2(sb->bpoint[bf->v3].choke2,choke);
+ sb->bpoint[bf->v1].choke2=MAX2(sb->bpoint[bf->v1].choke2,choke);
+ sb->bpoint[bf->v2].choke2=MAX2(sb->bpoint[bf->v2].choke2,choke);
+ sb->bpoint[bf->v3].choke2=MAX2(sb->bpoint[bf->v3].choke2,choke);
if (bf->v4){
- sb->bpoint[bf->v2].choke2=MAX2(sb->bpoint[bf->v2].choke2,choke);
+ sb->bpoint[bf->v2].choke2=MAX2(sb->bpoint[bf->v2].choke2,choke);
}
- }
+ }
}
}
}
@@ -1378,7 +1417,7 @@ static void scan_for_ext_face_forces(Object *ob,float timenow)
/* +++ the spring external section*/
-static int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],float *damp,
+static int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],float *damp,
float force[3], unsigned int par_layer,struct Object *vertexowner,float time)
{
Object *ob;
@@ -1399,7 +1438,7 @@ static int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],floa
hash = vertexowner->soft->scratch->colliderhash;
ihash = BLI_ghashIterator_new(hash);
- while (!BLI_ghashIterator_isDone(ihash) ) {
+ while (!BLI_ghashIterator_isDone(ihash) ) {
ccd_Mesh *ccdm = BLI_ghashIterator_getValue (ihash);
ob = BLI_ghashIterator_getKey (ihash);
@@ -1415,36 +1454,36 @@ static int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],floa
mprevvert= ccdm->mprevvert;
mima= ccdm->mima;
a = ccdm->totface;
-
- if ((aabbmax[0] < ccdm->bbmin[0]) ||
+
+ if ((aabbmax[0] < ccdm->bbmin[0]) ||
(aabbmax[1] < ccdm->bbmin[1]) ||
(aabbmax[2] < ccdm->bbmin[2]) ||
- (aabbmin[0] > ccdm->bbmax[0]) ||
- (aabbmin[1] > ccdm->bbmax[1]) ||
+ (aabbmin[0] > ccdm->bbmax[0]) ||
+ (aabbmin[1] > ccdm->bbmax[1]) ||
(aabbmin[2] > ccdm->bbmax[2]) ) {
- /* boxes dont intersect */
+ /* boxes dont intersect */
BLI_ghashIterator_step(ihash);
- continue;
- }
+ continue;
+ }
}
else{
/*aye that should be cached*/
printf("missing cache error \n");
BLI_ghashIterator_step(ihash);
- continue;
+ continue;
}
/* use mesh*/
while (a--) {
if (
- (aabbmax[0] < mima->minx) ||
- (aabbmin[0] > mima->maxx) ||
+ (aabbmax[0] < mima->minx) ||
+ (aabbmin[0] > mima->maxx) ||
(aabbmax[1] < mima->miny) ||
- (aabbmin[1] > mima->maxy) ||
+ (aabbmin[1] > mima->maxy) ||
(aabbmax[2] < mima->minz) ||
- (aabbmin[2] > mima->maxz)
+ (aabbmin[2] > mima->maxz)
) {
mface++;
mima++;
@@ -1454,7 +1493,7 @@ static int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],floa
if (mvert){
- VECCOPY(nv1,mvert[mface->v1].co);
+ VECCOPY(nv1,mvert[mface->v1].co);
VECCOPY(nv2,mvert[mface->v2].co);
VECCOPY(nv3,mvert[mface->v3].co);
if (mface->v4){
@@ -1463,18 +1502,18 @@ static int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],floa
if (mprevvert){
mul_v3_fl(nv1,time);
Vec3PlusStVec(nv1,(1.0f-time),mprevvert[mface->v1].co);
-
+
mul_v3_fl(nv2,time);
Vec3PlusStVec(nv2,(1.0f-time),mprevvert[mface->v2].co);
-
+
mul_v3_fl(nv3,time);
Vec3PlusStVec(nv3,(1.0f-time),mprevvert[mface->v3].co);
-
+
if (mface->v4){
mul_v3_fl(nv4,time);
Vec3PlusStVec(nv4,(1.0f-time),mprevvert[mface->v4].co);
}
- }
+ }
}
/* switch origin to be nv2*/
@@ -1501,7 +1540,7 @@ static int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],floa
VECSUB(edge2, nv1, nv4);
cross_v3_v3v3(d_nvect, edge2, edge1);
- normalize_v3(d_nvect);
+ normalize_v3(d_nvect);
if (isect_line_tri_v3( edge_v1, edge_v2,nv1, nv3, nv4, &t, NULL)){
float v1[3],v2[3];
float intrusiondepth,i1,i2;
@@ -1518,26 +1557,26 @@ static int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],floa
}
}
mface++;
- mima++;
- }/* while a */
+ mima++;
+ }/* while a */
} /* if(ob->pd && ob->pd->deflect) */
BLI_ghashIterator_step(ihash);
} /* while () */
BLI_ghashIterator_free(ihash);
- return deflected;
+ return deflected;
}
static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow, int ifirst, int ilast, struct ListBase *do_effector)
{
SoftBody *sb = ob->soft;
int a;
- float damp;
+ float damp;
float feedback[3];
if (sb && sb->totspring){
for(a=ifirst; a<ilast; a++) {
BodySpring *bs = &sb->bspring[a];
- bs->ext_force[0]=bs->ext_force[1]=bs->ext_force[2]=0.0f;
+ bs->ext_force[0]=bs->ext_force[1]=bs->ext_force[2]=0.0f;
feedback[0]=feedback[1]=feedback[2]=0.0f;
bs->flag &= ~BSF_INTERSECT;
@@ -1546,20 +1585,20 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow,
if (ob->softflag & OB_SB_EDGECOLL){
if ( sb_detect_edge_collisionCached (sb->bpoint[bs->v1].pos , sb->bpoint[bs->v2].pos,
&damp,feedback,ob->lay,ob,timenow)){
- add_v3_v3v3(bs->ext_force,bs->ext_force,feedback);
+ add_v3_v3(bs->ext_force, feedback);
bs->flag |= BSF_INTERSECT;
//bs->cf=damp;
- bs->cf=sb->choke*0.01f;
+ bs->cf=sb->choke*0.01f;
}
}
/* ---- springs colliding */
/* +++ springs seeing wind ... n stuff depending on their orientation*/
- /* note we don't use sb->mediafrict but use sb->aeroedge for magnitude of effect*/
+ /* note we don't use sb->mediafrict but use sb->aeroedge for magnitude of effect*/
if(sb->aeroedge){
float vel[3],sp[3],pr[3],force[3];
- float f,windfactor = 0.25f;
+ float f,windfactor = 0.25f;
/*see if we have wind*/
if(do_effector) {
EffectedPoint epoint;
@@ -1570,8 +1609,8 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow,
pd_point_from_soft(scene, pos, vel, -1, &epoint);
pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed);
- mul_v3_fl(speed,windfactor);
- add_v3_v3v3(vel,vel,speed);
+ mul_v3_fl(speed,windfactor);
+ add_v3_v3(vel, speed);
}
/* media in rest */
else{
@@ -1580,7 +1619,7 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow,
f = normalize_v3(vel);
f = -0.0001f*f*f*sb->aeroedge;
/* (todo) add a nice angle dependant function done for now BUT */
- /* still there could be some nice drag/lift function, but who needs it */
+ /* still there could be some nice drag/lift function, but who needs it */
VECSUB(sp, sb->bpoint[bs->v1].pos , sb->bpoint[bs->v2].pos);
project_v3_v3v3(pr,vel,sp);
@@ -1590,7 +1629,7 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow,
normalize_v3(sp);
Vec3PlusStVec(bs->ext_force,f*(1.0f-ABS(dot_v3v3(vel,sp))),vel);
}
- else{
+ else{
Vec3PlusStVec(bs->ext_force,f,vel); // to keep compatible with 2.45 release files
}
}
@@ -1604,8 +1643,8 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow,
static void scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow)
{
SoftBody *sb = ob->soft;
- ListBase *do_effector = NULL;
-
+ ListBase *do_effector = NULL;
+
do_effector = pdInitEffectors(scene, ob, NULL, sb->effector_weights);
if (sb){
_scan_for_ext_spring_forces(scene, ob, timenow, 0, sb->totspring, do_effector);
@@ -1618,11 +1657,11 @@ static void *exec_scan_for_ext_spring_forces(void *data)
SB_thread_context *pctx = (SB_thread_context*)data;
_scan_for_ext_spring_forces(pctx->scene, pctx->ob, pctx->timenow, pctx->ifirst, pctx->ilast, pctx->do_effector);
return 0;
-}
+}
static void sb_sfesf_threads_run(Scene *scene, struct Object *ob, float timenow,int totsprings,int *ptr_to_break_func())
{
- ListBase *do_effector = NULL;
+ ListBase *do_effector = NULL;
ListBase threads;
SB_thread_context *sb_threads;
int i, totthread,left,dec;
@@ -1646,18 +1685,18 @@ static void sb_sfesf_threads_run(Scene *scene, struct Object *ob, float timenow,
dec = totsprings/totthread +1;
for(i=0; i<totthread; i++) {
sb_threads[i].scene = scene;
- sb_threads[i].ob = ob;
- sb_threads[i].forcetime = 0.0; // not used here
- sb_threads[i].timenow = timenow;
- sb_threads[i].ilast = left;
+ sb_threads[i].ob = ob;
+ sb_threads[i].forcetime = 0.0; // not used here
+ sb_threads[i].timenow = timenow;
+ sb_threads[i].ilast = left;
left = left - dec;
if (left >0){
sb_threads[i].ifirst = left;
}
else
- sb_threads[i].ifirst = 0;
- sb_threads[i].do_effector = do_effector;
- sb_threads[i].do_deflector = 0;// not used here
+ sb_threads[i].ifirst = 0;
+ sb_threads[i].do_effector = do_effector;
+ sb_threads[i].do_deflector = 0;// not used here
sb_threads[i].fieldfactor = 0.0f;// not used here
sb_threads[i].windfactor = 0.0f;// not used here
sb_threads[i].nr= i;
@@ -1673,9 +1712,9 @@ static void sb_sfesf_threads_run(Scene *scene, struct Object *ob, float timenow,
}
else
exec_scan_for_ext_spring_forces(&sb_threads[0]);
- /* clean up */
+ /* clean up */
MEM_freeN(sb_threads);
-
+
pdEndEffectors(&do_effector);
}
@@ -1688,7 +1727,7 @@ static int choose_winner(float*w, float* pos,float*a,float*b,float*c,float*ca,fl
int winner =1;
mindist = ABS(dot_v3v3(pos,a));
- cp = ABS(dot_v3v3(pos,b));
+ cp = ABS(dot_v3v3(pos,b));
if ( mindist < cp ){
mindist = cp;
winner =2;
@@ -1699,10 +1738,10 @@ static int choose_winner(float*w, float* pos,float*a,float*b,float*c,float*ca,fl
mindist = cp;
winner =3;
}
- switch (winner){
- case 1: VECCOPY(w,ca); break;
- case 2: VECCOPY(w,cb); break;
- case 3: VECCOPY(w,cc);
+ switch (winner){
+ case 1: VECCOPY(w,ca); break;
+ case 2: VECCOPY(w,cb); break;
+ case 3: VECCOPY(w,cc);
}
return(winner);
}
@@ -1717,7 +1756,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
GHash *hash;
GHashIterator *ihash;
float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3],d_nvect[3], dv1[3],ve[3],avel[3]={0.0,0.0,0.0},
- vv1[3], vv2[3], vv3[3], vv4[3], coledge[3]={0.0f, 0.0f, 0.0f}, mindistedge = 1000.0f,
+ vv1[3], vv2[3], vv3[3], vv4[3], coledge[3]={0.0f, 0.0f, 0.0f}, mindistedge = 1000.0f,
outerforceaccu[3],innerforceaccu[3],
facedist,n_mag,force_mag_norm,minx,miny,minz,maxx,maxy,maxz,
innerfacethickness = -0.5f, outerfacethickness = 0.2f,
@@ -1730,7 +1769,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
outerforceaccu[0]=outerforceaccu[1]=outerforceaccu[2]=0.0f;
innerforceaccu[0]=innerforceaccu[1]=innerforceaccu[2]=0.0f;
/* go */
- while (!BLI_ghashIterator_isDone(ihash) ) {
+ while (!BLI_ghashIterator_isDone(ihash) ) {
ccd_Mesh *ccdm = BLI_ghashIterator_getValue (ihash);
ob = BLI_ghashIterator_getKey (ihash);
@@ -1748,30 +1787,30 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
mima= ccdm->mima;
a = ccdm->totface;
- minx =ccdm->bbmin[0];
- miny =ccdm->bbmin[1];
+ minx =ccdm->bbmin[0];
+ miny =ccdm->bbmin[1];
minz =ccdm->bbmin[2];
- maxx =ccdm->bbmax[0];
- maxy =ccdm->bbmax[1];
- maxz =ccdm->bbmax[2];
+ maxx =ccdm->bbmax[0];
+ maxy =ccdm->bbmax[1];
+ maxz =ccdm->bbmax[2];
- if ((opco[0] < minx) ||
+ if ((opco[0] < minx) ||
(opco[1] < miny) ||
(opco[2] < minz) ||
- (opco[0] > maxx) ||
- (opco[1] > maxy) ||
+ (opco[0] > maxx) ||
+ (opco[1] > maxy) ||
(opco[2] > maxz) ) {
- /* outside the padded boundbox --> collision object is too far away */
+ /* outside the padded boundbox --> collision object is too far away */
BLI_ghashIterator_step(ihash);
- continue;
- }
+ continue;
+ }
}
else{
/*aye that should be cached*/
printf("missing cache error \n");
BLI_ghashIterator_step(ihash);
- continue;
+ continue;
}
/* do object level stuff */
@@ -1781,16 +1820,16 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
fa = (ff*outerfacethickness-outerfacethickness);
fa *= fa;
fa = 1.0f/fa;
- avel[0]=avel[1]=avel[2]=0.0f;
+ avel[0]=avel[1]=avel[2]=0.0f;
/* use mesh*/
while (a--) {
if (
- (opco[0] < mima->minx) ||
- (opco[0] > mima->maxx) ||
+ (opco[0] < mima->minx) ||
+ (opco[0] > mima->maxx) ||
(opco[1] < mima->miny) ||
- (opco[1] > mima->maxy) ||
+ (opco[1] > mima->maxy) ||
(opco[2] < mima->minz) ||
- (opco[2] > mima->maxz)
+ (opco[2] > mima->maxz)
) {
mface++;
mima++;
@@ -1799,7 +1838,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
if (mvert){
- VECCOPY(nv1,mvert[mface->v1].co);
+ VECCOPY(nv1,mvert[mface->v1].co);
VECCOPY(nv2,mvert[mface->v2].co);
VECCOPY(nv3,mvert[mface->v3].co);
if (mface->v4){
@@ -1808,7 +1847,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
if (mprevvert){
/* grab the average speed of the collider vertices
- before we spoil nvX
+ before we spoil nvX
humm could be done once a SB steps but then we' need to store that too
since the AABB reduced propabitlty to get here drasticallly
it might be a nice tradeof CPU <--> memory
@@ -1833,9 +1872,9 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
mul_v3_fl(nv4,time);
Vec3PlusStVec(nv4,(1.0f-time),mprevvert[mface->v4].co);
}
- }
+ }
}
-
+
/* switch origin to be nv2*/
VECSUB(edge1, nv1, nv2);
VECSUB(edge2, nv3, nv2);
@@ -1847,7 +1886,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
// so rules are
//
- if ((facedist > innerfacethickness) && (facedist < outerfacethickness)){
+ if ((facedist > innerfacethickness) && (facedist < outerfacethickness)){
if (isect_point_tri_prism_v3(opco, nv1, nv2, nv3) ){
force_mag_norm =(float)exp(-ee*facedist);
if (facedist > outerfacethickness*ff)
@@ -1871,7 +1910,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
*intrusion += facedist;
ci++;
}
- }
+ }
if (mface->v4){ /* quad */
/* switch origin to be nv4 */
VECSUB(edge1, nv3, nv4);
@@ -1904,7 +1943,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
VECADD(avel,avel,ve);
cavel ++;
}
- *intrusion += facedist;
+ *intrusion += facedist;
ci++;
}
@@ -1914,7 +1953,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
float dist;
closest_to_line_segment_v3(ve, opco, nv1, nv2);
- VECSUB(ve,opco,ve);
+ VECSUB(ve,opco,ve);
dist = normalize_v3(ve);
if ((dist < outerfacethickness)&&(dist < mindistedge )){
VECCOPY(coledge,ve);
@@ -1923,7 +1962,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
}
closest_to_line_segment_v3(ve, opco, nv2, nv3);
- VECSUB(ve,opco,ve);
+ VECSUB(ve,opco,ve);
dist = normalize_v3(ve);
if ((dist < outerfacethickness)&&(dist < mindistedge )){
VECCOPY(coledge,ve);
@@ -1932,7 +1971,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
}
closest_to_line_segment_v3(ve, opco, nv3, nv1);
- VECSUB(ve,opco,ve);
+ VECSUB(ve,opco,ve);
dist = normalize_v3(ve);
if ((dist < outerfacethickness)&&(dist < mindistedge )){
VECCOPY(coledge,ve);
@@ -1941,7 +1980,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
}
if (mface->v4){ /* quad */
closest_to_line_segment_v3(ve, opco, nv3, nv4);
- VECSUB(ve,opco,ve);
+ VECSUB(ve,opco,ve);
dist = normalize_v3(ve);
if ((dist < outerfacethickness)&&(dist < mindistedge )){
VECCOPY(coledge,ve);
@@ -1950,22 +1989,22 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
}
closest_to_line_segment_v3(ve, opco, nv1, nv4);
- VECSUB(ve,opco,ve);
+ VECSUB(ve,opco,ve);
dist = normalize_v3(ve);
if ((dist < outerfacethickness)&&(dist < mindistedge )){
VECCOPY(coledge,ve);
mindistedge = dist,
deflected=1;
}
-
+
}
}
}
mface++;
- mima++;
- }/* while a */
+ mima++;
+ }/* while a */
} /* if(ob->pd && ob->pd->deflect) */
BLI_ghashIterator_step(ihash);
} /* while () */
@@ -1992,11 +2031,11 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
if (cavel) mul_v3_fl(avel,1.0f/(float)cavel);
VECCOPY(vel,avel);
if (ci) *intrusion /= ci;
- if (deflected){
+ if (deflected){
VECCOPY(facenormal,force);
normalize_v3(facenormal);
}
- return deflected;
+ return deflected;
}
@@ -2004,7 +2043,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
static int sb_deflect_face(Object *ob,float *actpos,float *facenormal,float *force,float *cf,float time,float *vel,float *intrusion)
{
float s_actpos[3];
- int deflected;
+ int deflected;
VECCOPY(s_actpos,actpos);
deflected= sb_detect_vertex_collisionCached(s_actpos, facenormal, cf, force , ob->lay, ob,time,vel,intrusion);
//deflected= sb_detect_vertex_collisionCachedEx(s_actpos, facenormal, cf, force , ob->lay, ob,time,vel,intrusion);
@@ -2013,7 +2052,7 @@ static int sb_deflect_face(Object *ob,float *actpos,float *facenormal,float *for
/* hiding this for now .. but the jacobian may pop up on other tasks .. so i'd like to keep it
static void dfdx_spring(int ia, int ic, int op, float dir[3],float L,float len,float factor)
-{
+{
float m,delta_ij;
int i ,j;
if (L < len){
@@ -2035,13 +2074,13 @@ static void dfdx_spring(int ia, int ic, int op, float dir[3],float L,float len,f
static void dfdx_goal(int ia, int ic, int op, float factor)
-{
+{
int i;
for(i=0;i<3;i++) nlMatrixAdd(ia+i,op+ic+i,factor);
}
static void dfdv_goal(int ia, int ic,float factor)
-{
+{
int i;
for(i=0;i<3;i++) nlMatrixAdd(ia+i,ic+i,factor);
}
@@ -2091,13 +2130,14 @@ static void sb_spring_force(Object *ob,int bpi,BodySpring *bs,float iks,float fo
kw = kw * kw;
switch (bs->springtype){
case SB_EDGE:
- forcefactor *= kw;
+ case SB_HANDLE:
+ forcefactor *= kw;
break;
case SB_BEND:
- forcefactor *=sb->secondspring*kw;
+ forcefactor *=sb->secondspring*kw;
break;
case SB_STIFFQUAD:
- forcefactor *=sb->shearstiff*sb->shearstiff* kw;
+ forcefactor *=sb->shearstiff*sb->shearstiff* kw;
break;
default:
break;
@@ -2119,12 +2159,12 @@ static void sb_spring_force(Object *ob,int bpi,BodySpring *bs,float iks,float fo
//int op =3*sb->totpoint;
//float mvel = -forcetime*kd;
//float mpos = -forcetime*forcefactor;
- /* depending on my pos */
+ /* depending on my pos */
// dfdx_spring(ia,ia,op,dir,bs->len,distance,-mpos);
/* depending on my vel */
// dfdv_goal(ia,ia,mvel); // well that ignores geometie
if(bp2->goal < SOFTGOALSNAP){ /* ommit this bp when it snaps */
- /* depending on other pos */
+ /* depending on other pos */
// dfdx_spring(ia,ic,op,dir,bs->len,distance,mpos);
/* depending on other vel */
// dfdv_goal(ia,ia,-mvel); // well that ignores geometie
@@ -2143,15 +2183,15 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo
int number_of_points_here = ilast - ifirst;
SoftBody *sb= ob->soft; /* is supposed to be there */
BodyPoint *bp;
-
+
/* intitialize */
if (sb) {
/* check conditions for various options */
- /* +++ could be done on object level to squeeze out the last bits of it */
+ /* +++ could be done on object level to squeeze out the last bits of it */
do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF));
do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL);
do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES));
- /* --- could be done on object level to squeeze out the last bits of it */
+ /* --- could be done on object level to squeeze out the last bits of it */
}
else {
printf("Error expected a SB here \n");
@@ -2166,29 +2206,29 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo
/* debugerin */
- bp = &sb->bpoint[ifirst];
+ bp = &sb->bpoint[ifirst];
for(bb=number_of_points_here; bb>0; bb--, bp++) {
/* clear forces accumulator */
bp->force[0]= bp->force[1]= bp->force[2]= 0.0;
/* naive ball self collision */
/* needs to be done if goal snaps or not */
if(do_selfcollision){
- int attached;
+ int attached;
BodyPoint *obp;
- BodySpring *bs;
+ BodySpring *bs;
int c,b;
float velcenter[3],dvel[3],def[3];
float distance;
float compare;
- float bstune = sb->ballstiff;
+ float bstune = sb->ballstiff;
for(c=sb->totpoint, obp= sb->bpoint; c>=ifirst+bb; c--, obp++) {
- compare = (obp->colball + bp->colball);
+ compare = (obp->colball + bp->colball);
sub_v3_v3v3(def, bp->pos, obp->pos);
/* rather check the AABBoxes before ever calulating the real distance */
/* mathematically it is completly nuts, but performace is pretty much (3) times faster */
if ((ABS(def[0]) > compare) || (ABS(def[1]) > compare) || (ABS(def[2]) > compare)) continue;
- distance = normalize_v3(def);
+ distance = normalize_v3(def);
if (distance < compare ){
/* exclude body points attached with a spring */
attached = 0;
@@ -2203,14 +2243,14 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo
mid_v3_v3v3(velcenter, bp->vec, obp->vec);
sub_v3_v3v3(dvel,velcenter,bp->vec);
- mul_v3_fl(dvel,bp->mass);
+ mul_v3_fl(dvel,_final_mass(ob,bp));
Vec3PlusStVec(bp->force,f*(1.0f-sb->balldamp),def);
Vec3PlusStVec(bp->force,sb->balldamp,dvel);
/* exploit force(a,b) == -force(b,a) part2/2 */
sub_v3_v3v3(dvel,velcenter,obp->vec);
- mul_v3_fl(dvel,bp->mass);
+ mul_v3_fl(dvel,_final_mass(ob,bp));
Vec3PlusStVec(obp->force,sb->balldamp,dvel);
Vec3PlusStVec(obp->force,-f*(1.0f-sb->balldamp),def);
@@ -2220,8 +2260,8 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo
}
/* naive ball self collision done */
- if(bp->goal < SOFTGOALSNAP){ /* ommit this bp when it snaps */
- float auxvect[3];
+ if(_final_goal(ob,bp) < SOFTGOALSNAP){ /* ommit this bp when it snaps */
+ float auxvect[3];
float velgoal[3];
/* do goal stuff */
@@ -2229,7 +2269,7 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo
/* true elastic goal */
float ks,kd;
sub_v3_v3v3(auxvect,bp->pos,bp->origT);
- ks = 1.0f/(1.0f- bp->goal*sb->goalspring)-1.0f ;
+ ks = 1.0f/(1.0f- _final_goal(ob,bp)*sb->goalspring)-1.0f ;
bp->force[0]+= -ks*(auxvect[0]);
bp->force[1]+= -ks*(auxvect[1]);
bp->force[2]+= -ks*(auxvect[2]);
@@ -2238,7 +2278,7 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo
sub_v3_v3v3(velgoal,bp->origS, bp->origE);
kd = sb->goalfrict * sb_fric_force_scale(ob) ;
add_v3_v3v3(auxvect,velgoal,bp->vec);
-
+
if (forcetime > 0.0 ) { /* make sure friction does not become rocket motor on time reversal */
bp->force[0]-= kd * (auxvect[0]);
bp->force[1]-= kd * (auxvect[1]);
@@ -2251,15 +2291,15 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo
}
}
/* done goal stuff */
-
+
/* gravitation */
- if (sb && scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY){
+ if (sb && scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY){
float gravity[3];
VECCOPY(gravity, scene->physics_settings.gravity);
- mul_v3_fl(gravity, sb_grav_force_scale(ob)*bp->mass*sb->effector_weights->global_gravity); /* individual mass of node here */
- add_v3_v3v3(bp->force, bp->force, gravity);
+ mul_v3_fl(gravity, sb_grav_force_scale(ob)*_final_mass(ob,bp)*sb->effector_weights->global_gravity); /* individual mass of node here */
+ add_v3_v3(bp->force, gravity);
}
-
+
/* particle field & vortex */
if(do_effector) {
EffectedPoint epoint;
@@ -2269,22 +2309,22 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo
float eval_sb_fric_force_scale = sb_fric_force_scale(ob); /* just for calling function once */
pd_point_from_soft(scene, bp->pos, bp->vec, sb->bpoint-bp, &epoint);
pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed);
-
+
/* apply forcefield*/
- mul_v3_fl(force,fieldfactor* eval_sb_fric_force_scale);
+ mul_v3_fl(force,fieldfactor* eval_sb_fric_force_scale);
VECADD(bp->force, bp->force, force);
-
- /* BP friction in moving media */
- kd= sb->mediafrict* eval_sb_fric_force_scale;
+
+ /* BP friction in moving media */
+ kd= sb->mediafrict* eval_sb_fric_force_scale;
bp->force[0] -= kd * (bp->vec[0] + windfactor*speed[0]/eval_sb_fric_force_scale);
bp->force[1] -= kd * (bp->vec[1] + windfactor*speed[1]/eval_sb_fric_force_scale);
bp->force[2] -= kd * (bp->vec[2] + windfactor*speed[2]/eval_sb_fric_force_scale);
/* now we'll have nice centrifugal effect for vortex */
-
+
}
else {
/* BP friction in media (not) moving*/
- float kd = sb->mediafrict* sb_fric_force_scale(ob);
+ float kd = sb->mediafrict* sb_fric_force_scale(ob);
/* assume it to be proportional to actual velocity */
bp->force[0]-= bp->vec[0]*kd;
bp->force[1]-= bp->vec[1]*kd;
@@ -2294,22 +2334,22 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo
/* +++cached collision targets */
bp->choke = 0.0f;
bp->choke2 = 0.0f;
- bp->flag &= ~SBF_DOFUZZY;
- if(do_deflector) {
+ bp->loc_flag &= ~SBF_DOFUZZY;
+ if(do_deflector && !(bp->loc_flag & SBF_OUTOFCOLLISION) ) {
float cfforce[3],defforce[3] ={0.0f,0.0f,0.0f}, vel[3] = {0.0f,0.0f,0.0f}, facenormal[3], cf = 1.0f,intrusion;
float kd = 1.0f;
if (sb_deflect_face(ob,bp->pos,facenormal,defforce,&cf,timenow,vel,&intrusion)){
if (intrusion < 0.0f){
sb->scratch->flag |= SBF_DOFUZZY;
- bp->flag |= SBF_DOFUZZY;
+ bp->loc_flag |= SBF_DOFUZZY;
bp->choke = sb->choke*0.01f;
}
VECSUB(cfforce,bp->vec,vel);
Vec3PlusStVec(bp->force,-cf*50.0f,cfforce);
-
- Vec3PlusStVec(bp->force,kd,defforce);
+
+ Vec3PlusStVec(bp->force,kd,defforce);
}
}
@@ -2320,19 +2360,19 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo
if(ob->softflag & OB_SB_EDGES) {
if (sb->bspring){ /* spring list exists at all ? */
int b;
- BodySpring *bs;
+ BodySpring *bs;
for(b=bp->nofsprings;b>0;b--){
bs = sb->bspring + bp->springs[b-1];
if (do_springcollision || do_aero){
- add_v3_v3v3(bp->force,bp->force,bs->ext_force);
+ add_v3_v3(bp->force, bs->ext_force);
if (bs->flag & BSF_INTERSECT)
- bp->choke = bs->cf;
+ bp->choke = bs->cf;
}
- // sb_spring_force(Object *ob,int bpi,BodySpring *bs,float iks,float forcetime,int nl_flags)
+ // sb_spring_force(Object *ob,int bpi,BodySpring *bs,float iks,float forcetime,int nl_flags)
sb_spring_force(ob,ilast-bb,bs,iks,forcetime,0);
}/* loop springs */
- }/* existing spring list */
+ }/* existing spring list */
}/*any edges*/
/* ---springs */
}/*omit on snap */
@@ -2343,9 +2383,9 @@ return 0; /*done fine*/
static void *exec_softbody_calc_forces(void *data)
{
SB_thread_context *pctx = (SB_thread_context*)data;
- _softbody_calc_forces_slice_in_a_thread(pctx->scene, pctx->ob, pctx->forcetime, pctx->timenow, pctx->ifirst, pctx->ilast, NULL, pctx->do_effector,pctx->do_deflector,pctx->fieldfactor,pctx->windfactor);
+ _softbody_calc_forces_slice_in_a_thread(pctx->scene, pctx->ob, pctx->forcetime, pctx->timenow, pctx->ifirst, pctx->ilast, NULL, pctx->do_effector,pctx->do_deflector,pctx->fieldfactor,pctx->windfactor);
return 0;
-}
+}
static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float timenow,int totpoint,int *ptr_to_break_func(),struct ListBase *do_effector,int do_deflector,float fieldfactor, float windfactor)
{
@@ -2364,7 +2404,7 @@ static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float t
totthread--;
}
- /* printf("sb_cf_threads_run spawning %d threads \n",totthread); */
+ /* printf("sb_cf_threads_run spawning %d threads \n",totthread); */
sb_threads= MEM_callocN(sizeof(SB_thread_context)*totthread, "SBThread");
memset(sb_threads, 0, sizeof(SB_thread_context)*totthread);
@@ -2372,18 +2412,18 @@ static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float t
dec = totpoint/totthread +1;
for(i=0; i<totthread; i++) {
sb_threads[i].scene = scene;
- sb_threads[i].ob = ob;
- sb_threads[i].forcetime = forcetime;
- sb_threads[i].timenow = timenow;
- sb_threads[i].ilast = left;
+ sb_threads[i].ob = ob;
+ sb_threads[i].forcetime = forcetime;
+ sb_threads[i].timenow = timenow;
+ sb_threads[i].ilast = left;
left = left - dec;
if (left >0){
sb_threads[i].ifirst = left;
}
else
- sb_threads[i].ifirst = 0;
- sb_threads[i].do_effector = do_effector;
- sb_threads[i].do_deflector = do_deflector;
+ sb_threads[i].ifirst = 0;
+ sb_threads[i].do_effector = do_effector;
+ sb_threads[i].do_deflector = do_deflector;
sb_threads[i].fieldfactor = fieldfactor;
sb_threads[i].windfactor = windfactor;
sb_threads[i].nr= i;
@@ -2401,36 +2441,36 @@ static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float t
}
else
exec_softbody_calc_forces(&sb_threads[0]);
- /* clean up */
+ /* clean up */
MEM_freeN(sb_threads);
}
static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, float timenow, int nl_flags)
{
-/* rule we never alter free variables :bp->vec bp->pos in here !
- * this will ruin adaptive stepsize AKA heun! (BM)
+/* rule we never alter free variables :bp->vec bp->pos in here !
+ * this will ruin adaptive stepsize AKA heun! (BM)
*/
SoftBody *sb= ob->soft; /* is supposed to be there */
BodyPoint *bproot;
ListBase *do_effector = NULL;
float iks, gravity;
- float fieldfactor = -1.0f, windfactor = 0.25;
+ float fieldfactor = -1.0f, windfactor = 0.25;
int do_deflector,do_selfcollision,do_springcollision,do_aero;
-
- gravity = sb->grav * sb_grav_force_scale(ob);
-
+
+ gravity = sb->grav * sb_grav_force_scale(ob);
+
/* check conditions for various options */
do_deflector= query_external_colliders(scene, ob);
do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF));
do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL);
do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES));
-
+
iks = 1.0f/(1.0f-sb->inspring)-1.0f ;/* inner spring constants function */
bproot= sb->bpoint; /* need this for proper spring addressing */
-
- if (do_springcollision || do_aero)
- sb_sfesf_threads_run(scene, ob, timenow,sb->totspring,NULL);
-
+
+ if (do_springcollision || do_aero)
+ sb_sfesf_threads_run(scene, ob, timenow,sb->totspring,NULL);
+
/* after spring scan because it uses Effoctors too */
do_effector= pdInitEffectors(scene, ob, NULL, sb->effector_weights);
@@ -2443,7 +2483,7 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl
/* finally add forces caused by face collision */
if (ob->softflag & OB_SB_FACECOLL) scan_for_ext_face_forces(ob,timenow);
-
+
/* finish matrix and solve */
pdEndEffectors(&do_effector);
}
@@ -2463,20 +2503,20 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
/* |||||||||||||||||||||||||| */
/* VVVVVVVVVVVVVVVVVVVVVVVVVV */
/*backward compatibility note:
- fixing bug [17428] which forces adaptive step size to tiny steps
- in some situations
+ fixing bug [17428] which forces adaptive step size to tiny steps
+ in some situations
.. keeping G.rt==17 0x11 option for old files 'needing' the bug*/
- /* rule we never alter free variables :bp->vec bp->pos in here !
- * this will ruin adaptive stepsize AKA heun! (BM)
+ /* rule we never alter free variables :bp->vec bp->pos in here !
+ * this will ruin adaptive stepsize AKA heun! (BM)
*/
SoftBody *sb= ob->soft; /* is supposed to be there */
BodyPoint *bp;
BodyPoint *bproot;
- BodySpring *bs;
+ BodySpring *bs;
ListBase *do_effector = NULL;
float iks, ks, kd, gravity[3] = {0.0f,0.0f,0.0f};
- float fieldfactor = -1.0f, windfactor = 0.25f;
+ float fieldfactor = -1.0f, windfactor = 0.25f;
float tune = sb->ballstiff;
int a, b, do_deflector,do_selfcollision,do_springcollision,do_aero;
@@ -2491,10 +2531,10 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
*/
- if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY){
+ if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY){
VECCOPY(gravity, scene->physics_settings.gravity);
mul_v3_fl(gravity, sb_grav_force_scale(ob)*sb->effector_weights->global_gravity);
- }
+ }
/* check conditions for various options */
do_deflector= query_external_colliders(scene, ob);
@@ -2520,7 +2560,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
if(nl_flags & NLF_BUILD){
//int ia =3*(sb->totpoint-a);
//int op =3*sb->totpoint;
- /* dF/dV = v */
+ /* dF/dV = v */
/* jacobioan
nlMatrixAdd(op+ia,ia,-forcetime);
nlMatrixAdd(op+ia+1,ia+1,-forcetime);
@@ -2552,7 +2592,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
//if ((bp->octantflag & obp->octantflag) == 0) continue;
- compare = (obp->colball + bp->colball);
+ compare = (obp->colball + bp->colball);
sub_v3_v3v3(def, bp->pos, obp->pos);
/* rather check the AABBoxes before ever calulating the real distance */
@@ -2574,7 +2614,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
mid_v3_v3v3(velcenter, bp->vec, obp->vec);
sub_v3_v3v3(dvel,velcenter,bp->vec);
- mul_v3_fl(dvel,bp->mass);
+ mul_v3_fl(dvel,_final_mass(ob,bp));
Vec3PlusStVec(bp->force,f*(1.0f-sb->balldamp),def);
Vec3PlusStVec(bp->force,sb->balldamp,dvel);
@@ -2596,16 +2636,16 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
/*TODO sit down an X-out the true jacobian entries*/
/*well does not make to much sense because the eigenvalues
of the jacobian go negative; and negative eigenvalues
- on a complex iterative system z(n+1)=A * z(n)
+ on a complex iterative system z(n+1)=A * z(n)
give imaginary roots in the charcateristic polynom
- --> solutions that to z(t)=u(t)* exp ( i omega t) --> oscilations we don't want here
+ --> solutions that to z(t)=u(t)* exp ( i omega t) --> oscilations we don't want here
where u(t) is a unknown amplitude function (worst case rising fast)
- */
+ */
}
/* exploit force(a,b) == -force(b,a) part2/2 */
sub_v3_v3v3(dvel,velcenter,obp->vec);
- mul_v3_fl(dvel,(bp->mass+obp->mass)/2.0f);
+ mul_v3_fl(dvel,(_final_mass(ob,bp)+_final_mass(ob,obp))/2.0f);
Vec3PlusStVec(obp->force,sb->balldamp,dvel);
Vec3PlusStVec(obp->force,-f*(1.0f-sb->balldamp),def);
@@ -2617,15 +2657,15 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
}
/* naive ball self collision done */
- if(bp->goal < SOFTGOALSNAP){ /* ommit this bp when it snaps */
- float auxvect[3];
+ if(_final_goal(ob,bp) < SOFTGOALSNAP){ /* ommit this bp when it snaps */
+ float auxvect[3];
float velgoal[3];
/* do goal stuff */
if(ob->softflag & OB_SB_GOAL) {
/* true elastic goal */
sub_v3_v3v3(auxvect,bp->pos,bp->origT);
- ks = 1.0f/(1.0f- bp->goal*sb->goalspring)-1.0f ;
+ ks = 1.0f/(1.0f- _final_goal(ob,bp)*sb->goalspring)-1.0f ;
bp->force[0]+= -ks*(auxvect[0]);
bp->force[1]+= -ks*(auxvect[1]);
bp->force[2]+= -ks*(auxvect[2]);
@@ -2633,7 +2673,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
if(nl_flags & NLF_BUILD){
//int ia =3*(sb->totpoint-a);
//int op =3*(sb->totpoint);
- /* depending on my pos */
+ /* depending on my pos */
//dfdx_goal(ia,ia,op,ks*forcetime);
}
@@ -2650,7 +2690,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
if(nl_flags & NLF_BUILD){
//int ia =3*(sb->totpoint-a);
normalize_v3(auxvect);
- /* depending on my vel */
+ /* depending on my vel */
//dfdv_goal(ia,ia,kd*forcetime);
}
@@ -2665,7 +2705,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
/* gravitation */
- VECADDFAC(bp->force, bp->force, gravity, bp->mass); /* individual mass of node here */
+ VECADDFAC(bp->force, bp->force, gravity, _final_mass(ob,bp)); /* individual mass of node here */
/* particle field & vortex */
@@ -2678,11 +2718,11 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed);
/* apply forcefield*/
- mul_v3_fl(force,fieldfactor* eval_sb_fric_force_scale);
+ mul_v3_fl(force,fieldfactor* eval_sb_fric_force_scale);
VECADD(bp->force, bp->force, force);
- /* BP friction in moving media */
- kd= sb->mediafrict* eval_sb_fric_force_scale;
+ /* BP friction in moving media */
+ kd= sb->mediafrict* eval_sb_fric_force_scale;
bp->force[0] -= kd * (bp->vec[0] + windfactor*speed[0]/eval_sb_fric_force_scale);
bp->force[1] -= kd * (bp->vec[1] + windfactor*speed[1]/eval_sb_fric_force_scale);
bp->force[2] -= kd * (bp->vec[2] + windfactor*speed[2]/eval_sb_fric_force_scale);
@@ -2691,7 +2731,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
}
else {
/* BP friction in media (not) moving*/
- kd= sb->mediafrict* sb_fric_force_scale(ob);
+ kd= sb->mediafrict* sb_fric_force_scale(ob);
/* assume it to be proportional to actual velocity */
bp->force[0]-= bp->vec[0]*kd;
bp->force[1]-= bp->vec[1]*kd;
@@ -2699,7 +2739,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
/* friction in media done */
if(nl_flags & NLF_BUILD){
//int ia =3*(sb->totpoint-a);
- /* da/dv = */
+ /* da/dv = */
// nlMatrixAdd(ia,ia,forcetime*kd);
// nlMatrixAdd(ia+1,ia+1,forcetime*kd);
@@ -2710,7 +2750,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
/* +++cached collision targets */
bp->choke = 0.0f;
bp->choke2 = 0.0f;
- bp->flag &= ~SBF_DOFUZZY;
+ bp->loc_flag &= ~SBF_DOFUZZY;
if(do_deflector) {
float cfforce[3],defforce[3] ={0.0f,0.0f,0.0f}, vel[3] = {0.0f,0.0f,0.0f}, facenormal[3], cf = 1.0f,intrusion;
kd = 1.0f;
@@ -2718,15 +2758,15 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
if (sb_deflect_face(ob,bp->pos,facenormal,defforce,&cf,timenow,vel,&intrusion)){
if ((!nl_flags)&&(intrusion < 0.0f)){
if(G.rt & 0x01){ // 17 we did check for bit 0x10 before
- /*fixing bug [17428] this forces adaptive step size to tiny steps
+ /*fixing bug [17428] this forces adaptive step size to tiny steps
in some situations .. keeping G.rt==17 option for old files 'needing' the bug
*/
- /*bjornmose: uugh.. what an evil hack
- violation of the 'don't touch bp->pos in here' rule
+ /*bjornmose: uugh.. what an evil hack
+ violation of the 'don't touch bp->pos in here' rule
but works nice, like this-->
we predict the solution beeing out of the collider
in heun step No1 and leave the heun step No2 adapt to it
- so we kind of introduced a implicit solver for this case
+ so we kind of introduced a implicit solver for this case
*/
Vec3PlusStVec(bp->pos,-intrusion,facenormal);
}
@@ -2738,7 +2778,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
sb->scratch->flag |= SBF_DOFUZZY;
- bp->flag |= SBF_DOFUZZY;
+ bp->loc_flag |= SBF_DOFUZZY;
bp->choke = sb->choke*0.01f;
}
else{
@@ -2765,16 +2805,16 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
for(b=bp->nofsprings;b>0;b--){
bs = sb->bspring + bp->springs[b-1];
if (do_springcollision || do_aero){
- add_v3_v3v3(bp->force,bp->force,bs->ext_force);
+ add_v3_v3(bp->force, bs->ext_force);
if (bs->flag & BSF_INTERSECT)
- bp->choke = bs->cf;
+ bp->choke = bs->cf;
}
// sb_spring_force(Object *ob,int bpi,BodySpring *bs,float iks,float forcetime,int nl_flags)
// rather remove nl_falgs from code .. will make things a lot cleaner
sb_spring_force(ob,sb->totpoint-a,bs,iks,forcetime,0);
}/* loop springs */
- }/* existing spring list */
+ }/* existing spring list */
}/*any edges*/
/* ---springs */
}/*omit on snap */
@@ -2799,7 +2839,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
nlEnd(NL_SYSTEM);
if ((G.rt == 32) && (nl_flags & NLF_BUILD))
- {
+ {
printf("####MEE#####\n");
nlPrintMatrix();
}
@@ -2870,36 +2910,36 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
float maxerrpos= 0.0f,maxerrvel = 0.0f;
int a,fuzzy=0;
- forcetime *= sb_time_scale(ob);
-
- aabbmin[0]=aabbmin[1]=aabbmin[2] = 1e20f;
- aabbmax[0]=aabbmax[1]=aabbmax[2] = -1e20f;
+ forcetime *= sb_time_scale(ob);
- /* old one with homogenous masses */
+ aabbmin[0]=aabbmin[1]=aabbmin[2] = 1e20f;
+ aabbmax[0]=aabbmax[1]=aabbmax[2] = -1e20f;
+
+ /* old one with homogenous masses */
/* claim a minimum mass for vertex */
/*
if (sb->nodemass > 0.009999f) timeovermass = forcetime/sb->nodemass;
else timeovermass = forcetime/0.009999f;
*/
-
+
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
/* now we have individual masses */
/* claim a minimum mass for vertex */
- if (bp->mass > 0.009999f) timeovermass = forcetime/bp->mass;
- else timeovermass = forcetime/0.009999f;
+ if (_final_mass(ob,bp) > 0.009999f) timeovermass = forcetime/_final_mass(ob,bp);
+ else timeovermass = forcetime/0.009999f;
- if(bp->goal < SOFTGOALSNAP){
- /* this makes t~ = t */
+ if(_final_goal(ob,bp) < SOFTGOALSNAP){
+ /* this makes t~ = t */
if(mid_flags & MID_PRESERVE) VECCOPY(dx,bp->vec);
-
+
/* so here is (v)' = a(cceleration) = sum(F_springs)/m + gravitation + some friction forces + more forces*/
/* the ( ... )' operator denotes derivate respective time */
/* the euler step for velocity then becomes */
- /* v(t + dt) = v(t) + a(t) * dt */
+ /* v(t + dt) = v(t) + a(t) * dt */
mul_v3_fl(bp->force,timeovermass);/* individual mass of node here */
/* some nasty if's to have heun in here too */
- VECCOPY(dv,bp->force);
+ VECCOPY(dv,bp->force);
if (mode == 1){
VECCOPY(bp->prevvec, bp->vec);
@@ -2918,12 +2958,12 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
}
else {VECADD(bp->vec, bp->vec, bp->force);}
- /* this makes t~ = t+dt */
+ /* this makes t~ = t+dt */
if(!(mid_flags & MID_PRESERVE)) VECCOPY(dx,bp->vec);
/* so here is (x)'= v(elocity) */
/* the euler step for location then becomes */
- /* x(t + dt) = x(t) + v(t~) * dt */
+ /* x(t + dt) = x(t) + v(t~) * dt */
mul_v3_fl(dx,forcetime);
/* the freezer coming sooner or later */
@@ -2935,13 +2975,13 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
bp->frozen =MIN2(bp->frozen*1.05f,1.0f);
}
mul_v3_fl(dx,bp->frozen);
- */
+ */
/* again some nasty if's to have heun in here too */
if (mode ==1){
VECCOPY(bp->prevpos,bp->pos);
VECCOPY(bp->prevdx ,dx);
}
-
+
if (mode ==2){
bp->pos[0] = bp->prevpos[0] + 0.5f * ( dx[0] + bp->prevdx[0]);
bp->pos[1] = bp->prevpos[1] + 0.5f * ( dx[1] + bp->prevdx[1]);
@@ -2950,9 +2990,9 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
maxerrpos = MAX2(maxerrpos,ABS(dx[1] - bp->prevdx[1]));
maxerrpos = MAX2(maxerrpos,ABS(dx[2] - bp->prevdx[2]));
-/* bp->choke is set when we need to pull a vertex or edge out of the collider.
- the collider object signals to get out by pushing hard. on the other hand
- we don't want to end up in deep space so we add some <viscosity>
+/* bp->choke is set when we need to pull a vertex or edge out of the collider.
+ the collider object signals to get out by pushing hard. on the other hand
+ we don't want to end up in deep space so we add some <viscosity>
to balance that out */
if (bp->choke2 > 0.0f){
mul_v3_fl(bp->vec,(1.0f - bp->choke2));
@@ -2971,7 +3011,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
aabbmax[0] = MAX2(aabbmax[0],bp->pos[0]);
aabbmax[1] = MAX2(aabbmax[1],bp->pos[1]);
aabbmax[2] = MAX2(aabbmax[2],bp->pos[2]);
- if (bp->flag & SBF_DOFUZZY) fuzzy =1;
+ if (bp->loc_flag & SBF_DOFUZZY) fuzzy =1;
} /*for*/
if (sb->totpoint) mul_v3_fl(cm,1.0f/sb->totpoint);
@@ -2979,7 +3019,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
VECCOPY(sb->scratch->aabbmin,aabbmin);
VECCOPY(sb->scratch->aabbmax,aabbmax);
}
-
+
if (err){ /* so step size will be controlled by biggest difference in slope */
if (sb->solverflags & SBSO_OLDERR)
*err = MAX2(maxerrpos,maxerrvel);
@@ -2998,7 +3038,7 @@ static void softbody_restore_prev_step(Object *ob)
SoftBody *sb= ob->soft; /* is supposed to be there*/
BodyPoint *bp;
int a;
-
+
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
VECCOPY(bp->vec, bp->prevvec);
VECCOPY(bp->pos, bp->prevpos);
@@ -3011,7 +3051,7 @@ static void softbody_store_step(Object *ob)
SoftBody *sb= ob->soft; /* is supposed to be there*/
BodyPoint *bp;
int a;
-
+
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
VECCOPY(bp->prevvec,bp->vec);
VECCOPY(bp->prevpos,bp->pos);
@@ -3026,12 +3066,12 @@ static void softbody_store_state(Object *ob,float *ppos,float *pvel)
BodyPoint *bp;
int a;
float *pp=ppos,*pv=pvel;
-
+
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
-
- VECCOPY(pv, bp->vec);
+
+ VECCOPY(pv, bp->vec);
pv+=3;
-
+
VECCOPY(pp, bp->pos);
pp+=3;
}
@@ -3044,12 +3084,12 @@ static void softbody_retrieve_state(Object *ob,float *ppos,float *pvel)
BodyPoint *bp;
int a;
float *pp=ppos,*pv=pvel;
-
+
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
-
- VECCOPY(bp->vec,pv);
+
+ VECCOPY(bp->vec,pv);
pv+=3;
-
+
VECCOPY(bp->pos,pp);
pp+=3;
}
@@ -3063,17 +3103,17 @@ static void softbody_swap_state(Object *ob,float *ppos,float *pvel)
int a;
float *pp=ppos,*pv=pvel;
float temp[3];
-
+
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
-
- VECCOPY(temp, bp->vec);
- VECCOPY(bp->vec,pv);
- VECCOPY(pv,temp);
+
+ VECCOPY(temp, bp->vec);
+ VECCOPY(bp->vec,pv);
+ VECCOPY(pv,temp);
pv+=3;
-
+
VECCOPY(temp, bp->pos);
- VECCOPY(bp->pos,pp);
- VECCOPY(pp,temp);
+ VECCOPY(bp->pos,pp);
+ VECCOPY(pp,temp);
pp+=3;
}
}
@@ -3082,8 +3122,8 @@ static void softbody_swap_state(Object *ob,float *ppos,float *pvel)
/* care for bodypoints taken out of the 'ordinary' solver step
** because they are screwed to goal by bolts
-** they just need to move along with the goal in time
-** we need to adjust them on sub frame timing in solver
+** they just need to move along with the goal in time
+** we need to adjust them on sub frame timing in solver
** so now when frame is done .. put 'em to the position at the end of frame
*/
static void softbody_apply_goalsnap(Object *ob)
@@ -3091,12 +3131,12 @@ static void softbody_apply_goalsnap(Object *ob)
SoftBody *sb= ob->soft; /* is supposed to be there */
BodyPoint *bp;
int a;
-
+
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
- if (bp->goal >= SOFTGOALSNAP){
+ if (_final_goal(ob,bp) >= SOFTGOALSNAP){
VECCOPY(bp->prevpos,bp->pos);
VECCOPY(bp->pos,bp->origT);
- }
+ }
}
}
@@ -3131,39 +3171,39 @@ static void interpolate_exciter(Object *ob, int timescale, int time)
BodyPoint *bp;
float f;
int a;
-
+
f = (float)time/(float)timescale;
-
- for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
- bp->origT[0] = bp->origS[0] + f*(bp->origE[0] - bp->origS[0]);
- bp->origT[1] = bp->origS[1] + f*(bp->origE[1] - bp->origS[1]);
- bp->origT[2] = bp->origS[2] + f*(bp->origE[2] - bp->origS[2]);
- if (bp->goal >= SOFTGOALSNAP){
+
+ for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
+ bp->origT[0] = bp->origS[0] + f*(bp->origE[0] - bp->origS[0]);
+ bp->origT[1] = bp->origS[1] + f*(bp->origE[1] - bp->origS[1]);
+ bp->origT[2] = bp->origS[2] + f*(bp->origE[2] - bp->origS[2]);
+ if (_final_goal(ob,bp) >= SOFTGOALSNAP){
bp->vec[0] = bp->origE[0] - bp->origS[0];
bp->vec[1] = bp->origE[1] - bp->origS[1];
bp->vec[2] = bp->origE[2] - bp->origS[2];
}
}
-
+
}
/* ************ convertors ********** */
/* for each object type we need;
- - xxxx_to_softbody(Object *ob) : a full (new) copy, creates SB geometry
+ - xxxx_to_softbody(Object *ob) : a full (new) copy, creates SB geometry
*/
static void get_scalar_from_vertexgroup(Object *ob, int vertID, short groupindex, float *target)
/* result 0 on success, else indicates error number
-- kind of *inverse* result defintion,
--- but this way we can signal error condition to caller
+-- but this way we can signal error condition to caller
-- and yes this function must not be here but in a *vertex group module*
*/
{
MDeformVert *dv= NULL;
int i;
-
+
/* spot the vert in deform vert list at mesh */
if(ob->type==OB_MESH) {
Mesh *me= ob->data;
@@ -3184,10 +3224,10 @@ static void get_scalar_from_vertexgroup(Object *ob, int vertID, short groupindex
}
}
}
-}
+}
-/* Resetting a Mesh SB object's springs */
-/* Spring lenght are caculted from'raw' mesh vertices that are NOT altered by modifier stack. */
+/* Resetting a Mesh SB object's springs */
+/* Spring lenght are caculted from'raw' mesh vertices that are NOT altered by modifier stack. */
static void springs_from_mesh(Object *ob)
{
SoftBody *sb;
@@ -3195,21 +3235,21 @@ static void springs_from_mesh(Object *ob)
BodyPoint *bp;
int a;
float scale =1.0f;
-
- sb= ob->soft;
+
+ sb= ob->soft;
if (me && sb)
- {
+ {
/* using bp->origS as a container for spring calcualtions here
- ** will be overwritten sbObjectStep() to receive
+ ** will be overwritten sbObjectStep() to receive
** actual modifier stack positions
*/
- if(me->totvert) {
+ if(me->totvert) {
bp= ob->soft->bpoint;
for(a=0; a<me->totvert; a++, bp++) {
- VECCOPY(bp->origS, me->mvert[a].co);
+ VECCOPY(bp->origS, me->mvert[a].co);
mul_m4_v3(ob->obmat, bp->origS);
}
-
+
}
/* recalculate spring length for meshes here */
/* public version shrink to fit */
@@ -3224,6 +3264,8 @@ static void springs_from_mesh(Object *ob)
}
+
+
/* makes totally fresh start situation */
static void mesh_to_softbody(Scene *scene, Object *ob)
{
@@ -3232,39 +3274,44 @@ static void mesh_to_softbody(Scene *scene, Object *ob)
MEdge *medge= me->medge;
BodyPoint *bp;
BodySpring *bs;
- float goalfac;
int a, totedge;
if (ob->softflag & OB_SB_EDGES) totedge= me->totedge;
else totedge= 0;
-
+
/* renew ends with ob->soft with points and edges, also checks & makes ob->soft */
renew_softbody(scene, ob, me->totvert, totedge);
-
+
/* we always make body points */
- sb= ob->soft;
+ sb= ob->soft;
bp= sb->bpoint;
- goalfac= ABS(sb->maxgoal - sb->mingoal);
-
+
for(a=0; a<me->totvert; a++, bp++) {
/* get scalar values needed *per vertex* from vertex group functions,
- so we can *paint* them nicly ..
+ so we can *paint* them nicly ..
they are normalized [0.0..1.0] so may be we need amplitude for scale
- which can be done by caller but still .. i'd like it to go this way
- */
-
- if((ob->softflag & OB_SB_GOAL) && sb->vertgroup) {
+ which can be done by caller but still .. i'd like it to go this way
+ */
+
+ if((ob->softflag & OB_SB_GOAL) && sb->vertgroup) { /* even this is a deprecated evil hack */
+ /* I'd like to have it .. if (sb->namedVG_Goal[0]) */
+
get_scalar_from_vertexgroup(ob, a,(short) (sb->vertgroup-1), &bp->goal);
/* do this always, regardless successfull read from vertex group */
- bp->goal= sb->mingoal + bp->goal*goalfac;
+ /* this is where '2.5 every thing is animateable' goes wrong in the first place jow_go_for2_5 */
+ /* 1st coding action to take : move this to frame level */
+ /* reads: leave the bp->goal as it was read from vertex group / or default .. we will need it at per frame call */
+ /* should be fixed for meshes */
+ // bp->goal= sb->mingoal + bp->goal*goalfac; /* do not do here jow_go_for2_5 */
+ }
+ else{
+ /* in consequence if no group was set .. but we want to animate it laters */
+ /* logically attach to goal with default first */
+ if(ob->softflag & OB_SB_GOAL){bp->goal =sb->defgoal;}
}
- /* a little ad hoc changing the goal control to be less *sharp* */
- bp->goal = (float)pow(bp->goal, 4.0f);
-
+
/* to proove the concept
- this would enable per vertex *mass painting*
+ this enables per vertex *mass painting*
*/
- /* first set the default */
- bp->mass = sb->nodemass;
if (sb->namedVG_Mass[0])
{
@@ -3272,7 +3319,7 @@ static void mesh_to_softbody(Scene *scene, Object *ob)
/* printf("VGN %s %d \n",sb->namedVG_Mass,grp); */
if(grp > -1){
get_scalar_from_vertexgroup(ob, a,(short) (grp), &bp->mass);
- bp->mass = bp->mass * sb->nodemass;
+ /* 2.5 bp->mass = bp->mass * sb->nodemass; */
/* printf("bp->mass %f \n",bp->mass); */
}
@@ -3283,7 +3330,7 @@ static void mesh_to_softbody(Scene *scene, Object *ob)
if (sb->namedVG_Spring_K[0])
{
int grp= defgroup_name_index (ob,sb->namedVG_Spring_K);
- //printf("VGN %s %d \n",sb->namedVG_Spring_K,grp);
+ //printf("VGN %s %d \n",sb->namedVG_Spring_K,grp);
if(grp > -1){
get_scalar_from_vertexgroup(ob, a,(short) (grp), &bp->springweight);
//printf("bp->springweight %f \n",bp->springweight);
@@ -3291,7 +3338,7 @@ static void mesh_to_softbody(Scene *scene, Object *ob)
}
}
-
+
}
/* but we only optionally add body edge springs */
@@ -3303,13 +3350,13 @@ static void mesh_to_softbody(Scene *scene, Object *ob)
bs->v2= medge->v2;
bs->springtype=SB_EDGE;
}
-
-
+
+
/* insert *diagonal* springs in quads if desired */
if (ob->softflag & OB_SB_QUADS) {
add_mesh_quad_diag_springs(ob);
}
-
+
build_bps_springlist(ob); /* scan for springs attached to bodypoints ONCE */
/* insert *other second order* springs if desired */
if (sb->secondspring > 0.0000001f) {
@@ -3317,23 +3364,23 @@ static void mesh_to_softbody(Scene *scene, Object *ob)
build_bps_springlist(ob); /* yes we need to do it again*/
}
springs_from_mesh(ob); /* write the 'rest'-lenght of the springs */
- if (ob->softflag & OB_SB_SELF) {calculate_collision_balls(ob);}
-
+ if (ob->softflag & OB_SB_SELF) {calculate_collision_balls(ob);}
+
}
-
+
}
}
static void mesh_faces_to_scratch(Object *ob)
{
- SoftBody *sb= ob->soft;
+ SoftBody *sb= ob->soft;
Mesh *me= ob->data;
MFace *mface;
BodyFace *bodyface;
int a;
/* alloc and copy faces*/
-
+
bodyface = sb->scratch->bodyface = MEM_mallocN(sizeof(BodyFace)*me->totface,"SB_body_Faces");
//memcpy(sb->scratch->mface,me->mface,sizeof(MFace)*me->totface);
mface = me->mface;
@@ -3343,13 +3390,13 @@ static void mesh_faces_to_scratch(Object *ob)
bodyface->v3 = mface->v3;
bodyface->v4 = mface->v4;
bodyface->ext_force[0] = bodyface->ext_force[1] = bodyface->ext_force[2] = 0.0f;
- bodyface->flag =0;
+ bodyface->flag =0;
}
sb->scratch->totface = me->totface;
}
static void reference_to_scratch(Object *ob)
{
- SoftBody *sb= ob->soft;
+ SoftBody *sb= ob->soft;
ReferenceVert *rp;
BodyPoint *bp;
float accu_pos[3] ={0.f,0.f,0.f};
@@ -3362,7 +3409,7 @@ static void reference_to_scratch(Object *ob)
for(a=0; a<sb->totpoint; a++, rp++, bp++) {
VECCOPY(rp->pos,bp->pos);
VECADD(accu_pos,accu_pos,bp->pos);
- accu_mass += bp-> mass;
+ accu_mass += _final_mass(ob,bp);
}
mul_v3_fl(accu_pos,1.0f/accu_mass);
VECCOPY(sb->scratch->Ref.com,accu_pos);
@@ -3370,14 +3417,14 @@ static void reference_to_scratch(Object *ob)
}
/*
-helper function to get proper spring length
+helper function to get proper spring length
when object is rescaled
*/
static float globallen(float *v1,float *v2,Object *ob)
{
float p1[3],p2[3];
VECCOPY(p1,v1);
- mul_m4_v3(ob->obmat, p1);
+ mul_m4_v3(ob->obmat, p1);
VECCOPY(p2,v2);
mul_m4_v3(ob->obmat, p2);
return len_v3v3(p1,p2);
@@ -3387,16 +3434,16 @@ static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff,Object *
{
BPoint *bp=lt->def, *bpu;
int u, v, w, dv, dw, bpc=0, bpuc;
-
+
dv= lt->pntsu;
dw= dv*lt->pntsv;
-
+
for(w=0; w<lt->pntsw; w++) {
-
+
for(v=0; v<lt->pntsv; v++) {
-
+
for(u=0, bpuc=0, bpu=NULL; u<lt->pntsu; u++, bp++, bpc++) {
-
+
if(w) {
bs->v1 = bpc;
bs->v2 = bpc-dw;
@@ -3418,7 +3465,7 @@ static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff,Object *
bs->len= globallen((bpu)->vec, bp->vec,ob);
bs++;
}
-
+
if (dostiff) {
if(w){
@@ -3428,14 +3475,14 @@ static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff,Object *
bs->springtype=SB_BEND;
bs->len= globallen((bp-dw-dv-1)->vec, bp->vec,ob);
bs++;
- }
+ }
if( (v < lt->pntsv-1) && (u) ) {
bs->v1 = bpc;
bs->v2 = bpc-dw+dv-1;
bs->springtype=SB_BEND;
bs->len= globallen((bp-dw+dv-1)->vec, bp->vec,ob);
bs++;
- }
+ }
}
if(w < lt->pntsw -1){
@@ -3445,14 +3492,14 @@ static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff,Object *
bs->springtype=SB_BEND;
bs->len= globallen((bp+dw-dv-1)->vec, bp->vec,ob);
bs++;
- }
+ }
if( (v < lt->pntsv-1) && (u) ) {
bs->v1 = bpc;
bs->v2 = bpc+dw+dv-1;
bs->springtype=SB_BEND;
bs->len= globallen((bp+dw+dv-1)->vec, bp->vec,ob);
bs++;
- }
+ }
}
}
bpu = bp;
@@ -3473,35 +3520,33 @@ static void lattice_to_softbody(Scene *scene, Object *ob)
totvert= lt->pntsu*lt->pntsv*lt->pntsw;
if (ob->softflag & OB_SB_EDGES){
- totspring = ((lt->pntsu -1) * lt->pntsv
- + (lt->pntsv -1) * lt->pntsu) * lt->pntsw
+ totspring = ((lt->pntsu -1) * lt->pntsv
+ + (lt->pntsv -1) * lt->pntsu) * lt->pntsw
+lt->pntsu*lt->pntsv*(lt->pntsw -1);
if (ob->softflag & OB_SB_QUADS){
totspring += 4*(lt->pntsu -1) * (lt->pntsv -1) * (lt->pntsw-1);
}
}
-
+
/* renew ends with ob->soft with points and edges, also checks & makes ob->soft */
renew_softbody(scene, ob, totvert, totspring);
sb= ob->soft; /* can be created in renew_softbody() */
-
+
/* weights from bpoints, same code used as for mesh vertices */
/* if((ob->softflag & OB_SB_GOAL) && sb->vertgroup) { 2.4x one*/
/* new! take the weights from lattice vertex anyhow */
if(ob->softflag & OB_SB_GOAL){
BodyPoint *bp= sb->bpoint;
BPoint *bpnt= lt->def;
- float goalfac= ABS(sb->maxgoal - sb->mingoal);
+ /* jow_go_for2_5 */
int a;
for(a=0; a<totvert; a++, bp++, bpnt++) {
- bp->goal= sb->mingoal + bpnt->weight*goalfac;
- /* a little ad hoc changing the goal control to be less *sharp* */
- bp->goal = (float)pow(bp->goal, 4.0f);
+ bp->goal= bpnt->weight;
}
- }
-
+ }
+
/* create some helper edges to enable SB lattice to be usefull at all */
if (ob->softflag & OB_SB_EDGES){
makelatticesprings(lt,ob->soft->bspring,ob->softflag & OB_SB_QUADS,ob);
@@ -3519,63 +3564,66 @@ static void curve_surf_to_softbody(Scene *scene, Object *ob)
Nurb *nu;
BezTriple *bezt;
BPoint *bpnt;
- float goalfac;
int a, curindex=0;
int totvert, totspring = 0, setgoal=0;
-
+
totvert= count_curveverts(&cu->nurb);
-
+
if (ob->softflag & OB_SB_EDGES){
if(ob->type==OB_CURVE) {
totspring= totvert - BLI_countlist(&cu->nurb);
}
}
-
+
/* renew ends with ob->soft with points and edges, also checks & makes ob->soft */
renew_softbody(scene, ob, totvert, totspring);
sb= ob->soft; /* can be created in renew_softbody() */
-
+
/* set vars now */
- goalfac= ABS(sb->maxgoal - sb->mingoal);
bp= sb->bpoint;
bs= sb->bspring;
-
+
/* weights from bpoints, same code used as for mesh vertices */
/* if((ob->softflag & OB_SB_GOAL) && sb->vertgroup) 2.4x hack*/
/* new! take the weights from curve vertex anyhow */
- if(ob->softflag & OB_SB_GOAL)
+ if(ob->softflag & OB_SB_GOAL)
setgoal= 1;
-
+
for(nu= cu->nurb.first; nu; nu= nu->next) {
if(nu->bezt) {
+ /* bezier case ; this is nicly said naive; who ever wrote this part, it was not me (JOW) :) */
+ /* a: never ever make tangent handles (sub) and or (ob)ject to collision */
+ /* b: rather calculate them using some C2 (C2= continous in second derivate -> no jump in bending ) condition */
+ /* not too hard to do, but needs some more code to care for; some one may want look at it JOW 2010/06/12*/
for(bezt=nu->bezt, a=0; a<nu->pntsu; a++, bezt++, bp+=3, curindex+=3) {
if(setgoal) {
- bp->goal= sb->mingoal + bezt->weight*goalfac;
- /* a little ad hoc changing the goal control to be less *sharp* */
- bp->goal = (float)pow(bp->goal, 4.0f);
-
+ bp->goal= bezt->weight;
+
/* all three triples */
(bp+1)->goal= bp->goal;
(bp+2)->goal= bp->goal;
+ /*do not collide handles */
+ (bp+1)->loc_flag |= SBF_OUTOFCOLLISION;
+ (bp+2)->loc_flag |= SBF_OUTOFCOLLISION;
}
-
+
if(totspring) {
if(a>0) {
- bs->v1= curindex-1;
+ bs->v1= curindex-3;
bs->v2= curindex;
- bs->springtype=SB_EDGE;
- bs->len= globallen( (bezt-1)->vec[2], bezt->vec[0], ob );
+ bs->springtype=SB_HANDLE;
+ bs->len= globallen( (bezt-1)->vec[0], bezt->vec[0], ob );
bs++;
}
bs->v1= curindex;
bs->v2= curindex+1;
- bs->springtype=SB_EDGE;
+ bs->springtype=SB_HANDLE;
bs->len= globallen( bezt->vec[0], bezt->vec[1], ob );
bs++;
bs->v1= curindex+1;
bs->v2= curindex+2;
- bs->springtype=SB_EDGE;
+ bs->springtype=SB_HANDLE;
bs->len= globallen( bezt->vec[1], bezt->vec[2], ob );
bs++;
}
@@ -3584,9 +3632,7 @@ static void curve_surf_to_softbody(Scene *scene, Object *ob)
else {
for(bpnt=nu->bp, a=0; a<nu->pntsu*nu->pntsv; a++, bpnt++, bp++, curindex++) {
if(setgoal) {
- bp->goal= sb->mingoal + bpnt->weight*goalfac;
- /* a little ad hoc changing the goal control to be less *sharp* */
- bp->goal = (float)pow(bp->goal, 4.0f);
+ bp->goal= bpnt->weight;
}
if(totspring && a>0) {
bs->v1= curindex-1;
@@ -3598,7 +3644,7 @@ static void curve_surf_to_softbody(Scene *scene, Object *ob)
}
}
}
-
+
if(totspring)
{
build_bps_springlist(ob); /* link bps to springs */
@@ -3619,7 +3665,7 @@ static void softbody_to_object(Object *ob, float (*vertexCos)[3], int numVerts,
for(a=0; a<numVerts; a++, bp++) {
VECCOPY(vertexCos[a], bp->pos);
- if(local==0)
+ if(local==0)
mul_m4_v3(ob->imat, vertexCos[a]); /* softbody is in global coords, baked optionally not */
}
}
@@ -3630,13 +3676,13 @@ static void sb_new_scratch(SoftBody *sb)
{
if (!sb) return;
sb->scratch = MEM_callocN(sizeof(SBScratch), "SBScratch");
- sb->scratch->colliderhash = BLI_ghash_new(BLI_ghashutil_ptrhash,BLI_ghashutil_ptrcmp);
+ sb->scratch->colliderhash = BLI_ghash_new(BLI_ghashutil_ptrhash,BLI_ghashutil_ptrcmp, "sb_new_scratch gh");
sb->scratch->bodyface = NULL;
sb->scratch->totface = 0;
sb->scratch->aabbmax[0]=sb->scratch->aabbmax[1]=sb->scratch->aabbmax[2] = 1.0e30f;
sb->scratch->aabbmin[0]=sb->scratch->aabbmin[1]=sb->scratch->aabbmin[2] = -1.0e30f;
sb->scratch->Ref.ivert = NULL;
-
+
}
/* --- ************ maintaining scratch *************** */
@@ -3646,26 +3692,26 @@ static void sb_new_scratch(SoftBody *sb)
SoftBody *sbNew(Scene *scene)
{
SoftBody *sb;
-
+
sb= MEM_callocN(sizeof(SoftBody), "softbody");
-
- sb->mediafrict= 0.5f;
+
+ sb->mediafrict= 0.5f;
sb->nodemass= 1.0f;
- sb->grav= 9.8f;
+ sb->grav= 9.8f;
sb->physics_speed= 1.0f;
sb->rklimit= 0.1f;
- sb->goalspring= 0.5f;
- sb->goalfrict= 0.0f;
- sb->mingoal= 0.0f;
+ sb->goalspring= 0.5f;
+ sb->goalfrict= 0.0f;
+ sb->mingoal= 0.0f;
sb->maxgoal= 1.0f;
sb->defgoal= 0.7f;
-
+
sb->inspring= 0.5f;
- sb->infrict= 0.5f;
+ sb->infrict= 0.5f;
/*todo backward file compat should copy inspring to inpush while reading old files*/
- sb->inpush = 0.5f;
-
+ sb->inpush = 0.5f;
+
sb->interval= 10;
sb->sfra= scene->r.sfra;
sb->efra= scene->r.efra;
@@ -3717,7 +3763,7 @@ void sbObjectToSoftbody(Object *ob)
free_softbody_intern(ob->soft);
}
-static int object_has_edges(Object *ob)
+static int object_has_edges(Object *ob)
{
if(ob->type==OB_MESH) {
return ((Mesh*) ob->data)->totedge;
@@ -3730,7 +3776,7 @@ static int object_has_edges(Object *ob)
}
}
-/* SB global visible functions */
+/* SB global visible functions */
void sbSetInterruptCallBack(int (*f)(void))
{
SB_localInterruptCallBack = f;
@@ -3745,7 +3791,7 @@ static void softbody_update_positions(Object *ob, SoftBody *sb, float (*vertexCo
return;
for(a=0,bp=sb->bpoint; a<numVerts; a++, bp++) {
- /* store where goals are now */
+ /* store where goals are now */
VECCOPY(bp->origS, bp->origE);
/* copy the position of the goals at desired end time */
VECCOPY(bp->origE, vertexCos[a]);
@@ -3753,7 +3799,7 @@ static void softbody_update_positions(Object *ob, SoftBody *sb, float (*vertexCo
mul_m4_v3(ob->obmat, bp->origE);
/* just to be save give bp->origT a defined value
will be calulated in interpolate_exciter()*/
- VECCOPY(bp->origT, bp->origE);
+ VECCOPY(bp->origT, bp->origE);
}
}
@@ -3767,7 +3813,7 @@ static void softbody_update_positions(Object *ob, SoftBody *sb, float (*vertexCo
see: this is kind of reverse engeneering: having to states of a point cloud and recover what happend
our advantage here we know the identity of the vertex
there are others methods giving other results.
- lloc,lrot,lscale are allowed to be NULL, just in case you don't need it.
+ lloc,lrot,lscale are allowed to be NULL, just in case you don't need it.
should be pretty useful for pythoneers :)
not! velocity .. 2nd order stuff
vcloud_estimate_transform see
@@ -3788,10 +3834,10 @@ void SB_estimate_transform(Object *ob,float lloc[3],float lrot[3][3],float lscal
if(!sb || !sb->bpoint) return;
opos= MEM_callocN( (sb->totpoint)*3*sizeof(float), "SB_OPOS");
rpos= MEM_callocN( (sb->totpoint)*3*sizeof(float), "SB_RPOS");
- /* might filter vertex selection with a vertex group */
+ /* might filter vertex selection with a vertex group */
for(a=0, bp=sb->bpoint, rp=sb->scratch->Ref.ivert; a<sb->totpoint; a++, bp++, rp++) {
- VECCOPY(rpos[a],rp->pos);
- VECCOPY(opos[a],bp->pos);
+ VECCOPY(rpos[a],rp->pos);
+ VECCOPY(opos[a],bp->pos);
}
vcloud_estimate_transform(sb->totpoint, opos, NULL, rpos, NULL, com, rcom,lrot,lscale);
@@ -3801,7 +3847,7 @@ void SB_estimate_transform(Object *ob,float lloc[3],float lrot[3][3],float lscal
if (lscale) copy_m3_m3(sb->lscale,lscale);
if (lrot) copy_m3_m3(sb->lrot,lrot);
-
+
MEM_freeN(opos);
MEM_freeN(rpos);
}
@@ -3824,9 +3870,9 @@ static void softbody_reset(Object *ob, SoftBody *sb, float (*vertexCos)[3], int
1. set sheduled time step to new dtime
2. try to advance the sheduled time step, beeing optimistic execute it
3. check for success
- 3.a we 're fine continue, may be we can increase sheduled time again ?? if so, do so!
+ 3.a we 're fine continue, may be we can increase sheduled time again ?? if so, do so!
3.b we did exceed error limit --> roll back, shorten the sheduled time and try again at 2.
- 4. check if we did reach dtime
+ 4. check if we did reach dtime
4.a nope we need to do some more at 2.
4.b yup we're done
*/
@@ -3840,7 +3886,7 @@ static void softbody_reset(Object *ob, SoftBody *sb, float (*vertexCos)[3], int
/* make a nice clean scratch struc */
free_scratch(sb); /* clear if any */
sb_new_scratch(sb); /* make a new */
- sb->scratch->needstobuildcollider=1;
+ sb->scratch->needstobuildcollider=1;
zero_v3(sb->lcom);
unit_m3(sb->lrot);
unit_m3(sb->lscale);
@@ -3873,15 +3919,15 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
/* the simulator */
float forcetime;
double sct,sst;
-
-
+
+
sst=PIL_check_seconds_timer();
- /* Integration back in time is possible in theory, but pretty useless here.
+ /* Integration back in time is possible in theory, but pretty useless here.
So we refuse to do so. Since we do not know anything about 'outside' canges
especially colliders we refuse to go more than 10 frames.
*/
- if(dtime < 0 || dtime > 10.5f) return;
-
+ if(dtime < 0 || dtime > 10.5f) return;
+
ccd_update_deflector_hash(scene, ob, sb->scratch->colliderhash);
if(sb->scratch->needstobuildcollider){
@@ -3891,7 +3937,7 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
sb->scratch->needstobuildcollider=0;
}
- if (sb->solver_ID < 2) {
+ if (sb->solver_ID < 2) {
/* special case of 2nd order Runge-Kutta type AKA Heun */
int mid_flags=0;
float err = 0;
@@ -3901,21 +3947,21 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
/* loops = counter for emergency brake
* we don't want to lock up the system if physics fail
*/
- int loops =0 ;
-
+ int loops =0 ;
+
SoftHeunTol = sb->rklimit; /* humm .. this should be calculated from sb parameters and sizes */
/* adjust loop limits */
if (sb->minloops > 0) forcetimemax = dtime / sb->minloops;
if (sb->maxloops > 0) forcetimemin = dtime / sb->maxloops;
if(sb->solver_ID>0) mid_flags |= MID_PRESERVE;
-
+
forcetime =forcetimemax; /* hope for integrating in one step */
while ( (ABS(timedone) < ABS(dtime)) && (loops < 2000) )
{
- /* set goals in time */
+ /* set goals in time */
interpolate_exciter(ob,200,(int)(200.0*(timedone/dtime)));
-
+
sb->scratch->flag &= ~SBF_DOFUZZY;
/* do predictive euler step */
softbody_calc_forces(scene, ob, forcetime,timedone/dtime,0);
@@ -3927,9 +3973,9 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
softbody_apply_forces(ob, forcetime, 2, &err,mid_flags);
softbody_apply_goalsnap(ob);
-
+
if (err > SoftHeunTol) { /* error needs to be scaled to some quantity */
-
+
if (forcetime > forcetimemin){
forcetime = MAX2(forcetime / 2.0f,forcetimemin);
softbody_restore_prev_step(ob);
@@ -3941,7 +3987,7 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
}
else {
float newtime = forcetime * 1.1f; /* hope for 1.1 times better conditions in next step */
-
+
if (sb->scratch->flag & SBF_DOFUZZY){
//if (err > SoftHeunTol/(2.0f*sb->fuzzyness)) { /* stay with this stepsize unless err really small */
newtime = forcetime;
@@ -3957,7 +4003,7 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
//if (newtime > forcetime) printf("up,");
if (forcetime > 0.0)
forcetime = MIN2(dtime - timedone,newtime);
- else
+ else
forcetime = MAX2(dtime - timedone,newtime);
}
loops++;
@@ -3965,20 +4011,20 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
sct=PIL_check_seconds_timer();
if (sct-sst > 0.5f) printf("%3.0f%% \r",100.0f*timedone/dtime);
}
- /* ask for user break */
+ /* ask for user break */
if (SB_localInterruptCallBack && SB_localInterruptCallBack()) break;
}
/* move snapped to final position */
interpolate_exciter(ob, 2, 2);
softbody_apply_goalsnap(ob);
-
+
// if(G.f & G_DEBUG){
if(sb->solverflags & SBSO_MONITOR ){
if (loops > HEUNWARNLIMIT) /* monitor high loop counts */
printf("\r needed %d steps/frame",loops);
}
-
+
}
else if (sb->solver_ID == 2)
{/* do semi "fake" implicit euler */
@@ -4025,17 +4071,13 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
/* check for changes in mesh, should only happen in case the mesh
* structure changes during an animation */
if(sb->bpoint && numVerts != sb->totpoint) {
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
- cache->last_exact= 0;
+ BKE_ptcache_invalidate(cache);
return;
}
/* clamp frame ranges */
if(framenr < startframe) {
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
- //cache->last_exact= 0;
+ BKE_ptcache_invalidate(cache);
return;
}
else if(framenr > endframe) {
@@ -4068,8 +4110,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
/* continue physics special case */
if(BKE_ptcache_get_continue_physics()) {
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
+ BKE_ptcache_invalidate(cache);
/* do simulation */
dtime = timescale;
softbody_update_positions(ob, sb, vertexCos, numVerts);
@@ -4082,14 +4123,13 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
if(sb->totpoint==0) {
return;
}
- if(framenr == startframe) {
+ if(framenr == startframe) {
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
/* first frame, no simulation to do, just set the positions */
softbody_update_positions(ob, sb, vertexCos, numVerts);
- cache->simframe= framenr;
- cache->flag |= PTCACHE_SIMULATION_VALID;
+ BKE_ptcache_validate(cache, framenr);
cache->flag &= ~PTCACHE_REDO_NEEDED;
return;
}
@@ -4100,8 +4140,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) {
softbody_to_object(ob, vertexCos, numVerts, sb->local);
- cache->simframe= framenr;
- cache->flag |= PTCACHE_SIMULATION_VALID;
+ BKE_ptcache_validate(cache, framenr);
if(cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED)
BKE_ptcache_write_cache(&pid, framenr);
@@ -4109,13 +4148,11 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
return;
}
else if(cache_result==PTCACHE_READ_OLD) {
- cache->flag |= PTCACHE_SIMULATION_VALID;
+ ; /* do nothing */
}
else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
/* if baked and nothing in cache, do nothing */
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
- cache->last_exact= 0;
+ BKE_ptcache_invalidate(cache);
return;
}
@@ -4133,8 +4170,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i
softbody_to_object(ob, vertexCos, numVerts, 0);
- cache->simframe= framenr;
- cache->flag |= PTCACHE_SIMULATION_VALID;
+ BKE_ptcache_validate(cache, framenr);
BKE_ptcache_write_cache(&pid, framenr);
}
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index e014b209e07..6402f908422 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -14,10 +14,8 @@
#include "DNA_anim_types.h"
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
-#include "DNA_sound_types.h"
#include "DNA_packedFile_types.h"
#include "DNA_screen_types.h"
-#include "DNA_userdef_types.h"
#include "AUD_C-API.h"
@@ -31,14 +29,10 @@
#include "BKE_fcurve.h"
#include "BKE_animsys.h"
-#include "RNA_access.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
static int force_device = -1;
+#ifdef WITH_JACK
static void sound_sync_callback(void* data, int mode, float time)
{
struct Main* bmain = (struct Main*)data;
@@ -58,6 +52,7 @@ static void sound_sync_callback(void* data, int mode, float time)
scene = scene->id.next;
}
}
+#endif
int sound_define_from_str(char *str)
{
@@ -78,6 +73,11 @@ void sound_force_device(int device)
force_device = device;
}
+void sound_init_once()
+{
+ AUD_initOnce();
+}
+
void sound_init(struct Main *bmain)
{
AUD_DeviceSpecs specs;
@@ -125,7 +125,7 @@ struct bSound* sound_new_file(struct Main *bmain, char* filename)
int len;
strcpy(str, filename);
- BLI_convertstringcode(str, bmain->name);
+ BLI_path_abs(str, bmain->name);
len = strlen(filename);
while(len > 0 && filename[len-1] != '/' && filename[len-1] != '\\')
@@ -256,11 +256,11 @@ void sound_load(struct Main *bmain, struct bSound* sound)
BLI_strncpy(fullpath, sound->name, sizeof(fullpath));
if(sound->id.lib)
- path = sound->id.lib->filename;
+ path = sound->id.lib->filepath;
else
path = bmain ? bmain->name : G.sce;
- BLI_convertstringcode(fullpath, path);
+ BLI_path_abs(fullpath, path);
/* but we need a packed file then */
if (pf)
@@ -347,6 +347,13 @@ void sound_destroy_scene(struct Scene *scene)
AUD_destroySequencer(scene->sound_scene);
}
+void* sound_scene_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip)
+{
+ if(scene != sequence->scene)
+ return AUD_addSequencer(scene->sound_scene, &(sequence->scene->sound_scene), startframe / FPS, endframe / FPS, frameskip / FPS, sequence);
+ return NULL;
+}
+
void* sound_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip)
{
return AUD_addSequencer(scene->sound_scene, &(sequence->sound->playback_handle), startframe / FPS, endframe / FPS, frameskip / FPS, sequence);
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 4c73e60f741..0d4c51f3b89 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -42,21 +42,17 @@
#include "DNA_scene_types.h"
#include "BKE_cdderivedmesh.h"
-#include "BKE_customdata.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_displist.h"
-#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
-#include "BKE_multires.h"
+#include "BKE_modifier.h"
+#include "BKE_paint.h"
#include "BKE_scene.h"
#include "BKE_subsurf.h"
#include "BKE_tessmesh.h"
+#include "BKE_utildefines.h"
#include "BLI_blenlib.h"
#include "BLI_edgehash.h"
-#include "BLI_editVert.h"
-#include "BLI_linklist.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_pbvh.h"
@@ -126,7 +122,7 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAgin
if (useArena) {
CCGAllocatorIFC allocatorIFC;
- CCGAllocatorHDL allocator = BLI_memarena_new((1<<16));
+ CCGAllocatorHDL allocator = BLI_memarena_new((1<<16), "subsurf arena");
allocatorIFC.alloc = arena_alloc;
allocatorIFC.realloc = arena_realloc;
@@ -386,7 +382,7 @@ static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result,
}
static void calc_ss_weights(int gridFaces,
- FaceVertWeight **qweight, FaceVertWeight **tweight)
+ FaceVertWeight **qweight, FaceVertWeight **tweight)
{
FaceVertWeight *qw, *tw;
int x, y, j;
@@ -899,7 +895,7 @@ static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
}
static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm,
- float (*vertexCos)[3], int useFlatSubdiv)
+ float (*vertexCos)[3], int useFlatSubdiv)
{
float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
CCGVertHDL *fVerts = NULL;
@@ -942,10 +938,10 @@ static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm,
float crease;
crease = useFlatSubdiv ? creaseFactor :
- me->crease * creaseFactor / 255.0f;
+ me->crease * creaseFactor / 255.0f;
ccgSubSurf_syncEdge(ss, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(me->v1),
- SET_INT_IN_POINTER(me->v2), crease, &e);
+ SET_INT_IN_POINTER(me->v2), crease, &e);
((int*)ccgSubSurf_getEdgeUserData(ss, e))[1] = (index)? *index++: i;
}
@@ -968,7 +964,7 @@ static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm,
* other parts of code significantly to handle missing faces.
* since this really shouldn't even be possible we just bail.*/
if(ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), fiter->len,
- fVerts, &f) == eCCGError_InvalidValue) {
+ fVerts, &f) == eCCGError_InvalidValue) {
static int hasGivenError = 0;
if(!hasGivenError) {
@@ -1064,10 +1060,11 @@ static int cgdm_getNumTessFaces(DerivedMesh *dm) {
return ccgSubSurf_getNumFinalFaces(cgdm->ss);
}
-static void cgdm_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
+static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
{
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = cgdm->ss;
+ DMGridData *vd;
int i;
memset(mv, 0, sizeof(*mv));
@@ -1099,19 +1096,25 @@ static void cgdm_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
offset = vertNum - cgdm->faceMap[i].startVert;
if(offset < 1) {
- copy_v3_v3(mv->co, ccgSubSurf_getFaceCenterData(f));
+ vd = ccgSubSurf_getFaceCenterData(f);
+ copy_v3_v3(mv->co, vd->co);
+ normal_float_to_short_v3(mv->no, vd->no);
} else if(offset < gridSideEnd) {
offset -= 1;
grid = offset / gridSideVerts;
x = offset % gridSideVerts + 1;
- copy_v3_v3(mv->co, ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x));
+ vd = ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x);
+ copy_v3_v3(mv->co, vd->co);
+ normal_float_to_short_v3(mv->no, vd->no);
} else if(offset < gridInternalEnd) {
offset -= gridSideEnd;
grid = offset / gridInternalVerts;
offset %= gridInternalVerts;
y = offset / gridSideVerts + 1;
x = offset % gridSideVerts + 1;
- copy_v3_v3(mv->co, ccgSubSurf_getFaceGridData(ss, f, grid, x, y));
+ vd = ccgSubSurf_getFaceGridData(ss, f, grid, x, y);
+ copy_v3_v3(mv->co, vd->co);
+ normal_float_to_short_v3(mv->no, vd->no);
}
} else if((vertNum < cgdm->vertMap[0].startVert) && (ccgSubSurf_getNumEdges(ss) > 0)) {
/* this vert comes from edge data */
@@ -1126,18 +1129,38 @@ static void cgdm_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
e = cgdm->edgeMap[i].edge;
x = vertNum - cgdm->edgeMap[i].startVert + 1;
- copy_v3_v3(mv->co, ccgSubSurf_getEdgeData(ss, e, x));
+ vd = ccgSubSurf_getEdgeData(ss, e, x);
+ copy_v3_v3(mv->co, vd->co);
+ normal_float_to_short_v3(mv->no, vd->no);
} else {
/* this vert comes from vert data */
CCGVert *v;
i = vertNum - cgdm->vertMap[0].startVert;
v = cgdm->vertMap[i].vert;
- copy_v3_v3(mv->co, ccgSubSurf_getVertData(ss, v));
+ vd = ccgSubSurf_getVertData(ss, v);
+ copy_v3_v3(mv->co, vd->co);
+ normal_float_to_short_v3(mv->no, vd->no);
}
}
-static void cgdm_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
+static void ccgDM_getFinalVertCo(DerivedMesh *dm, int vertNum, float co_r[3])
+{
+ MVert mvert;
+
+ ccgDM_getFinalVert(dm, vertNum, &mvert);
+ VECCOPY(co_r, mvert.co);
+}
+
+static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float no_r[3])
+{
+ MVert mvert;
+
+ ccgDM_getFinalVert(dm, vertNum, &mvert);
+ normal_short_to_float_v3(no_r, mvert.no);
+}
+
+static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
{
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = cgdm->ss;
@@ -1216,7 +1239,7 @@ static void cgdm_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
}
}
-static void cgdm_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
+static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
{
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = cgdm->ss;
@@ -1260,7 +1283,7 @@ static void cgdm_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
else mf->flag = ME_SMOOTH;
}
-static void cgdm_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
+static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
{
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = cgdm->ss;
@@ -1308,6 +1331,7 @@ static void cgdm_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
for(x = 1; x < edgeSize - 1; x++, i++) {
vd= ccgSubSurf_getEdgeData(ss, e, x);
copy_v3_v3(mvert[i].co, vd->co);
+ /* XXX, This gives errors with -fpe, the normals dont seem to be unit length - campbell */
normal_float_to_short_v3(mvert[i].no, vd->no);
}
}
@@ -1323,7 +1347,7 @@ static void cgdm_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
}
}
-static void cgdm_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
+static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
{
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = cgdm->ss;
@@ -1344,7 +1368,7 @@ static void cgdm_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
MEdge *med = &medge[i];
if(cgdm->drawInteriorEdges)
- med->flag = ME_EDGEDRAW | ME_EDGERENDER;
+ med->flag = ME_EDGEDRAW | ME_EDGERENDER;
med->v1 = getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize);
med->v2 = getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize);
i++;
@@ -1356,20 +1380,20 @@ static void cgdm_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
med = &medge[i];
if(cgdm->drawInteriorEdges)
- med->flag = ME_EDGEDRAW | ME_EDGERENDER;
+ med->flag = ME_EDGEDRAW | ME_EDGERENDER;
med->v1 = getFaceIndex(ss, f, S, x, y,
- edgeSize, gridSize);
+ edgeSize, gridSize);
med->v2 = getFaceIndex(ss, f, S, x, y + 1,
- edgeSize, gridSize);
+ edgeSize, gridSize);
i++;
med = &medge[i];
if(cgdm->drawInteriorEdges)
- med->flag = ME_EDGEDRAW | ME_EDGERENDER;
+ med->flag = ME_EDGEDRAW | ME_EDGERENDER;
med->v1 = getFaceIndex(ss, f, S, y, x,
- edgeSize, gridSize);
+ edgeSize, gridSize);
med->v2 = getFaceIndex(ss, f, S, y + 1, x,
- edgeSize, gridSize);
+ edgeSize, gridSize);
i++;
}
}
@@ -1388,7 +1412,7 @@ static void cgdm_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
if(edgeFlags) {
if(edgeIdx != -1) {
flags |= (edgeFlags[index] & (ME_SEAM | ME_SHARP))
- | ME_EDGEDRAW | ME_EDGERENDER;
+ | ME_EDGEDRAW | ME_EDGERENDER;
}
} else {
flags |= ME_EDGEDRAW | ME_EDGERENDER;
@@ -1493,7 +1517,7 @@ void cgdm_loopIterStep(void *self)
liter->head.eindex = GET_INT_FROM_POINTER(BLI_edgehash_lookup(liter->fiter->cgdm->ehash, v1, v2));
liter->lindex += 1;
- cgdm_getFinalVert((DerivedMesh*)liter->cgdm, v1, &liter->head.v);
+ ccgDM_getFinalVert((DerivedMesh*)liter->cgdm, v1, &liter->head.v);
}
void *cgdm_loopIterGetVCData(void *self, int type, int layer)
@@ -1561,7 +1585,7 @@ DMFaceIter *cgdm_newFaceIter(DerivedMesh *dm)
return fiter;
}
-static void cgdm_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
+static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
{
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = cgdm->ss;
@@ -1584,13 +1608,13 @@ static void cgdm_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
for(x = 0; x < gridSize - 1; x++) {
MFace *mf = &mface[i];
mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
- edgeSize, gridSize);
+ edgeSize, gridSize);
mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
- edgeSize, gridSize);
+ edgeSize, gridSize);
mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
- edgeSize, gridSize);
+ edgeSize, gridSize);
mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
- edgeSize, gridSize);
+ edgeSize, gridSize);
if (faceFlags) {
mat_nr = faceFlags[index*2+1];
mf->flag = faceFlags[index*2];
@@ -1724,7 +1748,7 @@ static void cgdm_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData,
ccgEdgeIterator_free(ei);
}
-static void cgdm_drawVerts(DerivedMesh *dm) {
+static void ccgDM_drawVerts(DerivedMesh *dm) {
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = cgdm->ss;
int edgeSize = ccgSubSurf_getEdgeSize(ss);
@@ -1768,9 +1792,9 @@ static void cgdm_drawVerts(DerivedMesh *dm) {
ccgFaceIterator_free(fi);
glEnd();
}
-static void cgdm_drawEdges(DerivedMesh *dm, int drawLooseEdges) {
- CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
- CCGSubSurf *ss = cgdm->ss;
+static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges) {
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
+ CCGSubSurf *ss = ccgdm->ss;
CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
@@ -1803,7 +1827,7 @@ static void cgdm_drawEdges(DerivedMesh *dm, int drawLooseEdges) {
glColor3ub(0, 0, 0);
}
- if (cgdm->drawInteriorEdges) {
+ if (ccgdm->drawInteriorEdges) {
for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
CCGFace *f = ccgFaceIterator_getCurrent(fi);
int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
@@ -1834,7 +1858,7 @@ static void cgdm_drawEdges(DerivedMesh *dm, int drawLooseEdges) {
ccgFaceIterator_free(fi);
ccgEdgeIterator_free(ei);
}
-static void cgdm_drawLooseEdges(DerivedMesh *dm) {
+static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = cgdm->ss;
CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
@@ -1873,7 +1897,7 @@ void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
{
- if(ccgdm->pbvh) {
+ if(ccgdm->pbvh && ccgdm->multires.mmd) {
CCGFace **faces;
int totface;
@@ -1888,22 +1912,22 @@ static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
/* Only used by non-editmesh types */
static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], int fast, int (*setMaterial)(int, void *attribs)) {
- CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
- CCGSubSurf *ss = cgdm->ss;
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
+ CCGSubSurf *ss = ccgdm->ss;
CCGFaceIterator *fi;
- int gridSize;
- char *faceFlags = cgdm->faceFlags;
+ int gridSize = ccgSubSurf_getGridSize(ss);
+ char *faceFlags = ccgdm->faceFlags;
int step = (fast)? gridSize-1: 1;
- ccgdm_pbvh_update(cgdm);
- if(cgdm->pbvh && cgdm->multires.mmd && !fast) {
+ ccgdm_pbvh_update(ccgdm);
+ if(ccgdm->pbvh && ccgdm->multires.mmd && !fast) {
if(dm->numFaceData) {
/* should be per face */
if(!setMaterial(faceFlags[1]+1, NULL))
return;
glShadeModel((faceFlags[0] & ME_SMOOTH)? GL_SMOOTH: GL_FLAT);
- BLI_pbvh_draw(cgdm->pbvh, partial_redraw_planes, NULL);
+ BLI_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL, (faceFlags[0] & ME_SMOOTH));
glShadeModel(GL_FLAT);
}
@@ -2422,8 +2446,8 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *u
if (draw) {
if (draw==2) {
- glEnable(GL_POLYGON_STIPPLE);
- glPolygonStipple(stipple_quarttone);
+ glEnable(GL_POLYGON_STIPPLE);
+ glPolygonStipple(stipple_quarttone);
}
for (S=0; S<numVerts; S++) {
@@ -2578,34 +2602,35 @@ static void cgdm_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *use
}
static void cgdm_release(DerivedMesh *dm) {
- CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
if (DM_release(dm)) {
/* Before freeing, need to update the displacement map */
- if(cgdm->multires.modified) {
+ if(ccgdm->multires.modified) {
/* Check that mmd still exists */
- if(!cgdm->multires.local_mmd && BLI_findindex(&cgdm->multires.ob->modifiers, cgdm->multires.mmd) < 0)
- cgdm->multires.mmd = NULL;
- if(cgdm->multires.mmd)
- cgdm->multires.update(dm);
+ if(!ccgdm->multires.local_mmd && BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0)
+ ccgdm->multires.mmd = NULL;
+ if(ccgdm->multires.mmd)
+ ccgdm->multires.update(dm);
}
- if(cgdm->pbvh) BLI_pbvh_free(cgdm->pbvh);
- if(cgdm->gridFaces) MEM_freeN(cgdm->gridFaces);
- if(cgdm->gridData) MEM_freeN(cgdm->gridData);
- if(cgdm->gridAdjacency) MEM_freeN(cgdm->gridAdjacency);
- if(cgdm->gridOffset) MEM_freeN(cgdm->gridOffset);
- if(cgdm->freeSS) ccgSubSurf_free(cgdm->ss);
- if(cgdm->reverseFaceMap) MEM_freeN(cgdm->reverseFaceMap);
+ if (ccgdm->ehash)
+ BLI_edgehash_free(ccgdm->ehash, NULL);
- BLI_edgehash_free(cgdm->ehash, NULL);
-
- MEM_freeN(cgdm->edgeFlags);
- MEM_freeN(cgdm->faceFlags);
- MEM_freeN(cgdm->vertMap);
- MEM_freeN(cgdm->edgeMap);
- MEM_freeN(cgdm->faceMap);
- MEM_freeN(cgdm);
+ if(ccgdm->reverseFaceMap) MEM_freeN(ccgdm->reverseFaceMap);
+ if(ccgdm->gridFaces) MEM_freeN(ccgdm->gridFaces);
+ if(ccgdm->gridData) MEM_freeN(ccgdm->gridData);
+ if(ccgdm->gridAdjacency) MEM_freeN(ccgdm->gridAdjacency);
+ if(ccgdm->gridOffset) MEM_freeN(ccgdm->gridOffset);
+ if(ccgdm->freeSS) ccgSubSurf_free(ccgdm->ss);
+ if(ccgdm->fmap) MEM_freeN(ccgdm->fmap);
+ if(ccgdm->fmap_mem) MEM_freeN(ccgdm->fmap_mem);
+ MEM_freeN(ccgdm->edgeFlags);
+ MEM_freeN(ccgdm->faceFlags);
+ MEM_freeN(ccgdm->vertMap);
+ MEM_freeN(ccgdm->edgeMap);
+ MEM_freeN(ccgdm->faceMap);
+ MEM_freeN(ccgdm);
}
}
@@ -2811,7 +2836,7 @@ static int cgdm_adjacent_grid(CCGSubSurf *ss, int *gridOffset, CCGFace *f, int S
return gridOffset[fIndex] + (j + offset)%numEdges;
}
-static void cgdm_create_grids(DerivedMesh *dm)
+static void ccgdm_create_grids(DerivedMesh *dm)
{
CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
CCGSubSurf *ss= cgdm->ss;
@@ -2878,7 +2903,7 @@ static DMGridData **ccgDM_getGridData(DerivedMesh *dm)
{
CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
- cgdm_create_grids(dm);
+ ccgdm_create_grids(dm);
return cgdm->gridData;
}
@@ -2886,7 +2911,7 @@ static DMGridAdjacency *ccgDM_getGridAdjacency(DerivedMesh *dm)
{
CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
- cgdm_create_grids(dm);
+ ccgdm_create_grids(dm);
return cgdm->gridAdjacency;
}
@@ -2894,45 +2919,106 @@ static int *ccgDM_getGridOffset(DerivedMesh *dm)
{
CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
- cgdm_create_grids(dm);
+ ccgdm_create_grids(dm);
return cgdm->gridOffset;
}
+static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm)
+{
+ CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
+
+ if(!ccgdm->multires.mmd && !ccgdm->fmap && ob->type == OB_MESH) {
+ Mesh *me= ob->data;
+
+ create_vert_face_map(&ccgdm->fmap, &ccgdm->fmap_mem, me->mface,
+ me->totvert, me->totface);
+ }
+
+ return ccgdm->fmap;
+}
+
+static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm)
+{
+ ModifierData *md;
+ MultiresModifierData *mmd= ccgdm->multires.mmd;
+
+ /* in sync with sculpt mode, only use multires grid pbvh if we are
+ the last enabled modifier in the stack, otherwise we use the base
+ mesh */
+ if(!mmd)
+ return 0;
+
+ for(md=mmd->modifier.next; md; md= md->next)
+ if(modifier_isEnabled(mmd->modifier.scene, md, eModifierMode_Realtime))
+ return 0;
+
+ return 1;
+}
+
static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
{
- CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
- int gridSize, numGrids;
+ CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
+ int gridSize, numGrids, grid_pbvh;
+
+ if(!ob) {
+ ccgdm->pbvh= NULL;
+ return NULL;
+ }
+
+ if(!ob->sculpt)
+ return NULL;
- if(cgdm->pbvh)
- return cgdm->pbvh;
+ grid_pbvh = ccgDM_use_grid_pbvh(ccgdm);
+
+ if(ob->sculpt->pbvh) {
+ if(grid_pbvh) {
+ /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
+ but this can be freed on ccgdm release, this updates the pointers
+ when the ccgdm gets remade, the assumption is that the topology
+ does not change. */
+ ccgdm_create_grids(dm);
+ BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces);
+ }
+
+ ccgdm->pbvh = ob->sculpt->pbvh;
+ ccgdm->pbvh_draw = grid_pbvh;
+ }
- if(cgdm->multires.mmd) {
- cgdm_create_grids(dm);
+ if(ccgdm->pbvh)
+ return ccgdm->pbvh;
+
+ /* no pbvh exists yet, we need to create one. only in case of multires
+ we build a pbvh over the modified mesh, in other cases the base mesh
+ is being sculpted, so we build a pbvh from that. */
+ if(grid_pbvh) {
+ ccgdm_create_grids(dm);
gridSize = ccgDM_getGridSize(dm);
numGrids = ccgDM_getNumGrids(dm);
- cgdm->pbvh = BLI_pbvh_new();
- BLI_pbvh_build_grids(cgdm->pbvh, cgdm->gridData, cgdm->gridAdjacency,
- numGrids, gridSize, (void**)cgdm->gridFaces);
+ ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
+ BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
+ numGrids, gridSize, (void**)ccgdm->gridFaces);
+ ccgdm->pbvh_draw = 1;
}
else if(ob->type == OB_MESH) {
Mesh *me= ob->data;
- cgdm->pbvh = BLI_pbvh_new();
- BLI_pbvh_build_mesh(cgdm->pbvh, me->mface, me->mvert,
- me->totface, me->totvert);
+ ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
+ BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
+ me->totface, me->totvert);
+ ccgdm->pbvh_draw = 0;
}
- return cgdm->pbvh;
+ return ccgdm->pbvh;
}
static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
- int drawInteriorEdges,
- int useSubsurfUv,
- DerivedMesh *dm)
+ int drawInteriorEdges,
+ int useSubsurfUv,
+ DerivedMesh *dm)
{
- CCGDerivedMesh *cgdm = MEM_callocN(sizeof(*cgdm), "cgdm");
+ CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "cgdm");
CCGVertIterator *vi;
CCGEdgeIterator *ei;
CCGFaceIterator *fi;
@@ -2959,105 +3045,121 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
MEdge *medge = NULL, medge2;
MFace *mface = NULL;
MPoly *mpoly = NULL;
+ int *orig_indices;
- DM_from_template(&cgdm->dm, dm, DM_TYPE_CCGDM,
+ DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM,
ccgSubSurf_getNumFinalVerts(ss),
ccgSubSurf_getNumFinalEdges(ss),
ccgSubSurf_getNumFinalFaces(ss),
ccgSubSurf_getNumFinalFaces(ss)*4,
ccgSubSurf_getNumFinalFaces(ss));
- numTex = CustomData_number_of_layers(&cgdm->dm.loopData, CD_MLOOPUV);
- numCol = CustomData_number_of_layers(&cgdm->dm.loopData, CD_MLOOPCOL);
+ numTex = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPUV);
+ numCol = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPCOL);
- if (numTex && CustomData_number_of_layers(&cgdm->dm.faceData, CD_MTFACE) != numTex)
- CustomData_from_bmeshpoly(&cgdm->dm.faceData, &cgdm->dm.polyData, &cgdm->dm.loopData, ccgSubSurf_getNumFinalFaces(ss));
- else if (numCol && CustomData_number_of_layers(&cgdm->dm.faceData, CD_MCOL) != numCol)
- CustomData_from_bmeshpoly(&cgdm->dm.faceData, &cgdm->dm.polyData, &cgdm->dm.loopData, ccgSubSurf_getNumFinalFaces(ss));
-
- cgdm->dm.getMinMax = cgdm_getMinMax;
- cgdm->dm.getNumVerts = cgdm_getNumVerts;
- cgdm->dm.getNumTessFaces = cgdm_getNumTessFaces;
- cgdm->dm.getNumFaces = cgdm_getNumTessFaces;
-
- cgdm->dm.getNumGrids = ccgDM_getNumGrids;
- cgdm->dm.getGridSize = ccgDM_getGridSize;
- cgdm->dm.getGridData = ccgDM_getGridData;
- cgdm->dm.getGridAdjacency = ccgDM_getGridAdjacency;
- cgdm->dm.getGridOffset = ccgDM_getGridOffset;
- cgdm->dm.getPBVH = ccgDM_getPBVH;
-
- cgdm->dm.newFaceIter = cgdm_newFaceIter;
- cgdm->dm.getNumEdges = cgdm_getNumEdges;
- cgdm->dm.getVert = cgdm_getFinalVert;
- cgdm->dm.getEdge = cgdm_getFinalEdge;
- cgdm->dm.getTessFace = cgdm_getFinalFace;
- cgdm->dm.copyVertArray = cgdm_copyFinalVertArray;
- cgdm->dm.copyEdgeArray = cgdm_copyFinalEdgeArray;
- cgdm->dm.copyTessFaceArray = cgdm_copyFinalFaceArray;
- cgdm->dm.getVertData = DM_get_vert_data;
- cgdm->dm.getEdgeData = DM_get_edge_data;
- cgdm->dm.getTessFaceData = DM_get_face_data;
- cgdm->dm.getVertDataArray = DM_get_vert_data_layer;
- cgdm->dm.getEdgeDataArray = DM_get_edge_data_layer;
- cgdm->dm.getTessFaceDataArray = DM_get_tessface_data_layer;
-
- cgdm->dm.getVertCos = cgdm_getVertCos;
- cgdm->dm.foreachMappedVert = cgdm_foreachMappedVert;
- cgdm->dm.foreachMappedEdge = cgdm_foreachMappedEdge;
- cgdm->dm.foreachMappedFaceCenter = cgdm_foreachMappedFaceCenter;
+ if (numTex && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MTFACE) != numTex)
+ CustomData_from_bmeshpoly(&ccgdm->dm.faceData, &ccgdm->dm.polyData, &ccgdm->dm.loopData, ccgSubSurf_getNumFinalFaces(ss));
+ else if (numCol && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MCOL) != numCol)
+ CustomData_from_bmeshpoly(&ccgdm->dm.faceData, &ccgdm->dm.polyData, &ccgdm->dm.loopData, ccgSubSurf_getNumFinalFaces(ss));
+
+ ccgdm->dm.getMinMax = cgdm_getMinMax;
+ ccgdm->dm.getNumVerts = cgdm_getNumVerts;
+ ccgdm->dm.getNumTessFaces = cgdm_getNumTessFaces;
+ ccgdm->dm.getNumFaces = cgdm_getNumTessFaces;
+
+ ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
+ ccgdm->dm.getPBVH = ccgDM_getPBVH;
+
+ ccgdm->dm.newFaceIter = cgdm_newFaceIter;
+ ccgdm->dm.getVert = ccgDM_getFinalVert;
+ ccgdm->dm.getEdge = ccgDM_getFinalEdge;
+ ccgdm->dm.getTessFace = ccgDM_getFinalFace;
+ ccgdm->dm.getVertCo = ccgDM_getFinalVertCo;
+ ccgdm->dm.getVertNo = ccgDM_getFinalVertNo;
+ ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
+ ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
+ ccgdm->dm.copyTessFaceArray = ccgDM_copyFinalFaceArray;
+ ccgdm->dm.getVertData = DM_get_vert_data;
+ ccgdm->dm.getEdgeData = DM_get_edge_data;
+ ccgdm->dm.getTessFaceData = DM_get_face_data;
+ ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer;
+ ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer;
+ ccgdm->dm.getTessFaceDataArray = ccgDM_get_face_data_layer;
+ ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
+ ccgdm->dm.getGridSize = ccgDM_getGridSize;
+ ccgdm->dm.getGridData = ccgDM_getGridData;
+ ccgdm->dm.getGridAdjacency = ccgDM_getGridAdjacency;
+ ccgdm->dm.getGridOffset = ccgDM_getGridOffset;
+ ccgdm->dm.getFaceMap = ccgDM_getFaceMap;
+ ccgdm->dm.getPBVH = ccgDM_getPBVH;
+
+ ccgdm->dm.getTessFace = ccgDM_getFinalFace;
+ ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
+ ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
+ ccgdm->dm.copyTessFaceArray = ccgDM_copyFinalFaceArray;
+ ccgdm->dm.getVertData = DM_get_vert_data;
+ ccgdm->dm.getEdgeData = DM_get_edge_data;
+ ccgdm->dm.getTessFaceData = DM_get_face_data;
+ ccgdm->dm.getVertDataArray = DM_get_vert_data_layer;
+ ccgdm->dm.getEdgeDataArray = DM_get_edge_data_layer;
+ ccgdm->dm.getTessFaceDataArray = DM_get_tessface_data_layer;
+
+ ccgdm->dm.getVertCos = cgdm_getVertCos;
+ ccgdm->dm.foreachMappedVert = cgdm_foreachMappedVert;
+ ccgdm->dm.foreachMappedEdge = cgdm_foreachMappedEdge;
+ ccgdm->dm.foreachMappedFaceCenter = cgdm_foreachMappedFaceCenter;
- cgdm->dm.drawVerts = cgdm_drawVerts;
- cgdm->dm.drawEdges = cgdm_drawEdges;
- cgdm->dm.drawLooseEdges = cgdm_drawLooseEdges;
- cgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
- cgdm->dm.drawFacesColored = cgdm_drawFacesColored;
- cgdm->dm.drawFacesTex = cgdm_drawFacesTex;
- cgdm->dm.drawFacesGLSL = cgdm_drawFacesGLSL;
- cgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
- cgdm->dm.drawMappedFacesTex = cgdm_drawMappedFacesTex;
- cgdm->dm.drawMappedFacesGLSL = cgdm_drawMappedFacesGLSL;
- cgdm->dm.drawUVEdges = cgdm_drawUVEdges;
-
- cgdm->dm.drawMappedEdgesInterp = cgdm_drawMappedEdgesInterp;
- cgdm->dm.drawMappedEdges = cgdm_drawMappedEdges;
+ ccgdm->dm.drawVerts = ccgDM_drawVerts;
+ ccgdm->dm.drawEdges = ccgDM_drawEdges;
+ ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
+ ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
+ ccgdm->dm.drawFacesColored = cgdm_drawFacesColored;
+ ccgdm->dm.drawFacesTex = cgdm_drawFacesTex;
+ ccgdm->dm.drawFacesGLSL = cgdm_drawFacesGLSL;
+ ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
+ ccgdm->dm.drawMappedFacesTex = cgdm_drawMappedFacesTex;
+ ccgdm->dm.drawMappedFacesGLSL = cgdm_drawMappedFacesGLSL;
+ ccgdm->dm.drawUVEdges = cgdm_drawUVEdges;
+
+ ccgdm->dm.drawMappedEdgesInterp = cgdm_drawMappedEdgesInterp;
+ ccgdm->dm.drawMappedEdges = cgdm_drawMappedEdges;
- cgdm->dm.release = cgdm_release;
+ ccgdm->dm.release = cgdm_release;
- cgdm->ss = ss;
- cgdm->drawInteriorEdges = drawInteriorEdges;
- cgdm->useSubsurfUv = useSubsurfUv;
+ ccgdm->ss = ss;
+ ccgdm->drawInteriorEdges = drawInteriorEdges;
+ ccgdm->useSubsurfUv = useSubsurfUv;
totvert = ccgSubSurf_getNumVerts(ss);
- cgdm->vertMap = MEM_mallocN(totvert * sizeof(*cgdm->vertMap), "vertMap");
+ ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
vi = ccgSubSurf_getVertIterator(ss);
for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
CCGVert *v = ccgVertIterator_getCurrent(vi);
- cgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))].vert = v;
+ ccgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))].vert = v;
}
ccgVertIterator_free(vi);
totedge = ccgSubSurf_getNumEdges(ss);
- cgdm->edgeMap = MEM_mallocN(totedge * sizeof(*cgdm->edgeMap), "edgeMap");
+ ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
ei = ccgSubSurf_getEdgeIterator(ss);
for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
- cgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e;
+ ccgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e;
}
totface = ccgSubSurf_getNumFaces(ss);
- cgdm->faceMap = MEM_mallocN(totface * sizeof(*cgdm->faceMap), "faceMap");
+ ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
fi = ccgSubSurf_getFaceIterator(ss);
for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
CCGFace *f = ccgFaceIterator_getCurrent(fi);
- cgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))].face = f;
+ ccgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))].face = f;
}
ccgFaceIterator_free(fi);
- cgdm->reverseFaceMap = MEM_callocN(sizeof(int)*ccgSubSurf_getNumFinalFaces(ss), "reverseFaceMap");
+ ccgdm->reverseFaceMap = MEM_callocN(sizeof(int)*ccgSubSurf_getNumFinalFaces(ss), "reverseFaceMap");
edgeSize = ccgSubSurf_getEdgeSize(ss);
gridSize = ccgSubSurf_getGridSize(ss);
@@ -3078,28 +3180,27 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
/*CDDM hack*/
- edgeFlags = cgdm->edgeFlags = MEM_callocN(sizeof(short)*totedge, "faceFlags");
- faceFlags = cgdm->faceFlags = MEM_callocN(sizeof(char)*2*totface, "faceFlags");
+ edgeFlags = ccgdm->edgeFlags = MEM_callocN(sizeof(short)*totedge, "faceFlags");
+ faceFlags = ccgdm->faceFlags = MEM_callocN(sizeof(char)*2*totface, "faceFlags");
- vertOrigIndex = DM_get_vert_data_layer(&cgdm->dm, CD_ORIGINDEX);
+ vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX);
/*edgeOrigIndex = DM_get_edge_data_layer(&cgdm->dm, CD_ORIGINDEX);*/
- faceOrigIndex = DM_get_tessface_data_layer(&cgdm->dm, CD_ORIGINDEX);
+ faceOrigIndex = DM_get_tessface_data_layer(&ccgdm->dm, CD_ORIGINDEX);
- polyOrigIndex = DM_get_face_data_layer(&cgdm->dm, CD_ORIGINDEX);
+ polyOrigIndex = DM_get_face_data_layer(&ccgdm->dm, CD_ORIGINDEX);
- if (!CustomData_has_layer(&cgdm->dm.faceData, CD_MCOL))
- DM_add_tessface_layer(&cgdm->dm, CD_MCOL, CD_CALLOC, NULL);
+ if (!CustomData_has_layer(&ccgdm->dm.faceData, CD_MCOL))
+ DM_add_tessface_layer(&ccgdm->dm, CD_MCOL, CD_CALLOC, NULL);
- mcol = DM_get_tessface_data_layer(&cgdm->dm, CD_MCOL);
- has_edge_origindex = CustomData_has_layer(&cgdm->dm.edgeData, CD_ORIGINDEX);
+ mcol = DM_get_tessface_data_layer(&ccgdm->dm, CD_MCOL);
+ has_edge_origindex = CustomData_has_layer(&ccgdm->dm.edgeData, CD_ORIGINDEX);
faceNum = 0;
loopindex = loopindex2 = 0; //current loop index
for (index = 0; index < totface; index++) {
- CCGFace *f = cgdm->faceMap[index].face;
+ CCGFace *f = ccgdm->faceMap[index].face;
int numVerts = ccgSubSurf_getFaceNumVerts(f);
int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
- int mapIndex = ccgDM_getFaceMapIndex(ss, f);
int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
int g2_wid = gridCuts+2;
float *w2;
@@ -3107,9 +3208,9 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
w = get_ss_weights(&wtable, gridCuts, numVerts);
- cgdm->faceMap[index].startVert = vertNum;
- cgdm->faceMap[index].startEdge = edgeNum;
- cgdm->faceMap[index].startFace = faceNum;
+ ccgdm->faceMap[index].startVert = vertNum;
+ ccgdm->faceMap[index].startEdge = edgeNum;
+ ccgdm->faceMap[index].startFace = faceNum;
faceFlags[0] = mpoly[origIndex].flag;
faceFlags[1] = mpoly[origIndex].mat_nr;
@@ -3135,7 +3236,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
/*I think this is for interpolating the center vert?*/
w2 = w; // + numVerts*(g2_wid-1)*(g2_wid-1); //numVerts*((g2_wid-1)*g2_wid+g2_wid-1);
- DM_interp_vert_data(dm, &cgdm->dm, vertidx, w2,
+ DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
numVerts, vertNum);
if (vertOrigIndex) {
*vertOrigIndex = ORIGINDEX_NONE;
@@ -3148,7 +3249,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
for(s = 0; s < numVerts; s++) {
for(x = 1; x < gridFaces; x++) {
w2 = w + s*numVerts*g2_wid*g2_wid + x*numVerts;
- DM_interp_vert_data(dm, &cgdm->dm, vertidx, w2,
+ DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
numVerts, vertNum);
if (vertOrigIndex) {
@@ -3165,7 +3266,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
for(y = 1; y < gridFaces; y++) {
for(x = 1; x < gridFaces; x++) {
w2 = w + s*numVerts*g2_wid*g2_wid + (y*g2_wid+x)*numVerts;
- DM_interp_vert_data(dm, &cgdm->dm, vertidx, w2,
+ DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
numVerts, vertNum);
if (vertOrigIndex) {
@@ -3180,7 +3281,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
if (has_edge_origindex) {
for(i = 0; i < numFinalEdges; ++i)
- *(int *)DM_get_edge_data(&cgdm->dm, edgeNum + i,
+ *(int *)DM_get_edge_data(&ccgdm->dm, edgeNum + i,
CD_ORIGINDEX) = ORIGINDEX_NONE;
}
@@ -3189,31 +3290,31 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
for (y=0; y<gridFaces; y++) {
for (x=0; x<gridFaces; x++) {
w2 = w + s*numVerts*g2_wid*g2_wid + (y*g2_wid+x)*numVerts;
- CustomData_interp(&dm->loopData, &cgdm->dm.loopData,
+ CustomData_interp(&dm->loopData, &ccgdm->dm.loopData,
loopidx, w2, NULL, numVerts, loopindex2);
loopindex2++;
w2 = w + s*numVerts*g2_wid*g2_wid + ((y+1)*g2_wid+(x))*numVerts;
- CustomData_interp(&dm->loopData, &cgdm->dm.loopData,
+ CustomData_interp(&dm->loopData, &ccgdm->dm.loopData,
loopidx, w2, NULL, numVerts, loopindex2);
loopindex2++;
w2 = w + s*numVerts*g2_wid*g2_wid + ((y+1)*g2_wid+(x+1))*numVerts;
- CustomData_interp(&dm->loopData, &cgdm->dm.loopData,
+ CustomData_interp(&dm->loopData, &ccgdm->dm.loopData,
loopidx, w2, NULL, numVerts, loopindex2);
loopindex2++;
w2 = w + s*numVerts*g2_wid*g2_wid + ((y)*g2_wid+(x+1))*numVerts;
- CustomData_interp(&dm->loopData, &cgdm->dm.loopData,
+ CustomData_interp(&dm->loopData, &ccgdm->dm.loopData,
loopidx, w2, NULL, numVerts, loopindex2);
loopindex2++;
/*copy over poly data, e.g. mtexpoly*/
- CustomData_copy_data(&dm->polyData, &cgdm->dm.polyData, origIndex, faceNum, 1);
+ CustomData_copy_data(&dm->polyData, &ccgdm->dm.polyData, origIndex, faceNum, 1);
/*generate tesselated face data used for drawing*/
- ccg_loops_to_corners(&cgdm->dm.faceData, &cgdm->dm.loopData,
- &cgdm->dm.polyData, loopindex2-4, faceNum, faceNum, numTex, numCol);
+ ccg_loops_to_corners(&ccgdm->dm.faceData, &ccgdm->dm.loopData,
+ &ccgdm->dm.polyData, loopindex2-4, faceNum, faceNum, numTex, numCol);
/*set original index data*/
if (faceOrigIndex) {
@@ -3225,7 +3326,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
polyOrigIndex++;
}
- cgdm->reverseFaceMap[faceNum] = index;
+ ccgdm->reverseFaceMap[faceNum] = index;
faceNum++;
}
@@ -3236,7 +3337,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
}
for(index = 0; index < totedge; ++index) {
- CCGEdge *e = cgdm->edgeMap[index].edge;
+ CCGEdge *e = ccgdm->edgeMap[index].edge;
int numFinalEdges = edgeSize - 1;
int mapIndex = ccgDM_getEdgeMapIndex(ss, e);
int x;
@@ -3249,8 +3350,8 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
v = ccgSubSurf_getEdgeVert1(e);
vertIdx[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
- cgdm->edgeMap[index].startVert = vertNum;
- cgdm->edgeMap[index].startEdge = edgeNum;
+ ccgdm->edgeMap[index].startVert = vertNum;
+ ccgdm->edgeMap[index].startEdge = edgeNum;
if(edgeIdx >= 0 && edgeFlags)
edgeFlags[edgeIdx] = medge[edgeIdx].flag;
@@ -3262,7 +3363,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
float w[2];
w[1] = (float) x / (edgeSize - 1);
w[0] = 1 - w[1];
- DM_interp_vert_data(dm, &cgdm->dm, vertIdx, w, 2, vertNum);
+ DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 2, vertNum);
if (vertOrigIndex) {
*vertOrigIndex = ORIGINDEX_NONE;
++vertOrigIndex;
@@ -3272,7 +3373,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
for(i = 0; i < numFinalEdges; ++i) {
if (has_edge_origindex) {
- *(int *)DM_get_edge_data(&cgdm->dm, edgeNum + i,
+ *(int *)DM_get_edge_data(&ccgdm->dm, edgeNum + i,
CD_ORIGINDEX) = mapIndex;
}
}
@@ -3281,18 +3382,18 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
}
for(index = 0; index < totvert; ++index) {
- CCGVert *v = cgdm->vertMap[index].vert;
- int mapIndex = ccgDM_getVertMapIndex(cgdm->ss, v);
+ CCGVert *v = ccgdm->vertMap[index].vert;
+ int mapIndex = ccgDM_getVertMapIndex(ccgdm->ss, v);
int vidx;
vidx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
- cgdm->vertMap[index].startVert = vertNum;
+ ccgdm->vertMap[index].startVert = vertNum;
/* set the vert base vert */
*((int*) ccgSubSurf_getVertUserData(ss, v)) = vertNum;
- DM_copy_vert_data(dm, &cgdm->dm, vidx, vertNum, 1);
+ DM_copy_vert_data(dm, &ccgdm->dm, vidx, vertNum, 1);
if (vertOrigIndex) {
*vertOrigIndex = mapIndex;
@@ -3301,32 +3402,32 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
++vertNum;
}
- cgdm->dm.numVertData = vertNum;
- cgdm->dm.numEdgeData = edgeNum;
- cgdm->dm.numFaceData = faceNum;
- cgdm->dm.numLoopData = loopindex2;
- cgdm->dm.numPolyData = faceNum;
+ ccgdm->dm.numVertData = vertNum;
+ ccgdm->dm.numEdgeData = edgeNum;
+ ccgdm->dm.numFaceData = faceNum;
+ ccgdm->dm.numLoopData = loopindex2;
+ ccgdm->dm.numPolyData = faceNum;
BLI_array_free(vertidx);
BLI_array_free(loopidx);
free_ss_weights(&wtable);
- cgdm->ehash = BLI_edgehash_new();
- for (i=0; i<cgdm->dm.numEdgeData; i++) {
- cgdm_getFinalEdge((DerivedMesh*)cgdm, i, &medge2);
- BLI_edgehash_insert(cgdm->ehash, medge2.v1, medge2.v2, SET_INT_IN_POINTER(i));
+ ccgdm->ehash = BLI_edgehash_new();
+ for (i=0; i<ccgdm->dm.numEdgeData; i++) {
+ ccgDM_getFinalEdge((DerivedMesh*)ccgdm, i, &medge2);
+ BLI_edgehash_insert(ccgdm->ehash, medge2.v1, medge2.v2, SET_INT_IN_POINTER(i));
}
- return cgdm;
+ return ccgdm;
}
/***/
struct DerivedMesh *subsurf_make_derived_from_derived(
- struct DerivedMesh *dm,
- struct SubsurfModifierData *smd,
- int useRenderParams, float (*vertCos)[3],
- int isFinalCalc, int editMode)
+ struct DerivedMesh *dm,
+ struct SubsurfModifierData *smd,
+ int useRenderParams, float (*vertCos)[3],
+ int isFinalCalc, int editMode)
{
int useSimple = smd->subdivType == ME_SIMPLE_SUBSURF;
int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
@@ -3338,12 +3439,12 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels;
smd->emCache = _getSubSurf(smd->emCache, levels, useAging, 0,
- useSimple);
+ useSimple);
ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple);
result = getCCGDerivedMesh(smd->emCache,
- drawInteriorEdges,
- useSubsurfUv, dm);
+ drawInteriorEdges,
+ useSubsurfUv, dm);
} else if(useRenderParams) {
/* Do not use cache in render mode. */
CCGSubSurf *ss;
@@ -3381,13 +3482,13 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
if(useIncremental && isFinalCalc) {
smd->mCache = ss = _getSubSurf(smd->mCache, levels,
- useAging, 0, useSimple);
+ useAging, 0, useSimple);
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
result = getCCGDerivedMesh(smd->mCache,
- drawInteriorEdges,
- useSubsurfUv, dm);
+ drawInteriorEdges,
+ useSubsurfUv, dm);
} else {
if (smd->mCache && isFinalCalc) {
ccgSubSurf_free(smd->mCache);
@@ -3441,7 +3542,7 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3])
}
for (i=0; i<numFaces; i++) {
CCGFace *f = ccgSubSurf_getVertFace(v, i);
- add_v3_v3v3(face_sum, face_sum, ccgSubSurf_getFaceCenterData(f));
+ add_v3_v3(face_sum, ccgSubSurf_getFaceCenterData(f));
}
/* ad-hoc correction for boundary vertices, to at least avoid them
diff --git a/source/blender/blenkernel/intern/suggestions.c b/source/blender/blenkernel/intern/suggestions.c
index 59635d4d344..1b720c1adaa 100644
--- a/source/blender/blenkernel/intern/suggestions.c
+++ b/source/blender/blenkernel/intern/suggestions.c
@@ -32,9 +32,7 @@
#include <ctype.h>
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "DNA_text_types.h"
-#include "BKE_text.h"
#include "BKE_suggestions.h"
/**********************/
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 4dcc26827d0..e8328d0e622 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -37,8 +37,6 @@
#include "BLI_blenlib.h"
-#include "DNA_action_types.h"
-#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
#include "DNA_controller_types.h"
#include "DNA_scene_types.h"
@@ -50,7 +48,6 @@
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
-#include "BKE_node.h"
#include "BKE_text.h"
#include "BKE_utildefines.h"
@@ -58,10 +55,6 @@
#include "BPY_extern.h"
#endif
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
/***************/ /*
How Texts should work
@@ -187,10 +180,12 @@ Text *add_empty_text(char *name)
ta->name= NULL;
- init_undo_text(ta);
+ init_undo_text(ta);
ta->nlines=1;
- ta->flags= TXT_ISDIRTY | TXT_ISMEM | TXT_TABSTOSPACES;
+ ta->flags= TXT_ISDIRTY | TXT_ISMEM;
+ if((U.flag & USER_TXT_TABSTOSPACES_DISABLE)==0)
+ ta->flags |= TXT_TABSTOSPACES;
ta->lines.first= ta->lines.last= NULL;
ta->markers.first= ta->markers.last= NULL;
@@ -237,15 +232,13 @@ int reopen_text(Text *text)
int i, llen, len, res;
unsigned char *buffer;
TextLine *tmp;
- char sfile[FILE_MAXFILE];
char str[FILE_MAXDIR+FILE_MAXFILE];
struct stat st;
if (!text || !text->name) return 0;
BLI_strncpy(str, text->name, FILE_MAXDIR+FILE_MAXFILE);
- BLI_convertstringcode(str, G.sce);
- BLI_split_dirfile_basic(str, NULL, sfile);
+ BLI_path_abs(str, G.sce);
fp= fopen(str, "r");
if(fp==NULL) return 0;
@@ -336,27 +329,26 @@ Text *add_text(char *file, const char *relpath)
unsigned char *buffer;
TextLine *tmp;
Text *ta;
- char sfile[FILE_MAXFILE];
char str[FILE_MAXDIR+FILE_MAXFILE];
struct stat st;
BLI_strncpy(str, file, FILE_MAXDIR+FILE_MAXFILE);
if (relpath) /* can be NULL (bg mode) */
- BLI_convertstringcode(str, relpath);
- BLI_split_dirfile_basic(str, NULL, sfile);
+ BLI_path_abs(str, relpath);
fp= fopen(str, "r");
if(fp==NULL) return NULL;
- ta= alloc_libblock(&G.main->text, ID_TXT, sfile);
+ ta= alloc_libblock(&G.main->text, ID_TXT, BLI_path_basename(str));
ta->id.us= 1;
ta->lines.first= ta->lines.last= NULL;
ta->markers.first= ta->markers.last= NULL;
ta->curl= ta->sell= NULL;
-
- ta->flags= TXT_TABSTOSPACES;
-
+
+ if((U.flag & USER_TXT_TABSTOSPACES_DISABLE)==0)
+ ta->flags= TXT_TABSTOSPACES;
+
fseek(fp, 0L, SEEK_END);
len= ftell(fp);
fseek(fp, 0L, SEEK_SET);
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 10fdbc7fa14..57816b7e470 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -42,28 +42,21 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
-#include "BLI_rand.h"
#include "BLI_kdopbvh.h"
-#include "DNA_texture_types.h"
#include "DNA_key_types.h"
#include "DNA_object_types.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
-#include "DNA_image_types.h"
#include "DNA_world_types.h"
#include "DNA_brush_types.h"
#include "DNA_node_types.h"
#include "DNA_color_types.h"
-#include "DNA_scene_types.h"
-#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "BKE_plugin_types.h"
-
#include "BKE_utildefines.h"
-
#include "BKE_global.h"
#include "BKE_main.h"
@@ -73,7 +66,6 @@
#include "BKE_texture.h"
#include "BKE_key.h"
#include "BKE_icons.h"
-#include "BKE_brush.h"
#include "BKE_node.h"
#include "BKE_animsys.h"
@@ -253,7 +245,7 @@ void init_colorband(ColorBand *coba, int rangetype)
coba->data[0].b= 0.0;
coba->data[0].a= 0.0;
- coba->data[1].r= 0.0;
+ coba->data[1].r= 1.0;
coba->data[1].g= 1.0;
coba->data[1].b= 1.0;
coba->data[1].a= 1.0;
@@ -459,6 +451,7 @@ void default_tex(Tex *tex)
tex->nabla= 0.025; // also in do_versions
tex->bright= 1.0;
tex->contrast= 1.0;
+ tex->saturation= 1.0;
tex->filtersize= 1.0;
tex->rfac= 1.0;
tex->gfac= 1.0;
@@ -483,10 +476,10 @@ void default_tex(Tex *tex)
tex->vn_coltype = 0;
if (tex->env) {
- tex->env->stype=ENV_STATIC;
+ tex->env->stype=ENV_ANIM;
tex->env->clipsta=0.1;
tex->env->clipend=100;
- tex->env->cuberes=100;
+ tex->env->cuberes=600;
tex->env->depth=0;
}
@@ -517,6 +510,27 @@ void default_tex(Tex *tex)
tex->preview = NULL;
}
+void tex_set_type(Tex *tex, int type)
+{
+ switch(type) {
+
+ case TEX_VOXELDATA:
+ if (tex->vd == NULL)
+ tex->vd = BKE_add_voxeldata();
+ break;
+ case TEX_POINTDENSITY:
+ if (tex->pd == NULL)
+ tex->pd = BKE_add_pointdensity();
+ break;
+ case TEX_ENVMAP:
+ if (tex->env == NULL)
+ tex->env = BKE_add_envmap();
+ break;
+ }
+
+ tex->type = type;
+}
+
/* ------------------------------------------------------------------------- */
Tex *add_texture(const char *name)
@@ -628,6 +642,8 @@ Tex *copy_texture(Tex *tex)
if(texn->coba) texn->coba= MEM_dupallocN(texn->coba);
if(texn->env) texn->env= BKE_copy_envmap(texn->env);
+ if(texn->pd) texn->pd= MEM_dupallocN(texn->pd);
+ if(texn->vd) texn->vd= MEM_dupallocN(texn->vd);
if(tex->preview) texn->preview = BKE_previewimg_copy(tex->preview);
@@ -651,9 +667,9 @@ void make_local_texture(Tex *tex)
int a, local=0, lib=0;
/* - only lib users: do nothing
- * - only local users: set flag
- * - mixed: make copy
- */
+ * - only local users: set flag
+ * - mixed: make copy
+ */
if(tex->id.lib==0) return;
@@ -885,9 +901,15 @@ Tex *give_current_material_texture(Material *ma)
}
else {
node= nodeGetActiveID(ma->nodetree, ID_MA);
- if(node)
+ if(node) {
ma= (Material*)node->id;
+ if(ma) {
+ mtex= ma->mtex[(int)(ma->texact)];
+ if(mtex) tex= mtex->tex;
+ }
+ }
}
+ return tex;
}
if(ma) {
@@ -1040,10 +1062,11 @@ EnvMap *BKE_add_envmap(void)
env= MEM_callocN(sizeof(EnvMap), "envmap");
env->type= ENV_CUBE;
- env->stype= ENV_STATIC;
+ env->stype= ENV_ANIM;
env->clipsta= 0.1;
env->clipend= 100.0;
- env->cuberes= 100;
+ env->cuberes= 600;
+ env->viewscale = 0.5;
return env;
}
@@ -1110,6 +1133,7 @@ PointDensity *BKE_add_pointdensity(void)
pd->totpoints = 0;
pd->object = NULL;
pd->psys = 0;
+ pd->psys_cache_space= TEX_PD_WORLDSPACE;
return pd;
}
@@ -1148,7 +1172,8 @@ void BKE_free_pointdensity(PointDensity *pd)
void BKE_free_voxeldatadata(struct VoxelData *vd)
{
if (vd->dataset) {
- MEM_freeN(vd->dataset);
+ if(vd->file_format != TEX_VD_SMOKE)
+ MEM_freeN(vd->dataset);
vd->dataset = NULL;
}
@@ -1172,6 +1197,8 @@ struct VoxelData *BKE_add_voxeldata(void)
vd->int_multiplier = 1.0;
vd->extend = TEX_CLIP;
vd->object = NULL;
+ vd->cachedframe = -1;
+ vd->ok = 0;
return vd;
}
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index 87424dda04d..133f858e9ea 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -81,7 +81,7 @@ static struct bUnitDef buMetricLenDef[] = {
{"decimetre", "decimetres", "dm", NULL, "10 Centimeters", 0.1, 0.0, B_UNIT_DEF_SUPPRESS},
{"centimeter", "centimeters", "cm", NULL, "Centimeters", 0.01, 0.0, B_UNIT_DEF_NONE},
{"millimeter", "millimeters", "mm", NULL, "Millimeters", 0.001, 0.0, B_UNIT_DEF_NONE},
- {"micrometer", "micrometers", "um", "µm", "Micrometers", 0.000001, 0.0, B_UNIT_DEF_NONE}, // micron too?
+ {"micrometer", "micrometers", "µm", "um", "Micrometers", 0.000001, 0.0, B_UNIT_DEF_NONE}, // micron too?
/* These get displayed because of float precision problems in the transform header,
* could work around, but for now probably people wont use these */
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index fff0a08136b..6fb1c5ff70c 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -35,20 +35,10 @@
#include "MEM_guardedalloc.h"
#include "DNA_world_types.h"
-#include "DNA_texture_types.h"
#include "DNA_scene_types.h"
-#include "DNA_object_types.h"
-#include "DNA_camera_types.h"
-
-
-#include "BLI_blenlib.h"
-#include "BLI_math.h"
-
-#include "BKE_utildefines.h"
#include "BKE_library.h"
#include "BKE_animsys.h"
-#include "BKE_world.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_icons.h"
@@ -57,10 +47,6 @@
#include "BPY_extern.h"
#endif
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
void free_world(World *wrld)
{
MTex *mtex;
@@ -86,12 +72,12 @@ World *add_world(char *name)
wrld= alloc_libblock(&G.main->world, ID_WO, name);
- wrld->horr= 0.25f;
- wrld->horg= 0.25f;
- wrld->horb= 0.25f;
- wrld->zenr= 0.1f;
- wrld->zeng= 0.1f;
- wrld->zenb= 0.1f;
+ wrld->horr= 0.05f;
+ wrld->horg= 0.05f;
+ wrld->horb= 0.05f;
+ wrld->zenr= 0.01f;
+ wrld->zeng= 0.01f;
+ wrld->zenb= 0.01f;
wrld->skytype= 0;
wrld->stardist= 15.0f;
wrld->starsize= 2.0f;
@@ -110,6 +96,8 @@ World *add_world(char *name)
wrld->ao_approx_error= 0.25f;
wrld->preview = NULL;
+ wrld->miststa = 5.0f;
+ wrld->mistdist = 25.0f;
return wrld;
}
@@ -145,9 +133,9 @@ void make_local_world(World *wrld)
int local=0, lib=0;
/* - only lib users: do nothing
- * - only local users: set flag
- * - mixed: make copy
- */
+ * - only local users: set flag
+ * - mixed: make copy
+ */
if(wrld->id.lib==0) return;
if(wrld->id.us==1) {
diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c
index d67a79154d2..00614ef0f4f 100644
--- a/source/blender/blenkernel/intern/writeavi.c
+++ b/source/blender/blenkernel/intern/writeavi.c
@@ -75,11 +75,6 @@ bMovieHandle *BKE_get_movie_handle(int imtype)
mh.get_movie_path = filepath_avi;
/* do the platform specific handles */
-#ifdef __sgi
- if (imtype == R_MOVIE) {
-
- }
-#endif
#if defined(_WIN32) && !defined(FREE_WINDOWS)
if (imtype == R_AVICODEC) {
//XXX mh.start_movie= start_avi_codec;
@@ -124,12 +119,12 @@ static void filepath_avi (char *string, RenderData *rd)
if (string==NULL) return;
strcpy(string, rd->pic);
- BLI_convertstringcode(string, G.sce);
+ BLI_path_abs(string, G.sce);
BLI_make_existing_file(string);
if (!BLI_testextensie(string, ".avi")) {
- BLI_convertstringframe_range(string, rd->sfra, rd->efra, 4);
+ BLI_path_frame_range(string, rd->sfra, rd->efra, 4);
strcat(string, ".avi");
}
}
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 6e94602c0c9..8ebf98ef930 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -69,10 +69,6 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
extern void do_init_ffmpeg();
static int ffmpeg_type = 0;
@@ -206,7 +202,7 @@ static const char** get_file_extensions(int format)
}
case FFMPEG_MPEG2: {
static const char * rv[] = { ".dvd", ".vob", ".mpg", ".mpeg",
- NULL };
+ NULL };
return rv;
}
case FFMPEG_MPEG4: {
@@ -271,7 +267,7 @@ static int write_video_frame(RenderData *rd, AVFrame* frame, ReportList *reports
}
outsize = avcodec_encode_video(c, video_buffer, video_buffersize,
- frame);
+ frame);
if (outsize != 0) {
AVPacket packet;
av_init_packet(&packet);
@@ -366,7 +362,7 @@ static AVFrame* generate_video_frame(uint8_t* pixels, ReportList *reports)
}
if (c->pix_fmt != PIX_FMT_BGR32) {
- sws_scale(img_convert_ctx, rgb_frame->data,
+ sws_scale(img_convert_ctx, (const uint8_t * const*) rgb_frame->data,
rgb_frame->linesize, 0, c->height,
current_frame->data, current_frame->linesize);
delete_picture(rgb_frame);
@@ -382,7 +378,7 @@ static void set_ffmpeg_property_option(AVCodecContext* c, IDProperty * prop)
fprintf(stderr, "FFMPEG expert option: %s: ", prop->name);
- strncpy(name, prop->name, 128);
+ BLI_strncpy(name, prop->name, sizeof(name));
param = strchr(name, ':');
@@ -446,7 +442,7 @@ static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char
/* prepare a video stream for the output file */
static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContext* of,
- int rectx, int recty)
+ int rectx, int recty)
{
AVStream* st;
AVCodecContext* c;
@@ -520,6 +516,12 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
/* arghhhh ... */
c->pix_fmt = PIX_FMT_YUV420P;
}
+
+ if (codec_id == CODEC_ID_H264) {
+ /* correct wrong default ffmpeg param which crash x264 */
+ c->qmin=10;
+ c->qmax=51;
+ }
if ((of->oformat->flags & AVFMT_GLOBALHEADER)
// || !strcmp(of->oformat->name, "mp4")
@@ -552,7 +554,7 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
video_buffersize = 2000000;
video_buffer = (uint8_t*)MEM_mallocN(video_buffersize,
- "FFMPEG video buffer");
+ "FFMPEG video buffer");
current_frame = alloc_picture(c->pix_fmt, c->width, c->height);
@@ -789,7 +791,7 @@ void filepath_ffmpeg(char* string, RenderData* rd) {
if (!string || !exts) return;
strcpy(string, rd->pic);
- BLI_convertstringcode(string, G.sce);
+ BLI_path_abs(string, G.sce);
BLI_make_existing_file(string);
@@ -810,7 +812,7 @@ void filepath_ffmpeg(char* string, RenderData* rd) {
if (!*fe) {
strcat(string, autosplit);
- BLI_convertstringframe_range(string, rd->sfra, rd->efra, 4);
+ BLI_path_frame_range(string, rd->sfra, rd->efra, 4);
strcat(string, *exts);
} else {
*(string + strlen(string) - strlen(*fe)) = 0;
@@ -1053,7 +1055,7 @@ IDProperty *ffmpeg_property_add(RenderData *rd, char * type, int opt_index, int
/* not all versions of ffmpeg include that, so here we go ... */
static const AVOption *my_av_find_opt(void *v, const char *name,
- const char *unit, int mask, int flags){
+ const char *unit, int mask, int flags){
AVClass *c= *(AVClass**)v;
const AVOption *o= c->option;
@@ -1078,7 +1080,7 @@ int ffmpeg_property_add_string(RenderData *rd, const char * type, const char * s
avcodec_get_context_defaults(&c);
- strncpy(name_, str, 128);
+ strncpy(name_, str, sizeof(name_));
name = name_;
while (*name == ' ') name++;
@@ -1242,7 +1244,8 @@ void ffmpeg_verify_image_type(RenderData *rd)
rd->ffcodecdata.video_bitrate <= 1) {
rd->ffcodecdata.codec = CODEC_ID_MPEG2VIDEO;
- ffmpeg_set_preset(rd, FFMPEG_PRESET_DVD);
+ /* Don't set preset, disturbs render resolution.
+ * ffmpeg_set_preset(rd, FFMPEG_PRESET_DVD); */
}
audio= 1;
diff --git a/source/blender/blenkernel/intern/writeframeserver.c b/source/blender/blenkernel/intern/writeframeserver.c
index 20d858fffeb..0ec8837c0e7 100644
--- a/source/blender/blenkernel/intern/writeframeserver.c
+++ b/source/blender/blenkernel/intern/writeframeserver.c
@@ -1,4 +1,6 @@
/*
+ * $Id$
+ *
* Frameserver
* Makes Blender accessible from TMPGenc directly using VFAPI (you can
* use firefox too ;-)
@@ -44,21 +46,14 @@
#include <stdlib.h>
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "DNA_userdef_types.h"
#include "BKE_global.h"
#include "BKE_report.h"
-#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
#include "DNA_scene_types.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
static int sock;
static int connsock;
static int write_ppm;
@@ -96,7 +91,7 @@ static int select_was_interrupted_by_signal()
return (errno == EINTR);
}
-static int closesocket(int fd)
+static int closesocket(int fd)
{
return close(fd);
}
@@ -143,10 +138,10 @@ int start_frameserver(struct Scene *scene, RenderData *rd, int rectx, int recty,
return 1;
}
-static char index_page[]
-=
-"HTTP/1.1 200 OK\n"
-"Content-Type: text/html\n\n"
+static char index_page[] =
+"HTTP/1.1 200 OK\r\n"
+"Content-Type: text/html\r\n"
+"\r\n"
"<html><head><title>Blender Frameserver</title></head>\n"
"<body><pre>\n"
"<H2>Blender Frameserver</H2>\n"
@@ -159,9 +154,10 @@ static char index_page[]
"\n"
"</pre></body></html>\n";
-static char good_bye[]
-= "HTTP/1.1 200 OK\n"
-"Content-Type: text/html\n\n"
+static char good_bye[] =
+"HTTP/1.1 200 OK\r\n"
+"Content-Type: text/html\r\n"
+"\r\n"
"<html><head><title>Blender Frameserver</title></head>\n"
"<body><pre>\n"
"Render stopped. Goodbye</pre></body></html>";
@@ -204,7 +200,7 @@ static int handle_request(RenderData *rd, char * req)
*p = 0;
if (strcmp(path, "/index.html") == 0
- || strcmp(path, "/") == 0) {
+ || strcmp(path, "/") == 0) {
safe_puts(index_page);
return -1;
}
@@ -219,13 +215,14 @@ static int handle_request(RenderData *rd, char * req)
if (strcmp(path, "/info.txt") == 0) {
char buf[4096];
- sprintf(buf,
- "HTTP/1.1 200 OK\n"
- "Content-Type: text/html\n\n"
+ sprintf(buf,
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/html\r\n"
+ "\r\n"
"start %d\n"
"end %d\n"
"width %d\n"
- "height %d\n"
+ "height %d\n"
"rate %d\n"
"ratescale %d\n",
rd->sfra,
@@ -290,7 +287,7 @@ int frameserver_loop(RenderData *rd, ReportList *reports)
tv.tv_sec = 10;
tv.tv_usec = 0;
- rval = select(connsock + 1, &readfds, NULL, NULL, &tv);
+ rval = select(connsock + 1, &readfds, NULL, NULL, &tv);
if (rval > 0) {
break;
} else if (rval == 0) {
@@ -320,10 +317,11 @@ static void serve_ppm(int *pixels, int rectx, int recty)
int y;
char header[1024];
- sprintf(header,
- "HTTP/1.1 200 OK\n"
- "Content-Type: image/ppm\n"
- "Connection: close\n\n"
+ sprintf(header,
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Type: image/ppm\r\n"
+ "Connection: close\r\n"
+ "\r\n"
"P6\n"
"# Creator: blender frameserver v0.0.1\n"
"%d %d\n"
@@ -346,7 +344,7 @@ static void serve_ppm(int *pixels, int rectx, int recty)
target += 3;
src += 4;
}
- safe_write((char*)row, 3 * rectx);
+ safe_write((char*)row, 3 * rectx);
}
free(row);
closesocket(connsock);