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:
authorDaniel Genrich <daniel.genrich@gmx.net>2008-01-27 00:54:09 +0300
committerDaniel Genrich <daniel.genrich@gmx.net>2008-01-27 00:54:09 +0300
commit1f0e182f351cf5bbf1226aef3385081348bea6bc (patch)
tree55e5e224dd73409fd09a77b9fba3a28f3bbb260c
parenta1a9e011b8d1f545a5db3144b22b48a7a4df2786 (diff)
parentbda73e2f353267dc3d7ba16dcebacbc80b937ed7 (diff)
svn merge -r 13382:13415 https://svn.blender.org/svnroot/bf-blender/trunk/blender
-rw-r--r--release/scripts/lightwave_import.py9
-rw-r--r--source/blender/blenkernel/BKE_particle.h2
-rw-r--r--source/blender/blenkernel/BKE_utildefines.h1
-rw-r--r--source/blender/blenkernel/intern/constraint.c116
-rw-r--r--source/blender/blenkernel/intern/particle.c33
-rw-r--r--source/blender/blenkernel/intern/particle_system.c3
-rw-r--r--source/blender/blenlib/intern/storage.c19
-rw-r--r--source/blender/blenloader/intern/readfile.c14
-rw-r--r--source/blender/include/BDR_sculptmode.h8
-rw-r--r--source/blender/include/BIF_transform.h2
-rw-r--r--source/blender/include/butspace.h2
-rw-r--r--source/blender/include/transform.h3
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h25
-rw-r--r--source/blender/makesdna/DNA_particle_types.h3
-rw-r--r--source/blender/makesdna/DNA_scene_types.h5
-rw-r--r--source/blender/python/api2_2x/doc/Render.py9
-rw-r--r--source/blender/python/api2_2x/sceneRender.c16
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h2
-rw-r--r--source/blender/render/intern/include/occlusion.h2
-rw-r--r--source/blender/render/intern/include/render_types.h16
-rw-r--r--source/blender/render/intern/include/strand.h6
-rw-r--r--source/blender/render/intern/include/zbuf.h2
-rw-r--r--source/blender/render/intern/source/convertblender.c198
-rw-r--r--source/blender/render/intern/source/occlusion.c73
-rw-r--r--source/blender/render/intern/source/pipeline.c2
-rw-r--r--source/blender/render/intern/source/rendercore.c39
-rw-r--r--source/blender/render/intern/source/sss.c8
-rw-r--r--source/blender/render/intern/source/strand.c69
-rw-r--r--source/blender/render/intern/source/zbuf.c260
-rw-r--r--source/blender/src/buttons_object.c131
-rw-r--r--source/blender/src/buttons_scene.c23
-rw-r--r--source/blender/src/buttons_shading.c6
-rw-r--r--source/blender/src/drawaction.c35
-rw-r--r--source/blender/src/editaction.c1
-rw-r--r--source/blender/src/editconstraint.c15
-rw-r--r--source/blender/src/editipo.c2
-rw-r--r--source/blender/src/editmesh_tools.c43
-rw-r--r--source/blender/src/editnode.c6
-rw-r--r--source/blender/src/editobject.c38
-rw-r--r--source/blender/src/editseq.c2
-rw-r--r--source/blender/src/header_view3d.c77
-rw-r--r--source/blender/src/outliner.c72
-rw-r--r--source/blender/src/previewrender.c5
-rw-r--r--source/blender/src/sculptmode-stroke.c12
-rw-r--r--source/blender/src/sculptmode.c441
-rw-r--r--source/blender/src/transform.c166
46 files changed, 1300 insertions, 722 deletions
diff --git a/release/scripts/lightwave_import.py b/release/scripts/lightwave_import.py
index 24e072f018a..2049fbd2380 100644
--- a/release/scripts/lightwave_import.py
+++ b/release/scripts/lightwave_import.py
@@ -656,7 +656,12 @@ def read_clip(lwochunk, dir_part):
# ima, IMAG, g_IMAG refers to clip dictionary 'ID' entries: refer to blok and surf
clip_dict = {}
data = cStringIO.StringIO(lwochunk.read())
- image_index, = struct.unpack(">L", data.read(4))
+ data_str = data.read(4)
+ if len(data_str) < 4: # can be zero also??? :/
+ # Should not happen but lw can import so we should too
+ return
+
+ image_index, = struct.unpack(">L", data_str)
clip_dict['ID'] = image_index
i = 4
while(i < lwochunk.chunksize):
@@ -1634,11 +1639,11 @@ def main():
return
Blender.Window.FileSelector(read, "Import LWO", '*.lwo')
-
if __name__=='__main__':
main()
+
# Cams debugging lwo loader
"""
TIME= Blender.sys.time()
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index af5713b565d..3358cfbfd2b 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -215,7 +215,7 @@ void free_keyed_keys(struct ParticleSystem *psys);
void psys_free(struct Object * ob, struct ParticleSystem * psys);
void psys_free_children(struct ParticleSystem *psys);
-void psys_render_set(struct Object *ob, struct ParticleSystem *psys, float viewmat[][4], float winmat[][4], int winx, int winy);
+void psys_render_set(struct Object *ob, struct ParticleSystem *psys, float viewmat[][4], float winmat[][4], int winx, int winy, int timeoffset);
void psys_render_restore(struct Object *ob, struct ParticleSystem *psys);
int psys_render_simplify_distribution(struct ParticleThreadContext *ctx, int tot);
int psys_render_simplify_params(struct ParticleSystem *psys, struct ChildParticle *cpa, float *params);
diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h
index d08f42375ac..fc22f6787b1 100644
--- a/source/blender/blenkernel/BKE_utildefines.h
+++ b/source/blender/blenkernel/BKE_utildefines.h
@@ -112,6 +112,7 @@
#define VECADD(v1,v2,v3) {*(v1)= *(v2) + *(v3); *(v1+1)= *(v2+1) + *(v3+1); *(v1+2)= *(v2+2) + *(v3+2);}
#define VECSUB(v1,v2,v3) {*(v1)= *(v2) - *(v3); *(v1+1)= *(v2+1) - *(v3+1); *(v1+2)= *(v2+2) - *(v3+2);}
#define VECADDFAC(v1,v2,v3,fac) {*(v1)= *(v2) + *(v3)*(fac); *(v1+1)= *(v2+1) + *(v3+1)*(fac); *(v1+2)= *(v2+2) + *(v3+2)*(fac);}
+#define QUATADDFAC(v1,v2,v3,fac) {*(v1)= *(v2) + *(v3)*(fac); *(v1+1)= *(v2+1) + *(v3+1)*(fac); *(v1+2)= *(v2+2) + *(v3+2)*(fac); *(v1+3)= *(v2+3) + *(v3+3)*(fac);}
#define INPR(v1, v2) ( (v1)[0]*(v2)[0] + (v1)[1]*(v2)[1] + (v1)[2]*(v2)[2] )
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 7d7180da271..38f25b54fd8 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -2382,6 +2382,118 @@ static bConstraintTypeInfo CTI_LOCKTRACK = {
locktrack_evaluate /* evaluate */
};
+/* ---------- Limit Distance Constraint ----------- */
+
+static void distlimit_new_data (void *cdata)
+{
+ bDistLimitConstraint *data= (bDistLimitConstraint *)cdata;
+
+ data->dist= 0.0;
+}
+
+static void distlimit_get_tars (bConstraint *con, ListBase *list)
+{
+ if (con && list) {
+ bDistLimitConstraint *data= con->data;
+ bConstraintTarget *ct;
+
+ /* standard target-getting macro for single-target constraints */
+ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list)
+ }
+}
+
+static void distlimit_flush_tars (bConstraint *con, ListBase *list, short nocopy)
+{
+ if (con && list) {
+ bDistLimitConstraint *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 distlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
+{
+ bDistLimitConstraint *data= con->data;
+ bConstraintTarget *ct= targets->first;
+
+ /* only evaluate if there is a target */
+ if (VALID_CONS_TARGET(ct)) {
+ float dvec[3], dist=0.0f, sfac=1.0f;
+ short clamp_surf= 0;
+
+ /* calculate our current distance from the target */
+ dist= VecLenf(cob->matrix[3], ct->matrix[3]);
+
+ /* set distance (flag is only set when user demands it) */
+ if (data->dist == 0)
+ data->dist= dist;
+
+ /* check if we're which way to clamp from, and calculate interpolation factor (if needed) */
+ if (data->mode == LIMITDIST_OUTSIDE) {
+ /* if inside, then move to surface */
+ if (dist <= data->dist) {
+ clamp_surf= 1;
+ sfac= data->dist / dist;
+ }
+ /* if soft-distance is enabled, start fading once owner is dist+softdist from the target */
+ else if (data->flag & LIMITDIST_USESOFT) {
+ if (dist <= (data->dist + data->soft)) {
+
+ }
+ }
+ }
+ else if (data->mode == LIMITDIST_INSIDE) {
+ /* if outside, then move to surface */
+ if (dist >= data->dist) {
+ clamp_surf= 1;
+ sfac= data->dist / dist;
+ }
+ /* if soft-distance is enabled, start fading once owner is dist-soft from the target */
+ else if (data->flag & LIMITDIST_USESOFT) {
+ // FIXME: there's a problem with "jumping" when this kicks in
+ if (dist >= (data->dist - data->soft)) {
+ sfac = data->soft*(1.0 - exp(-(dist - data->dist)/data->soft)) + data->dist;
+ sfac /= dist;
+
+ clamp_surf= 1;
+ }
+ }
+ }
+ else {
+ if (IS_EQ(dist, data->dist)==0) {
+ clamp_surf= 1;
+ sfac= data->dist / dist;
+ }
+ }
+
+ /* clamp to 'surface' (i.e. move owner so that dist == data->dist) */
+ if (clamp_surf) {
+ /* simply interpolate along line formed by target -> owner */
+ VecLerpf(dvec, ct->matrix[3], cob->matrix[3], sfac);
+
+ /* copy new vector onto owner */
+ VECCOPY(cob->matrix[3], dvec);
+ }
+ }
+}
+
+static bConstraintTypeInfo CTI_DISTLIMIT = {
+ CONSTRAINT_TYPE_DISTLIMIT, /* type */
+ sizeof(bDistLimitConstraint), /* size */
+ "Limit Distance", /* name */
+ "bDistLimitConstraint", /* struct name */
+ NULL, /* free data */
+ NULL, /* relink data */
+ NULL, /* copy data */
+ distlimit_new_data, /* new data */
+ distlimit_get_tars, /* get constraint targets */
+ distlimit_flush_tars, /* flush constraint targets */
+ default_get_tarmat, /* get a target matrix */
+ distlimit_evaluate /* evaluate */
+};
+
/* ---------- Stretch To ------------ */
static void stretchto_new_data (void *cdata)
@@ -3067,12 +3179,12 @@ static void constraints_init_typeinfo () {
constraintsTypeInfo[11]= &CTI_PYTHON; /* Python/Script Constraint */
constraintsTypeInfo[12]= &CTI_ACTION; /* Action Constraint */
constraintsTypeInfo[13]= &CTI_LOCKTRACK; /* Locked-Track Constraint */
- constraintsTypeInfo[14]= NULL; /* 'Distance Limit' Constraint */
+ constraintsTypeInfo[14]= &CTI_DISTLIMIT; /* Limit Distance Constraint */
constraintsTypeInfo[15]= &CTI_STRETCHTO; /* StretchTo Constaint */
constraintsTypeInfo[16]= &CTI_MINMAX; /* Floor Constraint */
constraintsTypeInfo[17]= &CTI_RIGIDBODYJOINT; /* RigidBody Constraint */
constraintsTypeInfo[18]= &CTI_CLAMPTO; /* ClampTo Constraint */
- constraintsTypeInfo[19]= &CTI_TRANSFORM; /* Transformation Constraint */
+ constraintsTypeInfo[19]= &CTI_TRANSFORM; /* Transformation Constraint */
}
/* This function should be used for getting the appropriate type-info when only
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 5b92eb12d4f..e09d6a7f06c 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -394,6 +394,7 @@ typedef struct ParticleRenderData {
int winx, winy;
int dosimplify;
+ int timeoffset;
ParticleRenderElem *elems;
int *origindex;
} ParticleRenderData;
@@ -455,13 +456,15 @@ static float psys_render_projected_area(ParticleSystem *psys, float *center, flo
return area;
}
-void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[][4], float winmat[][4], int winx, int winy)
+void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[][4], float winmat[][4], int winx, int winy, int timeoffset)
{
ParticleRenderData*data;
ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys);
if(!G.rendering)
return;
+ if(psys->renderdata)
+ return;
data= MEM_callocN(sizeof(ParticleRenderData), "ParticleRenderData");
@@ -489,6 +492,8 @@ void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[][4], float
data->winx= winx;
data->winy= winy;
+ data->timeoffset= timeoffset;
+
psys->renderdata= data;
}
@@ -554,7 +559,13 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
if(part->draw_as!=PART_DRAW_PATH || !(part->draw & PART_DRAW_REN_STRAND))
return tot;
- if(!ctx->psys->renderdata || !(part->simplify_flag & PART_SIMPLIFY_ENABLE))
+ if(!ctx->psys->renderdata)
+ return tot;
+
+ data= ctx->psys->renderdata;
+ if(data->timeoffset)
+ return 0;
+ if(!(part->simplify_flag & PART_SIMPLIFY_ENABLE))
return tot;
mvert= dm->getVertArray(dm);
@@ -571,7 +582,6 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
facetotvert= MEM_callocN(sizeof(int)*totorigface, "SimplifyFaceArea");
elems= MEM_callocN(sizeof(ParticleRenderElem)*totorigface, "SimplifyFaceElem");
- data= ctx->psys->renderdata;
if(data->elems)
MEM_freeN(data->elems);
@@ -2076,7 +2086,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
rough_t = t;
if(part->rough1 != 0.0 && pa_rough1 != 0.0)
- do_rough(orco, rough_t, pa_rough1*part->rough1, part->rough1_size, 0.0, (ParticleKey*)state);
+ do_rough(orco, rough_t, pa_rough1*part->rough1, part->rough1_size, 0.0, (ParticleKey*)state);
if(part->rough2 != 0.0 && pa_rough2 != 0.0)
do_rough(cpa->rand, rough_t, pa_rough2*part->rough2, part->rough2_size, part->rough2_thres, (ParticleKey*)state);
@@ -2262,6 +2272,7 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda
float sel_col[3];
float nosel_col[3];
float length, vec[3];
+ float *vg_effector= NULL, effector=0.0f;
/* we don't have anything valid to create paths from so let's quit here */
if((psys->flag & PSYS_HAIR_DONE)==0 && (psys->flag & PSYS_KEYED)==0)
@@ -2310,6 +2321,9 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda
ma= give_current_material(ob, psys->part->omat);
if(ma && (psys->part->draw & PART_DRAW_MAT_COL))
VECCOPY(col, &ma->r)
+
+ if(psys->part->from!=PART_FROM_PARTICLE)
+ vg_effector = psys_cache_vgroup(psmd->dm, psys, PSYS_VG_EFFECTOR);
/*---first main loop: create all actual particles' paths---*/
for(i=0,pa=psys->particles; i<totpart; i++, pa++){
@@ -2446,6 +2460,10 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda
VecSubf(vec,(cache[i]+1)->co,cache[i]->co);
length = VecLength(vec);
+ effector= 1.0f;
+ if(vg_effector)
+ effector*= psys_interpolate_value_from_verts(psmd->dm,psys->part->from,pa->num,pa->fuv,vg_effector);
+
for(k=0, ca=cache[i]; k<=steps; k++, ca++) {
/* apply effectors */
if(edit==0 && k) {
@@ -2458,7 +2476,7 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda
do_effectors(i, pa, &eff_key, ob, psys, force, vel, dfra, cfra);
- VecMulf(force, pow((float)k / (float)steps, 100.0f * psys->part->eff_hair) / (float)steps);
+ VecMulf(force, effector*pow((float)k / (float)steps, 100.0f * psys->part->eff_hair) / (float)steps);
VecAddf(force, force, vec);
@@ -2571,6 +2589,9 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda
end_latt_deform();
psys->lattice=0;
}
+
+ if(vg_effector)
+ MEM_freeN(vg_effector);
}
/************************************************/
/* Particle Key handling */
@@ -3517,7 +3538,7 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle
part->kink_amp, part->kink, part->kink_axis, ob->obmat);
if(part->rough1 != 0.0)
- do_rough(orco, t, part->rough1, part->rough1_size, 0.0, state);
+ do_rough(orco, t, part->rough1, part->rough1_size, 0.0, state);
if(part->rough2 != 0.0)
do_rough(cpa->rand, t, part->rough2, part->rough2_size, part->rough2_thres, state);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index e71c4f90d48..3db42f091d4 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -2724,7 +2724,8 @@ static void apply_particle_forces(int pa_no, ParticleData *pa, Object *ob, Parti
force[0]=force[1]=force[2]=0.0;
tvel[0]=tvel[1]=tvel[2]=0.0;
/* add effectors */
- do_effectors(pa_no,pa,states+i,ob,psys,force,tvel,dfra,fra);
+ if(part->type != PART_HAIR)
+ do_effectors(pa_no,pa,states+i,ob,psys,force,tvel,dfra,fra);
/* calculate air-particle interaction */
if(part->dragfac!=0.0f){
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index c6011bb6fd9..5902b7dd68a 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -50,7 +50,9 @@
#include <time.h>
#include <sys/stat.h>
-#if !defined(linux) && (defined(__sgi) || defined(__sun__) || defined(__sun) || defined(__sparc) || defined(__sparc__))
+#if defined (__sun__) || defined (__sun)
+#include <sys/statvfs.h> /* Other modern unix os's should probably use this also */
+#elif !defined(linux) && (defined(__sgi) || defined(__sparc) || defined(__sparc__))
#include <sys/statfs.h>
#endif
@@ -179,7 +181,12 @@ double BLI_diskfree(char *dir)
return (double) (freec*bytesps*sectorspc);
#else
+
+#if defined (__sun__) || defined (__sun)
+ struct statvfs disk;
+#else
struct statfs disk;
+#endif
char name[FILE_MAXDIR],*slash;
int len = strlen(dir);
@@ -199,12 +206,12 @@ double BLI_diskfree(char *dir)
#ifdef __BeOS
return -1;
#endif
-#if !defined(linux) && (defined (__sgi) || defined (__sun__) || defined (__sun) || defined(__sparc) || defined(__sparc__))
- if (statfs(name, &disk, sizeof(struct statfs), 0)){
- /* printf("diskfree: Couldn't get information about %s.\n",dir); */
- return(-1);
- }
+#if defined (__sun__) || defined (__sun)
+ if (statvfs(name, &disk)) return(-1);
+#elif !defined(linux) && (defined (__sgi) || defined(__sparc) || defined(__sparc__))
+ /* WARNING - This may not be supported by geeneric unix os's - Campbell */
+ if (statfs(name, &disk, sizeof(struct statfs), 0)) return(-1);
#endif
return ( ((double) disk.f_bsize) * ((double) disk.f_bfree));
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index c725b3d63ac..a9d2e7d05a1 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1754,6 +1754,13 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
data->tar = newlibadr(fd, id->lib, data->tar);
}
break;
+ case CONSTRAINT_TYPE_DISTLIMIT:
+ {
+ bDistLimitConstraint *data;
+ data= ((bDistLimitConstraint*)con->data);
+ data->tar = newlibadr(fd, id->lib, data->tar);
+ }
+ break;
case CONSTRAINT_TYPE_NULL:
break;
}
@@ -1767,6 +1774,7 @@ static void direct_link_constraints(FileData *fd, ListBase *lb)
link_list(fd, lb);
for (cons=lb->first; cons; cons=cons->next) {
cons->data = newdataadr(fd, cons->data);
+
if (cons->type == CONSTRAINT_TYPE_PYTHON) {
bPythonConstraint *data= cons->data;
link_list(fd, &data->targets);
@@ -7844,6 +7852,12 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
expand_doit(fd, mainvar, data->tar);
}
break;
+ case CONSTRAINT_TYPE_DISTLIMIT:
+ {
+ bDistLimitConstraint *data = (bDistLimitConstraint*)curcon->data;
+ expand_doit(fd, mainvar, data->tar);
+ }
+ break;
default:
break;
}
diff --git a/source/blender/include/BDR_sculptmode.h b/source/blender/include/BDR_sculptmode.h
index 8b0b65be4de..e36b8674612 100644
--- a/source/blender/include/BDR_sculptmode.h
+++ b/source/blender/include/BDR_sculptmode.h
@@ -35,8 +35,8 @@
#include "BKE_sculpt.h"
struct uiBlock;
+struct BrushAction;
struct BrushData;
-struct EditData;
struct IndexNode;
struct KeyBlock;
struct Mesh;
@@ -65,7 +65,7 @@ void sculpt_stroke_draw();
void sculpt_radialcontrol_start(int mode);
struct BrushData *sculptmode_brush(void);
-void do_symmetrical_brush_actions(struct EditData *e, short *, short *);
+void do_symmetrical_brush_actions(struct BrushAction *a, short *, short *);
void sculptmode_update_tex(void);
char sculpt_modifiers_active(struct Object *ob);
@@ -76,8 +76,8 @@ void set_sculptmode(void);
void sculpt_stroke_new(const int max);
void sculpt_stroke_free();
void sculpt_stroke_add_point(const short x, const short y);
-void sculpt_stroke_apply(struct EditData *);
-void sculpt_stroke_apply_all(struct EditData *e);
+void sculpt_stroke_apply(struct BrushAction *);
+void sculpt_stroke_apply_all(struct BrushAction *);
void sculpt_stroke_draw();
diff --git a/source/blender/include/BIF_transform.h b/source/blender/include/BIF_transform.h
index c8e2a4832ab..a0f991f2631 100644
--- a/source/blender/include/BIF_transform.h
+++ b/source/blender/include/BIF_transform.h
@@ -68,10 +68,10 @@
#define CTX_NO_PET 4
#define CTX_TWEAK 8
#define CTX_NO_MIRROR 16
+#define CTX_AUTOCONFIRM 32
void initTransform(int mode, int context);
void Transform(void);
-void Mirror(short mode);
/* Standalone call to get the transformation center corresponding to the current situation
* returns 1 if successful, 0 otherwise (usually means there's no selection)
diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h
index a7759f799ba..28a58f7f9e4 100644
--- a/source/blender/include/butspace.h
+++ b/source/blender/include/butspace.h
@@ -700,7 +700,7 @@ enum {
B_CONSTRAINT_ADD_ACTION,
B_CONSTRAINT_ADD_LOCKTRACK,
B_CONSTRAINT_ADD_FOLLOWPATH,
- B_CONSTRAINT_ADD_DISTANCELIMIT,
+ B_CONSTRAINT_ADD_DISTLIMIT,
B_CONSTRAINT_ADD_STRETCHTO,
B_CONSTRAINT_ADD_LOCLIMIT,
B_CONSTRAINT_ADD_ROTLIMIT,
diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h
index 30b9bbf3f51..48e840a7128 100644
--- a/source/blender/include/transform.h
+++ b/source/blender/include/transform.h
@@ -363,6 +363,9 @@ int TimeScale(TransInfo *t, short mval[2]);
void initBakeTime(TransInfo *t);
int BakeTime(TransInfo *t, short mval[2]);
+void initMirror(TransInfo *t);
+int Mirror(TransInfo *t, short mval[2]);
+
/*********************** transform_conversions.c ********** */
struct ListBase;
void flushTransIpoData(TransInfo *t);
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 4ae8d6b39e6..2bcf2412588 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -307,6 +307,19 @@ typedef struct bSizeLimitConstraint {
short flag2;
} bSizeLimitConstraint;
+/* Limit Distance Constraint */
+typedef struct bDistLimitConstraint {
+ Object *tar;
+ char subtarget[32];
+
+ float dist; /* distance (radius of clamping sphere) from target */
+ float soft; /* distance from clamping-sphere to start applying 'fade' */
+
+ short flag; /* settings */
+ short mode; /* how to limit in relation to clamping sphere */
+ int pad;
+} bDistLimitConstraint;
+
/* ------------------------------------------ */
/* bConstraint->type
@@ -328,13 +341,14 @@ typedef enum B_CONSTAINT_TYPES {
CONSTRAINT_TYPE_PYTHON, /* Unimplemented no longer :) - Aligorith. Scripts */
CONSTRAINT_TYPE_ACTION,
CONSTRAINT_TYPE_LOCKTRACK, /* New Tracking constraint that locks an axis in place - theeth */
- CONSTRAINT_TYPE_DISTANCELIMIT, /* was never properly coded - removed! */
+ CONSTRAINT_TYPE_DISTLIMIT, /* limit distance */
CONSTRAINT_TYPE_STRETCHTO, /* claiming this to be mine :) is in tuhopuu bjornmose */
CONSTRAINT_TYPE_MINMAX, /* floor constraint */
CONSTRAINT_TYPE_RIGIDBODYJOINT, /* rigidbody constraint */
CONSTRAINT_TYPE_CLAMPTO, /* clampto constraint */
CONSTRAINT_TYPE_TRANSFORM, /* transformation (loc/rot/size -> loc/rot/size) constraint */
+
/* NOTE: everytime a new constraint is added, update this */
NUM_CONSTRAINT_TYPES= CONSTRAINT_TYPE_TRANSFORM
} B_CONSTRAINT_TYPES;
@@ -478,6 +492,15 @@ typedef enum B_CONSTRAINTCHANNEL_FLAG {
#define LIMIT_NOPARENT 0x01
/* for all Limit constraints - allow to be used during transform? */
#define LIMIT_TRANSFORM 0x02
+
+/* distance limit constraint */
+ /* bDistLimitConstraint->flag */
+#define LIMITDIST_USESOFT (1<<0)
+
+ /* bDistLimitConstraint->mode */
+#define LIMITDIST_INSIDE 0
+#define LIMITDIST_OUTSIDE 1
+#define LIMITDIST_ONSURFACE 2
/* python constraint -> flag */
#define PYCON_USETARGETS 0x01
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index d39fbbbc679..6fcedcd934a 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -415,7 +415,7 @@ typedef struct ParticleSystem{
#define PARS_ALIVE 3
/* psys->vg */
-#define PSYS_TOT_VG 11
+#define PSYS_TOT_VG 12
#define PSYS_VG_DENSITY 0
#define PSYS_VG_VEL 1
@@ -428,6 +428,7 @@ typedef struct ParticleSystem{
#define PSYS_VG_SIZE 8
#define PSYS_VG_TAN 9
#define PSYS_VG_ROT 10
+#define PSYS_VG_EFFECTOR 11
/* part->boidrules */
#define BOID_TOT_RULES 8
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index b342bc5afe8..8bdea93b1f4 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -120,7 +120,11 @@ typedef struct SceneRenderLayer {
struct Group *light_override;
unsigned int lay; /* scene->lay itself has priority over this */
+ unsigned int lay_zmask; /* has to be after lay, this is for Z-masking */
int layflag;
+
+ int pad;
+
int passflag; /* pass_xor has to be after passflag */
int pass_xor;
} SceneRenderLayer;
@@ -137,6 +141,7 @@ typedef struct SceneRenderLayer {
#define SCE_LAY_ALL_Z 0x8000
#define SCE_LAY_XOR 0x10000
#define SCE_LAY_DISABLE 0x20000
+#define SCE_LAY_ZMASK 0x40000
/* srl->passflag */
#define SCE_PASS_COMBINED 1
diff --git a/source/blender/python/api2_2x/doc/Render.py b/source/blender/python/api2_2x/doc/Render.py
index 7ab3d7b90a9..ddcc5a239af 100644
--- a/source/blender/python/api2_2x/doc/Render.py
+++ b/source/blender/python/api2_2x/doc/Render.py
@@ -432,6 +432,15 @@ class RenderData:
sequences.
"""
+ def getFrameFilename( frame ):
+ """
+ Get the filename used for the remdered image.
+ @type frame: int
+ @param path: the frame to use in the filename, if no argument given, use the current frame.
+ @rtype: string
+ @return: Returns the filename that blender would render to, taking into account output path, extension and frame number.
+ """
+
def setBackbufPath(path):
"""
Set the path to a background image and load it.
diff --git a/source/blender/python/api2_2x/sceneRender.c b/source/blender/python/api2_2x/sceneRender.c
index ec160ddf4ce..f5861995073 100644
--- a/source/blender/python/api2_2x/sceneRender.c
+++ b/source/blender/python/api2_2x/sceneRender.c
@@ -2201,6 +2201,19 @@ static int RenderData_setRenderPath( BPy_RenderData * self, PyObject * value )
return 0;
}
+static PyObject *RenderData_getFrameFilename( BPy_RenderData * self, PyObject *args )
+{
+ char name[FILE_MAX];
+ int frame = self->renderContext->cfra;
+
+ if( !PyArg_ParseTuple( args, "|i", &( frame ) ) )
+ return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
+ "expected int argument or nothing" ) );
+
+ BKE_makepicstring(name, self->renderContext->pic, frame, self->renderContext->imtype);
+ return PyString_FromString( name );
+}
+
PyObject *RenderData_getBackbufPath( BPy_RenderData * self )
{
return PyString_FromString( self->renderContext->backbuf );
@@ -2726,6 +2739,9 @@ static PyMethodDef BPy_RenderData_methods[] = {
{"getRenderPath", ( PyCFunction ) RenderData_getRenderPath,
METH_NOARGS,
"() - get the path to directory where rendered images will go"},
+ {"getFrameFilename", ( PyCFunction ) RenderData_getFrameFilename,
+ METH_VARARGS,
+ "() - get the filename of the frame this will be rendered, taking into account extension and frame range"},
{"setBackbufPath", ( PyCFunction ) RenderData_SetBackbufPath,
METH_VARARGS,
"(string) - get/set the path to a background image and load it"},
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 846b0867a76..de12f75300e 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -73,7 +73,7 @@ typedef struct RenderLayer {
/* copy of RenderData */
char name[RE_MAXNAME];
- unsigned int lay;
+ unsigned int lay, lay_zmask;
int layflag, passflag, pass_xor;
struct Material *mat_override;
diff --git a/source/blender/render/intern/include/occlusion.h b/source/blender/render/intern/include/occlusion.h
index 3f10d50ab2e..646ad30b318 100644
--- a/source/blender/render/intern/include/occlusion.h
+++ b/source/blender/render/intern/include/occlusion.h
@@ -45,7 +45,5 @@ void sample_occ(struct Render *re, struct ShadeInput *shi);
void cache_occ_samples(struct Render *re, struct RenderPart *pa, struct ShadeSample *ssamp);
void free_occ_samples(struct Render *re, struct RenderPart *pa);
-void *cache_occ_mesh(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, float mat[][4]);
-
#endif
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 46b5face22a..16c46ec550f 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -161,7 +161,7 @@ struct Render
/* occlusion tree */
void *occlusiontree;
- ListBase occlusionmesh;
+ ListBase strandsurface;
/* use this instead of R.r.cfra */
float cfra;
@@ -337,6 +337,18 @@ typedef struct StrandVert {
float strandco;
} StrandVert;
+typedef struct StrandSurface {
+ struct StrandSurface *next, *prev;
+ ObjectRen obr;
+ int (*face)[4];
+ float (*co)[3];
+ /* for occlusion caching */
+ float (*col)[3]; /* for occlusion */
+ /* for speedvectors */
+ float (*prevco)[3], (*nextco)[3];
+ int totvert, totface;
+} StrandSurface;
+
typedef struct StrandBuffer {
struct StrandBuffer *next, *prev;
struct StrandVert *vert;
@@ -344,7 +356,7 @@ typedef struct StrandBuffer {
struct ObjectRen *obr;
struct Material *ma;
- void *occlusionmesh;
+ struct StrandSurface *surface;
unsigned int lay;
int overrideuv;
int flag, maxdepth;
diff --git a/source/blender/render/intern/include/strand.h b/source/blender/render/intern/include/strand.h
index f1c0b6d1e3a..8e34fa27342 100644
--- a/source/blender/render/intern/include/strand.h
+++ b/source/blender/render/intern/include/strand.h
@@ -44,6 +44,9 @@ struct RenderBuckets;
struct RenderPrimitiveIterator;
struct ZSpan;
struct ObjectInstanceRen;
+struct StrandSurface;
+struct DerivedMesh;
+struct ObjectRen;
typedef struct StrandPoint {
/* position within segment */
@@ -89,6 +92,9 @@ void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint);
void render_strand_segment(struct Render *re, float winmat[][4], struct StrandPart *spart, struct ZSpan *zspan, int totzspan, StrandSegment *sseg);
void project_strands(Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, int do_buckets);
+struct StrandSurface *cache_strand_surface(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, float mat[][4], int timeoffset);
+void free_strand_surface(struct Render *re);
+
struct RenderBuckets *init_buckets(struct Render *re);
void add_buckets_primitive(struct RenderBuckets *buckets, float *min, float *max, void *prim);
void free_buckets(struct RenderBuckets *buckets);
diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h
index 1d202fa45fa..8feb18a7ab8 100644
--- a/source/blender/render/intern/include/zbuf.h
+++ b/source/blender/render/intern/include/zbuf.h
@@ -48,7 +48,7 @@ void projectverto(float *v1, float winmat[][4], float *adr);
int testclip(float *v);
void zbuffer_shadow(struct Render *re, float winmat[][4], struct LampRen *lar, int *rectz, int size, float jitx, float jity);
-void zbuffer_solid(struct RenderPart *pa, unsigned int layer, short layflag, void (*fillfunc)(struct RenderPart*, struct ZSpan*, int, void*), void *data);
+void zbuffer_solid(struct RenderPart *pa, struct RenderLayer *rl, void (*fillfunc)(struct RenderPart*, struct ZSpan*, int, void*), void *data);
unsigned short *zbuffer_transp_shade(struct RenderPart *pa, struct RenderLayer *rl, float *pass, struct ListBase *psmlist);
unsigned short *zbuffer_strands_shade(struct Render *re, struct RenderPart *pa, struct RenderLayer *rl, float *pass);
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 69ae280dc4c..7a8d151c738 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -108,6 +108,7 @@
#include "radio.h"
#include "shadbuf.h"
#include "shading.h"
+#include "strand.h"
#include "texture.h"
#include "sss.h"
#include "zbuf.h"
@@ -1465,7 +1466,7 @@ static void render_new_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mat
if(har) har->lay= obr->ob->lay;
}
}
-static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem *psys)
+static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem *psys, int timeoffset)
{
Object *ob= obr->ob;
Object *tob=0, *bb_ob=re->scene->camera;
@@ -1487,7 +1488,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
float *orco=0,*surfnor=0,*uvco=0, strandlen=0.0f, curlen=0.0f;
float hasize, pa_size, pa_time, r_tilt, cfra=bsystem_time(ob,(float)CFRA,0.0);
float adapt_angle=0.0, adapt_pix=0.0, random, simplify[2];
- int i, a, k, max_k=0, totpart, totuv=0, override_uv=-1, dosimplify = 0, doapproxao = 0;
+ int i, a, k, max_k=0, totpart, totuv=0, override_uv=-1, dosimplify = 0, dosurfacecache = 0;
int path_possible=0, keys_possible=0, baked_keys=0, totchild=psys->totchild;
int seed, path_nbr=0, path=0, orco1=0, adapt=0, uv[3]={0,0,0}, num;
char **uv_name=0;
@@ -1647,9 +1648,11 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
svert= strandbuf->vert;
- if((re->wrld.mode & WO_AMB_OCC) && (re->wrld.ao_gather_method == WO_AOGATHER_APPROX))
+ if(re->r.mode & R_SPEED)
+ dosurfacecache= 1;
+ else if((re->wrld.mode & WO_AMB_OCC) && (re->wrld.ao_gather_method == WO_AOGATHER_APPROX))
if(ma->amb != 0.0f)
- doapproxao= 1;
+ dosurfacecache= 1;
}
}
}
@@ -1827,7 +1830,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
VECCOPY(snor, surfnor);
}
- if(doapproxao && num >= 0) {
+ if(dosurfacecache && num >= 0) {
int *facenum= RE_strandren_get_face(obr, strand, 1);
*facenum= num;
}
@@ -1931,8 +1934,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
break;
}
- if(doapproxao)
- strandbuf->occlusionmesh= cache_occ_mesh(re, obr, psmd->dm, mat);
+ if(dosurfacecache)
+ strandbuf->surface= cache_strand_surface(re, obr, psmd->dm, mat, timeoffset);
/* 4. clean up */
if(ma) do_mat_ipo(ma);
@@ -2543,7 +2546,7 @@ static void init_render_surf(Render *re, ObjectRen *obr)
freedisplist(&displist);
}
-static void init_render_curve(Render *re, ObjectRen *obr, int only_verts)
+static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
{
Object *ob= obr->ob;
Curve *cu;
@@ -2621,7 +2624,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int only_verts)
}
}
- if(only_verts==0) {
+ if(timeoffset==0) {
startvlak= obr->totvlak;
index= dl->index;
for(a=0; a<dl->parts; a++, index+=3) {
@@ -2674,7 +2677,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int only_verts)
}
}
- if(dl->bevelSplitFlag || only_verts==0) {
+ if(dl->bevelSplitFlag || timeoffset==0) {
startvlak= obr->totvlak;
for(a=0; a<dl->parts; a++) {
@@ -2890,7 +2893,7 @@ static void use_mesh_edge_lookup(ObjectRen *obr, DerivedMesh *dm, MEdge *medge,
}
}
-static void init_render_mesh(Render *re, ObjectRen *obr, int only_verts)
+static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
{
Object *ob= obr->ob;
Mesh *me;
@@ -2949,12 +2952,12 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int only_verts)
/* check autosmooth and displacement, we then have to skip only-verts optimize */
do_autosmooth |= (me->flag & ME_AUTOSMOOTH);
if(do_autosmooth)
- only_verts= 0;
+ timeoffset= 0;
if(test_for_displace(re, ob ) )
- only_verts= 0;
+ timeoffset= 0;
mask= CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL;
- if(!only_verts)
+ if(!timeoffset)
if(need_orco)
mask |= CD_MASK_ORCO;
@@ -3020,7 +3023,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int only_verts)
}
}
- if(!only_verts) {
+ if(!timeoffset) {
/* store customdata names, because DerivedMesh is freed */
RE_set_customdata_names(obr, &dm->faceData);
@@ -3174,7 +3177,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int only_verts)
}
}
- if(!only_verts) {
+ if(!timeoffset) {
if (test_for_displace(re, ob ) ) {
calc_vertexnormals(re, obr, 0);
do_displacement(re, obr);
@@ -3834,7 +3837,7 @@ static void check_non_flat_quads(ObjectRen *obr)
}
}
-static void finalize_render_object(Render *re, ObjectRen *obr, int only_verts)
+static void finalize_render_object(Render *re, ObjectRen *obr, int timeoffset)
{
Object *ob= obr->ob;
@@ -3845,7 +3848,7 @@ static void finalize_render_object(Render *re, ObjectRen *obr, int only_verts)
if(ob->type!=OB_MESH && test_for_displace(re, ob))
do_displacement(re, obr);
- if(!only_verts) {
+ if(!timeoffset) {
/* phong normal interpolation can cause error in tracing
* (terminator problem) */
ob->smoothresh= 0.0;
@@ -3934,7 +3937,7 @@ static ObjectRen *find_dupligroup_dupli(Render *re, Object *ob, int psysindex)
return NULL;
}
-static void init_render_object_data(Render *re, ObjectRen *obr, int only_verts)
+static void init_render_object_data(Render *re, ObjectRen *obr, int timeoffset)
{
Object *ob= obr->ob;
ParticleSystem *psys;
@@ -3952,20 +3955,20 @@ static void init_render_object_data(Render *re, ObjectRen *obr, int only_verts)
for(psys=ob->particlesystem.first, i=0; i<obr->psysindex-1; i++)
psys= psys->next;
- render_new_particle_system(re, obr, psys);
+ render_new_particle_system(re, obr, psys, timeoffset);
}
else {
if ELEM(ob->type, OB_FONT, OB_CURVE)
- init_render_curve(re, obr, only_verts);
+ init_render_curve(re, obr, timeoffset);
else if(ob->type==OB_SURF)
init_render_surf(re, obr);
else if(ob->type==OB_MESH)
- init_render_mesh(re, obr, only_verts);
+ init_render_mesh(re, obr, timeoffset);
else if(ob->type==OB_MBALL)
init_render_mball(re, obr);
}
- finalize_render_object(re, obr, only_verts);
+ finalize_render_object(re, obr, timeoffset);
re->totvert += obr->totvert;
re->totvlak += obr->totvlak;
@@ -3973,7 +3976,7 @@ static void init_render_object_data(Render *re, ObjectRen *obr, int only_verts)
re->totstrand += obr->totstrand;
}
-static void add_render_object(Render *re, Object *ob, Object *par, int index, int only_verts, int instanceable)
+static void add_render_object(Render *re, Object *ob, Object *par, int index, int timeoffset, int instanceable)
{
ObjectRen *obr;
ParticleSystem *psys;
@@ -3985,7 +3988,7 @@ static void add_render_object(Render *re, Object *ob, Object *par, int index, in
show_emitter= 0;
for(psys=ob->particlesystem.first; psys; psys=psys->next) {
show_emitter += psys->part->draw & PART_DRAW_EMITTER;
- psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy);
+ psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy, timeoffset);
}
/* if no psys has "show emitter" selected don't render emitter */
@@ -4000,7 +4003,7 @@ static void add_render_object(Render *re, Object *ob, Object *par, int index, in
obr->flag |= R_INSTANCEABLE;
Mat4CpyMat4(obr->obmat, ob->obmat);
}
- init_render_object_data(re, obr, only_verts);
+ init_render_object_data(re, obr, timeoffset);
/* only add instance for objects that have not been used for dupli */
if(!(ob->transflag & OB_RENDER_DUPLI))
@@ -4018,7 +4021,7 @@ static void add_render_object(Render *re, Object *ob, Object *par, int index, in
obr->flag |= R_INSTANCEABLE;
Mat4CpyMat4(obr->obmat, ob->obmat);
}
- init_render_object_data(re, obr, only_verts);
+ init_render_object_data(re, obr, timeoffset);
psys_render_restore(ob, psys);
/* only add instance for objects that have not been used for dupli */
@@ -4032,7 +4035,7 @@ static void add_render_object(Render *re, Object *ob, Object *par, int index, in
/* par = pointer to duplicator parent, needed for object lookup table */
/* index = when duplicater copies same object (particle), the counter */
-static void init_render_object(Render *re, Object *ob, Object *par, int index, int only_verts, int instanceable)
+static void init_render_object(Render *re, Object *ob, Object *par, int index, int timeoffset, int instanceable)
{
static double lasttime= 0.0;
double time;
@@ -4041,7 +4044,7 @@ static void init_render_object(Render *re, Object *ob, Object *par, int index, i
if(ob->type==OB_LAMP)
add_render_lamp(re, ob);
else if(render_object_type(ob->type))
- add_render_object(re, ob, par, index, only_verts, instanceable);
+ add_render_object(re, ob, par, index, timeoffset, instanceable);
else {
MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat);
MTC_Mat4Invert(ob->imat, mat);
@@ -4119,6 +4122,7 @@ void RE_Database_Free(Render *re)
free_sss(re);
free_occ(re);
+ free_strand_surface(re);
re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0;
re->i.convertdone= 0;
@@ -4174,7 +4178,7 @@ static int allow_render_dupli_instance(Render *re, DupliObject *dob, Object *obd
!(re->r.mode & R_RADIO));
}
-static void dupli_render_particle_set(Render *re, Object *ob, int level, int enable)
+static void dupli_render_particle_set(Render *re, Object *ob, int timeoffset, int level, int enable)
{
/* ugly function, but we need to set particle systems to their render
* settings before calling object_duplilist, to get render level duplis */
@@ -4190,7 +4194,7 @@ static void dupli_render_particle_set(Render *re, Object *ob, int level, int ena
for(psys=ob->particlesystem.first; psys; psys=psys->next) {
if(ELEM(psys->part->draw_as, PART_DRAW_OB, PART_DRAW_GR)) {
if(enable)
- psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy);
+ psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy, timeoffset);
else
psys_render_restore(ob, psys);
}
@@ -4212,10 +4216,10 @@ static void dupli_render_particle_set(Render *re, Object *ob, int level, int ena
group= ob->dup_group;
for(go= group->gobject.first; go; go= go->next)
- dupli_render_particle_set(re, go->ob, level+1, enable);
+ dupli_render_particle_set(re, go->ob, timeoffset, level+1, enable);
}
-static void database_init_objects(Render *re, unsigned int lay, int nolamps, int onlyselected, Object *actob, int only_verts)
+static void database_init_objects(Render *re, unsigned int lay, int nolamps, int onlyselected, Object *actob, int timeoffset)
{
Base *base;
Object *ob;
@@ -4243,16 +4247,16 @@ static void database_init_objects(Render *re, unsigned int lay, int nolamps, int
if(ob->flag & OB_DONE) {
if(ob->transflag & OB_RENDER_DUPLI)
if(allow_render_object(ob, nolamps, onlyselected, actob))
- init_render_object(re, ob, NULL, 0, only_verts, 1);
+ init_render_object(re, ob, NULL, 0, timeoffset, 1);
}
else if((base->lay & lay) || (ob->type==OB_LAMP && (base->lay & re->scene->lay)) ) {
if((ob->transflag & OB_DUPLI) && (ob->type!=OB_MBALL)) {
DupliObject *dob;
ListBase *lb;
- dupli_render_particle_set(re, ob, 0, 1);
+ dupli_render_particle_set(re, ob, timeoffset, 0, 1);
lb= object_duplilist(sce, ob);
- dupli_render_particle_set(re, ob, 0, 0);
+ dupli_render_particle_set(re, ob, timeoffset, 0, 0);
for(dob= lb->first; dob; dob= dob->next) {
Object *obd= dob->ob;
@@ -4294,7 +4298,7 @@ static void database_init_objects(Render *re, unsigned int lay, int nolamps, int
}
}
else
- init_render_object(re, obd, ob, dob->index, only_verts, !dob->animated);
+ init_render_object(re, obd, ob, dob->index, timeoffset, !dob->animated);
psysindex= 1;
for(psys=obd->particlesystem.first; psys; psys=psys->next) {
@@ -4319,17 +4323,17 @@ static void database_init_objects(Render *re, unsigned int lay, int nolamps, int
}
}
else
- init_render_object(re, obd, ob, dob->index, only_verts, !dob->animated);
+ init_render_object(re, obd, ob, dob->index, timeoffset, !dob->animated);
if(re->test_break()) break;
}
free_object_duplilist(lb);
if(allow_render_object(ob, nolamps, onlyselected, actob))
- init_render_object(re, ob, NULL, 0, only_verts, 0);
+ init_render_object(re, ob, NULL, 0, timeoffset, 0);
}
else if(allow_render_object(ob, nolamps, onlyselected, actob))
- init_render_object(re, ob, NULL, 0, only_verts, 0);
+ init_render_object(re, ob, NULL, 0, timeoffset, 0);
}
if(re->test_break()) break;
@@ -4513,7 +4517,7 @@ static void database_fromscene_vectors(Render *re, Scene *scene, int timeoffset)
}
/* MAKE RENDER DATA */
- database_init_objects(re, lay, 0, 0, 0, 1);
+ database_init_objects(re, lay, 0, 0, 0, timeoffset);
if(!re->test_break())
project_renderdata(re, projectverto, re->r.mode & R_PANORAMA, 0, 1);
@@ -4608,14 +4612,49 @@ static void calculate_speedvector(float *vectors, int step, float winsq, float w
}
}
+static float *calculate_strandsurface_speedvectors(Render *re, ObjectInstanceRen *obi, StrandSurface *mesh)
+{
+ float winsq= re->winx*re->winy, winroot= sqrt(winsq), (*winspeed)[4];
+ float ho[4], prevho[4], nextho[4], winmat[4][4], vec[2];
+ int a;
+
+ if(mesh->co && mesh->prevco && mesh->nextco) {
+ if(obi->flag & R_TRANSFORMED)
+ Mat4MulMat4(winmat, obi->mat, re->winmat);
+ else
+ Mat4CpyMat4(winmat, re->winmat);
+
+ winspeed= MEM_callocN(sizeof(float)*4*mesh->totvert, "StrandSurfWin");
+
+ for(a=0; a<mesh->totvert; a++) {
+ projectvert(mesh->co[a], winmat, ho);
+
+ projectvert(mesh->prevco[a], winmat, prevho);
+ speedvector_project(NULL, vec, mesh->prevco[a], prevho);
+ calculate_speedvector(vec, 0, winsq, winroot, mesh->co[a], ho, winspeed[a]);
+
+ projectvert(mesh->nextco[a], winmat, nextho);
+ speedvector_project(NULL, vec, mesh->nextco[a], nextho);
+ calculate_speedvector(vec, 1, winsq, winroot, mesh->co[a], ho, winspeed[a]);
+ }
+
+ return (float*)winspeed;
+ }
+
+ return NULL;
+}
+
static void calculate_speedvectors(Render *re, ObjectInstanceRen *obi, float *vectors, int step)
{
ObjectRen *obr= obi->obr;
VertRen *ver= NULL;
StrandRen *strand= NULL;
- float *speed, ho[4], winmat[4][4];
+ StrandBuffer *strandbuf;
+ StrandSurface *mesh= NULL;
+ float *speed, (*winspeed)[4]=NULL, ho[4], winmat[4][4];
+ float *co1, *co2, *co3, *co4, w[4];
float winsq= re->winx*re->winy, winroot= sqrt(winsq);
- int a;
+ int a, *face, *index;
if(obi->flag & R_TRANSFORMED)
Mat4MulMat4(winmat, obi->mat, re->winmat);
@@ -4634,13 +4673,42 @@ static void calculate_speedvectors(Render *re, ObjectInstanceRen *obi, float *ve
}
if(obr->strandnodes) {
- for(a=0; a<obr->totstrand; a++, vectors+=2) {
- if((a & 255)==0) strand= obr->strandnodes[a>>8].strand;
- else strand++;
+ strandbuf= obr->strandbufs.first;
+ mesh= (strandbuf)? strandbuf->surface: NULL;
+
+ /* compute speed vectors at surface vertices */
+ if(mesh)
+ winspeed= (float(*)[4])calculate_strandsurface_speedvectors(re, obi, mesh);
- speed= RE_strandren_get_winspeed(obi, strand, 1);
- projectvert(strand->vert->co, winmat, ho);
- calculate_speedvector(vectors, step, winsq, winroot, strand->vert->co, ho, speed);
+ if(winspeed) {
+ for(a=0; a<obr->totstrand; a++, vectors+=2) {
+ if((a & 255)==0) strand= obr->strandnodes[a>>8].strand;
+ else strand++;
+
+ index= RE_strandren_get_face(obr, strand, 0);
+ if(index && *index) {
+ speed= RE_strandren_get_winspeed(obi, strand, 1);
+
+ /* interpolate speed vectors from strand surface */
+ face= mesh->face[*index];
+
+ co1= mesh->co[face[0]];
+ co2= mesh->co[face[1]];
+ co3= mesh->co[face[2]];
+ co4= (face[3])? mesh->co[face[3]]: NULL;
+
+ InterpWeightsQ3Dfl(co1, co2, co3, co4, strand->vert->co, w);
+
+ speed[0]= speed[1]= speed[2]= speed[3]= 0.0f;
+ QUATADDFAC(speed, speed, winspeed[face[0]], w[0]);
+ QUATADDFAC(speed, speed, winspeed[face[1]], w[1]);
+ QUATADDFAC(speed, speed, winspeed[face[2]], w[2]);
+ if(face[3])
+ QUATADDFAC(speed, speed, winspeed[face[3]], w[3]);
+ }
+ }
+
+ MEM_freeN(winspeed);
}
}
}
@@ -4731,7 +4799,6 @@ static void copy_dbase_object_vectors(Render *re, ListBase *lb)
ObjectInstanceRen *obi, *obilb;
ObjectRen *obr;
VertRen *ver= NULL;
- StrandRen *strand= NULL;
float *vec, ho[4], winmat[4][4];
int a, totvector;
@@ -4742,7 +4809,7 @@ static void copy_dbase_object_vectors(Render *re, ListBase *lb)
memcpy(obilb, obi, sizeof(ObjectInstanceRen));
BLI_addtail(lb, obilb);
- obilb->totvector= totvector= obr->totvert + obr->totstrand;
+ obilb->totvector= totvector= obr->totvert;
if(totvector > 0) {
vec= obilb->vectors= MEM_mallocN(2*sizeof(float)*totvector, "vector array");
@@ -4759,14 +4826,6 @@ static void copy_dbase_object_vectors(Render *re, ListBase *lb)
projectvert(ver->co, winmat, ho);
speedvector_project(NULL, vec, ver->co, ho);
}
-
- for(a=0; a<obr->totstrand; a++, vec+=2) {
- if((a & 255)==0) strand= obr->strandnodes[a>>8].strand;
- else strand++;
-
- projectvert(strand->vert->co, winmat, ho);
- speedvector_project(NULL, vec, strand->vert->co, ho);
- }
}
}
}
@@ -4784,8 +4843,10 @@ static void free_dbase_object_vectors(ListBase *lb)
void RE_Database_FromScene_Vectors(Render *re, Scene *sce)
{
ObjectInstanceRen *obi, *oldobi;
+ StrandSurface *mesh;
ListBase *table;
ListBase oldtable= {NULL, NULL}, newtable= {NULL, NULL};
+ ListBase strandsurface;
int step;
re->i.infostr= "Calculating previous vectors";
@@ -4800,7 +4861,10 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce)
copy_dbase_object_vectors(re, &oldtable);
/* free dbase and make the future one */
+ strandsurface= re->strandsurface;
+ memset(&re->strandsurface, 0, sizeof(ListBase));
RE_Database_Free(re);
+ re->strandsurface= strandsurface;
if(!re->test_break()) {
/* creates entire dbase */
@@ -4812,7 +4876,10 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce)
copy_dbase_object_vectors(re, &newtable);
/* free dbase and make the real one */
+ strandsurface= re->strandsurface;
+ memset(&re->strandsurface, 0, sizeof(ListBase));
RE_Database_Free(re);
+ re->strandsurface= strandsurface;
if(!re->test_break())
RE_Database_FromScene(re, sce, 1);
@@ -4829,7 +4896,7 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce)
for(obi= re->instancetable.first; obi && oldobi; obi= obi->next, oldobi= oldobi->next) {
int ok= 1;
- obi->totvector= obi->obr->totvert + obi->obr->totstrand;
+ obi->totvector= obi->obr->totvert;
/* find matching object in old table */
if(oldobi->ob!=obi->ob || oldobi->par!=obi->par || oldobi->index!=obi->index || oldobi->psysindex!=obi->psysindex) {
@@ -4867,6 +4934,17 @@ void RE_Database_FromScene_Vectors(Render *re, Scene *sce)
free_dbase_object_vectors(&oldtable);
free_dbase_object_vectors(&newtable);
+
+ for(mesh=re->strandsurface.first; mesh; mesh=mesh->next) {
+ if(mesh->prevco) {
+ MEM_freeN(mesh->prevco);
+ mesh->prevco= NULL;
+ }
+ if(mesh->nextco) {
+ MEM_freeN(mesh->nextco);
+ mesh->nextco= NULL;
+ }
+ }
re->i.infostr= NULL;
re->stats_draw(&re->i);
diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c
index 7d7ed5bcdce..e1d491c69d9 100644
--- a/source/blender/render/intern/source/occlusion.c
+++ b/source/blender/render/intern/source/occlusion.c
@@ -35,14 +35,12 @@
#include "MEM_guardedalloc.h"
#include "DNA_material_types.h"
-#include "DNA_meshdata_types.h"
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
#include "BLI_memarena.h"
#include "BLI_threads.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_utildefines.h"
@@ -74,15 +72,6 @@ typedef struct OcclusionCache {
int x, y, w, h, step;
} OcclusionCache;
-typedef struct OcclusionCacheMesh {
- struct OcclusionCacheMesh *next, *prev;
- ObjectRen *obr;
- int (*face)[4];
- float (*co)[3];
- float (*col)[3];
- int totvert, totface;
-} OcclusionCacheMesh;
-
typedef struct OccFace {
int obi;
int facenr;
@@ -1418,10 +1407,10 @@ static int sample_occ_cache(OcclusionTree *tree, float *co, float *n, int x, int
return 0;
}
-static void sample_occ_cache_mesh(ShadeInput *shi)
+static void sample_occ_surface(ShadeInput *shi)
{
StrandRen *strand= shi->strand;
- OcclusionCacheMesh *mesh= strand->buffer->occlusionmesh;
+ StrandSurface *mesh= strand->buffer->surface;
int *face, *index = RE_strandren_get_face(shi->obr, strand, 0);
float w[4], *co1, *co2, *co3, *co4;
@@ -1449,53 +1438,11 @@ static void sample_occ_cache_mesh(ShadeInput *shi)
}
}
-void *cache_occ_mesh(Render *re, ObjectRen *obr, DerivedMesh *dm, float mat[][4])
-{
- OcclusionCacheMesh *mesh;
- MFace *mface;
- MVert *mvert;
- int a, totvert, totface;
-
- totvert= dm->getNumVerts(dm);
- totface= dm->getNumFaces(dm);
-
- mesh= re->occlusionmesh.last;
- if(mesh && mesh->obr->ob == obr->ob && mesh->obr->par == obr->par
- && mesh->totvert==totvert && mesh->totface==totface)
- return mesh;
-
- mesh= MEM_callocN(sizeof(OcclusionCacheMesh), "OcclusionCacheMesh");
- mesh->obr= obr;
- mesh->totvert= totvert;
- mesh->totface= totface;
- mesh->co= MEM_callocN(sizeof(float)*3*mesh->totvert, "OcclusionMeshCo");
- mesh->face= MEM_callocN(sizeof(int)*4*mesh->totface, "OcclusionMeshFaces");
- mesh->col= MEM_callocN(sizeof(float)*3*mesh->totvert, "OcclusionMeshCol");
-
- mvert= dm->getVertArray(dm);
- for(a=0; a<mesh->totvert; a++, mvert++) {
- VECCOPY(mesh->co[a], mvert->co);
- Mat4MulVecfl(mat, mesh->co[a]);
- }
-
- mface= dm->getFaceArray(dm);
- for(a=0; a<mesh->totface; a++, mface++) {
- mesh->face[a][0]= mface->v1;
- mesh->face[a][1]= mface->v2;
- mesh->face[a][2]= mface->v3;
- mesh->face[a][3]= mface->v4;
- }
-
- BLI_addtail(&re->occlusionmesh, mesh);
-
- return mesh;
-}
-
/* ------------------------- External Functions --------------------------- */
void make_occ_tree(Render *re)
{
- OcclusionCacheMesh *mesh;
+ StrandSurface *mesh;
float col[3], co[3], n[3], *co1, *co2, *co3, *co4;
int a, *face, *count;
@@ -1511,7 +1458,7 @@ void make_occ_tree(Render *re)
if(re->wrld.ao_approx_passes)
occ_compute_passes(re, re->occlusiontree, re->wrld.ao_approx_passes);
- for(mesh=re->occlusionmesh.first; mesh; mesh=mesh->next) {
+ for(mesh=re->strandsurface.first; mesh; mesh=mesh->next) {
count= MEM_callocN(sizeof(int)*mesh->totvert, "OcclusionCount");
for(a=0; a<mesh->totface; a++) {
@@ -1558,20 +1505,10 @@ void make_occ_tree(Render *re)
void free_occ(Render *re)
{
- OcclusionCacheMesh *mesh;
-
if(re->occlusiontree) {
occ_free_tree(re->occlusiontree);
re->occlusiontree = NULL;
}
-
- for(mesh=re->occlusionmesh.first; mesh; mesh=mesh->next) {
- if(mesh->co) MEM_freeN(mesh->co);
- if(mesh->col) MEM_freeN(mesh->col);
- if(mesh->face) MEM_freeN(mesh->face);
- }
-
- BLI_freelistN(&re->occlusionmesh);
}
void sample_occ(Render *re, ShadeInput *shi)
@@ -1584,7 +1521,7 @@ void sample_occ(Render *re, ShadeInput *shi)
if(tree) {
if(shi->strand) {
- sample_occ_cache_mesh(shi);
+ sample_occ_surface(shi);
}
/* try to get result from the cache if possible */
else if(!sample_occ_cache(tree, shi->co, shi->vno, shi->xs, shi->ys, shi->thread, shi->ao)) {
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 43f0a0d13e7..e4aa2326c0c 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -505,6 +505,7 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int
strcpy(rl->name, srl->name);
rl->lay= srl->lay;
+ rl->lay_zmask= srl->lay_zmask;
rl->layflag= srl->layflag;
rl->passflag= srl->passflag;
rl->pass_xor= srl->pass_xor;
@@ -2358,6 +2359,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra)
continue;
}
if (scene->r.mode & R_TOUCH && !BLI_exist(name)) {
+ BLI_make_existing_file(name); /* makes the dir if its not there */
BLI_touch(name);
}
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 50f3142f95a..220c06f1ede 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -897,7 +897,7 @@ void zbufshadeDA_tile(RenderPart *pa)
sdata.rl= rl;
sdata.psmlist= &psmlist;
sdata.edgerect= edgerect;
- zbuffer_solid(pa, rl->lay, rl->layflag, make_pixelstructs, &sdata);
+ zbuffer_solid(pa, rl, make_pixelstructs, &sdata);
if(R.test_break()) break;
}
@@ -1063,7 +1063,7 @@ void zbufshade_tile(RenderPart *pa)
shade_sample_initialize(&ssamp, pa, rl);
addpassflag= rl->passflag & ~(SCE_PASS_Z|SCE_PASS_COMBINED);
- zbuffer_solid(pa, rl->lay, rl->layflag, NULL, NULL);
+ zbuffer_solid(pa, rl, NULL, NULL);
if(!R.test_break()) { /* NOTE: this if() is not consistant */
@@ -1364,12 +1364,12 @@ void zbufshade_sss_tile(RenderPart *pa)
ShadeSample ssamp;
ZBufSSSHandle handle;
RenderResult *rr= pa->result;
- RenderLayer *rl= rr->layers.first;
+ RenderLayer *rl;
VlakRen *vlr;
Material *mat= re->sss_mat;
- float (*co)[3], (*color)[3], *area, *fcol= rl->rectf;
+ float (*co)[3], (*color)[3], *area, *fcol;
int x, y, seed, quad, totpoint, display = !(re->r.scemode & R_PREVIEWBUTS);
- int *ro, *rz, *rp, *rbo, *rbz, *rbp;
+ int *ro, *rz, *rp, *rbo, *rbz, *rbp, lay;
#if 0
PixStr *ps;
long *rs;
@@ -1394,13 +1394,32 @@ void zbufshade_sss_tile(RenderPart *pa)
pa->rectbackz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackz");
#endif
+ /* setup shade sample with correct passes */
+ memset(&ssamp, 0, sizeof(ssamp));
+ shade_sample_initialize(&ssamp, pa, rr->layers.first);
+ ssamp.tot= 1;
+
+ for(rl=rr->layers.first; rl; rl=rl->next) {
+ ssamp.shi[0].lay |= rl->lay;
+ ssamp.shi[0].layflag |= rl->layflag;
+ ssamp.shi[0].passflag |= rl->passflag;
+ ssamp.shi[0].combinedflag |= ~rl->pass_xor;
+ }
+
+ rl= rr->layers.first;
+ ssamp.shi[0].passflag |= SCE_PASS_RGBA|SCE_PASS_COMBINED;
+ ssamp.shi[0].combinedflag &= ~(SCE_PASS_SPEC);
+ lay= ssamp.shi[0].lay;
+
/* create the pixelstrs to be used later */
- zbuffer_sss(pa, rl->lay, &handle, addps_sss);
+ zbuffer_sss(pa, lay, &handle, addps_sss);
if(handle.totps==0) {
zbufshade_sss_free(pa);
return;
}
+
+ fcol= rl->rectf;
co= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSCo");
color= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSColor");
@@ -1412,14 +1431,6 @@ void zbufshade_sss_tile(RenderPart *pa)
ISB_create(pa, NULL);
#endif
- /* setup shade sample with correct passes */
- memset(&ssamp, 0, sizeof(ssamp));
- shade_sample_initialize(&ssamp, pa, rl);
- ssamp.shi[0].passflag= SCE_PASS_DIFFUSE|SCE_PASS_AO|SCE_PASS_RADIO;
- ssamp.shi[0].passflag |= SCE_PASS_RGBA;
- ssamp.shi[0].combinedflag= ~(SCE_PASS_SPEC);
- ssamp.tot= 1;
-
if(display) {
/* initialize scanline updates for main thread */
rr->renrect.ymin= 0;
diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c
index 09a3b9ef66d..88333265a84 100644
--- a/source/blender/render/intern/source/sss.c
+++ b/source/blender/render/intern/source/sss.c
@@ -860,13 +860,13 @@ static void sss_create_tree_mat(Render *re, Material *mat)
setting them back, maybe we need to create our own Render? */
/* do SSS preprocessing render */
- layers= re->r.layers;
+ rr= re->result;
+ layers= rr->layers;
osa= re->osa;
osaflag= re->r.mode & R_OSA;
partsdone= re->i.partsdone;
- rr= re->result;
- re->r.layers.first= re->r.layers.last= NULL;
+ rr->layers.first= rr->layers.last= NULL;
re->osa= 0;
re->r.mode &= ~R_OSA;
re->sss_points= &points;
@@ -881,7 +881,7 @@ static void sss_create_tree_mat(Render *re, Material *mat)
re->i.partsdone= partsdone;
re->sss_mat= NULL;
re->sss_points= NULL;
- re->r.layers= layers;
+ rr->layers= layers;
re->osa= osa;
if (osaflag) re->r.mode |= R_OSA;
diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c
index 3a1d98572ca..bf58c023998 100644
--- a/source/blender/render/intern/source/strand.c
+++ b/source/blender/render/intern/source/strand.c
@@ -35,12 +35,14 @@
#include "DNA_key_types.h"
#include "DNA_material_types.h"
+#include "DNA_meshdata_types.h"
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
#include "BLI_ghash.h"
#include "BLI_memarena.h"
+#include "BKE_DerivedMesh.h"
#include "BKE_key.h"
#include "BKE_utildefines.h"
@@ -1313,3 +1315,70 @@ void project_strands(Render *re, void (*projectfunc)(float *, float mat[][4], fl
#endif
}
+StrandSurface *cache_strand_surface(Render *re, ObjectRen *obr, DerivedMesh *dm, float mat[][4], int timeoffset)
+{
+ StrandSurface *mesh;
+ MFace *mface;
+ MVert *mvert;
+ float (*co)[3];
+ int a, totvert, totface;
+
+ totvert= dm->getNumVerts(dm);
+ totface= dm->getNumFaces(dm);
+
+ for(mesh=re->strandsurface.first; mesh; mesh=mesh->next)
+ if(mesh->obr.ob == obr->ob && mesh->obr.par == obr->par
+ && mesh->obr.index == obr->index && mesh->totvert==totvert && mesh->totface==totface)
+ break;
+
+ if(!mesh) {
+ mesh= MEM_callocN(sizeof(StrandSurface), "StrandSurface");
+ mesh->obr= *obr;
+ mesh->totvert= totvert;
+ mesh->totface= totface;
+ mesh->face= MEM_callocN(sizeof(int)*4*mesh->totface, "StrandSurfFaces");
+ mesh->col= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfCol");
+ BLI_addtail(&re->strandsurface, mesh);
+ }
+
+ if(timeoffset == -1 && !mesh->prevco)
+ mesh->prevco= co= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfCo");
+ else if(timeoffset == 0 && !mesh->co)
+ mesh->co= co= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfCo");
+ else if(timeoffset == 1 && !mesh->nextco)
+ mesh->nextco= co= MEM_callocN(sizeof(float)*3*mesh->totvert, "StrandSurfCo");
+ else
+ return mesh;
+
+ mvert= dm->getVertArray(dm);
+ for(a=0; a<mesh->totvert; a++, mvert++) {
+ VECCOPY(co[a], mvert->co);
+ Mat4MulVecfl(mat, co[a]);
+ }
+
+ mface= dm->getFaceArray(dm);
+ for(a=0; a<mesh->totface; a++, mface++) {
+ mesh->face[a][0]= mface->v1;
+ mesh->face[a][1]= mface->v2;
+ mesh->face[a][2]= mface->v3;
+ mesh->face[a][3]= mface->v4;
+ }
+
+ return mesh;
+}
+
+void free_strand_surface(Render *re)
+{
+ StrandSurface *mesh;
+
+ for(mesh=re->strandsurface.first; mesh; mesh=mesh->next) {
+ if(mesh->co) MEM_freeN(mesh->co);
+ if(mesh->prevco) MEM_freeN(mesh->prevco);
+ if(mesh->nextco) MEM_freeN(mesh->nextco);
+ if(mesh->col) MEM_freeN(mesh->col);
+ if(mesh->face) MEM_freeN(mesh->face);
+ }
+
+ BLI_freelistN(&re->strandsurface);
+}
+
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index a8b6dfec667..6b103d4fce2 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -196,7 +196,6 @@ static void zbuf_add_to_span(ZSpan *zspan, float *v1, float *v2)
/* Functions */
/*-----------------------------------------------------------*/
-
void fillrect(int *rect, int x, int y, int val)
{
int len, *drect;
@@ -1922,10 +1921,78 @@ void zbufclip4(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3
zspan->zbuffunc(zspan, obi, zvlnr, vez, vez+4, vez+8, vez+12);
}
+/* ************** ZMASK ******************************** */
+
+#define EXTEND_PIXEL(a) if(temprectp[a]) {z+= rectz[a]; tot++;}
+
+/* changes the zbuffer to be ready for z-masking: applies an extend-filter, and then clears */
+static void zmask_rect(int *rectz, int *rectp, int xs, int ys)
+{
+ int len=0, x, y;
+ int *temprectp;
+ int row1, row2, row3, *curp, *curz;
+
+ temprectp= MEM_dupallocN(rectp);
+
+ /* extend: if pixel is not filled in, we check surrounding pixels and average z value */
+
+ for(y=1; y<=ys; y++) {
+ /* setup row indices */
+ row1= (y-2)*xs;
+ row2= row1 + xs;
+ row3= row2 + xs;
+ if(y==1)
+ row1= row2;
+ else if(y==ys)
+ row3= row2;
+
+ curp= rectp + (y-1)*xs;
+ curz= rectz + (y-1)*xs;
+
+ for(x=0; x<xs; x++, curp++, curz++) {
+ if(curp[0]==0) {
+ int tot= 0;
+ float z= 0.0f;
+
+ EXTEND_PIXEL(row1);
+ EXTEND_PIXEL(row2);
+ EXTEND_PIXEL(row3);
+ EXTEND_PIXEL(row1 + 1);
+ EXTEND_PIXEL(row3 + 1);
+ if(x!=xs-1) {
+ EXTEND_PIXEL(row1 + 2);
+ EXTEND_PIXEL(row2 + 2);
+ EXTEND_PIXEL(row3 + 2);
+ }
+ if(tot) {
+ len++;
+ curz[0]= (int)(z/(float)tot);
+ curp[0]= -1; /* env */
+ }
+ }
+
+ if(x!=0) {
+ row1++; row2++; row3++;
+ }
+ }
+ }
+ MEM_freeN(temprectp);
+
+ /* clear not filled z values */
+ for(len= xs*ys -1; len>=0; len--) {
+ if(rectp[len]==0) {
+ rectz[len] = -0x7FFFFFFF;
+ rectp[len]= -1; /* env code */
+ }
+ }
+}
+
+
+
/* ***************** ZBUFFER MAIN ROUTINES **************** */
-void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag, void(*fillfunc)(RenderPart*, ZSpan*, int, void*), void *data)
+void zbuffer_solid(RenderPart *pa, RenderLayer *rl, void(*fillfunc)(RenderPart*, ZSpan*, int, void*), void *data)
{
ZbufProjectCache cache[ZBUF_PROJECT_CACHE_SIZE];
ZSpan zspans[16], *zspan; /* 16 = RE_MAX_OSA */
@@ -1935,9 +2002,11 @@ void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag, void(*fillfu
ObjectInstanceRen *obi;
ObjectRen *obr;
float winmat[4][4], bounds[4], ho1[4], ho2[4], ho3[4], ho4[4]={0};
+ unsigned int lay= rl->lay, lay_zmask= rl->lay_zmask;
int i, v, zvlnr, zsample, samples, c1, c2, c3, c4=0;
- short nofill=0, env=0, wire=0, all_z= layflag & SCE_LAY_ALL_Z;
-
+ short nofill=0, env=0, wire=0, zmaskpass=0;
+ short all_z= rl->layflag & SCE_LAY_ALL_Z;
+
samples= (R.osa? R.osa: 1);
samples= MIN2(4, samples-pa->sample);
@@ -1988,98 +2057,123 @@ void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag, void(*fillfu
zspan->zbuflinefunc= zbufline;
}
- for(i=0, obi=R.instancetable.first; obi; i++, obi=obi->next) {
- obr= obi->obr;
+ /* in case zmask we fill Z for objects in lay_zmask first, then clear Z, and then do normal zbuffering */
+ if(rl->layflag & SCE_LAY_ZMASK)
+ zmaskpass= 1;
+
+ for(; zmaskpass >=0; zmaskpass--) {
+ /* regular zbuffering loop, does all sample buffers */
+ for(i=0, obi=R.instancetable.first; obi; i++, obi=obi->next) {
+ obr= obi->obr;
- if(obi->flag & R_TRANSFORMED)
- zbuf_make_winmat(&R, obi->mat, winmat);
- else
- zbuf_make_winmat(&R, NULL, winmat);
+ /* continue happens in 2 different ways... zmaskpass only does lay_zmask stuff */
+ if(zmaskpass) {
+ if((obr->lay & lay_zmask)==0)
+ continue;
+ }
+ else {
+ if(!all_z && !(obr->lay & lay))
+ continue;
+ }
+
+ if(obi->flag & R_TRANSFORMED)
+ zbuf_make_winmat(&R, obi->mat, winmat);
+ else
+ zbuf_make_winmat(&R, NULL, winmat);
- zbuf_project_cache_clear(cache, obr->totvert);
+ zbuf_project_cache_clear(cache, obr->totvert);
- for(v=0; v<obr->totvlak; v++) {
- if((v & 255)==0) vlr= obr->vlaknodes[v>>8].vlak;
- else vlr++;
+ for(v=0; v<obr->totvlak; v++) {
+ if((v & 255)==0) vlr= obr->vlaknodes[v>>8].vlak;
+ else vlr++;
- /* three cases, visible for render, only z values and nothing */
- if(obr->lay & lay) {
- if(vlr->mat!=ma) {
- ma= vlr->mat;
- nofill= ma->mode & (MA_ZTRA|MA_ONLYCAST);
- env= (ma->mode & MA_ENV);
- wire= (ma->mode & MA_WIRE);
-
- for(zsample=0; zsample<samples; zsample++) {
- if(ma->mode & MA_ZINV) zspans[zsample].zbuffunc= zbuffillGLinv4;
- else zspans[zsample].zbuffunc= zbuffillGL4;
+ /* the cases: visible for render, only z values, zmask, nothing */
+ if(obr->lay & lay) {
+ if(vlr->mat!=ma) {
+ ma= vlr->mat;
+ nofill= ma->mode & (MA_ZTRA|MA_ONLYCAST);
+ env= (ma->mode & MA_ENV);
+ wire= (ma->mode & MA_WIRE);
+
+ for(zsample=0; zsample<samples; zsample++) {
+ if(ma->mode & MA_ZINV) zspans[zsample].zbuffunc= zbuffillGLinv4;
+ else zspans[zsample].zbuffunc= zbuffillGL4;
+ }
}
}
- }
- else if(all_z) {
- env= 1;
- nofill= 0;
- ma= NULL;
- }
- else {
- nofill= 1;
- ma= NULL; /* otherwise nofill can hang */
- }
-
- if(!(vlr->flag & R_HIDDEN) && nofill==0) {
- unsigned short partclip;
-
- v1= vlr->v1;
- v2= vlr->v2;
- v3= vlr->v3;
- v4= vlr->v4;
-
- c1= zbuf_part_project(cache, v1->index, winmat, bounds, v1->co, ho1);
- c2= zbuf_part_project(cache, v2->index, winmat, bounds, v2->co, ho2);
- c3= zbuf_part_project(cache, v3->index, winmat, bounds, v3->co, ho3);
-
- /* partclipping doesn't need viewplane clipping */
- partclip= c1 & c2 & c3;
- if(v4) {
- c4= zbuf_part_project(cache, v4->index, winmat, bounds, v4->co, ho4);
- partclip &= c4;
+ else if(all_z || (obr->lay & lay_zmask)) {
+ env= 1;
+ nofill= 0;
+ ma= NULL;
+ }
+ else {
+ nofill= 1;
+ ma= NULL; /* otherwise nofill can hang */
}
- if(partclip==0) {
+ if(!(vlr->flag & R_HIDDEN) && nofill==0) {
+ unsigned short partclip;
- if(env) zvlnr= -1;
- else zvlnr= v+1;
-
- c1= testclip(ho1);
- c2= testclip(ho2);
- c3= testclip(ho3);
- if(v4)
- c4= testclip(ho4);
-
- for(zsample=0; zsample<samples; zsample++) {
- zspan= &zspans[zsample];
-
- if(wire) {
- if(v4)
- zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, ho4, c1, c2, c3, c4);
- else
- zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, 0, c1, c2, c3, 0);
- }
- else {
- /* strands allow to be filled in as quad */
- if(v4 && (vlr->flag & R_STRAND)) {
- zbufclip4(zspan, i, zvlnr, ho1, ho2, ho3, ho4, c1, c2, c3, c4);
+ v1= vlr->v1;
+ v2= vlr->v2;
+ v3= vlr->v3;
+ v4= vlr->v4;
+
+ c1= zbuf_part_project(cache, v1->index, winmat, bounds, v1->co, ho1);
+ c2= zbuf_part_project(cache, v2->index, winmat, bounds, v2->co, ho2);
+ c3= zbuf_part_project(cache, v3->index, winmat, bounds, v3->co, ho3);
+
+ /* partclipping doesn't need viewplane clipping */
+ partclip= c1 & c2 & c3;
+ if(v4) {
+ c4= zbuf_part_project(cache, v4->index, winmat, bounds, v4->co, ho4);
+ partclip &= c4;
+ }
+
+ if(partclip==0) {
+
+ if(env) zvlnr= -1;
+ else zvlnr= v+1;
+
+ c1= testclip(ho1);
+ c2= testclip(ho2);
+ c3= testclip(ho3);
+ if(v4)
+ c4= testclip(ho4);
+
+ for(zsample=0; zsample<samples; zsample++) {
+ zspan= &zspans[zsample];
+
+ if(wire) {
+ if(v4)
+ zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, ho4, c1, c2, c3, c4);
+ else
+ zbufclipwire(zspan, i, zvlnr, vlr->ec, ho1, ho2, ho3, 0, c1, c2, c3, 0);
}
else {
- zbufclip(zspan, i, zvlnr, ho1, ho2, ho3, c1, c2, c3);
- if(v4)
- zbufclip(zspan, i, zvlnr+RE_QUAD_OFFS, ho1, ho3, ho4, c1, c3, c4);
+ /* strands allow to be filled in as quad */
+ if(v4 && (vlr->flag & R_STRAND)) {
+ zbufclip4(zspan, i, zvlnr, ho1, ho2, ho3, ho4, c1, c2, c3, c4);
+ }
+ else {
+ zbufclip(zspan, i, zvlnr, ho1, ho2, ho3, c1, c2, c3);
+ if(v4)
+ zbufclip(zspan, i, zvlnr+RE_QUAD_OFFS, ho1, ho3, ho4, c1, c3, c4);
+ }
}
}
}
}
}
}
+
+ /* clear all z to close value, so it works as mask for next passes (ztra+strand) */
+ if(zmaskpass) {
+ for(zsample=0; zsample<samples; zsample++) {
+ zspan= &zspans[zsample];
+ zmask_rect(zspan->rectz, zspan->rectp, pa->rectx, pa->recty);
+ }
+ }
}
for(zsample=0; zsample<samples; zsample++) {
@@ -2272,6 +2366,8 @@ void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int
if(obr->ob==re->excludeob)
continue;
+ else if(!(obr->lay & lay))
+ continue;
if(obi->flag & R_TRANSFORMED)
Mat4MulMat4(obwinmat, obi->mat, winmat);
@@ -2495,6 +2591,9 @@ void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(vo
for(i=0, obi=R.instancetable.first; obi; i++, obi=obi->next) {
obr= obi->obr;
+ if(!(obr->lay & lay))
+ continue;
+
if(obi->flag & R_TRANSFORMED)
zbuf_make_winmat(&R, obi->mat, winmat);
else
@@ -3196,6 +3295,9 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, un
for(i=0, obi=R.instancetable.first; obi; i++, obi=obi->next) {
obr= obi->obr;
+ if(!(obr->lay & lay))
+ continue;
+
if(obi->flag & R_TRANSFORMED)
zbuf_make_winmat(&R, obi->mat, winmat);
else
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index 7b87dd2108c..eb81c256289 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -604,13 +604,8 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
uiBlockBeginAlign(block);
uiBlockSetEmboss(block, UI_EMBOSS);
- if ((prev_proxylock) || (con->prev==NULL)) {
- /* don't draw 'button' behind arrow if disabled (and button doesn't do anything anyways) */
- uiBlockSetEmboss(block, UI_EMBOSSN);
- uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_UP, *xco+width-50, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint up in constraint stack");
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
- else {
+ /* only show buttons that will do anything valid */
+ if ((prev_proxylock==0) && (con->prev)) {
but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_UP, *xco+width-50, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint up in constraint stack");
uiButSetFunc(but, constraint_moveUp, ob, con);
}
@@ -619,12 +614,6 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_DOWN, *xco+width-50+18, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint down in constraint stack");
uiButSetFunc(but, constraint_moveDown, ob, con);
}
- else {
- /* don't draw 'button' behind arrow if no next constraint (it doesn't do anything anyways) */
- uiBlockSetEmboss(block, UI_EMBOSSN);
- uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_DOWN, *xco+width-50+18, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint down in constraint stack");
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
uiBlockEndAlign(block);
@@ -1441,6 +1430,54 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
draw_constraint_spaceselect(block, con, *xco, *yco-130, is_armature_owner(ob), -1);
}
break;
+ case CONSTRAINT_TYPE_DISTLIMIT:
+ {
+ bDistLimitConstraint *data = con->data;
+
+ height = 105;
+ uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
+
+ uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
+
+ /* Draw target parameters */
+ uiBlockBeginAlign(block);
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
+
+ if (is_armature_target(data->tar)) {
+ but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
+ uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
+ }
+ else if (is_geom_target(data->tar)) {
+ but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
+ uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
+ }
+ else {
+ strcpy(data->subtarget, "");
+ }
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ if (is_armature_target(data->tar)) {
+ uiDefButF(block, BUT, B_CONSTRAINT_TEST, "R", *xco, *yco-60, 20, 18, &data->dist, 0, 0, 0, 0, "Recalculate distance");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Distance:", *xco+18, *yco-60,139,18, &data->dist, 0.0, 100, 0.5, 0.5, "Radius of limiting sphere");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Head/Tail:", *xco+155, *yco-60,100,18, &con->headtail, 0.0, 1, 0.1, 0.1, "Target along length of bone: Head=0, Tail=1");
+ }
+ else {
+ uiDefButF(block, BUT, B_CONSTRAINT_TEST, "R", *xco, *yco-60, 20, 18, &data->dist, 0, 0, 0, 0, "Recalculate distance");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Distance:", *xco+18, *yco-60, 237, 18, &data->dist, 0.0, 100, 0.5, 0.5, "Radius of limiting sphere");
+ }
+
+ /* disabled soft-distance controls... currently it doesn't work yet. It was intended to be used for soft-ik (see xsi-blog for details) */
+#if 0
+ uiDefButBitS(block, TOG, LIMITDIST_USESOFT, B_CONSTRAINT_TEST, "Soft", *xco, *yco-82, 50, 18, &data->flag, 0, 24, 0, 0, "Enables soft-distance");
+ if (data->flag & LIMITDIST_USESOFT)
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Soft-Distance:", *xco+50, *yco-82, 187, 18, &data->soft, 0.0, 100, 0.5, 0.5, "Distance surrounding radius when transforms should get 'delayed'");
+#endif
+ uiBlockEndAlign(block);
+
+ uiDefButS(block, MENU, B_CONSTRAINT_TEST, "Limit Mode%t|Inside %x0|Outside %x1|Surface %x2", *xco+((width/2)-50), *yco-104, 100, 18, &data->mode, 0, 24, 0, 0, "Distances in relation to sphere of influence to allow");
+ }
+ break;
case CONSTRAINT_TYPE_RIGIDBODYJOINT:
{
bRigidBodyJointConstraint *data = con->data;
@@ -1750,6 +1787,7 @@ static uiBlock *add_constraintmenu(void *arg_unused)
uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCLIMIT, "Limit Location", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ROTLIMIT, "Limit Rotation", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
uiDefBut(block, BUTM, B_CONSTRAINT_ADD_SIZELIMIT, "Limit Scale", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, BUTM, B_CONSTRAINT_ADD_DISTLIMIT, "Limit Distance", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -1982,6 +2020,14 @@ void do_constraintbuts(unsigned short event)
BIF_undo_push("Add constraint");
}
break;
+ case B_CONSTRAINT_ADD_DISTLIMIT:
+ {
+ con = add_new_constraint(CONSTRAINT_TYPE_DISTLIMIT);
+ add_constraint_to_active(ob, con);
+
+ BIF_undo_push("Add constraint");
+ }
+ break;
default:
break;
@@ -3490,7 +3536,7 @@ static char sbsolvers[] = "Solver %t|RKP almost SOFT not usable but for some ger
/* SIF would have been candidate .. well lack of time .. brecht is busy .. better make a stable version for peach now :) */
static char sbsolvers[] = "SIF semi implicit euler with fixed step size (worth a try with real stiff egdes)%x3|SOFT step size controlled midpoint(1rst choice for real softbodies)%x0";
#else
-static char sbsolvers[] = "SOFT step size controlled midpoint(1rst choice for real softbodies)%x0";
+static char sbsolvers[] = "RKCP correct physics (harder to get stable but usefull for education :)%x1|SOFT step size controlled midpoint(1rst choice for real softbodies)%x0";
#endif
static void object_softbodies_collision(Object *ob)
@@ -3582,42 +3628,7 @@ static void object_softbodies_collision(Object *ob)
uiBlockEndAlign(block);
/*SOLVER SETTINGS*/
- uiBlockBeginAlign(block);
/* done in another panel now*/
- /*
- uiDefButS(block, MENU, B_SOFTBODY_CHANGE, sbsolvers,10,100,50,20, &sb->solver_ID, 14.0, 0.0, 0, 0, "Select Solver");
- sb->solver_ID = 0;
- switch (sb->solver_ID) {
- case 0:
- case 1:
- {adaptive_mode = 1; break;}
- case 3:
- {adaptive_mode = 0; break;}
- default: printf("SB_solver?\n"); // should never happen
-
- }
- if(adaptive_mode){
- uiDefButF(block, NUM, B_DIFF, "Error Lim:", 60,100,120,20, &sb->rklimit , 0.001, 10.0, 10, 0, "The Runge-Kutta ODE solver error limit, low value gives more precision, high values speed");
- uiDefButBitS(block, TOG, SBSO_OLDERR, B_DIFF,"O", 180,100,20,20, &sb->solverflags, 0, 0, 0, 0, "Old Error Calculation");
- uiDefButS(block, NUM, B_DIFF, "Fuzzy:", 200,100,90,20, &sb->fuzzyness, 1.00, 100.0, 10, 0, "Fuzzyness while on collision, high values make collsion handling faster but less stable");
- uiDefButBitS(block, TOG, SBSO_MONITOR, B_DIFF,"M", 290,100,20,20, &sb->solverflags, 0, 0, 0, 0, "Turn on SB diagnose console prints");
- uiBlockEndAlign(block);
- uiDefButS(block, NUM, B_DIFF, "MinS:", 10,80,100,20, &sb->minloops, 0.00, 30000.0, 10, 0, "Minimal # solver steps/frame ");
- uiDefButS(block, NUM, B_DIFF, "MaxS:", 110,80,100,20, &sb->maxloops, 0.00, 30000.0, 10, 0, "Maximal # solver steps/frame ");
- uiDefButS(block, NUM, B_DIFF, "Choke:", 210,80,100,20, &sb->choke, 0.00, 100.0, 10, 0, "'Viscosity' inside collision target ");
- }
- else{
- uiBlockEndAlign(block);
- uiBlockBeginAlign(block);
- uiDefButS(block, NUM, B_DIFF, "Fuzzy:", 210,100,90,20, &sb->fuzzyness, 1.00, 100.0, 10, 0, "Fuzzyness while on collision, high values make collsion handling faster but less stable");
- uiDefButBitS(block, TOG, SBSO_MONITOR, B_DIFF,"M", 290,100,20,20, &sb->solverflags, 0, 0, 0, 0, "Turn on SB diagnose console prints");
- uiBlockEndAlign(block);
- uiDefButS(block, NUM, B_DIFF, "Steps:", 10,80,100,20, &sb->minloops, 1.00, 30000.0, 10, 0, "Solver steps/frame ");
- uiDefButS(block, NUM, B_DIFF, "Choke:", 210,80,100,20, &sb->choke, 0.00, 100.0, 10, 0, "'Viscosity' inside collision target ");
- }
- */
-
-
}
/* OTHER OBJECTS COLLISION STUFF */
if (ob->type==OB_MESH){
@@ -3640,12 +3651,12 @@ static void object_softbodies_solver(Object *ob)
static int val;
short *softflag=&ob->softflag, psys_cur=0, adaptive_mode=0;
int ob_has_hair=psys_ob_has_hair(ob);
- if(!_can_softbodies_at_all(ob)) return;
+ if(!_can_softbodies_at_all(ob)) return;
block= uiNewBlock(&curarea->uiblocks, "object_softbodies_solver", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Soft Body Solver", "Physics", 651, 0, 318, 204)==0) return;
uiSetButLock(object_data_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
- /* doubt that is really needed here but for now */
+ /* doubt that is really needed here but for now */
if(ob_has_hair) {
if(PE_get_current_num(ob) >= 0) {
ParticleSystem *psys = PE_get_current(ob);
@@ -3680,11 +3691,10 @@ static void object_softbodies_solver(Object *ob)
/*SOLVER SETTINGS*/
uiBlockBeginAlign(block);
uiDefBut(block, LABEL, 0, "Solver select",10,200,300,20, NULL, 0.0, 0, 0, 0, "");
- uiDefButS(block, MENU, B_SOFTBODY_CHANGE, sbsolvers,10,180,300,20, &sb->solver_ID, 14.0, 0.0, 0, 0, "Select Solver (choose 1 of 1 i was working on some other but failed *sigh* BM) ");
+ uiDefButS(block, MENU, B_SOFTBODY_CHANGE, sbsolvers,10,180,300,20, &sb->solver_ID, 14.0, 0.0, 0, 0, "Select Solver");
uiBlockEndAlign(block);
-
+
/*some have adapive step size - some not*/
- sb->solver_ID = 0; /* ugly hack to prepare peach freeze */
switch (sb->solver_ID) {
case 0:
case 1:
@@ -3695,7 +3705,7 @@ static void object_softbodies_solver(Object *ob)
}
if(adaptive_mode){
uiBlockBeginAlign(block);
- uiDefBut(block, LABEL, 0, "Step size controls",10,160,300,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Step size controls",10,160,300,20, NULL, 0.0, 0, 0, 0, "");
uiDefButF(block, NUM, B_DIFF, "Error Lim:", 10,140,280,20, &sb->rklimit , 0.001, 10.0, 10, 0, "The Runge-Kutta ODE solver error limit, low value gives more precision, high values speed");
uiDefButBitS(block, TOG, SBSO_OLDERR, B_DIFF,"V", 290,140,20,20, &sb->solverflags, 0, 0, 0, 0, "Use velocities for automagic step sizes");
uiDefButS(block, NUM, B_DIFF, "MinS:", 10,120,150,20, &sb->minloops, 0.00, 30000.0, 10, 0, "Minimal # solver steps/frame ");
@@ -3703,11 +3713,11 @@ static void object_softbodies_solver(Object *ob)
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefBut(block, LABEL, 0, "Collision helpers",10,100,300,20, NULL, 0.0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Collision helpers",10,100,300,20, NULL, 0.0, 0, 0, 0, "");
uiDefButS(block, NUM, B_DIFF, "Choke:", 10,80,150,20, &sb->choke, 0.00, 100.0, 10, 0, "'Viscosity' inside collision target ");
uiDefButS(block, NUM, B_DIFF, "Fuzzy:", 160,80,150,20, &sb->fuzzyness, 1.00, 100.0, 10, 0, "Fuzzyness while on collision, high values make collsion handling faster but less stable");
uiBlockEndAlign(block);
-
+
uiBlockBeginAlign(block);
uiDefBut(block, LABEL, 0, "Diagnosis stuff",10,60,300,20, NULL, 0.0, 0, 0, 0, "");
uiDefButBitS(block, TOG, SBSO_MONITOR, B_DIFF,"Print Performance to Console", 10,40,300,20, &sb->solverflags, 0, 0, 0, 0, "Turn on SB diagnose console prints");
@@ -3723,10 +3733,9 @@ static void object_softbodies_solver(Object *ob)
uiDefButS(block, NUM, B_DIFF, "Choke:", 210,80,100,20, &sb->choke, 0.00, 100.0, 10, 0, "'Viscosity' inside collision target ");
}
- uiBlockEndAlign(block);
+ uiBlockEndAlign(block);
}
- //uiDefBut(block, LABEL, 0, "",10,10,1,2, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
}
uiBlockEndAlign(block);
}
@@ -3850,7 +3859,7 @@ static void object_softbodies(Object *ob)
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_DIFF, "Friction:", 10, 170,150,20, &sb->mediafrict, 0.0, 50.0, 10, 0, "General media friction for point movements");
uiDefButF(block, NUM, B_DIFF, "Mass:", 160, 170,150,20, &sb->nodemass , 0.001, 50000.0, 10, 0, str);
- uiDefButF(block, NUM, B_DIFF, "Grav:", 10,150,150,20, &sb->grav , 0.0, 10.0, 10, 0, "Apply gravitation to point movement");
+ uiDefButF(block, NUM, B_DIFF, "Grav:", 10,150,150,20, &sb->grav , -10.0, 10.0, 10, 0, "Apply gravitation to point movement");
uiDefButF(block, NUM, B_DIFF, "Speed:", 160,150,150,20, &sb->physics_speed , 0.01, 100.0, 10, 0, "Tweak timing for physics to control frequency and speed");
uiBlockEndAlign(block);
@@ -4110,7 +4119,7 @@ static void object_panel_particle_extra(Object *ob)
uiBlockBeginAlign(block);
- uiDefButS(block, MENU, B_PART_REDRAW, "Attribute%t|TanRot%x10|TanVel%x9|Size%x8|RoughE%x7|Rough2%x6|Rough1%x5|Kink%x4|Clump%x3|Length%x2|Velocity%x1|Density%x0", butx,(buty-=buth),butw-40,buth, &vgnum, 14.0, 0.0, 0, 0, "Attribute effected by vertex group");
+ uiDefButS(block, MENU, B_PART_REDRAW, "Attribute%t|Effector%x11|TanRot%x10|TanVel%x9|Size%x8|RoughE%x7|Rough2%x6|Rough1%x5|Kink%x4|Clump%x3|Length%x2|Velocity%x1|Density%x0", butx,(buty-=buth),butw-40,buth, &vgnum, 14.0, 0.0, 0, 0, "Attribute effected by vertex group");
but=uiDefButBitS(block, TOG, (1<<vgnum), B_PART_REDRAW, "Neg", butx+butw-40,buty,40,buth, &psys->vg_neg, 0, 0, 0, 0, "Negate the effect of the vertex group");
uiButSetFunc(but, particle_set_vg, (void *)ob, (void *)(&vgnum));
diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c
index 0dc6c485db5..d06028b09bc 100644
--- a/source/blender/src/buttons_scene.c
+++ b/source/blender/src/buttons_scene.c
@@ -2485,7 +2485,7 @@ static void layer_copy_func(void *lay_v, void *lay_p)
unsigned int *lay= lay_p;
int laybit= (int)lay_v;
- if(G.qual & LR_SHIFTKEY) {
+ if(G.qual & (LR_SHIFTKEY|LR_CTRLKEY)) {
if(*lay==0) *lay= 1<<laybit;
}
else
@@ -2556,29 +2556,29 @@ static char *scene_layer_menu(void)
return str;
}
-static void draw_3d_layer_buttons(uiBlock *block, unsigned int *poin, short xco, short yco, short dx, short dy)
+static void draw_3d_layer_buttons(uiBlock *block, int type, unsigned int *poin, short xco, short yco, short dx, short dy, char *tip)
{
uiBut *bt;
long a;
uiBlockBeginAlign(block);
for(a=0; a<5; a++) {
- bt= uiDefButBitI(block, TOG, 1<<a, B_NOP, "", (short)(xco+a*(dx/2)), yco+dy/2, (short)(dx/2), (short)(dy/2), (int *)poin, 0, 0, 0, 0, "");
+ bt= uiDefButBitI(block, type, 1<<a, B_NOP, "", (short)(xco+a*(dx/2)), yco+dy/2, (short)(dx/2), (short)(dy/2), (int *)poin, 0, 0, 0, 0, tip);
uiButSetFunc(bt, layer_copy_func, (void *)a, poin);
}
for(a=0; a<5; a++) {
- bt=uiDefButBitI(block, TOG, 1<<(a+10), B_NOP, "", (short)(xco+a*(dx/2)), yco, (short)(dx/2), (short)(dy/2), (int *)poin, 0, 0, 0, 0, "");
+ bt=uiDefButBitI(block, type, 1<<(a+10), B_NOP, "", (short)(xco+a*(dx/2)), yco, (short)(dx/2), (short)(dy/2), (int *)poin, 0, 0, 0, 0, tip);
uiButSetFunc(bt, layer_copy_func, (void *)(a+10), poin);
}
xco+= 7;
uiBlockBeginAlign(block);
for(a=5; a<10; a++) {
- bt=uiDefButBitI(block, TOG, 1<<a, B_NOP, "", (short)(xco+a*(dx/2)), yco+dy/2, (short)(dx/2), (short)(dy/2), (int *)poin, 0, 0, 0, 0, "");
+ bt=uiDefButBitI(block, type, 1<<a, B_NOP, "", (short)(xco+a*(dx/2)), yco+dy/2, (short)(dx/2), (short)(dy/2), (int *)poin, 0, 0, 0, 0, tip);
uiButSetFunc(bt, layer_copy_func, (void *)a, poin);
}
for(a=5; a<10; a++) {
- bt=uiDefButBitI(block, TOG, 1<<(a+10), B_NOP, "", (short)(xco+a*(dx/2)), yco, (short)(dx/2), (short)(dy/2), (int *)poin, 0, 0, 0, 0, "");
+ bt=uiDefButBitI(block, type, 1<<(a+10), B_NOP, "", (short)(xco+a*(dx/2)), yco, (short)(dx/2), (short)(dy/2), (int *)poin, 0, 0, 0, 0, tip);
uiButSetFunc(bt, layer_copy_func, (void *)(a+10), poin);
}
@@ -2603,7 +2603,7 @@ static void render_panel_layers(void)
/* first, as reminder, the scene layers */
uiDefBut(block, LABEL, 0, "Scene:", 10,170,100,20, NULL, 0, 0, 0, 0, "");
- draw_3d_layer_buttons(block, &G.scene->lay, 130, 170, 35, 30);
+ draw_3d_layer_buttons(block, TOG, &G.scene->lay, 130, 170, 35, 30, "Scene layers to render");
/* layer disable, menu, name, delete button */
uiBlockBeginAlign(block);
@@ -2623,10 +2623,11 @@ static void render_panel_layers(void)
/* RenderLayer visible-layers */
uiDefBut(block, LABEL, 0, "Layer:", 10,110,100,20, NULL, 0, 0, 0, 0, "");
- draw_3d_layer_buttons(block, &srl->lay, 130,110, 35, 30);
+ draw_3d_layer_buttons(block, BUT_TOGDUAL, &srl->lay, 130,110, 35, 30, "Scene-layers included in this render-layer (Hold CTRL for Z-mask)");
uiBlockBeginAlign(block);
- uiDefButBitI(block, TOG, SCE_LAY_ALL_Z, B_NOP,"AllZ", 10, 85, 40, 20, &srl->layflag, 0, 0, 0, 0, "Fill in Z values for all not-rendered faces, for masking");
+ uiDefButBitI(block, TOG, SCE_LAY_ALL_Z, B_NOP,"AllZ", 10, 85, 40, 20, &srl->layflag, 0, 0, 0, 0, "Fill in Z values for solid faces in invisible layers, for masking");
+ uiDefButBitI(block, TOG, SCE_LAY_ZMASK, B_NOP,"Zmask", 10, 65, 40, 20, &srl->layflag, 0, 0, 0, 0, "Only render what's in front of the solid z values");
uiBlockBeginAlign(block);
uiDefButBitI(block, TOG, SCE_LAY_SOLID, B_NOP,"Solid", 50, 85, 45, 20, &srl->layflag, 0, 0, 0, 0, "Render Solid faces in this Layer");
uiDefButBitI(block, TOG, SCE_LAY_HALO, B_NOP,"Halo", 95, 85, 40, 20, &srl->layflag, 0, 0, 0, 0, "Render Halos in this Layer (on top of Solid)");
@@ -2635,8 +2636,8 @@ static void render_panel_layers(void)
uiDefButBitI(block, TOG, SCE_LAY_EDGE, B_NOP,"Edge", 215, 85, 45, 20, &srl->layflag, 0, 0, 0, 0, "Render Edge-enhance in this Layer (only works for Solid faces)");
uiDefButBitI(block, TOG, SCE_LAY_STRAND, B_NOP,"Strand",260, 85, 50, 20, &srl->layflag, 0, 0, 0, 0, "Render Strands in this Layer");
- uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_SET_PASS, "Light:", 10, 65, 150, 20, &(srl->light_override), "Name of Group to use as Lamps instead");
- uiDefIDPoinBut(block, test_matpoin_but, ID_MA, B_SET_PASS, "Mat:", 160, 65, 150, 20, &(srl->mat_override), "Name of Material to use as Materials instead");
+ uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_SET_PASS, "Light:", 50, 65, 130, 20, &(srl->light_override), "Name of Group to use as Lamps instead");
+ uiDefIDPoinBut(block, test_matpoin_but, ID_MA, B_SET_PASS, "Mat:", 180, 65, 130, 20, &(srl->mat_override), "Name of Material to use as Materials instead");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c
index 2ac76942da7..be307a649b3 100644
--- a/source/blender/src/buttons_shading.c
+++ b/source/blender/src/buttons_shading.c
@@ -2283,8 +2283,8 @@ static void world_panel_world(World *wrld)
uiBlockBeginAlign(block);
uiBlockSetCol(block, TH_BUT_SETTING1);
- uiDefButF(block, NUMSLI,B_WORLDPRV, "Exp ", 160,30,145,19, &(wrld->exp), 0.0, 1.0, 0, 2, "Sets amount of exponential color correction for light");
- uiDefButF(block, NUMSLI,B_WORLDPRV, "Range ", 160,10,145,19, &(wrld->range), 0.2, 5.0, 0, 2, "Sets the color amount that will be mapped on color 1.0");
+ uiDefButF(block, NUMSLI,B_WORLDPRV2, "Exp ", 160,30,145,19, &(wrld->exp), 0.0, 1.0, 0, 2, "Sets amount of exponential color correction for light");
+ uiDefButF(block, NUMSLI,B_WORLDPRV2, "Range ", 160,10,145,19, &(wrld->range), 0.2, 5.0, 0, 2, "Sets the color amount that will be mapped on color 1.0");
}
@@ -2968,7 +2968,7 @@ void do_matbuts(unsigned short event)
allqueue(REDRAWBUTSSHADING, 0);
break;
case B_WORLDPRV2:
- BIF_preview_changed(ID_WO);
+ BIF_preview_changed(ID_TE);
allqueue(REDRAWBUTSSHADING, 0);
allqueue(REDRAWVIEW3D, 0);
break;
diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c
index a169af6cf93..3339385d565 100644
--- a/source/blender/src/drawaction.c
+++ b/source/blender/src/drawaction.c
@@ -813,19 +813,32 @@ static void draw_channel_strips(void)
if (NLA_ACTION_SCALED)
map_active_strip(di, OBACT, 0);
- /* draw keyframes */
+ /* Draw keyframes
+ * 1) Only channels that are visible in the Action Editor get drawn/evaluated.
+ * This is to try to optimise this for heavier data sets
+ * 2) Keyframes which are out of view horizontally could be disregarded (probably as
+ * option - 'drop-frames' or so). Todo...
+ */
y = 0.0;
for (ale= act_data.first; ale; ale= ale->next) {
- switch (ale->datatype) {
- case ALE_GROUP:
- draw_agroup_channel(di, ale->data, y);
- break;
- case ALE_IPO:
- draw_ipo_channel(di, ale->key_data, y);
- break;
- case ALE_ICU:
- draw_icu_channel(di, ale->key_data, y);
- break;
+ float yminc= y-CHANNELHEIGHT/2;
+ float ymaxc= y+CHANNELHEIGHT/2;
+
+ /* check if visible */
+ if ( IN_RANGE(yminc, G.v2d->cur.ymin, G.v2d->cur.ymax) ||
+ IN_RANGE(ymaxc, G.v2d->cur.ymin, G.v2d->cur.ymax) )
+ {
+ switch (ale->datatype) {
+ case ALE_GROUP:
+ draw_agroup_channel(di, ale->data, y);
+ break;
+ case ALE_IPO:
+ draw_ipo_channel(di, ale->key_data, y);
+ break;
+ case ALE_ICU:
+ draw_icu_channel(di, ale->key_data, y);
+ break;
+ }
}
y-=CHANNELHEIGHT+CHANNELSKIP;
diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c
index 6c9e6ce1f6f..1c091ed39d9 100644
--- a/source/blender/src/editaction.c
+++ b/source/blender/src/editaction.c
@@ -1160,6 +1160,7 @@ void duplicate_action_keys (void)
BLI_freelistN(&act_data);
/* now, go into transform-grab mode, to move keys */
+ BIF_TransformSetUndo("Add Duplicate");
transform_action_keys('g', 0);
}
diff --git a/source/blender/src/editconstraint.c b/source/blender/src/editconstraint.c
index ac5129dd021..ba73767387e 100644
--- a/source/blender/src/editconstraint.c
+++ b/source/blender/src/editconstraint.c
@@ -364,21 +364,21 @@ void add_constraint (short only_IK)
else {
if (pchanact) {
if (pchansel)
- nr= pupmenu("Add Constraint to Active Bone%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
+ nr= pupmenu("Add Constraint to Active Bone%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
else if ((obsel) && (obsel->type==OB_CURVE))
- nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|Stretch To%x7|%l|Action%x16|Script%x18");
+ nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|Stretch To%x7|%l|Action%x16|Script%x18");
else if (obsel)
- nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
+ nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
else
- nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
+ nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Action%x16|Script%x18");
}
else {
if ((obsel) && (obsel->type==OB_CURVE))
- nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|%l|Action%x16|Script%x18");
+ nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|%l|Action%x16|Script%x18");
else if (obsel)
- nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Action%x16|Script%x18");
+ nr= pupmenu("Add Constraint to Active Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Action%x16|Script%x18");
else
- nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Action%x16|Script%x18");
+ nr= pupmenu("Add Constraint to New Empty Object%t|Child Of%x19|Transformation%x20|%l|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Limit Distance%x21|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Action%x16|Script%x18");
}
}
@@ -475,6 +475,7 @@ void add_constraint (short only_IK)
}
}
else if (nr==20) con = add_new_constraint(CONSTRAINT_TYPE_TRANSFORM);
+ else if (nr==21) con = add_new_constraint(CONSTRAINT_TYPE_DISTLIMIT);
if (con==NULL) return; /* paranoia */
diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c
index 6fe2e032eed..b3ea3e1931c 100644
--- a/source/blender/src/editipo.c
+++ b/source/blender/src/editipo.c
@@ -2515,7 +2515,7 @@ static int match_adr_constraint(ID * id, int blocktype, char *actname, int adrco
case CONSTRAINT_TYPE_LOCKTRACK:
if (searchtype==2) foundmatch=1;
break;
- case CONSTRAINT_TYPE_DISTANCELIMIT:
+ case CONSTRAINT_TYPE_DISTLIMIT:
if (searchtype==1) foundmatch=1;
break;
case CONSTRAINT_TYPE_MINMAX:
diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c
index 1992ea8468a..9fc6f1896ea 100644
--- a/source/blender/src/editmesh_tools.c
+++ b/source/blender/src/editmesh_tools.c
@@ -51,6 +51,7 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
#include "DNA_mesh_types.h"
#include "DNA_material_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -1283,6 +1284,19 @@ static EditVert *subdivide_edge_addvert(EditEdge *edge, float rad, int beauty, f
/* offset for smooth or sphere or fractal */
alter_co(co, edge, rad, beauty, percent);
+ /* clip if needed by mirror modifier */
+ if (edge->v1->f2) {
+ if ( edge->v1->f2 & edge->v2->f2 & 1) {
+ co[0]= 0.0f;
+ }
+ if ( edge->v1->f2 & edge->v2->f2 & 2) {
+ co[1]= 0.0f;
+ }
+ if ( edge->v1->f2 & edge->v2->f2 & 4) {
+ co[2]= 0.0f;
+ }
+ }
+
ev = addvertlist(co, NULL);
/* vert data (vgroups, ..) */
@@ -2403,12 +2417,39 @@ void esubdivideflag(int flag, float rad, int beauty, int numcuts, int seltype)
EditMesh *em = G.editMesh;
EditFace *ef;
EditEdge *eed, *cedge, *sort[4];
- EditVert **templist;
+ EditVert *eve, **templist;
struct GHash *gh;
float length[4], v1mat[3], v2mat[3], v3mat[3], v4mat[3];
int i, j, edgecount, touchcount, facetype,hold;
+ ModifierData *md= G.obedit->modifiers.first;
if(multires_test()) return;
+
+ for (; md; md=md->next) {
+ if (md->type==eModifierType_Mirror) {
+ MirrorModifierData *mmd = (MirrorModifierData*) md;
+
+ if(mmd->flag & MOD_MIR_CLIPPING) {
+ for (eve= em->verts.first; eve; eve= eve->next) {
+ eve->f2= 0;
+ switch(mmd->axis){
+ case 0:
+ if (fabs(eve->co[0]) < mmd->tolerance)
+ eve->f2 |= 1;
+ break;
+ case 1:
+ if (fabs(eve->co[1]) < mmd->tolerance)
+ eve->f2 |= 2;
+ break;
+ case 2:
+ if (fabs(eve->co[2]) < mmd->tolerance)
+ eve->f2 |= 4;
+ break;
+ }
+ }
+ }
+ }
+ }
//Set faces f1 to 0 cause we need it later
for(ef=em->faces.first;ef;ef = ef->next) {
diff --git a/source/blender/src/editnode.c b/source/blender/src/editnode.c
index 645dc77c337..e42de1031e5 100644
--- a/source/blender/src/editnode.c
+++ b/source/blender/src/editnode.c
@@ -300,8 +300,12 @@ static void composit_node_event(SpaceNode *snode, short event)
/* not the best implementation of the world... but we need it to work now :) */
if(node->type==CMP_NODE_R_LAYERS && node->custom2) {
+ /* add event for this window (after render curarea can be changed) */
+ addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC);
+
composite_node_render(snode, node);
- /* new event, a render can go fullscreen and open new window */
+
+ /* add another event, a render can go fullscreen and open new window */
addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC);
}
else {
diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c
index cb1ed4c3e5a..a7b8400fb9d 100644
--- a/source/blender/src/editobject.c
+++ b/source/blender/src/editobject.c
@@ -5148,7 +5148,7 @@ void selectlinks_menu(void)
/* If you modify this menu, please remember to update view3d_select_linksmenu
* in header_view3d.c and the menu in toolbox.c
*/
- nr= pupmenu("Select Linked%t|Object Ipo%x1|ObData%x2|Material%x3|Texture%x4|DupliGroup%x5");
+ nr= pupmenu("Select Linked%t|Object Ipo%x1|ObData%x2|Material%x3|Texture%x4|DupliGroup%x5|ParticleSystem%x6");
if (nr <= 0) return;
@@ -5171,6 +5171,7 @@ void selectlinks(int nr)
* Current Material: 3
* Current Texture: 4
* DupliGroup: 5
+ * PSys: 6
*/
@@ -5196,6 +5197,9 @@ void selectlinks(int nr)
else if(nr==5) {
if(ob->dup_group==NULL) return;
}
+ else if(nr==6) {
+ if(ob->particlesystem.first==NULL) return;
+ }
else return;
base= FIRSTBASE;
@@ -5224,6 +5228,7 @@ void selectlinks(int nr)
if(tex==mat1->mtex[b]->tex) {
base->flag |= SELECT;
changed = 1;
+ break;
}
}
}
@@ -5236,6 +5241,25 @@ void selectlinks(int nr)
changed = 1;
}
}
+ else if(nr==6) {
+ /* loop through other, then actives particles*/
+ ParticleSystem *psys;
+ ParticleSystem *psys_act;
+
+ for(psys=base->object->particlesystem.first; psys; psys=psys->next) {
+ for(psys_act=ob->particlesystem.first; psys_act; psys_act=psys_act->next) {
+ if (psys->part == psys_act->part) {
+ base->flag |= SELECT;
+ changed = 1;
+ break;
+ }
+ }
+
+ if (base->flag & SELECT) {
+ break;
+ }
+ }
+ }
base->object->flag= base->flag;
}
base= base->next;
@@ -5580,17 +5604,9 @@ void mirrormenu(void)
if(G.f & G_PARTICLEEDIT) {
PE_mirror_x(0);
}
- else if (G.obedit==0) {
- mode=pupmenu("Mirror Axis %t|X Local%x4|Y Local%x5|Z Local%x6|");
-
- if (mode==-1) return; /* return */
- Mirror(mode); /* separating functionality from interface | call*/
- }
else {
- mode=pupmenu("Mirror Axis %t|X Global%x1|Y Global%x2|Z Global%x3|%l|X Local%x4|Y Local%x5|Z Local%x6|%l|X View%x7|Y View%x8|Z View%x9|");
-
- if (mode==-1) return; /* return */
- Mirror(mode); /* separating functionality from interface | call*/
+ initTransform(TFM_MIRROR, CTX_NO_PET);
+ Transform();
}
}
diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c
index 5d511b35633..a3bdbd0f7ab 100644
--- a/source/blender/src/editseq.c
+++ b/source/blender/src/editseq.c
@@ -788,7 +788,7 @@ void mouse_select_seq(void)
int hand,seldir;
TimeMarker *marker;
- marker=find_nearest_marker(0, 1);
+ marker=find_nearest_marker(SCE_MARKERS, 1);
if (marker) {
int oldflag;
diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c
index f7cf9dd22cd..4cbad8a9758 100644
--- a/source/blender/src/header_view3d.c
+++ b/source/blender/src/header_view3d.c
@@ -1881,10 +1881,24 @@ static uiBlock *view3d_transformmenu(void *arg_unused)
void do_view3d_object_mirrormenu(void *arg, int event)
{
switch(event) {
+ case 0:
+ initTransform(TFM_MIRROR, CTX_NO_PET);
+ Transform();
+ break;
case 1:
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setLocalAxisConstraint('X', " on X axis");
+ Transform();
+ break;
case 2:
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setLocalAxisConstraint('Y', " on Y axis");
+ Transform();
+ break;
case 3:
- Mirror(event + 3); /* + 3 because the first three modes are global*/
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setLocalAxisConstraint('Z', " on Z axis");
+ Transform();
break;
}
allqueue(REDRAWVIEW3D, 0);
@@ -1898,9 +1912,11 @@ static uiBlock *view3d_object_mirrormenu(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "view3d_object_mirrormenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
uiBlockSetButmFunc(block, do_view3d_object_mirrormenu, NULL);
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X Local|Ctrl M, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y Local|Ctrl M, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z Local|Ctrl M, 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Interactive Mirror|Ctrl M", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X Local|Ctrl M, X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y Local|Ctrl M, Y", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z Local|Ctrl M, Z", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 60);
@@ -2853,17 +2869,44 @@ static uiBlock *view3d_edit_mesh_normalsmenu(void *arg_unused)
void do_view3d_edit_mirrormenu(void *arg, int event)
{
+ float mat[3][3];
+
+ Mat3One(mat);
+
switch(event) {
+ case 0:
+ initTransform(TFM_MIRROR, CTX_NO_PET);
+ Transform();
+ break;
case 1:
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setSingleAxisConstraint(mat[0], " on global X axis");
+ Transform();
+ break;
case 2:
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setSingleAxisConstraint(mat[1], " on global Y axis");
+ Transform();
+ break;
case 3:
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setSingleAxisConstraint(mat[2], "on global Z axis");
+ Transform();
+ break;
case 4:
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setLocalAxisConstraint('X', " on local X axis");
+ Transform();
+ break;
case 5:
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setLocalAxisConstraint('Y', " on local Y axis");
+ Transform();
+ break;
case 6:
- case 7:
- case 8:
- case 9:
- Mirror(event);
+ initTransform(TFM_MIRROR, CTX_NO_PET|CTX_AUTOCONFIRM);
+ BIF_setLocalAxisConstraint('Z', " on local Z axis");
+ Transform();
break;
}
allqueue(REDRAWVIEW3D, 0);
@@ -2877,21 +2920,19 @@ static uiBlock *view3d_edit_mirrormenu(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "view3d_edit_mirrormenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
uiBlockSetButmFunc(block, do_view3d_edit_mirrormenu, NULL);
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X Global|Ctrl M, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y Global|Ctrl M, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z Global|Ctrl M, 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
-
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Interactive Mirror|Ctrl M", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
+
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X Local|Ctrl M, 4", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y Local|Ctrl M, 5", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z Local|Ctrl M, 6", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X Global|Ctrl M, X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y Global|Ctrl M, Y", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z Global|Ctrl M, Z", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X View|Ctrl M, 7", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y View|Ctrl M, 8", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z View|Ctrl M, 9", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "X Local|Ctrl M, X X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Y Local|Ctrl M, Y Y", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Z Local|Ctrl M, Z Z", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 60);
diff --git a/source/blender/src/outliner.c b/source/blender/src/outliner.c
index 63f39608f5d..c8ca48f64eb 100644
--- a/source/blender/src/outliner.c
+++ b/source/blender/src/outliner.c
@@ -2362,9 +2362,11 @@ void outliner_select(struct ScrArea *sa )
/* ************ SELECTION OPERATIONS ********* */
-static int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0; // globals, euh... you can do better
-
-static void set_operation_types(SpaceOops *soops, ListBase *lb)
+static void set_operation_types(SpaceOops *soops, ListBase *lb,
+ int *scenelevel,
+ int *objectlevel,
+ int *idlevel,
+ int *datalevel)
{
TreeElement *te;
TreeStoreElem *tselem;
@@ -2374,22 +2376,22 @@ static void set_operation_types(SpaceOops *soops, ListBase *lb)
if(tselem->flag & TSE_SELECTED) {
if(tselem->type) {
#ifdef WITH_VERSE
- if(te->idcode==ID_VS) datalevel= TSE_VERSE_SESSION;
- else if(te->idcode==ID_VN) datalevel= TSE_VERSE_OBJ_NODE;
- else if(datalevel==0) datalevel= tselem->type;
+ if(te->idcode==ID_VS) *datalevel= TSE_VERSE_SESSION;
+ else if(te->idcode==ID_VN) *datalevel= TSE_VERSE_OBJ_NODE;
+ else if(*datalevel==0) *datalevel= tselem->type;
#else
- if(datalevel==0) datalevel= tselem->type;
+ if(*datalevel==0) *datalevel= tselem->type;
#endif
- else if(datalevel!=tselem->type) datalevel= -1;
+ else if(*datalevel!=tselem->type) *datalevel= -1;
}
else {
int idcode= GS(tselem->id->name);
switch(idcode) {
case ID_SCE:
- scenelevel= 1;
+ *scenelevel= 1;
break;
case ID_OB:
- objectlevel= 1;
+ *objectlevel= 1;
break;
case ID_ME: case ID_CU: case ID_MB: case ID_LT:
@@ -2397,13 +2399,16 @@ static void set_operation_types(SpaceOops *soops, ListBase *lb)
case ID_MA: case ID_TE: case ID_IP: case ID_IM:
case ID_SO: case ID_KE: case ID_WO: case ID_AC:
case ID_NLA: case ID_TXT: case ID_GR:
- if(idlevel==0) idlevel= idcode;
- else if(idlevel!=idcode) idlevel= -1;
+ if(*idlevel==0) *idlevel= idcode;
+ else if(*idlevel!=idcode) *idlevel= -1;
break;
}
}
}
- if((tselem->flag & TSE_CLOSED)==0) set_operation_types(soops, &te->subtree);
+ if((tselem->flag & TSE_CLOSED)==0) {
+ set_operation_types(soops, &te->subtree,
+ scenelevel, objectlevel, idlevel, datalevel);
+ }
}
}
@@ -2559,6 +2564,30 @@ static void id_local_cb(TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *tse
}
}
+static void group_linkobs2scene_cb(TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *tselem)
+{
+ Group *group= (Group *)tselem->id;
+ GroupObject *gob;
+ Base *base;
+
+ for(gob=group->gobject.first; gob; gob=gob->next) {
+ base= object_in_scene(gob->ob, G.scene);
+ if (base) {
+ base->object->flag |= SELECT;
+ base->flag |= SELECT;
+ } else {
+
+ /* link to scene */
+ base= MEM_callocN( sizeof(Base), "add_base");
+ BLI_addhead(&G.scene->base, base);
+ base->lay= (1<<20)-1; /*G.vd->lay;*/ /* would be nice to use the 3d layer but the include's not here */
+ gob->ob->flag |= SELECT;
+ base->flag = gob->ob->flag;
+ base->object= gob->ob;
+ }
+ }
+}
+
static void outliner_do_object_operation(SpaceOops *soops, ListBase *lb,
void (*operation_cb)(TreeElement *, TreeStoreElem *, TreeStoreElem *))
{
@@ -2674,11 +2703,9 @@ void outliner_del(ScrArea *sa)
void outliner_operation_menu(ScrArea *sa)
{
SpaceOops *soops= sa->spacedata.first;
+ int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0;
- // bad globals
- scenelevel= objectlevel= idlevel= datalevel=0;
-
- set_operation_types(soops, &soops->tree);
+ set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
if(scenelevel) {
if(objectlevel || datalevel || idlevel) error("Mixed selection");
@@ -2719,7 +2746,12 @@ void outliner_operation_menu(ScrArea *sa)
else if(idlevel) {
if(idlevel==-1 || datalevel) error("Mixed selection");
else {
- short event= pupmenu("Unlink %x1|Make Local %x2");
+ short event;
+ if (idlevel==ID_GR)
+ event = pupmenu("Unlink %x1|Make Local %x2|Link Group Objects to Scene%x3");
+ else
+ event = pupmenu("Unlink %x1|Make Local %x2");
+
if(event==1) {
switch(idlevel) {
@@ -2747,6 +2779,10 @@ void outliner_operation_menu(ScrArea *sa)
BIF_undo_push("Localized Data");
allqueue(REDRAWALL, 0);
}
+ else if(event==3 && idlevel==ID_GR) {
+ outliner_do_libdata_operation(soops, &soops->tree, group_linkobs2scene_cb);
+ BIF_undo_push("Link Group Objects to Scene");
+ }
}
}
else if(datalevel) {
diff --git a/source/blender/src/previewrender.c b/source/blender/src/previewrender.c
index 2f7b4754d76..383b73b7619 100644
--- a/source/blender/src/previewrender.c
+++ b/source/blender/src/previewrender.c
@@ -270,6 +270,11 @@ static Scene *preview_prepare_scene(RenderInfo *ri, int id_type, ID *id, int pr_
sce->r.scemode |= R_PREVIEWBUTS;
/* set world always back, is used now */
sce->world= pr_main->world.first;
+ /* now: exposure copy */
+ if(G.scene->world) {
+ sce->world->exp= G.scene->world->exp;
+ sce->world->range= G.scene->world->range;
+ }
sce->r.cfra= G.scene->r.cfra;
diff --git a/source/blender/src/sculptmode-stroke.c b/source/blender/src/sculptmode-stroke.c
index c2c96b04a1d..69c20eeeddf 100644
--- a/source/blender/src/sculptmode-stroke.c
+++ b/source/blender/src/sculptmode-stroke.c
@@ -178,7 +178,7 @@ float sculpt_stroke_final_length(SculptStroke *stroke)
}
/* If partial is nonzero, cuts off apply after that length has been processed */
-static StrokePoint *sculpt_stroke_apply_generic(SculptStroke *stroke, struct EditData *e, const int partial)
+static StrokePoint *sculpt_stroke_apply_generic(SculptStroke *stroke, struct BrushAction *a, const int partial)
{
const int sdspace = sculpt_data()->spacing;
const short spacing = sdspace > 0 ? sdspace : 2;
@@ -215,13 +215,13 @@ static StrokePoint *sculpt_stroke_apply_generic(SculptStroke *stroke, struct Edi
co[0] = p->x*v + p->next->x*u;
co[1] = p->y*v + p->next->y*u;
- do_symmetrical_brush_actions(e, co, NULL);
+ do_symmetrical_brush_actions(a, co, NULL);
}
return p ? p->next : NULL;
}
-void sculpt_stroke_apply(struct EditData *e)
+void sculpt_stroke_apply(struct BrushAction *a)
{
SculptStroke *stroke = sculpt_session()->stroke;
/* TODO: make these values user-modifiable? */
@@ -232,7 +232,7 @@ void sculpt_stroke_apply(struct EditData *e)
sculpt_stroke_create_final();
if(sculpt_stroke_final_length(stroke) > min_len) {
- StrokePoint *p = sculpt_stroke_apply_generic(stroke, e, partial_len);
+ StrokePoint *p = sculpt_stroke_apply_generic(stroke, a, partial_len);
/* Replace remaining values in stroke->loc with remaining stroke->final values */
stroke->index = -1;
@@ -249,14 +249,14 @@ void sculpt_stroke_apply(struct EditData *e)
}
}
-void sculpt_stroke_apply_all(struct EditData *e)
+void sculpt_stroke_apply_all(struct BrushAction *a)
{
SculptStroke *stroke = sculpt_session()->stroke;
sculpt_stroke_create_final();
if(stroke) {
- sculpt_stroke_apply_generic(stroke, e, 0);
+ sculpt_stroke_apply_generic(stroke, a, 0);
}
}
diff --git a/source/blender/src/sculptmode.c b/source/blender/src/sculptmode.c
index 9e1fa16a44c..dbefadb2646 100644
--- a/source/blender/src/sculptmode.c
+++ b/source/blender/src/sculptmode.c
@@ -125,36 +125,39 @@ typedef struct ActiveData {
float dist;
} ActiveData;
-typedef struct GrabData {
- char firsttime;
- ListBase active_verts[8];
- unsigned char index;
- vec3f delta, delta_symm;
- float depth;
-} GrabData;
+typedef struct BrushActionSymm {
+ float center_3d[3];
+ char index;
-typedef struct EditData {
- vec3f center;
- float size;
- char flip;
- short mouse[2];
+ float up[3], right[3], out[3];
- /* Adjust brush strength along each axis
- to adjust for object scaling */
- float scale[3];
+ // Grab brush
+ float grab_delta[3];
+} BrushActionSymm;
- /* View normals */
- vec3f up, right, out;
+typedef struct BrushAction {
+ BrushActionSymm symm;
+
+ char firsttime;
+
+ short mouse[2];
+ float size_3d;
- GrabData *grabdata;
float *layer_disps;
vec3f *layer_store;
-
+ char flip;
+
char clip[3];
float cliptol[3];
-
- char symm;
-} EditData;
+
+ // Grab brush
+ ListBase grab_active_verts[8];
+ float depth;
+
+ /* Adjust brush strength along each axis
+ to adjust for object scaling */
+ float scale[3];
+} BrushAction;
typedef struct RectNode {
struct RectNode *next, *prev;
@@ -178,7 +181,7 @@ SculptData *sculpt_data(void)
}
void sculpt_init_session(void);
-void init_editdata(EditData *e, short *, short *);
+void init_brushaction(BrushAction *a, short *, short *);
void sculpt_undo_push(const short);
SculptSession *sculpt_session(void)
@@ -294,18 +297,16 @@ float get_depth(short x, short y)
/* Uses window coordinates (x,y) and depth component z to find a point in
modelspace */
-vec3f unproject(const short x, const short y, const float z)
+void unproject(float out[3], const short x, const short y, const float z)
{
SculptSession *ss= sculpt_session();
double ux, uy, uz;
- vec3f p;
gluUnProject(x,y,z, ss->mats->modelview, ss->mats->projection,
(GLint *)ss->mats->viewport, &ux, &uy, &uz );
- p.x= ux;
- p.y= uy;
- p.z= uz;
- return p;
+ out[0] = ux;
+ out[1] = uy;
+ out[2] = uz;
}
/* Convert a point in model coordinates to 2D screen coordinates. */
@@ -348,13 +349,13 @@ char brush_size()
/* Return modified brush strength. Includes the direction of the brush, positive
values pull vertices, negative values push. Uses tablet pressure and a
special multiplier found experimentally to scale the strength factor. */
-float brush_strength(EditData *e)
+float brush_strength(BrushAction *a)
{
const BrushData* b= sculptmode_brush();
float dir= b->dir==1 ? 1 : -1;
float pressure= 1;
short activedevice= get_activedevice();
- float flip= e->flip ? -1:1;
+ float flip= a->flip ? -1:1;
const float strength_factor= G.scene->sculptdata.tablet_strength / 10.0f;
if(ELEM(activedevice, DEV_STYLUS, DEV_ERASER))
@@ -385,11 +386,11 @@ float brush_strength(EditData *e)
}
/* For clipping against a mirror modifier */
-void sculpt_clip(const EditData *e, float *co, const float val[3])
+void sculpt_clip(const BrushAction *a, float *co, const float val[3])
{
char i;
for(i=0; i<3; ++i) {
- if(e->clip[i] && (fabs(co[i]) <= e->cliptol[i]))
+ if(a->clip[i] && (fabs(co[i]) <= a->cliptol[i]))
co[i]= 0.0f;
else
co[i]= val[i];
@@ -398,7 +399,7 @@ void sculpt_clip(const EditData *e, float *co, const float val[3])
/* Currently only for the draw brush; finds average normal for all active
vertices */
-vec3f calc_area_normal(const vec3f *outdir, const ListBase* active_verts)
+vec3f calc_area_normal(const float *outdir, const ListBase* active_verts)
{
Mesh *me= get_mesh(OBACT);
vec3f area_normal= {0,0,0};
@@ -412,28 +413,30 @@ vec3f calc_area_normal(const vec3f *outdir, const ListBase* active_verts)
node= node->next;
}
Normalize(&area_normal.x);
+
if(outdir) {
- area_normal.x= outdir->x * view + area_normal.x * (10-view);
- area_normal.y= outdir->y * view + area_normal.y * (10-view);
- area_normal.z= outdir->z * view + area_normal.z * (10-view);
+ area_normal.x= outdir[0] * view + area_normal.x * (10-view);
+ area_normal.y= outdir[1] * view + area_normal.y * (10-view);
+ area_normal.z= outdir[2] * view + area_normal.z * (10-view);
}
+
Normalize(&area_normal.x);
return area_normal;
}
-void do_draw_brush(const EditData *e, const ListBase* active_verts)
+void do_draw_brush(const BrushAction *a, const ListBase* active_verts)
{
Mesh *me= get_mesh(OBACT);
- const vec3f area_normal= calc_area_normal(&e->out, active_verts);
+ const vec3f area_normal= calc_area_normal(a->symm.out, active_verts);
ActiveData *node= active_verts->first;
while(node){
float *co= me->mvert[node->Index].co;
- const float val[3]= {co[0]+area_normal.x*node->Fade*e->scale[0],
- co[1]+area_normal.y*node->Fade*e->scale[1],
- co[2]+area_normal.z*node->Fade*e->scale[2]};
+ const float val[3]= {co[0]+area_normal.x*node->Fade*a->scale[0],
+ co[1]+area_normal.y*node->Fade*a->scale[1],
+ co[2]+area_normal.z*node->Fade*a->scale[2]};
- sculpt_clip(e, co, val);
+ sculpt_clip(a, co, val);
node= node->next;
}
@@ -489,7 +492,7 @@ vec3f neighbor_average(const int vert)
return avg;
}
-void do_smooth_brush(const EditData *e, const ListBase* active_verts)
+void do_smooth_brush(const BrushAction *a, const ListBase* active_verts)
{
ActiveData *node= active_verts->first;
Mesh *me= get_mesh(OBACT);
@@ -500,53 +503,53 @@ void do_smooth_brush(const EditData *e, const ListBase* active_verts)
const float val[3]= {co[0]+(avg.x-co[0])*node->Fade,
co[1]+(avg.y-co[1])*node->Fade,
co[2]+(avg.z-co[2])*node->Fade};
- sculpt_clip(e, co, val);
+ sculpt_clip(a, co, val);
node= node->next;
}
}
-void do_pinch_brush(const EditData *e, const ListBase* active_verts)
+void do_pinch_brush(const BrushAction *a, const ListBase* active_verts)
{
Mesh *me= get_mesh(OBACT);
ActiveData *node= active_verts->first;
while(node) {
float *co= me->mvert[node->Index].co;
- const float val[3]= {co[0]+(e->center.x-co[0])*node->Fade,
- co[1]+(e->center.y-co[1])*node->Fade,
- co[2]+(e->center.z-co[2])*node->Fade};
- sculpt_clip(e, co, val);
+ const float val[3]= {co[0]+(a->symm.center_3d[0]-co[0])*node->Fade,
+ co[1]+(a->symm.center_3d[1]-co[1])*node->Fade,
+ co[2]+(a->symm.center_3d[2]-co[2])*node->Fade};
+ sculpt_clip(a, co, val);
node= node->next;
}
}
-void do_grab_brush(EditData *e)
+void do_grab_brush(BrushAction *a)
{
Mesh *me= get_mesh(OBACT);
- ActiveData *node= e->grabdata->active_verts[e->grabdata->index].first;
+ ActiveData *node= a->grab_active_verts[a->symm.index].first;
float add[3];
while(node) {
float *co= me->mvert[node->Index].co;
- VecCopyf(add, &e->grabdata->delta_symm.x);
+ VecCopyf(add, a->symm.grab_delta);
VecMulf(add, node->Fade);
VecAddf(add, add, co);
- sculpt_clip(e, co, add);
+ sculpt_clip(a, co, add);
node= node->next;
}
}
-void do_layer_brush(EditData *e, const ListBase *active_verts)
+void do_layer_brush(BrushAction *a, const ListBase *active_verts)
{
Mesh *me= get_mesh(OBACT);
vec3f area_normal= calc_area_normal(NULL, active_verts);
ActiveData *node= active_verts->first;
- const float bstr= brush_strength(e);
+ const float bstr= brush_strength(a);
while(node){
- float *disp= &e->layer_disps[node->Index];
+ float *disp= &a->layer_disps[node->Index];
if((bstr > 0 && *disp < bstr) ||
(bstr < 0 && *disp > bstr)) {
@@ -563,10 +566,10 @@ void do_layer_brush(EditData *e, const ListBase *active_verts)
}
{
- const float val[3]= {e->layer_store[node->Index].x+area_normal.x * *disp*e->scale[0],
- e->layer_store[node->Index].y+area_normal.y * *disp*e->scale[1],
- e->layer_store[node->Index].z+area_normal.z * *disp*e->scale[2]};
- sculpt_clip(e, co, val);
+ const float val[3]= {a->layer_store[node->Index].x+area_normal.x * *disp*a->scale[0],
+ a->layer_store[node->Index].y+area_normal.y * *disp*a->scale[1],
+ a->layer_store[node->Index].z+area_normal.z * *disp*a->scale[2]};
+ sculpt_clip(a, co, val);
}
}
@@ -574,7 +577,7 @@ void do_layer_brush(EditData *e, const ListBase *active_verts)
}
}
-void do_inflate_brush(const EditData *e, const ListBase *active_verts)
+void do_inflate_brush(const BrushAction *a, const ListBase *active_verts)
{
ActiveData *node= active_verts->first;
float add[3];
@@ -588,18 +591,18 @@ void do_inflate_brush(const EditData *e, const ListBase *active_verts)
add[1]= no[1]/ 32767.0f;
add[2]= no[2]/ 32767.0f;
VecMulf(add, node->Fade);
- add[0]*= e->scale[0];
- add[1]*= e->scale[1];
- add[2]*= e->scale[2];
+ add[0]*= a->scale[0];
+ add[1]*= a->scale[1];
+ add[2]*= a->scale[2];
VecAddf(add, add, co);
- sculpt_clip(e, co, add);
+ sculpt_clip(a, co, add);
node= node->next;
}
}
-void calc_flatten_center(Mesh *me, ActiveData *node, const EditData *e, float co[3])
+void calc_flatten_center(Mesh *me, ActiveData *node, float co[3])
{
ActiveData *outer[FLATTEN_SAMPLE_SIZE];
int i;
@@ -622,15 +625,15 @@ void calc_flatten_center(Mesh *me, ActiveData *node, const EditData *e, float co
VecMulf(co, 1.0f / FLATTEN_SAMPLE_SIZE);
}
-void do_flatten_brush(const EditData *e, const ListBase *active_verts)
+void do_flatten_brush(const BrushAction *a, const ListBase *active_verts)
{
Mesh *me= get_mesh(OBACT);
ActiveData *node= active_verts->first;
/* area_normal and cntr define the plane towards which vertices are squashed */
- vec3f area_normal= calc_area_normal(&e->out, active_verts);
+ vec3f area_normal= calc_area_normal(a->symm.out, active_verts);
float cntr[3];
- calc_flatten_center(me, node, e, cntr);
+ calc_flatten_center(me, node, cntr);
while(node){
float *co= me->mvert[node->Index].co;
@@ -648,7 +651,7 @@ void do_flatten_brush(const EditData *e, const ListBase *active_verts)
VecMulf(val, node->Fade);
VecAddf(val, val, co);
- sculpt_clip(e, co, val);
+ sculpt_clip(a, co, val);
node= node->next;
}
@@ -709,7 +712,7 @@ unsigned *get_texcache_pixel(const SculptSession *ss, int px, int py)
}
/* Return a multiplier for brush strength on a particular vertex. */
-float tex_strength(EditData *e, float *point, const float len,const unsigned vindex)
+float tex_strength(BrushAction *a, float *point, const float len,const unsigned vindex)
{
SculptData *sd= sculpt_data();
SculptSession *ss= sculpt_session();
@@ -747,12 +750,12 @@ float tex_strength(EditData *e, float *point, const float len,const unsigned vin
/* If the active area is being applied for symmetry, flip it
across the symmetry axis in order to project it. This insures
that the brush texture will be oriented correctly. */
- if(!e->symm)
+ if(!a->symm.index)
pv= ss->projverts[vindex];
else {
float co[3];
VecCopyf(co, point);
- flip_coord(co, e->symm);
+ flip_coord(co, a->symm.index);
project(co, pv.co);
}
@@ -781,15 +784,15 @@ float tex_strength(EditData *e, float *point, const float len,const unsigned vin
py %= sy-1;
p= get_texcache_pixel(ss, tcw*px/sx, tch*py/sy);
} else {
- float fx= (pv.co[0] - e->mouse[0] + half) * (tcw*1.0f/bsize) - tcw/2;
- float fy= (pv.co[1] - e->mouse[1] + half) * (tch*1.0f/bsize) - tch/2;
-
+ float fx= (pv.co[0] - a->mouse[0] + half) * (tcw*1.0f/bsize) - tcw/2;
+ float fy= (pv.co[1] - a->mouse[1] + half) * (tch*1.0f/bsize) - tch/2;
+
float angle= atan2(fy, fx) - rot;
float len= sqrtf(fx*fx + fy*fy);
px= tcw/2 + len * cos(angle);
py= tch/2 + len * sin(angle);
-
+
p= get_texcache_pixel(ss, px, py);
}
@@ -801,7 +804,7 @@ float tex_strength(EditData *e, float *point, const float len,const unsigned vin
}
if(sd->texfade)
- avg*= curve_strength(len,e->size); /* Smooth curve */
+ avg*= curve_strength(len, a->size_3d); /* Smooth curve */
return avg;
}
@@ -809,7 +812,7 @@ float tex_strength(EditData *e, float *point, const float len,const unsigned vin
/* Mark area around the brush as damaged. projverts are marked if they are
inside the area and the damaged rectangle in 2D screen coordinates is
added to damaged_rects. */
-void sculpt_add_damaged_rect(EditData *e)
+void sculpt_add_damaged_rect(BrushAction *a)
{
short p[2];
const float radius= brush_size();
@@ -819,7 +822,7 @@ void sculpt_add_damaged_rect(EditData *e)
unsigned i;
/* Find center */
- project(&e->center.x, p);
+ project(a->symm.center_3d, p);
rn->r.xmin= p[0]-radius;
rn->r.ymin= p[1]-radius;
rn->r.xmax= p[0]+radius;
@@ -868,7 +871,7 @@ void sculpt_clear_damaged_areas(SculptSession *ss)
}
}
-void do_brush_action(EditData e)
+void do_brush_action(BrushAction *a)
{
int i;
float av_dist;
@@ -876,29 +879,32 @@ void do_brush_action(EditData e)
ActiveData *adata= 0;
float *vert;
Mesh *me= get_mesh(OBACT);
- const float bstrength= brush_strength(&e);
+ const float bstrength= brush_strength(a);
KeyBlock *keyblock= ob_get_keyblock(OBACT);
+ SculptData *sd = sculpt_data();
SculptSession *ss = sculpt_session();
- sculpt_add_damaged_rect(&e);
+ sculpt_add_damaged_rect(a);
/* Build a list of all vertices that are potentially within the brush's
area of influence. Only do this once for the grab brush. */
- if(!e.grabdata || (e.grabdata && e.grabdata->firsttime)) {
+ if((sd->brush_type != GRAB_BRUSH) || a->firsttime) {
for(i=0; i<me->totvert; ++i) {
/* Projverts.inside provides a rough bounding box */
if(ss->projverts[i].inside) {
vert= ss->vertexcosnos ? &ss->vertexcosnos[i*6] : me->mvert[i].co;
- av_dist= VecLenf(&e.center.x,vert);
- if(av_dist < e.size) {
+ av_dist= VecLenf(a->symm.center_3d, vert);
+ if(av_dist < a->size_3d) {
adata= (ActiveData*)MEM_mallocN(sizeof(ActiveData), "ActiveData");
+
adata->Index = i;
/* Fade is used to store the final strength at which the brush
should modify a particular vertex. */
- adata->Fade= tex_strength(&e,vert,av_dist,i) * bstrength;
+ adata->Fade= tex_strength(a, vert, av_dist, i) * bstrength;
adata->dist = av_dist;
- if(e.grabdata && e.grabdata->firsttime)
- BLI_addtail(&e.grabdata->active_verts[e.grabdata->index], adata);
+
+ if(sd->brush_type == GRAB_BRUSH && a->firsttime)
+ BLI_addtail(&a->grab_active_verts[a->symm.index], adata);
else
BLI_addtail(&active_verts, adata);
}
@@ -907,29 +913,29 @@ void do_brush_action(EditData e)
}
/* Only act if some verts are inside the brush area */
- if(active_verts.first || (e.grabdata && e.grabdata->active_verts[e.grabdata->index].first)) {
+ if(active_verts.first || (sd->brush_type == GRAB_BRUSH && a->grab_active_verts[a->symm.index].first)) {
/* Apply one type of brush action */
switch(G.scene->sculptdata.brush_type){
case DRAW_BRUSH:
- do_draw_brush(&e, &active_verts);
+ do_draw_brush(a, &active_verts);
break;
case SMOOTH_BRUSH:
- do_smooth_brush(&e, &active_verts);
+ do_smooth_brush(a, &active_verts);
break;
case PINCH_BRUSH:
- do_pinch_brush(&e, &active_verts);
+ do_pinch_brush(a, &active_verts);
break;
case INFLATE_BRUSH:
- do_inflate_brush(&e, &active_verts);
+ do_inflate_brush(a, &active_verts);
break;
case GRAB_BRUSH:
- do_grab_brush(&e);
+ do_grab_brush(a);
break;
case LAYER_BRUSH:
- do_layer_brush(&e, &active_verts);
+ do_layer_brush(a, &active_verts);
break;
case FLATTEN_BRUSH:
- do_flatten_brush(&e, &active_verts);
+ do_flatten_brush(a, &active_verts);
break;
}
@@ -937,7 +943,11 @@ void do_brush_action(EditData e)
if(keyblock) {
float *co= keyblock->data;
if(co) {
- adata = e.grabdata ? e.grabdata->active_verts[e.grabdata->index].first : active_verts.first;
+ if(sd->brush_type == GRAB_BRUSH)
+ adata = a->grab_active_verts[a->symm.index].first;
+ else
+ adata = active_verts.first;
+
for(; adata; adata= adata->next)
if(adata->Index < keyblock->totelem)
VecCopyf(&co[adata->Index*3], me->mvert[adata->Index].co);
@@ -947,7 +957,7 @@ void do_brush_action(EditData e)
if(ss->vertexcosnos)
BLI_freelistN(&active_verts);
else {
- if(!e.grabdata)
+ if(sd->brush_type != GRAB_BRUSH)
addlisttolist(&ss->damaged_verts, &active_verts);
}
}
@@ -955,51 +965,37 @@ void do_brush_action(EditData e)
/* Flip all the editdata across the axis/axes specified by symm. Used to
calculate multiple modifications to the mesh when symmetry is enabled. */
-EditData flip_editdata(EditData *e, const char symm)
+void calc_brushdata_symm(BrushAction *a, const char symm)
{
- EditData fe= *e;
- GrabData *gd= fe.grabdata;
-
- flip_coord(&fe.center.x, symm);
- flip_coord(&fe.up.x, symm);
- flip_coord(&fe.right.x, symm);
- flip_coord(&fe.out.x, symm);
+ flip_coord(a->symm.center_3d, symm);
+ flip_coord(a->symm.up, symm);
+ flip_coord(a->symm.right, symm);
+ flip_coord(a->symm.out, symm);
- fe.symm= symm;
-
- project(&e->center.x,fe.mouse);
-
- if(gd) {
- gd->index= symm;
- gd->delta_symm= gd->delta;
- flip_coord(&gd->delta_symm.x, symm);
- }
+ a->symm.index= symm;
- return fe;
+ flip_coord(a->symm.grab_delta, symm);
}
-void do_symmetrical_brush_actions(EditData * e, short co[2], short pr_co[2])
+void do_symmetrical_brush_actions(BrushAction *a, short co[2], short pr_co[2])
{
- const char symm= sculpt_data()->symm;
+ const char symm = sculpt_data()->symm;
+ BrushActionSymm orig;
+ int i;
- init_editdata(e, co, pr_co);
-
- do_brush_action(flip_editdata(e, 0));
+ init_brushaction(a, co, pr_co);
+ orig = a->symm;
+ do_brush_action(a);
- if(symm & SYMM_X)
- do_brush_action(flip_editdata(e, SYMM_X));
- if(symm & SYMM_Y)
- do_brush_action(flip_editdata(e, SYMM_Y));
- if(symm & SYMM_Z)
- do_brush_action(flip_editdata(e, SYMM_Z));
- if(symm & SYMM_X && symm & SYMM_Y)
- do_brush_action(flip_editdata(e, SYMM_X | SYMM_Y));
- if(symm & SYMM_X && symm & SYMM_Z)
- do_brush_action(flip_editdata(e, SYMM_X | SYMM_Z));
- if(symm & SYMM_Y && symm & SYMM_Z)
- do_brush_action(flip_editdata(e, SYMM_Y | SYMM_Z));
- if(symm & SYMM_X && symm & SYMM_Y && symm & SYMM_Z)
- do_brush_action(flip_editdata(e, SYMM_X | SYMM_Y | SYMM_Z));
+ for(i = 1; i <= symm; ++i) {
+ if(symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5))) {
+ // Restore the original symmetry data
+ a->symm = orig;
+
+ calc_brushdata_symm(a, i);
+ do_brush_action(a);
+ }
+ }
}
void add_face_normal(vec3f *norm, const MFace* face)
@@ -1039,19 +1035,17 @@ void update_damaged_vert(Mesh *me, ListBase *lb)
}
}
-void calc_damaged_verts(ListBase *damaged_verts, GrabData *grabdata)
+void calc_damaged_verts(ListBase *damaged_verts, BrushAction *a)
{
Mesh *me= get_mesh(OBACT);
+ int i;
+
+ for(i=0; i<8; ++i)
+ update_damaged_vert(me, &a->grab_active_verts[i]);
- if(grabdata) {
- int i;
- for(i=0; i<8; ++i)
- update_damaged_vert(me,&grabdata->active_verts[i]);
- } else {
- update_damaged_vert(me,damaged_verts);
- BLI_freelistN(damaged_verts);
- damaged_verts->first = damaged_verts->last = NULL;
- }
+ update_damaged_vert(me, damaged_verts);
+ BLI_freelistN(damaged_verts);
+ damaged_verts->first = damaged_verts->last = NULL;
}
void projverts_clear_inside(SculptSession *ss)
@@ -1137,83 +1131,80 @@ void sculptmode_update_tex()
}
/* pr_mouse is only used for the grab brush, can be NULL otherwise */
-void init_editdata(EditData *e, short *mouse, short *pr_mouse)
+void init_brushaction(BrushAction *a, short *mouse, short *pr_mouse)
{
SculptData *sd = sculpt_data();
- const float mouse_depth= get_depth(mouse[0],mouse[1]);
- vec3f brush_edge_loc, zero_loc, oldloc;
+ const float mouse_depth = get_depth(mouse[0], mouse[1]);
+ float brush_edge_loc[3], zero_loc[3], oldloc[3];
ModifierData *md;
int i;
const char flip = (get_qual() == LR_SHIFTKEY);
- e->flip= flip;
+ a->flip = flip;
+ a->symm.index = 0;
+ a->mouse[0] = mouse[0];
+ a->mouse[1] = mouse[1];
/* Convert the location and size of the brush to
modelspace coords */
- e->center= unproject(mouse[0],mouse[1],mouse_depth);
- brush_edge_loc= unproject(mouse[0] +
- brush_size(),mouse[1],
- mouse_depth);
- e->size= VecLenf(&e->center.x,&brush_edge_loc.x);
+ unproject(a->symm.center_3d, mouse[0], mouse[1], mouse_depth);
+ unproject(brush_edge_loc, mouse[0] + brush_size(), mouse[1], mouse_depth);
+ a->size_3d = VecLenf(a->symm.center_3d, brush_edge_loc);
/* Set the pivot to allow the model to rotate around the center of the brush */
if(get_depth(mouse[0],mouse[1]) < 1.0)
- sculpt_session()->pivot= e->center;
+ VecCopyf(&sculpt_session()->pivot.x, a->symm.center_3d);
/* Now project the Up, Right, and Out normals from view to model coords */
- zero_loc= unproject(0, 0, 0);
- e->up= unproject(0, -1, 0);
- e->right= unproject(1, 0, 0);
- e->out= unproject(0, 0, -1);
- VecSubf(&e->up.x, &e->up.x, &zero_loc.x);
- VecSubf(&e->right.x, &e->right.x, &zero_loc.x);
- VecSubf(&e->out.x, &e->out.x, &zero_loc.x);
- Normalize(&e->up.x);
- Normalize(&e->right.x);
- Normalize(&e->out.x);
+ unproject(zero_loc, 0, 0, 0);
+ unproject(a->symm.up, 0, -1, 0);
+ unproject(a->symm.right, 1, 0, 0);
+ unproject(a->symm.out, 0, 0, -1);
+ VecSubf(a->symm.up, a->symm.up, zero_loc);
+ VecSubf(a->symm.right, a->symm.right, zero_loc);
+ VecSubf(a->symm.out, a->symm.out, zero_loc);
+ Normalize(a->symm.up);
+ Normalize(a->symm.right);
+ Normalize(a->symm.out);
/* Initialize mirror modifier clipping */
for(i=0; i<3; ++i) {
- e->clip[i]= 0;
- e->cliptol[i]= 0;
+ a->clip[i]= 0;
+ a->cliptol[i]= 0;
}
for(md= OBACT->modifiers.first; md; md= md->next) {
if(md->type==eModifierType_Mirror && (md->mode & eModifierMode_Realtime)) {
const MirrorModifierData *mmd = (MirrorModifierData*) md;
if(mmd->flag & MOD_MIR_CLIPPING) {
- e->clip[mmd->axis]= 1;
- if(mmd->tolerance > e->cliptol[mmd->axis])
- e->cliptol[mmd->axis]= mmd->tolerance;
+ a->clip[mmd->axis]= 1;
+ if(mmd->tolerance > a->cliptol[mmd->axis])
+ a->cliptol[mmd->axis] = mmd->tolerance;
}
}
}
if(sd->brush_type == GRAB_BRUSH) {
- vec3f gcenter;
- if(!e->grabdata) {
- e->grabdata= MEM_callocN(sizeof(GrabData),"grab data");
- e->grabdata->firsttime= 1;
- e->grabdata->depth= mouse_depth;
- }
- else
- e->grabdata->firsttime= 0;
-
+ float gcenter[3];
+
+ if(a->firsttime)
+ a->depth = mouse_depth;
+
/* Find the delta */
- gcenter= unproject(mouse[0],mouse[1],e->grabdata->depth);
- oldloc= unproject(pr_mouse[0],pr_mouse[1],e->grabdata->depth);
- VecSubf(&e->grabdata->delta.x,&gcenter.x,&oldloc.x);
+ unproject(gcenter, mouse[0], mouse[1], a->depth);
+ unproject(oldloc, pr_mouse[0], pr_mouse[1], a->depth);
+ VecSubf(a->symm.grab_delta, gcenter, oldloc);
}
else if(sd->brush_type == LAYER_BRUSH) {
Mesh *me= get_mesh(OBACT);
- if(!e->layer_disps)
- e->layer_disps= MEM_callocN(sizeof(float)*me->totvert,"Layer disps");
- if(!e->layer_store) {
+ if(!a->layer_disps)
+ a->layer_disps= MEM_callocN(sizeof(float)*me->totvert,"Layer disps");
+ if(!a->layer_store) {
unsigned i;
- e->layer_store= MEM_mallocN(sizeof(vec3f)*me->totvert,"Layer store");
+ a->layer_store= MEM_mallocN(sizeof(vec3f)*me->totvert,"Layer store");
for(i=0; i<me->totvert; ++i)
- VecCopyf(&e->layer_store[i].x,me->mvert[i].co);
+ VecCopyf(&a->layer_store[i].x, me->mvert[i].co);
}
}
}
@@ -1470,11 +1461,11 @@ void sculpt(void)
/* lastSigMouse is for the rake, to store the last place the mouse movement was significant */
short mouse[2], mvalo[2], lastSigMouse[2],firsttime=1, mousebut;
short modifier_calculations= 0;
- EditData e;
+ BrushAction *a = MEM_callocN(sizeof(BrushAction), "brush action");
short spacing= 32000;
int scissor_box[4];
float offsetRot;
- int smooth_stroke = 0;
+ int smooth_stroke = 0, i;
if(!(G.f & G_SCULPTMODE) || G.obedit || !ob || ob->id.lib || !get_mesh(ob) || (get_mesh(ob)->totface == 0))
return;
@@ -1541,14 +1532,13 @@ void sculpt(void)
ss->vertexcosnos= mesh_get_mapped_verts_nors(ob);
sculptmode_update_all_projverts(ss->vertexcosnos);
- e.grabdata= NULL;
- e.layer_disps= NULL;
- e.layer_store= NULL;
+ a->layer_disps= NULL;
+ a->layer_store= NULL;
/* Set scaling adjustment */
- e.scale[0]= 1.0f / ob->size[0];
- e.scale[1]= 1.0f / ob->size[1];
- e.scale[2]= 1.0f / ob->size[2];
+ a->scale[0]= 1.0f / ob->size[0];
+ a->scale[1]= 1.0f / ob->size[1];
+ a->scale[2]= 1.0f / ob->size[2];
/* Capture original copy */
if(sd->flags & SCULPT_DRAW_FAST)
@@ -1571,6 +1561,7 @@ void sculpt(void)
}
if(firsttime || mouse[0]!=mvalo[0] || mouse[1]!=mvalo[1] || sculptmode_brush()->airbrush) {
+ a->firsttime = firsttime;
firsttime= 0;
if(smooth_stroke)
@@ -1583,27 +1574,27 @@ void sculpt(void)
if(G.scene->sculptdata.brush_type != GRAB_BRUSH) {
if(smooth_stroke) {
- sculpt_stroke_apply(&e);
+ sculpt_stroke_apply(a);
}
else if(sd->spacing==0 || spacing>sd->spacing) {
- do_symmetrical_brush_actions(&e, mouse, NULL);
+ do_symmetrical_brush_actions(a, mouse, NULL);
spacing= 0;
}
}
else {
- do_symmetrical_brush_actions(&e, mouse, mvalo);
- ss->pivot= unproject(mouse[0],mouse[1],e.grabdata->depth);
+ do_symmetrical_brush_actions(a, mouse, mvalo);
+ unproject(&ss->pivot.x, mouse[0], mouse[1], a->depth);
}
if(modifier_calculations || ob_get_keyblock(ob))
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
if(modifier_calculations || sd->brush_type == GRAB_BRUSH || !(sd->flags & SCULPT_DRAW_FAST)) {
- calc_damaged_verts(&ss->damaged_verts,e.grabdata);
+ calc_damaged_verts(&ss->damaged_verts, a);
scrarea_do_windraw(curarea);
screen_swapbuffers();
} else { /* Optimized drawing */
- calc_damaged_verts(&ss->damaged_verts,e.grabdata);
+ calc_damaged_verts(&ss->damaged_verts, a);
/* Draw the stored image to the screen */
glAccum(GL_RETURN, 1);
@@ -1648,20 +1639,16 @@ void sculpt(void)
set_tex_angle(offsetRot);
if(smooth_stroke) {
- sculpt_stroke_apply_all(&e);
- calc_damaged_verts(&ss->damaged_verts,e.grabdata);
+ sculpt_stroke_apply_all(a);
+ calc_damaged_verts(&ss->damaged_verts, a);
BLI_freelistN(&ss->damaged_rects);
}
- if(e.layer_disps) MEM_freeN(e.layer_disps);
- if(e.layer_store) MEM_freeN(e.layer_store);
- /* Free GrabData */
- if(e.grabdata) {
- int i;
- for(i=0; i<8; ++i)
- BLI_freelistN(&e.grabdata->active_verts[i]);
- MEM_freeN(e.grabdata);
- }
+ if(a->layer_disps) MEM_freeN(a->layer_disps);
+ if(a->layer_store) MEM_freeN(a->layer_store);
+ for(i=0; i<8; ++i)
+ BLI_freelistN(&a->grab_active_verts[i]);
+ MEM_freeN(a);
sculpt_stroke_free();
sculpt_undo_push(G.scene->sculptdata.brush_type);
@@ -1728,7 +1715,7 @@ void set_sculptmode(void)
static void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode)
{
Mesh *me= get_mesh(ob);
- vec3f hidebox[6];
+ float hidebox[6][3];
vec3f plane_normals[4];
float plane_ds[4];
unsigned i, j;
@@ -1740,23 +1727,23 @@ static void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode)
const unsigned SHOW= 0, HIDE=1;
/* Convert hide box from 2D to 3D */
- hidebox[0]= unproject(hb_2d->xmin, hb_2d->ymax, 1);
- hidebox[1]= unproject(hb_2d->xmax, hb_2d->ymax, 1);
- hidebox[2]= unproject(hb_2d->xmax, hb_2d->ymin, 1);
- hidebox[3]= unproject(hb_2d->xmin, hb_2d->ymin, 1);
- hidebox[4]= unproject(hb_2d->xmin, hb_2d->ymax, 0);
- hidebox[5]= unproject(hb_2d->xmax, hb_2d->ymin, 0);
+ unproject(hidebox[0], hb_2d->xmin, hb_2d->ymax, 1);
+ unproject(hidebox[1], hb_2d->xmax, hb_2d->ymax, 1);
+ unproject(hidebox[2], hb_2d->xmax, hb_2d->ymin, 1);
+ unproject(hidebox[3], hb_2d->xmin, hb_2d->ymin, 1);
+ unproject(hidebox[4], hb_2d->xmin, hb_2d->ymax, 0);
+ unproject(hidebox[5], hb_2d->xmax, hb_2d->ymin, 0);
/* Calculate normals for each side of hide box */
- CalcNormFloat(&hidebox[0].x,&hidebox[1].x,&hidebox[4].x,&plane_normals[0].x);
- CalcNormFloat(&hidebox[1].x,&hidebox[2].x,&hidebox[5].x,&plane_normals[1].x);
- CalcNormFloat(&hidebox[2].x,&hidebox[3].x,&hidebox[5].x,&plane_normals[2].x);
- CalcNormFloat(&hidebox[3].x,&hidebox[0].x,&hidebox[4].x,&plane_normals[3].x);
+ CalcNormFloat(hidebox[0], hidebox[1], hidebox[4], &plane_normals[0].x);
+ CalcNormFloat(hidebox[1], hidebox[2], hidebox[5], &plane_normals[1].x);
+ CalcNormFloat(hidebox[2], hidebox[3], hidebox[5], &plane_normals[2].x);
+ CalcNormFloat(hidebox[3], hidebox[0], hidebox[4], &plane_normals[3].x);
/* Calculate D for each side of hide box */
for(i= 0; i<4; ++i)
- plane_ds[i]= hidebox[i].x*plane_normals[i].x + hidebox[i].y*plane_normals[i].y +
- hidebox[i].z*plane_normals[i].z;
+ plane_ds[i]= hidebox[i][0]*plane_normals[i].x + hidebox[i][1]*plane_normals[i].y +
+ hidebox[i][2]*plane_normals[i].z;
/* Add partial visibility to mesh */
if(!me->pv) {
diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c
index bbb5e514942..1855ad3d147 100644
--- a/source/blender/src/transform.c
+++ b/source/blender/src/transform.c
@@ -888,6 +888,8 @@ static char *transform_to_undostr(TransInfo *t)
return "Time Slide";
case TFM_BAKE_TIME:
return "Key Time";
+ case TFM_MIRROR:
+ return "Mirror";
}
return "Transform";
}
@@ -1323,6 +1325,9 @@ void initTransform(int mode, int context) {
case TFM_BAKE_TIME:
initBakeTime(&Trans);
break;
+ case TFM_MIRROR:
+ initMirror(&Trans);
+ break;
}
}
@@ -1359,6 +1364,13 @@ void Transform()
}
Trans.redraw = 0;
}
+
+ /* If auto confirm is on, break after one pass */
+ if (Trans.context & CTX_AUTOCONFIRM)
+ {
+ Trans.state = TRANS_CONFIRM;
+ break;
+ }
/* essential for idling subloop */
if( qtest()==0) PIL_sleep_ms(2);
@@ -4033,105 +4045,83 @@ int BakeTime(TransInfo *t, short mval[2])
return 1;
}
-
/* ************************** MIRROR *************************** */
-void Mirror(short mode)
+void initMirror(TransInfo *t)
{
- TransData *td;
- float mati[3][3], matview[3][3], mat[3][3];
- float size[3];
- int i;
-
- Trans.context = CTX_NO_PET;
-
- initTrans(&Trans); // internal data, mouse, vectors
-
- Mat3One(mati);
- Mat3CpyMat4(matview, Trans.viewinv); // t->viewinv was set in initTrans
- Mat3Ortho(matview);
-
- createTransData(&Trans); // make TransData structs from selection
-
- calculatePropRatio(&Trans);
- calculateCenter(&Trans);
-
- initResize(&Trans);
-
- if (Trans.total == 0) {
- postTrans(&Trans);
- return;
- }
-
- size[0] = size[1] = size[2] = 1.0f;
- td = Trans.data;
-
- switch (mode) {
- case 1:
- size[0] = -1.0f;
- setConstraint(&Trans, mati, (CON_AXIS0), "");
- break;
- case 2:
- size[1] = -1.0f;
- setConstraint(&Trans, mati, (CON_AXIS1), "");
- break;
- case 3:
- size[2] = -1.0f;
- setConstraint(&Trans, mati, (CON_AXIS2), "");
- break;
- case 4:
- size[0] = -1.0f;
- setLocalConstraint(&Trans, (CON_AXIS0), "");
- break;
- case 5:
- size[1] = -1.0f;
- setLocalConstraint(&Trans, (CON_AXIS1), "");
- break;
- case 6:
- size[2] = -1.0f;
- setLocalConstraint(&Trans, (CON_AXIS2), "");
- break;
- case 7:
- size[0] = -1.0f;
- setConstraint(&Trans, matview, (CON_AXIS0), "");
- break;
- case 8:
- size[1] = -1.0f;
- setConstraint(&Trans, matview, (CON_AXIS1), "");
- break;
- case 9:
- size[2] = -1.0f;
- setConstraint(&Trans, matview, (CON_AXIS2), "");
- break;
- default:
- return;
+ t->flag |= T_NULL_ONE;
+ if (!G.obedit) {
+ t->flag |= T_NO_ZERO;
}
+
+ t->transform = Mirror;
+}
- SizeToMat3(size, mat);
-
- if (Trans.con.applySize) {
- Trans.con.applySize(&Trans, NULL, mat);
- }
+int Mirror(TransInfo *t, short mval[2])
+{
+ TransData *td;
+ float size[3], mat[3][3];
+ int i;
+ char str[200];
- for(i = 0 ; i < Trans.total; i++, td++) {
- if (td->flag & TD_NOACTION)
- break;
+ /*
+ * OPTIMISATION:
+ * This still recalcs transformation on mouse move
+ * while it should only recalc on constraint change
+ * */
- if (td->flag & TD_SKIP)
- continue;
+ /* if an axis has been selected */
+ if (t->con.mode & CON_APPLY) {
+ size[0] = size[1] = size[2] = -1;
+
+ SizeToMat3(size, mat);
+
+ if (t->con.applySize) {
+ t->con.applySize(t, NULL, mat);
+ }
- ElementResize(&Trans, td, mat);
+ sprintf(str, "Mirror%s", t->con.text);
+
+ for(i = 0, td=t->data; i < t->total; i++, td++) {
+ if (td->flag & TD_NOACTION)
+ break;
+
+ if (td->flag & TD_SKIP)
+ continue;
+
+ ElementResize(t, td, mat);
+ }
+
+ recalcData(t);
+
+ headerprint(str);
+
+ viewRedrawForce(t);
}
-
- recalcData(&Trans);
+ else
+ {
+ size[0] = size[1] = size[2] = 1;
- BIF_undo_push("Mirror");
-
- /* free data, reset vars */
- postTrans(&Trans);
+ SizeToMat3(size, mat);
+
+ for(i = 0, td=t->data; i < t->total; i++, td++) {
+ if (td->flag & TD_NOACTION)
+ break;
+
+ if (td->flag & TD_SKIP)
+ continue;
+
+ ElementResize(t, td, mat);
+ }
+
+ recalcData(t);
+
+ headerprint("Select a mirror axis (X, Y, Z)");
+
+ viewRedrawForce(t);
+ }
- /* send events out for redraws */
- viewRedrawPost(&Trans);
+ return 1;
}
/* ************************** ANIM EDITORS - TRANSFORM TOOLS *************************** */