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:
authorNicholas Bishop <nicholasbishop@gmail.com>2010-10-18 05:10:35 +0400
committerNicholas Bishop <nicholasbishop@gmail.com>2010-10-18 05:10:35 +0400
commit5b31d545dfae5ee3fd5f4a5d0e9497a1c7c2a86b (patch)
tree7494146547b5ca59c5a206ab59daa90d60a85a20 /source/blender/blenkernel
parent9e7142e2b0d2e8cdc78ca45162584b6da892931e (diff)
parent8b7e01b0bbdada3070c52f980a5f610d4a6c98c8 (diff)
svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r31926:32200
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_brush.h2
-rw-r--r--source/blender/blenkernel/BKE_context.h2
-rw-r--r--source/blender/blenkernel/BKE_exotic.h4
-rw-r--r--source/blender/blenkernel/BKE_image.h4
-rw-r--r--source/blender/blenkernel/BKE_unit.h7
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c9
-rw-r--r--source/blender/blenkernel/intern/anim.c28
-rw-r--r--source/blender/blenkernel/intern/armature.c4
-rw-r--r--source/blender/blenkernel/intern/boids.c70
-rw-r--r--source/blender/blenkernel/intern/brush.c16
-rw-r--r--source/blender/blenkernel/intern/constraint.c36
-rw-r--r--source/blender/blenkernel/intern/context.c11
-rw-r--r--source/blender/blenkernel/intern/curve.c25
-rw-r--r--source/blender/blenkernel/intern/displist.c62
-rw-r--r--source/blender/blenkernel/intern/effect.c2
-rw-r--r--source/blender/blenkernel/intern/exotic.c1706
-rw-r--r--source/blender/blenkernel/intern/fluidsim.c1
-rw-r--r--source/blender/blenkernel/intern/font.c2
-rw-r--r--source/blender/blenkernel/intern/image.c41
-rw-r--r--source/blender/blenkernel/intern/mesh.c3
-rw-r--r--source/blender/blenkernel/intern/object.c34
-rw-r--r--source/blender/blenkernel/intern/particle.c6
-rw-r--r--source/blender/blenkernel/intern/particle_system.c282
-rw-r--r--source/blender/blenkernel/intern/pointcache.c116
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c42
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c8
-rw-r--r--source/blender/blenkernel/intern/smoke.c23
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c2
-rw-r--r--source/blender/blenkernel/intern/unit.c266
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c108
31 files changed, 865 insertions, 2059 deletions
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index 0e406a16d0c..25d0eb5bc36 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -62,7 +62,7 @@ float brush_curve_strength_clamp(struct Brush *br, float p, const float len);
float brush_curve_strength(struct Brush *br, float p, const float len); /* used for sculpt */
/* sampling */
-void brush_sample_tex(struct Brush *brush, float *xy, float *rgba);
+void brush_sample_tex(struct Brush *brush, float *xy, float *rgba, const int thread);
void brush_imbuf_new(struct Brush *brush, short flt, short texfalloff, int size,
struct ImBuf **imbuf);
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index f6d41190c5a..9f38c5833a2 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -163,6 +163,8 @@ void CTX_wm_screen_set(bContext *C, struct bScreen *screen); /* to be removed */
void CTX_wm_area_set(bContext *C, struct ScrArea *sa);
void CTX_wm_region_set(bContext *C, struct ARegion *region);
void CTX_wm_menu_set(bContext *C, struct ARegion *menu);
+const char *CTX_wm_operator_poll_msg_get(struct bContext *C);
+void CTX_wm_operator_poll_msg_set(struct bContext *C, const char *msg);
/* Data Context
diff --git a/source/blender/blenkernel/BKE_exotic.h b/source/blender/blenkernel/BKE_exotic.h
index bd5af66c6a8..740a94b6169 100644
--- a/source/blender/blenkernel/BKE_exotic.h
+++ b/source/blender/blenkernel/BKE_exotic.h
@@ -34,9 +34,6 @@
struct Mesh;
struct Scene;
-void mcol_to_rgba(unsigned int col, float *r, float *g, float *b, float *a);
-unsigned int *mcol_to_vcol(struct Mesh *me); // used in py_main.c
-
/**
* Reads all 3D fileformats other than Blender fileformat
* @retval 0 The file could not be read.
@@ -46,7 +43,6 @@ unsigned int *mcol_to_vcol(struct Mesh *me); // used in py_main.c
int BKE_read_exotic(struct Scene *scene, char *name);
void write_dxf(struct Scene *scene, char *str);
-void write_vrml(struct Scene *scene, char *str);
void write_stl(struct Scene *scene, char *str);
#endif
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index c842efaa3b2..0a07e6d482c 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -48,7 +48,7 @@ void BKE_stamp_info(struct Scene *scene, struct ImBuf *ibuf);
void BKE_stamp_buf(struct Scene *scene, unsigned char *rect, float *rectf, int width, int height, int channels);
int BKE_write_ibuf(struct Scene *scene, struct ImBuf *ibuf, char *name, int imtype, int subimtype, int quality);
void BKE_makepicstring(char *string, char *base, int frame, int imtype, int use_ext);
-void BKE_add_image_extension(char *string, int imtype);
+int BKE_add_image_extension(char *string, int imtype);
int BKE_ftype_to_imtype(int ftype);
int BKE_imtype_to_ftype(int imtype);
int BKE_imtype_is_movie(int imtype);
@@ -115,7 +115,7 @@ void BKE_image_release_ibuf(struct Image *ima, void *lock);
struct Image *BKE_add_image_file(const char *name, int frame);
/* adds image, adds ibuf, generates color or pattern */
-struct Image *BKE_add_image_size(int width, int height, char *name, int depth, int floatbuf, short uvtestgrid, float color[4]);
+struct Image *BKE_add_image_size(unsigned int width, unsigned int height, char *name, int depth, int floatbuf, short uvtestgrid, float color[4]);
/* adds image from imbuf, owns imbuf */
struct Image *BKE_add_image_imbuf(struct ImBuf *ibuf);
diff --git a/source/blender/blenkernel/BKE_unit.h b/source/blender/blenkernel/BKE_unit.h
index 36ccc1f1497..7461d43e721 100644
--- a/source/blender/blenkernel/BKE_unit.h
+++ b/source/blender/blenkernel/BKE_unit.h
@@ -36,12 +36,18 @@ void bUnit_AsString(char *str, int len_max, double value, int prec, int system,
/* replace units with values, used before python button evaluation */
int bUnit_ReplaceString(char *str, int len_max, char *str_prev, double scale_pref, int system, int type);
+/* make string keyboard-friendly: 10µm --> 10um */
+void bUnit_ToUnitAltName(char *str, int len_max, char *orig_str, int system, int type);
+
/* the size of the unit used for this value (used for calculating the ckickstep) */
double bUnit_ClosestScalar(double value, int system, int type);
/* base scale for these units */
double bUnit_BaseScalar(int system, int type);
+/* return true is the unit system exists */
+int bUnit_IsValid(int system, int type);
+
/* loop over scales, coudl add names later */
//double bUnit_Iter(void **unit, char **name, int system, int type);
@@ -60,6 +66,7 @@ double bUnit_GetScaler(void *usys_pt, int index);
#define B_UNIT_TIME 6
#define B_UNIT_VELOCITY 7
#define B_UNIT_ACCELERATION 8
+#define B_UNIT_MAXDEF 9
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index f7f11279fad..784c7116a65 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -31,7 +31,6 @@ SET(INC
../avi
../blenlib
../blenloader
- ../editors/include
../gpu
../ikplugin
../imbuf
@@ -39,6 +38,7 @@ SET(INC
../makesrna
../modifiers
../nodes
+ ../editors/include
../render/extern/include
../../../extern/glew/include
../../../intern/audaspace/intern
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index b2441a8a58f..ae99e2c9242 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -242,6 +242,15 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me)
if(!CustomData_has_layer(&tmp.fdata, CD_MFACE))
CustomData_add_layer(&tmp.fdata, CD_MFACE, CD_ASSIGN, dm->dupFaceArray(dm), totface);
+ /* object had got displacement layer, should copy this layer to save sculpted data */
+ /* NOTE: maybe some other layers should be copied? nazgul */
+ if(CustomData_has_layer(&me->fdata, CD_MDISPS)) {
+ if (totface == me->totface) {
+ MDisps *mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
+ CustomData_add_layer(&tmp.fdata, CD_MDISPS, CD_DUPLICATE, mdisps, totface);
+ }
+ }
+
mesh_update_customdata_pointers(&tmp);
CustomData_free(&me->vdata, me->totvert);
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 98bdf3b2e9f..6da9f2bbabc 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -640,29 +640,19 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat,
/* Need to verify the quat interpolation is correct - XXX */
if (quat) {
- //float totfac, q1[4], q2[4];
+ float totfac, q1[4], q2[4];
- /* checks for totfac are needed when 'fac' is 1.0 key_curve_position_weights can assign zero
- * to more then one index in data which can give divide by zero error */
-/*
- totfac= data[0]+data[1];
- if(totfac>0.000001) interp_qt_qtqt(q1, p0->quat, p1->quat, data[0] / totfac);
- else QUATCOPY(q1, p1->quat);
+ totfac= data[0]+data[3];
+ if(totfac>FLT_EPSILON) interp_qt_qtqt(q1, p0->quat, p3->quat, data[3] / totfac);
+ else QUATCOPY(q1, p1->quat);
- normalize_qt(q1);
-
- totfac= data[2]+data[3];
- if(totfac>0.000001) interp_qt_qtqt(q2, p2->quat, p3->quat, data[2] / totfac);
- else QUATCOPY(q1, p3->quat);
- normalize_qt(q2);
+ totfac= data[1]+data[2];
+ if(totfac>FLT_EPSILON) interp_qt_qtqt(q2, p1->quat, p2->quat, data[2] / totfac);
+ else QUATCOPY(q1, p3->quat);
totfac = data[0]+data[1]+data[2]+data[3];
- if(totfac>0.000001) interp_qt_qtqt(quat, q1, q2, (data[0]+data[1]) / totfac);
- else QUATCOPY(quat, q2);
- normalize_qt(quat);
- */
- // XXX - find some way to make quat interpolation work correctly, above code fails in rare but nasty cases.
- QUATCOPY(quat, p1->quat);
+ if(totfac>FLT_EPSILON) interp_qt_qtqt(quat, q1, q2, (data[1]+data[2]) / totfac);
+ else QUATCOPY(quat, q2);
}
if(radius)
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 41821f34ba8..2e760f53155 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1289,7 +1289,9 @@ void vec_roll_to_mat3(float *vec, float roll, float mat[][3])
/* Find Axis & Amount for bone matrix*/
cross_v3_v3v3(axis,target,nor);
- if (dot_v3v3(axis,axis) > 0.0000000000001) {
+ /* was 0.0000000000001, caused bug [#23954], smaller values give unstable
+ * roll when toggling editmode */
+ if (dot_v3v3(axis,axis) > 0.00001) {
/* if nor is *not* a multiple of target ... */
normalize_v3(axis);
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index 54ffda6c0a9..69a42e52247 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -240,6 +240,7 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
mul_v3_fl(bbd->wanted_co, (1.0f - t) * val->personal_space * pa->size);
bbd->wanted_speed = sqrt(t) * len_v3(pa->prev_state.vel);
+ bbd->wanted_speed = MAX2(bbd->wanted_speed, val->min_speed);
return 1;
}
@@ -736,6 +737,7 @@ static void set_boid_values(BoidValues *val, BoidSettings *boids, ParticleData *
val->jump_speed = 0.0f; /* no jumping in air */
}
}
+
static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *ground_co, float *ground_nor)
{
BoidParticle *bpa = pa->boid;
@@ -765,16 +767,15 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro
if(!bbd->sim->colliders)
return NULL;
+ /* first try to find below boid */
copy_v3_v3(col.co1, pa->state.co);
- copy_v3_v3(col.co2, pa->state.co);
- add_v3_v3(col.co1, zvec);
+ sub_v3_v3v3(col.co2, pa->state.co, zvec);
sub_v3_v3(col.co2, zvec);
sub_v3_v3v3(ray_dir, col.co2, col.co1);
col.t = 0.0f;
hit.index = -1;
hit.dist = col.ray_len = len_v3(ray_dir);
- /* find out upmost deflector object */
for(coll = bbd->sim->colliders->first; coll; coll = coll->next){
col.ob = coll->ob;
col.md = coll->collmd;
@@ -789,14 +790,37 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro
normalize_v3_v3(ground_nor, col.nor);
return col.hit_ob;
}
- else {
- /* default to z=0 */
- VECCOPY(ground_co, pa->state.co);
- ground_co[2] = 0;
- ground_nor[0] = ground_nor[1] = 0.0f;
- ground_nor[2] = 1.0f;
- return NULL;
+
+ /* couldn't find below, so find upmost deflector object */
+ add_v3_v3v3(col.co1, pa->state.co, zvec);
+ sub_v3_v3v3(col.co2, pa->state.co, zvec);
+ sub_v3_v3(col.co2, zvec);
+ sub_v3_v3v3(ray_dir, col.co2, col.co1);
+ col.t = 0.0f;
+ hit.index = -1;
+ hit.dist = col.ray_len = len_v3(ray_dir);
+
+ for(coll = bbd->sim->colliders->first; coll; coll = coll->next){
+ col.ob = coll->ob;
+ col.md = coll->collmd;
+
+ if(col.md && col.md->bvhtree)
+ BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col);
+ }
+ /* then use that object */
+ if(hit.index>=0) {
+ t = hit.dist/col.ray_len;
+ interp_v3_v3v3(ground_co, col.co1, col.co2, t);
+ normalize_v3_v3(ground_nor, col.nor);
+ return col.hit_ob;
}
+
+ /* default to z=0 */
+ VECCOPY(ground_co, pa->state.co);
+ ground_co[2] = 0;
+ ground_nor[0] = ground_nor[1] = 0.0f;
+ ground_nor[2] = 1.0f;
+ return NULL;
}
}
static int boid_rule_applies(ParticleData *pa, BoidSettings *boids, BoidRule *rule)
@@ -1226,8 +1250,8 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
VECADDFAC(pa->state.vel, pa->state.vel, acc, dtime);
- if(bpa->data.mode != eBoidMode_InAir)
- bpa->ground = boid_find_ground(bbd, pa, ground_co, ground_nor);
+ //if(bpa->data.mode != eBoidMode_InAir)
+ bpa->ground = boid_find_ground(bbd, pa, ground_co, ground_nor);
/* change modes, constrain movement & keep track of down vector */
switch(bpa->data.mode) {
@@ -1255,11 +1279,18 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
boid_find_ground(bbd, pa, ground_co, ground_nor);
boid_climb(boids, pa, ground_co, ground_nor);
}
- /* land boid when belowg ground */
- else if(boids->options & BOID_ALLOW_LAND && pa->state.co[2] <= ground_co[2] + pa->size * boids->height) {
- pa->state.co[2] = ground_co[2] + pa->size * boids->height;
- pa->state.vel[2] = 0.0f;
- bpa->data.mode = eBoidMode_OnLand;
+ else if(pa->state.co[2] <= ground_co[2] + pa->size * boids->height) {
+ /* land boid when below ground */
+ if(boids->options & BOID_ALLOW_LAND) {
+ pa->state.co[2] = ground_co[2] + pa->size * boids->height;
+ pa->state.vel[2] = 0.0f;
+ bpa->data.mode = eBoidMode_OnLand;
+ }
+ /* fly above ground */
+ else {
+ pa->state.co[2] = ground_co[2] + pa->size * boids->height;
+ pa->state.vel[2] = 0.0f;
+ }
}
break;
}
@@ -1355,7 +1386,9 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
/* save direction to state.ave unless the boid is falling */
/* (boids can't effect their direction when falling) */
if(bpa->data.mode!=eBoidMode_Falling && len_v3(pa->state.vel) > 0.1*pa->size) {
- normalize_v3_v3(pa->state.ave, pa->state.vel);
+ copy_v3_v3(pa->state.ave, pa->state.vel);
+ pa->state.ave[2] *= bbd->part->boids->pitch;
+ normalize_v3(pa->state.ave);
}
/* apply damping */
@@ -1440,6 +1473,7 @@ void boid_default_settings(BoidSettings *boids)
boids->landing_smoothness = 3.0f;
boids->banking = 1.0f;
+ boids->pitch = 1.0f;
boids->height = 1.0f;
boids->health = 1.0f;
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 90ea562be9d..c67db9382f3 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -480,7 +480,7 @@ int brush_clone_image_delete(Brush *brush)
}
/* Brush Sampling */
-void brush_sample_tex(Brush *brush, float *xy, float *rgba)
+void brush_sample_tex(Brush *brush, float *xy, float *rgba, const int thread)
{
MTex *mtex= &brush->mtex;
@@ -493,7 +493,7 @@ void brush_sample_tex(Brush *brush, float *xy, float *rgba)
co[1]= xy[1]/radius;
co[2]= 0.0f;
- hasrgb= externtex(mtex, co, &tin, &tr, &tg, &tb, &ta);
+ hasrgb= externtex(mtex, co, &tin, &tr, &tg, &tb, &ta, thread);
if (hasrgb) {
rgba[0]= tr;
@@ -547,12 +547,12 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf
dstf[3]= alpha*brush_curve_strength_clamp(brush, dist, radius);
}
else if (texfall == 1) {
- brush_sample_tex(brush, xy, dstf);
+ brush_sample_tex(brush, xy, dstf, 0);
}
else {
dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
- brush_sample_tex(brush, xy, rgba);
+ brush_sample_tex(brush, xy, rgba, 0);
dstf[0] = rgba[0]*brush->rgb[0];
dstf[1] = rgba[1]*brush->rgb[1];
@@ -583,7 +583,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf
dst[3]= FTOCHAR(alpha*brush_curve_strength(brush, dist, radius));
}
else if (texfall == 1) {
- brush_sample_tex(brush, xy, rgba);
+ brush_sample_tex(brush, xy, rgba, 0);
dst[0]= FTOCHAR(rgba[0]);
dst[1]= FTOCHAR(rgba[1]);
dst[2]= FTOCHAR(rgba[2]);
@@ -592,7 +592,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf
else {
dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
- brush_sample_tex(brush, xy, rgba);
+ brush_sample_tex(brush, xy, rgba, 0);
dst[0] = FTOCHAR(rgba[0]*brush->rgb[0]);
dst[1] = FTOCHAR(rgba[1]*brush->rgb[1]);
dst[2] = FTOCHAR(rgba[2]*brush->rgb[2]);
@@ -739,7 +739,7 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf, i
xy[0] = x + xoff;
xy[1] = y + yoff;
- brush_sample_tex(brush, xy, tf);
+ brush_sample_tex(brush, xy, tf, 0);
}
bf[0] = tf[0]*mf[0];
@@ -770,7 +770,7 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf, i
xy[0] = x + xoff;
xy[1] = y + yoff;
- brush_sample_tex(brush, xy, rgba);
+ brush_sample_tex(brush, xy, rgba, 0);
t[0]= FTOCHAR(rgba[0]);
t[1]= FTOCHAR(rgba[1]);
t[2]= FTOCHAR(rgba[2]);
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 57e5630da19..fe69f13bbda 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -850,7 +850,14 @@ static void childof_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
* the effect of this constraint (i.e. owner is 'parented' to parent)
*/
copy_m4_m4(tempmat, cob->matrix);
- mul_m4_m4m4(cob->matrix, tempmat, parmat);
+ mul_m4_m4m4(cob->matrix, tempmat, parmat);
+
+ /* without this, changes to scale and rotation can change location
+ * of a parentless bone or a disconnected bone. Even though its set
+ * to zero above. */
+ if (!(data->flag & CHILDOF_LOCX)) cob->matrix[3][0]= tempmat[3][0];
+ if (!(data->flag & CHILDOF_LOCY)) cob->matrix[3][1]= tempmat[3][1];
+ if (!(data->flag & CHILDOF_LOCZ)) cob->matrix[3][2]= tempmat[3][2];
}
}
@@ -1629,8 +1636,9 @@ static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
mat4_to_size(size, cob->matrix);
/* to allow compatible rotations, must get both rotations in the order of the owner... */
- mat4_to_eulO(eul, cob->rotOrder, ct->matrix);
mat4_to_eulO(obeul, cob->rotOrder, cob->matrix);
+ /* we must get compatible eulers from the beginning because some of them can be modified below (see bug #21875) */
+ mat4_to_compatible_eulO(eul, obeul, cob->rotOrder, ct->matrix);
if ((data->flag & ROTLIKE_X)==0)
eul[0] = obeul[0];
@@ -1662,6 +1670,7 @@ static void rotlike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
eul[2] *= -1;
}
+ /* good to make eulers compatible again, since we don't know how much they were changed above */
compatible_eul(eul, obeul);
loc_eulO_size_to_mat4(cob->matrix, loc, eul, size, cob->rotOrder);
}
@@ -4349,8 +4358,7 @@ void get_constraint_target_matrix (struct Scene *scene, bConstraint *con, int n,
void solve_constraints (ListBase *conlist, bConstraintOb *cob, float ctime)
{
bConstraint *con;
- float solution[4][4], delta[4][4];
- float oldmat[4][4], imat[4][4];
+ float oldmat[4][4];
float enf;
/* check that there is a valid constraint object to evaluate */
@@ -4402,7 +4410,7 @@ void solve_constraints (ListBase *conlist, bConstraintOb *cob, float ctime)
}
}
- /* Solve the constraint */
+ /* Solve the constraint and put result in cob->matrix */
cti->evaluate_constraint(con, cob, &targets);
/* clear targets after use
@@ -4414,23 +4422,13 @@ void solve_constraints (ListBase *conlist, bConstraintOb *cob, float ctime)
}
/* Interpolate the enforcement, to blend result of constraint into final owner transform */
- /* 1. Remove effects of original matrix from constraint solution ==> delta */
- invert_m4_m4(imat, oldmat);
- copy_m4_m4(solution, cob->matrix);
- mul_m4_m4m4(delta, solution, imat);
-
- /* 2. If constraint influence is not full strength, then interpolate
- * identity_matrix --> delta_matrix to get the effect the constraint actually exerts
- */
+ /* Note: all kind of stuff here before (caused trouble), much easier to just interpolate, or did I miss something? -jahka */
if (enf < 1.0) {
- float identity[4][4];
- unit_m4(identity);
- blend_m4_m4m4(delta, identity, delta, enf);
+ float solution[4][4];
+ copy_m4_m4(solution, cob->matrix);
+ blend_m4_m4m4(cob->matrix, oldmat, solution, enf);
}
- /* 3. Now multiply the delta by the matrix in use before the evaluation */
- mul_m4_m4m4(cob->matrix, delta, oldmat);
-
/* move owner back into worldspace for next constraint/other business */
if ((con->flag & CONSTRAINT_SPACEONCE) == 0)
constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, con->ownspace, CONSTRAINT_SPACE_WORLD);
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 7928424e47c..a5d96baf049 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -64,6 +64,7 @@ struct bContext {
struct ARegion *region;
struct ARegion *menu;
struct bContextStore *store;
+ const char *operator_poll_msg; /* reason for poll failing */
} wm;
/* data context */
@@ -399,6 +400,16 @@ void CTX_wm_menu_set(bContext *C, ARegion *menu)
C->wm.menu= menu;
}
+void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg)
+{
+ C->wm.operator_poll_msg= msg;
+}
+
+const char *CTX_wm_operator_poll_msg_get(bContext *C)
+{
+ return C->wm.operator_poll_msg;
+}
+
/* data context utility functions */
struct bContextDataResult {
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 358dd1914e7..d13738808d1 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -74,12 +74,22 @@ void unlink_curve(Curve *cu)
for(a=0; a<cu->totcol; a++) {
if(cu->mat[a]) cu->mat[a]->id.us--;
- cu->mat[a]= 0;
+ cu->mat[a]= NULL;
}
if(cu->vfont) cu->vfont->id.us--;
- cu->vfont= 0;
+ cu->vfont= NULL;
+
+ if(cu->vfontb) cu->vfontb->id.us--;
+ cu->vfontb= NULL;
+
+ if(cu->vfonti) cu->vfonti->id.us--;
+ cu->vfonti= NULL;
+
+ if(cu->vfontbi) cu->vfontbi->id.us--;
+ cu->vfontbi= NULL;
+
if(cu->key) cu->key->id.us--;
- cu->key= 0;
+ cu->key= NULL;
}
/* frees editcurve entirely */
@@ -210,9 +220,12 @@ void make_local_curve(Curve *cu)
*/
if(cu->id.lib==0) return;
-
- if(cu->vfont) cu->vfont->id.lib= 0;
-
+
+ if(cu->vfont) cu->vfont->id.lib= NULL;
+ if(cu->vfontb) cu->vfontb->id.lib= NULL;
+ if(cu->vfonti) cu->vfonti->id.lib= NULL;
+ if(cu->vfontbi) cu->vfontbi->id.lib= NULL;
+
if(cu->id.us==1) {
cu->id.lib= 0;
cu->id.flag= LIB_LOCAL;
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index a44c5ace298..d0336d9f786 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -930,7 +930,7 @@ void filldisplist(ListBase *dispbase, ListBase *to, int flipnormal)
EditFace *efa;
DispList *dlnew=0, *dl;
float *f1;
- int colnr=0, charidx=0, cont=1, tot, a, *index;
+ int colnr=0, charidx=0, cont=1, tot, a, *index, nextcol= 0;
intptr_t totvert;
if(dispbase==0) return;
@@ -938,38 +938,41 @@ void filldisplist(ListBase *dispbase, ListBase *to, int flipnormal)
while(cont) {
cont= 0;
- totvert=0;
+ totvert= 0;
+ nextcol= 0;
dl= dispbase->first;
while(dl) {
if(dl->type==DL_POLY) {
if(charidx<dl->charidx) cont= 1;
- else if(charidx==dl->charidx) {
-
- colnr= dl->col;
- charidx= dl->charidx;
-
- /* make editverts and edges */
- f1= dl->verts;
- a= dl->nr;
- eve= v1= 0;
-
- while(a--) {
- vlast= eve;
-
- eve= BLI_addfillvert(f1);
- totvert++;
+ else if(charidx==dl->charidx) { /* character with needed index */
+ if(colnr==dl->col) {
+ /* make editverts and edges */
+ f1= dl->verts;
+ a= dl->nr;
+ eve= v1= 0;
- if(vlast==0) v1= eve;
- else {
- BLI_addfilledge(vlast, eve);
+ while(a--) {
+ vlast= eve;
+
+ eve= BLI_addfillvert(f1);
+ totvert++;
+
+ if(vlast==0) v1= eve;
+ else {
+ BLI_addfilledge(vlast, eve);
+ }
+ f1+=3;
}
- f1+=3;
- }
-
- if(eve!=0 && v1!=0) {
- BLI_addfilledge(eve, v1);
+
+ if(eve!=0 && v1!=0) {
+ BLI_addfilledge(eve, v1);
+ }
+ } else if (colnr<dl->col) {
+ /* got poly with next material at current char */
+ cont= 1;
+ nextcol= 1;
}
}
}
@@ -1032,7 +1035,14 @@ void filldisplist(ListBase *dispbase, ListBase *to, int flipnormal)
}
BLI_end_edgefill();
- charidx++;
+ if(nextcol) {
+ /* stay at current char but fill polys with next material */
+ colnr++;
+ } else {
+ /* switch to next char and start filling from first material */
+ charidx++;
+ colnr= 0;
+ }
}
/* do not free polys, needed for wireframe display */
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 05fcabd371f..4860e7d8eed 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -29,6 +29,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#include <stddef.h>
#include "BLI_storage.h" /* _LARGEFILE_SOURCE */
#include <math.h>
@@ -85,7 +86,6 @@
#include "BKE_object.h"
#include "BKE_particle.h"
#include "BKE_scene.h"
-#include "BKE_screen.h"
#include "BKE_utildefines.h"
#include "RE_render_ext.h"
diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c
index cdefbb54ecf..9dac409226b 100644
--- a/source/blender/blenkernel/intern/exotic.c
+++ b/source/blender/blenkernel/intern/exotic.c
@@ -29,12 +29,14 @@
*
* ***** END GPL LICENSE BLOCK *****/
+#include <stddef.h>
#include "BLI_storage.h"
+#include <stdlib.h>
#include <ctype.h> /* isdigit, isspace */
#include <math.h>
#include <stdio.h>
-#include <stdlib.h>
+
#include <fcntl.h>
#include <string.h>
#include <errno.h>
@@ -449,1328 +451,10 @@ static void read_stl_mesh_ascii(Scene *scene, char *str)
#undef STLREADLINE
#undef STLREADVERT
-/* ***************** INVENTOR ******************* */
-
-
-#define IV_MAXSTACK 3000000
-#define IV_MAXFIELD 10
-#define IV_MAXCOL 16
-
-static float *iv_data_stack;
-static float ivcolors[IV_MAXCOL][3];
-static Object *ivsurf;
-static ListBase ivbase;
-
-struct IvNode {
- struct IvNode *next, *prev;
- char *nodename;
- char *fieldname[IV_MAXFIELD];
- int datalen[IV_MAXFIELD];
- float *data[IV_MAXFIELD];
-};
-
-static int iv_curcol=0;
-
-static int iv_colornumber(struct IvNode *iv)
-{
- float *fp, fr = 0.0, fg = 0.0, fb = 0.0;
- int a;
- char *cp;
-
- /* search back to last material */
- while(iv) {
- if( strcmp(iv->nodename, "Material")==0) {
- fp= iv->data[0];
- if(fp==0) fp= iv->data[1];
- if(fp) {
- fr= fp[0];
- fg= fp[1];
- fb= fp[2];
- }
- break;
- }
- else if( strcmp(iv->nodename, "BaseColor")==0) {
- fp= iv->data[0];
- fr= fp[0];
- fg= fp[1];
- fb= fp[2];
- break;
- }
- else if( strcmp(iv->nodename, "PackedColor")==0) {
- cp= (char *)iv->data[0];
- fr= cp[3]/255.0f;
- fg= cp[2]/255.0f;
- fb= cp[1]/255.0f;
- break;
- }
- iv= iv->prev;
-
- }
- if(iv==0) return 0;
- if(iv->datalen[0]<3) return 0;
-
- for(a=0; a<iv_curcol; a++) {
-
- if(ivcolors[a][0]== fr)
- if(ivcolors[a][1]== fg)
- if(ivcolors[a][2]== fb) return a+1
- ;
- }
-
- if(a>=IV_MAXCOL) a= IV_MAXCOL-1;
- iv_curcol= a+1;
- ivcolors[a][0]= fr;
- ivcolors[a][1]= fg;
- ivcolors[a][2]= fb;
-
- return iv_curcol;
-}
-
-static int iv_finddata(struct IvNode *iv, char *field, int fieldnr)
-{
- /* search for "field", count data size and make datablock. return skipdata */
- float *fp;
- int len, stackcount, skipdata=0;
- char *cpa, terminator, str[64];
- intptr_t i;
-
- len= strlen(field);
-
- cpa= iv->nodename+1;
- while( *cpa != '}' ) {
-
- if( *cpa == *field ) {
- if( strncmp(cpa, field, len)==0 ) {
- iv->fieldname[fieldnr]= cpa;
-
- /* read until first character */
- cpa+= len;
- skipdata+= len;
- *cpa= 0;
- cpa++;
- skipdata++;
-
- while( *cpa==32 || *cpa==13 || *cpa==10 || *cpa==9) cpa++;
- if( *cpa=='[' ) {
- terminator= ']';
- cpa++;
- skipdata++;
- }
- else terminator= 13;
-
- stackcount= 0;
- fp= iv_data_stack;
-
- while( *cpa!=terminator && *cpa != '}' ) {
-
- /* in fact, isdigit should include the dot and minus */
- if( (isdigit(*cpa) || *cpa=='.' || *cpa=='-') && (isspace(cpa[-1]) || cpa[-1]==0 || cpa[-1]==',') ) {
- if(cpa[1]=='x') {
- memcpy(str, cpa, 16);
- str[16]= 0;
-
- sscanf(str, "%x", (int *)fp);
- }
- else {
- /* atof doesn't stop after the first float
- * in a long string at Windows... so we copy
- * the float to a new string then atof... */
- char *cpa_temp = strpbrk(cpa, ", \n");
- i = cpa_temp - cpa;
-
- if (i>63) *fp= 0.0;
- else {
- memcpy(str, cpa, i);
- str[i]=0;
-
- *fp= (float) atof(str);
- }
- }
-
- stackcount++;
- if(stackcount>=IV_MAXSTACK) {
- printf("stackoverflow in IV read\n");
- break;
- }
- fp++;
- }
- cpa++;
- skipdata++;
- }
-
- iv->datalen[fieldnr]= stackcount;
- if(stackcount) {
- iv->data[fieldnr]= MEM_mallocN(sizeof(float)*stackcount, "iv_finddata");
- memcpy(iv->data[fieldnr], iv_data_stack, sizeof(float)*stackcount);
- }
- else iv->data[fieldnr]= 0;
-
- return skipdata;
- }
- }
- cpa++;
- skipdata++;
- }
-
- return skipdata;
-}
-
-static void read_iv_index(float *data, float *baseadr, float *index, int nr, int coordtype)
-{
- /* write in data: baseadr with offset index (and number nr) */
- float *fp;
- int ofs;
-
- while(nr--) {
- ofs= (int) *index;
- fp= baseadr+coordtype*ofs;
- VECCOPY(data, fp);
- data+= 3;
- index++;
- }
-}
-
-
-
-static void read_inventor(Scene *scene, char *str, struct ListBase *listb)
-{
- struct IvNode *iv, *ivp, *ivn;
- char *maindata, *md, *cpa;
- float *index, *data, *fp;
- int file, filelen, count, lll, face, nr = 0;
- int skipdata, ok, a, b, tot, first, colnr, coordtype, polytype, *idata;
- struct DispList *dl;
- ReportList *reports= NULL; /* XXX */
-
- ivbase.first= ivbase.last= 0;
- iv_curcol= 0;
- ivsurf= 0;
-
- file= open(str, O_BINARY|O_RDONLY);
- if(file== -1) {
- BKE_reportf(reports, RPT_ERROR, "Can't read file: %s.", strerror(errno));
- return;
- }
-
- filelen= BLI_filesize(file);
- if(filelen < 1) {
- close(file);
- return;
- }
-
- maindata= MEM_mallocN(filelen, "leesInventor");
- if(read(file, maindata, filelen) < filelen) {
- BKE_reportf(reports, RPT_ERROR, "Failed reading file: premature end of file.");
- close(file);
- return;
- }
- close(file);
-
- iv_data_stack= MEM_mallocN(sizeof(float)*IV_MAXSTACK, "ivstack");
-
- /* preprocess: remove comments */
- md= maindata+20;
- count= 20;
- while(count<filelen) {
- if( *md=='#' ) { /* comment */
- while( *md!=13 && *md!=10) { /* enters */
- *md= 32;
- md++;
- count++;
- if(count>=filelen) break;
- }
- }
- md++;
- count++;
- }
-
-
- /* now time to collect: which are the nodes and fields? */
- md= maindata;
- count= 0;
- while(count<filelen) {
- if( *md=='{' ) { /* read back */
-
- cpa= md-1;
- while( *cpa==32 || *cpa==13 || *cpa==10 || *cpa==9) { /* remove spaces/enters/tab */
- *cpa= 0;
- cpa--;
- }
-
- while( *cpa>32 && *cpa<128) cpa--;
- cpa++;
- *md= 0;
-
- ok= 0;
- skipdata= 0;
- iv= MEM_callocN(sizeof(struct IvNode), "leesInventor");
- iv->nodename= cpa;
-
- if(strcmp(cpa, "Coordinate3")==0 || strcmp(cpa, "Coordinate4")==0) {
- skipdata= iv_finddata(iv, "point", 0);
- ok= 1;
- }
- else if(strcmp(cpa, "VertexProperty")==0) {
- skipdata= iv_finddata(iv, "vertex", 0);
- ok= 1;
- }
- else if(strcmp(cpa, "IndexedLineSet")==0) {
- skipdata= iv_finddata(iv, "coordIndex", 0);
- ok= 1;
- }
- else if(strcmp(cpa, "IndexedTriangleMesh")==0) {
- skipdata= iv_finddata(iv, "coordIndex", 0);
- ok= 1;
- }
- else if(strcmp(cpa, "IndexedFaceSet")==0) {
- skipdata= iv_finddata(iv, "coordIndex", 0);
- ok= 1;
- }
- else if(strcmp(cpa, "FaceSet")==0) {
- skipdata= iv_finddata(iv, "numVertices", 0);
- ok= 1;
- }
- else if(strcmp(cpa, "Material")==0) {
- iv_finddata(iv, "diffuseColor", 0);
- iv_finddata(iv, "ambientColor", 1);
- ok= 1;
- }
- else if(strcmp(cpa, "BaseColor")==0) {
- iv_finddata(iv, "rgb", 0);
- ok= 1;
- }
- else if(strcmp(cpa, "PackedColor")==0) {
- iv_finddata(iv, "rgba", 0);
- ok= 1;
- }
- else if(strcmp(cpa, "QuadMesh")==0) {
- iv_finddata(iv, "verticesPerColumn", 0);
- iv_finddata(iv, "verticesPerRow", 1);
-
- ok= 1;
- }
- else if(strcmp(cpa, "IndexedTriangleStripSet")==0) {
- skipdata= iv_finddata(iv, "coordIndex", 0);
- ok= 1;
- }
- else if(strcmp(cpa, "TriangleStripSet")==0) {
- skipdata= iv_finddata(iv, "numVertices", 0);
- ok= 1;
- }
- else if(strcmp(cpa, "IndexedNurbsSurface")==0 || strcmp(cpa, "NurbsSurface")==0) {
- iv_finddata(iv, "numUControlPoints", 0);
- iv_finddata(iv, "numVControlPoints", 1);
- iv_finddata(iv, "uKnotVector", 2);
- iv_finddata(iv, "vKnotVector", 3);
- ok= 1;
- }
- else {
- /* to the end */
- while( *md != '}') {
- md++;
- count++;
- if(count<filelen) break;
- }
- }
-
-
- if(ok) {
- BLI_addtail(&ivbase, iv);
- md+= skipdata;
- count+= skipdata;
- }
- else MEM_freeN(iv);
-
- }
- md++;
- count++;
- }
-
- /* join nodes */
- iv= ivbase.first;
-
- while(iv) {
- ivn= iv->next;
-
- if( strncmp(iv->nodename, "Indexed", 7)==0) {
- /* seek back: same name? */
-
- ivp= iv->prev;
- while(ivp) {
- if(strcmp(iv->nodename, ivp->nodename)==0) break;
-
- if(strcmp(ivp->nodename, "Coordinate3")==0 ||
- strcmp(ivp->nodename, "Coordinate4")==0 ||
- strcmp(ivp->nodename, "VertexProperty")==0) {
- ivp= 0;
- break;
- }
- ivp= ivp->prev;
- }
-
- if(ivp) {
- /* add iv to ivp */
-
- tot= iv->datalen[0] + ivp->datalen[0];
- if(tot) {
- data= MEM_mallocN(tot*sizeof(float), "samenvoeg iv");
- memcpy(data, ivp->data[0], sizeof(float)*ivp->datalen[0]);
- memcpy(data+ivp->datalen[0], iv->data[0], sizeof(float)*iv->datalen[0]);
-
- ivp->datalen[0]+= iv->datalen[0];
- MEM_freeN(ivp->data[0]);
- ivp->data[0]= data;
-
- BLI_remlink(&ivbase, iv);
- MEM_freeN(iv->data[0]);
- MEM_freeN(iv);
- }
- }
- }
-
- iv= ivn;
- }
-
-
- /* convert Nodes to DispLists */
- iv= ivbase.first;
- while(iv) {
-
- /* printf(" Node: %s\n", iv->nodename); */
- /* if(iv->fieldname[0]) printf(" Field: %s len %d\n", iv->fieldname[0], iv->datalen[0]); */
- coordtype= 3;
-
- if( strcmp(iv->nodename, "IndexedLineSet")==0 ) {
-
- colnr= iv_colornumber(iv);
-
- /* seek back to data */
- ivp= iv;
- while(ivp->prev) {
- ivp= ivp->prev;
- if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
- coordtype= 3;
- break;
- }
- if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
- coordtype= 4;
- break;
- }
- }
- if(ivp) {
-
- /* count the nr of lines */
- tot= 0;
- index= iv->data[0];
- lll = iv->datalen[0]-1;
- for(a=0; a<lll; a++) {
- if(index[0]!= -1 && index[1]!= -1) tot++;
- index++;
- }
-
- tot*= 2; /* nr of vertices */
- dl= MEM_callocN(sizeof(struct DispList)+tot*3*sizeof(float), "leesInventor1");
- BLI_addtail(listb, dl);
- dl->type= DL_SEGM;
- dl->nr= 2;
- dl->parts= tot/2;
- dl->col= colnr;
- data= (float *)(dl+1);
-
- index= iv->data[0];
- for(a=0; a<lll; a++) {
- if(index[0]!= -1 && index[1]!= -1) {
- read_iv_index(data, ivp->data[0], index, 2, coordtype);
- data+= 6;
- }
- index++;
- }
- }
- }
- else if( strcmp(iv->nodename, "FaceSet")==0 ) {
-
- colnr= iv_colornumber(iv);
-
- /* seek back to data */
- ivp= iv;
- while(ivp->prev) {
- ivp= ivp->prev;
- if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
- coordtype= 3;
- break;
- }
- if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
- coordtype= 4;
- break;
- }
- }
-
- if(ivp) {
- /* count triangles */
- tot= 0;
-
- index= iv->data[0];
- polytype= (int) index[0];
-
- for(a=0; a<iv->datalen[0]; a++) {
- if(index[0]== polytype) tot++; /* one kind? */
- index++;
- }
-
-
- tot*= polytype; /* nr of vertices */
- dl= MEM_callocN(sizeof(struct DispList)+tot*3*sizeof(float), "leesInventor4");
- BLI_addtail(listb, dl);
- dl->type= DL_POLY;
- dl->nr= polytype;
- dl->parts= tot/polytype;
- dl->col= colnr;
- data= (float *)(dl+1);
-
- index= ivp->data[0];
- first= 1;
- for(a=0; a<iv->datalen[0]; a++) {
-
- VECCOPY(data, index);
- data+= 3;
- index+= 3;
-
- VECCOPY(data, index);
- data+= 3;
- index+= 3;
-
- VECCOPY(data, index);
- data+= 3;
- index+= 3;
-
- if(polytype==4) {
- VECCOPY(data, index);
- data+= 3;
- index+= 3;
- }
- }
- }
- }
- else if( strcmp(iv->nodename, "TriangleStripSet")==0 ) {
-
- colnr= iv_colornumber(iv);
-
- /* seek back to data */
- ivp= iv;
- while(ivp->prev) {
- ivp= ivp->prev;
- if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
- coordtype= 3;
- break;
- }
- if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
- coordtype= 4;
- break;
- }
- }
-
- if(ivp) {
- /* count triangles */
- tot= 0;
- face= 0;
-
- index= iv->data[0]; /* strip size */
-
- for(a=0; a<iv->datalen[0]; a++) {
- tot+= (int) index[0];
- face+= ((int) index[0]) - 2;
- index++;
- }
-
- dl= MEM_callocN(sizeof(struct DispList), "leesInventor4");
- dl->verts= MEM_callocN( tot*3*sizeof(float), "dl verts");
- dl->index= MEM_callocN( face*3*sizeof(int), "dl index");
-
- dl->type= DL_INDEX3;
- dl->nr= tot;
- dl->parts= face;
-
- BLI_addtail(listb, dl);
- dl->col= colnr;
-
- index= iv->data[0]; /* strip size */
- fp= ivp->data[0]; /* vertices */
- data= dl->verts;
- idata= dl->index;
- first= 0;
-
- for(a=0; a<iv->datalen[0]; a++) {
-
- /* vertices */
- for(b=0; b<index[0]; b++) {
- VECCOPY(data, fp);
- data+= 3;
- fp+= coordtype;
- }
-
- /* indices */
- lll = index[0] - 2;
- for(b=0; b<lll; b++) {
- idata[0]= first;
- idata[1]= first+1;
- idata[2]= first+2;
- first++;
- idata+= 3;
- }
- first+= 2;
-
- index++;
- }
- }
- }
- else if( strcmp(iv->nodename, "IndexedFaceSet")==0 ) {
-
- colnr= iv_colornumber(iv);
-
- /* seek back to data */
- ivp= iv;
- while(ivp->prev) {
- ivp= ivp->prev;
- if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
- coordtype= 3;
- break;
- }
- if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
- coordtype= 4;
- break;
- }
- }
- if(ivp) {
-
- /* count triangles */
- face= 0;
- index= iv->data[0];
- lll = iv->datalen[0]-2;
- for(a=0; a<lll; a++) {
- if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) face++;
- index++;
- }
-
- /*number of vertices */
- tot= ivp->datalen[0]/coordtype;
-
- if(tot) {
- dl= MEM_callocN(sizeof(struct DispList), "leesInventor5");
- BLI_addtail(listb, dl);
- dl->type= DL_INDEX3;
- dl->nr= tot;
- dl->parts= face;
- dl->col= colnr;
-
- dl->verts= MEM_callocN( tot*3*sizeof(float), "dl verts");
- dl->index= MEM_callocN(sizeof(int)*3*face, "dl index");
-
- /* vertices */
- fp= ivp->data[0];
- data= dl->verts;
- for(b=tot; b>0; b--) {
- VECCOPY(data, fp);
- data+= 3;
- fp+= coordtype;
- }
-
- /* indices */
- index= iv->data[0];
- idata= dl->index;
- first= 1;
- lll=iv->datalen[0]-2;
- for(a=0; a<lll; a++) {
-
- if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) {
-
- /* this trick is to fill poly's with more than 3 vertices correctly */
- if(first) {
- nr= (int) index[0];
- first= 0;
- }
- idata[0]= nr;
- idata[1]= (int) index[1];
- idata[2]= (int) index[2];
- idata+= 3;
- }
- else first= 1;
-
- index++;
- }
- }
- }
- }
- else if( strcmp(iv->nodename, "IndexedTriangleMesh")==0 ||
- strcmp(iv->nodename, "IndexedTriangleStripSet")==0 ) {
-
- colnr= iv_colornumber(iv);
-
- /* seek back to data */
- ivp= iv;
- while(ivp->prev) {
- ivp= ivp->prev;
- if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
- coordtype= 3;
- break;
- }
- if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
- coordtype= 4;
- break;
- }
- }
- if(ivp) {
-
- /* count triangles */
- face= 0;
- index= iv->data[0];
- lll=iv->datalen[0]-2;
- for(a=0; a<lll; a++) {
- if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) face++;
- index++;
- }
-
- /* nr of vertices */
- tot= ivp->datalen[0]/coordtype;
-
- dl= MEM_callocN(sizeof(struct DispList), "leesInventor6");
- BLI_addtail(listb, dl);
- dl->type= DL_INDEX3;
- dl->nr= tot;
- dl->parts= face;
- dl->col= colnr;
-
- dl->verts= MEM_callocN( tot*3*sizeof(float), "dl verts");
- dl->index= MEM_callocN(sizeof(int)*3*face, "dl index");
-
- /* vertices */
- fp= ivp->data[0];
- data= dl->verts;
- for(b=tot; b>0; b--) {
- VECCOPY(data, fp);
- data+= 3;
- fp+= coordtype;
- }
-
- /* indices */
- index= iv->data[0];
- idata= dl->index;
-
- lll=iv->datalen[0]-2;
- for(a=lll; a>0; a--) {
-
- if(index[0]!= -1 && index[1]!= -1 && index[2]!= -1) {
- idata[0]= (int) index[0];
- idata[1]= (int) index[1];
- idata[2]= (int) index[2];
- idata+= 3;
- }
- index++;
- }
- }
- }
- else if( strcmp(iv->nodename, "QuadMesh")==0 ) {
-
- colnr= iv_colornumber(iv);
-
- /* seek back to data */
- ivp= iv;
- while(ivp->prev) {
- ivp= ivp->prev;
- if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
- coordtype= 3;
- break;
- }
- if( strcmp(ivp->nodename, "VertexProperty")==0 ) {
- coordtype= 3;
- break;
- }
- if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
- coordtype= 4;
- break;
- }
- }
-
- if(ivp) {
- tot= (int) (floor(*(iv->data[0])+0.5) * floor(*(iv->data[1])+0.5));
-
- if(tot>0) {
- dl= MEM_callocN(sizeof(struct DispList)+tot*3*sizeof(float), "leesInventor8");
- BLI_addtail(listb, dl);
- dl->type= DL_SURF;
- dl->parts= (int) floor(*(iv->data[0])+0.5);
- dl->nr= (int) floor(*(iv->data[1])+0.5);
- dl->col= colnr;
- data= (float *)(dl+1);
- memcpy(data, ivp->data[0], tot*3*sizeof(float));
- }
- }
- }
- else if(strcmp(iv->nodename, "IndexedNurbsSurface")==0 || strcmp(iv->nodename, "NurbsSurface")==0) {
-
- colnr= iv_colornumber(iv);
-
- /* sek back to data */
- ivp= iv;
- while(ivp->prev) {
- ivp= ivp->prev;
- if( strcmp(ivp->nodename, "Coordinate3")==0 ) {
- coordtype= 3;
- break;
- }
- if( strcmp(ivp->nodename, "Coordinate4")==0 ) {
- coordtype= 4;
- break;
- }
- }
- if(ivp) {
- a= (int) *(iv->data[0]);
- b= (int) *(iv->data[1]);
-
- tot= a*b;
-
- if( (a>=4 || b>=4) && tot>6) {
- Object *ob;
- Curve *cu;
- Nurb *nu;
- BPoint *bp;
-
- if(ivsurf==0) {
- ob= add_object(scene, OB_SURF);
- ivsurf= ob;
- }
- else ob= ivsurf;
- cu= ob->data;
- nu = (Nurb*) MEM_callocN(sizeof(Nurb),"addNurbprim") ;
- BLI_addtail(&cu->nurb, nu);
- nu->type= CU_NURBS;
-
- nu->pntsu= a;
- nu->pntsv= b;
- nu->resolu= 2*a;
- nu->resolv= 2*b;
-
- nu->flagu= 0;
- nu->flagv= 0;
-
- nu->bp = bp =
- (BPoint*)MEM_callocN(tot * sizeof(BPoint), "addNurbprim3");
- a= tot;
- data= ivp->data[0];
- while(a--) {
- VECCOPY(bp->vec, data);
- if(coordtype==4) {
- bp->vec[3]= data[3];
- mul_v3_fl(bp->vec, 1.0f/data[3]);
- }
- else bp->vec[3]= 1.0;
- data+= coordtype;
- bp++;
- }
-
- /* iv->datalen[2] / [3] is number of knots */
- nu->orderu= iv->datalen[2] - nu->pntsu;
- nu->orderv= iv->datalen[3] - nu->pntsv;
-
- nu->knotsu= MEM_mallocN( sizeof(float)*(iv->datalen[2]), "knots");
- memcpy(nu->knotsu, iv->data[2], sizeof(float)*(iv->datalen[2]));
- nu->knotsv= MEM_mallocN( sizeof(float)*(iv->datalen[3]), "knots");
- memcpy(nu->knotsv, iv->data[3], sizeof(float)*(iv->datalen[3]));
-
- switchdirectionNurb(nu);
-
- }
- else {
- dl= MEM_callocN(sizeof(struct DispList)+tot*3*sizeof(float), "leesInventor3");
- BLI_addtail(listb, dl);
- dl->type= DL_SURF;
- dl->nr= (int) *(iv->data[0]);
- dl->parts= (int) *(iv->data[1]);
- dl->col= colnr;
- data= (float *)(dl+1);
-
- a= tot;
- fp= ivp->data[0];
- while(a--) {
- VECCOPY(data, fp);
- fp+= coordtype;
- data+= 3;
- }
- }
- }
- }
- iv= iv->next;
- }
-
- /* free */
- iv= ivbase.first;
- while(iv) {
- for(a=0; a<IV_MAXFIELD; a++) {
- if(iv->data[a]) MEM_freeN(iv->data[a]);
- }
- iv= iv->next;
- }
-
- BLI_freelistN(&ivbase);
- MEM_freeN(maindata);
- MEM_freeN(iv_data_stack);
-
-}
-
/* ************************************************************ */
-static void displist_to_mesh(Scene *scene, DispList *dlfirst)
-{
- Object *ob;
- Mesh *me;
- Material *ma;
- DispList *dl;
- MVert *mvert;
- MFace *mface;
- float *data, vec[3], min[3], max[3];
- int a, b, startve, *idata, totedge=0, tottria=0, totquad=0, totvert=0, totface, totcol=0, colnr;
- int p1, p2, p3, p4;
- unsigned int maxvertidx;
-
- /* count first */
- INIT_MINMAX(min, max);
-
- dl= dlfirst;
- while(dl) {
-
- /* PATCH 1 (polyfill) can't be done, there's no listbase here. do that first! */
- /* PATCH 2 */
- if(dl->type==DL_SEGM && dl->nr>2) {
- data= (float *)(dl+1);
- if(data[0]==data[3*(dl->nr-1)]) {
- if(data[1]==data[3*(dl->nr-1)+1]) {
- if(data[2]==data[3*(dl->nr-1)+2]) {
- dl->type= DL_POLY;
- dl->nr--;
- }
- }
- }
- }
-
- /* colors */
- if(dl->col > totcol) totcol= dl->col;
-
- /* size and count */
- if(dl->type==DL_SURF) {
- a= dl->nr;
- b= dl->parts;
- if(dl->flag & DL_CYCL_U) a++;
- if(dl->flag & DL_CYCL_V) b++;
-
- totquad+= a*b;
-
- totvert+= dl->nr*dl->parts;
-
- data= (float *)(dl+1);
- for(a= dl->nr*dl->parts; a>0; a--) {
- DO_MINMAX(data, min, max);
- data+= 3;
- }
- }
- else if(dl->type==DL_POLY) {
- if(dl->nr==3 || dl->nr==4) {
- if(dl->nr==3) tottria+= dl->parts;
- else totquad+= dl->parts;
-
- totvert+= dl->nr*dl->parts;
-
- data= (float *)(dl+1);
- for(a= dl->nr*dl->parts; a>0; a--) {
- DO_MINMAX(data, min, max);
- data+= 3;
- }
- }
- else if(dl->nr>4) {
-
- tottria+= dl->nr*dl->parts;
- totvert+= dl->nr*dl->parts;
-
- data= (float *)(dl+1);
- for(a= dl->nr*dl->parts; a>0; a--) {
- DO_MINMAX(data, min, max);
- data+= 3;
- }
-
- }
- }
- else if(dl->type==DL_INDEX3) {
- tottria+= dl->parts;
- totvert+= dl->nr;
-
- data= dl->verts;
- for(a= dl->nr; a>0; a--) {
- DO_MINMAX(data, min, max);
- data+= 3;
- }
- }
- else if(dl->type==DL_SEGM) {
-
- tottria+= (dl->nr-1)*dl->parts;
- totvert+= dl->nr*dl->parts;
-
- data= (float *)(dl+1);
- for(a= dl->nr*dl->parts; a>0; a--) {
- DO_MINMAX(data, min, max);
- data+= 3;
- }
- }
-
- dl= dl->next;
- }
-
- if(totvert==0) {
- return;
- }
-
- vec[0]= (min[0]+max[0])/2;
- vec[1]= (min[1]+max[1])/2;
- vec[2]= (min[2]+max[2])/2;
-
- ob= add_object(scene, OB_MESH);
- VECCOPY(ob->loc, vec);
- where_is_object(scene, ob);
-
- me= ob->data;
-
- /* colors */
- if(totcol) {
- ob->mat= MEM_callocN(sizeof(void *)*totcol, "ob->mat");
- ob->matbits= MEM_callocN(sizeof(char)*totcol, "ob->matbits");
- me->mat= MEM_callocN(sizeof(void *)*totcol, "me->mat");
- me->totcol= totcol;
- ob->totcol= (unsigned char) me->totcol;
- ob->actcol= 1;
- }
-
- /* materials */
- for(a=0; a<totcol; a++) {
- ma= G.main->mat.first;
- while(ma) {
- if(ma->mtex[0]==0) {
- if(ivcolors[a][0]==ma->r && ivcolors[a][1]==ma->g && ivcolors[a][2]==ma->b) {
- me->mat[a]= ma;
- ma->id.us++;
- break;
- }
- }
- ma= ma->id.next;
- }
- if(ma==0) {
- ma= add_material("ext");
- me->mat[a]= ma;
- ma->r= ivcolors[a][0];
- ma->g= ivcolors[a][1];
- ma->b= ivcolors[a][2];
- automatname(ma);
- }
- }
-
- totface= totquad+tottria+totedge;
-
- printf("Import: %d vertices %d faces\n", totvert, totface);
-
- me->totvert= totvert;
- me->totface= totface;
- me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC,
- NULL, me->totvert);
- me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC,
- NULL, me->totface);
- maxvertidx= totvert-1;
-
- mvert= me->mvert;
- mface= me->mface;
-
- startve= 0;
-
- dl= dlfirst;
- while(dl) {
-
- colnr= dl->col;
- if(colnr) colnr--;
-
- if(dl->type==DL_SURF) {
- data= (float *)(dl+1);
-
- for(a=dl->parts*dl->nr; a>0; a--) {
- mvert->co[0]= data[0] -vec[0];
- mvert->co[1]= data[1] -vec[1];
- mvert->co[2]= data[2] -vec[2];
-
- data+=3;
- mvert++;
- }
-
- for(a=0; a<dl->parts; a++) {
-
- if (surfindex_displist(dl, a, &b, &p1, &p2, &p3, &p4)==0)
- break;
-
- p1+= startve;
- p2+= startve;
- p3+= startve;
- p4+= startve;
-
- for(; b<dl->nr; b++) {
-
- mface->v1= p1;
- mface->v2= p2;
- mface->v3= p4;
- mface->v4= p3;
-
- mface->mat_nr= colnr;
- test_index_face(mface, NULL, 0, 4);
-
- mface++;
-
- p4= p3;
- p3++;
- p2= p1;
- p1++;
- }
- }
-
- startve += dl->parts*dl->nr;
-
- }
- else if(dl->type==DL_POLY) {
-
- if(dl->nr==3 || dl->nr==4) {
- data= (float *)(dl+1);
-
- for(a=dl->parts*dl->nr; a>0; a--) {
- mvert->co[0]= data[0] -vec[0];
- mvert->co[1]= data[1] -vec[1];
- mvert->co[2]= data[2] -vec[2];
- data+=3;
- mvert++;
- }
-
- for(a=0; a<dl->parts; a++) {
- if(dl->nr==3) {
- mface->v1= startve+a*dl->nr;
- mface->v2= startve+a*dl->nr+1;
- mface->v3= startve+a*dl->nr+2;
- mface->mat_nr= colnr;
- test_index_face(mface, NULL, 0, 3);
- mface++;
- }
- else {
- mface->v1= startve+a*dl->nr;
- mface->v2= startve+a*dl->nr+1;
- mface->v3= startve+a*dl->nr+2;
- mface->v4= startve+a*dl->nr+3;
- mface->mat_nr= colnr;
- test_index_face(mface, NULL, 0, 4);
- mface++;
- }
- }
- startve += dl->parts*dl->nr;
- }
- else if(dl->nr>4) {
- data= (float *)(dl+1);
-
- for(a=dl->parts*dl->nr; a>0; a--) {
- mvert->co[0]= data[0] -vec[0];
- mvert->co[1]= data[1] -vec[1];
- mvert->co[2]= data[2] -vec[2];
-
- data+=3;
- mvert++;
- }
-
- for(b=0; b<dl->parts; b++) {
- for(a=0; a<dl->nr; a++) {
- mface->v1= startve+a;
-
- if(a==dl->nr-1) mface->v2= startve;
- else mface->v2= startve+a+1;
-
- mface->mat_nr= colnr;
-
- mface++;
- }
- startve += dl->nr;
- }
- }
- }
- else if(dl->type==DL_INDEX3) {
- data= dl->verts;
-
- for(a=dl->nr; a>0; a--) {
- mvert->co[0]= data[0] -vec[0];
- mvert->co[1]= data[1] -vec[1];
- mvert->co[2]= data[2] -vec[2];
- data+=3;
- mvert++;
- }
-
- idata= dl->index;
- for(b=dl->parts; b>0; b--) {
- mface->v1= startve+idata[0];
- mface->v2= startve+idata[1];
- mface->v3= startve+idata[2];
- mface->mat_nr= colnr;
-
- if (mface->v1>maxvertidx) mface->v1= maxvertidx;
- if (mface->v2>maxvertidx) mface->v2= maxvertidx;
- if (mface->v3>maxvertidx) mface->v3= maxvertidx;
-
- test_index_face(mface, NULL, 0, 3);
- mface++;
- idata+= 3;
- }
- startve += dl->nr;
- }
- else if(dl->type==DL_SEGM) {
- data= (float *)(dl+1);
-
- for(a=dl->parts*dl->nr; a>0; a--) {
- mvert->co[0]= data[0] -vec[0];
- mvert->co[1]= data[1] -vec[1];
- mvert->co[2]= data[2] -vec[2];
- data+=3;
- mvert++;
- }
-
- for(b=0; b<dl->parts; b++) {
- for(a=0; a<dl->nr-1; a++) {
- mface->v1= startve+a;
- mface->v2= startve+a+1;
- mface->mat_nr= colnr;
- mface++;
- }
- startve += dl->nr;
- }
- }
- dl= dl->next;
- }
-
- mesh_add_normals_flags(me);
- make_edges(me, 0);
-}
-
-static void displist_to_objects(Scene *scene, ListBase *lbase)
-{
- DispList *dl, *first, *prev, *next;
- ListBase tempbase;
- int maxaantal, curcol, totvert=0, vert;
-
- /* irst this: is still active */
- if(ivsurf) {
- where_is_object(scene, ivsurf);
-// XXX docenter_new();
- }
-
- dl= lbase->first;
- while(dl) {
- next= dl->next;
-
- /* PATCH 1: polyfill */
- if(dl->type==DL_POLY && dl->nr>4) {
- /* solution: put them together in separate listbase */
- ;
- }
- /* PATCH 2: poly's of 2 points */
- if(dl->type==DL_POLY && dl->nr==2) dl->type= DL_SEGM;
-
- dl= next;
- }
-
- /* count vertices */
-
- dl= lbase->first;
- while(dl) {
-
- if(dl->type==DL_SURF) totvert+= dl->nr*dl->parts;
- else if(dl->type==DL_POLY) {
- if(dl->nr==3 || dl->nr==4) totvert+= dl->nr*dl->parts;
- else if(dl->nr>4) totvert+= dl->nr*dl->parts;
- }
- else if(dl->type==DL_INDEX3) totvert+= dl->nr;
- else if(dl->type==DL_SEGM) totvert+= dl->nr*dl->parts;
-
- dl= dl->next;
- }
-
- if(totvert==0) {
-
- if(ivsurf==0) {}; //XXX error("Found no data");
- if(lbase->first) BLI_freelistN(lbase);
-
- return;
- }
-
- maxaantal= 32000;
-
- if(totvert>maxaantal) {
-
- /* try to put colors together */
- curcol= 0;
- tempbase.first= tempbase.last= 0;
-
- while(lbase->first) {
- dl= lbase->first;
- while(dl) {
- next= dl->next;
- if(dl->col==curcol) {
- BLI_remlink(lbase, dl);
- BLI_addtail(&tempbase, dl);
- dl->col= 0;
- }
-
- dl= next;
- }
-
- /* in tempbase are all 'curcol' */
- totvert= 0;
- dl= first= tempbase.first;
- while(dl) {
- vert= 0;
-
- if(dl->type==DL_SURF) vert= dl->nr*dl->parts;
- else if(dl->type==DL_POLY) {
- if(dl->nr==3 || dl->nr==4) vert= dl->nr*dl->parts;
- else if(dl->nr>4) vert= dl->nr*dl->parts;
- }
- else if(dl->type==DL_INDEX3) totvert+= dl->nr;
- else if(dl->type==DL_SEGM) vert= dl->nr*dl->parts;
-
- totvert+= vert;
- if(totvert > maxaantal || dl->next==0) {
- if(dl->next==0) {
- displist_to_mesh(scene, first);
- }
- else if(dl->prev) {
- prev= dl->prev;
- prev->next= 0;
- displist_to_mesh(scene, first);
- prev->next= dl;
- first= dl;
- totvert= 0;
- }
- }
-
- dl= dl->next;
- }
-
- freedisplist(&tempbase);
-
- curcol++;
- }
- }
- else displist_to_mesh(scene, lbase->first);
-
- freedisplist(lbase);
-
-}
-
int BKE_read_exotic(Scene *scene, char *name)
{
- ListBase lbase={0, 0};
int len;
gzFile gzfile;
char str[32];
@@ -1793,21 +477,7 @@ int BKE_read_exotic(Scene *scene, char *name)
if ((*s0 != FORM) && (strncmp(str, "BLEN", 4) != 0) && !BLI_testextensie(name,".blend.gz")) {
//XXX waitcursor(1);
- if(strncmp(str, "#Inventor V1.0", 14)==0) {
- if( strncmp(str+15, "ascii", 5)==0) {
- read_inventor(scene, name, &lbase);
- displist_to_objects(scene, &lbase);
- retval = 1;
- } else {
- //XXX error("Can only read Inventor 1.0 ascii");
- }
- }
- else if((strncmp(str, "#VRML V1.0 asc", 14)==0)) {
- read_inventor(scene, name, &lbase);
- displist_to_objects(scene, &lbase);
- retval = 1;
- }
- else if(is_dxf(name)) {
+ if(is_dxf(name)) {
dxf_read(scene, name);
retval = 1;
}
@@ -1907,15 +577,8 @@ void write_stl(Scene *scene, char *str)
FILE *fpSTL;
int numfacets = 0;
ReportList *reports= NULL; /* XXX */
-
- if(BLI_testextensie(str,".blend")) str[ strlen(str)-6]= 0;
- if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
- if(BLI_testextensie(str,".stl")==0) strcat(str, ".stl");
- if (BLI_exists(str)) {
- ; //XXX if(saveover(str)==0)
- //XXX return;
- }
+ /* XXX, operator needs to manage filename extension */
fpSTL= fopen(str, "wb");
@@ -1965,7 +628,6 @@ void write_stl(Scene *scene, char *str)
//XXX waitcursor(0);
}
-/* ******************************* WRITE VRML ***************************** */
static void replace_chars(char *str1, char *str2)
{
@@ -1978,354 +640,6 @@ static void replace_chars(char *str1, char *str2)
}
}
-
-static void write_material_vrml(FILE *fp, Material *ma)
-{
- char str[32];
-
- replace_chars(str, ma->id.name+2);
-
- fprintf(fp, "\tDEF %s\n", str);
- fprintf(fp, "\tMaterial {\n");
-
- fprintf(fp, "\t\tdiffuseColor %f %f %f\n", ma->r, ma->g, ma->b);
- fprintf(fp, "\t\tspecularColor %f %f %f\n", ma->specr, ma->specg, ma->specb);
- fprintf(fp, "\t\tshininess %f \n", ((float)ma->har)/100.0);
- fprintf(fp, "\t\ttransparency %f \n", 1.0-ma->alpha);
-
- fprintf(fp, "\t}\n");
-
-}
-
-unsigned int *mcol_to_vcol(Mesh *me)
-{
- MFace *mface;
- unsigned int *mcol, *mcoln, *mcolmain;
- int a;
-
- if(me->totface==0 || me->mcol==0) return 0;
-
- mcoln= mcolmain= MEM_mallocN(sizeof(int)*me->totvert, "mcoln");
- mcol = (unsigned int *)me->mcol;
- mface= me->mface;
-
- for(a=me->totface; a>0; a--, mface++) {
- mcoln[mface->v1]= mcol[0];
- mcoln[mface->v2]= mcol[1];
- mcoln[mface->v3]= mcol[2];
- if(mface->v4) mcoln[mface->v4]= mcol[3];
-
- mcol+= 4;
- }
-
- return mcolmain;
-}
-
-void mcol_to_rgba(unsigned int col, float *r, float *g, float *b, float *a)
-{
- char *cp;
-
- cp = (char *)&col;
-
- *r= cp[3];
- *r /= 255.0;
-
- *g= cp[2];
- *g /= 255.0;
-
- *b= cp[1];
- *b /= 255.0;
-
- *a= cp[0];
- *a /= 255.0;
-}
-
-static void write_mesh_vrml(FILE *fp, Mesh *me)
-{
- Material *ma;
- MVert *mvert;
- MFace *mface;
- MTFace *tface;
- Image *ima;
- int a, b, totcol, texind;
- char str[32];
-
- replace_chars(str, me->id.name+2);
-
- fprintf(fp, "\tDEF %s\n", str);
- fprintf(fp, "\tSeparator {\n");
-
- if(me->mtface) {
- ima= ((MTFace *)me->mtface)->tpage;
- if(ima) {
- fprintf(fp, "\t\tTexture2 {\n");
- fprintf(fp, "\t\t\tfilename %s\n", ima->name);
- fprintf(fp, "\t\t\twrapS REPEAT \n");
- fprintf(fp, "\t\t\twrapT REPEAT \n");
- fprintf(fp, "\t\t}\n");
- }
- }
-
- if(me->mcol) {
- unsigned int *mcol, *mcolmain;
- float r, g, b, cola;
-
- fprintf(fp, "\t\tMaterial {\n");
- fprintf(fp, "\t\t\tdiffuseColor [\n");
-
- a= me->totvert;
- mcol= mcolmain= mcol_to_vcol(me);
- if(mcol) {
- while(a--) {
- mcol_to_rgba(*mcol, &r, &g, &b, &cola);
- fprintf(fp, "\t\t\t\t %f %f %f,\n", r, g, b);
- mcol++;
- }
- MEM_freeN(mcolmain);
- }
- fprintf(fp, "\t\t\t]\n");
- fprintf(fp, "\t\t}\n");
-
- fprintf(fp, "\t\tMaterialBinding { value PER_VERTEX_INDEXED }\n");
- }
-
-
- fprintf(fp, "\t\tCoordinate3 {\n");
- fprintf(fp, "\t\t\tpoint [\n");
-
- a= me->totvert;
- mvert= me->mvert;
- while(a--) {
- fprintf(fp, "\t\t\t\t %f %f %f,\n", mvert->co[0], mvert->co[1], mvert->co[2]);
- mvert++;
- }
- fprintf(fp, "\t\t\t]\n");
- fprintf(fp, "\t\t}\n");
-
-
- totcol= me->totcol;
- if(totcol==0) totcol= 1;
- texind= 0; // index for uv coords
-
- for(b=0; b<totcol; b++) {
-
- if(me->mcol==0) {
- if(me->mat) {
- ma= me->mat[b];
- if(ma) {
- replace_chars(str, ma->id.name+2);
-
- fprintf(fp, "\t\tUSE %s\n\n", str);
- }
- }
- }
-
- if(me->mtface) {
- fprintf(fp, "\t\tTextureCoordinate2 {\n");
- fprintf(fp, "\t\t\tpoint [\n");
-
- a= me->totface;
- mface= me->mface;
- tface= me->mtface;
- while(a--) {
- if(mface->mat_nr==b) {
- fprintf(fp, "\t\t\t\t %f %f,\n", tface->uv[0][0], tface->uv[0][1]);
- fprintf(fp, "\t\t\t\t %f %f,\n", tface->uv[1][0], tface->uv[1][1]);
- fprintf(fp, "\t\t\t\t %f %f,\n", tface->uv[2][0], tface->uv[2][1]);
- if(mface->v4) fprintf(fp, "\t\t\t\t %f %f,\n", tface->uv[3][0], tface->uv[3][1]);
- }
- mface++;
- tface++;
- }
- fprintf(fp, "\t\t\t]\n");
- fprintf(fp, "\t\t}\n");
- }
-
- fprintf(fp, "\t\tIndexedFaceSet {\n");
- fprintf(fp, "\t\t\tcoordIndex [\n");
-
- a= me->totface;
- mface= me->mface;
- while(a--) {
- if(mface->mat_nr==b) {
- if(mface->v4) fprintf(fp, "\t\t\t\t %d, %d, %d, %d, -1,\n", mface->v1, mface->v2, mface->v3, mface->v4);
- else fprintf(fp, "\t\t\t\t %d, %d, %d, -1,\n", mface->v1, mface->v2, mface->v3);
- }
- mface++;
- }
- fprintf(fp, "\t\t\t]\n");
-
- if(me->mtface) {
- fprintf(fp, "\t\t\ttextureCoordIndex [\n");
-
- a= me->totface;
- mface= me->mface;
- while(a--) {
- if(mface->mat_nr==b) {
- if(mface->v4) {
- fprintf(fp, "\t\t\t\t %d, %d, %d, %d, -1,\n", texind, texind+1, texind+2, texind+3);
- texind+= 4;
- }
- else {
- fprintf(fp, "\t\t\t\t %d, %d, %d, -1,\n", texind, texind+1, texind+2);
- texind+= 3;
- }
- }
- mface++;
- }
- fprintf(fp, "\t\t\t]\n");
- }
- fprintf(fp, "\t\t}\n");
- }
-
- fprintf(fp, "\t}\n");
-}
-
-static void write_camera_vrml(FILE *fp, Object *ob)
-{
- Camera *cam;
-
- if(ob==0) return;
- invert_m4_m4(ob->imat, ob->obmat);
-
- fprintf(fp, "\tMatrixTransform {\n");
-
- fprintf(fp, "\tmatrix \n");
-
- fprintf(fp, "\t\t%f %f %f %f\n", ob->imat[0][0], ob->imat[0][1], ob->imat[0][2], ob->imat[0][3]);
- fprintf(fp, "\t\t%f %f %f %f\n", ob->imat[1][0], ob->imat[1][1], ob->imat[1][2], ob->imat[1][3]);
- fprintf(fp, "\t\t%f %f %f %f\n", ob->imat[2][0], ob->imat[2][1], ob->imat[2][2], ob->imat[2][3]);
- fprintf(fp, "\t\t%f %f %f %f\n", ob->imat[3][0], ob->imat[3][1], ob->imat[3][2], ob->imat[3][3]);
-
- fprintf(fp, "\t}\n");
-
- cam= ob->data;
-
- fprintf(fp, "\tPerspectiveCamera {\n");
- fprintf(fp, "\t\tfocalDistance %f\n", cam->lens/10.0);
-
- fprintf(fp, "\t}\n");
-
-}
-
-static void write_object_vrml(FILE *fp, Object *ob)
-{
- ID *id;
- char str[32];
-
- fprintf(fp, "\tSeparator {\n");
- fprintf(fp, "\t\tMatrixTransform {\n");
-
- fprintf(fp, "\t\tmatrix \n");
-
- fprintf(fp, "\t\t\t%f %f %f %f\n", ob->obmat[0][0], ob->obmat[0][1], ob->obmat[0][2], ob->obmat[0][3]);
- fprintf(fp, "\t\t\t%f %f %f %f\n", ob->obmat[1][0], ob->obmat[1][1], ob->obmat[1][2], ob->obmat[1][3]);
- fprintf(fp, "\t\t\t%f %f %f %f\n", ob->obmat[2][0], ob->obmat[2][1], ob->obmat[2][2], ob->obmat[2][3]);
- fprintf(fp, "\t\t\t%f %f %f %f\n", ob->obmat[3][0], ob->obmat[3][1], ob->obmat[3][2], ob->obmat[3][3]);
-
- fprintf(fp, "\t\t}\n");
-
- id= ob->data;
-
- replace_chars(str, id->name+2);
-
- fprintf(fp, "\t\tUSE %s\n", str);
- fprintf(fp, "\t}\n");
-}
-
-
-void write_vrml(Scene *scene, char *str)
-{
- Mesh *me;
- Material *ma;
- Base *base;
- FILE *fp;
-
- if(BLI_testextensie(str,".blend")) str[ strlen(str)-6]= 0;
- if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
- if(BLI_testextensie(str,".wrl")==0) strcat(str, ".wrl");
- //XXX saveover() if(saveover(str)==0) return;
-
- fp= fopen(str, "w");
-
- if(fp==NULL) {
- //XXX error("Can't write file");
- return;
- }
- strcpy(temp_dir, str);
-
- //XXX waitcursor(1);
-
- /* FIRST: write all the datablocks */
-
- fprintf(fp, "#VRML V1.0 ascii\n\n# Blender V%d\n\n# 'Switch' is used as a hack, to ensure it is not part of the drawing\n\n", BLENDER_VERSION);
- fprintf(fp, "Separator {\n");
- fprintf(fp, "Switch {\n");
-
- ma= G.main->mat.first;
- while(ma) {
- if(ma->id.us) {
- write_material_vrml(fp, ma);
- }
- ma= ma->id.next;
- }
-
- /* only write meshes we're using in this scene */
- flag_listbase_ids(&G.main->mesh, LIB_DOIT, 0);
-
- for(base= scene->base.first; base; base= base->next)
- if(base->object->type== OB_MESH)
- ((ID *)base->object->data)->flag |= LIB_DOIT;
-
- me= G.main->mesh.first;
- while(me) {
- if(me->id.flag & LIB_DOIT) { /* is the mesh used in this scene ? */
- write_mesh_vrml(fp, me);
- }
- me= me->id.next;
- }
-
- /* THEN:Hidden Objects */
- fprintf(fp, "\n\t# Hidden Objects, in invisible layers\n\n");
- base= scene->base.first;
- while(base) {
- if(base->object->type== OB_MESH) {
- if( (base->lay & scene->lay)==0 ) {
- write_object_vrml(fp, base->object);
- }
- }
- base= base->next;
- }
-
- fprintf(fp, "}\n");
- fprintf(fp, "\n# Visible Objects\n\n");
- fprintf(fp, "Separator {\n");
-
- /* The camera */
-
- write_camera_vrml(fp, scene->camera);
-
- /* THEN:The Objects */
-
- base= scene->base.first;
- while(base) {
- if(base->object->type== OB_MESH) {
- if(base->lay & scene->lay) {
- write_object_vrml(fp, base->object);
- }
- }
- base= base->next;
- }
-
- fprintf(fp, "}\n");
- fprintf(fp, "}\n");
-
- fclose(fp);
-
- //XXX waitcursor(0);
-}
-
-
/* ******************************* WRITE DXF ***************************** */
#define write_group(id,data) fprintf(fp, "%d\n%s\n", id, data)
@@ -2551,15 +865,7 @@ void write_dxf(struct Scene *scene, char *str)
Base *base;
FILE *fp;
- if(BLI_testextensie(str,".blend")) str[ strlen(str)-6]= 0;
- if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
- if(BLI_testextensie(str,".dxf")==0) strcat(str, ".dxf");
-
-
- if (BLI_exists(str)) {
- ; //XXX if(saveover(str)==0)
- // return;
- }
+ /* XXX, operator needs to handle overwrite & rename */
fp= fopen(str, "w");
diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c
index 04ce6c39694..ef89d39864a 100644
--- a/source/blender/blenkernel/intern/fluidsim.c
+++ b/source/blender/blenkernel/intern/fluidsim.c
@@ -28,6 +28,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#include <stddef.h>
#include "BLI_storage.h" /* _LARGEFILE_SOURCE */
#include "MEM_guardedalloc.h"
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index c0a60ea6294..47627d09b97 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -1146,7 +1146,7 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
return NULL;
}
- if(mode==0) {
+ if(mode == FO_EDIT) {
/* make nurbdata */
unsigned long cha;
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index e77183d785f..cb2261932ce 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -382,7 +382,7 @@ Image *BKE_add_image_file(const char *name, int frame)
return ima;
}
-static ImBuf *add_ibuf_size(int width, int height, char *name, int depth, int floatbuf, short uvtestgrid, float color[4])
+static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, char *name, int depth, int floatbuf, short uvtestgrid, float color[4])
{
ImBuf *ibuf;
unsigned char *rect= NULL;
@@ -415,7 +415,7 @@ static ImBuf *add_ibuf_size(int width, int height, char *name, int depth, int fl
}
/* adds new image block, creates ImBuf and initializes color */
-Image *BKE_add_image_size(int width, int height, char *name, int depth, int floatbuf, short uvtestgrid, float color[4])
+Image *BKE_add_image_size(unsigned int width, unsigned int height, char *name, int depth, int floatbuf, short uvtestgrid, float color[4])
{
/* on save, type is changed to FILE in editsima.c */
Image *ima= image_alloc(name, IMA_SRC_GENERATED, IMA_TYPE_UV_TEST);
@@ -757,9 +757,9 @@ int BKE_imtype_is_movie(int imtype)
return 0;
}
-void BKE_add_image_extension(char *string, int imtype)
+int BKE_add_image_extension(char *string, int imtype)
{
- char *extension="";
+ char *extension= NULL;
if(imtype== R_IRIS) {
if(!BLI_testextensie(string, ".rgb"))
@@ -830,7 +830,12 @@ void BKE_add_image_extension(char *string, int imtype)
extension= ".jpg";
}
- strcat(string, extension);
+ if(extension) {
+ return BLI_replace_extension(string, FILE_MAX, extension);
+ }
+ else {
+ return FALSE;
+ }
}
/* could allow access externally - 512 is for long names, 64 is for id names */
@@ -1772,8 +1777,6 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
else
BLI_path_abs(str, G.sce);
- BLI_path_frame(str, cfra, 0);
-
/* read ibuf */
ibuf = IMB_loadiffname(str, flag);
}
@@ -2017,14 +2020,9 @@ static ImBuf *image_get_ibuf_threadsafe(Image *ima, ImageUser *iuser, int *frame
ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0);
}
else if(ima->source == IMA_SRC_VIEWER) {
- if(ima->type==IMA_TYPE_R_RESULT) {
- /* always verify entirely, not that this shouldn't happen
- * during render anyway */
- }
- else if(ima->type==IMA_TYPE_COMPOSITE) {
- frame= iuser?iuser->framenr:0;
- ibuf= image_get_ibuf(ima, 0, frame);
- }
+ /* always verify entirely, not that this shouldn't happen
+ * as part of texture sampling in rendering anyway, so not
+ * a big bottleneck */
}
*frame_r = frame;
@@ -2141,10 +2139,15 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
BLI_lock_thread(LOCK_VIEWER);
*lock_r= ima;
- /* Composite Viewer, all handled in compositor */
- /* fake ibuf, will be filled in compositor */
- ibuf= IMB_allocImBuf(256, 256, 32, IB_rect, 0);
- image_assign_ibuf(ima, ibuf, 0, frame);
+ frame= iuser?iuser->framenr:0;
+ ibuf= image_get_ibuf(ima, 0, frame);
+
+ if(!ibuf) {
+ /* Composite Viewer, all handled in compositor */
+ /* fake ibuf, will be filled in compositor */
+ ibuf= IMB_allocImBuf(256, 256, 32, IB_rect, 0);
+ image_assign_ibuf(ima, ibuf, 0, frame);
+ }
}
}
}
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 2f8553b06b3..6f1cdefbcad 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -440,7 +440,7 @@ void transform_mesh_orco_verts(Mesh *me, float (*orco)[3], int totvert, int inve
int test_index_face(MFace *mface, CustomData *fdata, int mfindex, int nr)
{
/* first test if the face is legal */
- if(mface->v3 && mface->v3==mface->v4) {
+ if((mface->v3 || nr==4) && mface->v3==mface->v4) {
mface->v4= 0;
nr--;
}
@@ -854,6 +854,7 @@ int nurbs_to_mdata_customdb(Object *ob, ListBase *dispbase, MVert **allvert, int
mface->v2= startvert+index[2];
mface->v3= startvert+index[1];
mface->v4= 0;
+ mface->mat_nr= (unsigned char)dl->col;
test_index_face(mface, NULL, 0, 3);
if(smooth) mface->flag |= ME_SMOOTH;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 4a9f7116755..c5a12d1fb4e 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -509,12 +509,10 @@ void unlink_object(Scene *scene, Object *ob)
}
/* textures */
- tex= bmain->tex.first;
- while(tex) {
- if(tex->env) {
- if(tex->env->object == ob) tex->env->object= NULL;
- }
- tex= tex->id.next;
+ for(tex= bmain->tex.first; tex; tex= tex->id.next) {
+ if(tex->env && (ob==tex->env->object)) tex->env->object= NULL;
+ if(tex->pd && (ob==tex->pd->object)) tex->pd->object= NULL;
+ if(tex->vd && (ob==tex->vd->object)) tex->vd->object= NULL;
}
/* worlds */
@@ -1315,6 +1313,8 @@ Object *copy_object(Object *ob)
obn->gpulamp.first = obn->gpulamp.last = NULL;
obn->pc_ids.first = obn->pc_ids.last = NULL;
+
+ obn->mpath= NULL;
return obn;
}
@@ -1665,11 +1665,29 @@ void object_mat3_to_rot(Object *ob, float mat[][3], int use_compat)
/* see pchan_apply_mat4() for the equivalent 'pchan' function */
void object_apply_mat4(Object *ob, float mat[][4])
{
- float mat3[3][3];
+ float mat3[3][3], tmat[3][3], imat[3][3];
+
+ /* location */
copy_v3_v3(ob->loc, mat[3]);
- mat4_to_size(ob->size, mat);
+
+ /* rotation */
copy_m3_m4(mat3, mat);
object_mat3_to_rot(ob, mat3, 0);
+
+ /* scale */
+#if 0
+ /* works fine except for neg scales */
+ mat4_to_size(ob->size, mat);
+#else
+ /* this is more complicated but works for negative scales */
+ object_rot_to_mat3(ob, tmat);
+ invert_m3_m3(imat, tmat);
+ mul_m3_m3m3(tmat, imat, mat3);
+
+ ob->size[0]= tmat[0][0];
+ ob->size[1]= tmat[1][1];
+ ob->size[2]= tmat[2][2];
+#endif
}
void object_to_mat3(Object *ob, float mat[][3]) /* no parent */
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 07b712c4330..723ff7faed3 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -272,7 +272,7 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys)
}
psmd= psys_get_modifier(ob, psys);
- if(psys->renderdata) {
+ if(psys->renderdata || G.rendering) {
if(!(psmd->modifier.mode & eModifierMode_Render))
return 0;
}
@@ -3686,7 +3686,7 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float
else
VECCOPY(texco,orco);
- externtex(mtex, texco, &value, rgba, rgba+1, rgba+2, rgba+3);
+ externtex(mtex, texco, &value, rgba, rgba+1, rgba+2, rgba+3, 0);
if((event & mtex->pmapto) & MAP_PA_TIME){
if((setvars&MAP_PA_TIME)==0){
ptex->time=0.0;
@@ -3740,7 +3740,7 @@ void psys_get_texture(ParticleSimulationData *sim, Material *ma, ParticleData *p
psys_particle_on_emitter(sim->psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0);
}
- externtex(mtex, texco, &value, rgba, rgba+1, rgba+2, rgba+3);
+ externtex(mtex, texco, &value, rgba, rgba+1, rgba+2, rgba+3, 0);
if((event & mtex->pmapto) & MAP_PA_TIME){
/* the first time has to set the base value for time regardless of blend mode */
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 0d14c3cb9f6..47a220dcefb 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -29,6 +29,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#include <stddef.h>
#include "BLI_storage.h" /* _LARGEFILE_SOURCE */
#include <stdlib.h>
@@ -194,9 +195,11 @@ static void realloc_particles(ParticleSimulationData *sim, int new_totpart)
psys->free_edit = NULL;
}
- newpars= MEM_callocN(totpart*sizeof(ParticleData), "particles");
- if(psys->part->phystype == PART_PHYS_BOIDS)
- newboids= MEM_callocN(totpart*sizeof(BoidParticle), "boid particles");
+ if(totpart) {
+ newpars= MEM_callocN(totpart*sizeof(ParticleData), "particles");
+ if(psys->part->phystype == PART_PHYS_BOIDS)
+ newboids= MEM_callocN(totpart*sizeof(BoidParticle), "boid particles");
+ }
if(psys->particles) {
totsaved=MIN2(psys->totpart,totpart);
@@ -2836,11 +2839,18 @@ void particle_intersect_face(void *userdata, int index, const BVHTreeRay *ray, B
} while(t2);
}
-/* particle - mesh collision code */
-/* in addition to basic point to surface collisions handles friction & damping,*/
-/* angular momentum <-> linear momentum and swept sphere - mesh collisions */
-/* 1. check for all possible deflectors for closest intersection on particle path */
-/* 2. if deflection was found kill the particle or calculate new coordinates */
+/* Particle - Mesh collision code
+ * Features:
+ * - point and swept sphere to mesh surface collisions
+ * - moving colliders (but not yet rotating or deforming colliders)
+ * - friction & damping
+ * - angular momentum <-> linear momentum
+ * - high accuracy by re-applying particle acceleration after collision
+ * - behaves relatively well even if limit of 10 collisions per simulation step is exceeded
+ * Main parts:
+ * 1. check for all possible deflectors for closest intersection on particle path
+ * 2. if deflection was found calculate new coordinates or kill the particle
+ */
static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, float cfra){
Object *ground_ob = NULL;
ParticleSettings *part = sim->psys->part;
@@ -2848,19 +2858,21 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
ParticleCollision col;
ColliderCache *coll;
BVHTreeRayHit hit;
- float ray_dir[3], zerovec[3]={0.0,0.0,0.0};
+ float ray_dir[3], acc[3];
float radius = ((part->flag & PART_SIZE_DEFL)?pa->size:0.0f), boid_z = 0.0f;
- float timestep = psys_get_timestep(sim);
+ float timestep = psys_get_timestep(sim) * dfra;
+ float inv_timestep = 1.0f/timestep;
int deflections=0, max_deflections=10;
- VECCOPY(col.co1, pa->prev_state.co);
- VECCOPY(col.co2, pa->state.co);
-
- VECCOPY(col.ve1, pa->prev_state.vel);
- VECCOPY(col.ve2, pa->state.vel);
- mul_v3_fl(col.ve1, timestep * dfra);
- mul_v3_fl(col.ve2, timestep * dfra);
-
+ /* get acceleration (from gravity, forcefields etc. to be re-applied after collision) */
+ sub_v3_v3v3(acc, pa->state.vel, pa->prev_state.vel);
+ mul_v3_fl(acc, inv_timestep);
+
+ /* set values for first iteration */
+ copy_v3_v3(col.co1, pa->prev_state.co);
+ copy_v3_v3(col.co2, pa->state.co);
+ copy_v3_v3(col.ve1, pa->prev_state.vel);
+ copy_v3_v3(col.ve2, pa->state.vel);
col.t = 0.0f;
/* override for boids */
@@ -2875,7 +2887,7 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
if(sim->colliders) while(deflections < max_deflections){
/* 1. */
- VECSUB(ray_dir, col.co2, col.co1);
+ sub_v3_v3v3(ray_dir, col.co2, col.co1);
hit.index = -1;
hit.dist = col.ray_len = len_v3(ray_dir);
@@ -2903,45 +2915,49 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
/* 2. */
if(hit.index>=0) {
PartDeflect *pd = col.hit_ob->pd;
- int through = (BLI_frand() < pd->pdef_perm) ? 1 : 0;
float co[3]; /* point of collision */
- float vec[3]; /* movement through collision */
- float acc[3]; /* acceleration */
-
float x = hit.dist/col.ray_len; /* location of collision between this iteration */
- float le = len_v3(col.ve1)/col.ray_len;
- float ac = len_v3(col.ve2)/col.ray_len - le; /* (taking acceleration into account) */
- float t = (-le + sqrt(le*le + 2*ac*x))/ac; /* time of collision between this iteration */
- float dt = col.t + x * (1.0f - col.t); /* time of collision between frame change*/
- float it = 1.0 - t;
+ float df = col.t + x * (1.0f - col.t); /* time of collision between frame change*/
+ float dt1 = (df - col.t) * timestep; /* iteration time of collision (in seconds) */
+ float dt2 = (1.0f - df) * timestep; /* time left after collision (in seconds) */
+ int through = (BLI_frand() < pd->pdef_perm) ? 1 : 0; /* did particle pass through the collision surface? */
+
+ deflections++;
interp_v3_v3v3(co, col.co1, col.co2, x);
- VECSUB(vec, col.co2, col.co1);
-
- VECSUB(acc, col.ve2, col.ve1);
- mul_v3_fl(col.vel, 1.0f-col.t);
+ /* make sure we don't hit the current face again */
+ /* TODO: could/should this be proportional to pa->size? */
+ madd_v3_v3fl(co, col.nor, (through ? -0.0001f : 0.0001f));
/* particle dies in collision */
if(through == 0 && (part->flag & PART_DIE_ON_COL || pd->flag & PDEFLE_KILL_PART)) {
pa->alive = PARS_DYING;
- pa->dietime = pa->state.time + (cfra - pa->state.time) * dt;
-
- /* we have to add this for dying particles too so that reactors work correctly */
- VECADDFAC(co, co, col.nor, (through ? -0.0001f : 0.0001f));
+ pa->dietime = pa->state.time + (cfra - pa->state.time) * df;
- VECCOPY(pa->state.co, co);
- interp_v3_v3v3(pa->state.vel, pa->prev_state.vel, pa->state.vel, dt);
- interp_qt_qtqt(pa->state.rot, pa->prev_state.rot, pa->state.rot, dt);
- interp_v3_v3v3(pa->state.ave, pa->prev_state.ave, pa->state.ave, dt);
+ copy_v3_v3(pa->state.co, co);
+ interp_v3_v3v3(pa->state.vel, pa->prev_state.vel, pa->state.vel, df);
+ interp_qt_qtqt(pa->state.rot, pa->prev_state.rot, pa->state.rot, df);
+ interp_v3_v3v3(pa->state.ave, pa->prev_state.ave, pa->state.ave, df);
/* particle is dead so we don't need to calculate further */
- deflections=max_deflections;
+ return;
}
+ /* figure out velocity and other data after collision */
else {
- float nor_vec[3], tan_vec[3], tan_vel[3];
+ float v0[3]; /* velocity directly before collision to be modified into velocity directly after collision */
+ float v0_nor[3];/* normal component of v0 */
+ float v0_tan[3];/* tangential component of v0 */
+ float vc_tan[3];/* tangential component of collision surface velocity */
+ float check[3];
+ float v0_dot, vc_dot, check_dot;
float damp, frict;
- float inp, inp_v;
+
+ /* get exact velocity right before collision */
+ madd_v3_v3v3fl(v0, col.ve1, acc, dt1);
+
+ /* convert collider velocity from 1/framestep to 1/s */
+ mul_v3_fl(col.vel, inv_timestep);
/* get damping & friction factors */
damp = pd->pdef_damp + pd->pdef_rdamp * 2 * (BLI_frand() - 0.5f);
@@ -2951,119 +2967,118 @@ static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, flo
CLAMP(frict,0.0,1.0);
/* treat normal & tangent components separately */
- inp = dot_v3v3(col.nor, vec);
- inp_v = dot_v3v3(col.nor, col.vel);
-
- VECADDFAC(tan_vec, vec, col.nor, -inp);
- VECADDFAC(tan_vel, col.vel, col.nor, -inp_v);
- if((part->flag & PART_ROT_DYN)==0)
- interp_v3_v3v3(tan_vec, tan_vec, tan_vel, frict);
-
- VECCOPY(nor_vec, col.nor);
- inp *= 1.0f - damp;
-
- if(through)
- inp_v *= damp;
-
- /* special case for object hitting the particle from behind */
- if(through==0 && ((inp_v>0 && inp>0 && inp_v>inp) || (inp_v<0 && inp<0 && inp_v<inp)))
- mul_v3_fl(nor_vec, inp_v);
- else
- mul_v3_fl(nor_vec, inp_v + (through ? 1.0f : -1.0f) * inp);
+ v0_dot = dot_v3v3(col.nor, v0);
+ madd_v3_v3v3fl(v0_tan, v0, col.nor, -v0_dot);
- /* angular <-> linear velocity - slightly more physical and looks even nicer than before */
- if(part->flag & PART_ROT_DYN) {
- float surface_vel[3], rot_vel[3], friction[3], dave[3], dvel[3];
+ vc_dot = dot_v3v3(col.nor, col.vel);
+ madd_v3_v3v3fl(vc_tan, col.vel, col.nor, -vc_dot);
- /* apparent velocity along collision surface */
- VECSUB(surface_vel, tan_vec, tan_vel);
+ /* handle friction effects (tangential and angular velocity) */
+ if(frict > 0.0f) {
+ /* angular <-> linear velocity */
+ if(part->flag & PART_ROT_DYN) {
+ float vr_tan[3], v1_tan[3], ave[3];
+
+ /* linear velocity of particle surface */
+ cross_v3_v3v3(vr_tan, col.nor, pa->state.ave);
+ mul_v3_fl(vr_tan, pa->size);
- /* direction of rolling friction */
- cross_v3_v3v3(rot_vel, pa->state.ave, col.nor);
- /* convert to current dt */
- mul_v3_fl(rot_vel, (timestep*dfra) * (1.0f - col.t));
- mul_v3_fl(rot_vel, pa->size);
+ /* change to coordinates that move with the collision plane */
+ sub_v3_v3v3(v1_tan, v0_tan, vc_tan);
+
+ /* The resulting velocity is a weighted average of particle cm & surface
+ * velocity. This weight (related to particle's moment of inertia) could
+ * be made a parameter for angular <-> linear conversion.
+ */
+ madd_v3_v3fl(v1_tan, vr_tan, -0.4);
+ mul_v3_fl(v1_tan, 1.0f/1.4f); /* 1/(1+0.4) */
- /* apply sliding friction */
- VECSUB(surface_vel, surface_vel, rot_vel);
- VECCOPY(friction, surface_vel);
+ /* rolling friction is around 0.01 of sliding friction (could be made a parameter) */
+ mul_v3_fl(v1_tan, 1.0f - 0.01f * frict);
- mul_v3_fl(surface_vel, 1.0 - frict);
- mul_v3_fl(friction, frict);
+ /* surface_velocity is opposite to cm velocity */
+ mul_v3_v3fl(vr_tan, v1_tan, -1.0f);
- /* sliding changes angular velocity */
- cross_v3_v3v3(dave, col.nor, friction);
- mul_v3_fl(dave, 1.0f/MAX2(pa->size, 0.001));
+ /* get back to global coordinates */
+ add_v3_v3(v1_tan, vc_tan);
- /* we assume rolling friction is around 0.01 of sliding friction */
- mul_v3_fl(rot_vel, 1.0 - frict*0.01);
+ /* convert to angular velocity*/
+ cross_v3_v3v3(ave, vr_tan, col.nor);
+ mul_v3_fl(ave, 1.0f/MAX2(pa->size, 0.001));
- /* change in angular velocity has to be added to the linear velocity too */
- cross_v3_v3v3(dvel, dave, col.nor);
- mul_v3_fl(dvel, pa->size);
- VECADD(rot_vel, rot_vel, dvel);
+ /* only friction will cause change in linear & angular velocity */
+ interp_v3_v3v3(pa->state.ave, pa->state.ave, ave, frict);
+ interp_v3_v3v3(v0_tan, v0_tan, v1_tan, frict);
+ }
+ else {
+ /* just basic friction (unphysical due to the friction model used in Blender) */
+ interp_v3_v3v3(v0_tan, v0_tan, vc_tan, frict);
+ }
+ }
- VECADD(surface_vel, surface_vel, rot_vel);
- VECADD(tan_vec, surface_vel, tan_vel);
+ /* stickness was possibly added before, so cancel that before calculating new normal velocity */
+ /* otherwise particles go flying out of the surface because of high reversed sticky velocity */
+ if(v0_dot < 0.0f) {
+ v0_dot += pd->pdef_stickness;
+ if(v0_dot > 0.0f)
+ v0_dot = 0.0f;
+ }
- /* convert back to normal time */
- mul_v3_fl(dave, 1.0f/MAX2((timestep*dfra) * (1.0f - col.t), 0.00001));
+ /* damping and flipping of velocity around normal */
+ v0_dot *= 1.0f - damp;
+ vc_dot *= through ? damp : 1.0f;
- mul_v3_fl(pa->state.ave, 1.0 - frict*0.01);
- VECADD(pa->state.ave, pa->state.ave, dave);
- }
+ /* special case for object hitting the particle from behind */
+ if(through==0 && ((vc_dot>0.0f && v0_dot>0.0f && vc_dot>v0_dot) || (vc_dot<0.0f && v0_dot<0.0f && vc_dot<v0_dot)))
+ mul_v3_v3fl(v0_nor, col.nor, vc_dot);
+ else
+ mul_v3_v3fl(v0_nor, col.nor, vc_dot + (through ? 1.0f : -1.0f) * v0_dot);
/* combine components together again */
- VECADD(vec, nor_vec, tan_vec);
-
- /* make sure we don't hit the current face again */
- VECADDFAC(co, co, col.nor, (through ? -0.0001f : 0.0001f));
+ add_v3_v3v3(v0, v0_nor, v0_tan);
+ /* keep boids above ground */
if(part->phystype == PART_PHYS_BOIDS && part->boids->options & BOID_ALLOW_LAND) {
BoidParticle *bpa = pa->boid;
if(bpa->data.mode == eBoidMode_OnLand || co[2] <= boid_z) {
co[2] = boid_z;
- vec[2] = 0.0f;
+ v0[2] = 0.0f;
}
}
-
- /* set coordinates for next iteration */
- /* apply acceleration to final position, but make sure particle stays above surface */
- madd_v3_v3v3fl(acc, vec, acc, it);
- ac = dot_v3v3(acc, col.nor);
- if((!through && ac < 0.0f) || (through && ac > 0.0f))
- madd_v3_v3fl(acc, col.nor, -ac);
-
- VECCOPY(col.co1, co);
- VECADDFAC(col.co2, co, acc, it);
-
- VECCOPY(col.ve1, vec);
- VECCOPY(col.ve2, acc);
-
- if(len_v3(vec) < 0.001 && len_v3v3(pa->state.co, pa->prev_state.co) < 0.001) {
- /* kill speed to stop slipping */
- VECCOPY(pa->state.vel,zerovec);
- VECCOPY(pa->state.co, co);
- if(part->flag & PART_ROT_DYN) {
- VECCOPY(pa->state.ave,zerovec);
- }
- }
- else {
- VECCOPY(pa->state.co, col.co2);
- mul_v3_v3fl(pa->state.vel, acc, 1.0f/MAX2((timestep*dfra) * (1.0f - col.t), 0.00001));
-
+ if(deflections < max_deflections) {
+ /* re-apply acceleration to final velocity and location */
+ madd_v3_v3v3fl(pa->state.vel, v0, acc, dt2);
+ madd_v3_v3v3fl(pa->state.co, co, v0, dt2);
+ madd_v3_v3fl(pa->state.co, acc, 0.5f*dt2*dt2);
+
+ /* make sure particle stays on the right side of the surface */
+ sub_v3_v3v3(check, pa->state.co, co);
+ /* (collision surface has moved during the time too) */
+ madd_v3_v3fl(check, col.vel, -dt2);
+
+ check_dot = dot_v3v3(check, col.nor);
+ if((!through && check_dot < 0.0f) || (through && check_dot > 0.0f))
+ madd_v3_v3fl(pa->state.co, col.nor, (through ? -0.0001f : 0.0001f) - check_dot);
+
/* Stickness to surface */
- normalize_v3(nor_vec);
madd_v3_v3fl(pa->state.vel, col.nor, -pd->pdef_stickness);
- }
- col.t = dt;
- }
- deflections++;
+ /* set coordinates for next iteration */
+ copy_v3_v3(col.co1, co);
+ copy_v3_v3(col.co2, pa->state.co);
- //reaction_state.time = cfra - (1.0f - dt) * dfra;
- //push_reaction(col.ob, psys, p, PART_EVENT_COLLIDE, &reaction_state);
+ copy_v3_v3(col.ve1, v0);
+ copy_v3_v3(col.ve2, pa->state.vel);
+
+ col.t = df;
+ }
+ else {
+ /* final chance to prevent failure, so don't do anything fancy */
+ copy_v3_v3(pa->state.co, co);
+ copy_v3_v3(pa->state.vel, v0);
+ }
+ }
}
else
return;
@@ -3345,6 +3360,8 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
/* frame & time changes */
float dfra, dtime, pa_dtime, pa_dfra=0.0;
float birthtime, dietime;
+
+ int invalidParticles=0;
/* where have we gone in time since last time */
dfra= cfra - psys->cfra;
@@ -3440,7 +3457,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
else if(part->phystype == PART_PHYS_NO)
reset_particle(sim, pa, dtime, cfra);
- if(dfra>0.0 && ELEM(pa->alive,PARS_ALIVE,PARS_DYING)){
+ if(pa_dfra>0.0 && ELEM(pa->alive,PARS_ALIVE,PARS_DYING)){
switch(part->phystype){
case PART_PHYS_NEWTON:
/* do global forces & effectors */
@@ -3495,6 +3512,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
//push_reaction(ob,psys,p,PART_EVENT_NEAR,&pa->state);
}
+ if (isnan(pa->state.co[0]) || isnan(pa->state.co[1]) || isnan(pa->state.co[2])) {invalidParticles++;}
}
free_collider_cache(&sim->colliders);
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 741580048cf..784f6e40706 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -1008,11 +1008,22 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup
}
for(psys=ob->particlesystem.first; psys; psys=psys->next) {
- if(psys->part) {
- pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
- BKE_ptcache_id_from_particles(pid, ob, psys);
- BLI_addtail(lb, pid);
- }
+ if(psys->part==NULL)
+ continue;
+
+ /* check to make sure point cache is actually used by the particles */
+ if(ELEM(psys->part->phystype, PART_PHYS_NO, PART_PHYS_KEYED))
+ continue;
+
+ if(psys->part->type == PART_HAIR && (psys->flag & PSYS_HAIR_DYNAMICS)==0)
+ continue;
+
+ if(psys->part->type == PART_FLUID)
+ continue;
+
+ pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
+ BKE_ptcache_id_from_particles(pid, ob, psys);
+ BLI_addtail(lb, pid);
}
for(md=ob->modifiers.first; md; md=md->next) {
@@ -1876,6 +1887,9 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
else
cache->flag |= PTCACHE_FRAMES_SKIPPED;
}
+
+ if(cache->cached_frames)
+ cache->cached_frames[cfra] = 1;
if(pf) ptcache_file_close(pf);
@@ -1893,6 +1907,9 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
{
int len; /* store the length of the string */
+ int i;
+ int sta = pid->cache->startframe;
+ int end = pid->cache->endframe;
/* mode is same as fopen's modes */
DIR *dir;
@@ -1936,6 +1953,8 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
pid->cache->last_exact = MIN2(pid->cache->startframe, 0);
BLI_join_dirfile(path_full, path, de->d_name);
BLI_delete(path_full, 0, 0);
+ if(pid->cache->cached_frames) for(i=0; i<end-sta+1; i++)
+ pid->cache->cached_frames[i] = 0;
} else {
/* read the number of the file */
int frame, len2 = (int)strlen(de->d_name);
@@ -1950,6 +1969,8 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
BLI_join_dirfile(path_full, path, de->d_name);
BLI_delete(path_full, 0, 0);
+ if(frame >=sta && frame <= end)
+ pid->cache->cached_frames[frame-sta] = 0;
}
}
}
@@ -1970,11 +1991,16 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
for(; pm; pm=pm->next)
ptcache_free_data(pm);
BLI_freelistN(&pid->cache->mem_cache);
+
+ if(pid->cache->cached_frames) for(i=0; i<end-sta+1; i++)
+ pid->cache->cached_frames[i] = 0;
} else {
while(pm) {
if((mode==PTCACHE_CLEAR_BEFORE && pm->frame < cfra) ||
(mode==PTCACHE_CLEAR_AFTER && pm->frame > cfra) ) {
link = pm;
+ if(pm->frame >=sta && pm->frame <= end)
+ pid->cache->cached_frames[pm->frame-sta] = 0;
ptcache_free_data(pm);
pm = pm->next;
BLI_freelinkN(&pid->cache->mem_cache, link);
@@ -2004,6 +2030,8 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
}
}
}
+ if(pid->cache->cached_frames && cfra>=sta && cfra<=end)
+ pid->cache->cached_frames[cfra-sta] = 0;
break;
}
@@ -2014,6 +2042,12 @@ int BKE_ptcache_id_exist(PTCacheID *pid, int cfra)
{
if(!pid->cache)
return 0;
+
+ if(cfra<pid->cache->startframe || cfra > pid->cache->endframe)
+ return 0;
+
+ if(pid->cache->cached_frames && pid->cache->cached_frames[cfra-pid->cache->startframe]==0)
+ return 0;
if(pid->cache->flag & PTCACHE_DISK_CACHE) {
char filename[MAX_PTCACHE_FILE];
@@ -2073,6 +2107,71 @@ void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startfra
*endframe += (int)(offset+0.5f);
}
}
+
+ /* verify cached_frames array is up to date */
+ if(cache->cached_frames) {
+ if(MEM_allocN_len(cache->cached_frames) != sizeof(char) * (cache->endframe-cache->startframe+1)) {
+ MEM_freeN(cache->cached_frames);
+ cache->cached_frames = NULL;
+ }
+ }
+
+ if(cache->cached_frames==NULL && cache->endframe > cache->startframe) {
+ int sta=cache->startframe;
+ int end=cache->endframe;
+
+ cache->cached_frames = MEM_callocN(sizeof(char) * (cache->endframe-cache->startframe+1), "cached frames array");
+
+ if(pid->cache->flag & PTCACHE_DISK_CACHE) {
+ /* mode is same as fopen's modes */
+ DIR *dir;
+ struct dirent *de;
+ char path[MAX_PTCACHE_PATH];
+ char filename[MAX_PTCACHE_FILE];
+ char ext[MAX_PTCACHE_PATH];
+ int len; /* store the length of the string */
+
+ ptcache_path(pid, path);
+
+ len = BKE_ptcache_id_filename(pid, filename, (int)cfra, 0, 0); /* no path */
+
+ dir = opendir(path);
+ if (dir==NULL)
+ return;
+
+ snprintf(ext, sizeof(ext), "_%02d"PTCACHE_EXT, pid->stack_index);
+
+ while ((de = readdir(dir)) != NULL) {
+ if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
+ if (strncmp(filename, de->d_name, len ) == 0) { /* do we have the right prefix */
+ /* read the number of the file */
+ int frame, len2 = (int)strlen(de->d_name);
+ char num[7];
+
+ if (len2 > 15) { /* could crash if trying to copy a string out of this range*/
+ BLI_strncpy(num, de->d_name + (strlen(de->d_name) - 15), sizeof(num));
+ frame = atoi(num);
+
+ if(frame >= sta && frame <= end)
+ cache->cached_frames[frame-sta] = 1;
+ }
+ }
+ }
+ }
+ closedir(dir);
+ }
+ else {
+ PTCacheMem *pm= pid->cache->mem_cache.first;
+
+ pm= pid->cache->mem_cache.first;
+
+ while(pm) {
+ if(pm->frame >= sta && pm->frame <= end)
+ cache->cached_frames[pm->frame-sta] = 1;
+ pm = pm->next;
+ }
+ }
+ }
}
int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
@@ -2293,6 +2392,8 @@ void BKE_ptcache_free(PointCache *cache)
BKE_ptcache_free_mem(&cache->mem_cache);
if(cache->edit && cache->free_edit)
cache->free_edit(cache->edit);
+ if(cache->cached_frames)
+ MEM_freeN(cache->cached_frames);
MEM_freeN(cache);
}
void BKE_ptcache_free_list(ListBase *ptcaches)
@@ -2840,7 +2941,10 @@ void BKE_ptcache_update_info(PTCacheID *pid)
totframes++;
}
- if(totframes && cache->totpoint)
+ /* smoke doesn't use frame 0 as info frame so can't check based on totpoint */
+ if(pid->type == PTCACHE_TYPE_SMOKE_DOMAIN && totframes)
+ sprintf(cache->info, "%i frames found!", totframes);
+ else if(totframes && cache->totpoint)
sprintf(cache->info, "%i points found!", cache->totpoint);
else
sprintf(cache->info, "No valid data to read!");
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 461cb075bb0..4a00922f1d2 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -2873,7 +2873,7 @@ static void init_speed_effect(Sequence *seq)
v = (SpeedControlVars *)seq->effectdata;
v->globalSpeed = 1.0;
v->frameMap = 0;
- v->flags = 0;
+ v->flags |= SEQ_SPEED_INTEGRATE; /* should be default behavior */
v->length = 0;
}
@@ -2936,9 +2936,8 @@ static void store_icu_yrange_speed(struct Sequence * seq,
}
void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
{
- float ctime, div;
int cfra;
- float fallback_fac;
+ float fallback_fac = 1.0f;
SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
FCurve *fcu= NULL;
@@ -2955,7 +2954,7 @@ void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
/* XXX - new in 2.5x. should we use the animation system this way?
* The fcurve is needed because many frames need evaluating at once - campbell */
- fcu= id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_fader", 0);
+ fcu= id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0);
if (!v->frameMap || v->length != seq->len) {
@@ -2966,17 +2965,12 @@ void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
v->frameMap = MEM_callocN(sizeof(float) * v->length,
"speedcontrol frameMap");
}
-
- fallback_fac = 1.0;
- /* if there is no fcurve, try to make retiming easy by stretching the
- strip */
- if (!fcu && seq->seq1->enddisp != seq->seq1->start && seq->seq1->len != 0) {
- fallback_fac = (float) seq->seq1->len /
- (float) (seq->seq1->enddisp - seq->seq1->start);
- }
+ /* if there is no fcurve, use value as simple multiplier */
+ if (!fcu)
+ fallback_fac = seq->speed_fader; /* same as speed_factor in rna*/
- if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) {
+ if (v->flags & SEQ_SPEED_INTEGRATE) {
float cursor = 0;
float facf;
@@ -2985,10 +2979,7 @@ void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
for (cfra = 1; cfra < v->length; cfra++) {
if(fcu) {
- ctime = seq->startdisp + cfra;
- div = 1.0;
-
- facf = evaluate_fcurve(fcu, ctime/div);
+ facf = evaluate_fcurve(fcu, seq->startdisp + cfra);
} else {
facf = fallback_fac;
}
@@ -3010,19 +3001,16 @@ void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
for (cfra = 0; cfra < v->length; cfra++) {
if(fcu) {
- ctime = seq->startdisp + cfra;
- div = 1.0;
-
- facf = evaluate_fcurve(fcu, ctime / div);
- if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
- facf *= v->length;
- }
+ facf = evaluate_fcurve(fcu, seq->startdisp + cfra);
+ } else {
+ facf = fallback_fac;
}
-
- if (!fcu) {
- facf = (float) cfra * fallback_fac;
+
+ if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
+ facf *= v->length;
}
facf *= v->globalSpeed;
+
if (facf >= seq->seq1->len) {
facf = seq->seq1->len - 1;
} else {
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index 8edb01c09a6..ceb693c4ecc 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -337,7 +337,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, struct S
}
//After sucessufuly build the trees, start projection vertexs
- if( bvhtree_from_mesh_faces(&treeData, calc->target, calc->keepDist, 4, 6)
+ if( bvhtree_from_mesh_faces(&treeData, calc->target, 0.0, 4, 6)
&& (auxMesh == NULL || bvhtree_from_mesh_faces(&auxData, auxMesh, 0.0, 4, 6)))
{
@@ -383,6 +383,9 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, struct S
normal_projection_project_vertex(0, tmp_co, tmp_no, &local2aux, auxData.tree, &hit, auxData.raycast_callback, &auxData);
normal_projection_project_vertex(calc->smd->shrinkOpts, tmp_co, tmp_no, &calc->local2target, treeData.tree, &hit, treeData.raycast_callback, &treeData);
+
+ if(hit.index != -1)
+ madd_v3_v3v3fl(hit.co, hit.co, tmp_no, -calc->keepDist);
}
//Project over negative direction of axis
@@ -395,6 +398,9 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, struct S
normal_projection_project_vertex(0, tmp_co, inv_no, &local2aux, auxData.tree, &hit, auxData.raycast_callback, &auxData);
normal_projection_project_vertex(calc->smd->shrinkOpts, tmp_co, inv_no, &calc->local2target, treeData.tree, &hit, treeData.raycast_callback, &treeData);
+
+ if(hit.index != -1)
+ madd_v3_v3v3fl(hit.co, hit.co, tmp_no, calc->keepDist);
}
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index d2d8d5a6e07..d0fcde0da58 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -1338,10 +1338,17 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
cache_wt = sds->point_cache[1];
BKE_ptcache_id_from_smoke_turbulence(&pid_wt, ob, smd);
- if(!smd->domain->fluid)
+ if(!smd->domain->fluid || framenr == startframe)
{
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
+ BKE_ptcache_validate(cache, framenr);
+ cache->flag &= ~PTCACHE_REDO_NEEDED;
+
BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_OUTDATED);
+ if(cache_wt) {
+ BKE_ptcache_validate(cache_wt, framenr);
+ cache_wt->flag &= ~PTCACHE_REDO_NEEDED;
+ }
}
if(framenr < startframe)
@@ -1368,6 +1375,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
if(cache_result == PTCACHE_READ_EXACT)
{
BKE_ptcache_validate(cache, framenr);
+ smd->time = framenr;
if(sds->wt)
{
@@ -1388,14 +1396,21 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
else
return;
}
-
- /* only calculate something when we advanced a frame */
- if(framenr == smd->time)
+ /* only calculate something when we advanced a single frame */
+ else if(framenr != (int)smd->time+1)
return;
tstart();
smoke_calc_domain(scene, ob, smd);
+
+ /* if on second frame, write cache for first frame */
+ /* this needs to be done for smoke too so that pointcache works properly */
+ if((int)smd->time == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0)) {
+ BKE_ptcache_write_cache(&pid, startframe);
+ if(sds->wt)
+ BKE_ptcache_write_cache(&pid_wt, startframe);
+ }
// set new time
smd->time = scene->r.cfra;
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index a4f1d5d0578..90a8ca03079 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -1557,7 +1557,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, v
DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
}
- if(!doDraw || (setDrawOptions && !setDrawOptions(userData, origIndex))) {
+ if(!doDraw || (setDrawOptions && (origIndex != ORIGINDEX_NONE) && !setDrawOptions(userData, origIndex))) {
a += gridFaces*gridFaces*numVerts;
continue;
}
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index 133f858e9ea..3d984c7e877 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -24,6 +24,8 @@
#include <stdio.h>
#include <ctype.h>
#include <string.h>
+#include "BKE_unit.h"
+
#ifdef WIN32
#define _USE_MATH_DEFINES
#endif
@@ -31,20 +33,51 @@
#include "BLI_winstuff.h"
+
#define TEMP_STR_SIZE 256
#define SEP_CHR '#'
#define SEP_STR "#"
-#define EPS 0.000001
-
+#define EPS 0.00001
+
+#define UN_SC_KM 1000.0f
+#define UN_SC_HM 100.0f
+#define UN_SC_DAM 10.0f
+#define UN_SC_M 1.0f
+#define UN_SC_DM 0.1f
+#define UN_SC_CM 0.01f
+#define UN_SC_MM 0.001f
+#define UN_SC_UM 0.000001f
+
+#define UN_SC_MI 1609.344f
+#define UN_SC_FUR 201.168f
+#define UN_SC_CH 20.1168f
+#define UN_SC_YD 0.9144f
+#define UN_SC_FT 0.3048f
+#define UN_SC_IN 0.0254f
+#define UN_SC_MIL 0.0000254f
+
+#define UN_SC_MTON 1000.0f /* metric ton */
+#define UN_SC_QL 100.0f
+#define UN_SC_KG 1.0f
+#define UN_SC_HG 0.1f
+#define UN_SC_DAG 0.01f
+#define UN_SC_G 0.001f
+
+#define UN_SC_ITON 907.18474f /* imperial ton */
+#define UN_SC_CWT 45.359237f
+#define UN_SC_ST 6.35029318f
+#define UN_SC_LB 0.45359237f
+#define UN_SC_OZ 0.028349523125f
/* define a single unit */
typedef struct bUnitDef {
char *name;
char *name_plural; /* abused a bit for the display name */
char *name_short; /* this is used for display*/
- char *name_alt; /* can be NULL */
+ char *name_alt; /* keyboard-friendly ASCII-only version of name_short, can be NULL */
+ /* if name_short has non-ASCII chars, name_alt should be present */
char *name_display; /* can be NULL */
@@ -59,7 +92,7 @@ typedef struct bUnitDef {
/* define a single unit */
typedef struct bUnitCollection {
struct bUnitDef *units;
- int base_unit; /* use for 0.0, or none given */
+ int base_unit; /* basic unit index (when user desn't specify unit explicitly) */
int flag; /* options for this system */
int length; /* to quickly find the last item */
} bUnitCollection;
@@ -74,14 +107,14 @@ static struct bUnitCollection buDummyCollecton = {buDummyDef, 0, 0, sizeof(buDum
/* Lengths */
static struct bUnitDef buMetricLenDef[] = {
- {"kilometer", "kilometers", "km", NULL, "Kilometers", 1000.0, 0.0, B_UNIT_DEF_NONE},
- {"hectometer", "hectometers", "hm", NULL, "100 Meters", 100.0, 0.0, B_UNIT_DEF_SUPPRESS},
- {"dekameter", "dekameters", "dkm",NULL, "10 Meters", 10.0, 0.0, B_UNIT_DEF_SUPPRESS},
- {"meter", "meters", "m", NULL, "Meters", 1.0, 0.0, B_UNIT_DEF_NONE}, /* base unit */
- {"decimetre", "decimetres", "dm", NULL, "10 Centimeters", 0.1, 0.0, B_UNIT_DEF_SUPPRESS},
- {"centimeter", "centimeters", "cm", NULL, "Centimeters", 0.01, 0.0, B_UNIT_DEF_NONE},
- {"millimeter", "millimeters", "mm", NULL, "Millimeters", 0.001, 0.0, B_UNIT_DEF_NONE},
- {"micrometer", "micrometers", "µm", "um", "Micrometers", 0.000001, 0.0, B_UNIT_DEF_NONE}, // micron too?
+ {"kilometer", "kilometers", "km", NULL, "Kilometers", UN_SC_KM, 0.0, B_UNIT_DEF_NONE},
+ {"hectometer", "hectometers", "hm", NULL, "100 Meters", UN_SC_HM, 0.0, B_UNIT_DEF_SUPPRESS},
+ {"dekameter", "dekameters", "dam",NULL, "10 Meters", UN_SC_DAM, 0.0, B_UNIT_DEF_SUPPRESS},
+ {"meter", "meters", "m", NULL, "Meters", UN_SC_M, 0.0, B_UNIT_DEF_NONE}, /* base unit */
+ {"decimetre", "decimetres", "dm", NULL, "10 Centimeters", UN_SC_DM, 0.0, B_UNIT_DEF_SUPPRESS},
+ {"centimeter", "centimeters", "cm", NULL, "Centimeters", UN_SC_CM, 0.0, B_UNIT_DEF_NONE},
+ {"millimeter", "millimeters", "mm", NULL, "Millimeters", UN_SC_MM, 0.0, B_UNIT_DEF_NONE},
+ {"micrometer", "micrometers", "µm", "um", "Micrometers", UN_SC_UM, 0.0, B_UNIT_DEF_NONE}, // micron too?
/* These get displayed because of float precision problems in the transform header,
* could work around, but for now probably people wont use these */
@@ -94,17 +127,121 @@ static struct bUnitDef buMetricLenDef[] = {
static struct bUnitCollection buMetricLenCollecton = {buMetricLenDef, 3, 0, sizeof(buMetricLenDef)/sizeof(bUnitDef)};
static struct bUnitDef buImperialLenDef[] = {
- {"mile", "miles", "mi", "m", "Miles", 1609.344, 0.0, B_UNIT_DEF_NONE},
- {"furlong", "furlongs", "fur", NULL, "Furlongs",201.168, 0.0, B_UNIT_DEF_SUPPRESS},
- {"chain", "chains", "ch", NULL, "Chains", 0.9144*22.0, 0.0, B_UNIT_DEF_SUPPRESS},
- {"yard", "yards", "yd", NULL, "Yards", 0.9144, 0.0, B_UNIT_DEF_NONE},
- {"foot", "feet", "'", "ft", "Feet", 0.3048, 0.0, B_UNIT_DEF_NONE},
- {"inch", "inches", "\"", "in", "Inches", 0.0254, 0.0, B_UNIT_DEF_NONE}, /* base unit */
- {"thou", "thous", "mil", NULL, "Thous", 0.0000254, 0.0, B_UNIT_DEF_NONE},
+ {"mile", "miles", "mi", "m", "Miles", UN_SC_MI, 0.0, B_UNIT_DEF_NONE},
+ {"furlong", "furlongs", "fur", NULL, "Furlongs",UN_SC_FUR, 0.0, B_UNIT_DEF_SUPPRESS},
+ {"chain", "chains", "ch", NULL, "Chains", UN_SC_CH, 0.0, B_UNIT_DEF_SUPPRESS},
+ {"yard", "yards", "yd", NULL, "Yards", UN_SC_YD, 0.0, B_UNIT_DEF_NONE},
+ {"foot", "feet", "'", "ft", "Feet", UN_SC_FT, 0.0, B_UNIT_DEF_NONE}, /* base unit */
+ {"inch", "inches", "\"", "in", "Inches", UN_SC_IN, 0.0, B_UNIT_DEF_NONE},
+ {"thou", "thous", "mil", NULL, "Thous", UN_SC_MIL, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
static struct bUnitCollection buImperialLenCollecton = {buImperialLenDef, 4, 0, sizeof(buImperialLenDef)/sizeof(bUnitDef)};
+/* Areas */
+static struct bUnitDef buMetricAreaDef[] = {
+ {"square kilometer", "square kilometers", "km²", "km2", "Square Kilometers", UN_SC_KM*UN_SC_KM, 0.0, B_UNIT_DEF_NONE},
+ {"square hectometer","square hectometers", "hm²", "hm2", "Square Hectometers", UN_SC_HM*UN_SC_HM, 0.0, B_UNIT_DEF_NONE}, /* hectare */
+ {"square dekameter", "square dekameters", "dam²","dam2", "Square Dekameters", UN_SC_DAM*UN_SC_DAM, 0.0, B_UNIT_DEF_SUPPRESS}, /* are */
+ {"square meter", "square meters", "m²", "m2", "Square Meters", UN_SC_M*UN_SC_M, 0.0, B_UNIT_DEF_NONE}, /* base unit */
+ {"square decimetre", "square decimetres", "dm²", "dm2", "Square Decimetres", UN_SC_DM*UN_SC_DM, 0.0, B_UNIT_DEF_SUPPRESS},
+ {"square centimeter", "square centimeters", "cm²", "cm2", "Square Centimeters", UN_SC_CM*UN_SC_CM, 0.0, B_UNIT_DEF_NONE},
+ {"square millimeter", "square millimeters", "mm²", "mm2", "Square Millimeters", UN_SC_MM*UN_SC_MM, 0.0, B_UNIT_DEF_NONE},
+ {"square micrometer", "square micrometers", "µm²", "um2", "Square Micrometers", UN_SC_UM*UN_SC_UM, 0.0, B_UNIT_DEF_NONE},
+ {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
+};
+static struct bUnitCollection buMetricAreaCollecton = {buMetricAreaDef, 3, 0, sizeof(buMetricAreaDef)/sizeof(bUnitDef)};
+
+static struct bUnitDef buImperialAreaDef[] = {
+ {"square mile", "square miles", "sq mi", "sq m","Square Miles", UN_SC_MI*UN_SC_MI, 0.0, B_UNIT_DEF_NONE},
+ {"square furlong", "square furlongs", "sq fur",NULL, "Square Furlongs", UN_SC_FUR*UN_SC_FUR, 0.0,B_UNIT_DEF_SUPPRESS},
+ {"square chain", "square chains", "sq ch", NULL, "Square Chains", UN_SC_CH*UN_SC_CH, 0.0, B_UNIT_DEF_SUPPRESS},
+ {"square yard", "square yards", "sq yd", NULL, "Square Yards", UN_SC_YD*UN_SC_YD, 0.0, B_UNIT_DEF_NONE},
+ {"square foot", "square feet", "sq ft", NULL, "Square Feet", UN_SC_FT*UN_SC_FT, 0.0, B_UNIT_DEF_NONE}, /* base unit */
+ {"square inch", "square inches", "sq in", NULL, "Square Inches", UN_SC_IN*UN_SC_IN, 0.0, B_UNIT_DEF_NONE},
+ {"square thou", "square thous", "sq mil",NULL, "Square Thous", UN_SC_MIL*UN_SC_MIL, 0.0, B_UNIT_DEF_NONE},
+ {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
+};
+static struct bUnitCollection buImperialAreaCollecton = {buImperialAreaDef, 4, 0, sizeof(buImperialAreaDef)/sizeof(bUnitDef)};
+
+/* Volumes */
+static struct bUnitDef buMetricVolDef[] = {
+ {"cubic kilometer", "cubic kilometers", "km³", "km3", "Cubic Kilometers", UN_SC_KM*UN_SC_KM*UN_SC_KM, 0.0, B_UNIT_DEF_NONE},
+ {"cubic hectometer","cubic hectometers", "hm³", "hm3", "Cubic Hectometers", UN_SC_HM*UN_SC_HM*UN_SC_HM, 0.0, B_UNIT_DEF_NONE},
+ {"cubic dekameter", "cubic dekameters", "dam³","dam3", "Cubic Dekameters", UN_SC_DAM*UN_SC_DAM*UN_SC_DAM, 0.0, B_UNIT_DEF_SUPPRESS},
+ {"cubic meter", "cubic meters", "m³", "m3", "Cubic Meters", UN_SC_M*UN_SC_M*UN_SC_M, 0.0, B_UNIT_DEF_NONE}, /* base unit */
+ {"cubic decimetre", "cubic decimetres", "dm³", "dm3", "Cubic Decimetres", UN_SC_DM*UN_SC_DM*UN_SC_DM, 0.0, B_UNIT_DEF_SUPPRESS},
+ {"cubic centimeter", "cubic centimeters", "cm³", "cm3", "Cubic Centimeters", UN_SC_CM*UN_SC_CM*UN_SC_CM, 0.0, B_UNIT_DEF_NONE},
+ {"cubic millimeter", "cubic millimeters", "mm³", "mm3", "Cubic Millimeters", UN_SC_MM*UN_SC_MM*UN_SC_MM, 0.0, B_UNIT_DEF_NONE},
+ {"cubic micrometer", "cubic micrometers", "µm³", "um3", "Cubic Micrometers", UN_SC_UM*UN_SC_UM*UN_SC_UM, 0.0, B_UNIT_DEF_NONE},
+ {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
+};
+static struct bUnitCollection buMetricVolCollecton = {buMetricVolDef, 3, 0, sizeof(buMetricVolDef)/sizeof(bUnitDef)};
+
+static struct bUnitDef buImperialVolDef[] = {
+ {"cubic mile", "cubic miles", "cu mi", "cu m","Cubic Miles", UN_SC_MI*UN_SC_MI*UN_SC_MI, 0.0, B_UNIT_DEF_NONE},
+ {"cubic furlong", "cubic furlongs", "cu fur",NULL, "Cubic Furlongs", UN_SC_FUR*UN_SC_FUR*UN_SC_FUR, 0.0,B_UNIT_DEF_SUPPRESS},
+ {"cubic chain", "cubic chains", "cu ch", NULL, "Cubic Chains", UN_SC_CH*UN_SC_CH*UN_SC_CH, 0.0, B_UNIT_DEF_SUPPRESS},
+ {"cubic yard", "cubic yards", "cu yd", NULL, "Cubic Yards", UN_SC_YD*UN_SC_YD*UN_SC_YD, 0.0, B_UNIT_DEF_NONE},
+ {"cubic foot", "cubic feet", "cu ft", NULL, "Cubic Feet", UN_SC_FT*UN_SC_FT*UN_SC_FT, 0.0, B_UNIT_DEF_NONE}, /* base unit */
+ {"cubic inch", "cubic inches", "cu in", NULL, "Cubic Inches", UN_SC_IN*UN_SC_IN*UN_SC_IN, 0.0, B_UNIT_DEF_NONE},
+ {"cubic thou", "cubic thous", "cu mil",NULL, "Cubic Thous", UN_SC_MIL*UN_SC_MIL*UN_SC_MIL, 0.0, B_UNIT_DEF_NONE},
+ {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
+};
+static struct bUnitCollection buImperialVolCollecton = {buImperialVolDef, 4, 0, sizeof(buImperialVolDef)/sizeof(bUnitDef)};
+
+/* Mass */
+static struct bUnitDef buMetricMassDef[] = {
+ {"ton", "tonnes", "ton", "t", "1000 Kilograms", UN_SC_MTON, 0.0, B_UNIT_DEF_NONE},
+ {"quintal", "quintals", "ql", "q", "100 Kilograms", UN_SC_QL, 0.0, B_UNIT_DEF_NONE},
+ {"kilogram", "kilograms", "kg", NULL, "Kilograms", UN_SC_KG, 0.0, B_UNIT_DEF_NONE}, /* base unit */
+ {"hectogram", "hectograms", "hg", NULL, "Hectograms", UN_SC_HG, 0.0, B_UNIT_DEF_NONE},
+ {"dekagram", "dekagrams", "dag",NULL, "10 Grams", UN_SC_DAG, 0.0, B_UNIT_DEF_SUPPRESS},
+ {"gram", "grams", "g", NULL, "Grams", UN_SC_G, 0.0, B_UNIT_DEF_NONE},
+ {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
+};
+static struct bUnitCollection buMetricMassCollecton = {buMetricMassDef, 2, 0, sizeof(buMetricMassDef)/sizeof(bUnitDef)};
+
+static struct bUnitDef buImperialMassDef[] = {
+ {"ton", "tonnes", "ton", "t", "Tonnes", UN_SC_ITON, 0.0, B_UNIT_DEF_NONE},
+ {"centum weight", "centum weights", "cwt", NULL, "Centum weights", UN_SC_CWT, 0.0, B_UNIT_DEF_NONE},
+ {"stone", "stones", "st", NULL, "Stones", UN_SC_ST, 0.0, B_UNIT_DEF_NONE},
+ {"pound", "pounds", "lb", NULL, "Pounds", UN_SC_LB, 0.0, B_UNIT_DEF_NONE}, /* base unit */
+ {"ounce", "ounces", "oz", NULL, "Ounces", UN_SC_OZ, 0.0, B_UNIT_DEF_NONE},
+ {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
+};
+static struct bUnitCollection buImperialMassCollecton = {buImperialMassDef, 3, 0, sizeof(buImperialMassDef)/sizeof(bUnitDef)};
+
+/* Even if user scales the system to a point where km^3 is used, velocity and
+ * acceleration aren't scaled: that's why we have so few units for them */
+
+/* Velocity */
+static struct bUnitDef buMetricVelDef[] = {
+ {"meter per second", "meters per second", "m/s", NULL, "Meters per second", UN_SC_M, 0.0, B_UNIT_DEF_NONE}, /* base unit */
+ {"kilometer per hour", "kilometers per hour", "km/h", NULL, "Kilometers per hour", UN_SC_KM/3600.0f, 0.0, B_UNIT_DEF_SUPPRESS},
+ {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
+};
+static struct bUnitCollection buMetricVelCollecton = {buMetricVelDef, 0, 0, sizeof(buMetricVelDef)/sizeof(bUnitDef)};
+
+static struct bUnitDef buImperialVelDef[] = {
+ {"foot per second", "feet per second", "ft/s", "fps", "Feet per second", UN_SC_FT, 0.0, B_UNIT_DEF_NONE}, /* base unit */
+ {"mile per hour", "miles per hour", "mph", NULL, "Miles per hour", UN_SC_MI/3600.0f, 0.0,B_UNIT_DEF_SUPPRESS},
+ {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
+};
+static struct bUnitCollection buImperialVelCollecton = {buImperialVelDef, 0, 0, sizeof(buImperialVelDef)/sizeof(bUnitDef)};
+
+/* Acceleration */
+static struct bUnitDef buMetricAclDef[] = {
+ {"meter per second squared", "meters per second squared", "m/s²", "m/s2", "Meters per second squared", UN_SC_M, 0.0, B_UNIT_DEF_NONE}, /* base unit */
+ {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
+};
+static struct bUnitCollection buMetricAclCollecton = {buMetricAclDef, 0, 0, sizeof(buMetricAclDef)/sizeof(bUnitDef)};
+
+static struct bUnitDef buImperialAclDef[] = {
+ {"foot per second squared", "feet per second squared", "ft/s²", "ft/s2", "Feet per second squared", UN_SC_FT, 0.0, B_UNIT_DEF_NONE}, /* base unit */
+ {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
+};
+static struct bUnitCollection buImperialAclCollecton = {buImperialAclDef, 0, 0, sizeof(buImperialAclDef)/sizeof(bUnitDef)};
/* Time */
static struct bUnitDef buNaturalTimeDef[] = {
@@ -114,7 +251,7 @@ static struct bUnitDef buNaturalTimeDef[] = {
{"minute", "minutes", "min", "m", "Minutes", 60.0, 0.0, B_UNIT_DEF_NONE},
{"second", "seconds", "sec", "s", "Seconds", 1.0, 0.0, B_UNIT_DEF_NONE}, /* base unit */
{"millisecond", "milliseconds", "ms", NULL, "Milliseconds", 0.001, 0.0 , B_UNIT_DEF_NONE},
- {"microsecond", "microseconds", "us", NULL, "Microseconds", 0.000001, 0.0, B_UNIT_DEF_NONE},
+ {"microsecond", "microseconds", "µs", "us", "Microseconds", 0.000001, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
static struct bUnitCollection buNaturalTimeCollecton = {buNaturalTimeDef, 3, 0, sizeof(buNaturalTimeDef)/sizeof(bUnitDef)};
@@ -126,14 +263,16 @@ static struct bUnitDef buNaturalRotDef[] = {
};
static struct bUnitCollection buNaturalRotCollection = {buNaturalRotDef, 0, 0, sizeof(buNaturalRotDef)/sizeof(bUnitDef)};
-#define UNIT_SYSTEM_MAX 3
-static struct bUnitCollection *bUnitSystems[][8] = {
- {0,0,0,0,0,&buNaturalRotCollection,&buNaturalTimeCollecton,0},
- {0,&buMetricLenCollecton, 0,0,0, &buNaturalRotCollection, &buNaturalTimeCollecton,0}, /* metric */
- {0,&buImperialLenCollecton, 0,0,0,&buNaturalRotCollection, &buNaturalTimeCollecton,0}, /* imperial */
- {0,0,0,0,0,0,0,0}
+#define UNIT_SYSTEM_TOT (((sizeof(bUnitSystems) / 9) / sizeof(void *)) - 1)
+static struct bUnitCollection *bUnitSystems[][9] = {
+ {0, 0, 0, 0, 0, &buNaturalRotCollection, &buNaturalTimeCollecton, 0, 0},
+ {0, &buMetricLenCollecton, &buMetricAreaCollecton, &buMetricVolCollecton, &buMetricMassCollecton, &buNaturalRotCollection, &buNaturalTimeCollecton, &buMetricVelCollecton, &buMetricAclCollecton}, /* metric */
+ {0, &buImperialLenCollecton, &buImperialAreaCollecton, &buImperialVolCollecton, &buImperialMassCollecton, &buNaturalRotCollection, &buNaturalTimeCollecton, &buImperialVelCollecton, &buImperialAclCollecton}, /* imperial */
+ {0, 0, 0, 0, 0, 0, 0, 0, 0}
};
+
+
/* internal, has some option not exposed */
static bUnitCollection *unit_get_system(int system, int type)
{
@@ -256,8 +395,9 @@ void bUnit_AsString(char *str, int len_max, double value, int prec, int system,
if(usys==NULL || usys->units[0].name==NULL)
usys= &buDummyCollecton;
-
- if(split) {
+
+ /* split output makes sense only for length, mass and time */
+ if(split && (type==B_UNIT_LENGTH || type==B_UNIT_MASS || type==B_UNIT_TIME)) {
int i;
bUnitDef *unit_a, *unit_b;
double value_a, value_b;
@@ -443,10 +583,6 @@ int bUnit_ReplaceString(char *str, int len_max, char *str_prev, double scale_pre
for(unit= usys->units; unit->name; unit++) {
-
- if(unit->flag & B_UNIT_DEF_SUPPRESS)
- continue;
-
/* incase there are multiple instances */
while(unit_replace(str, len_max, str_tmp, scale_pref, unit))
change= 1;
@@ -458,18 +594,15 @@ int bUnit_ReplaceString(char *str, int len_max, char *str_prev, double scale_pre
bUnitCollection *usys_iter;
int system_iter;
- for(system_iter= 0; system_iter<UNIT_SYSTEM_MAX; system_iter++) {
+ for(system_iter= 0; system_iter<UNIT_SYSTEM_TOT; system_iter++) {
if (system_iter != system) {
usys_iter= unit_get_system(system_iter, type);
if (usys_iter) {
for(unit= usys_iter->units; unit->name; unit++) {
-
- if((unit->flag & B_UNIT_DEF_SUPPRESS) == 0) {
- int ofs = 0;
- /* incase there are multiple instances */
- while((ofs=unit_replace(str+ofs, len_max-ofs, str_tmp, scale_pref, unit)))
- change= 1;
- }
+ int ofs = 0;
+ /* incase there are multiple instances */
+ while((ofs=unit_replace(str+ofs, len_max-ofs, str_tmp, scale_pref, unit)))
+ change= 1;
}
}
}
@@ -482,10 +615,6 @@ int bUnit_ReplaceString(char *str, int len_max, char *str_prev, double scale_pre
if(str_prev) {
/* see which units the original value had */
for(unit= usys->units; unit->name; unit++) {
-
- if(unit->flag & B_UNIT_DEF_SUPPRESS)
- continue;
-
if (unit_find(str_prev, unit))
break;
}
@@ -543,6 +672,49 @@ int bUnit_ReplaceString(char *str, int len_max, char *str_prev, double scale_pre
return change;
}
+/* 45µm --> 45um */
+void bUnit_ToUnitAltName(char *str, int len_max, char *orig_str, int system, int type)
+{
+ bUnitCollection *usys = unit_get_system(system, type);
+
+ bUnitDef *unit;
+ bUnitDef *unit_def= unit_default(usys);
+
+ /* find and substitute all units */
+ for(unit= usys->units; unit->name; unit++) {
+ if(len_max > 0 && (unit->name_alt || unit == unit_def))
+ {
+ char *found= NULL;
+
+ found= unit_find_str(orig_str, unit->name_short);
+ if(found) {
+ int offset= found - orig_str;
+ int len_name= 0;
+
+ /* copy everything before the unit */
+ offset= (offset<len_max? offset: len_max);
+ strncpy(str, orig_str, offset);
+
+ str+= offset;
+ orig_str+= offset + strlen(unit->name_short);
+ len_max-= offset;
+
+ /* print the alt_name */
+ if(unit->name_alt)
+ len_name= snprintf(str, len_max, "%s", unit->name_alt);
+ else
+ len_name= 0;
+
+ len_name= (len_name<len_max? len_name: len_max);
+ str+= len_name;
+ len_max-= len_name;
+ }
+ }
+ }
+
+ /* finally copy the rest of the string */
+ strncpy(str, orig_str, len_max);
+}
double bUnit_ClosestScalar(double value, int system, int type)
{
@@ -566,6 +738,12 @@ double bUnit_BaseScalar(int system, int type)
}
/* external access */
+int bUnit_IsValid(int system, int type)
+{
+ return !(type < 0 || type >= B_UNIT_MAXDEF || system < 0 || system > UNIT_SYSTEM_TOT);
+}
+
+
void bUnit_GetSystem(void **usys_pt, int *len, int system, int type)
{
bUnitCollection *usys = unit_get_system(system, type);
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 6cd207f628c..473c10d6ced 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -160,7 +160,7 @@ static int write_audio_frame(void)
pkt.stream_index = audio_stream->index;
pkt.flags |= PKT_FLAG_KEY;
if (av_interleaved_write_frame(outfile, &pkt) != 0) {
- // XXX error("Error writing audio packet");
+ fprintf(stderr, "Error writing audio packet!\n");
return -1;
}
return 0;
@@ -290,7 +290,9 @@ static int write_video_frame(RenderData *rd, AVFrame* frame, ReportList *reports
packet.data = video_buffer;
packet.size = outsize;
ret = av_interleaved_write_frame(outfile, &packet);
- } else ret = 0;
+ } else {
+ ret = 0;
+ }
if (ret != 0) {
success= 0;
@@ -778,6 +780,69 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
return 1;
}
+/**
+ * Writes any delayed frames in the encoder. This function is called before
+ * closing the encoder.
+ *
+ * <p>
+ * Since an encoder may use both past and future frames to predict
+ * inter-frames (H.264 B-frames, for example), it can output the frames
+ * in a different order from the one it was given.
+ * For example, when sending frames 1, 2, 3, 4 to the encoder, it may write
+ * them in the order 1, 4, 2, 3 - first the two frames used for predition,
+ * and then the bidirectionally-predicted frames. What this means in practice
+ * is that the encoder may not immediately produce one output frame for each
+ * input frame. These delayed frames must be flushed before we close the
+ * stream. We do this by calling avcodec_encode_video with NULL for the last
+ * parameter.
+ * </p>
+ */
+void flush_ffmpeg(void)
+{
+ int outsize = 0;
+ int ret = 0;
+
+ AVCodecContext* c = get_codec_from_stream(video_stream);
+ /* get the delayed frames */
+ while (1) {
+ AVPacket packet;
+ av_init_packet(&packet);
+
+ outsize = avcodec_encode_video(c, video_buffer, video_buffersize, NULL);
+ if (outsize < 0) {
+ fprintf(stderr, "Error encoding delayed frame %d\n", outsize);
+ break;
+ }
+ if (outsize == 0) {
+ break;
+ }
+ if (c->coded_frame->pts != AV_NOPTS_VALUE) {
+#ifdef FFMPEG_CODEC_TIME_BASE
+ packet.pts = av_rescale_q(c->coded_frame->pts,
+ c->time_base,
+ video_stream->time_base);
+#else
+ packet.pts = c->coded_frame->pts;
+#endif
+ fprintf(stderr, "Video Frame PTS: %d\n", (int)packet.pts);
+ } else {
+ fprintf(stderr, "Video Frame PTS: not set\n");
+ }
+ if (c->coded_frame->key_frame) {
+ packet.flags |= PKT_FLAG_KEY;
+ }
+ packet.stream_index = video_stream->index;
+ packet.data = video_buffer;
+ packet.size = outsize;
+ ret = av_interleaved_write_frame(outfile, &packet);
+ if (ret != 0) {
+ fprintf(stderr, "Error writing delayed frame %d\n", ret);
+ break;
+ }
+ }
+ avcodec_flush_buffers(get_codec_from_stream(video_stream));
+}
+
/* **********************************************************************
* public interface
********************************************************************** */
@@ -888,7 +953,6 @@ int append_ffmpeg(RenderData *rd, int frame, int *pixels, int rectx, int recty,
return success;
}
-
void end_ffmpeg(void)
{
int i;
@@ -905,6 +969,11 @@ void end_ffmpeg(void)
audio_mixdown_device = 0;
}
+ if (video_stream && get_codec_from_stream(video_stream)) {
+ fprintf(stderr, "Flushing delayed frames...\n");
+ flush_ffmpeg ();
+ }
+
if (outfile) {
av_write_trailer(outfile);
}
@@ -913,8 +982,8 @@ void end_ffmpeg(void)
if (video_stream && get_codec_from_stream(video_stream)) {
avcodec_close(get_codec_from_stream(video_stream));
- video_stream = 0;
printf("zero video stream %p\n", video_stream);
+ video_stream = 0;
}
@@ -1195,20 +1264,47 @@ void ffmpeg_set_preset(RenderData *rd, int preset)
rd->ffcodecdata.mux_packet_size = 2048;
rd->ffcodecdata.mux_rate = 10080000;
+ /*
+ * All options here are for x264, but must be set via ffmpeg.
+ * The names are therefore different - Search for "x264 to FFmpeg option mapping"
+ * to get a list.
+ */
+
+ /*
+ * Use CABAC coder. Using "coder:1", which should be equivalent,
+ * crashes Blender for some reason. Either way - this is no big deal.
+ */
ffmpeg_property_add_string(rd, "video", "coder:vlc");
+
+ /*
+ * The other options were taken from the libx264-default.preset
+ * included in the ffmpeg distribution.
+ */
ffmpeg_property_add_string(rd, "video", "flags:loop");
ffmpeg_property_add_string(rd, "video", "cmp:chroma");
ffmpeg_property_add_string(rd, "video", "partitions:parti4x4");
ffmpeg_property_add_string(rd, "video", "partitions:partp8x8");
ffmpeg_property_add_string(rd, "video", "partitions:partb8x8");
ffmpeg_property_add_string(rd, "video", "me:hex");
- ffmpeg_property_add_string(rd, "video", "subq:5");
+ ffmpeg_property_add_string(rd, "video", "subq:6");
ffmpeg_property_add_string(rd, "video", "me_range:16");
+ ffmpeg_property_add_string(rd, "video", "qdiff:4");
ffmpeg_property_add_string(rd, "video", "keyint_min:25");
ffmpeg_property_add_string(rd, "video", "sc_threshold:40");
ffmpeg_property_add_string(rd, "video", "i_qfactor:0.71");
ffmpeg_property_add_string(rd, "video", "b_strategy:1");
-
+ ffmpeg_property_add_string(rd, "video", "bf:3");
+ ffmpeg_property_add_string(rd, "video", "refs:2");
+ ffmpeg_property_add_string(rd, "video", "qcomp:0.6");
+ ffmpeg_property_add_string(rd, "video", "directpred:3");
+ ffmpeg_property_add_string(rd, "video", "trellis:0");
+ ffmpeg_property_add_string(rd, "video", "flags2:wpred");
+ ffmpeg_property_add_string(rd, "video", "flags2:dct8x8");
+ ffmpeg_property_add_string(rd, "video", "flags2:fastpskip");
+ ffmpeg_property_add_string(rd, "video", "wpredp:2");
+
+ // This makes x264 output lossless. Will be a separate option later.
+ //ffmpeg_property_add_string(rd, "video", "cqp:0");
break;
case FFMPEG_PRESET_THEORA: