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
path: root/source
diff options
context:
space:
mode:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2011-03-13 05:10:39 +0300
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2011-03-13 05:10:39 +0300
commitc8deda32763d68b59d28f00734785dc0c7a91571 (patch)
treed5b7320d79136c7c2d0282fe45ec3be619ec6806 /source
parent33efa9eeb63db672d9da97b68718aefb14b98f64 (diff)
parent25a2eb4675f8e1fcf8b990bc345aac694dba8228 (diff)
Merged changes in the trunk up to revision 35505.
Conflicts resolved: source/blender/makesdna/DNA_material_types.h
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c2
-rw-r--r--source/blender/blenkernel/BKE_blender.h2
-rw-r--r--source/blender/blenkernel/BKE_idcode.h8
-rw-r--r--source/blender/blenkernel/BKE_node.h2
-rw-r--r--source/blender/blenkernel/BKE_paint.h9
-rw-r--r--source/blender/blenkernel/BKE_particle.h2
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h2
-rw-r--r--source/blender/blenkernel/intern/anim.c6
-rw-r--r--source/blender/blenkernel/intern/brush.c51
-rw-r--r--source/blender/blenkernel/intern/idcode.c5
-rw-r--r--source/blender/blenkernel/intern/idprop.c2
-rw-r--r--source/blender/blenkernel/intern/node.c6
-rw-r--r--source/blender/blenkernel/intern/particle.c112
-rw-r--r--source/blender/blenkernel/intern/particle_system.c1402
-rw-r--r--source/blender/blenkernel/intern/pointcache.c41
-rw-r--r--source/blender/blenkernel/intern/sequencer.c6
-rw-r--r--source/blender/blenlib/BLI_math_rotation.h2
-rw-r--r--source/blender/blenlib/BLI_path_util.h3
-rw-r--r--source/blender/blenlib/intern/math_rotation.c2
-rw-r--r--source/blender/blenlib/intern/path_util.c66
-rw-r--r--source/blender/blenloader/BLO_readfile.h22
-rw-r--r--source/blender/blenloader/intern/readblenentry.c13
-rw-r--r--source/blender/blenloader/intern/readfile.c72
-rw-r--r--source/blender/collada/AnimationImporter.cpp3
-rw-r--r--source/blender/collada/DocumentImporter.cpp33
-rw-r--r--source/blender/collada/MeshImporter.cpp73
-rw-r--r--source/blender/collada/MeshImporter.h1
-rw-r--r--source/blender/editors/animation/anim_markers.c23
-rw-r--r--source/blender/editors/animation/keyframes_general.c46
-rw-r--r--source/blender/editors/include/ED_screen.h4
-rw-r--r--source/blender/editors/include/ED_uvedit.h6
-rw-r--r--source/blender/editors/include/ED_view3d.h5
-rw-r--r--source/blender/editors/include/UI_interface.h1
-rw-r--r--source/blender/editors/interface/interface_handlers.c28
-rw-r--r--source/blender/editors/mesh/editmesh_mods.c19
-rw-r--r--source/blender/editors/render/render_opengl.c19
-rw-r--r--source/blender/editors/render/render_preview.c4
-rw-r--r--source/blender/editors/screen/area.c22
-rw-r--r--source/blender/editors/screen/screen_edit.c11
-rw-r--r--source/blender/editors/screen/screen_ops.c24
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c33
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c258
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c4
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c2
-rw-r--r--source/blender/editors/space_file/file_ops.c10
-rw-r--r--source/blender/editors/space_file/filelist.c9
-rw-r--r--source/blender/editors/space_file/space_file.c4
-rw-r--r--source/blender/editors/space_graph/graph_select.c23
-rw-r--r--source/blender/editors/space_image/image_ops.c4
-rw-r--r--source/blender/editors/space_node/node_draw.c6
-rw-r--r--source/blender/editors/space_sequencer/sequencer_ops.c11
-rw-r--r--source/blender/editors/space_userpref/space_userpref.c5
-rw-r--r--source/blender/editors/space_view3d/drawobject.c89
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c1
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c21
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c20
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c18
-rw-r--r--source/blender/editors/transform/transform.c18
-rw-r--r--source/blender/editors/transform/transform_conversions.c42
-rw-r--r--source/blender/editors/util/undo.c3
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c42
-rw-r--r--source/blender/gpu/GPU_extensions.h10
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c4
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c71
-rw-r--r--source/blender/gpu/intern/gpu_material.c4
-rw-r--r--source/blender/makesdna/DNA_material_types.h9
-rw-r--r--source/blender/makesdna/DNA_particle_types.h38
-rw-r--r--source/blender/makesdna/DNA_scene_types.h6
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h6
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c8
-rw-r--r--source/blender/makesrna/intern/rna_image.c2
-rw-r--r--source/blender/makesrna/intern/rna_material.c13
-rw-r--r--source/blender/makesrna/intern/rna_particle.c125
-rw-r--r--source/blender/makesrna/intern/rna_scene.c8
-rw-r--r--source/blender/modifiers/intern/MOD_particlesystem.c2
-rw-r--r--source/blender/modifiers/intern/MOD_smoke.c2
-rw-r--r--source/blender/modifiers/intern/MOD_solidify.c13
-rw-r--r--source/blender/modifiers/intern/MOD_subsurf.c2
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_math.c2
-rw-r--r--source/blender/nodes/intern/SHD_nodes/SHD_material.c2
-rw-r--r--source/blender/nodes/intern/SHD_nodes/SHD_math.c4
-rw-r--r--source/blender/nodes/intern/SHD_nodes/SHD_output.c2
-rw-r--r--source/blender/nodes/intern/SHD_nodes/SHD_texture.c2
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_math.c2
-rw-r--r--source/blender/nodes/intern/TEX_util.c2
-rw-r--r--source/blender/python/generic/bpy_internal_import.c13
-rw-r--r--source/blender/python/generic/bpy_internal_import.h2
-rw-r--r--source/blender/python/generic/py_capi_utils.c36
-rw-r--r--source/blender/python/intern/CMakeLists.txt1
-rw-r--r--source/blender/python/intern/bpy.c7
-rw-r--r--source/blender/python/intern/bpy_interface.c8
-rw-r--r--source/blender/python/intern/bpy_library.c343
-rw-r--r--source/blender/python/intern/bpy_operator.c3
-rw-r--r--source/blender/python/intern/bpy_rna.c41
-rw-r--r--source/blender/python/intern/bpy_rna_anim.c8
-rw-r--r--source/blender/python/intern/bpy_util.c6
-rw-r--r--source/blender/python/intern/bpy_util.h6
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h1
-rw-r--r--source/blender/render/intern/raytrace/bvh.h3
-rw-r--r--source/blender/render/intern/raytrace/rayobject_qbvh.cpp9
-rw-r--r--source/blender/render/intern/raytrace/rayobject_rtbuild.cpp12
-rw-r--r--source/blender/render/intern/raytrace/rayobject_svbvh.cpp8
-rw-r--r--source/blender/render/intern/raytrace/rayobject_vbvh.cpp18
-rw-r--r--source/blender/render/intern/raytrace/vbvh.h7
-rw-r--r--source/blender/render/intern/source/convertblender.c25
-rw-r--r--source/blender/render/intern/source/rayshade.c14
-rw-r--r--source/blender/render/intern/source/shadeinput.c5
-rw-r--r--source/blender/render/intern/source/shadeoutput.c107
-rw-r--r--source/blender/render/intern/source/strand.c29
-rw-r--r--source/blender/windowmanager/WM_types.h1
-rw-r--r--source/blender/windowmanager/intern/wm_cursors.c24
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c33
-rw-r--r--source/blender/windowmanager/intern/wm_files.c4
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c53
-rw-r--r--source/blender/windowmanager/wm_cursors.h6
-rw-r--r--source/creator/CMakeLists.txt587
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp2
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.cpp7
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.cpp5
-rw-r--r--source/gameengine/GameLogic/SCA_PythonController.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_PolygonMaterial.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_PyConstraintBinding.cpp17
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp16
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h2
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h1
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp2
-rw-r--r--source/gameengine/Rasterizer/RAS_IRasterizer.h6
-rw-r--r--source/tests/pep8.py2
132 files changed, 2758 insertions, 1864 deletions
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index b9154951fb1..e165012f43e 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -135,6 +135,8 @@ void blf_glyph_cache_clear(FontBLF *font)
}
}
}
+
+ memset(font->glyph_ascii_table, 0, sizeof(font->glyph_ascii_table));
}
void blf_glyph_cache_free(GlyphCacheBLF *gc)
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index f6bb4fbb635..6cbc49e19c8 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -44,7 +44,7 @@ extern "C" {
* and keep comment above the defines.
* Use STRINGIFY() rather then defining with quotes */
#define BLENDER_VERSION 256
-#define BLENDER_SUBVERSION 2
+#define BLENDER_SUBVERSION 3
#define BLENDER_MINVERSION 250
#define BLENDER_MINSUBVERSION 0
diff --git a/source/blender/blenkernel/BKE_idcode.h b/source/blender/blenkernel/BKE_idcode.h
index 1b2b3d2ee95..e46ad450c31 100644
--- a/source/blender/blenkernel/BKE_idcode.h
+++ b/source/blender/blenkernel/BKE_idcode.h
@@ -76,4 +76,12 @@ int BKE_idcode_is_linkable(int code);
*/
int BKE_idcode_is_valid(int code);
+/**
+ * Return an ID code and steps the index forward 1.
+ *
+ * @param index, start as 0.
+ * @return the code, 0 when all codes have been returned.
+ */
+int BKE_idcode_iter_step(int *index);
+
#endif
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 41e41eab78f..a126f405d09 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -168,7 +168,7 @@ void ntreeLocalMerge(struct bNodeTree *localtree, struct bNodeTree *ntree);
void nodeVerifyType(struct bNodeTree *ntree, struct bNode *node);
-void nodeAddToPreview(struct bNode *, float *, int, int);
+void nodeAddToPreview(struct bNode *, float *, int, int, int);
void nodeUnlinkNode(struct bNodeTree *ntree, struct bNode *node);
void nodeUniqueName(struct bNodeTree *ntree, struct bNode *node);
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 238c812906d..ef16129e1e7 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -32,8 +32,6 @@
* \ingroup bke
*/
-#include "DNA_vec_types.h"
-
struct Brush;
struct MFace;
struct MultireModifierData;
@@ -65,15 +63,12 @@ int paint_facesel_test(struct Object *ob);
/* Session data (mode-specific) */
typedef struct SculptSession {
- struct ProjVert *projverts;
-
/* Mesh data (not copied) can come either directly from a Mesh, or from a MultiresDM */
struct MultiresModifierData *multires; /* Special handling for multires meshes */
struct MVert *mvert;
struct MFace *mface;
int totvert, totface;
float *face_normals;
- struct Object *ob;
struct KeyBlock *kb;
/* Mesh connectivity */
@@ -99,10 +94,6 @@ typedef struct SculptSession {
struct SculptStroke *stroke;
struct StrokeCache *cache;
-
- struct GPUDrawObject *drawobject;
-
- rcti previous_r;
} SculptSession;
void free_sculptsession(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 507adcc5f2d..e4fbd5603f2 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -242,7 +242,7 @@ void psys_get_particle_on_path(struct ParticleSimulationData *sim, int pa_num, s
int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, int always);
/* for anim.c */
-void psys_get_dupli_texture(struct Object *ob, struct ParticleSettings *part, struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, float *uv, float *orco);
+void psys_get_dupli_texture(struct ParticleSystem *psys, struct ParticleSettings *part, struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, float *uv, float *orco);
void psys_get_dupli_path_transform(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ChildParticle *cpa, struct ParticleCacheKey *cache, float mat[][4], float *scale);
ParticleThread *psys_threads_create(struct ParticleSimulationData *sim);
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index cc1d8537cbd..c53871cabd2 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -322,7 +322,7 @@ struct Sequence *sequencer_add_sound_strip(struct bContext *C, ListBase *seqbase
struct Sequence *sequencer_add_movie_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load);
/* view3d draw callback, run when not in background view */
-typedef struct ImBuf *(*SequencerDrawView)(struct Scene *, int, int, unsigned int, int);
+typedef struct ImBuf *(*SequencerDrawView)(struct Scene *, int, int, unsigned int, int, char[256]);
extern SequencerDrawView sequencer_view3d_cb;
/* copy/paste */
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 39fea333cbc..2e1fbf2917a 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -1346,8 +1346,6 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
/* for groups, pick the object based on settings */
if(part->draw&PART_DRAW_RAND_GR)
b= BLI_rand() % totgroup;
- else if(part->from==PART_FROM_PARTICLE)
- b= pa_num % totgroup;
else
b= a % totgroup;
@@ -1402,7 +1400,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS, animated);
copy_m4_m4(dob->omat, obcopylist[b].obmat);
if(G.rendering)
- psys_get_dupli_texture(par, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
+ psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
}
}
else {
@@ -1434,7 +1432,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
dob= new_dupli_object(lb, ob, mat, ob->lay, counter, GS(id->name) == ID_GR ? OB_DUPLIGROUP : OB_DUPLIPARTS, animated);
copy_m4_m4(dob->omat, oldobmat);
if(G.rendering)
- psys_get_dupli_texture(par, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
+ psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
}
}
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index f4d117d8a07..869123de97f 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -732,6 +732,12 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf, i
dotexold = (oldtexibuf != NULL);
+ /* not sure if it's actually needed or it's a mistake in coords/sizes
+ calculation in brush_painter_fixed_tex_partial_update(), but without this
+ limitation memory gets corrupted at fast strokes with quite big spacing (sergey) */
+ w = MIN2(w, ibuf->x);
+ h = MIN2(h, ibuf->y);
+
if (painter->cache.flt) {
for (; y < h; y++) {
bf = ibuf->rect_float + (y*ibuf->x + origx)*4;
@@ -1018,29 +1024,42 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
len= normalize_v2(dmousepos);
painter->accumdistance += len;
- /* do paint op over unpainted distance */
- while ((len > 0.0f) && (painter->accumdistance >= spacing)) {
- step= spacing - startdistance;
- paintpos[0]= painter->lastmousepos[0] + dmousepos[0]*step;
- paintpos[1]= painter->lastmousepos[1] + dmousepos[1]*step;
+ if (brush->flag & BRUSH_SPACE) {
+ /* do paint op over unpainted distance */
+ while ((len > 0.0f) && (painter->accumdistance >= spacing)) {
+ step= spacing - startdistance;
+ paintpos[0]= painter->lastmousepos[0] + dmousepos[0]*step;
+ paintpos[1]= painter->lastmousepos[1] + dmousepos[1]*step;
+
+ t = step/len;
+ press= (1.0f-t)*painter->lastpressure + t*pressure;
+ brush_apply_pressure(painter, brush, press);
+ spacing= MAX2(1.0f, radius)*brush->spacing*0.01f;
+
+ brush_jitter_pos(brush, paintpos, finalpos);
+
+ if (painter->cache.enabled)
+ brush_painter_refresh_cache(painter, finalpos);
- t = step/len;
- press= (1.0f-t)*painter->lastpressure + t*pressure;
- brush_apply_pressure(painter, brush, press);
- spacing= MAX2(1.0f, radius)*brush->spacing*0.01f;
+ totpaintops +=
+ func(user, painter->cache.ibuf, painter->lastpaintpos, finalpos);
- brush_jitter_pos(brush, paintpos, finalpos);
+ painter->lastpaintpos[0]= paintpos[0];
+ painter->lastpaintpos[1]= paintpos[1];
+ painter->accumdistance -= spacing;
+ startdistance -= spacing;
+ }
+ } else {
+ brush_jitter_pos(brush, pos, finalpos);
if (painter->cache.enabled)
brush_painter_refresh_cache(painter, finalpos);
- totpaintops +=
- func(user, painter->cache.ibuf, painter->lastpaintpos, finalpos);
+ totpaintops += func(user, painter->cache.ibuf, pos, finalpos);
- painter->lastpaintpos[0]= paintpos[0];
- painter->lastpaintpos[1]= paintpos[1];
- painter->accumdistance -= spacing;
- startdistance -= spacing;
+ painter->lastpaintpos[0]= pos[0];
+ painter->lastpaintpos[1]= pos[1];
+ painter->accumdistance= 0;
}
/* do airbrush paint ops, based on the number of paint ops left over
diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c
index 1b3d43e1f49..ba5a49daf52 100644
--- a/source/blender/blenkernel/intern/idcode.c
+++ b/source/blender/blenkernel/intern/idcode.c
@@ -134,3 +134,8 @@ const char *BKE_idcode_to_name_plural(int code)
return idt?idt->plural:NULL;
}
+
+int BKE_idcode_iter_step(int *index)
+{
+ return (*index < nidtypes) ? idtypes[(*index)++].code : 0;
+}
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 40d12e06320..67be3e71101 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -240,7 +240,7 @@ void IDP_ResizeArray(IDProperty *prop, int newlen)
else {
/* newlen is smaller*/
idp_resize_group_array(prop, newlen, newarr);
- memcpy(newarr, prop->data.pointer, newlen*prop->len*idp_size_table[(int)prop->subtype]);
+ memcpy(newarr, prop->data.pointer, newlen*idp_size_table[(int)prop->subtype]);
}
MEM_freeN(prop->data.pointer);
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 1f8cd1ca152..ccb38ca7ce1 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1325,7 +1325,7 @@ void ntreeClearPreview(bNodeTree *ntree)
/* hack warning! this function is only used for shader previews, and
since it gets called multiple times per pixel for Ztransp we only
add the color once. Preview gets cleared before it starts render though */
-void nodeAddToPreview(bNode *node, float *col, int x, int y)
+void nodeAddToPreview(bNode *node, float *col, int x, int y, int do_manage)
{
bNodePreview *preview= node->preview;
if(preview) {
@@ -1333,7 +1333,7 @@ void nodeAddToPreview(bNode *node, float *col, int x, int y)
if(x<preview->xsize && y<preview->ysize) {
unsigned char *tar= preview->rect+ 4*((preview->xsize*y) + x);
- if(TRUE) {
+ if(do_manage) {
tar[0]= FTOCHAR(linearrgb_to_srgb(col[0]));
tar[1]= FTOCHAR(linearrgb_to_srgb(col[1]));
tar[2]= FTOCHAR(linearrgb_to_srgb(col[2]));
@@ -2333,7 +2333,7 @@ void ntreeBeginExecTree(bNodeTree *ntree)
ns->hasoutput = 1;
/* sock type is needed to detect rgba or value or vector types */
- if(sock->link)
+ if(sock->link && sock->link->fromsock)
ns->sockettype= sock->link->fromsock->type;
else
sock->ns.sockettype= sock->type;
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 48c29d5e96f..fcea0ffb6cf 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -571,6 +571,7 @@ void psys_free(Object *ob, ParticleSystem * psys)
BLI_freelistN(&psys->targets);
+ BLI_bvhtree_free(psys->bvhtree);
BLI_kdtree_free(psys->tree);
if(psys->fluid_springs)
@@ -2407,7 +2408,7 @@ static int psys_threads_init_path(ParticleThread *threads, Scene *scene, float c
steps = (int)pow(2.0, (double)pset->draw_step);
}
- if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
+ if(totchild && part->childtype==PART_CHILD_FACES){
totparent=(int)(totchild*part->parents*0.3);
if(G.rendering && part->child_nbr && part->ren_child_nbr)
@@ -2449,16 +2450,14 @@ static int psys_threads_init_path(ParticleThread *threads, Scene *scene, float c
psys->lattice = psys_get_lattice(&ctx->sim);
/* cache all relevant vertex groups if they exist */
- if(part->from!=PART_FROM_PARTICLE){
- ctx->vg_length = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_LENGTH);
- ctx->vg_clump = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_CLUMP);
- ctx->vg_kink = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_KINK);
- ctx->vg_rough1 = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_ROUGH1);
- ctx->vg_rough2 = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_ROUGH2);
- ctx->vg_roughe = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_ROUGHE);
- if(psys->part->flag & PART_CHILD_EFFECT)
- ctx->vg_effector = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_EFFECTOR);
- }
+ ctx->vg_length = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_LENGTH);
+ ctx->vg_clump = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_CLUMP);
+ ctx->vg_kink = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_KINK);
+ ctx->vg_rough1 = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_ROUGH1);
+ ctx->vg_rough2 = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_ROUGH2);
+ ctx->vg_roughe = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_ROUGHE);
+ if(psys->part->flag & PART_CHILD_EFFECT)
+ ctx->vg_effector = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_EFFECTOR);
/* set correct ipo timing */
#if 0 // XXX old animation system
@@ -2705,7 +2704,7 @@ static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle
sub_v3_v3v3((child-1)->vel, child->co, (child-2)->co);
mul_v3_fl((child-1)->vel, 0.5);
- if(ctx->ma && (part->draw & PART_DRAW_MAT_COL))
+ if(ctx->ma && (part->draw_col == PART_DRAW_COL_MAT))
get_strand_normal(ctx->ma, ornor, cur_length, (child-1)->vel);
}
@@ -2724,7 +2723,7 @@ static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle
cur_length = 0.0f;
}
- if(ctx->ma && (part->draw & PART_DRAW_MAT_COL)) {
+ if(ctx->ma && (part->draw_col == PART_DRAW_COL_MAT)) {
VECCOPY(child->col, &ctx->ma->r)
get_strand_normal(ctx->ma, ornor, cur_length, child->vel);
}
@@ -2909,11 +2908,11 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
psys->lattice = psys_get_lattice(sim);
ma= give_current_material(sim->ob, psys->part->omat);
- if(ma && (psys->part->draw & PART_DRAW_MAT_COL))
+ if(ma && (psys->part->draw_col == PART_DRAW_COL_MAT))
VECCOPY(col, &ma->r)
- if(psys->part->from!=PART_FROM_PARTICLE && !(psys->flag & PSYS_GLOBAL_HAIR)) {
- if(!(psys->part->flag & PART_CHILD_EFFECT))
+ if((psys->flag & PSYS_GLOBAL_HAIR)==0) {
+ if((psys->part->flag & PART_CHILD_EFFECT)==0)
vg_effector = psys_cache_vgroup(psmd->dm, psys, PSYS_VG_EFFECTOR);
if(!psys->totchild)
@@ -3347,7 +3346,8 @@ static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float m
/* ugly hack to use non-transformed orcos, since only those
* give symmetric results for mirroring in particle mode */
- transform_mesh_orco_verts(ob->data, v, 3, 1);
+ if(DM_get_vert_data_layer(dm, CD_ORIGINDEX))
+ transform_mesh_orco_verts(ob->data, v, 3, 1);
}
else {
dm->getVertCo(dm,mface->v1,v[0]);
@@ -3375,7 +3375,8 @@ void psys_mat_hair_to_orco(Object *ob, DerivedMesh *dm, short from, ParticleData
psys_particle_on_dm(dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, orco, 0);
/* see psys_face_mat for why this function is called */
- transform_mesh_orco_verts(ob->data, &orco, 1, 1);
+ if(DM_get_vert_data_layer(dm, CD_ORIGINDEX))
+ transform_mesh_orco_verts(ob->data, &orco, 1, 1);
VECCOPY(hairmat[3],orco);
}
@@ -3535,16 +3536,15 @@ static void default_particle_settings(ParticleSettings *part)
part->clength=1.0f;
part->clength_thres=0.0f;
- part->draw= PART_DRAW_EMITTER|PART_DRAW_MAT_COL;
+ part->draw= PART_DRAW_EMITTER;
part->draw_line[0]=0.5;
part->path_start = 0.0f;
part->path_end = 1.0f;
part->keyed_loops = 1;
-#if 0 // XXX old animation system
- part->ipo = NULL;
-#endif // XXX old animation system
+ part->color_vec_max = 1.f;
+ part->draw_col = PART_DRAW_COL_MAT;
part->simplify_refsize= 1920;
part->simplify_rate= 1.0f;
@@ -4040,7 +4040,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
if(state->time < 0.0f)
t = psys_get_child_time(psys, cpa, -state->time, NULL, NULL);
- if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
+ if(totchild && part->childtype==PART_CHILD_FACES){
/* part->parents could still be 0 so we can't test with totparent */
between=1;
}
@@ -4190,7 +4190,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
if(!psys->totchild)
return 0;
- if(part->from != PART_FROM_PARTICLE && part->childtype == PART_CHILD_FACES){
+ if(part->childtype == PART_CHILD_FACES){
if(!(psys->flag & PSYS_KEYED))
return 0;
@@ -4312,13 +4312,15 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
}
}
-void psys_get_dupli_texture(Object *UNUSED(ob), ParticleSettings *part, ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, float *uv, float *orco)
+void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part, ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, float *uv, float *orco)
{
MFace *mface;
MTFace *mtface;
float loc[3];
int num;
+ uv[0] = uv[1] = 0.f;
+
if(cpa) {
if(part->childtype == PART_CHILD_FACES) {
mtface= CustomData_get_layer(&psmd->dm->faceData, CD_MTFACE);
@@ -4327,43 +4329,36 @@ void psys_get_dupli_texture(Object *UNUSED(ob), ParticleSettings *part, Particle
mtface += cpa->num;
psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, uv);
}
- else
- uv[0]= uv[1]= 0.0f;
+
+ psys_particle_on_emitter(psmd,PART_FROM_FACE,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,loc,0,0,0,orco,0);
+ return;
+ }
+ else {
+ pa = psys->particles + cpa->pa[0];
}
- else
- uv[0]= uv[1]= 0.0f;
-
- psys_particle_on_emitter(psmd,
- (part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE,
- cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,loc,0,0,0,orco,0);
}
- else {
- if(part->from == PART_FROM_FACE) {
- mtface= CustomData_get_layer(&psmd->dm->faceData, CD_MTFACE);
- num= pa->num_dmcache;
- if(num == DMCACHE_NOTFOUND)
- num= pa->num;
+ if(part->from == PART_FROM_FACE) {
+ mtface= CustomData_get_layer(&psmd->dm->faceData, CD_MTFACE);
+ num= pa->num_dmcache;
- if (num >= psmd->dm->getNumFaces(psmd->dm)) {
- /* happens when simplify is enabled
- * gives invalid coords but would crash otherwise */
- num= DMCACHE_NOTFOUND;
- }
+ if(num == DMCACHE_NOTFOUND)
+ num= pa->num;
- if(mtface && num != DMCACHE_NOTFOUND) {
- mface= psmd->dm->getFaceData(psmd->dm, num, CD_MFACE);
- mtface += num;
- psys_interpolate_uvs(mtface, mface->v4, pa->fuv, uv);
- }
- else
- uv[0]= uv[1]= 0.0f;
+ if (num >= psmd->dm->getNumFaces(psmd->dm)) {
+ /* happens when simplify is enabled
+ * gives invalid coords but would crash otherwise */
+ num= DMCACHE_NOTFOUND;
}
- else
- uv[0]= uv[1]= 0.0f;
- psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,orco,0);
+ if(mtface && num != DMCACHE_NOTFOUND) {
+ mface= psmd->dm->getFaceData(psmd->dm, num, CD_MFACE);
+ mtface += num;
+ psys_interpolate_uvs(mtface, mface->v4, pa->fuv, uv);
+ }
}
+
+ psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,orco,0);
}
void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa, ChildParticle *cpa, ParticleCacheKey *cache, float mat[][4], float *scale)
@@ -4378,7 +4373,7 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa
len= normalize_v3(vec);
if(psys->part->rotmode) {
- if(!pa)
+ if(pa == NULL)
pa= psys->particles+cpa->pa[0];
vec_to_quat( q,xvec, ob->trackflag, ob->upflag);
@@ -4389,12 +4384,13 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa
mul_m4_m4m4(mat, obrotmat, qmat);
}
else {
+ if(pa == NULL && psys->part->childflat != PART_CHILD_FACES)
+ pa = psys->particles + cpa->pa[0];
+
if(pa)
psys_particle_on_emitter(psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,nor,0,0,0,0);
else
- psys_particle_on_emitter(psmd,
- (psys->part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE,
- cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,loc,nor,0,0,0,0);
+ psys_particle_on_emitter(psmd,PART_FROM_FACE,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,loc,nor,0,0,0,0);
copy_m3_m4(nmat, ob->imat);
transpose_m3(nmat);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 336b683e26b..56291ad753c 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -329,6 +329,10 @@ static void alloc_child_particles(ParticleSystem *psys, int tot)
}
}
+/************************************************/
+/* Distribution */
+/************************************************/
+
void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
{
/* use for building derived mesh mapping info:
@@ -405,7 +409,36 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
}
}
-static void distribute_particles_in_grid(DerivedMesh *dm, ParticleSystem *psys)
+static void distribute_simple_children(Scene *scene, Object *ob, DerivedMesh *finaldm, ParticleSystem *psys)
+{
+ ChildParticle *cpa = NULL;
+ int i, p;
+ int child_nbr= get_psys_child_number(scene, psys);
+ int totpart= get_psys_tot_child(scene, psys);
+
+ alloc_child_particles(psys, totpart);
+
+ cpa = psys->child;
+ for(i=0; i<child_nbr; i++){
+ for(p=0; p<psys->totpart; p++,cpa++){
+ float length=2.0;
+ cpa->parent=p;
+
+ /* create even spherical distribution inside unit sphere */
+ while(length>=1.0f){
+ cpa->fuv[0]=2.0f*BLI_frand()-1.0f;
+ cpa->fuv[1]=2.0f*BLI_frand()-1.0f;
+ cpa->fuv[2]=2.0f*BLI_frand()-1.0f;
+ length=len_v3(cpa->fuv);
+ }
+
+ cpa->num=-1;
+ }
+ }
+ /* dmcache must be updated for parent particles if children from faces is used */
+ psys_calc_dmcache(ob, finaldm, psys);
+}
+static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys)
{
ParticleData *pa=NULL;
float min[3], max[3], delta[3], d;
@@ -686,7 +719,7 @@ static void psys_uv_to_w(float u, float v, int quad, float *w)
}
/* Find the index in "sum" array before "value" is crossed. */
-static int binary_search_distribution(float *sum, int n, float value)
+static int distribute_binary_search(float *sum, int n, float value)
{
int mid, low=0, high=n;
@@ -716,13 +749,11 @@ static int binary_search_distribution(float *sum, int n, float value)
/* note: this function must be thread safe, for from == PART_FROM_CHILD */
#define ONLY_WORKING_WITH_PA_VERTS 0
-static void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, ChildParticle *cpa, int p)
+static void distribute_threads_exec(ParticleThread *thread, ParticleData *pa, ChildParticle *cpa, int p)
{
ParticleThreadContext *ctx= thread->ctx;
Object *ob= ctx->sim.ob;
DerivedMesh *dm= ctx->dm;
- ParticleData *tpa;
-/* ParticleSettings *part= ctx->sim.psys->part; */
float *v1, *v2, *v3, *v4, nor[3], orco1[3], co1[3], co2[3], nor1[3];
float cur_d, min_d, randu, randv;
int from= ctx->from;
@@ -760,9 +791,17 @@ static void psys_thread_distribute_particle(ParticleThread *thread, ParticleData
switch(distr){
case PART_DISTR_JIT:
- ctx->jitoff[i] = fmod(ctx->jitoff[i],(float)ctx->jitlevel);
- psys_uv_to_w(ctx->jit[2*(int)ctx->jitoff[i]], ctx->jit[2*(int)ctx->jitoff[i]+1], mface->v4, pa->fuv);
- ctx->jitoff[i]++;
+ if(ctx->jitlevel == 1) {
+ if(mface->v4)
+ psys_uv_to_w(0.5f, 0.5f, mface->v4, pa->fuv);
+ else
+ psys_uv_to_w(0.33333f, 0.33333f, mface->v4, pa->fuv);
+ }
+ else {
+ ctx->jitoff[i] = fmod(ctx->jitoff[i],(float)ctx->jitlevel);
+ psys_uv_to_w(ctx->jit[2*(int)ctx->jitoff[i]], ctx->jit[2*(int)ctx->jitoff[i]+1], mface->v4, pa->fuv);
+ ctx->jitoff[i]++;
+ }
break;
case PART_DISTR_RAND:
randu= rng_getFloat(thread->rng);
@@ -828,15 +867,6 @@ static void psys_thread_distribute_particle(ParticleThread *thread, ParticleData
}
}
}
- else if(from == PART_FROM_PARTICLE) {
- tpa=ctx->tpars+ctx->index[p];
- pa->num=ctx->index[p];
- pa->fuv[0]=tpa->fuv[0];
- pa->fuv[1]=tpa->fuv[1];
- /* abusing foffset a little for timing in near reaction */
- pa->foffset=ctx->weight[ctx->index[p]];
- ctx->weight[ctx->index[p]]+=ctx->maxweight;
- }
else if(from == PART_FROM_CHILD) {
MFace *mf;
@@ -870,7 +900,6 @@ static void psys_thread_distribute_particle(ParticleThread *thread, ParticleData
maxd=ptn[maxw-1].dist;
mind=ptn[0].dist;
- /*dd=maxd-mind;*/ /*UNUSED*/
/* the weights here could be done better */
for(w=0; w<maxw; w++){
@@ -906,7 +935,7 @@ static void psys_thread_distribute_particle(ParticleThread *thread, ParticleData
rng_skip(thread->rng, rng_skip_tot);
}
-static void *exec_distribution(void *data)
+static void *distribute_threads_exec_cb(void *data)
{
ParticleThread *thread= (ParticleThread*)data;
ParticleSystem *psys= thread->ctx->sim.psys;
@@ -923,7 +952,7 @@ static void *exec_distribution(void *data)
rng_skip(thread->rng, PSYS_RND_DIST_SKIP * thread->ctx->skip[p]);
if((p+thread->num) % thread->tot == 0)
- psys_thread_distribute_particle(thread, NULL, cpa, p);
+ distribute_threads_exec(thread, NULL, cpa, p);
else /* thread skip */
rng_skip(thread->rng, PSYS_RND_DIST_SKIP);
}
@@ -932,7 +961,7 @@ static void *exec_distribution(void *data)
totpart= psys->totpart;
pa= psys->particles + thread->num;
for(p=thread->num; p<totpart; p+=thread->tot, pa+=thread->tot)
- psys_thread_distribute_particle(thread, pa, NULL, p);
+ distribute_threads_exec(thread, pa, NULL, p);
}
return 0;
@@ -940,7 +969,7 @@ static void *exec_distribution(void *data)
/* not thread safe, but qsort doesn't take userdata argument */
static int *COMPARE_ORIG_INDEX = NULL;
-static int compare_orig_index(const void *p1, const void *p2)
+static int distribute_compare_orig_index(const void *p1, const void *p2)
{
int index1 = COMPARE_ORIG_INDEX[*(const int*)p1];
int index2 = COMPARE_ORIG_INDEX[*(const int*)p2];
@@ -961,44 +990,53 @@ static int compare_orig_index(const void *p1, const void *p2)
return 1;
}
-/* creates a distribution of coordinates on a DerivedMesh */
-/* */
-/* 1. lets check from what we are emitting */
-/* 2. now we know that we have something to emit from so */
-/* let's calculate some weights */
-/* 2.1 from even distribution */
-/* 2.2 and from vertex groups */
-/* 3. next we determine the indexes of emitting thing that */
-/* the particles will have */
-/* 4. let's do jitter if we need it */
-/* 5. now we're ready to set the indexes & distributions to */
-/* the particles */
-/* 6. and we're done! */
+static void distribute_invalid(Scene *scene, ParticleSystem *psys, int from)
+{
+ if(from == PART_FROM_CHILD) {
+ ChildParticle *cpa;
+ int p, totchild = get_psys_tot_child(scene, psys);
+
+ if(psys->child && totchild) {
+ for(p=0,cpa=psys->child; p<totchild; p++,cpa++){
+ cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3]= 0.0;
+ cpa->foffset= 0.0f;
+ cpa->parent=0;
+ cpa->pa[0]=cpa->pa[1]=cpa->pa[2]=cpa->pa[3]=0;
+ cpa->num= -1;
+ }
+ }
+ }
+ else {
+ PARTICLE_P;
+ LOOP_PARTICLES {
+ pa->fuv[0]=pa->fuv[1]=pa->fuv[2]= pa->fuv[3]= 0.0;
+ pa->foffset= 0.0f;
+ pa->num= -1;
+ }
+ }
+}
+/* Creates a distribution of coordinates on a DerivedMesh */
/* This is to denote functionality that does not yet work with mesh - only derived mesh */
-static int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, DerivedMesh *finaldm, int from)
+static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, DerivedMesh *finaldm, int from)
{
ParticleThreadContext *ctx= threads[0].ctx;
Object *ob= ctx->sim.ob;
ParticleSystem *psys= ctx->sim.psys;
- Object *tob;
ParticleData *pa=0, *tpars= 0;
ParticleSettings *part;
- ParticleSystem *tpsys;
ParticleSeam *seams= 0;
- ChildParticle *cpa=0;
KDTree *tree=0;
DerivedMesh *dm= NULL;
float *jit= NULL;
int i, seed, p=0, totthread= threads[0].tot;
- int /*no_distr=0,*/ cfrom=0;
- int tot=0, totpart, *index=0, children=0, totseam=0;
- //int *vertpart=0;
+ int cfrom=0;
+ int totelem=0, totpart, *particle_element=0, children=0, totseam=0;
int jitlevel= 1, distr;
- float *weight=0,*sum=0,*jitoff=0;
- float cur, maxweight=0.0, tweight, totweight, co[3], nor[3], orco[3], ornor[3];
+ float *element_weight=NULL,*element_sum=NULL,*jitter_offset=NULL, *vweight=NULL;
+ float cur, maxweight=0.0, tweight, totweight, inv_totweight, co[3], nor[3], orco[3], ornor[3];
- if(ob==0 || psys==0 || psys->part==0)
+ if(ELEM3(NULL, ob, psys, psys->part))
return 0;
part=psys->part;
@@ -1012,81 +1050,63 @@ static int psys_threads_init_distribution(ParticleThread *threads, Scene *scene,
return 0;
}
- BLI_srandom(31415926 + psys->seed);
+ /* First handle special cases */
+ if(from == PART_FROM_CHILD) {
+ /* Simple children */
+ if(part->childtype != PART_CHILD_FACES) {
+ BLI_srandom(31415926 + psys->seed + psys->child_seed);
+ distribute_simple_children(scene, ob, finaldm, psys);
+ return 0;
+ }
+ }
+ else {
+ /* Grid distribution */
+ if(part->distr==PART_DISTR_GRID && from != PART_FROM_VERT){
+ BLI_srandom(31415926 + psys->seed);
+ dm= CDDM_from_mesh((Mesh*)ob->data, ob);
+ distribute_grid(dm,psys);
+ dm->release(dm);
+ return 0;
+ }
+ }
- if(from==PART_FROM_CHILD){
+ /* Create trees and original coordinates if needed */
+ if(from == PART_FROM_CHILD) {
distr=PART_DISTR_RAND;
BLI_srandom(31415926 + psys->seed + psys->child_seed);
+ dm= finaldm;
+ children=1;
- if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
- dm= finaldm;
- children=1;
-
- tree=BLI_kdtree_new(totpart);
+ tree=BLI_kdtree_new(totpart);
- for(p=0,pa=psys->particles; p<totpart; p++,pa++){
- psys_particle_on_dm(dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,ornor);
- transform_mesh_orco_verts((Mesh*)ob->data, &orco, 1, 1);
- BLI_kdtree_insert(tree, p, orco, ornor);
- }
-
- BLI_kdtree_balance(tree);
-
- totpart=get_psys_tot_child(scene, psys);
- cfrom=from=PART_FROM_FACE;
+ for(p=0,pa=psys->particles; p<totpart; p++,pa++){
+ psys_particle_on_dm(dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,ornor);
+ transform_mesh_orco_verts((Mesh*)ob->data, &orco, 1, 1);
+ BLI_kdtree_insert(tree, p, orco, ornor);
}
- else{
- /* no need to figure out distribution */
- int child_nbr= get_psys_child_number(scene, psys);
-
- totpart= get_psys_tot_child(scene, psys);
- alloc_child_particles(psys, totpart);
- cpa=psys->child;
- for(i=0; i<child_nbr; i++){
- for(p=0; p<psys->totpart; p++,cpa++){
- float length=2.0;
- cpa->parent=p;
-
- /* create even spherical distribution inside unit sphere */
- while(length>=1.0f){
- cpa->fuv[0]=2.0f*BLI_frand()-1.0f;
- cpa->fuv[1]=2.0f*BLI_frand()-1.0f;
- cpa->fuv[2]=2.0f*BLI_frand()-1.0f;
- length=len_v3(cpa->fuv);
- }
- cpa->num=-1;
- }
- }
- /* dmcache must be updated for parent particles if children from faces is used */
- psys_calc_dmcache(ob, finaldm, psys);
+ BLI_kdtree_balance(tree);
- return 0;
- }
+ totpart = get_psys_tot_child(scene, psys);
+ cfrom = from = PART_FROM_FACE;
}
- else{
+ else {
+ distr = part->distr;
+ BLI_srandom(31415926 + psys->seed);
+
dm= CDDM_from_mesh((Mesh*)ob->data, ob);
- /* special handling of grid distribution */
- if(part->distr==PART_DISTR_GRID && from != PART_FROM_VERT){
- distribute_particles_in_grid(dm,psys);
- dm->release(dm);
- return 0;
- }
-
/* we need orco for consistent distributions */
DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob));
- distr=part->distr;
-
- if(from==PART_FROM_VERT){
+ if(from == PART_FROM_VERT) {
MVert *mv= dm->getVertDataArray(dm, CD_MVERT);
float (*orcodata)[3]= dm->getVertDataArray(dm, CD_ORCO);
int totvert = dm->getNumVerts(dm);
tree=BLI_kdtree_new(totvert);
- for(p=0; p<totvert; p++){
+ for(p=0; p<totvert; p++) {
if(orcodata) {
VECCOPY(co,orcodata[p])
transform_mesh_orco_verts((Mesh*)ob->data, &co, 1, 1);
@@ -1100,73 +1120,33 @@ static int psys_threads_init_distribution(ParticleThread *threads, Scene *scene,
}
}
- /* 1. */
- switch(from){
- case PART_FROM_VERT:
- tot = dm->getNumVerts(dm);
- break;
- case PART_FROM_VOLUME:
- case PART_FROM_FACE:
- tot = dm->getNumFaces(dm);
- break;
- case PART_FROM_PARTICLE:
- if(psys->target_ob)
- tob=psys->target_ob;
- else
- tob=ob;
+ /* Get total number of emission elements and allocate needed arrays */
+ totelem = (from == PART_FROM_VERT) ? dm->getNumVerts(dm) : dm->getNumFaces(dm);
- if((tpsys=BLI_findlink(&tob->particlesystem,psys->target_psys-1))){
- tpars=tpsys->particles;
- tot=tpsys->totpart;
- }
- break;
- }
+ if(totelem == 0){
+ distribute_invalid(scene, psys, children ? PART_FROM_CHILD : 0);
- if(tot==0){
- /*no_distr=1;*/ /*UNUSED*/
- if(children){
- if(G.f & G_DEBUG)
- fprintf(stderr,"Particle child distribution error: Nothing to emit from!\n");
- if(psys->child) {
- for(p=0,cpa=psys->child; p<totpart; p++,cpa++){
- cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3]= 0.0;
- cpa->foffset= 0.0f;
- cpa->parent=0;
- cpa->pa[0]=cpa->pa[1]=cpa->pa[2]=cpa->pa[3]=0;
- cpa->num= -1;
- }
- }
- }
- else {
- if(G.f & G_DEBUG)
- fprintf(stderr,"Particle distribution error: Nothing to emit from!\n");
- for(p=0,pa=psys->particles; p<totpart; p++,pa++){
- pa->fuv[0]=pa->fuv[1]=pa->fuv[2]= pa->fuv[3]= 0.0;
- pa->foffset= 0.0f;
- pa->num= -1;
- }
- }
+ if(G.f & G_DEBUG)
+ fprintf(stderr,"Particle distribution error: Nothing to emit from!\n");
if(dm != finaldm) dm->release(dm);
return 0;
}
- /* 2. */
-
- weight=MEM_callocN(sizeof(float)*tot, "particle_distribution_weights");
- index=MEM_callocN(sizeof(int)*totpart, "particle_distribution_indexes");
- sum=MEM_callocN(sizeof(float)*(tot+1), "particle_distribution_sum");
- jitoff=MEM_callocN(sizeof(float)*tot, "particle_distribution_jitoff");
+ element_weight = MEM_callocN(sizeof(float)*totelem, "particle_distribution_weights");
+ particle_element= MEM_callocN(sizeof(int)*totpart, "particle_distribution_indexes");
+ element_sum = MEM_callocN(sizeof(float)*(totelem+1), "particle_distribution_sum");
+ jitter_offset = MEM_callocN(sizeof(float)*totelem, "particle_distribution_jitoff");
- /* 2.1 */
- if((part->flag&PART_EDISTR || children) && ELEM(from,PART_FROM_PARTICLE,PART_FROM_VERT)==0){
+ /* Calculate weights from face areas */
+ if((part->flag&PART_EDISTR || children) && from != PART_FROM_VERT){
MVert *v1, *v2, *v3, *v4;
- float totarea=0.0, co1[3], co2[3], co3[3], co4[3];
+ float totarea=0.f, co1[3], co2[3], co3[3], co4[3];
float (*orcodata)[3];
orcodata= dm->getVertDataArray(dm, CD_ORCO);
- for(i=0; i<tot; i++){
+ for(i=0; i<totelem; i++){
MFace *mf=dm->getFaceData(dm,i,CD_MFACE);
if(orcodata) {
@@ -1176,6 +1156,10 @@ static int psys_threads_init_distribution(ParticleThread *threads, Scene *scene,
transform_mesh_orco_verts((Mesh*)ob->data, &co1, 1, 1);
transform_mesh_orco_verts((Mesh*)ob->data, &co2, 1, 1);
transform_mesh_orco_verts((Mesh*)ob->data, &co3, 1, 1);
+ if(mf->v4) {
+ VECCOPY(co4, orcodata[mf->v4]);
+ transform_mesh_orco_verts((Mesh*)ob->data, &co4, 1, 1);
+ }
}
else {
v1= (MVert*)dm->getVertData(dm,mf->v1,CD_MVERT);
@@ -1184,156 +1168,133 @@ static int psys_threads_init_distribution(ParticleThread *threads, Scene *scene,
VECCOPY(co1, v1->co);
VECCOPY(co2, v2->co);
VECCOPY(co3, v3->co);
- }
-
- if (mf->v4){
- if(orcodata) {
- VECCOPY(co4, orcodata[mf->v4]);
- transform_mesh_orco_verts((Mesh*)ob->data, &co4, 1, 1);
- }
- else {
+ if(mf->v4) {
v4= (MVert*)dm->getVertData(dm,mf->v4,CD_MVERT);
VECCOPY(co4, v4->co);
}
- cur= area_quad_v3(co1, co2, co3, co4);
}
- else
- cur= area_tri_v3(co1, co2, co3);
+
+ cur = mf->v4 ? area_quad_v3(co1, co2, co3, co4) : area_tri_v3(co1, co2, co3);
- if(cur>maxweight)
- maxweight=cur;
+ if(cur > maxweight)
+ maxweight = cur;
- weight[i]= cur;
- totarea+=cur;
+ element_weight[i] = cur;
+ totarea += cur;
}
- for(i=0; i<tot; i++)
- weight[i] /= totarea;
+ for(i=0; i<totelem; i++)
+ element_weight[i] /= totarea;
maxweight /= totarea;
}
- else if(from==PART_FROM_PARTICLE){
- float val=(float)tot/(float)totpart;
- for(i=0; i<tot; i++)
- weight[i]=val;
- maxweight=val;
- }
else{
- float min=1.0f/(float)(MIN2(tot,totpart));
- for(i=0; i<tot; i++)
- weight[i]=min;
+ float min=1.0f/(float)(MIN2(totelem,totpart));
+ for(i=0; i<totelem; i++)
+ element_weight[i]=min;
maxweight=min;
}
- /* 2.2 */
- if(ELEM3(from,PART_FROM_VERT,PART_FROM_FACE,PART_FROM_VOLUME)){
- float *vweight= psys_cache_vgroup(dm,psys,PSYS_VG_DENSITY);
+ /* Calculate weights from vgroup */
+ vweight = psys_cache_vgroup(dm,psys,PSYS_VG_DENSITY);
- if(vweight){
- if(from==PART_FROM_VERT) {
- for(i=0;i<tot; i++)
- weight[i]*=vweight[i];
- }
- else { /* PART_FROM_FACE / PART_FROM_VOLUME */
- for(i=0;i<tot; i++){
- MFace *mf=dm->getFaceData(dm,i,CD_MFACE);
- tweight = vweight[mf->v1] + vweight[mf->v2] + vweight[mf->v3];
+ if(vweight){
+ if(from==PART_FROM_VERT) {
+ for(i=0;i<totelem; i++)
+ element_weight[i]*=vweight[i];
+ }
+ else { /* PART_FROM_FACE / PART_FROM_VOLUME */
+ for(i=0;i<totelem; i++){
+ MFace *mf=dm->getFaceData(dm,i,CD_MFACE);
+ tweight = vweight[mf->v1] + vweight[mf->v2] + vweight[mf->v3];
- if(mf->v4) {
- tweight += vweight[mf->v4];
- tweight /= 4.0;
- }
- else {
- tweight /= 3.0;
- }
-
- weight[i]*=tweight;
+ if(mf->v4) {
+ tweight += vweight[mf->v4];
+ tweight /= 4.0;
}
+ else {
+ tweight /= 3.0;
+ }
+
+ element_weight[i]*=tweight;
}
- MEM_freeN(vweight);
}
+ MEM_freeN(vweight);
}
- /* 3. */
+ /* Calculate total weight of all elements */
totweight= 0.0f;
- for(i=0;i<tot; i++)
- totweight += weight[i];
+ for(i=0;i<totelem; i++)
+ totweight += element_weight[i];
- if(totweight > 0.0f)
- totweight= 1.0f/totweight;
+ inv_totweight = (totweight > 0.f ? 1.f/totweight : 0.f);
- sum[0]= 0.0f;
- for(i=0;i<tot; i++)
- sum[i+1]= sum[i]+weight[i]*totweight;
+ /* Calculate cumulative weights */
+ element_sum[0]= 0.0f;
+ for(i=0; i<totelem; i++)
+ element_sum[i+1]= element_sum[i] + element_weight[i] * inv_totweight;
+ /* Finally assign elements to particles */
if((part->flag&PART_TRAND) || (part->simplify_flag&PART_SIMPLIFY_ENABLE)) {
float pos;
for(p=0; p<totpart; p++) {
- /* In theory sys[tot] should be 1.0, but due to float errors this is not necessarily always true, so scale pos accordingly. */
- pos= BLI_frand() * sum[tot];
- index[p]= binary_search_distribution(sum, tot, pos);
- index[p]= MIN2(tot-1, index[p]);
- jitoff[index[p]]= pos;
+ /* In theory element_sum[totelem] should be 1.0, but due to float errors this is not necessarily always true, so scale pos accordingly. */
+ pos= BLI_frand() * element_sum[totelem];
+ particle_element[p]= distribute_binary_search(element_sum, totelem, pos);
+ particle_element[p]= MIN2(totelem-1, particle_element[p]);
+ jitter_offset[particle_element[p]]= pos;
}
}
else {
double step, pos;
- step= (totpart <= 1)? 0.5: 1.0/(totpart-1);
- pos= 1e-16f; /* tiny offset to avoid zero weight face */
+ step= (totpart < 2) ? 0.5 : 1.0/(double)totpart;
+ pos= 1e-16; /* tiny offset to avoid zero weight face */
i= 0;
for(p=0; p<totpart; p++, pos+=step) {
- while((i < tot) && (pos > sum[i+1]))
+ while((i < totelem) && (pos > element_sum[i+1]))
i++;
- index[p]= MIN2(tot-1, i);
+ particle_element[p]= MIN2(totelem-1, i);
/* avoid zero weight face */
- if(p == totpart-1 && weight[index[p]] == 0.0f)
- index[p]= index[p-1];
+ if(p == totpart-1 && element_weight[particle_element[p]] == 0.0f)
+ particle_element[p]= particle_element[p-1];
- jitoff[index[p]]= pos;
+ jitter_offset[particle_element[p]]= pos;
}
}
- MEM_freeN(sum);
+ MEM_freeN(element_sum);
- /* for hair, sort by origindex, allows optimizations in rendering */
- /* however with virtual parents the children need to be in random order */
+ /* For hair, sort by origindex (allows optimizations in rendering), */
+ /* however with virtual parents the children need to be in random order. */
if(part->type == PART_HAIR && !(part->childtype==PART_CHILD_FACES && part->parents!=0.0)) {
- if(from != PART_FROM_PARTICLE) {
- COMPARE_ORIG_INDEX = NULL;
-
- if(from == PART_FROM_VERT) {
- if(dm->numVertData)
- COMPARE_ORIG_INDEX= dm->getVertDataArray(dm, CD_ORIGINDEX);
- }
- else {
- if(dm->numFaceData)
- COMPARE_ORIG_INDEX= dm->getFaceDataArray(dm, CD_ORIGINDEX);
- }
+ COMPARE_ORIG_INDEX = NULL;
- if(COMPARE_ORIG_INDEX) {
- qsort(index, totpart, sizeof(int), compare_orig_index);
- COMPARE_ORIG_INDEX = NULL;
- }
+ if(from == PART_FROM_VERT) {
+ if(dm->numVertData)
+ COMPARE_ORIG_INDEX= dm->getVertDataArray(dm, CD_ORIGINDEX);
+ }
+ else {
+ if(dm->numFaceData)
+ COMPARE_ORIG_INDEX= dm->getFaceDataArray(dm, CD_ORIGINDEX);
}
- }
- /* weights are no longer used except for FROM_PARTICLE, which needs them zeroed for indexing */
- if(from==PART_FROM_PARTICLE){
- for(i=0; i<tot; i++)
- weight[i]=0.0f;
+ if(COMPARE_ORIG_INDEX) {
+ qsort(particle_element, totpart, sizeof(int), distribute_compare_orig_index);
+ COMPARE_ORIG_INDEX = NULL;
+ }
}
- /* 4. */
+ /* Create jittering if needed */
if(distr==PART_DISTR_JIT && ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)) {
jitlevel= part->userjit;
if(jitlevel == 0) {
- jitlevel= totpart/tot;
+ jitlevel= totpart/totelem;
if(part->flag & PART_EDISTR) jitlevel*= 2; /* looks better in general, not very scietific */
if(jitlevel<3) jitlevel= 3;
}
@@ -1350,16 +1311,16 @@ static int psys_threads_init_distribution(ParticleThread *threads, Scene *scene,
BLI_array_randomize(jit, 2*sizeof(float), jitlevel, psys->seed); /* for custom jit or even distribution */
}
- /* 5. */
+ /* Setup things for threaded distribution */
ctx->tree= tree;
ctx->seams= seams;
ctx->totseam= totseam;
ctx->sim.psys= psys;
- ctx->index= index;
+ ctx->index= particle_element;
ctx->jit= jit;
ctx->jitlevel= jitlevel;
- ctx->jitoff= jitoff;
- ctx->weight= weight;
+ ctx->jitoff= jitter_offset;
+ ctx->weight= element_weight;
ctx->maxweight= maxweight;
ctx->from= (children)? PART_FROM_CHILD: from;
ctx->cfrom= cfrom;
@@ -1394,14 +1355,14 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from)
pthreads= psys_threads_create(sim);
- if(!psys_threads_init_distribution(pthreads, sim->scene, finaldm, from)) {
+ if(!distribute_threads_init_data(pthreads, sim->scene, finaldm, from)) {
psys_threads_free(pthreads);
return;
}
totthread= pthreads[0].tot;
if(totthread > 1) {
- BLI_init_threads(&threads, exec_distribution, totthread);
+ BLI_init_threads(&threads, distribute_threads_exec_cb, totthread);
for(i=0; i<totthread; i++)
BLI_insert_thread(&threads, &pthreads[i]);
@@ -1409,7 +1370,7 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from)
BLI_end_threads(&threads);
}
else
- exec_distribution(&pthreads[0]);
+ distribute_threads_exec_cb(&pthreads[0]);
psys_calc_dmcache(sim->ob, finaldm, sim->psys);
@@ -1423,17 +1384,11 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from)
/* ready for future use, to emit particles without geometry */
static void distribute_particles_on_shape(ParticleSimulationData *sim, int UNUSED(from))
{
- ParticleSystem *psys = sim->psys;
- PARTICLE_P;
+ distribute_invalid(sim->scene, sim->psys, 0);
fprintf(stderr,"Shape emission not yet possible!\n");
-
- LOOP_PARTICLES {
- pa->fuv[0]=pa->fuv[1]=pa->fuv[2]=pa->fuv[3]= 0.0;
- pa->foffset= 0.0f;
- pa->num= -1;
- }
}
+
static void distribute_particles(ParticleSimulationData *sim, int from)
{
PARTICLE_PSMD;
@@ -1449,16 +1404,9 @@ static void distribute_particles(ParticleSimulationData *sim, int from)
distribute_particles_on_shape(sim, from);
if(distr_error){
- ParticleSystem *psys = sim->psys;
- PARTICLE_P;
+ distribute_invalid(sim->scene, sim->psys, from);
fprintf(stderr,"Particle distribution error!\n");
-
- LOOP_PARTICLES {
- pa->fuv[0]=pa->fuv[1]=pa->fuv[2]=pa->fuv[3]= 0.0;
- pa->foffset= 0.0f;
- pa->num= -1;
- }
}
}
@@ -1547,7 +1495,7 @@ void initialize_particle(ParticleSimulationData *sim, ParticleData *pa, int p)
pa->flag &= ~PARS_UNEXIST;
- if(part->from != PART_FROM_PARTICLE && part->type != PART_FLUID) {
+ if(part->type != PART_FLUID) {
psys_get_texture(sim, pa, &ptex, PAMAP_INIT, 0.f);
if(ptex.exist < PSYS_FRAND(p+125))
@@ -1628,34 +1576,6 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
int p = pa - psys->particles;
part=psys->part;
-#if 0 /* deprecated code */
- if(part->from==PART_FROM_PARTICLE){
- float speed;
- ParticleSimulationData tsim= {0};
- tsim.scene= sim->scene;
- tsim.ob= psys->target_ob ? psys->target_ob : ob;
- tsim.psys = BLI_findlink(&tsim.ob->particlesystem, sim->psys->target_psys-1);
-
- state.time = pa->time;
- if(pa->num == -1)
- memset(&state, 0, sizeof(state));
- else
- psys_get_particle_state(&tsim, pa->num, &state, 1);
- psys_get_from_key(&state, loc, nor, rot, 0);
-
- mul_qt_v3(rot, vtan);
- mul_qt_v3(rot, utan);
-
- speed= normalize_v3_v3(p_vel, state.vel);
- mul_v3_fl(p_vel, dot_v3v3(r_vel, p_vel));
- VECSUB(p_vel, r_vel, p_vel);
- normalize_v3(p_vel);
- mul_v3_fl(p_vel, speed);
-
- VECCOPY(pa->fuv, loc); /* abusing pa->fuv (not used for "from particle") for storing emit location */
- }
- else{
-#endif
/* get precise emitter matrix if particle is born */
if(part->type!=PART_HAIR && pa->time < cfra && pa->time >= sim->psys->cfra) {
/* we have to force RECALC_ANIM here since where_is_objec_time only does drivers */
@@ -2037,112 +1957,7 @@ static void set_keyed_keys(ParticleSimulationData *sim)
psys->flag |= PSYS_KEYED;
}
-/************************************************/
-/* Reactors */
-/************************************************/
-//static void push_reaction(ParticleSimulationData *sim, int pa_num, int event, ParticleKey *state)
-//{
-// Object *rob;
-// ParticleSystem *rpsys;
-// ParticleSettings *rpart;
-// ParticleData *pa;
-// ListBase *lb=&sim->psys->effectors;
-// ParticleEffectorCache *ec;
-// ParticleReactEvent *re;
-//
-// if(lb->first) for(ec = lb->first; ec; ec= ec->next){
-// if(ec->type & PSYS_EC_REACTOR){
-// /* all validity checks already done in add_to_effectors */
-// rob=ec->ob;
-// rpsys=BLI_findlink(&rob->particlesystem,ec->psys_nbr);
-// rpart=rpsys->part;
-// if(rpsys->part->reactevent==event){
-// pa=sim->psys->particles+pa_num;
-// re= MEM_callocN(sizeof(ParticleReactEvent), "react event");
-// re->event=event;
-// re->pa_num = pa_num;
-// re->ob = sim->ob;
-// re->psys = sim->psys;
-// re->size = pa->size;
-// copy_particle_key(&re->state,state,1);
-//
-// switch(event){
-// case PART_EVENT_DEATH:
-// re->time=pa->dietime;
-// break;
-// case PART_EVENT_COLLIDE:
-// re->time=state->time;
-// break;
-// case PART_EVENT_NEAR:
-// re->time=state->time;
-// break;
-// }
-//
-// BLI_addtail(&rpsys->reactevents, re);
-// }
-// }
-// }
-//}
-//static void react_to_events(ParticleSystem *psys, int pa_num)
-//{
-// ParticleSettings *part=psys->part;
-// ParticleData *pa=psys->particles+pa_num;
-// ParticleReactEvent *re=psys->reactevents.first;
-// int birth=0;
-// float dist=0.0f;
-//
-// for(re=psys->reactevents.first; re; re=re->next){
-// birth=0;
-// if(part->from==PART_FROM_PARTICLE){
-// if(pa->num==re->pa_num && pa->alive==PARS_UNBORN){
-// if(re->event==PART_EVENT_NEAR){
-// ParticleData *tpa = re->psys->particles+re->pa_num;
-// float pa_time=tpa->time + pa->foffset*tpa->lifetime;
-// if(re->time >= pa_time){
-// pa->time=pa_time;
-// pa->dietime=pa->time+pa->lifetime;
-// }
-// }
-// else{
-// pa->time=re->time;
-// pa->dietime=pa->time+pa->lifetime;
-// }
-// }
-// }
-// else{
-// dist=len_v3v3(pa->state.co, re->state.co);
-// if(dist <= re->size){
-// if(pa->alive==PARS_UNBORN){
-// pa->time=re->time;
-// pa->dietime=pa->time+pa->lifetime;
-// birth=1;
-// }
-// if(birth || part->flag&PART_REACT_MULTIPLE){
-// float vec[3];
-// VECSUB(vec,pa->state.co, re->state.co);
-// if(birth==0)
-// mul_v3_fl(vec,(float)pow(1.0f-dist/re->size,part->reactshape));
-// VECADDFAC(pa->state.vel,pa->state.vel,vec,part->reactfac);
-// VECADDFAC(pa->state.vel,pa->state.vel,re->state.vel,part->partfac);
-// }
-// if(birth)
-// mul_v3_fl(pa->state.vel,(float)pow(1.0f-dist/re->size,part->reactshape));
-// }
-// }
-// }
-//}
-//void psys_get_reactor_target(ParticleSimulationData *sim, Object **target_ob, ParticleSystem **target_psys)
-//{
-// Object *tob;
-//
-// tob = sim->psys->target_ob ? sim->psys->target_ob : sim->ob;
-//
-// *target_psys = BLI_findlink(&tob->particlesystem, sim->psys->target_psys-1);
-// if(*target_psys)
-// *target_ob=tob;
-// else
-// *target_ob=0;
-//}
+
/************************************************/
/* Point Cache */
/************************************************/
@@ -2174,17 +1989,48 @@ void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra
/************************************************/
/* Effectors */
/************************************************/
+static void psys_update_particle_bvhtree(ParticleSystem *psys, float cfra)
+{
+ if(psys) {
+ PARTICLE_P;
+ int totpart = 0;
+
+ if(!psys->bvhtree || psys->bvhtree_frame != cfra) {
+ LOOP_SHOWN_PARTICLES {
+ totpart++;
+ }
+
+ BLI_bvhtree_free(psys->bvhtree);
+ psys->bvhtree = BLI_bvhtree_new(totpart, 0.0, 4, 6);
+
+ LOOP_SHOWN_PARTICLES {
+ if(pa->alive == PARS_ALIVE) {
+ if(pa->state.time == cfra)
+ BLI_bvhtree_insert(psys->bvhtree, p, pa->prev_state.co, 1);
+ else
+ BLI_bvhtree_insert(psys->bvhtree, p, pa->state.co, 1);
+ }
+ }
+ BLI_bvhtree_balance(psys->bvhtree);
+
+ psys->bvhtree_frame = cfra;
+ }
+ }
+}
void psys_update_particle_tree(ParticleSystem *psys, float cfra)
{
if(psys) {
PARTICLE_P;
+ int totpart = 0;
if(!psys->tree || psys->tree_frame != cfra) {
-
- BLI_kdtree_free(psys->tree);
+ LOOP_SHOWN_PARTICLES {
+ totpart++;
+ }
+ BLI_kdtree_free(psys->tree);
psys->tree = BLI_kdtree_new(psys->totpart);
-
+
LOOP_SHOWN_PARTICLES {
if(pa->alive == PARS_ALIVE) {
if(pa->state.time == cfra)
@@ -2195,7 +2041,7 @@ void psys_update_particle_tree(ParticleSystem *psys, float cfra)
}
BLI_kdtree_balance(psys->tree);
- psys->tree_frame = psys->cfra;
+ psys->tree_frame = cfra;
}
}
}
@@ -2207,6 +2053,128 @@ static void psys_update_effectors(ParticleSimulationData *sim)
precalc_guides(sim, sim->psys->effectors);
}
+static void integrate_particle(ParticleSettings *part, ParticleData *pa, float dtime, float *external_acceleration, void (*force_func)(void *forcedata, ParticleKey *state, float *force, float *impulse), void *forcedata)
+{
+ ParticleKey states[5];
+ float force[3],acceleration[3],impulse[3],dx[4][3],dv[4][3],oldpos[3];
+ float pa_mass= (part->flag & PART_SIZEMASS ? part->mass * pa->size : part->mass);
+ int i, steps=1;
+
+ copy_v3_v3(oldpos, pa->state.co);
+
+ switch(part->integrator){
+ case PART_INT_EULER:
+ steps=1;
+ break;
+ case PART_INT_MIDPOINT:
+ steps=2;
+ break;
+ case PART_INT_RK4:
+ steps=4;
+ break;
+ case PART_INT_VERLET:
+ steps=1;
+ break;
+ }
+
+ copy_particle_key(states, &pa->state, 1);
+
+ states->time = 0.f;
+
+ for(i=0; i<steps; i++){
+ zero_v3(force);
+ zero_v3(impulse);
+
+ force_func(forcedata, states+i, force, impulse);
+
+ /* force to acceleration*/
+ mul_v3_v3fl(acceleration, force, 1.0f/pa_mass);
+
+ if(external_acceleration)
+ add_v3_v3(acceleration, external_acceleration);
+
+ /* calculate next state */
+ add_v3_v3(states[i].vel, impulse);
+
+ switch(part->integrator){
+ case PART_INT_EULER:
+ madd_v3_v3v3fl(pa->state.co, states->co, states->vel, dtime);
+ madd_v3_v3v3fl(pa->state.vel, states->vel, acceleration, dtime);
+ break;
+ case PART_INT_MIDPOINT:
+ if(i==0){
+ madd_v3_v3v3fl(states[1].co, states->co, states->vel, dtime*0.5f);
+ madd_v3_v3v3fl(states[1].vel, states->vel, acceleration, dtime*0.5f);
+ states[1].time = dtime*0.5f;
+ /*fra=sim->psys->cfra+0.5f*dfra;*/
+ }
+ else{
+ madd_v3_v3v3fl(pa->state.co, states->co, states[1].vel, dtime);
+ madd_v3_v3v3fl(pa->state.vel, states->vel, acceleration, dtime);
+ }
+ break;
+ case PART_INT_RK4:
+ switch(i){
+ case 0:
+ copy_v3_v3(dx[0], states->vel);
+ mul_v3_fl(dx[0], dtime);
+ copy_v3_v3(dv[0], acceleration);
+ mul_v3_fl(dv[0], dtime);
+
+ madd_v3_v3v3fl(states[1].co, states->co, dx[0], 0.5f);
+ madd_v3_v3v3fl(states[1].vel, states->vel, dv[0], 0.5f);
+ states[1].time = dtime*0.5f;
+ /*fra=sim->psys->cfra+0.5f*dfra;*/
+ break;
+ case 1:
+ madd_v3_v3v3fl(dx[1], states->vel, dv[0], 0.5f);
+ mul_v3_fl(dx[1], dtime);
+ copy_v3_v3(dv[1], acceleration);
+ mul_v3_fl(dv[1], dtime);
+
+ madd_v3_v3v3fl(states[2].co, states->co, dx[1], 0.5f);
+ madd_v3_v3v3fl(states[2].vel, states->vel, dv[1], 0.5f);
+ states[2].time = dtime*0.5f;
+ break;
+ case 2:
+ madd_v3_v3v3fl(dx[2], states->vel, dv[1], 0.5f);
+ mul_v3_fl(dx[2], dtime);
+ copy_v3_v3(dv[2], acceleration);
+ mul_v3_fl(dv[2], dtime);
+
+ add_v3_v3v3(states[3].co, states->co, dx[2]);
+ add_v3_v3v3(states[3].vel, states->vel, dv[2]);
+ states[3].time = dtime;
+ /*fra=cfra;*/
+ break;
+ case 3:
+ add_v3_v3v3(dx[3], states->vel, dv[2]);
+ mul_v3_fl(dx[3], dtime);
+ copy_v3_v3(dv[3], acceleration);
+ mul_v3_fl(dv[3], dtime);
+
+ madd_v3_v3v3fl(pa->state.co, states->co, dx[0], 1.0f/6.0f);
+ madd_v3_v3fl(pa->state.co, dx[1], 1.0f/3.0f);
+ madd_v3_v3fl(pa->state.co, dx[2], 1.0f/3.0f);
+ madd_v3_v3fl(pa->state.co, dx[3], 1.0f/6.0f);
+
+ madd_v3_v3v3fl(pa->state.vel, states->vel, dv[0], 1.0f/6.0f);
+ madd_v3_v3fl(pa->state.vel, dv[1], 1.0f/3.0f);
+ madd_v3_v3fl(pa->state.vel, dv[2], 1.0f/3.0f);
+ madd_v3_v3fl(pa->state.vel, dv[3], 1.0f/6.0f);
+ }
+ break;
+ case PART_INT_VERLET: /* Verlet integration */
+ madd_v3_v3v3fl(pa->state.vel, pa->prev_state.vel, acceleration, dtime);
+ madd_v3_v3v3fl(pa->state.co, pa->prev_state.co, pa->state.vel, dtime);
+
+ sub_v3_v3v3(pa->state.vel, pa->state.co, oldpos);
+ mul_v3_fl(pa->state.vel, 1.0f/dtime);
+ break;
+ }
+ }
+}
+
/*********************************************************************************************************
SPH fluid physics
@@ -2222,7 +2190,7 @@ static void psys_update_effectors(ParticleSimulationData *sim)
***********************************************************************************************************/
#define PSYS_FLUID_SPRINGS_INITIAL_SIZE 256
-static ParticleSpring *add_fluid_spring(ParticleSystem *psys, ParticleSpring *spring)
+static ParticleSpring *sph_spring_add(ParticleSystem *psys, ParticleSpring *spring)
{
/* Are more refs required? */
if(psys->alloc_fluidsprings == 0 || psys->fluid_springs == NULL) {
@@ -2240,8 +2208,7 @@ static ParticleSpring *add_fluid_spring(ParticleSystem *psys, ParticleSpring *sp
return psys->fluid_springs + psys->tot_fluidsprings - 1;
}
-
-static void delete_fluid_spring(ParticleSystem *psys, int j)
+static void sph_spring_delete(ParticleSystem *psys, int j)
{
if (j != psys->tot_fluidsprings - 1)
psys->fluid_springs[j] = psys->fluid_springs[psys->tot_fluidsprings - 1];
@@ -2253,8 +2220,52 @@ static void delete_fluid_spring(ParticleSystem *psys, int j)
psys->fluid_springs = (ParticleSpring*)MEM_reallocN(psys->fluid_springs, psys->alloc_fluidsprings * sizeof(ParticleSpring));
}
}
+static void sph_springs_modify(ParticleSystem *psys, float dtime){
+ SPHFluidSettings *fluid = psys->part->fluid;
+ ParticleData *pa1, *pa2;
+ ParticleSpring *spring = psys->fluid_springs;
+
+ float h, d, Rij[3], rij, Lij;
+ int i;
+
+ float yield_ratio = fluid->yield_ratio;
+ float plasticity = fluid->plasticity_constant;
+ /* scale things according to dtime */
+ float timefix = 25.f * dtime;
+
+ if((fluid->flag & SPH_VISCOELASTIC_SPRINGS)==0 || fluid->spring_k == 0.f)
+ return;
-static EdgeHash *build_fluid_springhash(ParticleSystem *psys)
+ /* Loop through the springs */
+ for(i=0; i<psys->tot_fluidsprings; i++, spring++) {
+ pa1 = psys->particles + spring->particle_index[0];
+ pa2 = psys->particles + spring->particle_index[1];
+
+ sub_v3_v3v3(Rij, pa2->prev_state.co, pa1->prev_state.co);
+ rij = normalize_v3(Rij);
+
+ /* adjust rest length */
+ Lij = spring->rest_length;
+ d = yield_ratio * timefix * Lij;
+
+ if (rij > Lij + d) // Stretch
+ spring->rest_length += plasticity * (rij - Lij - d) * timefix;
+ else if(rij < Lij - d) // Compress
+ spring->rest_length -= plasticity * (Lij - d - rij) * timefix;
+
+ h = 4.f*pa1->size;
+
+ if(spring->rest_length > h)
+ spring->delete_flag = 1;
+ }
+
+ /* Loop through springs backwaqrds - for efficient delete function */
+ for (i=psys->tot_fluidsprings-1; i >= 0; i--) {
+ if(psys->fluid_springs[i].delete_flag)
+ sph_spring_delete(psys, i);
+ }
+}
+static EdgeHash *sph_springhash_build(ParticleSystem *psys)
{
EdgeHash *springhash = NULL;
ParticleSpring *spring;
@@ -2267,347 +2278,275 @@ static EdgeHash *build_fluid_springhash(ParticleSystem *psys)
return springhash;
}
-static void particle_fluidsim(ParticleSystem *psys, int own_psys, ParticleData *pa, float dtime, float mass, float *gravity, EdgeHash *springhash)
+
+typedef struct SPHNeighbor
{
- SPHFluidSettings *fluid = psys->part->fluid;
- KDTreeNearest *ptn = NULL;
- ParticleData *npa;
+ ParticleSystem *psys;
+ int index;
+} SPHNeighbor;
+typedef struct SPHRangeData
+{
+ SPHNeighbor neighbors[128];
+ int tot_neighbors;
+
+ float density, near_density;
+ float h;
+
+ ParticleSystem *npsys;
+ ParticleData *pa;
+
+ float massfac;
+ int use_size;
+} SPHRangeData;
+typedef struct SPHData {
+ ParticleSystem *psys[10];
+ ParticleData *pa;
+ float mass;
+ EdgeHash *eh;
+ float *gravity;
+}SPHData;
+static void sph_density_accum_cb(void *userdata, int index, float squared_dist)
+{
+ SPHRangeData *pfr = (SPHRangeData *)userdata;
+ ParticleData *npa = pfr->npsys->particles + index;
+ float q;
+
+ if(npa == pfr->pa || squared_dist < FLT_EPSILON)
+ return;
+
+ /* Ugh! One particle has over 128 neighbors! Really shouldn't happen,
+ * but even if it does it shouldn't do any terrible harm if all are
+ * not taken into account - jahka
+ */
+ if(pfr->tot_neighbors >= 128)
+ return;
+
+ pfr->neighbors[pfr->tot_neighbors].index = index;
+ pfr->neighbors[pfr->tot_neighbors].psys = pfr->npsys;
+ pfr->tot_neighbors++;
+
+ q = (1.f - sqrt(squared_dist)/pfr->h) * pfr->massfac;
+
+ if(pfr->use_size)
+ q *= npa->size;
+
+ pfr->density += q*q;
+ pfr->near_density += q*q*q;
+}
+static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, float *UNUSED(impulse))
+{
+ SPHData *sphdata = (SPHData *)sphdata_v;
+ ParticleSystem **psys = sphdata->psys;
+ ParticleData *pa = sphdata->pa;
+ SPHFluidSettings *fluid = psys[0]->part->fluid;
ParticleSpring *spring = NULL;
+ SPHRangeData pfr;
+ SPHNeighbor *pfn;
+ float mass = sphdata->mass;
+ float *gravity = sphdata->gravity;
+ EdgeHash *springhash = sphdata->eh;
- float temp[3];
- float q, q1, u, I, D, rij, d, Lij;
- float pressure_near, pressure;
- float p=0, pnear=0;
+ float q, u, rij, dv[3];
+ float pressure, near_pressure;
- float omega = fluid->viscosity_omega;
- float beta = fluid->viscosity_beta;
- float massfactor = 1.0f/mass;
- float spring_k = fluid->spring_k;
- float h = fluid->radius;
- float L = fluid->rest_length * fluid->radius;
+ float visc = fluid->viscosity_omega;
+ float stiff_visc = fluid->viscosity_beta * (fluid->flag & SPH_FAC_VISCOSITY ? fluid->viscosity_omega : 1.f);
- int n, neighbours = BLI_kdtree_range_search(psys->tree, h, pa->prev_state.co, NULL, &ptn);
- int spring_index = 0, index = own_psys ? pa - psys->particles : -1;
+ float inv_mass = 1.0f/mass;
+ float spring_constant = fluid->spring_k;
+
+ float h = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.f*pa->size : 1.f); /* 4.0 seems to be a pretty good value */
+ float rest_density = fluid->rest_density * (fluid->flag & SPH_FAC_DENSITY ? 4.77f : 1.f); /* 4.77 is an experimentally determined density factor */
+ float rest_length = fluid->rest_length * (fluid->flag & SPH_FAC_REST_LENGTH ? 2.588f * pa->size : 1.f);
- /* pressure and near pressure */
- for(n=own_psys?1:0; n<neighbours; n++) {
- /* disregard particles at the exact same location */
- if(ptn[n].dist < FLT_EPSILON)
- continue;
+ float stiffness = fluid->stiffness_k;
+ float stiffness_near_fac = fluid->stiffness_knear * (fluid->flag & SPH_FAC_REPULSION ? fluid->stiffness_k : 1.f);
- sub_v3_v3(ptn[n].co, pa->prev_state.co);
- mul_v3_fl(ptn[n].co, 1.f/ptn[n].dist);
- q = ptn[n].dist/h;
+ ParticleData *npa;
+ float vec[3];
+ float vel[3];
+ float co[3];
- if(q < 1.f) {
- q1 = 1.f - q;
+ int i, spring_index, index = pa - psys[0]->particles;
- p += q1*q1;
- pnear += q1*q1*q1;
- }
+ pfr.tot_neighbors = 0;
+ pfr.density = pfr.near_density = 0.f;
+ pfr.h = h;
+ pfr.pa = pa;
+
+ for(i=0; i<10 && psys[i]; i++) {
+ pfr.npsys = psys[i];
+ pfr.massfac = psys[i]->part->mass*inv_mass;
+ pfr.use_size = psys[i]->part->flag & PART_SIZEMASS;
+
+ BLI_bvhtree_range_query(psys[i]->bvhtree, state->co, h, sph_density_accum_cb, &pfr);
}
- p *= mass;
- pnear *= mass;
- pressure = fluid->stiffness_k * (p - fluid->rest_density);
- pressure_near = fluid->stiffness_knear * pnear;
+ pressure = stiffness * (pfr.density - rest_density);
+ near_pressure = stiffness_near_fac * pfr.near_density;
- /* main calculations */
- for(n=own_psys?1:0; n<neighbours; n++) {
- /* disregard particles at the exact same location */
- if(ptn[n].dist < FLT_EPSILON)
- continue;
+ pfn = pfr.neighbors;
+ for(i=0; i<pfr.tot_neighbors; i++, pfn++) {
+ npa = pfn->psys->particles + pfn->index;
- npa = psys->particles + ptn[n].index;
+ madd_v3_v3v3fl(co, npa->prev_state.co, npa->prev_state.vel, state->time);
- rij = ptn[n].dist;
- q = rij/h;
- q1 = 1.f-q;
+ sub_v3_v3v3(vec, co, state->co);
+ rij = normalize_v3(vec);
- /* Double Density Relaxation - Algorithm 2 (can't be thread safe!)*/
- D = dtime * dtime * (pressure + pressure_near*q1)*q1 * 0.5f;
- madd_v3_v3fl(pa->state.co, ptn[n].co, -D * massfactor);
- if(own_psys)
- madd_v3_v3fl(npa->state.co, ptn[n].co, D * massfactor);
+ q = (1.f - rij/h) * pfn->psys->part->mass * inv_mass;
- if(index < ptn[n].index) {
- /* Viscosity - Algorithm 5 */
- if(omega > 0.f || beta > 0.f) {
- sub_v3_v3v3(temp, pa->state.vel, npa->state.vel);
- u = dot_v3v3(ptn[n].co, temp);
+ if(pfn->psys->part->flag & PART_SIZEMASS)
+ q *= npa->size;
- if (u > 0){
- I = dtime * (q1 * (omega * u + beta * u*u)) * 0.5f;
- madd_v3_v3fl(pa->state.vel, ptn[n].co, -I * massfactor);
+ copy_v3_v3(vel, npa->prev_state.vel);
- if(own_psys)
- madd_v3_v3fl(npa->state.vel, ptn[n].co, I * massfactor);
- }
- }
+ /* Double Density Relaxation */
+ madd_v3_v3fl(force, vec, -(pressure + near_pressure*q)*q);
- if(spring_k > 0.f) {
- /* Viscoelastic spring force - Algorithm 4*/
- if (fluid->flag & SPH_VISCOELASTIC_SPRINGS && springhash){
- spring_index = GET_INT_FROM_POINTER(BLI_edgehash_lookup(springhash, index, ptn[n].index));
+ /* Viscosity */
+ if(visc > 0.f || stiff_visc > 0.f) {
+ sub_v3_v3v3(dv, vel, state->vel);
+ u = dot_v3v3(vec, dv);
- if(spring_index) {
- spring = psys->fluid_springs + spring_index - 1;
- }
- else {
- ParticleSpring temp_spring;
- temp_spring.particle_index[0] = index;
- temp_spring.particle_index[1] = ptn[n].index;
- temp_spring.rest_length = (fluid->flag & SPH_CURRENT_REST_LENGTH) ? rij : L;
- temp_spring.delete_flag = 0;
-
- spring = add_fluid_spring(psys, &temp_spring);
- }
+ if(u < 0.f && visc > 0.f)
+ madd_v3_v3fl(force, vec, 0.5f * q * visc * u );
+
+ if(u > 0.f && stiff_visc > 0.f)
+ madd_v3_v3fl(force, vec, 0.5f * q * stiff_visc * u );
+ }
+
+ if(spring_constant > 0.f) {
+ /* Viscoelastic spring force */
+ if (pfn->psys == psys[0] && fluid->flag & SPH_VISCOELASTIC_SPRINGS && springhash) {
+ spring_index = GET_INT_FROM_POINTER(BLI_edgehash_lookup(springhash, index, pfn->index));
- Lij = spring->rest_length;
- d = fluid->yield_ratio * Lij;
+ if(spring_index) {
+ spring = psys[0]->fluid_springs + spring_index - 1;
- if (rij > Lij + d) // Stretch, 25 is just a multiplier for plasticity_constant value to counter default dtime of 1/25
- spring->rest_length += dtime * 25.f * fluid->plasticity_constant * (rij - Lij - d);
- else if(rij < Lij - d) // Compress
- spring->rest_length -= dtime * 25.f * fluid->plasticity_constant * (Lij - d - rij);
+ madd_v3_v3fl(force, vec, -10.f * spring_constant * (1.f - rij/h) * (spring->rest_length - rij));
}
- else { /* PART_SPRING_HOOKES - Hooke's spring force */
- /* L is a factor of radius */
- D = 0.5 * dtime * dtime * 10.f * fluid->spring_k * (1.f - L/h) * (L - rij);
-
- madd_v3_v3fl(pa->state.co, ptn[n].co, -D * massfactor);
- if(own_psys)
- madd_v3_v3fl(npa->state.co, ptn[n].co, D * massfactor);
+ else if(fluid->spring_frames == 0 || (pa->prev_state.time-pa->time) <= fluid->spring_frames){
+ ParticleSpring temp_spring;
+ temp_spring.particle_index[0] = index;
+ temp_spring.particle_index[1] = pfn->index;
+ temp_spring.rest_length = (fluid->flag & SPH_CURRENT_REST_LENGTH) ? rij : rest_length;
+ temp_spring.delete_flag = 0;
+
+ sph_spring_add(psys[0], &temp_spring);
}
}
+ else {/* PART_SPRING_HOOKES - Hooke's spring force */
+ madd_v3_v3fl(force, vec, -10.f * spring_constant * (1.f - rij/h) * (rest_length - rij));
+ }
}
- }
-
- /* Artificial buoyancy force in negative gravity direction */
- if (fluid->buoyancy >= 0.f && gravity) {
- float B = -dtime * dtime * fluid->buoyancy * (p - fluid->rest_density) * 0.5f;
- madd_v3_v3fl(pa->state.co, gravity, -B * massfactor);
}
-
- if(ptn)
- MEM_freeN(ptn);
-}
-
-static void apply_particle_fluidsim(Object *ob, ParticleSystem *psys, ParticleData *pa, float dtime, float *gravity, EdgeHash *springhash){
- ParticleTarget *pt;
-
- particle_fluidsim(psys, 1, pa, dtime, psys->part->mass, gravity, springhash);
- /*----check other SPH systems (Multifluids) , each fluid has its own parameters---*/
- for(pt=psys->targets.first; pt; pt=pt->next) {
- ParticleSystem *epsys = psys_get_target_system(ob, pt);
-
- if(epsys)
- particle_fluidsim(epsys, 0, pa, dtime, psys->part->mass, gravity, NULL);
- }
- /*----------------------------------------------------------------*/
+ /* Artificial buoyancy force in negative gravity direction */
+ if (fluid->buoyancy > 0.f && gravity)
+ madd_v3_v3fl(force, gravity, fluid->buoyancy * (pfr.density-rest_density));
}
-static void apply_fluid_springs(ParticleSystem *psys, float timestep){
- SPHFluidSettings *fluid = psys->part->fluid;
- ParticleData *pa1, *pa2;
- ParticleSpring *spring = psys->fluid_springs;
-
- float h = fluid->radius;
- float massfactor = 1.0f/psys->part->mass;
- float D, Rij[3], rij, Lij;
+static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float dfra, float *gravity, EdgeHash *springhash){
+ ParticleTarget *pt;
int i;
- if((fluid->flag & SPH_VISCOELASTIC_SPRINGS)==0 || fluid->spring_k == 0.f)
- return;
-
- /* Loop through the springs */
- for(i=0; i<psys->tot_fluidsprings; i++, spring++) {
- Lij = spring->rest_length;
+ ParticleSettings *part = sim->psys->part;
+ // float timestep = psys_get_timestep(sim); // UNUSED
+ float pa_mass = part->mass * (part->flag & PART_SIZEMASS ? pa->size : 1.f);
+ float dtime = dfra*psys_get_timestep(sim);
+ // int steps = 1; // UNUSED
+ float effector_acceleration[3];
+ SPHData sphdata;
- if (Lij > h) {
- spring->delete_flag = 1;
- }
- else {
- pa1 = psys->particles + spring->particle_index[0];
- pa2 = psys->particles + spring->particle_index[1];
+ sphdata.psys[0] = sim->psys;
+ for(i=1, pt=sim->psys->targets.first; i<10; i++, pt=(pt?pt->next:NULL))
+ sphdata.psys[i] = pt ? psys_get_target_system(sim->ob, pt) : NULL;
- sub_v3_v3v3(Rij, pa2->prev_state.co, pa1->prev_state.co);
- rij = normalize_v3(Rij);
+ sphdata.pa = pa;
+ sphdata.gravity = gravity;
+ sphdata.mass = pa_mass;
+ sphdata.eh = springhash;
- /* Calculate displacement and apply value */
- D = 0.5f * timestep * timestep * 10.f * fluid->spring_k * (1.f - Lij/h) * (Lij - rij);
+ /* restore previous state and treat gravity & effectors as external acceleration*/
+ sub_v3_v3v3(effector_acceleration, pa->state.vel, pa->prev_state.vel);
+ mul_v3_fl(effector_acceleration, 1.f/dtime);
- madd_v3_v3fl(pa1->state.co, Rij, -D * pa1->state.time * pa1->state.time * massfactor);
- madd_v3_v3fl(pa2->state.co, Rij, D * pa2->state.time * pa2->state.time * massfactor);
- }
- }
+ copy_particle_key(&pa->state, &pa->prev_state, 0);
- /* Loop through springs backwaqrds - for efficient delete function */
- for (i=psys->tot_fluidsprings-1; i >= 0; i--) {
- if(psys->fluid_springs[i].delete_flag)
- delete_fluid_spring(psys, i);
- }
+ integrate_particle(part, pa, dtime, effector_acceleration, sph_force_cb, &sphdata);
}
/************************************************/
-/* Newtonian physics */
+/* Basic physics */
/************************************************/
-/* gathers all forces that effect particles and calculates a new state for the particle */
-static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra, float cfra)
+typedef struct EfData
{
+ ParticleTexture ptex;
+ ParticleSimulationData *sim;
+ ParticleData *pa;
+} EfData;
+static void basic_force_cb(void *efdata_v, ParticleKey *state, float *force, float *impulse)
+{
+ EfData *efdata = (EfData *)efdata_v;
+ ParticleSimulationData *sim = efdata->sim;
ParticleSettings *part = sim->psys->part;
- ParticleData *pa = sim->psys->particles + p;
+ ParticleData *pa = efdata->pa;
EffectedPoint epoint;
- ParticleKey states[5], tkey;
- float timestep = psys_get_timestep(sim);
- float force[3],impulse[3],dx[4][3],dv[4][3],oldpos[3];
- float dtime=dfra*timestep, time, pa_mass=part->mass, fac /*, fra=sim->psys->cfra*/;
- int i, steps=1;
- ParticleTexture ptex;
- psys_get_texture(sim, pa, &ptex, PAMAP_PHYSICS, cfra);
-
- /* maintain angular velocity */
- VECCOPY(pa->state.ave,pa->prev_state.ave);
- VECCOPY(oldpos,pa->state.co);
+ /* add effectors */
+ pd_point_from_particle(efdata->sim, efdata->pa, state, &epoint);
+ if(part->type != PART_HAIR || part->effector_weights->flag & EFF_WEIGHT_DO_HAIR)
+ pdDoEffectors(sim->psys->effectors, sim->colliders, part->effector_weights, &epoint, force, impulse);
- if(part->flag & PART_SIZEMASS)
- pa_mass*=pa->size;
+ mul_v3_fl(force, efdata->ptex.field);
+ mul_v3_fl(impulse, efdata->ptex.field);
- switch(part->integrator){
- case PART_INT_EULER:
- steps=1;
- break;
- case PART_INT_MIDPOINT:
- steps=2;
- break;
- case PART_INT_RK4:
- steps=4;
- break;
- case PART_INT_VERLET:
- steps=1;
- break;
- }
-
- copy_particle_key(states,&pa->state,1);
-
- for(i=0; i<steps; i++){
- force[0]=force[1]=force[2]=0.0;
- impulse[0]=impulse[1]=impulse[2]=0.0;
- /* add effectors */
- pd_point_from_particle(sim, pa, states+i, &epoint);
- if(part->type != PART_HAIR || part->effector_weights->flag & EFF_WEIGHT_DO_HAIR)
- pdDoEffectors(sim->psys->effectors, sim->colliders, part->effector_weights, &epoint, force, impulse);
-
- mul_v3_fl(force, ptex.field);
- mul_v3_fl(impulse, ptex.field);
-
- /* calculate air-particle interaction */
- if(part->dragfac!=0.0f){
- fac=-part->dragfac*pa->size*pa->size*len_v3(states[i].vel);
- VECADDFAC(force,force,states[i].vel,fac);
- }
+ /* calculate air-particle interaction */
+ if(part->dragfac != 0.0f)
+ madd_v3_v3fl(force, state->vel, -part->dragfac * pa->size * pa->size * len_v3(state->vel));
- /* brownian force */
- if(part->brownfac!=0.0){
- force[0]+=(BLI_frand()-0.5f)*part->brownfac;
- force[1]+=(BLI_frand()-0.5f)*part->brownfac;
- force[2]+=(BLI_frand()-0.5f)*part->brownfac;
- }
-
- /* force to acceleration*/
- mul_v3_fl(force,1.0f/pa_mass);
-
- /* add global acceleration (gravitation) */
- if(psys_uses_gravity(sim)
- /* normal gravity is too strong for hair so it's disabled by default */
- && (part->type != PART_HAIR || part->effector_weights->flag & EFF_WEIGHT_DO_HAIR)) {
- madd_v3_v3fl(force, sim->scene->physics_settings.gravity, part->effector_weights->global_gravity * ptex.gravity);
- }
-
- /* calculate next state */
- VECADD(states[i].vel,states[i].vel,impulse);
+ /* brownian force */
+ if(part->brownfac != 0.0){
+ force[0] += (BLI_frand()-0.5f) * part->brownfac;
+ force[1] += (BLI_frand()-0.5f) * part->brownfac;
+ force[2] += (BLI_frand()-0.5f) * part->brownfac;
+ }
+}
+/* gathers all forces that effect particles and calculates a new state for the particle */
+static void basic_integrate(ParticleSimulationData *sim, int p, float dfra, float cfra)
+{
+ ParticleSettings *part = sim->psys->part;
+ ParticleData *pa = sim->psys->particles + p;
+ ParticleKey tkey;
+ float dtime=dfra*psys_get_timestep(sim), time;
+ float *gravity = NULL, gr[3];
+ EfData efdata;
- switch(part->integrator){
- case PART_INT_EULER:
- VECADDFAC(pa->state.co,states->co,states->vel,dtime);
- VECADDFAC(pa->state.vel,states->vel,force,dtime);
- break;
- case PART_INT_MIDPOINT:
- if(i==0){
- VECADDFAC(states[1].co,states->co,states->vel,dtime*0.5f);
- VECADDFAC(states[1].vel,states->vel,force,dtime*0.5f);
- /*fra=sim->psys->cfra+0.5f*dfra;*/
- }
- else{
- VECADDFAC(pa->state.co,states->co,states[1].vel,dtime);
- VECADDFAC(pa->state.vel,states->vel,force,dtime);
- }
- break;
- case PART_INT_RK4:
- switch(i){
- case 0:
- VECCOPY(dx[0],states->vel);
- mul_v3_fl(dx[0],dtime);
- VECCOPY(dv[0],force);
- mul_v3_fl(dv[0],dtime);
+ psys_get_texture(sim, pa, &efdata.ptex, PAMAP_PHYSICS, cfra);
- VECADDFAC(states[1].co,states->co,dx[0],0.5f);
- VECADDFAC(states[1].vel,states->vel,dv[0],0.5f);
- /*fra=sim->psys->cfra+0.5f*dfra;*/
- break;
- case 1:
- VECADDFAC(dx[1],states->vel,dv[0],0.5f);
- mul_v3_fl(dx[1],dtime);
- VECCOPY(dv[1],force);
- mul_v3_fl(dv[1],dtime);
+ efdata.pa = pa;
+ efdata.sim = sim;
- VECADDFAC(states[2].co,states->co,dx[1],0.5f);
- VECADDFAC(states[2].vel,states->vel,dv[1],0.5f);
- break;
- case 2:
- VECADDFAC(dx[2],states->vel,dv[1],0.5f);
- mul_v3_fl(dx[2],dtime);
- VECCOPY(dv[2],force);
- mul_v3_fl(dv[2],dtime);
+ /* add global acceleration (gravitation) */
+ if(psys_uses_gravity(sim)
+ /* normal gravity is too strong for hair so it's disabled by default */
+ && (part->type != PART_HAIR || part->effector_weights->flag & EFF_WEIGHT_DO_HAIR)) {
+ zero_v3(gr);
+ madd_v3_v3fl(gr, sim->scene->physics_settings.gravity, part->effector_weights->global_gravity * efdata.ptex.gravity);
+ gravity = gr;
+ }
- VECADD(states[3].co,states->co,dx[2]);
- VECADD(states[3].vel,states->vel,dv[2]);
- /*fra=cfra;*/
- break;
- case 3:
- VECADD(dx[3],states->vel,dv[2]);
- mul_v3_fl(dx[3],dtime);
- VECCOPY(dv[3],force);
- mul_v3_fl(dv[3],dtime);
-
- VECADDFAC(pa->state.co,states->co,dx[0],1.0f/6.0f);
- VECADDFAC(pa->state.co,pa->state.co,dx[1],1.0f/3.0f);
- VECADDFAC(pa->state.co,pa->state.co,dx[2],1.0f/3.0f);
- VECADDFAC(pa->state.co,pa->state.co,dx[3],1.0f/6.0f);
-
- VECADDFAC(pa->state.vel,states->vel,dv[0],1.0f/6.0f);
- VECADDFAC(pa->state.vel,pa->state.vel,dv[1],1.0f/3.0f);
- VECADDFAC(pa->state.vel,pa->state.vel,dv[2],1.0f/3.0f);
- VECADDFAC(pa->state.vel,pa->state.vel,dv[3],1.0f/6.0f);
- }
- break;
- case PART_INT_VERLET: /* Verlet integration */
- VECADDFAC(pa->state.vel,pa->state.vel,force,dtime);
- VECADDFAC(pa->state.co,pa->state.co,pa->state.vel,dtime);
+ /* maintain angular velocity */
+ copy_v3_v3(pa->state.ave, pa->prev_state.ave);
- VECSUB(pa->state.vel,pa->state.co,oldpos);
- mul_v3_fl(pa->state.vel,1.0f/dtime);
- break;
- }
- }
+ integrate_particle(part, pa, dtime, gravity, basic_force_cb, &efdata);
/* damp affects final velocity */
if(part->dampfac != 0.f)
- mul_v3_fl(pa->state.vel, 1.f - part->dampfac * ptex.damp);
+ mul_v3_fl(pa->state.vel, 1.f - part->dampfac * efdata.ptex.damp);
- VECCOPY(pa->state.ave, states->ave);
+ //VECCOPY(pa->state.ave, states->ave);
/* finally we do guides */
time=(cfra-pa->time)/pa->lifetime;
@@ -2627,7 +2566,7 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra
}
}
}
-static void rotate_particle(ParticleSettings *part, ParticleData *pa, float dfra, float timestep)
+static void basic_rotate(ParticleSettings *part, ParticleData *pa, float dfra, float timestep)
{
float rotfac, rot1[4], rot2[4]={1.0,0.0,0.0,0.0}, dtime=dfra*timestep;
@@ -2665,6 +2604,9 @@ static void rotate_particle(ParticleSettings *part, ParticleData *pa, float dfra
normalize_qt(pa->state.rot);
}
+/************************************************/
+/* Collisions */
+/************************************************/
/* convert from triangle barycentric weights to quad mean value weights */
static void intersect_dm_quad_weights(float *v1, float *v2, float *v3, float *v4, float *w)
{
@@ -3156,7 +3098,7 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra)
if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) {
distribute_particles(sim, PART_FROM_CHILD);
- if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES && part->parents!=0.0)
+ if(part->childtype==PART_CHILD_FACES && part->parents!=0.0)
psys_find_parents(sim);
}
}
@@ -3452,11 +3394,11 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
case PART_PHYS_FLUID:
{
ParticleTarget *pt = psys->targets.first;
- psys_update_particle_tree(psys, cfra);
+ psys_update_particle_bvhtree(psys, psys->cfra);
for(; pt; pt=pt->next) { /* Updating others systems particle tree for fluid-fluid interaction */
if(pt->ob)
- psys_update_particle_tree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), cfra);
+ psys_update_particle_bvhtree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), psys->cfra);
}
break;
}
@@ -3508,14 +3450,14 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
{
LOOP_DYNAMIC_PARTICLES {
/* do global forces & effectors */
- apply_particle_forces(sim, p, pa->state.time, cfra);
+ basic_integrate(sim, p, pa->state.time, cfra);
/* deflection */
if(sim->colliders)
deflect_particle(sim, p, pa->state.time, cfra);
/* rotations */
- rotate_particle(part, pa, pa->state.time, timestep);
+ basic_rotate(part, pa, pa->state.time, timestep);
}
break;
}
@@ -3538,43 +3480,28 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
}
case PART_PHYS_FLUID:
{
- EdgeHash *springhash = build_fluid_springhash(psys);
+ EdgeHash *springhash = sph_springhash_build(psys);
float *gravity = NULL;
if(psys_uses_gravity(sim))
gravity = sim->scene->physics_settings.gravity;
- /* do global forces & effectors */
- LOOP_DYNAMIC_PARTICLES {
- apply_particle_forces(sim, p, pa->state.time, cfra);
- /* in fluids forces only effect velocity */
- copy_v3_v3(pa->state.co, pa->prev_state.co);
- }
-
- /* actual fluids calculations (not threadsafe!) */
- LOOP_DYNAMIC_PARTICLES {
- apply_particle_fluidsim(sim->ob, psys, pa, pa->state.time*timestep, gravity, springhash);
- }
-
- /* Apply springs to particles */
- apply_fluid_springs(psys, timestep);
-
- /* apply velocity, collisions and rotation */
LOOP_DYNAMIC_PARTICLES {
- /* velocity holds forces and viscosity, so apply them before collisions */
- madd_v3_v3fl(pa->state.co, pa->state.vel, pa->state.time*timestep);
+ /* do global forces & effectors */
+ basic_integrate(sim, p, pa->state.time, cfra);
- /* calculate new velocity based on new-old location */
- sub_v3_v3v3(pa->state.vel, pa->state.co, pa->prev_state.co);
- mul_v3_fl(pa->state.vel, 1.f/(pa->state.time*timestep));
+ /* actual fluids calculations */
+ sph_integrate(sim, pa, pa->state.time, gravity, springhash);
if(sim->colliders)
deflect_particle(sim, p, pa->state.time, cfra);
/* SPH particles are not physical particles, just interpolation particles, thus rotation has not a direct sense for them */
- rotate_particle(part, pa, pa->state.time, timestep);
+ basic_rotate(part, pa, pa->state.time, timestep);
}
+ sph_springs_modify(psys, timestep);
+
if(springhash) {
BLI_edgehash_free(springhash, NULL);
springhash = NULL;
@@ -3923,13 +3850,6 @@ static void psys_changed_type(ParticleSimulationData *sim)
BKE_ptcache_id_from_particles(&pid, sim->ob, sim->psys);
- if(part->from == PART_FROM_PARTICLE) {
- //if(part->type != PART_REACTOR)
- part->from = PART_FROM_FACE;
- if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT)
- part->distr = PART_DISTR_JIT;
- }
-
if(part->phystype != PART_PHYS_KEYED)
sim->psys->flag &= ~PSYS_KEYED;
@@ -3937,6 +3857,9 @@ static void psys_changed_type(ParticleSimulationData *sim)
if(ELEM4(part->ren_as, PART_DRAW_NOT, PART_DRAW_PATH, PART_DRAW_OB, PART_DRAW_GR)==0)
part->ren_as = PART_DRAW_PATH;
+ if(part->distr == PART_DISTR_GRID)
+ part->distr = PART_DISTR_JIT;
+
if(ELEM3(part->draw_as, PART_DRAW_NOT, PART_DRAW_REND, PART_DRAW_PATH)==0)
part->draw_as = PART_DRAW_REND;
@@ -3982,17 +3905,18 @@ void psys_check_boid_data(ParticleSystem *psys)
static void fluid_default_settings(ParticleSettings *part){
SPHFluidSettings *fluid = part->fluid;
- fluid->radius = 0.5f;
fluid->spring_k = 0.f;
fluid->plasticity_constant = 0.1f;
fluid->yield_ratio = 0.1f;
- fluid->rest_length = 0.5f;
+ fluid->rest_length = 1.f;
fluid->viscosity_omega = 2.f;
- fluid->viscosity_beta = 0.f;
- fluid->stiffness_k = 0.1f;
- fluid->stiffness_knear = 0.05f;
- fluid->rest_density = 10.f;
+ fluid->viscosity_beta = 0.1f;
+ fluid->stiffness_k = 1.f;
+ fluid->stiffness_knear = 1.f;
+ fluid->rest_density = 1.f;
fluid->buoyancy = 0.f;
+ fluid->radius = 1.f;
+ fluid->flag |= SPH_FAC_REPULSION|SPH_FAC_DENSITY|SPH_FAC_RADIUS|SPH_FAC_VISCOSITY|SPH_FAC_REST_LENGTH;
}
static void psys_prepare_physics(ParticleSimulationData *sim)
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index c70a02ac457..618945b27bd 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -2517,14 +2517,55 @@ typedef struct {
Scene *scene;
} ptcache_bake_data;
+static void ptcache_dt_to_str(char *str, double dtime)
+{
+ if(dtime > 60.0) {
+ if(dtime > 3600.0)
+ sprintf(str, "%ih %im %is", (int)(dtime/3600), ((int)(dtime/60))%60, ((int)dtime) % 60);
+ else
+ sprintf(str, "%im %is", ((int)(dtime/60))%60, ((int)dtime) % 60);
+ }
+ else
+ sprintf(str, "%is", ((int)dtime) % 60);
+}
+
static void *ptcache_bake_thread(void *ptr) {
+ int usetimer = 0, sfra, efra;
+ double stime, ptime, ctime, fetd;
+ char run[32], cur[32], etd[32];
+
ptcache_bake_data *data = (ptcache_bake_data*)ptr;
+ stime = ptime = PIL_check_seconds_timer();
+ sfra = *data->cfra_ptr;
+ efra = data->endframe;
+
for(; (*data->cfra_ptr <= data->endframe) && !data->break_operation; *data->cfra_ptr+=data->step) {
scene_update_for_newframe(data->main, data->scene, data->scene->lay);
if(G.background) {
printf("bake: frame %d :: %d\n", (int)*data->cfra_ptr, data->endframe);
}
+ else {
+ ctime = PIL_check_seconds_timer();
+
+ fetd = (ctime-ptime)*(efra-*data->cfra_ptr)/data->step;
+
+ if(usetimer || fetd > 60.0) {
+ usetimer = 1;
+
+ ptcache_dt_to_str(cur, ctime-ptime);
+ ptcache_dt_to_str(run, ctime-stime);
+ ptcache_dt_to_str(etd, fetd);
+
+ printf("Baked for %s, current frame: %i/%i (%.3fs), ETC: %s \r", run, *data->cfra_ptr-sfra+1, efra-sfra+1, (float)(ctime-ptime), etd);
+ }
+ ptime = ctime;
+ }
+ }
+
+ if(usetimer) {
+ ptcache_dt_to_str(run, PIL_check_seconds_timer()-stime);
+ printf("Bake %s %s (%i frames simulated). \n", (data->break_operation ? "canceled after" : "finished in"), run, *data->cfra_ptr-sfra);
}
data->thread_ended = TRUE;
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index c8c5ab921fa..96fac075412 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -1906,13 +1906,17 @@ static ImBuf * seq_render_scene_strip_impl(
#endif
if(sequencer_view3d_cb && BLI_thread_is_main() && doseq_gl && (seq->scene == context.scene || have_seq==0) && seq->scene->camera) {
+ char err_out[256]= "unknown";
/* for old scened this can be uninitialized, should probably be added to do_versions at some point if the functionality stays */
if(context.scene->r.seq_prev_type==0)
context.scene->r.seq_prev_type = 3 /* ==OB_SOLID */;
/* opengl offscreen render */
scene_update_for_newframe(context.bmain, seq->scene, seq->scene->lay);
- ibuf= sequencer_view3d_cb(seq->scene, context.rectx, context.recty, IB_rect, context.scene->r.seq_prev_type);
+ ibuf= sequencer_view3d_cb(seq->scene, context.rectx, context.recty, IB_rect, context.scene->r.seq_prev_type, err_out);
+ if(ibuf == NULL) {
+ fprintf(stderr, "seq_render_scene_strip_impl failed to get opengl buffer: %s\n", err_out);
+ }
}
else {
Render *re = RE_GetRender(sce->id.name);
diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h
index d1f5fa89c3d..11849e0be6d 100644
--- a/source/blender/blenlib/BLI_math_rotation.h
+++ b/source/blender/blenlib/BLI_math_rotation.h
@@ -85,7 +85,7 @@ void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q
void mat3_to_quat_is_ok(float q[4], float mat[3][3]);
/* other */
-void print_qt(char *str, float q[4]);
+void print_qt(const char *str, const float q[4]);
/******************************** Axis Angle *********************************/
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index b3220937e19..ed52bf30f62 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -132,8 +132,9 @@ void BLI_clean(char *path);
* converts it to a regular full path.
* Also removes garbage from directory paths, like /../ or double slashes etc
*/
-void BLI_cleanup_file(const char *relabase, char *dir);
+void BLI_cleanup_file(const char *relabase, char *dir); /* removes trailing slash */
void BLI_cleanup_dir(const char *relabase, char *dir); /* same as above but adds a trailing slash */
+void BLI_cleanup_path(const char *relabase, char *dir); /* doesn't touch trailing slash */
/* go back one directory */
int BLI_parent_dir(char *path);
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index 90614402b0d..d9afd9f3cd4 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -635,7 +635,7 @@ void tri_to_quat(float quat[4], const float v1[3], const float v2[3], const floa
mul_qt_qtqt(quat, q1, q2);
}
-void print_qt(char *str, float q[4])
+void print_qt(const char *str, const float q[4])
{
printf("%s: %.3f %.3f %.3f %.3f\n", str, q[0], q[1], q[2], q[3]);
}
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index c0c8fc4e24f..0dc09606533 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -296,14 +296,7 @@ void BLI_uniquename(ListBase *list, void *vlink, const char defname[], char deli
* If relbase is NULL then its ignored
*/
-void BLI_cleanup_dir(const char *relabase, char *dir)
-{
- BLI_cleanup_file(relabase, dir);
- BLI_add_slash(dir);
-
-}
-
-void BLI_cleanup_file(const char *relabase, char *dir)
+void BLI_cleanup_path(const char *relabase, char *dir)
{
short a;
char *start, *eind;
@@ -358,13 +351,6 @@ void BLI_cleanup_file(const char *relabase, char *dir)
eind = start + strlen("\\\\") - 1;
memmove( start, eind, strlen(eind)+1 );
}
-
- if((a = strlen(dir))){ /* remove the '\\' at the end */
- while(a>0 && dir[a-1] == '\\'){
- a--;
- dir[a] = 0;
- }
- }
#else
if(dir[0]=='.') { /* happens, for example in FILE_MAIN */
dir[0]= '/';
@@ -402,17 +388,21 @@ void BLI_cleanup_file(const char *relabase, char *dir)
eind = start + (2 - 1) /* strlen("//") - 1 */;
memmove( start, eind, strlen(eind)+1 );
}
-
- if( (a = strlen(dir)) ){ /* remove all '/' at the end */
- while(dir[a-1] == '/'){
- a--;
- dir[a] = 0;
- if (a<=0) break;
- }
- }
#endif
}
+void BLI_cleanup_dir(const char *relabase, char *dir)
+{
+ BLI_cleanup_path(relabase, dir);
+ BLI_add_slash(dir);
+
+}
+
+void BLI_cleanup_file(const char *relabase, char *dir)
+{
+ BLI_cleanup_path(relabase, dir);
+ BLI_del_slash(dir);
+}
void BLI_path_rel(char *file, const char *relfile)
{
@@ -453,8 +443,8 @@ void BLI_path_rel(char *file, const char *relfile)
BLI_char_switch(file, '\\', '/');
/* remove /./ which confuse the following slash counting... */
- BLI_cleanup_file(NULL, file);
- BLI_cleanup_file(NULL, temp);
+ BLI_cleanup_path(NULL, file);
+ BLI_cleanup_path(NULL, temp);
/* the last slash in the file indicates where the path part ends */
lslash = BLI_last_slash(temp);
@@ -687,8 +677,9 @@ int BLI_path_abs(char *path, const char *basepath)
#endif
BLI_strncpy(base, basepath, sizeof(base));
-
- BLI_cleanup_file(NULL, base);
+
+ /* file component is ignored, so dont bother with the trailing slash */
+ BLI_cleanup_path(NULL, base);
/* push slashes into unix mode - strings entering this part are
potentially messed up: having both back- and forward slashes.
@@ -717,17 +708,9 @@ int BLI_path_abs(char *path, const char *basepath)
} else {
BLI_strncpy(path, tmp, FILE_MAX);
}
-
- if (path[0]!='\0') {
- if ( path[strlen(path)-1]=='/') {
- /* remove the '/' so we avoid BLI_cleanup_dir adding an extra \ in WIN32 */
- path[strlen(path)-1] = '\0';
- BLI_cleanup_dir(NULL, path);
- } else {
- BLI_cleanup_file(NULL, path);
- }
- }
-
+
+ BLI_cleanup_path(NULL, path);
+
#ifdef WIN32
/* skip first two chars, which in case of
absolute path will be drive:/blabla and
@@ -1392,9 +1375,12 @@ int BLI_replace_extension(char *path, int maxlen, const char *ext)
{
unsigned int a;
- for(a=strlen(path)-1; a>=0; a--)
- if(path[a] == '.' || path[a] == '/' || path[a] == '\\')
+ for(a=strlen(path); a>0; a--) {
+ if(path[a-1] == '.' || path[a-1] == '/' || path[a-1] == '\\') {
+ a--;
break;
+ }
+ }
if(path[a] != '.')
a= strlen(path);
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index 681e014c2ec..891dc47b4ae 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -120,11 +120,13 @@ BLO_blendfiledata_free(
* Open a blendhandle from a file path.
*
* @param file The file path to open.
+ * @param reports Report errors in opening the file (can be NULL).
* @return A handle on success, or NULL on failure.
*/
BlendHandle*
BLO_blendhandle_from_file(
- char *file);
+ char *file,
+ struct ReportList *reports);
/**
* Open a blendhandle from memory.
@@ -146,13 +148,15 @@ BLO_blendhandle_from_memory(
*
* @param bh The blendhandle to access.
* @param ofblocktype The type of names to get.
+ * @param totnames The length of the returned list.
* @return A BLI_linklist of strings. The string links
* should be freed with malloc.
*/
struct LinkNode*
BLO_blendhandle_get_datablock_names(
BlendHandle *bh,
- int ofblocktype);
+ int ofblocktype,
+ int *totnames);
/**
* Gets the previews of all the datablocks in a file
@@ -204,7 +208,19 @@ int BLO_has_bfile_extension(char *str);
int BLO_is_a_library(const char *path, char *dir, char *group);
struct Main* BLO_library_append_begin(const struct bContext *C, BlendHandle** bh, char *dir);
-void BLO_library_append_named_part(const struct bContext *C, struct Main *mainl, BlendHandle** bh, const char *name, int idcode, short flag);
+
+/**
+ * Link/Append a named datablock from an external blend file.
+ *
+ * @param C The context, when NULL instancing object in the scene isnt done.
+ * @param mainl The main database to link from (not the active one).
+ * @param bh The blender file handle.
+ * @param name The name of the datablock (without the 2 char ID prefix)
+ * @param idcode The kind of datablock to link.
+ * @param flag Options for linking, used for instancing.
+ * @return Boolean, 0 when the datablock could not be found.
+ */
+int BLO_library_append_named_part(const struct bContext *C, struct Main *mainl, BlendHandle** bh, const char *name, int idcode, short flag);
void BLO_library_append_end(const struct bContext *C, struct Main *mainl, BlendHandle** bh, int idcode, short flag);
/* deprecated */
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index eda0ac1c375..ae4ba6629a6 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -75,11 +75,11 @@ void BLO_blendhandle_print_sizes(BlendHandle *, void *);
/* Access routines used by filesel. */
-BlendHandle *BLO_blendhandle_from_file(char *file)
+BlendHandle *BLO_blendhandle_from_file(char *file, ReportList *reports)
{
BlendHandle *bh;
- bh= (BlendHandle*)blo_openblenderfile(file, NULL);
+ bh= (BlendHandle*)blo_openblenderfile(file, reports);
return bh;
}
@@ -123,21 +123,24 @@ void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp)
fprintf(fp, "]\n");
}
-LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype)
+LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype, int *tot_names)
{
FileData *fd= (FileData*) bh;
LinkNode *names= NULL;
BHead *bhead;
+ int tot= 0;
for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
if (bhead->code==ofblocktype) {
char *idname= bhead_id_name(fd, bhead);
-
+
BLI_linklist_prepend(&names, strdup(idname+2));
+ tot++;
} else if (bhead->code==ENDB)
break;
}
-
+
+ *tot_names= tot;
return names;
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 1751b056d35..074dd86daf8 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1201,7 +1201,7 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
OldNew *entry= fd->imamap->entries;
Image *ima= oldmain->image.first;
Scene *sce= oldmain->scene.first;
- int i, a;
+ int i;
/* used entries were restored, so we put them to zero */
for (i=0; i<fd->imamap->nentries; i++, entry++) {
@@ -1221,10 +1221,10 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
ima->gputexture= NULL;
}
}
+ for(i=0; i<IMA_MAX_RENDER_SLOT; i++)
+ ima->renders[i]= newimaadr(fd, ima->renders[i]);
ima->gputexture= newimaadr(fd, ima->gputexture);
- for(a=0; a<IMA_MAX_RENDER_SLOT; a++)
- ima->renders[a]= newimaadr(fd, ima->renders[a]);
}
for(; sce; sce= sce->id.next) {
if(sce->nodetree) {
@@ -2774,8 +2774,18 @@ static void direct_link_image(FileData *fd, Image *ima)
ima->anim= NULL;
ima->rr= NULL;
ima->repbind= NULL;
- memset(ima->renders, 0, sizeof(ima->renders));
- ima->last_render_slot= ima->render_slot;
+
+ /* undo system, try to restore render buffers */
+ if(fd->imamap) {
+ int a;
+
+ for(a=0; a<IMA_MAX_RENDER_SLOT; a++)
+ ima->renders[a]= newimaadr(fd, ima->renders[a]);
+ }
+ else {
+ memset(ima->renders, 0, sizeof(ima->renders));
+ ima->last_render_slot= ima->render_slot;
+ }
ima->packedfile = direct_link_packedfile(fd, ima->packedfile);
ima->preview = direct_link_preview_image(fd, ima->preview);
@@ -3321,6 +3331,7 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
}
psys->tree = NULL;
+ psys->bvhtree = NULL;
}
return;
}
@@ -4310,7 +4321,6 @@ static void direct_link_object(FileData *fd, Object *ob)
if(ob->sculpt) {
ob->sculpt= MEM_callocN(sizeof(SculptSession), "reload sculpt session");
- ob->sculpt->ob= ob;
}
}
@@ -5170,7 +5180,6 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
rv3d->clipbb= newdataadr(fd, rv3d->clipbb);
rv3d->depths= NULL;
- rv3d->retopo_view_data= NULL;
rv3d->ri= NULL;
rv3d->sms= NULL;
rv3d->smooth_timer= NULL;
@@ -11629,13 +11638,31 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
- /* put compatibility code here until next subversion bump */
-
- {
+ if (main->versionfile < 256 || (main->versionfile == 256 && main->subversionfile <3)){
bScreen *sc;
Brush *brush;
Object *ob;
+ ParticleSettings *part;
+ Material *mat;
+ int tex_nr, transp_tex;
+ for(mat = main->mat.first; mat; mat = mat->id.next){
+ if(!(mat->mode & MA_TRANSP) && !(mat->material_type & MA_TYPE_VOLUME)){
+
+ transp_tex= 0;
+
+ for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++){
+ if(!mat->mtex[tex_nr]) continue;
+ if(mat->mtex[tex_nr]->mapto & MAP_ALPHA) transp_tex= 1;
+ }
+
+ if(mat->alpha < 1.0f || mat->fresnel_tra > 0.0f || transp_tex){
+ mat->mode |= MA_TRANSP;
+ mat->mode &= ~(MA_ZTRANSP|MA_RAYTRANSP);
+ }
+ }
+ }
+
/* redraws flag in SpaceTime has been moved to Screen level */
for (sc = main->screen.first; sc; sc= sc->id.next) {
if (sc->redraws_flag == 0) {
@@ -11663,6 +11690,18 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
}
+
+ /* particle draw color from material */
+ for(part = main->particle.first; part; part = part->id.next) {
+ if(part->draw & PART_DRAW_MAT_COL)
+ part->draw_col = PART_DRAW_COL_MAT;
+ }
+ }
+
+ /* put compatibility code here until next subversion bump */
+
+ {
+
}
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
@@ -12833,7 +12872,9 @@ static void give_base_to_groups(Main *mainvar, Scene *scene)
}
}
-static void append_named_part(const bContext *C, Main *mainl, FileData *fd, const char *name, int idcode, short flag)
+/* returns true if the item was found
+ * but it may already have already been appended/linked */
+static int append_named_part(const bContext *C, Main *mainl, FileData *fd, const char *name, int idcode, short flag)
{
Scene *scene= CTX_data_scene(C);
Object *ob;
@@ -12841,6 +12882,7 @@ static void append_named_part(const bContext *C, Main *mainl, FileData *fd, cons
BHead *bhead;
ID *id;
int endloop=0;
+ int found=0;
bhead = blo_firstbhead(fd);
while(bhead && endloop==0) {
@@ -12850,7 +12892,7 @@ static void append_named_part(const bContext *C, Main *mainl, FileData *fd, cons
char *idname= bhead_id_name(fd, bhead);
if(strcmp(idname+2, name)==0) {
-
+ found= 1;
id= is_yet_read(fd, mainl, bhead);
if(id==NULL) {
read_libblock(fd, mainl, bhead, LIB_TESTEXT, NULL);
@@ -12897,12 +12939,14 @@ static void append_named_part(const bContext *C, Main *mainl, FileData *fd, cons
bhead = blo_nextbhead(fd, bhead);
}
+
+ return found;
}
-void BLO_library_append_named_part(const bContext *C, Main *mainl, BlendHandle** bh, const char *name, int idcode, short flag)
+int BLO_library_append_named_part(const bContext *C, Main *mainl, BlendHandle** bh, const char *name, int idcode, short flag)
{
FileData *fd= (FileData*)(*bh);
- append_named_part(C, mainl, fd, name, idcode, flag);
+ return append_named_part(C, mainl, fd, name, idcode, flag);
}
static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp
index cba39b04c3c..85fc6e3cbeb 100644
--- a/source/blender/collada/AnimationImporter.cpp
+++ b/source/blender/collada/AnimationImporter.cpp
@@ -405,6 +405,9 @@ bool AnimationImporter::write_animation_list(const COLLADAFW::AnimationList* ani
return true;
}
+// \todo refactor read_node_transform to not automatically apply anything,
+// but rather return the transform matrix, so caller can do with it what is
+// necessary. Same for \ref get_node_mat
void AnimationImporter::read_node_transform(COLLADAFW::Node *node, Object *ob)
{
float mat[4][4];
diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp
index 9669266d851..b4264f88b2f 100644
--- a/source/blender/collada/DocumentImporter.cpp
+++ b/source/blender/collada/DocumentImporter.cpp
@@ -75,6 +75,7 @@
#include "MEM_guardedalloc.h"
#include "DocumentImporter.h"
+#include "TransformReader.h"
#include "collada_internal.h"
#include "collada_utils.h"
@@ -336,10 +337,29 @@ private:
obn->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
scene_add_base(sce, obn);
- if (instance_node)
+ if (instance_node) {
anim_importer.read_node_transform(instance_node, obn);
- else
+ // if we also have a source_node (always ;), take its
+ // transformation matrix and apply it to the newly instantiated
+ // object to account for node hierarchy transforms in
+ // .dae
+ if(source_node) {
+ COLLADABU::Math::Matrix4 mat4 = source_node->getTransformationMatrix();
+ COLLADABU::Math::Matrix4 bmat4 = mat4.transpose(); // transpose to get blender row-major order
+ float mat[4][4];
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ mat[i][j] = bmat4[i][j];
+ }
+ }
+ // calc new matrix and apply
+ mul_m4_m4m4(obn->obmat, mat, obn->obmat);
+ object_apply_mat4(obn, obn->obmat, 0, 0);
+ }
+ }
+ else {
anim_importer.read_node_transform(source_node, obn);
+ }
DAG_scene_sort(CTX_data_main(mContext), sce);
DAG_ids_flush_update(CTX_data_main(mContext), 0);
@@ -353,7 +373,7 @@ private:
continue;
COLLADAFW::InstanceNodePointerArray &inodes = child_node->getInstanceNodes();
Object *new_child = NULL;
- if (inodes.getCount()) {
+ if (inodes.getCount()) { // \todo loop through instance nodes
const COLLADAFW::UniqueId& id = inodes[0]->getInstanciatedObjectId();
new_child = create_instance_node(object_map[id], node_map[id], child_node, sce, is_library_node);
}
@@ -367,7 +387,10 @@ private:
}
}
- return obn;
+ // when we have an instance_node, don't return the object, because otherwise
+ // its correct location gets overwritten in write_node(). Fixes bug #26012.
+ if(instance_node) return NULL;
+ else return obn;
}
void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *parent_node, Scene *sce, Object *par, bool is_library_node)
@@ -444,7 +467,7 @@ private:
libnode_ob.push_back(ob);
}
- anim_importer.read_node_transform(node, ob);
+ anim_importer.read_node_transform(node, ob); // overwrites location set earlier
if (!is_joint) {
// if par was given make this object child of the previous
diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp
index 35098b14072..b6576858c51 100644
--- a/source/blender/collada/MeshImporter.cpp
+++ b/source/blender/collada/MeshImporter.cpp
@@ -165,7 +165,7 @@ void UVDataWrapper::getUV(int uv_index[2], float *uv)
}
break;
- case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN:
+ case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN:
default:
fprintf(stderr, "MeshImporter.getUV(): unknown data type\n");
}
@@ -278,7 +278,7 @@ void MeshImporter::print_index_list(COLLADAFW::IndexList& index_list)
}
#endif
-bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh)
+bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh) // checks if mesh has supported primitive types: polylist, triangles, triangle_fans
{
COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
@@ -307,7 +307,7 @@ bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh)
}
}
- else if(type != COLLADAFW::MeshPrimitive::TRIANGLES) {
+ else if(type != COLLADAFW::MeshPrimitive::TRIANGLES && type!= COLLADAFW::MeshPrimitive::TRIANGLE_FANS) {
fprintf(stderr, "Primitive type %s is not supported.\n", type_str);
return false;
}
@@ -426,7 +426,7 @@ int MeshImporter::count_new_tris(COLLADAFW::Mesh *mesh, Mesh *me)
}
// TODO: import uv set names
-void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris)
+void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) //TODO:: Refactor. Possibly replace by iterators
{
unsigned int i;
@@ -478,6 +478,12 @@ void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris)
size_t prim_totface = mp->getFaceCount();
unsigned int *indices = mp->getPositionIndices().getData();
unsigned int *nind = mp->getNormalIndices().getData();
+
+ if (has_normals && mp->getPositionIndices().getCount() != mp->getNormalIndices().getCount()) {
+ fprintf(stderr, "Warning: Number of normals is different from the number of vertcies, skipping normals\n");
+ has_normals = false;
+ }
+
unsigned int j, k;
int type = mp->getPrimitiveType();
int index = 0;
@@ -532,6 +538,43 @@ void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris)
prim.totface++;
}
}
+
+ // If MeshPrimitive is TRIANGLE_FANS we split it into triangles
+ // The first trifan vertex will be the first vertex in every triangle
+ if (type == COLLADAFW::MeshPrimitive::TRIANGLE_FANS) {
+ unsigned grouped_vertex_count = mp->getGroupedVertexElementsCount();
+ for (unsigned int group_index = 0; group_index < grouped_vertex_count; group_index++){
+ unsigned int first_vertex = indices[0]; // Store first trifan vertex
+ unsigned int first_normal = nind[0]; // Store first trifan vertex normal
+ unsigned int vertex_count = mp->getGroupedVerticesVertexCount(group_index);
+
+ for (unsigned int vertex_index = 0; vertex_index < vertex_count - 2; vertex_index++){
+ // For each triangle store indeces of its 3 vertices
+ unsigned int triangle_vertex_indices[3]={first_vertex, indices[1], indices[2]};
+ set_face_indices(mface, triangle_vertex_indices, false);
+ test_index_face(mface, &me->fdata, face_index, 3);
+
+ if (has_normals) { // vertex normals, same inplementation as for the triangles
+ // the same for vertces normals
+ unsigned int vertex_normal_indices[3]={first_normal, nind[1], nind[2]};
+ if (!flat_face(vertex_normal_indices, nor, 3))
+ mface->flag |= ME_SMOOTH;
+ nind++;
+ }
+
+ mface++; // same inplementation as for the triangles
+ indices++;
+ face_index++;
+ prim.totface++;
+ }
+
+ // Moving cursor to the next triangle fan.
+ if (has_normals)
+ nind += 2;
+
+ indices += 2;
+ }
+ }
else if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) {
COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp;
COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray();
@@ -760,6 +803,18 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri
return NULL;
}
+ // different nodes can point to same geometry, but still also specify the same materials
+ // again. Make sure we don't overwrite them on the next occurrences, so keep list of
+ // what we already have handled.
+ std::multimap<COLLADAFW::UniqueId, COLLADAFW::UniqueId>::iterator it;
+ it=materials_mapped_to_geom.find(*geom_uid);
+ while(it!=materials_mapped_to_geom.end()) {
+ if(it->second == ma_uid) return NULL; // do nothing if already found
+ it++;
+ }
+ // first time we get geom_uid, ma_uid pair. Save for later check.
+ materials_mapped_to_geom.insert(std::pair<COLLADAFW::UniqueId, COLLADAFW::UniqueId>(*geom_uid, ma_uid));
+
Material *ma = uid_material_map[ma_uid];
assign_material(ob, ma, ob->totcol + 1);
@@ -869,9 +924,13 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta
// loop through geom's materials
for (unsigned int i = 0; i < mat_array.getCount(); i++) {
- texture_face = assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid,
- &color_texture, layername, texture_face,
- material_texture_mapping_map, i);
+ if(mat_array[i].getReferencedMaterial().isValid()) {
+ texture_face = assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid,
+ &color_texture, layername, texture_face,
+ material_texture_mapping_map, i);
+ } else {
+ fprintf(stderr, "invalid referenced material for %s\n", mat_array[i].getName().c_str());
+ }
}
return ob;
diff --git a/source/blender/collada/MeshImporter.h b/source/blender/collada/MeshImporter.h
index 1a9f698a7ce..20fdb0dcc6e 100644
--- a/source/blender/collada/MeshImporter.h
+++ b/source/blender/collada/MeshImporter.h
@@ -91,6 +91,7 @@ private:
};
typedef std::map<COLLADAFW::MaterialId, std::vector<Primitive> > MaterialIdPrimitiveArrayMap;
std::map<COLLADAFW::UniqueId, MaterialIdPrimitiveArrayMap> geom_uid_mat_mapping_map; // crazy name!
+ std::multimap<COLLADAFW::UniqueId, COLLADAFW::UniqueId> materials_mapped_to_geom; //< materials that have already been mapped to a geometry. A pair of geom uid and mat uid, one geometry can have several materials
void set_face_indices(MFace *mface, unsigned int *indices, bool quad);
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 44ad8368063..b6450ada96f 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -413,9 +413,6 @@ void draw_markers_time(const bContext *C, int flag)
* primary operations of those editors.
*/
-/* maximum y-axis value (in region screen-space) that marker events should still be accepted for */
-#define ANIMEDIT_MARKER_YAXIS_MAX 30
-
/* ------------------------ */
/* special poll() which checks if there are selected markers first */
@@ -460,15 +457,7 @@ static int ed_markers_opwrap_invoke_custom(bContext *C, wmOperator *op, wmEvent
ScrArea *sa = CTX_wm_area(C);
int retval = OPERATOR_PASS_THROUGH;
- /* only timeline view doesn't need calling-location validation as it's the only dedicated view */
- if (sa->spacetype != SPACE_TIME) {
- /* restrict y-values to within ANIMEDIT_MARKER_YAXIS_MAX of the view's vertical extents, including scrollbars */
- if (evt->mval[1] > ANIMEDIT_MARKER_YAXIS_MAX) {
- /* not ok... "pass-through" to let normal editor's operators have a chance at tackling this event... */
- //printf("MARKER-WRAPPER-DEBUG: event mval[1] = %d, so over accepted tolerance\n", evt->mval[1]);
- return OPERATOR_CANCELLED|OPERATOR_PASS_THROUGH;
- }
- }
+ /* removed check for Y coord of event, keymap has bounbox now */
/* allow operator to run now */
if (invoke_func)
@@ -702,18 +691,24 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt)
ed_marker_move_cancel(C, op);
return OPERATOR_CANCELLED;
+ case RIGHTMOUSE:
+ /* press = user manually demands transform to be cancelled */
+ if (evt->val == KM_PRESS) {
+ ed_marker_move_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ /* else continue; <--- see if release event should be caught for tweak-end */
+
case RETKEY:
case PADENTER:
case LEFTMOUSE:
case MIDDLEMOUSE:
- case RIGHTMOUSE:
if (WM_modal_tweak_exit(evt, mm->event_type)) {
ed_marker_move_exit(C, op);
WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
WM_event_add_notifier(C, NC_ANIMATION|ND_MARKERS, NULL);
return OPERATOR_FINISHED;
}
-
break;
case MOUSEMOVE:
if (hasNumInput(&mm->num))
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index 53d8b4d67f1..07069a69c40 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -279,28 +279,21 @@ void clean_fcurve(FCurve *fcu, float thresh)
/* temp struct used for smooth_fcurve */
typedef struct tSmooth_Bezt {
float *h1, *h2, *h3; /* bezt->vec[0,1,2][1] */
+ float y1, y2, y3; /* averaged before/new/after y-values */
} tSmooth_Bezt;
/* Use a weighted moving-means method to reduce intensity of fluctuations */
+// TODO: introduce scaling factor for weighting falloff
void smooth_fcurve (FCurve *fcu)
{
BezTriple *bezt;
int i, x, totSel = 0;
- /* first loop through - count how many verts are selected, and fix up handles
- * this is done for both modes
- */
+ /* first loop through - count how many verts are selected */
bezt= fcu->bezt;
for (i=0; i < fcu->totvert; i++, bezt++) {
- if (BEZSELECTED(bezt)) {
- /* line point's handles up with point's vertical position */
- bezt->vec[0][1]= bezt->vec[2][1]= bezt->vec[1][1];
- if ((bezt->h1==HD_AUTO) || (bezt->h1==HD_VECT)) bezt->h1= HD_ALIGN;
- if ((bezt->h2==HD_AUTO) || (bezt->h2==HD_VECT)) bezt->h2= HD_ALIGN;
-
- /* add value to total */
+ if (BEZSELECTED(bezt))
totSel++;
- }
}
/* if any points were selected, allocate tSmooth_Bezt points to work on */
@@ -320,7 +313,7 @@ void smooth_fcurve (FCurve *fcu)
tsb->h3 = &bezt->vec[2][1];
/* advance to the next tsb to populate */
- if (x < totSel- 1)
+ if (x < totSel-1)
tsb++;
else
break;
@@ -334,10 +327,10 @@ void smooth_fcurve (FCurve *fcu)
* - next: w/a ratio = 1:1:2:5:3
*/
- /* round 1: calculate previous and next */
+ /* round 1: calculate smoothing deltas and new values */
tsb= tarray;
for (i=0; i < totSel; i++, tsb++) {
- /* don't touch end points (otherwise, curves slowly explode) */
+ /* don't touch end points (otherwise, curves slowly explode, as we don't have enough data there) */
if (ELEM(i, 0, (totSel-1)) == 0) {
const tSmooth_Bezt *tP1 = tsb - 1;
const tSmooth_Bezt *tP2 = (i-2 > 0) ? (tsb - 2) : (NULL);
@@ -350,21 +343,26 @@ void smooth_fcurve (FCurve *fcu)
const float n1 = *tN1->h2;
const float n2 = (tN2) ? (*tN2->h2) : (*tN1->h2);
- /* calculate previous and next */
- *tsb->h1= (3*p2 + 5*p1 + 2*c1 + n1 + n2) / 12;
- *tsb->h3= (p2 + p1 + 2*c1 + 5*n1 + 3*n2) / 12;
+ /* calculate previous and next, then new position by averaging these */
+ tsb->y1= (3*p2 + 5*p1 + 2*c1 + n1 + n2) / 12;
+ tsb->y3= (p2 + p1 + 2*c1 + 5*n1 + 3*n2) / 12;
+
+ tsb->y2 = (tsb->y1 + tsb->y3) / 2;
}
}
- /* round 2: calculate new values and reset handles */
+ /* round 2: apply new values */
tsb= tarray;
for (i=0; i < totSel; i++, tsb++) {
- /* calculate new position by averaging handles */
- *tsb->h2 = (*tsb->h1 + *tsb->h3) / 2;
-
- /* reset handles now */
- *tsb->h1 = *tsb->h2;
- *tsb->h3 = *tsb->h2;
+ /* don't touch end points, as their values were't touched above */
+ if (ELEM(i, 0, (totSel-1)) == 0) {
+ /* y2 takes the average of the 2 points */
+ *tsb->h2 = tsb->y2;
+
+ /* handles are weighted between their original values and the averaged values */
+ *tsb->h1 = ((*tsb->h1) * 0.7f) + (tsb->y1 * 0.3f);
+ *tsb->h3 = ((*tsb->h3) * 0.7f) + (tsb->y3 * 0.3f);
+ }
}
/* free memory required for tarray */
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index f1665f2b165..71c732d6647 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -95,14 +95,14 @@ void ED_area_swapspace(struct bContext *C, ScrArea *sa1, ScrArea *sa2);
void ED_screens_initialize(struct wmWindowManager *wm);
void ED_screen_draw(struct wmWindow *win);
void ED_screen_refresh(struct wmWindowManager *wm, struct wmWindow *win);
-void ED_screen_do_listen(struct wmWindow *win, struct wmNotifier *note);
+void ED_screen_do_listen(struct bContext *C, struct wmNotifier *note);
bScreen *ED_screen_duplicate(struct wmWindow *win, struct bScreen *sc);
bScreen *ED_screen_add(struct wmWindow *win, struct Scene *scene, const char *name);
void ED_screen_set(struct bContext *C, struct bScreen *sc);
void ED_screen_delete(struct bContext *C, struct bScreen *sc);
void ED_screen_set_scene(struct bContext *C, struct Scene *scene);
void ED_screen_delete_scene(struct bContext *C, struct Scene *scene);
-void ED_screen_set_subwinactive(struct wmWindow *win, struct wmEvent *event);
+void ED_screen_set_subwinactive(struct bContext *C, struct wmEvent *event);
void ED_screen_exit(struct bContext *C, struct wmWindow *window, struct bScreen *screen);
void ED_screen_animation_timer(struct bContext *C, int redraws, int refresh, int sync, int enable);
void ED_screen_animation_timer_update(struct bScreen *screen, int redraws, int refresh);
diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index a0c4148c055..b975be54f5f 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -66,11 +66,15 @@ void uvedit_uv_select(struct Scene *scene, struct EditFace *efa, struct MTFace *
int ED_uvedit_nearest_uv(struct Scene *scene, struct Object *obedit, struct Image *ima, float co[2], float uv[2]);
-/* uvedit_unwrap.c */
+/* uvedit_unwrap_ops.c */
void ED_uvedit_live_unwrap_begin(struct Scene *scene, struct Object *obedit);
void ED_uvedit_live_unwrap_re_solve(void);
void ED_uvedit_live_unwrap_end(short cancel);
+/* single call up unwrap using scene settings, used for edge tag unwrapping */
+void ED_unwrap_lscm(struct Scene *scene, struct Object *obedit, const short sel);
+
+/* uvedit_draw.c */
void draw_uvedit_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene, struct Object *obedit);
#endif /* ED_UVEDIT_H */
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index fdfad7c4128..9b70b655b3d 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -171,12 +171,13 @@ int ED_view3d_context_activate(struct bContext *C);
void ED_view3d_draw_offscreen(struct Scene *scene, struct View3D *v3d, struct ARegion *ar,
int winx, int winy, float viewmat[][4], float winmat[][4]);
-struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag);
-struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, int width, int height, unsigned int flag, int drawtype);
+struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag, char err_out[256]);
+struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, int width, int height, unsigned int flag, int drawtype, char err_out[256]);
Base *ED_view3d_give_base_under_cursor(struct bContext *C, short *mval);
void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, short do_clip);
+int ED_view3d_lock(struct RegionView3D *rv3d);
unsigned int ED_viewedit_datamask(struct bScreen *screen);
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index db05b05173e..e938192c5aa 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -322,6 +322,7 @@ void uiBlockSetEmboss(uiBlock *block, char dt);
void uiFreeBlock(const struct bContext *C, uiBlock *block);
void uiFreeBlocks(const struct bContext *C, struct ListBase *lb);
void uiFreeInactiveBlocks(const struct bContext *C, struct ListBase *lb);
+void uiFreeActiveButtons(const struct bContext *C, struct bScreen *screen);
void uiBlockSetRegion(uiBlock *block, struct ARegion *region);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index c01eb351fba..91380d20f41 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -144,11 +144,11 @@ typedef struct uiHandleButtonData {
float dragf, dragfstart;
CBData *dragcbd;
- /* menu open */
+ /* menu open (watch uiFreeActiveButtons) */
uiPopupBlockHandle *menu;
int menuretval;
- /* search box */
+ /* search box (watch uiFreeActiveButtons) */
ARegion *searchbox;
/* post activate */
@@ -1254,7 +1254,7 @@ static int ui_textedit_delete_selection(uiBut *but, uiHandleButtonData *data)
int len= strlen(str);
int change= 0;
if(but->selsta != but->selend && len) {
- memmove( str+but->selsta, str+but->selend, len-but->selsta+1 );
+ memmove( str+but->selsta, str+but->selend, (len - but->selend) + 1 );
change= 1;
}
@@ -4595,6 +4595,28 @@ int ui_button_is_active(ARegion *ar)
return (ui_but_find_activated(ar) != NULL);
}
+/* is called by notifier */
+void uiFreeActiveButtons(const bContext *C, bScreen *screen)
+{
+ ScrArea *sa= screen->areabase.first;
+
+ for(;sa; sa= sa->next) {
+ ARegion *ar= sa->regionbase.first;
+ for(;ar; ar= ar->next) {
+ uiBut *but= ui_but_find_activated(ar);
+ if(but) {
+ uiHandleButtonData *data= but->active;
+
+ if(data->menu==NULL && data->searchbox==NULL)
+ if(data->state == BUTTON_STATE_HIGHLIGHT)
+ ui_button_active_free(C, but);
+ }
+ }
+ }
+}
+
+
+
/* returns TRUE if highlighted button allows drop of names */
/* called in region context */
int UI_but_active_drop_name(bContext *C)
diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c
index 50ea99f46ba..a6f05b8c2f6 100644
--- a/source/blender/editors/mesh/editmesh_mods.c
+++ b/source/blender/editors/mesh/editmesh_mods.c
@@ -79,6 +79,7 @@ editmesh_mods.c, UI level access, no geometry changes
#include "ED_mesh.h"
#include "ED_screen.h"
#include "ED_view3d.h"
+#include "ED_uvedit.h"
#include "BIF_gl.h"
@@ -2201,7 +2202,15 @@ static void mouse_mesh_shortest_path(bContext *C, short mval[2])
me->drawflag |= ME_DRAWBWEIGHTS;
break;
}
-
+
+ /* live unwrap while tagging */
+ if( (vc.scene->toolsettings->edge_mode_live_unwrap) &&
+ (vc.scene->toolsettings->edge_mode == EDGE_MODE_TAG_SEAM) &&
+ (CustomData_has_layer(&em->fdata, CD_MTFACE))
+ ) {
+ ED_unwrap_lscm(vc.scene, vc.obedit, FALSE); /* unwrap all not just sel */
+ }
+
DAG_id_tag_update(vc.obedit->data, 0);
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit->data);
}
@@ -3718,6 +3727,7 @@ void EM_deselect_by_material(EditMesh *em, int index)
static int editmesh_mark_seam(bContext *C, wmOperator *op)
{
+ Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
Mesh *me= ((Mesh *)obedit->data);
@@ -3748,6 +3758,13 @@ static int editmesh_mark_seam(bContext *C, wmOperator *op)
}
}
+ /* live unwrap while tagging */
+ if( (scene->toolsettings->edge_mode_live_unwrap) &&
+ (CustomData_has_layer(&em->fdata, CD_MTFACE))
+ ) {
+ ED_unwrap_lscm(scene, obedit, FALSE); /* unwrap all not just sel */
+ }
+
BKE_mesh_end_editmesh(obedit->data, em);
DAG_id_tag_update(obedit->data, 0);
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 5d3bf92a492..43fb41a5e3d 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -188,9 +188,17 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
GPU_offscreen_unbind(oglrender->ofs); /* unbind */
}
else {
- ImBuf *ibuf_view= ED_view3d_draw_offscreen_imbuf_simple(scene, oglrender->sizex, oglrender->sizey, IB_rectfloat, OB_SOLID);
- memcpy(rr->rectf, ibuf_view->rect_float, sizeof(float) * 4 * oglrender->sizex * oglrender->sizey);
- IMB_freeImBuf(ibuf_view);
+ /* shouldnt suddenly give errors mid-render but possible */
+ char err_out[256]= "unknown";
+ ImBuf *ibuf_view= ED_view3d_draw_offscreen_imbuf_simple(scene, oglrender->sizex, oglrender->sizey, IB_rectfloat, OB_SOLID, err_out);
+
+ if(ibuf_view) {
+ memcpy(rr->rectf, ibuf_view->rect_float, sizeof(float) * 4 * oglrender->sizex * oglrender->sizey);
+ IMB_freeImBuf(ibuf_view);
+ }
+ else {
+ fprintf(stderr, "screen_opengl_render_apply: failed to get buffer, %s\n", err_out);
+ }
}
/* rr->rectf is now filled with image data */
@@ -230,6 +238,7 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op)
short is_view_context= RNA_boolean_get(op->ptr, "view_context");
const short is_animation= RNA_boolean_get(op->ptr, "animation");
const short is_write_still= RNA_boolean_get(op->ptr, "write_still");
+ char err_out[256]= "unknown";
/* ensure we have a 3d view */
@@ -263,10 +272,10 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op)
sizey= (scene->r.size*scene->r.ysch)/100;
/* corrects render size with actual size, not every card supports non-power-of-two dimensions */
- ofs= GPU_offscreen_create(&sizex, &sizey);
+ ofs= GPU_offscreen_create(&sizex, &sizey, err_out);
if(!ofs) {
- BKE_report(op->reports, RPT_ERROR, "Failed to create OpenGL offscreen buffer.");
+ BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL offscreen buffer, %s", err_out);
return 0;
}
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index a1ef042f8e4..73d7fc2abee 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -1053,8 +1053,10 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
/* callbacs are cleared on GetRender() */
if(ELEM(sp->pr_method, PR_BUTS_RENDER, PR_NODE_RENDER)) {
RE_display_draw_cb(re, sp, shader_preview_draw);
- RE_test_break_cb(re, sp, shader_preview_break);
}
+ /* set this for all previews, default is react to G.afbreek still */
+ RE_test_break_cb(re, sp, shader_preview_break);
+
/* lens adjust */
oldlens= ((Camera *)sce->camera->data)->lens;
if(sizex > sp->sizey)
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 883f2ee7128..7af5064218e 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -843,7 +843,7 @@ static void region_subwindow(wmWindow *win, ARegion *ar)
wm_subwindow_position(win, ar->swinid, &ar->winrct);
}
-static void ed_default_handlers(wmWindowManager *wm, ListBase *handlers, int flag)
+static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ListBase *handlers, int flag)
{
/* note, add-handler checks if it already exists */
@@ -860,8 +860,20 @@ static void ed_default_handlers(wmWindowManager *wm, ListBase *handlers, int fla
if(flag & ED_KEYMAP_MARKERS) {
/* time-markers */
wmKeyMap *keymap= WM_keymap_find(wm->defaultconf, "Markers", 0, 0);
- WM_event_add_keymap_handler(handlers, keymap);
- // XXX need boundbox check urgently!!!
+
+ /* time space only has this keymap, the others get a boundbox restricted map */
+ if(sa->spacetype!=SPACE_TIME) {
+ ARegion *ar;
+ static rcti rect= {0, 10000, 0, 30}; /* same local check for all areas */
+
+ for(ar= sa->regionbase.first; ar; ar= ar->next)
+ if(ar->regiontype == RGN_TYPE_WINDOW)
+ break;
+ if(ar)
+ WM_event_add_keymap_handler_bb(handlers, keymap, &rect, &ar->winrct);
+ }
+ else
+ WM_event_add_keymap_handler(handlers, keymap);
}
if(flag & ED_KEYMAP_ANIMATION) {
/* frame changing and timeline operators (for time spaces) */
@@ -914,7 +926,7 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
region_rect_recursive(sa, sa->regionbase.first, &rect, 0);
/* default area handlers */
- ed_default_handlers(wm, &sa->handlers, sa->type->keymapflag);
+ ed_default_handlers(wm, sa, &sa->handlers, sa->type->keymapflag);
/* checks spacedata, adds own handlers */
if(sa->type->init)
sa->type->init(wm, sa);
@@ -925,7 +937,7 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
if(ar->swinid) {
/* default region handlers */
- ed_default_handlers(wm, &ar->handlers, ar->type->keymapflag);
+ ed_default_handlers(wm, sa, &ar->handlers, ar->type->keymapflag);
/* own handlers */
if(ar->type->init)
ar->type->init(wm, ar);
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 44a7a7c48b3..41354c83cec 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -960,8 +960,9 @@ static void region_cursor_set(wmWindow *win, int swinid)
}
}
-void ED_screen_do_listen(wmWindow *win, wmNotifier *note)
+void ED_screen_do_listen(bContext *C, wmNotifier *note)
{
+ wmWindow *win= CTX_wm_window(C);
/* generic notes */
switch(note->category) {
@@ -973,8 +974,11 @@ void ED_screen_do_listen(wmWindow *win, wmNotifier *note)
win->screen->do_draw= 1;
break;
case NC_SCREEN:
+ if(note->data==ND_SUBWINACTIVE)
+ uiFreeActiveButtons(C, win->screen);
if(note->action==NA_EDITED)
win->screen->do_draw= win->screen->do_refresh= 1;
+ break;
case NC_SCENE:
if(note->data==ND_MODE)
region_cursor_set(win, note->swinid);
@@ -1217,8 +1221,10 @@ static void screen_cursor_set(wmWindow *win, wmEvent *event)
/* called in wm_event_system.c. sets state vars in screen, cursors */
/* event type is mouse move */
-void ED_screen_set_subwinactive(wmWindow *win, wmEvent *event)
+void ED_screen_set_subwinactive(bContext *C, wmEvent *event)
{
+ wmWindow *win= CTX_wm_window(C);
+
if(win->screen) {
bScreen *scr= win->screen;
ScrArea *sa;
@@ -1264,6 +1270,7 @@ void ED_screen_set_subwinactive(wmWindow *win, wmEvent *event)
}
else if(oldswin!=scr->subwinactive) {
region_cursor_set(win, scr->subwinactive);
+ WM_event_add_notifier(C, NC_SCREEN|ND_SUBWINACTIVE, scr);
}
}
}
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 70bb4d48296..0c3a430089f 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -66,6 +66,7 @@
#include "ED_armature.h"
#include "ED_screen_types.h"
#include "ED_keyframes_draw.h"
+#include "ED_view3d.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -1417,7 +1418,10 @@ static int area_split_modal(bContext *C, wmOperator *op, wmEvent *event)
sd->origmin= sd->sarea->totrct.ymin;
sd->sarea->flag |= AREA_FLAG_DRAWSPLIT_H;
}
- }
+ }
+
+ CTX_wm_window(C)->screen->do_draw= 1;
+
}
fac= (dir == 'v') ? event->x-sd->origmin : event->y-sd->origmin;
@@ -2464,26 +2468,36 @@ static int region_quadview_exec(bContext *C, wmOperator *op)
/* lock views and set them */
if(sa->spacetype==SPACE_VIEW3D) {
+ /* run ED_view3d_lock() so the correct 'rv3d->viewquat' is set,
+ * otherwise when restoring rv3d->localvd the 'viewquat' won't
+ * match the 'view', set on entering localview See: [#26315],
+ *
+ * We could avoid manipulating rv3d->localvd here if exiting
+ * localview with a 4-split would assign these view locks */
RegionView3D *rv3d;
rv3d= ar->regiondata;
rv3d->viewlock= RV3D_LOCKED; rv3d->view= RV3D_VIEW_FRONT; rv3d->persp= RV3D_ORTHO;
- if (rv3d->localvd) { rv3d->localvd->view = rv3d->view; rv3d->localvd->persp = rv3d->persp; }
+ ED_view3d_lock(rv3d);
+ if (rv3d->localvd) { rv3d->localvd->view = rv3d->view; rv3d->localvd->persp = rv3d->persp; copy_qt_qt(rv3d->localvd->viewquat, rv3d->viewquat);}
ar= ar->next;
rv3d= ar->regiondata;
rv3d->viewlock= RV3D_LOCKED; rv3d->view= RV3D_VIEW_TOP; rv3d->persp= RV3D_ORTHO;
- if (rv3d->localvd) { rv3d->localvd->view = rv3d->view; rv3d->localvd->persp = rv3d->persp; }
+ ED_view3d_lock(rv3d);
+ if (rv3d->localvd) { rv3d->localvd->view = rv3d->view; rv3d->localvd->persp = rv3d->persp; copy_qt_qt(rv3d->localvd->viewquat, rv3d->viewquat);}
ar= ar->next;
rv3d= ar->regiondata;
rv3d->viewlock= RV3D_LOCKED; rv3d->view= RV3D_VIEW_RIGHT; rv3d->persp= RV3D_ORTHO;
- if (rv3d->localvd) { rv3d->localvd->view = rv3d->view; rv3d->localvd->persp = rv3d->persp; }
+ ED_view3d_lock(rv3d);
+ if (rv3d->localvd) { rv3d->localvd->view = rv3d->view; rv3d->localvd->persp = rv3d->persp; copy_qt_qt(rv3d->localvd->viewquat, rv3d->viewquat);}
ar= ar->next;
rv3d= ar->regiondata;
rv3d->view= RV3D_VIEW_CAMERA; rv3d->persp= RV3D_CAMOB;
- if (rv3d->localvd) {rv3d->localvd->view = rv3d->view; rv3d->localvd->persp = rv3d->persp; }
+ ED_view3d_lock(rv3d);
+ if (rv3d->localvd) {rv3d->localvd->view = rv3d->view; rv3d->localvd->persp = rv3d->persp; copy_qt_qt(rv3d->localvd->viewquat, rv3d->viewquat);}
}
ED_area_tag_redraw(sa);
WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 6c696ac357b..83f3661ac31 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -512,8 +512,34 @@ static float VecZDepthOrtho(float pt[2], float v1[3], float v2[3], float v3[3],
static float VecZDepthPersp(float pt[2], float v1[3], float v2[3], float v3[3], float w[3])
{
+ float wtot_inv, wtot;
+ float w_tmp[3];
+
barycentric_weights_v2_persp(v1, v2, v3, pt, w);
- return (v1[2]*w[0]) + (v2[2]*w[1]) + (v3[2]*w[2]);
+ /* for the depth we need the weights to match what
+ * barycentric_weights_v2 would return, in this case its easiest just to
+ * undo the 4th axis division and make it unit-sum
+ *
+ * don't call barycentric_weights_v2() becaue our callers expect 'w'
+ * to be weighted from the perspective */
+ w_tmp[0]= w[0] * v1[3];
+ w_tmp[1]= w[1] * v2[3];
+ w_tmp[2]= w[2] * v3[3];
+
+ wtot = w_tmp[0]+w_tmp[1]+w_tmp[2];
+
+ if (wtot != 0.0f) {
+ wtot_inv = 1.0f/wtot;
+
+ w_tmp[0] = w_tmp[0]*wtot_inv;
+ w_tmp[1] = w_tmp[1]*wtot_inv;
+ w_tmp[2] = w_tmp[2]*wtot_inv;
+ }
+ else /* dummy values for zero area face */
+ w_tmp[0] = w_tmp[1] = w_tmp[2] = 1.0f/3.0f;
+ /* done mimicing barycentric_weights_v2() */
+
+ return (v1[2]*w_tmp[0]) + (v2[2]*w_tmp[1]) + (v3[2]*w_tmp[2]);
}
@@ -5587,6 +5613,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
int w= settings->imapaint.screen_grab_size[0];
int h= settings->imapaint.screen_grab_size[1];
int maxsize;
+ char err_out[256]= "unknown";
RNA_string_get(op->ptr, "filepath", filename);
@@ -5595,11 +5622,11 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
if(w > maxsize) w= maxsize;
if(h > maxsize) h= maxsize;
- ibuf= ED_view3d_draw_offscreen_imbuf(CTX_data_scene(C), CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect);
+ ibuf= ED_view3d_draw_offscreen_imbuf(CTX_data_scene(C), CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, err_out);
if(!ibuf) {
/* Mostly happens when OpenGL offscreen buffer was failed to create, */
/* but could be other reasons. Should be handled in the future. nazgul */
- BKE_report(op->reports, RPT_ERROR, "Failed to create OpenGL offscreen buffer.");
+ BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL offscreen buffer: %s", err_out);
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 3f37238c40f..1e3aa4fca1b 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -390,7 +390,7 @@ static int sculpt_get_brush_geometry(bContext* C, int x, int y, int* pixel_radiu
if (*pixel_radius == 0)
*pixel_radius = brush_size(stroke->brush);
- mul_m4_v3(stroke->vc.obact->sculpt->ob->obmat, location);
+ mul_m4_v3(stroke->vc.obact->obmat, location);
hit = 1;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 4f4d6b2ef11..c82b7ffdafa 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -814,8 +814,9 @@ static void add_norm_if(float view_vec[3], float out[3], float out_flip[3], floa
}
}
-static void calc_area_normal(Sculpt *sd, SculptSession *ss, float an[3], PBVHNode **nodes, int totnode)
+static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nodes, int totnode)
{
+ SculptSession *ss = ob->sculpt;
int n;
float out_flip[3] = {0.0f, 0.0f, 0.0f};
@@ -832,7 +833,7 @@ static void calc_area_normal(Sculpt *sd, SculptSession *ss, float an[3], PBVHNod
float private_an[3] = {0.0f, 0.0f, 0.0f};
float private_out_flip[3] = {0.0f, 0.0f, 0.0f};
- unode = sculpt_undo_push_node(ss, nodes[n]);
+ unode = sculpt_undo_push_node(ob, nodes[n]);
sculpt_brush_test_init(ss, &test);
if(ss->cache->original) {
@@ -878,8 +879,9 @@ static void calc_area_normal(Sculpt *sd, SculptSession *ss, float an[3], PBVHNod
/* This initializes the faces to be moved for this sculpt for draw/layer/flatten; then it
finds average normal for all active vertices - note that this is called once for each mirroring direction */
-static void calc_sculpt_normal(Sculpt *sd, SculptSession *ss, float an[3], PBVHNode **nodes, int totnode)
+static void calc_sculpt_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nodes, int totnode)
{
+ SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
if (ss->cache->mirror_symmetry_pass == 0 &&
@@ -910,7 +912,7 @@ static void calc_sculpt_normal(Sculpt *sd, SculptSession *ss, float an[3], PBVHN
break;
case SCULPT_DISP_DIR_AREA:
- calc_area_normal(sd, ss, an, nodes, totnode);
+ calc_area_normal(sd, ob, an, nodes, totnode);
default:
break;
@@ -1113,8 +1115,9 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no
}
}
-static void smooth(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode, float bstrength)
+static void smooth(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float bstrength)
{
+ SculptSession *ss = ob->sculpt;
const int max_iterations = 4;
const float fract = 1.0f/max_iterations;
int iteration, n, count;
@@ -1136,23 +1139,25 @@ static void smooth(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode,
}
if(ss->multires)
- multires_stitch_grids(ss->ob);
+ multires_stitch_grids(ob);
}
}
-static void do_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode)
+static void do_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
- smooth(sd, ss, nodes, totnode, ss->cache->bstrength);
+ SculptSession *ss = ob->sculpt;
+ smooth(sd, ob, nodes, totnode, ss->cache->bstrength);
}
-static void do_draw_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode)
+static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
+ SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
float offset[3], area_normal[3];
float bstrength= ss->cache->bstrength;
int n;
- calc_sculpt_normal(sd, ss, area_normal, nodes, totnode);
+ calc_sculpt_normal(sd, ob, area_normal, nodes, totnode);
/* offset with as much as possible factored in already */
mul_v3_v3fl(offset, area_normal, ss->cache->radius);
@@ -1186,15 +1191,16 @@ static void do_draw_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int t
}
}
-static void do_crease_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode)
+static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
+ SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
float offset[3], area_normal[3];
float bstrength= ss->cache->bstrength;
float flippedbstrength, crease_correction;
int n;
- calc_sculpt_normal(sd, ss, area_normal, nodes, totnode);
+ calc_sculpt_normal(sd, ob, area_normal, nodes, totnode);
/* offset with as much as possible factored in already */
mul_v3_v3fl(offset, area_normal, ss->cache->radius);
@@ -1249,8 +1255,9 @@ static void do_crease_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int
}
}
-static void do_pinch_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode)
+static void do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
+ SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
float bstrength= ss->cache->bstrength;
int n;
@@ -1281,8 +1288,9 @@ static void do_pinch_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int
}
}
-static void do_grab_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode)
+static void do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
+ SculptSession *ss = ob->sculpt;
Brush *brush= paint_brush(&sd->paint);
float bstrength= ss->cache->bstrength;
float grab_delta[3], an[3];
@@ -1293,7 +1301,7 @@ static void do_grab_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int t
int cache= 1;
/* grab brush requires to test on original data */
SWAP(int, ss->cache->original, cache);
- calc_sculpt_normal(sd, ss, an, nodes, totnode);
+ calc_sculpt_normal(sd, ob, an, nodes, totnode);
SWAP(int, ss->cache->original, cache);
}
@@ -1316,7 +1324,7 @@ static void do_grab_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int t
short (*origno)[3];
float (*proxy)[3];
- unode= sculpt_undo_push_node(ss, nodes[n]);
+ unode= sculpt_undo_push_node(ob, nodes[n]);
origco= unode->co;
origno= unode->no;
@@ -1338,8 +1346,9 @@ static void do_grab_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int t
}
}
-static void do_nudge_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode)
+static void do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
+ SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
float bstrength = ss->cache->bstrength;
float grab_delta[3];
@@ -1349,7 +1358,7 @@ static void do_nudge_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int
copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
- calc_sculpt_normal(sd, ss, an, nodes, totnode);
+ calc_sculpt_normal(sd, ob, an, nodes, totnode);
cross_v3_v3v3(tmp, an, grab_delta);
cross_v3_v3v3(cono, tmp, an);
@@ -1378,8 +1387,9 @@ static void do_nudge_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int
}
}
-static void do_snake_hook_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode)
+static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
+ SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
float bstrength = ss->cache->bstrength;
float grab_delta[3], an[3];
@@ -1387,7 +1397,7 @@ static void do_snake_hook_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes,
float len;
if (brush->normal_weight > 0 || brush->flag & BRUSH_FRONTFACE)
- calc_sculpt_normal(sd, ss, an, nodes, totnode);
+ calc_sculpt_normal(sd, ob, an, nodes, totnode);
copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
@@ -1426,8 +1436,9 @@ static void do_snake_hook_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes,
}
}
-static void do_thumb_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode)
+static void do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
+ SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
float bstrength = ss->cache->bstrength;
float grab_delta[3];
@@ -1437,7 +1448,7 @@ static void do_thumb_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int
copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
- calc_sculpt_normal(sd, ss, an, nodes, totnode);
+ calc_sculpt_normal(sd, ob, an, nodes, totnode);
cross_v3_v3v3(tmp, an, grab_delta);
cross_v3_v3v3(cono, tmp, an);
@@ -1451,7 +1462,7 @@ static void do_thumb_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int
short (*origno)[3];
float (*proxy)[3];
- unode= sculpt_undo_push_node(ss, nodes[n]);
+ unode= sculpt_undo_push_node(ob, nodes[n]);
origco= unode->co;
origno= unode->no;
@@ -1473,8 +1484,9 @@ static void do_thumb_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int
}
}
-static void do_rotate_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode)
+static void do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
+ SculptSession *ss = ob->sculpt;
Brush *brush= paint_brush(&sd->paint);
float bstrength= ss->cache->bstrength;
float an[3];
@@ -1483,7 +1495,7 @@ static void do_rotate_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int
static const int flip[8] = { 1, -1, -1, 1, -1, 1, 1, -1 };
float angle = ss->cache->vertex_rotation * flip[ss->cache->mirror_symmetry_pass];
- calc_sculpt_normal(sd, ss, an, nodes, totnode);
+ calc_sculpt_normal(sd, ob, an, nodes, totnode);
axis_angle_to_mat3(m, an, angle);
@@ -1496,7 +1508,7 @@ static void do_rotate_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int
short (*origno)[3];
float (*proxy)[3];
- unode= sculpt_undo_push_node(ss, nodes[n]);
+ unode= sculpt_undo_push_node(ob, nodes[n]);
origco= unode->co;
origno= unode->no;
@@ -1520,8 +1532,9 @@ static void do_rotate_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int
}
}
-static void do_layer_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode)
+static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
+ SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
float bstrength= ss->cache->bstrength;
float area_normal[3], offset[3];
@@ -1531,7 +1544,7 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int
if(bstrength < 0)
lim = -lim;
- calc_sculpt_normal(sd, ss, area_normal, nodes, totnode);
+ calc_sculpt_normal(sd, ob, area_normal, nodes, totnode);
mul_v3_v3v3(offset, ss->cache->scale, area_normal);
@@ -1545,7 +1558,7 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int
//proxy= BLI_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co;
- unode= sculpt_undo_push_node(ss, nodes[n]);
+ unode= sculpt_undo_push_node(ob, nodes[n]);
origco=unode->co;
if(!unode->layer_disp)
{
@@ -1591,8 +1604,9 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int
}
}
-static void do_inflate_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode)
+static void do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
+ SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
float bstrength= ss->cache->bstrength;
int n;
@@ -1626,8 +1640,9 @@ static void do_inflate_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, in
}
}
-static void calc_flatten_center(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode, float fc[3])
+static void calc_flatten_center(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float fc[3])
{
+ SculptSession *ss = ob->sculpt;
int n;
float count = 0;
@@ -1644,7 +1659,7 @@ static void calc_flatten_center(Sculpt *sd, SculptSession *ss, PBVHNode **nodes,
float private_fc[3] = {0.0f, 0.0f, 0.0f};
int private_count = 0;
- unode = sculpt_undo_push_node(ss, nodes[n]);
+ unode = sculpt_undo_push_node(ob, nodes[n]);
sculpt_brush_test_init(ss, &test);
if(ss->cache->original) {
@@ -1678,8 +1693,9 @@ static void calc_flatten_center(Sculpt *sd, SculptSession *ss, PBVHNode **nodes,
/* this calculates flatten center and area normal together,
amortizing the memory bandwidth and loop overhead to calculate both at the same time */
-static void calc_area_normal_and_flatten_center(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode, float an[3], float fc[3])
+static void calc_area_normal_and_flatten_center(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float an[3], float fc[3])
{
+ SculptSession *ss = ob->sculpt;
int n;
// an
@@ -1706,7 +1722,7 @@ static void calc_area_normal_and_flatten_center(Sculpt *sd, SculptSession *ss, P
float private_fc[3] = {0.0f, 0.0f, 0.0f};
int private_count = 0;
- unode = sculpt_undo_push_node(ss, nodes[n]);
+ unode = sculpt_undo_push_node(ob, nodes[n]);
sculpt_brush_test_init(ss, &test);
if(ss->cache->original) {
@@ -1774,8 +1790,9 @@ static void calc_area_normal_and_flatten_center(Sculpt *sd, SculptSession *ss, P
}
}
-static void calc_sculpt_plane(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode, float an[3], float fc[3])
+static void calc_sculpt_plane(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float an[3], float fc[3])
{
+ SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
if (ss->cache->mirror_symmetry_pass == 0 &&
@@ -1806,7 +1823,7 @@ static void calc_sculpt_plane(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, i
break;
case SCULPT_DISP_DIR_AREA:
- calc_area_normal_and_flatten_center(sd, ss, nodes, totnode, an, fc);
+ calc_area_normal_and_flatten_center(sd, ob, nodes, totnode, an, fc);
default:
break;
@@ -1815,7 +1832,7 @@ static void calc_sculpt_plane(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, i
// fc
/* flatten center has not been calculated yet if we are not using the area normal */
if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA)
- calc_flatten_center(sd, ss, nodes, totnode, fc);
+ calc_flatten_center(sd, ob, nodes, totnode, fc);
// an
copy_v3_v3(ss->cache->last_area_normal, an);
@@ -1891,8 +1908,9 @@ static float get_offset(Sculpt *sd, SculptSession *ss)
return rv;
}
-static void do_flatten_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode)
+static void do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
+ SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
float bstrength = ss->cache->bstrength;
@@ -1909,7 +1927,7 @@ static void do_flatten_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, in
float temp[3];
- calc_sculpt_plane(sd, ss, nodes, totnode, an, fc);
+ calc_sculpt_plane(sd, ob, nodes, totnode, an, fc);
displace = radius*offset;
@@ -1950,8 +1968,9 @@ static void do_flatten_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, in
}
}
-static void do_clay_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode)
+static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
+ SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
float bstrength = ss->cache->bstrength;
@@ -1970,7 +1989,7 @@ static void do_clay_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int t
int flip;
- calc_sculpt_plane(sd, ss, nodes, totnode, an, fc);
+ calc_sculpt_plane(sd, ob, nodes, totnode, an, fc);
flip = bstrength < 0;
@@ -2023,8 +2042,9 @@ static void do_clay_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int t
}
}
-static void do_clay_tubes_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode)
+static void do_clay_tubes_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
+ SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
float bstrength = ss->cache->bstrength;
@@ -2046,10 +2066,10 @@ static void do_clay_tubes_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes,
int flip;
- calc_sculpt_plane(sd, ss, nodes, totnode, sn, fc);
+ calc_sculpt_plane(sd, ob, nodes, totnode, sn, fc);
if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA || (brush->flag & BRUSH_ORIGINAL_NORMAL))
- calc_area_normal(sd, ss, an, nodes, totnode);
+ calc_area_normal(sd, ob, an, nodes, totnode);
else
copy_v3_v3(an, sn);
@@ -2113,8 +2133,9 @@ static void do_clay_tubes_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes,
}
}
-static void do_fill_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode)
+static void do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
+ SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
float bstrength = ss->cache->bstrength;
@@ -2130,7 +2151,7 @@ static void do_fill_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int t
float temp[3];
- calc_sculpt_plane(sd, ss, nodes, totnode, an, fc);
+ calc_sculpt_plane(sd, ob, nodes, totnode, an, fc);
displace = radius*offset;
@@ -2173,8 +2194,9 @@ static void do_fill_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int t
}
}
-static void do_scrape_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode)
+static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
+ SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
float bstrength = ss->cache->bstrength;
@@ -2190,7 +2212,7 @@ static void do_scrape_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int
float temp[3];
- calc_sculpt_plane(sd, ss, nodes, totnode, an, fc);
+ calc_sculpt_plane(sd, ob, nodes, totnode, an, fc);
displace = -radius*offset;
@@ -2283,8 +2305,9 @@ void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3])
vertcos_to_key(ob, kb, vertCos);
}
-static void do_brush_action(Sculpt *sd, SculptSession *ss, Brush *brush)
+static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush)
{
+ SculptSession *ss = ob->sculpt;
SculptSearchSphereData data;
PBVHNode **nodes = NULL;
int n, totnode;
@@ -2300,71 +2323,71 @@ static void do_brush_action(Sculpt *sd, SculptSession *ss, Brush *brush)
if (totnode) {
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
for (n= 0; n < totnode; n++) {
- sculpt_undo_push_node(ss, nodes[n]);
+ sculpt_undo_push_node(ob, nodes[n]);
BLI_pbvh_node_mark_update(nodes[n]);
}
/* Apply one type of brush action */
switch(brush->sculpt_tool){
case SCULPT_TOOL_DRAW:
- do_draw_brush(sd, ss, nodes, totnode);
+ do_draw_brush(sd, ob, nodes, totnode);
break;
case SCULPT_TOOL_SMOOTH:
- do_smooth_brush(sd, ss, nodes, totnode);
+ do_smooth_brush(sd, ob, nodes, totnode);
break;
case SCULPT_TOOL_CREASE:
- do_crease_brush(sd, ss, nodes, totnode);
+ do_crease_brush(sd, ob, nodes, totnode);
break;
case SCULPT_TOOL_BLOB:
- do_crease_brush(sd, ss, nodes, totnode);
+ do_crease_brush(sd, ob, nodes, totnode);
break;
case SCULPT_TOOL_PINCH:
- do_pinch_brush(sd, ss, nodes, totnode);
+ do_pinch_brush(sd, ob, nodes, totnode);
break;
case SCULPT_TOOL_INFLATE:
- do_inflate_brush(sd, ss, nodes, totnode);
+ do_inflate_brush(sd, ob, nodes, totnode);
break;
case SCULPT_TOOL_GRAB:
- do_grab_brush(sd, ss, nodes, totnode);
+ do_grab_brush(sd, ob, nodes, totnode);
break;
case SCULPT_TOOL_ROTATE:
- do_rotate_brush(sd, ss, nodes, totnode);
+ do_rotate_brush(sd, ob, nodes, totnode);
break;
case SCULPT_TOOL_SNAKE_HOOK:
- do_snake_hook_brush(sd, ss, nodes, totnode);
+ do_snake_hook_brush(sd, ob, nodes, totnode);
break;
case SCULPT_TOOL_NUDGE:
- do_nudge_brush(sd, ss, nodes, totnode);
+ do_nudge_brush(sd, ob, nodes, totnode);
break;
case SCULPT_TOOL_THUMB:
- do_thumb_brush(sd, ss, nodes, totnode);
+ do_thumb_brush(sd, ob, nodes, totnode);
break;
case SCULPT_TOOL_LAYER:
- do_layer_brush(sd, ss, nodes, totnode);
+ do_layer_brush(sd, ob, nodes, totnode);
break;
case SCULPT_TOOL_FLATTEN:
- do_flatten_brush(sd, ss, nodes, totnode);
+ do_flatten_brush(sd, ob, nodes, totnode);
break;
case SCULPT_TOOL_CLAY:
- do_clay_brush(sd, ss, nodes, totnode);
+ do_clay_brush(sd, ob, nodes, totnode);
break;
case SCULPT_TOOL_CLAY_TUBES:
- do_clay_tubes_brush(sd, ss, nodes, totnode);
+ do_clay_tubes_brush(sd, ob, nodes, totnode);
break;
case SCULPT_TOOL_FILL:
- do_fill_brush(sd, ss, nodes, totnode);
+ do_fill_brush(sd, ob, nodes, totnode);
break;
case SCULPT_TOOL_SCRAPE:
- do_scrape_brush(sd, ss, nodes, totnode);
+ do_scrape_brush(sd, ob, nodes, totnode);
break;
}
if (brush->sculpt_tool != SCULPT_TOOL_SMOOTH && brush->autosmooth_factor > 0) {
if (brush->flag & BRUSH_INVERSE_SMOOTH_PRESSURE) {
- smooth(sd, ss, nodes, totnode, brush->autosmooth_factor*(1-ss->cache->pressure));
+ smooth(sd, ob, nodes, totnode, brush->autosmooth_factor*(1-ss->cache->pressure));
}
else {
- smooth(sd, ss, nodes, totnode, brush->autosmooth_factor);
+ smooth(sd, ob, nodes, totnode, brush->autosmooth_factor);
}
}
@@ -2373,9 +2396,9 @@ static void do_brush_action(Sculpt *sd, SculptSession *ss, Brush *brush)
}
/* flush displacement from deformed PBVH vertex to original mesh */
-static void sculpt_flush_pbvhvert_deform(SculptSession *ss, PBVHVertexIter *vd)
+static void sculpt_flush_pbvhvert_deform(Object *ob, PBVHVertexIter *vd)
{
- Object *ob= ss->ob;
+ SculptSession *ss = ob->sculpt;
Mesh *me= ob->data;
float disp[3], newco[3];
int index= vd->vert_indices[vd->i];
@@ -2391,8 +2414,9 @@ static void sculpt_flush_pbvhvert_deform(SculptSession *ss, PBVHVertexIter *vd)
copy_v3_v3(me->mvert[index].co, newco);
}
-static void sculpt_combine_proxies(Sculpt *sd, SculptSession *ss)
+static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
{
+ SculptSession *ss = ob->sculpt;
Brush *brush= paint_brush(&sd->paint);
PBVHNode** nodes;
int totnode, n;
@@ -2412,7 +2436,7 @@ static void sculpt_combine_proxies(Sculpt *sd, SculptSession *ss)
float (*orco)[3];
if(use_orco)
- orco= sculpt_undo_push_node(ss, nodes[n])->co;
+ orco= sculpt_undo_push_node(ob, nodes[n])->co;
BLI_pbvh_node_get_proxies(nodes[n], &proxies, &proxy_count);
@@ -2431,7 +2455,7 @@ static void sculpt_combine_proxies(Sculpt *sd, SculptSession *ss)
sculpt_clip(sd, ss, vd.co, val);
if(ss->modifiers_active)
- sculpt_flush_pbvhvert_deform(ss, &vd);
+ sculpt_flush_pbvhvert_deform(ob, &vd);
}
BLI_pbvh_vertex_iter_end;
@@ -2444,8 +2468,9 @@ static void sculpt_combine_proxies(Sculpt *sd, SculptSession *ss)
}
/* copy the modified vertices from bvh to the active key */
-static void sculpt_update_keyblock(SculptSession *ss)
+static void sculpt_update_keyblock(Object *ob)
{
+ SculptSession *ss = ob->sculpt;
float (*vertCos)[3];
/* Keyblock update happens after hadning deformation caused by modifiers,
@@ -2454,7 +2479,7 @@ static void sculpt_update_keyblock(SculptSession *ss)
else vertCos = BLI_pbvh_get_vertCos(ss->pbvh);
if (vertCos) {
- sculpt_vertcos_to_key(ss->ob, ss->kb, vertCos);
+ sculpt_vertcos_to_key(ob, ss->kb, vertCos);
if(vertCos != ss->orig_cos)
MEM_freeN(vertCos);
@@ -2462,10 +2487,11 @@ static void sculpt_update_keyblock(SculptSession *ss)
}
/* flush displacement from deformed PBVH to original layer */
-static void sculpt_flush_stroke_deform(Sculpt *sd, SculptSession *ss)
+static void sculpt_flush_stroke_deform(Sculpt *sd, Object *ob)
{
+ SculptSession *ss = ob->sculpt;
+
if(!ss->kb) {
- Object *ob= ss->ob;
Mesh *me= (Mesh*)ob->data;
Brush *brush= paint_brush(&sd->paint);
@@ -2483,7 +2509,7 @@ static void sculpt_flush_stroke_deform(Sculpt *sd, SculptSession *ss)
PBVHVertexIter vd;
BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) {
- sculpt_flush_pbvhvert_deform(ss, &vd);
+ sculpt_flush_pbvhvert_deform(ob, &vd);
}
BLI_pbvh_vertex_iter_end;
}
@@ -2495,7 +2521,7 @@ static void sculpt_flush_stroke_deform(Sculpt *sd, SculptSession *ss)
Note, then if sculpting happens on locked key, normals should be re-calculated
after applying coords from keyblock on base mesh */
mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
- } else sculpt_update_keyblock(ss);
+ } else sculpt_update_keyblock(ob);
}
//static int max_overlap_count(Sculpt *sd)
@@ -2549,33 +2575,36 @@ static void calc_brushdata_symm(Sculpt *sd, StrokeCache *cache, const char symm,
mul_m4_v3(cache->symm_rot_mat, cache->grab_delta_symmetry);
}
-static void do_radial_symmetry(Sculpt *sd, SculptSession *ss, Brush *brush, const char symm, const int axis, const float feather)
+static void do_radial_symmetry(Sculpt *sd, Object *ob, Brush *brush, const char symm, const int axis, const float feather)
{
+ SculptSession *ss = ob->sculpt;
int i;
for(i = 1; i < sd->radial_symm[axis-'X']; ++i) {
const float angle = 2*M_PI*i/sd->radial_symm[axis-'X'];
ss->cache->radial_symmetry_pass= i;
calc_brushdata_symm(sd, ss->cache, symm, axis, angle, feather);
- do_brush_action(sd, ss, brush);
+ do_brush_action(sd, ob, brush);
}
}
/* noise texture gives different values for the same input coord; this
can tear a multires mesh during sculpting so do a stitch in this
case */
-static void sculpt_fix_noise_tear(Sculpt *sd, SculptSession *ss)
+static void sculpt_fix_noise_tear(Sculpt *sd, Object *ob)
{
+ SculptSession *ss = ob->sculpt;
Brush *brush = paint_brush(&sd->paint);
MTex *mtex = &brush->mtex;
if(ss->multires && mtex->tex && mtex->tex->type == TEX_NOISE)
- multires_stitch_grids(ss->ob);
+ multires_stitch_grids(ob);
}
-static void do_symmetrical_brush_actions(Sculpt *sd, SculptSession *ss)
+static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob)
{
Brush *brush = paint_brush(&sd->paint);
+ SculptSession *ss = ob->sculpt;
StrokeCache *cache = ss->cache;
const char symm = sd->flags & 7;
int i;
@@ -2593,21 +2622,21 @@ static void do_symmetrical_brush_actions(Sculpt *sd, SculptSession *ss)
cache->radial_symmetry_pass= 0;
calc_brushdata_symm(sd, cache, i, 0, 0, feather);
- do_brush_action(sd, ss, brush);
+ do_brush_action(sd, ob, brush);
- do_radial_symmetry(sd, ss, brush, i, 'X', feather);
- do_radial_symmetry(sd, ss, brush, i, 'Y', feather);
- do_radial_symmetry(sd, ss, brush, i, 'Z', feather);
+ do_radial_symmetry(sd, ob, brush, i, 'X', feather);
+ do_radial_symmetry(sd, ob, brush, i, 'Y', feather);
+ do_radial_symmetry(sd, ob, brush, i, 'Z', feather);
}
}
- sculpt_combine_proxies(sd, ss);
+ sculpt_combine_proxies(sd, ob);
/* hack to fix noise texture tearing mesh */
- sculpt_fix_noise_tear(sd, ss);
+ sculpt_fix_noise_tear(sd, ob);
if (ss->modifiers_active)
- sculpt_flush_stroke_deform(sd, ss);
+ sculpt_flush_stroke_deform(sd, ob);
cache->first_time= 0;
}
@@ -2647,8 +2676,6 @@ void sculpt_update_mesh_elements(Scene *scene, Object *ob, int need_fmap)
SculptSession *ss = ob->sculpt;
MultiresModifierData *mmd= sculpt_multires_active(scene, ob);
- ss->ob= ob;
-
ss->modifiers_active= sculpt_modifiers_active(scene, ob);
if((ob->shapeflag & OB_SHAPE_LOCK) && !mmd) ss->kb= ob_get_keyblock(ob);
@@ -2967,8 +2994,9 @@ static void sculpt_update_cache_invariants(bContext* C, Sculpt *sd, SculptSessio
cache->vertex_rotation= 0;
}
-static void sculpt_update_brush_delta(Sculpt *sd, SculptSession *ss, Brush *brush)
+static void sculpt_update_brush_delta(Sculpt *sd, Object *ob, Brush *brush)
{
+ SculptSession *ss = ob->sculpt;
StrokeCache *cache = ss->cache;
int tool = brush->sculpt_tool;
@@ -3000,19 +3028,19 @@ static void sculpt_update_brush_delta(Sculpt *sd, SculptSession *ss, Brush *brus
case SCULPT_TOOL_GRAB:
case SCULPT_TOOL_THUMB:
sub_v3_v3v3(delta, grab_location, cache->old_grab_location);
- invert_m4_m4(imat, ss->ob->obmat);
+ invert_m4_m4(imat, ob->obmat);
mul_mat3_m4_v3(imat, delta);
add_v3_v3(cache->grab_delta, delta);
break;
case SCULPT_TOOL_CLAY_TUBES:
case SCULPT_TOOL_NUDGE:
sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location);
- invert_m4_m4(imat, ss->ob->obmat);
+ invert_m4_m4(imat, ob->obmat);
mul_mat3_m4_v3(imat, cache->grab_delta);
break;
case SCULPT_TOOL_SNAKE_HOOK:
sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location);
- invert_m4_m4(imat, ss->ob->obmat);
+ invert_m4_m4(imat, ob->obmat);
mul_mat3_m4_v3(imat, cache->grab_delta);
break;
}
@@ -3040,8 +3068,9 @@ static void sculpt_update_brush_delta(Sculpt *sd, SculptSession *ss, Brush *brus
}
/* Initialize the stroke cache variants from operator properties */
-static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, SculptSession *ss, struct PaintStroke *stroke, PointerRNA *ptr)
+static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, struct PaintStroke *stroke, PointerRNA *ptr)
{
+ SculptSession *ss = ob->sculpt;
StrokeCache *cache = ss->cache;
Brush *brush = paint_brush(&sd->paint);
@@ -3167,7 +3196,7 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, SculptSession
}
}
- sculpt_update_brush_delta(sd, ss, brush);
+ sculpt_update_brush_delta(sd, ob, brush);
if(brush->sculpt_tool == SCULPT_TOOL_ROTATE) {
dx = cache->mouse[0] - cache->initial_mouse[0];
@@ -3184,13 +3213,15 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, SculptSession
sd->special_rotation = cache->special_rotation;
}
-static void sculpt_stroke_modifiers_check(bContext *C, SculptSession *ss)
+static void sculpt_stroke_modifiers_check(bContext *C, Object *ob)
{
+ SculptSession *ss = ob->sculpt;
+
if(ss->modifiers_active) {
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
Brush *brush = paint_brush(&sd->paint);
- sculpt_update_mesh_elements(CTX_data_scene(C), ss->ob, brush->sculpt_tool == SCULPT_TOOL_SMOOTH);
+ sculpt_update_mesh_elements(CTX_data_scene(C), ob, brush->sculpt_tool == SCULPT_TOOL_SMOOTH);
}
}
@@ -3228,7 +3259,8 @@ static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float* tmin)
int sculpt_stroke_get_location(bContext *C, struct PaintStroke *stroke, float out[3], float mouse[2])
{
ViewContext *vc = paint_stroke_view_context(stroke);
- SculptSession *ss= vc->obact->sculpt;
+ Object *ob = vc->obact;
+ SculptSession *ss= ob->sculpt;
StrokeCache *cache= ss->cache;
float ray_start[3], ray_end[3], ray_normal[3], dist;
float obimat[4][4];
@@ -3238,11 +3270,11 @@ int sculpt_stroke_get_location(bContext *C, struct PaintStroke *stroke, float ou
mval[0] = mouse[0] - vc->ar->winrct.xmin;
mval[1] = mouse[1] - vc->ar->winrct.ymin;
- sculpt_stroke_modifiers_check(C, ss);
+ sculpt_stroke_modifiers_check(C, ob);
viewline(vc->ar, vc->v3d, mval, ray_start, ray_end);
- invert_m4_m4(obimat, ss->ob->obmat);
+ invert_m4_m4(obimat, ob->obmat);
mul_m4_v3(obimat, ray_start);
mul_m4_v3(obimat, ray_end);
@@ -3440,12 +3472,13 @@ static int sculpt_stroke_test_start(bContext *C, struct wmOperator *op,
static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
{
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
- SculptSession *ss = CTX_data_active_object(C)->sculpt;
-
- sculpt_stroke_modifiers_check(C, ss);
- sculpt_update_cache_variants(C, sd, ss, stroke, itemptr);
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+
+ sculpt_stroke_modifiers_check(C, ob);
+ sculpt_update_cache_variants(C, sd, ob, stroke, itemptr);
sculpt_restore_mesh(sd, ss);
- do_symmetrical_brush_actions(sd, ss);
+ do_symmetrical_brush_actions(sd, ob);
/* Cleanup */
sculpt_flush_update(C);
@@ -3478,7 +3511,7 @@ static void sculpt_stroke_done(bContext *C, struct PaintStroke *unused)
Brush *brush= paint_brush(&sd->paint);
brush->flag &= ~BRUSH_INVERTED;
- sculpt_stroke_modifiers_check(C, ss);
+ sculpt_stroke_modifiers_check(C, ob);
/* Alt-Smooth */
if (ss->cache->alt_smooth) {
@@ -3499,7 +3532,7 @@ static void sculpt_stroke_done(bContext *C, struct PaintStroke *unused)
/* optimization: if there is locked key and active modifiers present in */
/* the stack, keyblock is updating at each step. otherwise we could update */
/* keyblock only when stroke is finished */
- if(ss->kb && !ss->modifiers_active) sculpt_update_keyblock(ss);
+ if(ss->kb && !ss->modifiers_active) sculpt_update_keyblock(ob);
ss->partial_redraw = 0;
@@ -3637,7 +3670,6 @@ static void SCULPT_OT_set_persistent_base(wmOperatorType *ot)
static void sculpt_init_session(Scene *scene, Object *ob)
{
ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
- ob->sculpt->ob = ob;
sculpt_update_mesh_elements(scene, ob, 0);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index e8073b259d4..5e017d0dc20 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -107,7 +107,7 @@ typedef struct SculptUndoNode {
char shapeName[sizeof(((KeyBlock *)0))->name];
} SculptUndoNode;
-SculptUndoNode *sculpt_undo_push_node(SculptSession *ss, PBVHNode *node);
+SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node);
SculptUndoNode *sculpt_undo_get_node(PBVHNode *node);
void sculpt_undo_push_begin(const char *name);
void sculpt_undo_push_end(void);
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 4e62c66c425..b463c77bbb7 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -246,10 +246,10 @@ SculptUndoNode *sculpt_undo_get_node(PBVHNode *node)
return NULL;
}
-SculptUndoNode *sculpt_undo_push_node(SculptSession *ss, PBVHNode *node)
+SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node)
{
ListBase *lb= undo_paint_push_get_list(UNDO_PAINT_MESH);
- Object *ob= ss->ob;
+ SculptSession *ss = ob->sculpt;
SculptUndoNode *unode;
int totvert, allvert, totgrid, maxgrid, gridsize, *grids;
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 0767da40984..8df1f218767 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -68,7 +68,7 @@ static SpaceLink *buttons_new(const bContext *UNUSED(C))
sbuts= MEM_callocN(sizeof(SpaceButs), "initbuts");
sbuts->spacetype= SPACE_BUTS;
- sbuts->align= BUT_AUTO;
+ sbuts->align= BUT_VERTICAL;
/* header */
ar= MEM_callocN(sizeof(ARegion), "header for buts");
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index bf30db97748..28f5423f3a6 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -1337,12 +1337,8 @@ void FILE_OT_delete(struct wmOperatorType *ot)
void ED_operatormacros_file(void)
{
- wmOperatorType *ot;
- wmOperatorTypeMacro *otmacro;
+// wmOperatorType *ot;
+// wmOperatorTypeMacro *otmacro;
- ot= WM_operatortype_append_macro("FILE_OT_select_execute", "Select and Execute", OPTYPE_UNDO|OPTYPE_REGISTER);
- WM_operatortype_macro_define(ot, "FILE_OT_select");
- otmacro= WM_operatortype_macro_define(ot, "FILE_OT_execute");
- RNA_boolean_set(otmacro->ptr, "need_active", 1);
-
+ /* future macros */
}
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index bd188d07a86..42efa5d4a3b 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -986,7 +986,7 @@ void filelist_from_library(struct FileList* filelist)
/* there we go */
/* for the time being only read filedata when libfiledata==0 */
if (filelist->libfiledata == NULL) {
- filelist->libfiledata= BLO_blendhandle_from_file(dir);
+ filelist->libfiledata= BLO_blendhandle_from_file(dir, NULL);
if(filelist->libfiledata == NULL) return;
}
@@ -997,16 +997,15 @@ void filelist_from_library(struct FileList* filelist)
previews = NULL;
if (idcode) {
previews= BLO_blendhandle_get_previews(filelist->libfiledata, idcode);
- names= BLO_blendhandle_get_datablock_names(filelist->libfiledata, idcode);
+ names= BLO_blendhandle_get_datablock_names(filelist->libfiledata, idcode, &nnames);
/* ugh, no rewind, need to reopen */
BLO_blendhandle_close(filelist->libfiledata);
- filelist->libfiledata= BLO_blendhandle_from_file(dir);
+ filelist->libfiledata= BLO_blendhandle_from_file(dir, NULL);
} else {
names= BLO_blendhandle_get_linkable_groups(filelist->libfiledata);
+ nnames= BLI_linklist_length(names);
}
-
- nnames= BLI_linklist_length(names);
filelist->numfiles= nnames + 1;
filelist->filelist= malloc(filelist->numfiles * sizeof(*filelist->filelist));
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index b8a512335c5..d4240a9ad53 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -412,7 +412,8 @@ static void file_keymap(struct wmKeyConfig *keyconf)
/* keys for main area */
keymap= WM_keymap_find(keyconf, "File Browser Main", SPACE_FILE, 0);
- WM_keymap_add_item(keymap, "FILE_OT_select_execute", LEFTMOUSE, KM_DBL_CLICK, 0, 0);
+ kmi= WM_keymap_add_item(keymap, "FILE_OT_execute", LEFTMOUSE, KM_DBL_CLICK, 0, 0);
+ RNA_boolean_set(kmi->ptr, "need_active", 1);
WM_keymap_add_item(keymap, "FILE_OT_select", LEFTMOUSE, KM_CLICK, 0, 0);
kmi = WM_keymap_add_item(keymap, "FILE_OT_select", LEFTMOUSE, KM_CLICK, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "extend", 1);
@@ -420,6 +421,7 @@ static void file_keymap(struct wmKeyConfig *keyconf)
RNA_boolean_set(kmi->ptr, "extend", 1);
RNA_boolean_set(kmi->ptr, "fill", 1);
WM_keymap_add_item(keymap, "FILE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "FILE_OT_refresh", PADPERIOD, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "FILE_OT_select_border", BKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "FILE_OT_select_border", EVT_TWEAK_L, KM_ANY, 0, 0);
WM_keymap_add_item(keymap, "FILE_OT_rename", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 18f2b4944e7..8bec0803c5e 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -239,7 +239,7 @@ static void borderselect_graphkeys (bAnimContext *ac, rcti rect, short mode, sho
* guess when a callback might use something different
*/
if (adt)
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, incl_handles==0);
/* set horizontal range (if applicable)
* NOTE: these values are only used for x-range and y-range but not region
@@ -269,7 +269,7 @@ static void borderselect_graphkeys (bAnimContext *ac, rcti rect, short mode, sho
/* un-apply NLA mapping from all the keyframes */
if (adt)
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, incl_handles==0);
/* unapply unit corrections */
ANIM_unit_mapping_apply_fcurve(ac->scene, ale->id, ale->key_data, ANIM_UNITCONV_RESTORE|ANIM_UNITCONV_ONLYKEYS);
@@ -987,7 +987,7 @@ static void get_nearest_fcurve_verts_list (bAnimContext *ac, int mval[2], ListBa
/* apply NLA mapping to all the keyframes */
if (adt)
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
if (fcu->bezt) {
BezTriple *bezt1=fcu->bezt, *prevbezt=NULL;
@@ -1020,7 +1020,7 @@ static void get_nearest_fcurve_verts_list (bAnimContext *ac, int mval[2], ListBa
/* un-apply NLA mapping from all the keyframes */
if (adt)
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
/* unapply unit corrections */
ANIM_unit_mapping_apply_fcurve(ac->scene, ale->id, ale->key_data, ANIM_UNITCONV_RESTORE);
@@ -1203,14 +1203,15 @@ static void mouse_graph_keys (bAnimContext *ac, int mval[], short select_mode, s
else if (select_mode == SELECT_ADD)
nvi->fcu->flag |= FCURVE_SELECTED;
}
-
- /* set active F-Curve (NOTE: sync the filter flags with findnearest_fcurve_vert) */
- if (nvi->fcu->flag & FCURVE_SELECTED) {
- int filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
- ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nvi->fcu, ANIMTYPE_FCURVE);
- }
}
-
+
+ /* set active F-Curve (NOTE: sync the filter flags with findnearest_fcurve_vert) */
+ /* needs to be called with (sipo->flag & SIPO_SELCUVERTSONLY) otherwise the active flag won't be set [#26452] */
+ if (nvi->fcu->flag & FCURVE_SELECTED) {
+ int filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nvi->fcu, ANIMTYPE_FCURVE);
+ }
+
/* free temp sample data for filtering */
MEM_freeN(nvi);
}
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index fd2c14dd434..93e5465cd64 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -2133,6 +2133,10 @@ static int cycle_render_slot_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL);
+ /* no undo push for browsing existing */
+ if(ima->renders[ima->render_slot] || ima->render_slot==ima->last_render_slot)
+ return OPERATOR_CANCELLED;
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index ebbb33631a9..f1261f1e6f5 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -284,7 +284,7 @@ static void node_update(const bContext *C, bNodeTree *ntree, bNode *node)
node->butr.xmax= node->width - 2*NODE_DYS;
node->butr.ymin= 0;
node->butr.ymax= 0;
-
+
RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
layout= uiBlockLayout(node->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL,
@@ -386,7 +386,7 @@ static int node_get_colorid(bNode *node)
/* based on settings in node, sets drawing rect info. each redraw! */
/* note: this assumes only 1 group at a time is drawn (linked data) */
/* in node->totr the entire boundbox for the group is stored */
-static void node_update_group(const bContext *C, bNodeTree *ntree, bNode *gnode)
+static void node_update_group(const bContext *C, bNodeTree *UNUSED(ntree), bNode *gnode)
{
bNodeTree *ngroup= (bNodeTree *)gnode->id;
bNode *node;
@@ -406,7 +406,7 @@ static void node_update_group(const bContext *C, bNodeTree *ntree, bNode *gnode)
if(node->flag & NODE_HIDDEN)
node_update_hidden(node);
else
- node_update(C, ntree, node);
+ node_update(C, ngroup, node);
node->locx-= gnode->locx;
node->locy-= gnode->locy;
}
diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c
index 04edbfd5593..f476f911ab6 100644
--- a/source/blender/editors/space_sequencer/sequencer_ops.c
+++ b/source/blender/editors/space_sequencer/sequencer_ops.c
@@ -124,12 +124,7 @@ void sequencer_keymap(wmKeyConfig *keyconf)
/* operators for sequence */
keymap= WM_keymap_find(keyconf, "Sequencer", SPACE_SEQ, 0);
-
- WM_keymap_add_item(keymap, "MARKER_OT_add", MKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
- WM_keymap_add_item(keymap, "MARKER_OT_move", GKEY, KM_PRESS, KM_CTRL, 0);
- WM_keymap_add_item(keymap, "MARKER_OT_duplicate", DKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "MARKER_OT_delete", XKEY, KM_PRESS, KM_SHIFT, 0);
-
+
WM_keymap_add_item(keymap, "SEQUENCER_OT_properties", NKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "SEQUENCER_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
@@ -162,8 +157,8 @@ void sequencer_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "SEQUENCER_OT_meta_toggle", TABKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "SEQUENCER_OT_meta_make", MKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "SEQUENCER_OT_meta_separate", MKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "SEQUENCER_OT_meta_make", GKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "SEQUENCER_OT_meta_separate", GKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "SEQUENCER_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "SEQUENCER_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c
index f0202e2a105..248b65e4e9c 100644
--- a/source/blender/editors/space_userpref/space_userpref.c
+++ b/source/blender/editors/space_userpref/space_userpref.c
@@ -49,6 +49,8 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "UI_view2d.h"
+
#include "userpref_intern.h" // own include
/* ******************** default callbacks for userpref space ***************** */
@@ -110,6 +112,9 @@ static void userpref_main_area_init(wmWindowManager *wm, ARegion *ar)
static void userpref_main_area_draw(const bContext *C, ARegion *ar)
{
+ /* this solves "vibrating UI" bug #25422 */
+ UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx, ar->winy);
+
ED_region_panels(C, ar, 1, NULL, -1);
}
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 82d7cac1a42..4979c3c2a2a 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -575,6 +575,7 @@ typedef struct ViewCachedString {
short mval[2];
short xoffs;
short flag;
+ int str_len, pad;
/* str is allocated past the end */
} ViewCachedString;
@@ -596,6 +597,7 @@ void view3d_cached_text_draw_add(const float co[3], const char *str, short xoffs
vos->col.pack= *((int *)col);
vos->xoffs= xoffs;
vos->flag= flag;
+ vos->str_len= alloc_len-1;
/* allocate past the end */
memcpy(++vos, str, alloc_len);
@@ -661,10 +663,10 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa
col_pack_prev= vos->col.pack;
}
if(vos->flag & V3D_CACHE_TEXT_ASCII) {
- BLF_draw_default_ascii((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], (depth_write)? 0.0f: 2.0f, str, 65535); /* XXX, use real length */
+ BLF_draw_default_ascii((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], (depth_write)? 0.0f: 2.0f, str, vos->str_len);
}
else {
- BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], (depth_write)? 0.0f: 2.0f, str, 65535); /* XXX, use real length */
+ BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], (depth_write)? 0.0f: 2.0f, str, vos->str_len);
}
}
}
@@ -2121,7 +2123,7 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
float fvec[3];
char val[32]; /* Stores the measurement display text here */
const char *conv_float; /* Use a float conversion matching the grid size */
- unsigned char col[3]; /* color of the text to draw */
+ unsigned char col[4]= {0, 0, 0, 255}; /* color of the text to draw */
float area; /* area of the face */
float grid= unit->system ? unit->scale_length : v3d->grid;
const int do_split= unit->flag & USER_UNIT_OPT_SPLIT;
@@ -3463,7 +3465,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
Material *ma;
float vel[3], imat[4][4];
float timestep, pixsize=1.0, pa_size, r_tilt, r_length;
- float pa_time, pa_birthtime, pa_dietime, pa_health;
+ float pa_time, pa_birthtime, pa_dietime, pa_health, intensity;
float cfra;
float ma_r=0.0f, ma_g=0.0f, ma_b=0.0f;
int a, totpart, totpoint=0, totve=0, drawn, draw_as, totchild=0;
@@ -3527,7 +3529,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
if(v3d->zbuf) glDepthMask(1);
- if((ma) && (part->draw&PART_DRAW_MAT_COL)) {
+ if((ma) && (part->draw_col == PART_DRAW_COL_MAT)) {
rgb_float_to_byte(&(ma->r), tcol);
ma_r = ma->r;
@@ -3628,6 +3630,10 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
normalize_v3(imat[1]);
}
+ if(ELEM3(draw_as, PART_DRAW_DOT, PART_DRAW_CROSS, PART_DRAW_LINE)
+ && part->draw_col > PART_DRAW_COL_MAT)
+ create_cdata = 1;
+
if(!create_cdata && pdd && pdd->cdata) {
MEM_freeN(pdd->cdata);
pdd->cdata = pdd->cd = NULL;
@@ -3670,7 +3676,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
if(create_cdata && !pdd->cdata)
pdd->cdata = MEM_callocN(tot_vec_size, "particle_cdata");
if(create_ndata && !pdd->ndata)
- pdd->ndata = MEM_callocN(tot_vec_size, "particle_vdata");
+ pdd->ndata = MEM_callocN(tot_vec_size, "particle_ndata");
if(part->draw & PART_DRAW_VEL && draw_as != PART_DRAW_LINE) {
if(!pdd->vedata)
@@ -3725,65 +3731,26 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
else
pa_health = -1.0;
-#if 0 // XXX old animation system
- if((part->flag&PART_ABS_TIME)==0){
- if(ma && ma->ipo){
- IpoCurve *icu;
-
- /* correction for lifetime */
- calc_ipo(ma->ipo, 100.0f*pa_time);
-
- for(icu = ma->ipo->curve.first; icu; icu=icu->next) {
- if(icu->adrcode == MA_COL_R)
- ma_r = icu->curval;
- else if(icu->adrcode == MA_COL_G)
- ma_g = icu->curval;
- else if(icu->adrcode == MA_COL_B)
- ma_b = icu->curval;
- }
- }
- if(part->ipo) {
- IpoCurve *icu;
-
- /* correction for lifetime */
- calc_ipo(part->ipo, 100*pa_time);
+ r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f);
+ r_length = PSYS_FRAND(a + 22);
- for(icu = part->ipo->curve.first; icu; icu=icu->next) {
- if(icu->adrcode == PART_SIZE)
- pa_size = icu->curval;
- }
+ if(part->draw_col > PART_DRAW_COL_MAT) {
+ switch(part->draw_col) {
+ case PART_DRAW_COL_VEL:
+ intensity = len_v3(pa->state.vel)/part->color_vec_max;
+ break;
+ case PART_DRAW_COL_ACC:
+ intensity = len_v3v3(pa->state.vel, pa->prev_state.vel)/((pa->state.time-pa->prev_state.time)*part->color_vec_max);
+ break;
}
+ CLAMP(intensity, 0.f, 1.f);
+ weight_to_rgb(intensity, &ma_r, &ma_g, &ma_b);
}
-#endif // XXX old animation system
-
- r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f);
- r_length = PSYS_FRAND(a + 22);
}
else{
ChildParticle *cpa= &psys->child[a-totpart];
pa_time=psys_get_child_time(psys,cpa,cfra,&pa_birthtime,&pa_dietime);
-
-#if 0 // XXX old animation system
- if((part->flag&PART_ABS_TIME)==0) {
- if(ma && ma->ipo){
- IpoCurve *icu;
-
- /* correction for lifetime */
- calc_ipo(ma->ipo, 100.0f*pa_time);
-
- for(icu = ma->ipo->curve.first; icu; icu=icu->next) {
- if(icu->adrcode == MA_COL_R)
- ma_r = icu->curval;
- else if(icu->adrcode == MA_COL_G)
- ma_g = icu->curval;
- else if(icu->adrcode == MA_COL_B)
- ma_b = icu->curval;
- }
- }
- }
-#endif // XXX old animation system
-
pa_size=psys_get_child_size(psys,cpa,cfra,NULL);
pa_health = -1.0;
@@ -3909,7 +3876,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
if (1) { //ob_dt > OB_WIRE) {
glEnableClientState(GL_NORMAL_ARRAY);
- if(part->draw&PART_DRAW_MAT_COL)
+ if(part->draw_col == PART_DRAW_COL_MAT)
glEnableClientState(GL_COLOR_ARRAY);
glEnable(GL_LIGHTING);
@@ -3938,7 +3905,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
if(1) { //ob_dt > OB_WIRE) {
glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel);
- if(part->draw&PART_DRAW_MAT_COL)
+ if(part->draw_col == PART_DRAW_COL_MAT)
glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
}
@@ -3954,7 +3921,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
if(1) { //ob_dt > OB_WIRE) {
glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel);
- if(part->draw&PART_DRAW_MAT_COL)
+ if(part->draw_col == PART_DRAW_COL_MAT)
glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col);
}
@@ -3964,7 +3931,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
/* restore & clean up */
if(1) { //ob_dt > OB_WIRE) {
- if(part->draw&PART_DRAW_MAT_COL)
+ if(part->draw_col == PART_DRAW_COL_MAT)
glDisable(GL_COLOR_ARRAY);
glDisable(GL_COLOR_MATERIAL);
}
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 5e4a0d30909..86b15a922a8 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -530,7 +530,6 @@ static void *view3d_main_area_duplicate(void *poin)
new->clipbb= MEM_dupallocN(rv3d->clipbb);
new->depths= NULL;
- new->retopo_view_data= NULL;
new->ri= NULL;
new->gpd= NULL;
new->sms= NULL;
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 3ca6d39305c..6e286578dad 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -2150,7 +2150,7 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx,
}
/* utility func for ED_view3d_draw_offscreen */
-ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, int sizex, int sizey, unsigned int flag)
+ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, int sizex, int sizey, unsigned int flag, char err_out[256])
{
RegionView3D *rv3d= ar->regiondata;
ImBuf *ibuf;
@@ -2160,7 +2160,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in
glPushAttrib(GL_LIGHTING_BIT);
/* bind */
- ofs= GPU_offscreen_create(&sizex, &sizey);
+ ofs= GPU_offscreen_create(&sizex, &sizey, err_out);
if(ofs == NULL)
return NULL;
@@ -2204,7 +2204,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in
}
/* creates own 3d views, used by the sequencer */
-ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, int width, int height, unsigned int flag, int drawtype)
+ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, int width, int height, unsigned int flag, int drawtype, char err_out[256])
{
View3D v3d= {NULL};
ARegion ar= {NULL};
@@ -2235,7 +2235,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, int width, int height
mul_m4_m4m4(rv3d.persmat, rv3d.viewmat, rv3d.winmat);
invert_m4_m4(rv3d.persinv, rv3d.viewinv);
- return ED_view3d_draw_offscreen_imbuf(scene, &v3d, &ar, width, height, flag);
+ return ED_view3d_draw_offscreen_imbuf(scene, &v3d, &ar, width, height, flag, err_out);
// seq_view3d_cb(scene, cfra, render_size, seqrectx, seqrecty);
}
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index eb66608ecd3..30ca1638d34 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -189,26 +189,6 @@ void view3d_keymap(wmKeyConfig *keyconf)
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", WHEELDOWNMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0)->ptr, "type", V3D_VIEW_STEPDOWN);
/* active aligned, replaces '*' key in 2.4x */
-#ifdef WIN32
- kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD1, KM_PRESS, KM_ALT, 0);
- RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_FRONT);
- RNA_boolean_set(kmi->ptr, "align_active", TRUE);
- kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD3, KM_PRESS, KM_ALT, 0);
- RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_RIGHT);
- RNA_boolean_set(kmi->ptr, "align_active", TRUE);
- kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD7, KM_PRESS, KM_ALT, 0);
- RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_TOP);
- RNA_boolean_set(kmi->ptr, "align_active", TRUE);
- kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD1, KM_PRESS, KM_ALT|KM_CTRL, 0);
- RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_BACK);
- RNA_boolean_set(kmi->ptr, "align_active", TRUE);
- kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD3, KM_PRESS, KM_ALT|KM_CTRL, 0);
- RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_LEFT);
- RNA_boolean_set(kmi->ptr, "align_active", TRUE);
- kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD7, KM_PRESS, KM_ALT|KM_CTRL, 0);
- RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_BOTTOM);
- RNA_boolean_set(kmi->ptr, "align_active", TRUE);
-#else
kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD1, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_FRONT);
RNA_boolean_set(kmi->ptr, "align_active", TRUE);
@@ -227,7 +207,6 @@ void view3d_keymap(wmKeyConfig *keyconf)
kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD7, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_BOTTOM);
RNA_boolean_set(kmi->ptr, "align_active", TRUE);
-#endif
WM_keymap_add_item(keymap, "VIEW3D_OT_localview", PADSLASHKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 72061bdbdac..9d882f09d02 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -198,26 +198,6 @@ static void EM_backbuf_checkAndSelectTFaces(Mesh *me, int select)
}
}
-#if 0
-void arrows_move_cursor(unsigned short event)
-{
- short mval[2];
-
- getmouseco_sc(mval);
-
- if(event==UPARROWKEY) {
- warp_pointer(mval[0], mval[1]+1);
- } else if(event==DOWNARROWKEY) {
- warp_pointer(mval[0], mval[1]-1);
- } else if(event==LEFTARROWKEY) {
- warp_pointer(mval[0]-1, mval[1]);
- } else if(event==RIGHTARROWKEY) {
- warp_pointer(mval[0]+1, mval[1]);
- }
-}
-#endif
-
-
/* *********************** GESTURE AND LASSO ******************* */
static int view3d_selectable_data(bContext *C)
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 4b290f277b6..a1726d8a537 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -1179,33 +1179,37 @@ static void obmat_to_viewmat(View3D *v3d, RegionView3D *rv3d, Object *ob, short
#define QUATSET(a, b, c, d, e) a[0]=b; a[1]=c; a[2]=d; a[3]=e;
-static void view3d_viewlock(RegionView3D *rv3d)
+int ED_view3d_lock(RegionView3D *rv3d)
{
switch(rv3d->view) {
case RV3D_VIEW_BOTTOM :
QUATSET(rv3d->viewquat,0.0, -1.0, 0.0, 0.0);
break;
-
+
case RV3D_VIEW_BACK:
QUATSET(rv3d->viewquat,0.0, 0.0, (float)-cos(M_PI/4.0), (float)-cos(M_PI/4.0));
break;
-
+
case RV3D_VIEW_LEFT:
QUATSET(rv3d->viewquat,0.5, -0.5, 0.5, 0.5);
break;
-
+
case RV3D_VIEW_TOP:
QUATSET(rv3d->viewquat,1.0, 0.0, 0.0, 0.0);
break;
-
+
case RV3D_VIEW_FRONT:
QUATSET(rv3d->viewquat,(float)cos(M_PI/4.0), (float)-sin(M_PI/4.0), 0.0, 0.0);
break;
-
+
case RV3D_VIEW_RIGHT:
QUATSET(rv3d->viewquat, 0.5, -0.5, -0.5, -0.5);
break;
+ default:
+ return FALSE;
}
+
+ return TRUE;
}
/* dont set windows active in in here, is used by renderwin too */
@@ -1224,7 +1228,7 @@ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d)
else {
/* should be moved to better initialize later on XXX */
if(rv3d->viewlock)
- view3d_viewlock(rv3d);
+ ED_view3d_lock(rv3d);
quat_to_mat4( rv3d->viewmat,rv3d->viewquat);
if(rv3d->persp==RV3D_PERSP) rv3d->viewmat[3][2]-= rv3d->dist;
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index b2dd512e461..d523b25e0e5 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -54,22 +54,10 @@
#include "RNA_access.h"
-//#include "BIF_editview.h" /* arrows_move_cursor */
#include "BIF_gl.h"
#include "BIF_glutil.h"
-//#include "BIF_mywindow.h"
-//#include "BIF_resources.h"
-//#include "BIF_screen.h"
-//#include "BIF_space.h" /* undo */
-//#include "BIF_toets.h" /* persptoetsen */
-//#include "BIF_mywindow.h" /* warp_pointer */
-//#include "BIF_toolbox.h" /* notice */
-//#include "BIF_editmesh.h"
-//#include "BIF_editsima.h"
-//#include "BIF_editparticle.h"
#include "BKE_nla.h"
-//#include "BKE_bad_level_calls.h"/* popmenu and error */
#include "BKE_bmesh.h"
#include "BKE_context.h"
#include "BKE_constraint.h"
@@ -78,8 +66,6 @@
#include "BKE_pointcache.h"
#include "BKE_unit.h"
-//#include "BSE_view.h"
-
#include "ED_image.h"
#include "ED_keyframing.h"
#include "ED_screen.h"
@@ -551,9 +537,6 @@ wmKeyMap* transform_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_add_item(keymap, AKEY, KM_PRESS, 0, 0, TFM_MODAL_ADD_SNAP);
WM_modalkeymap_add_item(keymap, AKEY, KM_PRESS, KM_ALT, 0, TFM_MODAL_REMOVE_SNAP);
- WM_modalkeymap_add_item(keymap, UPARROWKEY, KM_PRESS, 0, 0, NUM_MODAL_INCREMENT_UP);
- WM_modalkeymap_add_item(keymap, DOWNARROWKEY, KM_PRESS, 0, 0, NUM_MODAL_INCREMENT_DOWN);
-
WM_modalkeymap_add_item(keymap, PAGEUPKEY, KM_PRESS, 0, 0, TFM_MODAL_PROPSIZE_UP);
WM_modalkeymap_add_item(keymap, PAGEDOWNKEY, KM_PRESS, 0, 0, TFM_MODAL_PROPSIZE_DOWN);
WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, 0, 0, TFM_MODAL_PROPSIZE_UP);
@@ -1067,7 +1050,6 @@ int transformEvent(TransInfo *t, wmEvent *event)
// Snapping events
t->redraw |= handleSnapping(t, event);
- //arrows_move_cursor(event->type);
}
else if (event->val==KM_RELEASE) {
switch (event->type){
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 9a70ec2f3be..2c08524ae63 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -2056,27 +2056,25 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
if(propmode) editmesh_set_connectivity_distance(em, mtx);
/* detect CrazySpace [tm] */
- if(propmode==0) {
- if(modifiers_getCageIndex(t->scene, t->obedit, NULL, 1)>=0) {
- if(modifiers_isCorrectableDeformed(t->obedit)) {
- /* check if we can use deform matrices for modifier from the
- start up to stack, they are more accurate than quats */
- totleft= editmesh_get_first_deform_matrices(t->scene, t->obedit, em, &defmats, &defcos);
-
- /* if we still have more modifiers, also do crazyspace
- correction with quats, relative to the coordinates after
- the modifiers that support deform matrices (defcos) */
- if(totleft > 0) {
- mappedcos= crazyspace_get_mapped_editverts(t->scene, t->obedit);
- quats= MEM_mallocN( (t->total)*sizeof(float)*4, "crazy quats");
- crazyspace_set_quats_editmesh(em, (float*)defcos, mappedcos, quats);
- if(mappedcos)
- MEM_freeN(mappedcos);
- }
-
- if(defcos)
- MEM_freeN(defcos);
+ if(modifiers_getCageIndex(t->scene, t->obedit, NULL, 1)>=0) {
+ if(modifiers_isCorrectableDeformed(t->obedit)) {
+ /* check if we can use deform matrices for modifier from the
+ start up to stack, they are more accurate than quats */
+ totleft= editmesh_get_first_deform_matrices(t->scene, t->obedit, em, &defmats, &defcos);
+
+ /* if we still have more modifiers, also do crazyspace
+ correction with quats, relative to the coordinates after
+ the modifiers that support deform matrices (defcos) */
+ if(totleft > 0) {
+ mappedcos= crazyspace_get_mapped_editverts(t->scene, t->obedit);
+ quats= MEM_mallocN( (t->total)*sizeof(float)*4, "crazy quats");
+ crazyspace_set_quats_editmesh(em, (float*)defcos, mappedcos, quats);
+ if(mappedcos)
+ MEM_freeN(mappedcos);
}
+
+ if(defcos)
+ MEM_freeN(defcos);
}
}
@@ -4860,9 +4858,9 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
((cancelled == 0) || (duplicate)) )
{
if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 1);
+ ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0);
posttrans_fcurve_clean(fcu);
- ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 1);
+ ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 0);
}
else
posttrans_fcurve_clean(fcu);
diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c
index b366a8460fc..2659863e592 100644
--- a/source/blender/editors/util/undo.c
+++ b/source/blender/editors/util/undo.c
@@ -80,6 +80,9 @@ void ED_undo_push(bContext *C, const char *str)
Object *obedit= CTX_data_edit_object(C);
Object *obact= CTX_data_active_object(C);
+ if (G.f & G_DEBUG)
+ printf("undo push %s\n", str);
+
if(obedit) {
if (U.undosteps == 0) return;
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index e0dbe8407d3..368d43a674e 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -812,41 +812,57 @@ static void uv_map_clip_correct(EditMesh *em, wmOperator *op)
/* ******************** Unwrap operator **************** */
+/* assumes UV layer is checked, doesn't run update funcs */
+void ED_unwrap_lscm(Scene *scene, Object *obedit, const short sel)
+{
+ EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
+
+ const short fill_holes= scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES;
+ const short correct_aspect= !(scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT);
+
+ ParamHandle *handle= construct_param_handle(scene, em, 0, fill_holes, sel, correct_aspect);
+
+ param_lscm_begin(handle, PARAM_FALSE, scene->toolsettings->unwrapper == 0);
+ param_lscm_solve(handle);
+ param_lscm_end(handle);
+
+ param_pack(handle, scene->toolsettings->uvcalc_margin);
+
+ param_flush(handle);
+
+ param_delete(handle);
+
+ BKE_mesh_end_editmesh(obedit->data, em);
+}
+
static int unwrap_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
- ParamHandle *handle;
int method = RNA_enum_get(op->ptr, "method");
int fill_holes = RNA_boolean_get(op->ptr, "fill_holes");
int correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect");
/* add uvs if they don't exist yet */
if(!ED_uvedit_ensure_uvs(C, scene, obedit)) {
- BKE_mesh_end_editmesh(obedit->data, em);
return OPERATOR_CANCELLED;
}
/* remember last method for live unwrap */
scene->toolsettings->unwrapper = method;
- handle= construct_param_handle(scene, em, 0, fill_holes, 1, correct_aspect);
-
- param_lscm_begin(handle, PARAM_FALSE, method == 0);
- param_lscm_solve(handle);
- param_lscm_end(handle);
-
- param_pack(handle, scene->toolsettings->uvcalc_margin);
+ if(fill_holes) scene->toolsettings->uvcalc_flag |= UVCALC_FILLHOLES;
+ else scene->toolsettings->uvcalc_flag &= ~UVCALC_FILLHOLES;
- param_flush(handle);
+ if(correct_aspect) scene->toolsettings->uvcalc_flag &= ~UVCALC_NO_ASPECT_CORRECT;
+ else scene->toolsettings->uvcalc_flag |= UVCALC_NO_ASPECT_CORRECT;
- param_delete(handle);
+ /* execute unwrap */
+ ED_unwrap_lscm(scene, obedit, TRUE);
DAG_id_tag_update(obedit->data, 0);
WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
- BKE_mesh_end_editmesh(obedit->data, em);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index 90c99257087..8bf923a5679 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -108,10 +108,10 @@ int GPU_type_matches(GPUDeviceType device, GPUOSType os, GPUDriverType driver);
- if created with from_blender, will not free the texture
*/
-GPUTexture *GPU_texture_create_1D(int w, float *pixels);
-GPUTexture *GPU_texture_create_2D(int w, int h, float *pixels);
+GPUTexture *GPU_texture_create_1D(int w, float *pixels, char err_out[256]);
+GPUTexture *GPU_texture_create_2D(int w, int h, float *pixels, char err_out[256]);
GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels);
-GPUTexture *GPU_texture_create_depth(int w, int h);
+GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256]);
GPUTexture *GPU_texture_from_blender(struct Image *ima,
struct ImageUser *iuser, double time, int mipmap);
void GPU_texture_free(GPUTexture *tex);
@@ -135,7 +135,7 @@ int GPU_texture_opengl_height(GPUTexture *tex);
be called before rendering to the window framebuffer again */
GPUFrameBuffer *GPU_framebuffer_create(void);
-int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex);
+int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, char err_out[256]);
void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex);
void GPU_framebuffer_texture_bind(GPUFrameBuffer *fb, GPUTexture *tex);
void GPU_framebuffer_texture_unbind(GPUFrameBuffer *fb, GPUTexture *tex);
@@ -147,7 +147,7 @@ void GPU_framebuffer_restore(void);
- wrapper around framebuffer and texture for simple offscreen drawing
- changes size if graphics card can't support it */
-GPUOffScreen *GPU_offscreen_create(int *width, int *height);
+GPUOffScreen *GPU_offscreen_create(int *width, int *height, char err_out[256]);
void GPU_offscreen_free(GPUOffScreen *ofs);
void GPU_offscreen_bind(GPUOffScreen *ofs);
void GPU_offscreen_unbind(GPUOffScreen *ofs);
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index fad65a95a49..470b99de00b 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -983,11 +983,11 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type)
input->textype = type;
if (type == GPU_TEX1D) {
- input->tex = GPU_texture_create_1D(link->texturesize, link->ptr1);
+ input->tex = GPU_texture_create_1D(link->texturesize, link->ptr1, NULL);
input->textarget = GL_TEXTURE_1D;
}
else {
- input->tex = GPU_texture_create_2D(link->texturesize, link->texturesize, link->ptr2);
+ input->tex = GPU_texture_create_2D(link->texturesize, link->texturesize, link->ptr2, NULL);
input->textarget = GL_TEXTURE_2D;
}
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index 78ac17d450d..453eb995113 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -54,6 +54,8 @@
#include <stdio.h>
#include <string.h>
+#include "BLI_winstuff.h"
+
/* Extensions support */
/* extensions used:
@@ -225,39 +227,44 @@ int GPU_print_error(const char *str)
return 0;
}
-static void GPU_print_framebuffer_error(GLenum status)
+static void GPU_print_framebuffer_error(GLenum status, char err_out[256])
{
- fprintf(stderr, "GPUFrameBuffer: framebuffer incomplete error %d\n",
- (int)status);
+ const char *err= "unknown";
switch(status) {
case GL_FRAMEBUFFER_COMPLETE_EXT:
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
- fprintf(stderr, "Incomplete attachment.\n");
+ err= "Incomplete attachment";
break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
- fprintf(stderr, "Unsupported framebuffer format.\n");
+ err= "Unsupported framebuffer format";
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
- fprintf(stderr, "Missing attachment.\n");
+ err= "Missing attachment";
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
- fprintf(stderr, "Attached images must have same dimensions.\n");
+ err= "Attached images must have same dimensions";
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
- fprintf(stderr, "Attached images must have same format.\n");
+ err= "Attached images must have same format";
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
- fprintf(stderr, "Missing draw buffer.\n");
+ err= "Missing draw buffer";
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
- fprintf(stderr, "Missing read buffer.\n");
- break;
- default:
- fprintf(stderr, "Unknown.\n");
+ err= "Missing read buffer";
break;
}
+
+ if(err_out) {
+ BLI_snprintf(err_out, 256, "GPUFrameBuffer: framebuffer incomplete error %d '%s'",
+ (int)status, err);
+ }
+ else {
+ fprintf(stderr, "GPUFrameBuffer: framebuffer incomplete error %d '%s'\n",
+ (int)status, err);
+ }
}
/* GPUTexture */
@@ -318,7 +325,7 @@ static void GPU_glTexSubImageEmpty(GLenum target, GLenum format, int x, int y, i
MEM_freeN(pixels);
}
-static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, int depth)
+static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, int depth, char err_out[256])
{
GPUTexture *tex;
GLenum type, format, internalformat;
@@ -338,8 +345,14 @@ static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, in
glGenTextures(1, &tex->bindcode);
if (!tex->bindcode) {
- fprintf(stderr, "GPUTexture: texture create failed: %d\n",
- (int)glGetError());
+ if(err_out) {
+ BLI_snprintf(err_out, 256, "GPUTexture: texture create failed: %d",
+ (int)glGetError());
+ }
+ else {
+ fprintf(stderr, "GPUTexture: texture create failed: %d\n",
+ (int)glGetError());
+ }
GPU_texture_free(tex);
return NULL;
}
@@ -555,9 +568,9 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, double time,
return tex;
}
-GPUTexture *GPU_texture_create_1D(int w, float *fpixels)
+GPUTexture *GPU_texture_create_1D(int w, float *fpixels, char err_out[256])
{
- GPUTexture *tex = GPU_texture_create_nD(w, 1, 1, fpixels, 0);
+ GPUTexture *tex = GPU_texture_create_nD(w, 1, 1, fpixels, 0, err_out);
if (tex)
GPU_texture_unbind(tex);
@@ -565,9 +578,9 @@ GPUTexture *GPU_texture_create_1D(int w, float *fpixels)
return tex;
}
-GPUTexture *GPU_texture_create_2D(int w, int h, float *fpixels)
+GPUTexture *GPU_texture_create_2D(int w, int h, float *fpixels, char err_out[256])
{
- GPUTexture *tex = GPU_texture_create_nD(w, h, 2, fpixels, 0);
+ GPUTexture *tex = GPU_texture_create_nD(w, h, 2, fpixels, 0, err_out);
if (tex)
GPU_texture_unbind(tex);
@@ -575,9 +588,9 @@ GPUTexture *GPU_texture_create_2D(int w, int h, float *fpixels)
return tex;
}
-GPUTexture *GPU_texture_create_depth(int w, int h)
+GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256])
{
- GPUTexture *tex = GPU_texture_create_nD(w, h, 2, NULL, 1);
+ GPUTexture *tex = GPU_texture_create_nD(w, h, 2, NULL, 1, err_out);
if (tex)
GPU_texture_unbind(tex);
@@ -705,7 +718,7 @@ GPUFrameBuffer *GPU_framebuffer_create(void)
return fb;
}
-int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex)
+int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, char err_out[256])
{
GLenum status;
GLenum attachment;
@@ -734,7 +747,7 @@ int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex)
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
GPU_framebuffer_restore();
- GPU_print_framebuffer_error(status);
+ GPU_print_framebuffer_error(status, err_out);
return 0;
}
@@ -846,7 +859,7 @@ struct GPUOffScreen {
GPUTexture *depth;
};
-GPUOffScreen *GPU_offscreen_create(int *width, int *height)
+GPUOffScreen *GPU_offscreen_create(int *width, int *height, char err_out[256])
{
GPUOffScreen *ofs;
@@ -858,7 +871,7 @@ GPUOffScreen *GPU_offscreen_create(int *width, int *height)
return NULL;
}
- ofs->depth = GPU_texture_create_depth(*width, *height);
+ ofs->depth = GPU_texture_create_depth(*width, *height, err_out);
if(!ofs->depth) {
GPU_offscreen_free(ofs);
return NULL;
@@ -870,18 +883,18 @@ GPUOffScreen *GPU_offscreen_create(int *width, int *height)
printf("Offscreen size differs from given size!\n");
}
- if(!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth)) {
+ if(!GPU_framebuffer_texture_attach(ofs->fb, ofs->depth, err_out)) {
GPU_offscreen_free(ofs);
return NULL;
}
- ofs->color = GPU_texture_create_2D(*width, *height, NULL);
+ ofs->color = GPU_texture_create_2D(*width, *height, NULL, err_out);
if(!ofs->color) {
GPU_offscreen_free(ofs);
return NULL;
}
- if(!GPU_framebuffer_texture_attach(ofs->fb, ofs->color)) {
+ if(!GPU_framebuffer_texture_attach(ofs->fb, ofs->color, err_out)) {
GPU_offscreen_free(ofs);
return NULL;
}
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index f644700fb81..8e71f259557 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -1553,13 +1553,13 @@ GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
return lamp;
}
- lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size);
+ lamp->tex = GPU_texture_create_depth(lamp->size, lamp->size, NULL);
if(!lamp->tex) {
gpu_lamp_shadow_free(lamp);
return lamp;
}
- if(!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex)) {
+ if(!GPU_framebuffer_texture_attach(lamp->fb, lamp->tex, NULL)) {
gpu_lamp_shadow_free(lamp);
return lamp;
}
diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h
index 9d97b6af8f3..b8540fabd5b 100644
--- a/source/blender/makesdna/DNA_material_types.h
+++ b/source/blender/makesdna/DNA_material_types.h
@@ -160,7 +160,9 @@ typedef struct Material {
short sss_flag, sss_preset;
int mapto_textured; /* render-time cache to optimise texture lookups */
- short vcol_alpha, pad4;
+ short shadowonly_flag; /* "shadowsonly" type */
+
+ short vcol_alpha;
ListBase gpumaterial; /* runtime */
} Material;
@@ -238,6 +240,11 @@ typedef struct Material {
#define MA_RAYMIR_FADETOSKY 0
#define MA_RAYMIR_FADETOMAT 1
+/* shadowonly_flag */
+#define MA_SO_OLD 0
+#define MA_SO_SHADOW 1
+#define MA_SO_SHADED 2
+
/* shade_flag */
#define MA_CUBIC 1
#define MA_OBCOLOR 2
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index ae97b023e58..09053848b28 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -123,16 +123,23 @@ typedef struct ParticleData {
typedef struct SPHFluidSettings {
/*Particle Fluid*/
- float spring_k, radius, rest_length, plasticity_constant, yield_ratio;
+ float radius, spring_k, rest_length;
+ float plasticity_constant, yield_ratio;
+ float plasticity_balance, yield_balance;
float viscosity_omega, viscosity_beta;
float stiffness_k, stiffness_knear, rest_density;
float buoyancy;
- int flag, pad;
+ int flag, spring_frames;
} SPHFluidSettings;
/* fluid->flag */
#define SPH_VISCOELASTIC_SPRINGS 1
#define SPH_CURRENT_REST_LENGTH 2
+#define SPH_FAC_REPULSION 4
+#define SPH_FAC_DENSITY 8
+#define SPH_FAC_RADIUS 16
+#define SPH_FAC_VISCOSITY 32
+#define SPH_FAC_REST_LENGTH 64
typedef struct ParticleSettings {
ID id;
@@ -143,12 +150,12 @@ typedef struct ParticleSettings {
struct EffectorWeights *effector_weights;
- int flag;
+ int flag, rt;
short type, from, distr, texact;
/* physics modes */
short phystype, rotmode, avemode, reactevent;
short draw, draw_as, draw_size, childtype;
- short ren_as, subframes;
+ short ren_as, subframes, draw_col;
/* number of path segments, power of 2 except */
short draw_step, ren_step;
short hair_step, keys_step;
@@ -157,12 +164,15 @@ typedef struct ParticleSettings {
short adapt_angle, adapt_pix;
short disp, omat, interpolation, rotfrom, integrator;
- short kink, kink_axis, rt2;
+ short kink, kink_axis;
/* billboards */
short bb_align, bb_uv_split, bb_anim, bb_split_offset;
float bb_tilt, bb_rand_tilt, bb_offset[2];
+ /* draw color */
+ float color_vec_max;
+
/* simplification */
short simplify_flag, simplify_refsize;
float simplify_rate, simplify_transition;
@@ -249,9 +259,9 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
char name[32]; /* particle system name */
float imat[4][4]; /* used for duplicators */
- float cfra, tree_frame;
+ float cfra, tree_frame, bvhtree_frame;
int seed, child_seed;
- int flag, totpart, totunexist, totchild, totcached, totchildcache, rt;
+ int flag, totpart, totunexist, totchild, totcached, totchildcache;
short recalc, target_psys, totkeyed, bakespace;
char bb_uvname[3][32]; /* billboard uv name */
@@ -271,7 +281,8 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
ParticleSpring *fluid_springs;
int tot_fluidsprings, alloc_fluidsprings;
- struct KDTree *tree; /* used for interactions with self and other systems */
+ struct KDTree *tree; /* used for interactions with self and other systems */
+ struct BVHTree *bvhtree; /* used for interactions with self and other systems */
struct ParticleDrawData *pdd;
@@ -339,7 +350,7 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
#define PART_FROM_VERT 0
#define PART_FROM_FACE 1
#define PART_FROM_VOLUME 2
-#define PART_FROM_PARTICLE 3
+/* #define PART_FROM_PARTICLE 3 deprecated! */
#define PART_FROM_CHILD 4
/* part->distr */
@@ -375,10 +386,17 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
#define PART_DRAW_RAND_GR 1024
#define PART_DRAW_REN_ADAPT 2048
#define PART_DRAW_VEL_LENGTH (1<<12)
-#define PART_DRAW_MAT_COL (1<<13)
+#define PART_DRAW_MAT_COL (1<<13) /* deprecated, but used in do_versions */
#define PART_DRAW_WHOLE_GR (1<<14)
#define PART_DRAW_REN_STRAND (1<<15)
+/* part->draw_col */
+#define PART_DRAW_COL_NONE 0
+#define PART_DRAW_COL_MAT 1
+#define PART_DRAW_COL_VEL 2
+#define PART_DRAW_COL_ACC 3
+
+
/* part->simplify_flag */
#define PART_SIMPLIFY_ENABLE 1
#define PART_SIMPLIFY_VIEWPORT 2
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index b95a6596b4f..4eb18612c81 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -731,9 +731,11 @@ typedef struct ToolSettings {
/* Alt+RMB option */
char edge_mode;
+ char edge_mode_live_unwrap;
/* Transform */
- short snap_mode, snap_flag, snap_target;
+ char snap_mode;
+ short snap_flag, snap_target;
short proportional, prop_mode;
char proportional_objects; /* proportional edit, object mode */
char pad[3];
@@ -1182,7 +1184,7 @@ typedef enum SculptFlags {
/* toolsettings->uvcalc_flag */
#define UVCALC_FILLHOLES 1
-/*#define UVCALC_NO_ASPECT_CORRECT 2*/ /* would call this UVCALC_ASPECT_CORRECT, except it should be default with old file */
+#define UVCALC_NO_ASPECT_CORRECT 2 /* would call this UVCALC_ASPECT_CORRECT, except it should be default with old file */
#define UVCALC_TRANSFORM_CORRECT 4 /* adjust UV's while transforming to avoid distortion */
/* toolsettings->uv_flag */
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 3ffef475e1b..c9a440522d1 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -41,7 +41,6 @@ struct SpaceLink;
struct Base;
struct BoundBox;
struct RenderInfo;
-struct RetopoViewData;
struct bGPdata;
struct SmoothViewStore;
struct wmTimer;
@@ -113,9 +112,8 @@ typedef struct RegionView3D {
struct bGPdata *gpd; /* Grease-Pencil Data (annotation layers) */
- struct RegionView3D *localvd;
+ struct RegionView3D *localvd; /* allocated backup of its self while in localview */
struct RenderInfo *ri;
- struct RetopoViewData *retopo_view_data;
struct ViewDepths *depths;
/* animated smooth view */
@@ -153,7 +151,7 @@ typedef struct View3D {
struct ListBase bgpicbase;
struct BGpic *bgpic; /* deprecated, use bgpicbase, only kept for do_versions(...) */
- struct View3D *localvd;
+ struct View3D *localvd; /* allocated backup of its self while in localview */
char ob_centre_bone[32]; /* optional string for armature bone to define center */
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index 099e66e9034..b14b6a396db 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -1209,7 +1209,7 @@ static void rna_def_fpoint(BlenderRNA *brna)
RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME|NA_SELECTED, NULL);
/* Vector value */
- prop= RNA_def_property(srna, "co", PROP_FLOAT, PROP_XYZ);
+ prop= RNA_def_property(srna, "co", PROP_FLOAT, PROP_NONE); /* keyframes are dimensionless */
RNA_def_property_float_sdna(prop, NULL, "vec");
RNA_def_property_array(prop, 2);
RNA_def_property_ui_text(prop, "Point", "Point coordinates");
@@ -1271,19 +1271,19 @@ static void rna_def_fkeyframe(BlenderRNA *brna)
RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
/* Vector values */
- prop= RNA_def_property(srna, "handle_left", PROP_FLOAT, PROP_TRANSLATION);
+ prop= RNA_def_property(srna, "handle_left", PROP_FLOAT, PROP_NONE); /* keyframes are dimensionless */
RNA_def_property_array(prop, 2);
RNA_def_property_float_funcs(prop, "rna_FKeyframe_handle1_get", "rna_FKeyframe_handle1_set", NULL);
RNA_def_property_ui_text(prop, "Handle 1", "Coordinates of the first handle");
RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
- prop= RNA_def_property(srna, "co", PROP_FLOAT, PROP_TRANSLATION);
+ prop= RNA_def_property(srna, "co", PROP_FLOAT, PROP_NONE); /* keyframes are dimensionless */
RNA_def_property_array(prop, 2);
RNA_def_property_float_funcs(prop, "rna_FKeyframe_ctrlpoint_get", "rna_FKeyframe_ctrlpoint_set", NULL);
RNA_def_property_ui_text(prop, "Control Point", "Coordinates of the control point");
RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
- prop= RNA_def_property(srna, "handle_right", PROP_FLOAT, PROP_TRANSLATION);
+ prop= RNA_def_property(srna, "handle_right", PROP_FLOAT, PROP_NONE); /* keyframes are dimensionless */
RNA_def_property_array(prop, 2);
RNA_def_property_float_funcs(prop, "rna_FKeyframe_handle2_get", "rna_FKeyframe_handle2_set", NULL);
RNA_def_property_ui_text(prop, "Handle 2", "Coordinates of the second handle");
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 6fa0e2bae82..64b7e589ecb 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -234,7 +234,7 @@ static int rna_Image_depth_get(PointerRNA *ptr)
if(!ibuf)
depth= 0;
else if(ibuf->rect_float)
- depth= 128;
+ depth= ibuf->depth * 4;
else
depth= ibuf->depth;
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index ce568c2af63..e593f305094 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -1569,6 +1569,7 @@ void RNA_def_material(BlenderRNA *brna)
{MA_TYPE_HALO, "HALO", 0, "Halo", "Render object as halo particles"},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem transparency_items[] = {
+ {0, "MASK", 0, "Mask", "Mask the background"},
{MA_ZTRANSP, "Z_TRANSPARENCY", 0, "Z Transparency", "Use alpha buffer for transparent faces"},
{MA_RAYTRANSP, "RAYTRACE", 0, "Raytrace", "Use raytracing for transparent refraction rendering"},
{0, NULL, 0, NULL, NULL}};
@@ -1583,6 +1584,12 @@ void RNA_def_material(BlenderRNA *brna)
{MA_SPHERE_A, "SPHERE_A", ICON_MAT_SPHERE_SKY, "Flat", "Preview type: Large sphere with sky"},
{0, NULL, 0, NULL, NULL}};
+ static EnumPropertyItem prop_shadows_only_items[] = {
+ {MA_SO_OLD, "SHADOW_ONLY_OLD", 0, "Shadow and Distance", ""},
+ {MA_SO_SHADOW, "SHADOW_ONLY", 0, "Shadow Only", ""},
+ {MA_SO_SHADED, "SHADOW_ONLY_SHADED", 0, "Shadow and Shading", ""},
+ {0, NULL, 0, NULL, NULL}};
+
srna= RNA_def_struct(brna, "Material", "ID");
RNA_def_struct_ui_text(srna, "Material", "Material datablock to defined the appearance of geometric objects for rendering");
RNA_def_struct_ui_icon(srna, ICON_MATERIAL_DATA);
@@ -1713,6 +1720,12 @@ void RNA_def_material(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_ONLYSHADOW);
RNA_def_property_ui_text(prop, "Only Shadow", "Renders shadows as the material's alpha value, making materials transparent except for shadowed areas");
RNA_def_property_update(prop, 0, "rna_Material_update");
+
+ prop= RNA_def_property(srna, "shadow_only_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "shadowonly_flag");
+ RNA_def_property_enum_items(prop, prop_shadows_only_items);
+ RNA_def_property_ui_text(prop, "Shadow Type", "How to draw shadows");
+ RNA_def_property_update(prop, 0, "rna_Material_update");
prop= RNA_def_property(srna, "use_face_texture", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_FACETEXTURE);
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index f1142e16e8e..069f674bf4a 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -60,7 +60,19 @@ EnumPropertyItem part_reactor_from_items[] = {
{PART_FROM_VERT, "VERT", 0, "Verts", ""},
{PART_FROM_FACE, "FACE", 0, "Faces", ""},
{PART_FROM_VOLUME, "VOLUME", 0, "Volume", ""},
- {PART_FROM_PARTICLE, "PARTICLE", 0, "Particle", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+EnumPropertyItem part_dist_items[] = {
+ {PART_DISTR_JIT, "JIT", 0, "Jittered", ""},
+ {PART_DISTR_RAND, "RAND", 0, "Random", ""},
+ {PART_DISTR_GRID, "GRID", 0, "Grid", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+EnumPropertyItem part_hair_dist_items[] = {
+ {PART_DISTR_JIT, "JIT", 0, "Jittered", ""},
+ {PART_DISTR_RAND, "RAND", 0, "Random", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -665,6 +677,16 @@ static EnumPropertyItem *rna_Particle_from_itemf(bContext *C, PointerRNA *ptr, i
return part_from_items;
}
+static EnumPropertyItem *rna_Particle_dist_itemf(bContext *C, PointerRNA *ptr, int *free)
+{
+ ParticleSettings *part = ptr->id.data;
+
+ if(part->type==PART_HAIR)
+ return part_hair_dist_items;
+ else
+ return part_dist_items;
+}
+
static EnumPropertyItem *rna_Particle_draw_as_itemf(bContext *C, PointerRNA *ptr, int *free)
{
ParticleSettings *part = ptr->id.data;
@@ -1051,10 +1073,9 @@ static void rna_def_fluid_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Interaction Radius", "Fluid interaction radius");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
- /* Hidden in ui to give a little easier user experience. */
prop= RNA_def_property(srna, "rest_length", PROP_FLOAT, PROP_NONE);
- RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_ui_text(prop, "Rest Length", "Spring rest length (factor of interaction radius)");
+ RNA_def_property_range(prop, 0.0f, 2.0f);
+ RNA_def_property_ui_text(prop, "Rest Length", "Spring rest length (factor of particle radius)");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
prop= RNA_def_property(srna, "use_viscoelastic_springs", PROP_BOOLEAN, PROP_NONE);
@@ -1064,12 +1085,12 @@ static void rna_def_fluid_settings(BlenderRNA *brna)
prop= RNA_def_property(srna, "use_initial_rest_length", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SPH_CURRENT_REST_LENGTH);
- RNA_def_property_ui_text(prop, "Initial Rest Length", "Use the initial length as spring rest length instead of interaction radius/2");
+ RNA_def_property_ui_text(prop, "Initial Rest Length", "Use the initial length as spring rest length instead of 2 * particle size");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
prop= RNA_def_property(srna, "plasticity", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "plasticity_constant");
- RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_range(prop, 0.0f, 100.0f);
RNA_def_property_ui_text(prop, "Plasticity", "How much the spring rest length can change after the elastic limit is crossed");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
@@ -1078,6 +1099,11 @@ static void rna_def_fluid_settings(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Elastic Limit", "How much the spring has to be stretched/compressed in order to change it's rest length");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
+
+ prop= RNA_def_property(srna, "spring_frames", PROP_INT, PROP_NONE);
+ RNA_def_property_range(prop, 0.0f, 100.0f);
+ RNA_def_property_ui_text(prop, "Spring Frames", "Create springs for this number of frames since particles birth (0 is always)");
+ RNA_def_property_update(prop, 0, "rna_Particle_reset");
/* Viscosity */
prop= RNA_def_property(srna, "linear_viscosity", PROP_FLOAT, PROP_NONE);
@@ -1087,42 +1113,69 @@ static void rna_def_fluid_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Viscosity", "Linear viscosity");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
- prop= RNA_def_property(srna, "square_viscosity", PROP_FLOAT, PROP_NONE);
+ prop= RNA_def_property(srna, "stiff_viscosity", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "viscosity_beta");
RNA_def_property_range(prop, 0.0f, 100.0f);
- RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
- RNA_def_property_ui_text(prop, "Square viscosity", "Square viscosity");
+ RNA_def_property_ui_range(prop, 0.0f, 2.0f, 1, 3);
+ RNA_def_property_ui_text(prop, "Stiff viscosity", "Creates viscosity for expanding fluid)");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
/* Double density relaxation */
- prop= RNA_def_property(srna, "density_force", PROP_FLOAT, PROP_NONE);
+ prop= RNA_def_property(srna, "stiffness", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "stiffness_k");
RNA_def_property_range(prop, 0.0f, 100.0f);
RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
- RNA_def_property_ui_text(prop, "Density Force", "How strongly the fluid tends to rest density");
+ RNA_def_property_ui_text(prop, "Stiffness", "How incompressible the fluid is");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
- prop= RNA_def_property(srna, "repulsion_force", PROP_FLOAT, PROP_NONE);
+ prop= RNA_def_property(srna, "repulsion", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "stiffness_knear");
RNA_def_property_range(prop, 0.0f, 100.0f);
- RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
- RNA_def_property_ui_text(prop, "Repulsion", "How strongly the fluid tries to keep from clustering");
+ RNA_def_property_ui_range(prop, 0.0f, 2.0f, 1, 3);
+ RNA_def_property_ui_text(prop, "Repulsion Factor", "How strongly the fluid tries to keep from clustering (factor of stiffness)");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
prop= RNA_def_property(srna, "rest_density", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "rest_density");
- RNA_def_property_range(prop, 0.0f, 1000.0f);
- RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3);
- RNA_def_property_ui_text(prop, "Rest Density", "Rest density of the fluid");
+ RNA_def_property_range(prop, 0.0f, 100.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 2.0f, 1, 3);
+ RNA_def_property_ui_text(prop, "Rest Density", "Fluid rest density");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
/* Buoyancy */
prop= RNA_def_property(srna, "buoyancy", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "buoyancy");
- RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_range(prop, 0.0f, 10.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 1.0f, 1, 3);
RNA_def_property_ui_text(prop, "Buoyancy", "Artificial buoyancy force in negative gravity direction based on pressure differences inside the fluid");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
+
+ /* Factor flags */
+ prop= RNA_def_property(srna, "factor_repulsion", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SPH_FAC_REPULSION);
+ RNA_def_property_ui_text(prop, "Factor Repulsion", "Repulsion is a factor of stiffness");
+ RNA_def_property_update(prop, 0, "rna_Particle_reset");
+
+ prop= RNA_def_property(srna, "factor_density", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SPH_FAC_DENSITY);
+ RNA_def_property_ui_text(prop, "Factor Density", "Density is calculated as a factor of default density (depends on particle size)");
+ RNA_def_property_update(prop, 0, "rna_Particle_reset");
+
+ prop= RNA_def_property(srna, "factor_radius", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SPH_FAC_RADIUS);
+ RNA_def_property_ui_text(prop, "Factor Radius", "Interaction radius is a factor of 4 * particle size");
+ RNA_def_property_update(prop, 0, "rna_Particle_reset");
+
+ prop= RNA_def_property(srna, "factor_stiff_viscosity", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SPH_FAC_VISCOSITY);
+ RNA_def_property_ui_text(prop, "Factor Stiff Viscosity", "Stiff viscosity is a factor of normal viscosity");
+ RNA_def_property_update(prop, 0, "rna_Particle_reset");
+
+ prop= RNA_def_property(srna, "factor_rest_length", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", SPH_FAC_REST_LENGTH);
+ RNA_def_property_ui_text(prop, "Factor Rest Length", "Spring rest length is a factor of 2 * particle size");
+ RNA_def_property_update(prop, 0, "rna_Particle_reset");
}
static void rna_def_particle_settings_mtex(BlenderRNA *brna)
@@ -1361,13 +1414,6 @@ static void rna_def_particle_settings(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
- static EnumPropertyItem dist_items[] = {
- {PART_DISTR_JIT, "JIT", 0, "Jittered", ""},
- {PART_DISTR_RAND, "RAND", 0, "Random", ""},
- {PART_DISTR_GRID, "GRID", 0, "Grid", ""},
- {0, NULL, 0, NULL, NULL}
- };
-
static EnumPropertyItem phys_type_items[] = {
{PART_PHYS_NO, "NO", 0, "No", ""},
{PART_PHYS_NEWTON, "NEWTON", 0, "Newtonian", ""},
@@ -1468,6 +1514,14 @@ static void rna_def_particle_settings(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem draw_col_items[] = {
+ {PART_DRAW_COL_NONE, "NONE", 0, "None", ""},
+ {PART_DRAW_COL_MAT, "MATERIAL", 0, "Material", ""},
+ {PART_DRAW_COL_VEL, "VELOCITY", 0, "Velocity", ""},
+ {PART_DRAW_COL_ACC, "ACCELERATION", 0, "Acceleration", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
srna= RNA_def_struct(brna, "ParticleSettings", "ID");
RNA_def_struct_ui_text(srna, "Particle Settings", "Particle settings, reusable by multiple particle systems");
RNA_def_struct_ui_icon(srna, ICON_PARTICLE_DATA);
@@ -1609,7 +1663,9 @@ static void rna_def_particle_settings(BlenderRNA *brna)
prop= RNA_def_property(srna, "distribution", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "distr");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_enum_items(prop, dist_items);
+ RNA_def_property_enum_items(prop, part_dist_items);
+ RNA_def_property_enum_items(prop, part_draw_as_items);
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Particle_dist_itemf");
RNA_def_property_ui_text(prop, "Distribution", "How to distribute particles on selected element");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
@@ -1708,11 +1764,6 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Speed", "Multiply line length by particle speed");
RNA_def_property_update(prop, 0, "rna_Particle_redo");
- prop= RNA_def_property(srna, "show_material_color", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_MAT_COL);
- RNA_def_property_ui_text(prop, "Material Color", "Draw particles using material's diffuse color");
- RNA_def_property_update(prop, 0, "rna_Particle_redo");
-
prop= RNA_def_property(srna, "use_whole_group", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_WHOLE_GR);
RNA_def_property_ui_text(prop, "Whole Group", "Use whole group at once");
@@ -1737,6 +1788,12 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Particle Rendering", "How particles are rendered");
RNA_def_property_update(prop, 0, "rna_Particle_redo");
+ prop= RNA_def_property(srna, "draw_color", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "draw_col");
+ RNA_def_property_enum_items(prop, draw_col_items);
+ RNA_def_property_ui_text(prop, "Draw Color", "Draw additional particle data as a color");
+ RNA_def_property_update(prop, 0, "rna_Particle_redo");
+
prop= RNA_def_property(srna, "draw_size", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 0, 1000);
RNA_def_property_ui_range(prop, 0, 100, 1, 0);
@@ -1848,6 +1905,12 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Tilt", "Tilt of the billboards");
RNA_def_property_update(prop, 0, "rna_Particle_redo");
+ prop= RNA_def_property(srna, "color_maximum", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "color_vec_max");
+ RNA_def_property_range(prop, 0.01f, 100.0f);
+ RNA_def_property_ui_text(prop, "Color Maximum", "Maximum length of the particle color vector");
+ RNA_def_property_update(prop, 0, "rna_Particle_redo");
+
prop= RNA_def_property(srna, "billboard_tilt_random", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "bb_rand_tilt");
RNA_def_property_range(prop, 0.0f, 1.0f);
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 721dfc1b689..dca2540af14 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1252,6 +1252,10 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_enum_items(prop, edge_tag_items);
RNA_def_property_ui_text(prop, "Edge Tag Mode", "The edge flag to tag when selecting the shortest path");
+ prop= RNA_def_property(srna, "edge_path_live_unwrap", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "edge_mode_live_unwrap", 1);
+ RNA_def_property_ui_text(prop, "Live Unwrap", "Changing edges seam re-calculates UV unwrap");
+
/* etch-a-ton */
prop= RNA_def_property(srna, "use_bone_sketching", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bone_sketching", BONE_SKETCHING);
@@ -2273,7 +2277,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem color_mode_items[] ={
- {R_PLANESBW, "BW", 0, "BW", "Images are saved with BW (grayscale) data"},
+ {R_PLANESBW, "BW", 0, "BW", "Images get saved in 8 bits grayscale (only PNG, JPEG, TGA, TIF)"},
{R_PLANES24, "RGB", 0, "RGB", "Images are saved with RGB (color) data"},
{R_PLANES32, "RGBA", 0, "RGBA", "Images are saved with RGB and Alpha data (if supported)"},
{0, NULL, 0, NULL, NULL}};
@@ -2282,7 +2286,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
{R_OUTPUT_SCREEN, "SCREEN", 0, "Full Screen", "Images are rendered in full Screen"},
{R_OUTPUT_AREA, "AREA", 0, "Image Editor", "Images are rendered in Image Editor"},
{R_OUTPUT_WINDOW, "WINDOW", 0, "New Window", "Images are rendered in new Window"},
- {R_OUTPUT_NONE, "NONE", 0, "No Output", "Images are rendered without drawing"},
+ {R_OUTPUT_NONE, "NONE", 0, "Keep UI", "Images are rendered without forcing UI changes, optionally showing result"},
{0, NULL, 0, NULL, NULL}};
/* Bake */
diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c
index 1a6cbc4781f..7e94a76598b 100644
--- a/source/blender/modifiers/intern/MOD_particlesystem.c
+++ b/source/blender/modifiers/intern/MOD_particlesystem.c
@@ -35,7 +35,7 @@
*/
-#include "stddef.h"
+#include <stddef.h>
#include "DNA_material_types.h"
diff --git a/source/blender/modifiers/intern/MOD_smoke.c b/source/blender/modifiers/intern/MOD_smoke.c
index 351a86624be..b13d86a609e 100644
--- a/source/blender/modifiers/intern/MOD_smoke.c
+++ b/source/blender/modifiers/intern/MOD_smoke.c
@@ -35,7 +35,7 @@
*/
-#include "stddef.h"
+#include <stddef.h>
#include "MEM_guardedalloc.h"
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c
index 8e44cd1ec37..f7a55720a5e 100644
--- a/source/blender/modifiers/intern/MOD_solidify.c
+++ b/source/blender/modifiers/intern/MOD_solidify.c
@@ -593,11 +593,18 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
mf->mat_nr += mat_ofs_rim;
CLAMP(mf->mat_nr, 0, mat_nr_max);
}
- if(crease_outer)
- ed->crease= crease_outer;
+ if(crease_outer) {
+ /* crease += crease_outer; without wrapping */
+ unsigned char *cr= (unsigned char *)&(ed->crease);
+ int tcr= *cr + crease_outer;
+ *cr= tcr > 255 ? 255 : tcr;
+ }
if(crease_inner) {
- medge[numEdges + eidx].crease= crease_inner;
+ /* crease += crease_inner; without wrapping */
+ unsigned char *cr= (unsigned char *)&(medge[numEdges + eidx].crease);
+ int tcr= *cr + crease_inner;
+ *cr= tcr > 255 ? 255 : tcr;
}
#ifdef SOLIDIFY_SIDE_NORMALS
diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c
index 0d0e81925f7..fc9958b08d0 100644
--- a/source/blender/modifiers/intern/MOD_subsurf.c
+++ b/source/blender/modifiers/intern/MOD_subsurf.c
@@ -35,7 +35,7 @@
*/
-#include "stddef.h"
+#include <stddef.h>
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_math.c b/source/blender/nodes/intern/CMP_nodes/CMP_math.c
index 09c08f01a8a..039f7e6fab1 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_math.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_math.c
@@ -140,7 +140,7 @@ static void do_math(bNode *node, float *out, float *in, float *in2)
break;
case 14: /* Round */
{
- out[0]= (int)(in[0] + 0.5f);
+ out[0]= (out[0]<0)?(int)(in[0] - 0.5f):(int)(in[0] + 0.5f);
}
break;
case 15: /* Less Than */
diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_material.c b/source/blender/nodes/intern/SHD_nodes/SHD_material.c
index a95968e7fc9..317dd07f8fe 100644
--- a/source/blender/nodes/intern/SHD_nodes/SHD_material.c
+++ b/source/blender/nodes/intern/SHD_nodes/SHD_material.c
@@ -155,7 +155,7 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in,
col[3]= shrnode.alpha;
if(shi->do_preview)
- nodeAddToPreview(node, col, shi->xs, shi->ys);
+ nodeAddToPreview(node, col, shi->xs, shi->ys, shi->do_manage);
VECCOPY(out[MAT_OUT_COLOR]->vec, col);
out[MAT_OUT_ALPHA]->vec[0]= shrnode.alpha;
diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_math.c b/source/blender/nodes/intern/SHD_nodes/SHD_math.c
index 0c9e9bd0fe3..dd0a564dc4b 100644
--- a/source/blender/nodes/intern/SHD_nodes/SHD_math.c
+++ b/source/blender/nodes/intern/SHD_nodes/SHD_math.c
@@ -174,9 +174,9 @@ bNodeStack **out)
case 14: /* Round */
{
if(in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
- out[0]->vec[0]= (int)(in[0]->vec[0] + 0.5f);
+ out[0]->vec[0]= (in[0]->vec[0]<0)?(int)(in[0]->vec[0] - 0.5f):(int)(in[0]->vec[0] + 0.5f);
else
- out[0]->vec[0]= (int)(in[1]->vec[0] + 0.5f);
+ out[0]->vec[0]= (in[1]->vec[0]<0)?(int)(in[1]->vec[0] - 0.5f):(int)(in[1]->vec[0] + 0.5f);
}
break;
case 15: /* Less Than */
diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_output.c b/source/blender/nodes/intern/SHD_nodes/SHD_output.c
index 4b6488cf4e0..e42caabff34 100644
--- a/source/blender/nodes/intern/SHD_nodes/SHD_output.c
+++ b/source/blender/nodes/intern/SHD_nodes/SHD_output.c
@@ -52,7 +52,7 @@ static void node_shader_exec_output(void *data, bNode *node, bNodeStack **in, bN
nodestack_get_vec(col+3, SOCK_VALUE, in[1]);
if(shi->do_preview) {
- nodeAddToPreview(node, col, shi->xs, shi->ys);
+ nodeAddToPreview(node, col, shi->xs, shi->ys, shi->do_manage);
node->lasty= shi->ys;
}
diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_texture.c b/source/blender/nodes/intern/SHD_nodes/SHD_texture.c
index c2fb18a939b..249e4eeca5d 100644
--- a/source/blender/nodes/intern/SHD_nodes/SHD_texture.c
+++ b/source/blender/nodes/intern/SHD_nodes/SHD_texture.c
@@ -116,7 +116,7 @@ static void node_shader_exec_texture(void *data, bNode *node, bNodeStack **in, b
VECCOPY(out[2]->vec, nor);
if(shi->do_preview)
- nodeAddToPreview(node, out[1]->vec, shi->xs, shi->ys);
+ nodeAddToPreview(node, out[1]->vec, shi->xs, shi->ys, shi->do_manage);
}
}
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_math.c b/source/blender/nodes/intern/TEX_nodes/TEX_math.c
index add8c24341e..a84573f1d09 100644
--- a/source/blender/nodes/intern/TEX_nodes/TEX_math.c
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_math.c
@@ -151,7 +151,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
break;
case 14: /* Round */
{
- *out= (int)(in0 + 0.5f);
+ *out= (in0<0)?(int)(in0 - 0.5f):(int)(in0 + 0.5f);
}
break;
diff --git a/source/blender/nodes/intern/TEX_util.c b/source/blender/nodes/intern/TEX_util.c
index da047fc9a87..51b3c6d909f 100644
--- a/source/blender/nodes/intern/TEX_util.c
+++ b/source/blender/nodes/intern/TEX_util.c
@@ -124,7 +124,7 @@ void tex_do_preview(bNode *node, float *co, float *col)
int xs= ((co[0] + 1.0f)*0.5f)*preview->xsize;
int ys= ((co[1] + 1.0f)*0.5f)*preview->ysize;
- nodeAddToPreview(node, col, xs, ys);
+ nodeAddToPreview(node, col, xs, ys, 0); /* 0 = no color management */
}
}
diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c
index 533225b1135..e0af6e085eb 100644
--- a/source/blender/python/generic/bpy_internal_import.c
+++ b/source/blender/python/generic/bpy_internal_import.c
@@ -74,16 +74,9 @@ void bpy_import_main_set(struct Main *maggie)
}
/* returns a dummy filename for a textblock so we can tell what file a text block comes from */
-void bpy_text_filename_get(char *fn, Text *text)
+void bpy_text_filename_get(char *fn, size_t fn_len, Text *text)
{
-#if PY_VERSION_HEX >= 0x03020000
- sprintf(fn, "%s%c%s", text->id.lib ? text->id.lib->filepath : G.main->name, SEP, text->id.name+2);
-#else
- /* this is a bug in python's Py_CompileString()!, fixed for python 3.2.
- the string encoding should not be required to be utf-8
- reported: http://bugs.python.org/msg115202 */
- strcpy(fn, text->id.name+2);
-#endif
+ BLI_snprintf(fn, fn_len, "%s%c%s", text->id.lib ? text->id.lib->filepath : G.main->name, SEP, text->id.name+2);
}
PyObject *bpy_text_import(Text *text)
@@ -94,7 +87,7 @@ PyObject *bpy_text_import(Text *text)
if( !text->compiled ) {
char fn_dummy[256];
- bpy_text_filename_get(fn_dummy, text);
+ bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text);
buf = txt_to_buf( text );
text->compiled = Py_CompileString( buf, fn_dummy, Py_file_input );
diff --git a/source/blender/python/generic/bpy_internal_import.h b/source/blender/python/generic/bpy_internal_import.h
index 45169b1b56f..7aabdcf3bf2 100644
--- a/source/blender/python/generic/bpy_internal_import.h
+++ b/source/blender/python/generic/bpy_internal_import.h
@@ -52,7 +52,7 @@ PyObject* bpy_text_import_name(char *name, int *found);
PyObject* bpy_text_reimport(PyObject *module, int *found);
/* void bpy_text_clear_modules(int clear_all);*/ /* Clear user modules */
-void bpy_text_filename_get(char *fn, struct Text *text);
+void bpy_text_filename_get(char *fn, size_t fn_len, struct Text *text);
extern PyMethodDef bpy_import_meth;
extern PyMethodDef bpy_reload_meth;
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index ed24c164921..113a553c6f5 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -60,18 +60,6 @@ void PyC_LineSpit(void) {
fprintf(stderr, "%s:%d\n", filename, lineno);
}
-/* python 3.2 only, copied from frameobjec.c */
-#if PY_VERSION_HEX < 0x03020000
-int
-PyFrame_GetLineNumber(PyFrameObject *f)
-{
- if (f->f_trace)
- return f->f_lineno;
- else
- return PyCode_Addr2Line(f->f_code, f->f_lasti);
-}
-#endif
-
void PyC_FileAndNum(const char **filename, int *lineno)
{
PyFrameObject *frame;
@@ -224,29 +212,7 @@ const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
return PyBytes_AS_STRING(py_str);
}
else {
- /* mostly copied from fileio.c's, fileio_init */
- PyObject *stringobj;
- PyObject *u;
-
- PyErr_Clear();
-
- u= PyUnicode_FromObject(py_str); /* coerce into unicode */
-
- if (u == NULL)
- return NULL;
-
- stringobj= PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(u), PyUnicode_GET_SIZE(u), "surrogateescape");
- Py_DECREF(u);
- if (stringobj == NULL)
- return NULL;
- if (!PyBytes_Check(stringobj)) { /* this seems wrong but it works fine */
- // printf("encoder failed to return bytes\n");
- Py_DECREF(stringobj);
- return NULL;
- }
- *coerce= stringobj;
-
- return PyBytes_AS_STRING(stringobj);
+ return PyBytes_AS_STRING((*coerce= PyUnicode_EncodeFSDefault(py_str)));
}
}
diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt
index 934600711c0..30e3d5a1052 100644
--- a/source/blender/python/intern/CMakeLists.txt
+++ b/source/blender/python/intern/CMakeLists.txt
@@ -43,6 +43,7 @@ set(SRC
bpy_app.c
bpy_driver.c
bpy_interface.c
+ bpy_library.c
bpy_operator.c
bpy_operator_wrap.c
bpy_props.c
diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c
index 9f2feee7404..69b28ed51fa 100644
--- a/source/blender/python/intern/bpy.c
+++ b/source/blender/python/intern/bpy.c
@@ -165,7 +165,7 @@ static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObj
if (!path)
path = BLI_get_user_folder_notest(folder_id, subdir);
- return PyUnicode_FromString(path ? path : "");
+ return PyUnicode_DecodeFSDefault(path ? path : "");
}
static PyMethodDef meth_bpy_script_paths = {"script_paths", (PyCFunction)bpy_script_paths, METH_NOARGS, bpy_script_paths_doc};
@@ -192,6 +192,7 @@ static PyObject *bpy_import_test(const char *modname)
void BPy_init_modules( void )
{
extern BPy_StructRNA *bpy_context_module;
+ extern int bpy_lib_init(PyObject *);
PointerRNA ctx_ptr;
PyObject *mod;
@@ -222,7 +223,9 @@ void BPy_init_modules( void )
PyModule_AddObject( mod, "types", BPY_rna_types() ); /* needs to be first so bpy_types can run */
PyModule_AddObject(mod, "StructMetaPropGroup", (PyObject *)&pyrna_struct_meta_idprop_Type); /* metaclass for idprop types, bpy_types.py needs access */
-
+
+ bpy_lib_init(mod); /* adds '_bpy._library_load', must be called before 'bpy_types' which uses it */
+
bpy_import_test("bpy_types");
PyModule_AddObject( mod, "data", BPY_rna_module() ); /* imports bpy_types by running this */
bpy_import_test("bpy_types");
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index 03d5f528670..58e277d9766 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -378,7 +378,7 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text, st
if (text) {
char fn_dummy[FILE_MAXDIR];
- bpy_text_filename_get(fn_dummy, text);
+ bpy_text_filename_get(fn_dummy, sizeof(fn_dummy), text);
if( !text->compiled ) { /* if it wasn't already compiled, do it now */
char *buf = txt_to_buf( text );
@@ -724,13 +724,13 @@ void bpy_module_delay_init(PyObject *bpy_proxy)
{
const int argc= 1;
const char *argv[2];
-
- const char *filename_rel= PyModule_GetFilename(bpy_proxy); /* can be relative */
+ PyObject *filename_obj= PyModule_GetFilenameObject(bpy_proxy); /* updating the module dict below will loose the reference to __file__ */
+ const char *filename_rel= _PyUnicode_AsString(filename_obj); /* can be relative */
char filename_abs[1024];
BLI_strncpy(filename_abs, filename_rel, sizeof(filename_abs));
BLI_path_cwd(filename_abs);
-
+
argv[0]= filename_abs;
argv[1]= NULL;
diff --git a/source/blender/python/intern/bpy_library.c b/source/blender/python/intern/bpy_library.c
new file mode 100644
index 00000000000..977bcabe694
--- /dev/null
+++ b/source/blender/python/intern/bpy_library.c
@@ -0,0 +1,343 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/intern/bpy_library.c
+ * \ingroup pythonintern
+ */
+
+#include <Python.h>
+#include <stddef.h>
+
+#include "BLO_readfile.h"
+
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_library.h"
+#include "BKE_idcode.h"
+#include "BKE_report.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_string.h"
+#include "BLI_linklist.h"
+#include "BLI_path_util.h"
+#include "BLI_listbase.h"
+
+#include "DNA_space_types.h" /* FILE_LINK, FILE_RELPATH */
+
+#include "bpy_util.h"
+
+typedef struct {
+ PyObject_HEAD /* required python macro */
+ /* collection iterator spesific parts */
+ char relpath[FILE_MAX];
+ char abspath[FILE_MAX]; /* absolute path */
+ BlendHandle *blo_handle;
+ int flag;
+ PyObject *dict;
+} BPy_Library;
+
+static PyObject *bpy_lib_load(PyObject *self, PyObject *args, PyObject *kwds);
+static PyObject *bpy_lib_enter(BPy_Library *self, PyObject *args);
+static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *args);
+
+static PyMethodDef bpy_lib_methods[] = {
+ {"__enter__", (PyCFunction)bpy_lib_enter, METH_NOARGS},
+ {"__exit__", (PyCFunction)bpy_lib_exit, METH_VARARGS},
+ {NULL} /* sentinel */
+};
+
+static void bpy_lib_dealloc(BPy_Library *self)
+{
+ Py_XDECREF(self->dict);
+ Py_TYPE(self)->tp_free(self);
+}
+
+
+PyTypeObject bpy_lib_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "bpy_lib", /* tp_name */
+ sizeof(BPy_Library), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)bpy_lib_dealloc,/* tp_dealloc */
+ NULL, /* printfunc tp_print; */
+ NULL, /* getattrfunc tp_getattr; */
+ NULL, /* setattrfunc tp_setattr; */
+ NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */
+ NULL, /* tp_repr */
+
+ /* Method suites for standard classes */
+
+ NULL, /* PyNumberMethods *tp_as_number; */
+ NULL, /* PySequenceMethods *tp_as_sequence; */
+ NULL, /* PyMappingMethods *tp_as_mapping; */
+
+ /* More standard operations (here for binary compatibility) */
+
+ NULL, /* hashfunc tp_hash; */
+ NULL, /* ternaryfunc tp_call; */
+ NULL, /* reprfunc tp_str; */
+
+ /* will only use these if this is a subtype of a py class */
+ PyObject_GenericGetAttr, /* getattrofunc tp_getattro; */
+ NULL, /* setattrofunc tp_setattro; */
+
+ /* Functions to access object as input/output buffer */
+ NULL, /* PyBufferProcs *tp_as_buffer; */
+
+ /*** Flags to define presence of optional/expanded features ***/
+ Py_TPFLAGS_DEFAULT, /* long tp_flags; */
+
+ NULL, /* char *tp_doc; Documentation string */
+ /*** Assigned meaning in release 2.0 ***/
+ /* call function for all accessible objects */
+ NULL, /* traverseproc tp_traverse; */
+
+ /* delete references to contained objects */
+ NULL, /* inquiry tp_clear; */
+
+ /*** Assigned meaning in release 2.1 ***/
+ /*** rich comparisons ***/
+ NULL, /* subclassed */ /* richcmpfunc tp_richcompare; */
+
+ /*** weak reference enabler ***/
+ 0,
+ /*** Added in release 2.2 ***/
+ /* Iterators */
+ NULL, /* getiterfunc tp_iter; */
+ NULL, /* iternextfunc tp_iternext; */
+
+ /*** Attribute descriptor and subclassing stuff ***/
+ bpy_lib_methods, /* struct PyMethodDef *tp_methods; */
+ NULL, /* struct PyMemberDef *tp_members; */
+ NULL, /* struct PyGetSetDef *tp_getset; */
+ NULL, /* struct _typeobject *tp_base; */
+ NULL, /* PyObject *tp_dict; */
+ NULL, /* descrgetfunc tp_descr_get; */
+ NULL, /* descrsetfunc tp_descr_set; */
+ offsetof(BPy_Library, dict),/* long tp_dictoffset; */
+ NULL, /* initproc tp_init; */
+ NULL, /* allocfunc tp_alloc; */
+ NULL, /* newfunc tp_new; */
+ /* Low-level free-memory routine */
+ NULL, /* freefunc tp_free; */
+ /* For PyObject_IS_GC */
+ NULL, /* inquiry tp_is_gc; */
+ NULL, /* PyObject *tp_bases; */
+ /* method resolution order */
+ NULL, /* PyObject *tp_mro; */
+ NULL, /* PyObject *tp_cache; */
+ NULL, /* PyObject *tp_subclasses; */
+ NULL, /* PyObject *tp_weaklist; */
+ NULL
+};
+
+
+static PyObject *bpy_lib_load(PyObject *UNUSED(self), PyObject *args, PyObject *kwds)
+{
+ static const char *kwlist[] = {"filepath", "link", "relative", NULL};
+ BPy_Library *ret;
+ const char* filename = NULL;
+ int is_rel= 0, is_link= 0;
+
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "s|ii:load", (char **)kwlist, &filename, &is_link, &is_rel))
+ return NULL;
+
+ ret= PyObject_New(BPy_Library, &bpy_lib_Type);
+
+ BLI_strncpy(ret->relpath, filename, sizeof(BPy_Library));
+ BLI_strncpy(ret->abspath, filename, sizeof(BPy_Library));
+ BLI_path_abs(ret->abspath, G.main->name);
+
+ ret->blo_handle= NULL;
+ ret->flag= (is_link ? FILE_LINK : 0) |
+ (is_rel ? FILE_RELPATH : 0);
+
+ ret->dict= PyDict_New();
+
+ return (PyObject *)ret;
+}
+
+static PyObject *_bpy_names(BPy_Library *self, int blocktype)
+{
+ PyObject *list;
+ LinkNode *l, *names;
+ int totnames;
+
+ names= BLO_blendhandle_get_datablock_names(self->blo_handle, blocktype, &totnames);
+
+ if(names) {
+ int counter = 0;
+ list = PyList_New(totnames);
+ for(l = names; l; l = l->next) {
+ PyList_SET_ITEM(list, counter, PyUnicode_FromString((char * )l->link));
+ counter++;
+ }
+ BLI_linklist_free(names, free); /* free linklist *and* each node's data */
+ }
+ else {
+ list= PyList_New(0);
+ }
+
+ return list;
+}
+
+static PyObject *bpy_lib_enter(BPy_Library *self, PyObject *UNUSED(args))
+{
+ PyObject *ret;
+ BPy_Library *self_from;
+ PyObject *from_dict= PyDict_New();
+ ReportList reports;
+
+ BKE_reports_init(&reports, RPT_STORE);
+
+ self->blo_handle= BLO_blendhandle_from_file(self->abspath, &reports);
+
+ if(self->blo_handle == NULL) {
+ if(BPy_reports_to_error(&reports, PyExc_IOError, TRUE) != -1) {
+ PyErr_Format(PyExc_IOError, "load: %s failed to open blend file", self->abspath);
+ }
+ return NULL;
+ }
+ else {
+ int i= 0, code;
+ while((code= BKE_idcode_iter_step(&i))) {
+ if(BKE_idcode_is_linkable(code)) {
+ const char *name_plural= BKE_idcode_to_name_plural(code);
+ PyObject *str= PyUnicode_FromString(name_plural);
+ PyDict_SetItem(self->dict, str, PyList_New(0));
+ PyDict_SetItem(from_dict, str, _bpy_names(self, code));
+ Py_DECREF(str);
+ }
+ }
+ }
+
+ /* create a dummy */
+ self_from= PyObject_New(BPy_Library, &bpy_lib_Type);
+ BLI_strncpy(self_from->relpath, self->relpath, sizeof(BPy_Library));
+ BLI_strncpy(self_from->abspath, self->abspath, sizeof(BPy_Library));
+
+ self_from->blo_handle= NULL;
+ self_from->flag= 0;
+ self_from->dict= from_dict; /* owns the dict */
+
+ /* return pair */
+ ret= PyTuple_New(2);
+
+ PyTuple_SET_ITEM(ret, 0, (PyObject *)self_from);
+
+ PyTuple_SET_ITEM(ret, 1, (PyObject *)self);
+ Py_INCREF(self);
+
+ BKE_reports_clear(&reports);
+
+ return ret;
+}
+
+static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
+{
+ Main *mainl= NULL;
+ int err= 0;
+
+ flag_all_listbases_ids(LIB_PRE_EXISTING, 1);
+
+ /* here appending/linking starts */
+ mainl = BLO_library_append_begin(BPy_GetContext(), &(self->blo_handle), self->relpath);
+
+ {
+ int i= 0, code;
+ while((code= BKE_idcode_iter_step(&i))) {
+ if(BKE_idcode_is_linkable(code)) {
+ const char *name_plural= BKE_idcode_to_name_plural(code);
+ PyObject *ls= PyDict_GetItemString(self->dict, name_plural);
+ // printf("lib: %s\n", name_plural);
+ if(ls && PyList_Check(ls)) {
+ /* loop */
+ Py_ssize_t size= PyList_GET_SIZE(ls);
+ Py_ssize_t i;
+ PyObject *item;
+ const char *item_str;
+
+ for(i= 0; i < size; i++) {
+ item= PyList_GET_ITEM(ls, i);
+ item_str= _PyUnicode_AsString(item);
+
+ // printf(" %s\n", item_str);
+
+ if(item_str) {
+ if(!BLO_library_append_named_part(NULL, mainl, &(self->blo_handle), item_str, code, self->flag)) {
+ PyErr_Format(PyExc_KeyError, "load: %s does not contain %s[\"%s\"]", self->abspath, name_plural, item_str);
+ err= -1;
+ break;
+ }
+ }
+ else {
+ /* XXX, could complain about this */
+ PyErr_Clear();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if(err == -1) {
+ /* exception raised above, XXX, this leaks some memory */
+ BLO_blendhandle_close(self->blo_handle);
+ self->blo_handle= NULL;
+ return NULL;
+ }
+ else {
+ BLO_library_append_end(NULL, mainl, &(self->blo_handle), 0, self->flag);
+ BLO_blendhandle_close(self->blo_handle);
+ self->blo_handle= NULL;
+
+ { /* copied from wm_operator.c */
+ /* mark all library linked objects to be updated */
+ recalc_all_library_objects(G.main);
+
+ /* append, rather than linking */
+ if((self->flag & FILE_LINK)==0) {
+ Library *lib= BLI_findstring(&G.main->library, self->abspath, offsetof(Library, name));
+ if(lib) all_local(lib, 1);
+ else BLI_assert(!"cant find name of just added library!");
+ }
+ }
+
+ flag_all_listbases_ids(LIB_PRE_EXISTING, 0);
+
+ Py_RETURN_NONE;
+ }
+}
+
+int bpy_lib_init(PyObject *mod_par)
+{
+ static PyMethodDef load_meth= {"load", (PyCFunction)bpy_lib_load, METH_STATIC|METH_VARARGS|METH_KEYWORDS};
+ PyModule_AddObject(mod_par, "_library_load", PyCFunction_New(&load_meth, NULL));
+
+ if(PyType_Ready(&bpy_lib_Type) < 0)
+ return -1;
+
+ return 0;
+}
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index 73a8deb1b97..ad1bce89896 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -198,8 +198,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
operator_ret= WM_operator_call_py(C, ot, context, &ptr, reports);
- if(BPy_reports_to_error(reports, FALSE))
- error_val = -1;
+ error_val= BPy_reports_to_error(reports, PyExc_RuntimeError, FALSE);
/* operator output is nice to have in the terminal/console too */
if(reports->list.first) {
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 0f452605c28..aa657f34f39 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -76,6 +76,7 @@
#define USE_MATHUTILS
#define USE_STRING_COERCE
+static PyObject* pyrna_struct_Subtype(PointerRNA *ptr);
static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self);
int pyrna_struct_validity_check(BPy_StructRNA *pysrna)
@@ -3126,8 +3127,36 @@ static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject
}
}
- /* The error raised here will be displayed */
+#if 0
return PyObject_GenericGetAttr((PyObject *)self, pyname);
+#else
+ {
+ /* Could just do this except for 1 awkward case.
+ * PyObject_GenericGetAttr((PyObject *)self, pyname);
+ * so as to support 'bpy.data.library.load()'
+ * note, this _only_ supports static methods */
+
+ PyObject *ret= PyObject_GenericGetAttr((PyObject *)self, pyname);
+
+ if(ret == NULL) {
+ /* since this is least common case, handle it last */
+ PointerRNA r_ptr;
+ PyObject *error_type, *error_value, *error_traceback;
+ PyErr_Fetch(&error_type, &error_value, &error_traceback);
+ PyErr_Clear();
+
+ if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
+ PyObject *cls= pyrna_struct_Subtype(&r_ptr); /* borrows */
+ ret= PyObject_GenericGetAttr(cls, pyname);
+ if(ret == NULL) {
+ PyErr_Restore(error_type, error_value, error_traceback);
+ }
+ }
+ }
+
+ return ret;
+ }
+#endif
}
//--------------- setattr-------------------------------------------
@@ -4194,10 +4223,10 @@ static PyObject *pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
BKE_reports_init(&reports, RPT_STORE);
RNA_function_call(C, &reports, self_ptr, self_func, &parms);
- err= (BPy_reports_to_error(&reports, TRUE))? -1: 0;
+ err= (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE));
/* return value */
- if(err==0) {
+ if(err != -1) {
if (ret_len > 0) {
if (ret_len > 1) {
ret= PyTuple_New(ret_len);
@@ -4843,6 +4872,10 @@ PyObject *pyrna_prop_collection_iter_CreatePyObject(PointerRNA *ptr, PropertyRNA
{
BPy_PropertyCollectionIterRNA *self= PyObject_New(BPy_PropertyCollectionIterRNA, &pyrna_prop_collection_iter_Type);
+#ifdef USE_WEAKREFS
+ self->in_weakreflist= NULL;
+#endif
+
RNA_property_collection_begin(ptr, prop, &self->iter);
return (PyObject *)self;
@@ -6094,7 +6127,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class
srna_new= reg(C, &reports, py_class, identifier, bpy_class_validate, bpy_class_call, bpy_class_free);
- if(BPy_reports_to_error(&reports, TRUE))
+ if(BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
return NULL;
/* python errors validating are not converted into reports so the check above will fail.
diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c
index e000f19be82..9dc6fd28762 100644
--- a/source/blender/python/intern/bpy_rna_anim.c
+++ b/source/blender/python/intern/bpy_rna_anim.c
@@ -183,7 +183,7 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
result= insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
MEM_freeN((void *)path_full);
- if(BPy_reports_to_error(&reports, TRUE))
+ if(BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
return NULL;
return PyBool_FromLong(result);
@@ -228,7 +228,7 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb
result= delete_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
MEM_freeN((void *)path_full);
- if(BPy_reports_to_error(&reports, TRUE))
+ if(BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
return NULL;
return PyBool_FromLong(result);
@@ -270,7 +270,7 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
result= ANIM_add_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0, DRIVER_TYPE_PYTHON);
- if(BPy_reports_to_error(&reports, TRUE))
+ if(BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
return NULL;
if(result) {
@@ -345,7 +345,7 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
MEM_freeN((void *)path_full);
- if(BPy_reports_to_error(&reports, TRUE))
+ if(BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
return NULL;
return PyBool_FromLong(result);
diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c
index 3d5090b73fa..ccbee2abcd1 100644
--- a/source/blender/python/intern/bpy_util.c
+++ b/source/blender/python/intern/bpy_util.c
@@ -57,7 +57,7 @@ char *BPy_enum_as_string(EnumPropertyItem *item)
return cstring;
}
-short BPy_reports_to_error(ReportList *reports, const short clear)
+short BPy_reports_to_error(ReportList *reports, PyObject *exception, const short clear)
{
char *report_str;
@@ -68,11 +68,11 @@ short BPy_reports_to_error(ReportList *reports, const short clear)
}
if(report_str) {
- PyErr_SetString(PyExc_RuntimeError, report_str);
+ PyErr_SetString(exception, report_str);
MEM_freeN(report_str);
}
- return (report_str != NULL);
+ return (report_str == NULL) ? 0 : -1;
}
diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h
index 9b217e77844..b16c8fe2e8c 100644
--- a/source/blender/python/intern/bpy_util.h
+++ b/source/blender/python/intern/bpy_util.h
@@ -30,8 +30,8 @@
#ifndef BPY_UTIL_H
#define BPY_UTIL_H
-#if PY_VERSION_HEX < 0x03010000
-#error "Python versions below 3.1 are not supported anymore, you'll need to update your python."
+#if PY_VERSION_HEX < 0x03020000
+#error "Python 3.2 or greater is required, you'll need to update your python."
#endif
#include "RNA_types.h" /* for EnumPropertyItem only */
@@ -44,7 +44,7 @@ char *BPy_enum_as_string(struct EnumPropertyItem *item);
#define BLANK_PYTHON_TYPE {PyVarObject_HEAD_INIT(NULL, 0) NULL}
/* error reporting */
-short BPy_reports_to_error(struct ReportList *reports, const short clear);
+short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const short clear);
short BPy_errors_to_report(struct ReportList *reports);
/* TODO - find a better solution! */
diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h
index ca04990efad..958c19ab9ca 100644
--- a/source/blender/render/extern/include/RE_shader_ext.h
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -174,6 +174,7 @@ typedef struct ShadeInput
/* from initialize, part or renderlayer */
short do_preview; /* for nodes, in previewrender */
+ short do_manage; /* color management flag */
short thread, sample; /* sample: ShadeSample array index */
short nodes; /* indicate node shading, temp hack to prevent recursion */
diff --git a/source/blender/render/intern/raytrace/bvh.h b/source/blender/render/intern/raytrace/bvh.h
index 56912ad7cdc..3ba5bbc624e 100644
--- a/source/blender/render/intern/raytrace/bvh.h
+++ b/source/blender/render/intern/raytrace/bvh.h
@@ -129,7 +129,8 @@ static void bvh_free(Tree *obj)
template<class Tree>
static void bvh_bb(Tree *obj, float *min, float *max)
{
- bvh_node_merge_bb(obj->root, min, max);
+ if(obj->root)
+ bvh_node_merge_bb(obj->root, min, max);
}
diff --git a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp
index fb23165a6e0..331358f727b 100644
--- a/source/blender/render/intern/raytrace/rayobject_qbvh.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_qbvh.cpp
@@ -80,9 +80,12 @@ void bvh_done<QBVHTree>(QBVHTree *obj)
return;
}
- pushup_simd<VBVHNode,4>(root);
-
- obj->root = Reorganize_SVBVH<VBVHNode>(arena2).transform(root);
+ if(root) {
+ pushup_simd<VBVHNode,4>(root);
+ obj->root = Reorganize_SVBVH<VBVHNode>(arena2).transform(root);
+ }
+ else
+ obj->root = NULL;
//Free data
BLI_memarena_free(arena1);
diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
index bcd5cb61608..c9de887d392 100644
--- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
@@ -106,9 +106,19 @@ void rtbuild_add(RTBuilder *b, RayObject *o)
INIT_MINMAX(bb, bb+3);
RE_rayobject_merge_bb(o, bb, bb+3);
+ /* skip objects with invalid bounding boxes, nan causes DO_MINMAX
+ to do nothing, so we get these invalid values. this shouldn't
+ happen usually, but bugs earlier in the pipeline can cause it. */
+ if(bb[0] > bb[3] || bb[1] > bb[4] || bb[2] > bb[5])
+ return;
+ /* skip objects with inf bounding boxes */
+ if(!finite(bb[0]) || !finite(bb[1]) || !finite(bb[2]))
+ return;
+ if(!finite(bb[3]) || !finite(bb[4]) || !finite(bb[5]))
+ return;
/* skip objects with zero bounding box, they are of no use, and
will give problems in rtbuild_heuristic_object_split later */
- if(len_squared_v3v3(bb, bb+3) == 0.0f)
+ if(bb[0] == bb[3] && bb[1] == bb[4] && bb[2] == bb[5])
return;
copy_v3_v3(b->primitives.end->bb, bb);
diff --git a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp
index 3a29ac29390..a99c57ab233 100644
--- a/source/blender/render/intern/raytrace/rayobject_svbvh.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_svbvh.cpp
@@ -115,8 +115,12 @@ void bvh_done<SVBVHTree>(SVBVHTree *obj)
return;
}
- VBVH_optimalPackSIMD<OVBVHNode,PackCost>(PackCost()).transform(root);
- obj->root = Reorganize_SVBVH<OVBVHNode>(arena2).transform(root);
+ if(root) {
+ VBVH_optimalPackSIMD<OVBVHNode,PackCost>(PackCost()).transform(root);
+ obj->root = Reorganize_SVBVH<OVBVHNode>(arena2).transform(root);
+ }
+ else
+ obj->root = NULL;
}
//Free data
diff --git a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp
index 1765f3da381..25eada43a4a 100644
--- a/source/blender/render/intern/raytrace/rayobject_vbvh.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_vbvh.cpp
@@ -98,13 +98,17 @@ void bvh_done<VBVHTree>(VBVHTree *obj)
return;
}
- reorganize(root);
- remove_useless(root, &root);
- bvh_refit(root);
-
- pushup(root);
- pushdown(root);
- obj->root = root;
+ if(root) {
+ reorganize(root);
+ remove_useless(root, &root);
+ bvh_refit(root);
+
+ pushup(root);
+ pushdown(root);
+ obj->root = root;
+ }
+ else
+ obj->root = NULL;
}
else
{
diff --git a/source/blender/render/intern/raytrace/vbvh.h b/source/blender/render/intern/raytrace/vbvh.h
index d91a7c209c8..62cccdb5af9 100644
--- a/source/blender/render/intern/raytrace/vbvh.h
+++ b/source/blender/render/intern/raytrace/vbvh.h
@@ -157,9 +157,12 @@ struct BuildBinaryVBVH
Node *_transform(RTBuilder *builder)
{
-
int size = rtbuild_size(builder);
- if(size == 1)
+
+ if(size == 0) {
+ return NULL;
+ }
+ else if(size == 1)
{
Node *node = create_node();
INIT_MINMAX(node->bb, node->bb+3);
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index bbf41f7ac6d..d7eb22b5fc7 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -1713,25 +1713,6 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
bb.totnum = totpart+totchild;
bb.uv_split = part->bb_uv_split;
}
-
-#if 0 // XXX old animation system
-/* 2.3 setup time */
- if(part->flag&PART_ABS_TIME && part->ipo) {
- calc_ipo(part->ipo, cfra);
- execute_ipo((ID *)part, part->ipo);
- }
-
- if(part->flag & PART_GLOB_TIME)
-#endif // XXX old animation system
-
-///* 2.4 setup reactors */
-// if(part->type == PART_REACTOR){
-// psys_get_reactor_target(ob, psys, &tob, &tpsys);
-// if(tpsys && (part->from==PART_FROM_PARTICLE || part->phystype==PART_PHYS_NO)){
-// psmd = psys_get_modifier(tob,tpsys);
-// tpart = tpsys->part;
-// }
-// }
/* 2.5 setup matrices */
mul_m4_m4m4(mat, ob->obmat, re->viewmat);
@@ -1828,7 +1809,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
hasize = ma->hasize;
/* get orco */
- if(tpsys && (part->from==PART_FROM_PARTICLE || part->phystype==PART_PHYS_NO)){
+ if(tpsys && part->phystype==PART_PHYS_NO){
tpa=tpsys->particles+pa->num;
psys_particle_on_emitter(psmd,tpart->from,tpa->num,pa->num_dmcache,tpa->fuv,tpa->foffset,co,nor,0,0,sd.orco,0);
}
@@ -1892,7 +1873,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
}
/* get uvco & mcol */
- if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES) {
+ if(part->childtype==PART_CHILD_FACES) {
get_particle_uvco_mcol(PART_FROM_FACE, psmd->dm, cpa->fuv, cpa->num, &sd);
}
else {
@@ -3369,7 +3350,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
/* test for 100% transparant */
ok= 1;
- if(ma->alpha==0.0f && ma->spectra==0.0f && ma->filter==0.0f) {
+ if(ma->alpha==0.0f && ma->spectra==0.0f && ma->filter==0.0f && (ma->mode & MA_TRANSP)) {
ok= 0;
/* texture on transparency? */
for(a=0; a<MAX_MTEX; a++) {
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index 6f639de70d5..0acae258cf8 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -762,7 +762,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo
if(depth>0) {
float fr, fg, fb, f, f1;
- if((shi.mat->mode_l & MA_TRANSP) && shr.alpha < 1.0f) {
+ if((shi.mat->mode_l & MA_TRANSP) && shr.alpha < 1.0f && (shi.mat->mode_l & (MA_ZTRANSP | MA_RAYTRANSP))) {
float nf, f, refract[3], tracol[4];
tracol[0]= shi.r;
@@ -1824,7 +1824,7 @@ static float *threadsafe_table_sphere(int test, int thread, int xs, int ys, int
return R.wrld.aotables+ thread*tot*3;
}
-static float *sphere_sampler(int type, int resol, int thread, int xs, int ys)
+static float *sphere_sampler(int type, int resol, int thread, int xs, int ys, int reset)
{
int tot;
float *vec;
@@ -1852,8 +1852,8 @@ static float *sphere_sampler(int type, int resol, int thread, int xs, int ys)
float ang, *vec1;
int a;
- // returns table if xs and ys were equal to last call
- sphere= threadsafe_table_sphere(1, thread, xs, ys, tot);
+ // returns table if xs and ys were equal to last call, and not resetting
+ sphere= (reset)? NULL: threadsafe_table_sphere(1, thread, xs, ys, tot);
if(sphere==NULL) {
sphere= threadsafe_table_sphere(0, thread, xs, ys, tot);
@@ -2071,8 +2071,10 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *ao, float *env)
envcolor= WO_AOPLAIN;
if(resol>32) resol= 32;
-
- vec= sphere_sampler(R.wrld.aomode, resol, shi->thread, shi->xs, shi->ys);
+
+ /* get sphere samples. for faces we get the same samples for sample x/y values,
+ for strand render we always require a new sampler because x/y are not set */
+ vec= sphere_sampler(R.wrld.aomode, resol, shi->thread, shi->xs, shi->ys, shi->strand != NULL);
// warning: since we use full sphere now, and dotproduct is below, we do twice as much
tot= 2*resol*resol;
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index 14f1c28aa38..db533cf7a42 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -582,7 +582,7 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
}
}
- if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
+ if (shi->do_manage) {
if(mode & (MA_VERTEXCOL|MA_VERTEXCOLP|MA_FACETEXTURE)) {
srgb_to_linearrgb_v3_v3(shi->vcol, shi->vcol);
}
@@ -1318,7 +1318,7 @@ void shade_input_set_shade_texco(ShadeInput *shi)
} /* else {
Note! For raytracing winco is not set, important because thus means all shader input's need to have their variables set to zero else in-initialized values are used
*/
- if (R.r.color_mgt_flag & R_COLOR_MANAGEMENT) {
+ if (shi->do_manage) {
if(mode & (MA_VERTEXCOL|MA_VERTEXCOLP|MA_FACETEXTURE)) {
srgb_to_linearrgb_v3_v3(shi->vcol, shi->vcol);
}
@@ -1337,6 +1337,7 @@ void shade_input_initialize(ShadeInput *shi, RenderPart *pa, RenderLayer *rl, in
shi->sample= sample;
shi->thread= pa->thread;
shi->do_preview= (R.r.scemode & R_MATNODE_PREVIEW) != 0;
+ shi->do_manage= (R.r.color_mgt_flag & R_COLOR_MANAGEMENT);
shi->lay= rl->lay;
shi->layflag= rl->layflag;
shi->passflag= rl->passflag;
diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c
index a8d790d9d78..c4634b261af 100644
--- a/source/blender/render/intern/source/shadeoutput.c
+++ b/source/blender/render/intern/source/shadeoutput.c
@@ -878,7 +878,9 @@ void shade_color(ShadeInput *shi, ShadeResult *shr)
if(ma->fresnel_tra!=0.0f)
shi->alpha*= fresnel_fac(shi->view, shi->vn, ma->fresnel_tra_i, ma->fresnel_tra);
-
+
+ if (!(shi->mode & MA_TRANSP)) shi->alpha= 1.0f;
+
shr->diff[0]= shi->r;
shr->diff[1]= shi->g;
shr->diff[2]= shi->b;
@@ -1502,10 +1504,10 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr)
float inpr, lv[3];
float *view, shadfac[4];
float ir, accum, visifac, lampdist;
+ float shaded = 0.0f, lightness = 0.0f;
view= shi->view;
-
accum= ir= 0.0f;
lights= get_lights(shi);
@@ -1522,27 +1524,69 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr)
if(lar->shb || (lar->mode & LA_SHAD_RAY)) {
visifac= lamp_get_visibility(lar, shi->co, lv, &lampdist);
if(visifac <= 0.0f) {
- ir+= 1.0f;
- accum+= 1.0f;
+ if (shi->mat->shadowonly_flag == MA_SO_OLD) {
+ ir+= 1.0f;
+ accum+= 1.0f;
+ }
continue;
}
inpr= INPR(shi->vn, lv);
if(inpr <= 0.0f) {
- ir+= 1.0f;
- accum+= 1.0f;
+ if (shi->mat->shadowonly_flag == MA_SO_OLD) {
+ ir+= 1.0f;
+ accum+= 1.0f;
+ }
continue;
- }
+ }
+
lamp_get_shadow(lar, shi, inpr, shadfac, shi->depth);
- ir+= 1.0f;
- accum+= (1.0f-visifac) + (visifac)*rgb_to_grayscale(shadfac)*shadfac[3];
+ if (shi->mat->shadowonly_flag == MA_SO_OLD) {
+ /* Old "Shadows Only" */
+ ir+= 1.0f;
+ accum+= (1.0f-visifac) + (visifac)*rgb_to_grayscale(shadfac)*shadfac[3];
+ }
+ else {
+ ir+= lar->energy;
+ shaded += rgb_to_grayscale(shadfac)*shadfac[3] * visifac * lar->energy;
+
+ if (shi->mat->shadowonly_flag == MA_SO_SHADOW) {
+ lightness += visifac * lar->energy;
+ }
+ }
}
}
+
+ /* Apply shadows as alpha */
if(ir>0.0f) {
- accum/= ir;
- shr->alpha= (shi->mat->alpha)*(1.0f-accum);
+ if (shi->mat->shadowonly_flag == MA_SO_OLD) {
+ accum = 1.0f - accum/ir;
+ }
+ else {
+ shaded/= ir;
+ lightness/= ir;
+
+ if (shi->mat->shadowonly_flag == MA_SO_SHADOW) {
+ if (lightness > 0.0f) {
+ /* Get shadow value from between 0.0f and non-shadowed lightness */
+ accum = (lightness - shaded) / (lightness);
+ }
+ else {
+ accum = 0.0f;
+ }
+ }
+ else { /* shadowonly_flag == MA_SO_SHADED */
+ /* Use shaded value */
+ accum = 1.0f - shaded;
+ }}
+
+ shr->alpha= (shi->alpha)*(accum);
+ }
+ else {
+ /* If "fully shaded", use full alpha even on areas that have no lights */
+ if (shi->mat->shadowonly_flag == MA_SO_SHADED) shr->alpha=1.0f;
+ else shr->alpha= 0.f;
}
- else shr->alpha= 0.f;
}
/* quite disputable this... also note it doesn't mirror-raytrace */
@@ -1551,18 +1595,31 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr)
if(R.wrld.mode & WO_AMB_OCC) {
f= R.wrld.aoenergy*shi->amb;
-
+
if(R.wrld.aomix==WO_AOADD) {
- f= f*(1.0f - rgb_to_grayscale(shi->ao));
- shr->alpha= (shr->alpha + f)*f;
+ if (shi->mat->shadowonly_flag == MA_SO_OLD) {
+ f= f*(1.0f - rgb_to_grayscale(shi->ao));
+ shr->alpha= (shr->alpha + f)*f;
+ }
+ else {
+ shr->alpha -= f*rgb_to_grayscale(shi->ao);
+ if (shr->alpha<0.0f) shr->alpha=0.0f;
+ }
}
- else
+ else /* AO Multiply */
shr->alpha= (1.0f - f)*shr->alpha + f*(1.0f - (1.0f - shr->alpha)*rgb_to_grayscale(shi->ao));
}
if(R.wrld.mode & WO_ENV_LIGHT) {
- f= R.wrld.ao_env_energy*shi->amb*(1.0f - rgb_to_grayscale(shi->env));
- shr->alpha= (shr->alpha + f)*f;
+ if (shi->mat->shadowonly_flag == MA_SO_OLD) {
+ f= R.wrld.ao_env_energy*shi->amb*(1.0f - rgb_to_grayscale(shi->env));
+ shr->alpha= (shr->alpha + f)*f;
+ }
+ else {
+ f= R.wrld.ao_env_energy*shi->amb;
+ shr->alpha -= f*rgb_to_grayscale(shi->env);
+ if (shr->alpha<0.0f) shr->alpha=0.0f;
+ }
}
}
}
@@ -1583,6 +1640,8 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
memset(shr, 0, sizeof(ShadeResult));
+ if(!(shi->mode & MA_TRANSP)) shi->alpha = 1.0f;
+
/* separate loop */
if(ma->mode & MA_ONLYSHADOW) {
shade_lamp_loop_only_shadow(shi, shr);
@@ -1599,10 +1658,12 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
shi->g= shi->vcol[1];
shi->b= shi->vcol[2];
if((ma->mode & (MA_FACETEXTURE_ALPHA)) || ma->vcol_alpha)
- shi->alpha= shi->vcol[3];
+ shi->alpha= (shi->mode & MA_TRANSP) ? shi->vcol[3] : 1.0f;
}
- if(ma->texco)
+ if(ma->texco){
do_material_tex(shi);
+ if (!(shi->mode & MA_TRANSP)) shi->alpha = 1.0f;
+ }
shr->col[0]= shi->r*shi->alpha;
shr->col[1]= shi->g*shi->alpha;
@@ -1757,11 +1818,11 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
/* alpha in end, spec can influence it */
if(passflag & (SCE_PASS_COMBINED)) {
- if(ma->fresnel_tra!=0.0f)
+ if((ma->fresnel_tra!=0.0f) && (shi->mode & MA_TRANSP))
shi->alpha*= fresnel_fac(shi->view, shi->vn, ma->fresnel_tra_i, ma->fresnel_tra);
/* note: shi->mode! */
- if(shi->mode & MA_TRANSP) {
+ if(shi->mode & MA_TRANSP && (shi->mode & (MA_ZTRANSP|MA_RAYTRANSP))) {
if(shi->spectra!=0.0f) {
float t = MAX3(shr->spec[0], shr->spec[1], shr->spec[2]);
t *= shi->spectra;
@@ -1831,7 +1892,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
shr->combined[0] *= obcol[0];
shr->combined[1] *= obcol[1];
shr->combined[2] *= obcol[2];
- shr->alpha *= obcol[3];
+ if (shi->mode & MA_TRANSP) shr->alpha *= obcol[3];
}
}
diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c
index 4dfd5b1b069..f7ec0050c5d 100644
--- a/source/blender/render/intern/source/strand.c
+++ b/source/blender/render/intern/source/strand.c
@@ -47,6 +47,7 @@
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "BLI_memarena.h"
+#include "BLI_rand.h"
#include "BKE_DerivedMesh.h"
#include "BKE_key.h"
@@ -268,11 +269,12 @@ void strand_apply_shaderesult_alpha(ShadeResult *shr, float alpha)
}
}
-void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *sseg, StrandPoint *spoint)
+static void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *sseg, StrandVert *svert, StrandPoint *spoint)
{
ShadeInput *shi= ssamp->shi;
ShadeResult *shr= ssamp->shr;
VlakRen vlr;
+ int seed;
memset(&vlr, 0, sizeof(vlr));
vlr.flag= R_SMOOTH;
@@ -290,6 +292,13 @@ void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *sseg, Str
/* cache for shadow */
shi->samplenr= re->shadowsamplenr[shi->thread]++;
+ /* all samples */
+ shi->mask= 0xFFFF;
+
+ /* seed RNG for consistent results across tiles */
+ seed = shi->strand->index + (svert - shi->strand->vert);
+ BLI_thread_srandom(shi->thread, seed);
+
shade_input_set_strand(shi, sseg->strand, spoint);
shade_input_set_strand_texco(shi, sseg->strand, sseg->v[1], spoint);
@@ -352,7 +361,7 @@ static void strand_shade_get(Render *re, StrandShadeCache *cache, ShadeSample *s
/* not shaded yet, shade and insert into hash */
p.t= (sseg->v[1] == svert)? 0.0f: 1.0f;
strand_eval_point(sseg, &p);
- strand_shade_point(re, ssamp, sseg, &p);
+ strand_shade_point(re, ssamp, sseg, svert, &p);
hashshr= MEM_callocN(sizeof(ShadeResult), "HashShadeResult");
*hashshr= ssamp->shr[0];
@@ -666,8 +675,9 @@ static void strand_render(Render *re, StrandSegment *sseg, float winmat[][4], St
obi= sseg->obi - re->objectinstance;
index= sseg->strand->index;
- projectvert(p1->co, winmat, hoco1);
- projectvert(p2->co, winmat, hoco2);
+ projectvert(p1->co, winmat, hoco1);
+ projectvert(p2->co, winmat, hoco2);
+
for(a=0; a<totzspan; a++) {
#if 0
@@ -855,7 +865,7 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBa
else if(!shadow && (ma->mode & MA_ONLYCAST))
continue;
- if(clip_render_object(obi->obr->boundbox, bounds, winmat))
+ if(clip_render_object(obi->obr->boundbox, bounds, obwinmat))
continue;
widthx= obr->strandbuf->maxwidth*obwinmat[0][0];
@@ -864,7 +874,7 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBa
/* for each bounding box containing a number of strands */
sbound= obr->strandbuf->bound;
for(c=0; c<obr->strandbuf->totbound; c++, sbound++) {
- if(clip_render_object(sbound->boundbox, bounds, winmat))
+ if(clip_render_object(sbound->boundbox, bounds, obwinmat))
continue;
/* for each strand in this bounding box */
@@ -931,11 +941,6 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBa
obi= &re->objectinstance[sortseg->obi];
obr= obi->obr;
- if(obi->flag & R_TRANSFORMED)
- mul_m4_m4m4(obwinmat, obi->mat, winmat);
- else
- copy_m4_m4(obwinmat, winmat);
-
sseg.obi= obi;
sseg.strand= RE_findOrAddStrand(obr, sortseg->strand);
sseg.buffer= sseg.strand->buffer;
@@ -951,7 +956,7 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBa
spart.segment= &sseg;
- render_strand_segment(re, obwinmat, &spart, &zspan, 1, &sseg);
+ render_strand_segment(re, winmat, &spart, &zspan, 1, &sseg);
}
}
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 82ef6a1b80e..8748703ad8e 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -179,6 +179,7 @@ typedef struct wmNotifier {
#define ND_EDITOR_CHANGED (6<<16) /*sent to new editors after switching to them*/
#define ND_SCREENSET (7<<16)
#define ND_SKETCH (8<<16)
+#define ND_SUBWINACTIVE (9<<16)
/* NC_SCENE Scene */
#define ND_SCENEBROWSE (1<<16)
diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c
index 5951393a497..32a4648c7f8 100644
--- a/source/blender/windowmanager/intern/wm_cursors.c
+++ b/source/blender/windowmanager/intern/wm_cursors.c
@@ -47,6 +47,7 @@
#include "BKE_main.h"
#include "WM_api.h"
+#include "WM_types.h"
#include "wm_cursors.h"
/* XXX this still is mess from old code */
@@ -211,6 +212,29 @@ void WM_cursor_ungrab(wmWindow *win)
}
}
+/* give it a modal keymap one day? */
+int wm_cursor_arrow_move(wmWindow *win, wmEvent *event)
+{
+ if(win && event->val==KM_PRESS) {
+
+ if(event->type==UPARROWKEY) {
+ WM_cursor_warp(win, event->x, event->y+1);
+ return 1;
+ } else if(event->type==DOWNARROWKEY) {
+ WM_cursor_warp(win, event->x, event->y-1);
+ return 1;
+ } else if(event->type==LEFTARROWKEY) {
+ WM_cursor_warp(win, event->x-1, event->y);
+ return 1;
+ } else if(event->type==RIGHTARROWKEY) {
+ WM_cursor_warp(win, event->x+1, event->y);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
/* afer this you can call restore too */
void WM_timecursor(wmWindow *win, int nr)
{
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 4268f192821..e7bbdf07407 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -183,6 +183,7 @@ void wm_event_do_notifiers(bContext *C)
wmWindowManager *wm= CTX_wm_manager(C);
wmNotifier *note, *next;
wmWindow *win;
+ unsigned int win_combine_v3d_datamask= 0;
if(wm==NULL)
return;
@@ -270,7 +271,7 @@ void wm_event_do_notifiers(bContext *C)
CTX_wm_window_set(C, win);
/* printf("notifier win %d screen %s cat %x\n", win->winid, win->screen->id.name+2, note->category); */
- ED_screen_do_listen(win, note);
+ ED_screen_do_listen(C, note);
for(ar=win->screen->regionbase.first; ar; ar= ar->next) {
ED_region_do_listen(ar, note);
@@ -288,6 +289,11 @@ void wm_event_do_notifiers(bContext *C)
MEM_freeN(note);
}
+ /* combine datamasks so 1 win doesn't disable UV's in another [#26448] */
+ for(win= wm->windows.first; win; win= win->next) {
+ win_combine_v3d_datamask |= ED_viewedit_datamask(win->screen);
+ }
+
/* cached: editor refresh callbacks now, they get context */
for(win= wm->windows.first; win; win= win->next) {
ScrArea *sa;
@@ -305,7 +311,7 @@ void wm_event_do_notifiers(bContext *C)
/* depsgraph & animation: update tagged datablocks */
/* copied to set's in scene_update_tagged_recursive() */
- win->screen->scene->customdata_mask= ED_viewedit_datamask(win->screen);
+ win->screen->scene->customdata_mask= win_combine_v3d_datamask;
scene_update_tagged(CTX_data_main(C), win->screen->scene);
}
@@ -1557,6 +1563,9 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
}
}
}
+
+ if(action == (WM_HANDLER_BREAK|WM_HANDLER_MODAL))
+ wm_cursor_arrow_move(CTX_wm_window(C), event);
return action;
}
@@ -1735,14 +1744,6 @@ void wm_event_do_handlers(bContext *C)
CTX_wm_area_set(C, area_event_inside(C, event->x, event->y));
CTX_wm_region_set(C, region_event_inside(C, event->x, event->y));
- /* XXX to solve, here screen handlers? */
- if(event->type==MOUSEMOVE) {
- /* state variables in screen, cursors, also used in wm_draw.c */
- ED_screen_set_subwinactive(win, event);
- /* for regions having custom cursors */
- wm_paintcursor_test(C, event);
- }
-
/* MVC demands to not draw in event handlers... but we need to leave it for ogl selecting etc */
wm_window_make_drawable(C, win);
@@ -1764,6 +1765,14 @@ void wm_event_do_handlers(bContext *C)
ARegion *ar;
int doit= 0;
+ /* Note: setting subwin active should be done here, after modal handlers have been done */
+ if(event->type==MOUSEMOVE) {
+ /* state variables in screen, cursors. Also used in wm_draw.c, fails for modal handlers though */
+ ED_screen_set_subwinactive(C, event);
+ /* for regions having custom cursors */
+ wm_paintcursor_test(C, event);
+ }
+
for(sa= win->screen->areabase.first; sa; sa= sa->next) {
if(wm_event_inside_i(event, &sa->totrct)) {
CTX_wm_area_set(C, sa);
@@ -1939,11 +1948,13 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
WM_event_fileselect_event(C, op, full?EVT_FILESELECT_FULL_OPEN:EVT_FILESELECT_OPEN);
}
+#if 0
/* lets not expose struct outside wm? */
static void WM_event_set_handler_flag(wmEventHandler *handler, int flag)
{
handler->flag= flag;
}
+#endif
wmEventHandler *WM_event_add_modal_handler(bContext *C, wmOperator *op)
{
@@ -2089,11 +2100,13 @@ void WM_event_remove_area_handler(ListBase *handlers, void *area)
}
}
+#if 0
static void WM_event_remove_handler(ListBase *handlers, wmEventHandler *handler)
{
BLI_remlink(handlers, handler);
wm_event_free_handler(handler);
}
+#endif
void WM_event_add_mousemove(bContext *C)
{
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 141c51adc58..48528574f7e 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -569,6 +569,7 @@ static ImBuf *blend_file_thumb(Scene *scene, int **thumb_pt)
/* will be scaled down, but gives some nice oversampling */
ImBuf *ibuf;
int *thumb;
+ char err_out[256]= "unknown";
*thumb_pt= NULL;
@@ -576,7 +577,7 @@ static ImBuf *blend_file_thumb(Scene *scene, int **thumb_pt)
return NULL;
/* gets scaled to BLEN_THUMB_SIZE */
- ibuf= ED_view3d_draw_offscreen_imbuf_simple(scene, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, IB_rect, OB_SOLID);
+ ibuf= ED_view3d_draw_offscreen_imbuf_simple(scene, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, IB_rect, OB_SOLID, err_out);
if(ibuf) {
float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp);
@@ -597,6 +598,7 @@ static ImBuf *blend_file_thumb(Scene *scene, int **thumb_pt)
}
else {
/* '*thumb_pt' needs to stay NULL to prevent a bad thumbnail from being handled */
+ fprintf(stderr, "blend_file_thumb failed to create thumbnail: %s\n", err_out);
thumb= NULL;
}
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index b46f5f34271..27276e2aaac 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -940,7 +940,6 @@ static uiBlock *wm_block_create_dialog(bContext *C, ARegion *ar, void *userData)
wmOperator *op= data->op;
uiBlock *block;
uiLayout *layout;
- uiBut *btn;
uiStyle *style= U.uistyles.first;
block = uiBeginBlock(C, ar, "operator dialog", UI_EMBOSS);
@@ -956,9 +955,18 @@ static uiBlock *wm_block_create_dialog(bContext *C, ARegion *ar, void *userData)
/* clear so the OK button is left alone */
uiBlockSetFunc(block, NULL, NULL, NULL);
- /* Create OK button, the callback of which will execute op */
- btn= uiDefBut(block, BUT, 0, "OK", 0, 0, 0, 20, NULL, 0, 0, 0, 0, "");
- uiButSetFunc(btn, dialog_exec_cb, op, block);
+ /* new column so as not to interfear with custom layouts [#26436] */
+ {
+ uiBlock *col_block;
+ uiLayout *col;
+ uiBut *btn;
+
+ col= uiLayoutColumn(layout, FALSE);
+ col_block= uiLayoutGetBlock(col);
+ /* Create OK button, the callback of which will execute op */
+ btn= uiDefBut(col_block, BUT, 0, "OK", 0, -30, 0, 20, NULL, 0, 0, 0, 0, "");
+ uiButSetFunc(btn, dialog_exec_cb, op, col_block);
+ }
/* center around the mouse */
uiPopupBoundsBlock(block, 4.0f, data->width/-2, data->height/2);
@@ -1480,21 +1488,6 @@ static short wm_link_append_flag(wmOperator *op)
return flag;
}
-static void wm_link_make_library_local(Main *main, const char *libname)
-{
- Library *lib;
-
- /* and now find the latest append lib file */
- for(lib= main->library.first; lib; lib=lib->id.next)
- if(BLI_streq(libname, lib->filepath))
- break;
-
- /* make local */
- if(lib) {
- all_local(lib, 1);
- }
-}
-
static int wm_link_append_exec(bContext *C, wmOperator *op)
{
Main *bmain= CTX_data_main(C);
@@ -1540,12 +1533,23 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
+ bh = BLO_blendhandle_from_file(libname, op->reports);
+
+ if(bh == NULL) {
+ /* unlikely since we just browsed it, but possible
+ * error reports will have been made by BLO_blendhandle_from_file() */
+ return OPERATOR_CANCELLED;
+ }
+
+
+ /* from here down, no error returns */
+
+ idcode = BKE_idcode_from_name(group);
+
/* now we have or selected, or an indicated file */
if(RNA_boolean_get(op->ptr, "autoselect"))
scene_deselect_all(scene);
- bh = BLO_blendhandle_from_file(libname);
- idcode = BKE_idcode_from_name(group);
flag = wm_link_append_flag(op);
@@ -1581,8 +1585,11 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
recalc_all_library_objects(bmain);
/* append, rather than linking */
- if((flag & FILE_LINK)==0)
- wm_link_make_library_local(bmain, libname);
+ if((flag & FILE_LINK)==0) {
+ Library *lib= BLI_findstring(&bmain->library, libname, offsetof(Library, filepath));
+ if(lib) all_local(lib, 1);
+ else BLI_assert(!"cant find name of just added library!");
+ }
/* important we unset, otherwise these object wont
* link into other scenes from this blend file */
diff --git a/source/blender/windowmanager/wm_cursors.h b/source/blender/windowmanager/wm_cursors.h
index c858b9d94f3..5f262f34724 100644
--- a/source/blender/windowmanager/wm_cursors.h
+++ b/source/blender/windowmanager/wm_cursors.h
@@ -116,5 +116,11 @@ enum {
#define SMALL_CURSOR 0
#define BIG_CURSOR 1
+struct wmWindow;
+struct wmEvent;
+
+int wm_cursor_arrow_move(struct wmWindow *win, struct wmEvent *event);
+
+
#endif /* WM_CURSORS_H */
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index 83ee6a4cb88..49712a70799 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -149,7 +149,7 @@ if(WITH_BUILDINFO)
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/buildinfo.h
PROPERTIES GENERATED TRUE
HEADER_FILE_ONLY TRUE)
-
+
# add deps below, after adding blender
# -------------- done with header values.
@@ -182,293 +182,366 @@ endif()
# Post build steps for bundling/packaging.
-set(TARGETDIR ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR})
+
+if(MSVC)
+ # ${CMAKE_CFG_INTDIR} should replace \${BUILD_TYPE} when using add_command
+ set(TARGETDIR ${EXECUTABLE_OUTPUT_PATH}/\${BUILD_TYPE})
+elseif(APPLE)
+ set(TARGETDIR ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR})
+else()
+ set(TARGETDIR ${EXECUTABLE_OUTPUT_PATH})
+endif()
if(WITH_INSTALL)
- if(UNIX)
- add_custom_command(TARGET blender
- POST_BUILD
- MAIN_DEPENDENCY blender
- #COMMAND cp -R ${CMAKE_SOURCE_DIR}/release/plugins ${TARGETDIR}/
- #COMMAND cp -R ${CMAKE_SOURCE_DIR}/release/text/* ${TARGETDIR}/
+ if(UNIX AND NOT APPLE)
+
+ if(WITH_INSTALL_PORTABLE)
+ set(TARGETDIR_VER ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/${BLENDER_VERSION})
+ else()
+ set(TARGETDIR_VER ${CMAKE_INSTALL_PREFIX}/share/blender/${BLENDER_VERSION})
+ endif()
+
+ # important to make a clean install each time
+ # else old scripts get loaded.
+ install(
+ CODE
+ "file(REMOVE_RECURSE ${TARGETDIR_VER})"
)
- endif()
- if(UNIX AND NOT APPLE)
-
- # Local installation, "make install" can be done after this optionally
-
+ # message after building.
add_custom_command(
TARGET blender POST_BUILD MAIN_DEPENDENCY blender
- COMMAND rm -Rf ${TARGETDIR}/${BLENDER_VERSION}
- COMMAND mkdir ${TARGETDIR}/${BLENDER_VERSION}/
- COMMAND cp ${CMAKE_SOURCE_DIR}/release/bin/.blender/.bfont.ttf ${TARGETDIR}/${BLENDER_VERSION}/
+ COMMAND ${CMAKE_COMMAND} -E echo 'now run: \"make install\" to copy runtime files & scripts to ${TARGETDIR_VER}'
+ )
+
+ # there are a few differences between portable and system install
+ if(WITH_INSTALL_PORTABLE)
+ install(
+ FILES
+ ${CMAKE_SOURCE_DIR}/release/freedesktop/blender.desktop
+ ${CMAKE_SOURCE_DIR}/release/freedesktop/icons/scalable/blender.svg
+ ${CMAKE_SOURCE_DIR}/doc/manpage/blender.1
+ DESTINATION ${TARGETDIR}
+ )
+
+ install(
+ PROGRAMS
+ ${CMAKE_SOURCE_DIR}/release/bin/blender-thumbnailer.py
+ DESTINATION ${TARGETDIR}
+ )
+
+ install(
+ DIRECTORY ${CMAKE_SOURCE_DIR}/release/text/
+ DESTINATION ${TARGETDIR}
+ PATTERN ".svn" EXCLUDE
+ )
+
+ else()
+ # main blender binary
+ install(
+ PROGRAMS ${TARGETDIR}/blender
+ DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
+ )
+
+ if(WITH_GAMEENGINE AND WITH_PLAYER)
+ install(
+ PROGRAMS ${TARGETDIR}/blenderplayer
+ DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
+ )
+ endif()
+
+ # misc files
+ install(
+ FILES ${CMAKE_SOURCE_DIR}/release/freedesktop/blender.desktop
+ DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications
+ )
+ install(
+ FILES ${CMAKE_SOURCE_DIR}/release/freedesktop/icons/scalable/blender.svg
+ DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pixmaps
+ )
+ install(
+ PROGRAMS ${CMAKE_SOURCE_DIR}/release/bin/blender-thumbnailer.py
+ DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
+ )
+ install(
+ FILES ${CMAKE_SOURCE_DIR}/doc/manpage/blender.1
+ DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1
+ )
+ install(
+ DIRECTORY ${CMAKE_SOURCE_DIR}/release/text/
+ DESTINATION ${CMAKE_INSTALL_PREFIX}/share/doc/blender
+ PATTERN ".svn" EXCLUDE
+ )
+ endif()
+
+ install(
+ FILES ${CMAKE_SOURCE_DIR}/release/bin/.blender/.bfont.ttf
+ DESTINATION ${TARGETDIR_VER}/config
)
-
+
if(WITH_INTERNATIONAL)
- add_custom_command(
- TARGET blender POST_BUILD MAIN_DEPENDENCY blender
- COMMAND cp ${CMAKE_SOURCE_DIR}/release/bin/.blender/.Blanguages ${TARGETDIR}/${BLENDER_VERSION}/
- COMMAND cp -R ${CMAKE_SOURCE_DIR}/release/bin/.blender/locale ${TARGETDIR}/${BLENDER_VERSION}/
+ install(
+ FILES ${CMAKE_SOURCE_DIR}/release/bin/.blender/.Blanguages
+ DESTINATION ${TARGETDIR_VER}/config
+ )
+
+ install(
+ DIRECTORY ${CMAKE_SOURCE_DIR}/release/bin/.blender/locale
+ DESTINATION ${TARGETDIR_VER}/datafiles/
+ PATTERN ".svn" EXCLUDE
)
endif()
-
+
+ # plugins in blender 2.5 don't work at the moment.
+ #
+ # install(
+ # DIRECTORY ${CMAKE_SOURCE_DIR}/release/plugins
+ # DESTINATION ${TARGETDIR_VER}/
+ # PATTERN ".svn" EXCLUDE
+ # )
+
if(WITH_PYTHON)
- add_custom_command(
- TARGET blender POST_BUILD MAIN_DEPENDENCY blender
- COMMENT "copying blender scripts..."
- COMMAND cp -R ${CMAKE_SOURCE_DIR}/release/scripts ${TARGETDIR}/${BLENDER_VERSION}/
- COMMAND find ${TARGETDIR} -name '*.py[co]' -prune -exec rm -rf {} '\;'
- COMMAND find ${TARGETDIR} -name '__pycache__' -exec rmdir {} '+'
+ # install(CODE "message(\"copying blender scripts...\")")
+ install(
+ DIRECTORY ${CMAKE_SOURCE_DIR}/release/scripts
+ DESTINATION ${TARGETDIR_VER}/
+ PATTERN ".svn" EXCLUDE
+ PATTERN "__pycache__" EXCLUDE
)
+
if(WITH_PYTHON_INSTALL)
# Copy the systems python into the install directory
# Scons copy in tools/Blender.py
- add_custom_command(
- TARGET blender POST_BUILD MAIN_DEPENDENCY blender
- COMMENT "copying a subset of the systems python..."
-
- COMMAND mkdir ${TARGETDIR}/${BLENDER_VERSION}/python # PYTHONPATH and PYTHONHOME is set here
- COMMAND mkdir ${TARGETDIR}/${BLENDER_VERSION}/python/lib/
- COMMAND cp -R ${PYTHON_LIBPATH}/python${PYTHON_VERSION} ${TARGETDIR}/${BLENDER_VERSION}/python/lib/
-
- COMMAND rm -rf ${TARGETDIR}/${BLENDER_VERSION}/python/lib/python${PYTHON_VERSION}/distutils
- COMMAND rm -rf ${TARGETDIR}/${BLENDER_VERSION}/python/lib/python${PYTHON_VERSION}/lib2to3
- COMMAND rm -rf ${TARGETDIR}/${BLENDER_VERSION}/python/lib/python${PYTHON_VERSION}/idlelib
- COMMAND rm -rf ${TARGETDIR}/${BLENDER_VERSION}/python/lib/python${PYTHON_VERSION}/tkinter
- COMMAND rm -rf ${TARGETDIR}/${BLENDER_VERSION}/python/lib/python${PYTHON_VERSION}/config
-
- COMMAND rm -rf ${TARGETDIR}/${BLENDER_VERSION}/python/lib/python${PYTHON_VERSION}/site-packages
- COMMAND mkdir ${TARGETDIR}/${BLENDER_VERSION}/python/lib/python${PYTHON_VERSION}/site-packages # python needs it.
-
- COMMAND rm -f ${TARGETDIR}/${BLENDER_VERSION}/python/lib/python${PYTHON_VERSION}/lib-dynload/_tkinter.so
- COMMAND find ${TARGETDIR}/${BLENDER_VERSION}/python/lib/python${PYTHON_VERSION} -type d -name 'test' -prune -exec rm -rf {} '\;'
- COMMAND find ${TARGETDIR}/${BLENDER_VERSION}/python/lib/python${PYTHON_VERSION} -type d -name 'turtledemo' -prune -exec rm -rf {} '\;'
- COMMAND find ${TARGETDIR}/${BLENDER_VERSION}/python/lib/python${PYTHON_VERSION} -type d -name 'config-*' -prune -exec rm -rf {} '\;'
- COMMAND find ${TARGETDIR}/${BLENDER_VERSION}/python/lib/python${PYTHON_VERSION} -name '*.py[co]' -exec rm -rf {} '\;'
- COMMAND find ${TARGETDIR}/${BLENDER_VERSION}/python/lib/python${PYTHON_VERSION} -name '__pycache__' -exec rmdir {} '+'
- COMMAND find ${TARGETDIR}/${BLENDER_VERSION}/python/lib/python${PYTHON_VERSION} -name '*.so' -exec strip -s {} '\;'
+ # install(CODE "message(\"copying a subset of the systems python...\")")
+ install(
+ DIRECTORY ${PYTHON_LIBPATH}/python${PYTHON_VERSION}
+ DESTINATION ${TARGETDIR_VER}/python/lib/
+ PATTERN ".svn" EXCLUDE
+ PATTERN "__pycache__" EXCLUDE # ./distutils
+ PATTERN "distutils" EXCLUDE # ./distutils
+ PATTERN "lib2to3" EXCLUDE # ./lib2to3
+ PATTERN "config" EXCLUDE # ./config
+ PATTERN "config-*" EXCLUDE # ./config-*
+ PATTERN "site-packages/*" EXCLUDE # ./site-packages/*
+ PATTERN "tkinter" EXCLUDE # ./tkinter
+ PATTERN "lib-dynload/_tkinter.*" EXCLUDE # ./lib-dynload/_tkinter.co
+ PATTERN "test" EXCLUDE # ./test
+ PATTERN "turtledemo" EXCLUDE # ./turtledemo
)
+
+ # # doesnt work, todo
+ # install(CODE "execute_process(COMMAND find ${TARGETDIR}/${BLENDER_VERSION}/python/lib/ -name '*.so' -exec strip -s {} '\;')")
endif()
endif()
-
- add_custom_command(
- TARGET blender POST_BUILD MAIN_DEPENDENCY blender
- COMMAND find ${TARGETDIR} -name .svn -prune -exec rm -rf {} "\;"
- )
-
-
- # Above we bundle a portable distribution in ./bin
- # This is an optional "make install" which installs blender on the system.
- install(
- PROGRAMS ${TARGETDIR}/blender
- DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
- )
+ elseif(WIN32)
- if(WITH_GAMEENGINE AND WITH_PLAYER)
- install(
- PROGRAMS ${TARGETDIR}/blenderplayer
- DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
- )
- endif()
+ set(TARGETDIR_VER ${TARGETDIR}/${BLENDER_VERSION})
- install(
- FILES ${CMAKE_SOURCE_DIR}/release/freedesktop/blender.desktop
- DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications
- )
- install(
- FILES ${CMAKE_SOURCE_DIR}/release/freedesktop/icons/scalable/blender.svg
- DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pixmaps
+ install( # same as linux!, deduplicate
+ CODE
+ "file(REMOVE_RECURSE ${TARGETDIR_VER})"
)
- install(
- PROGRAMS ${CMAKE_SOURCE_DIR}/release/bin/blender-thumbnailer.py
- DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
- )
- install(
- FILES ${CMAKE_SOURCE_DIR}/doc/manpage/blender.1
- DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1
- )
- install(
+
+ install( # same as linux!, deduplicate
DIRECTORY ${CMAKE_SOURCE_DIR}/release/text/
- DESTINATION ${CMAKE_INSTALL_PREFIX}/share/doc/blender
+ DESTINATION ${TARGETDIR}/
PATTERN ".svn" EXCLUDE
)
- install(
- DIRECTORY ${CMAKE_SOURCE_DIR}/release/scripts/
- DESTINATION ${CMAKE_INSTALL_PREFIX}/share/blender/${BLENDER_VERSION}/scripts
- PATTERN ".svn" EXCLUDE
- PATTERN "*.pyc" EXCLUDE
- PATTERN "__pycache__" EXCLUDE
- )
- install(
- DIRECTORY ${CMAKE_SOURCE_DIR}/release/datafiles/brushicons/
- DESTINATION ${CMAKE_INSTALL_PREFIX}/share/blender/${BLENDER_VERSION}/datafiles/brushicons
- PATTERN ".svn" EXCLUDE
+
+ install( # same as linux!, deduplicate
+ FILES ${CMAKE_SOURCE_DIR}/release/bin/.blender/.bfont.ttf
+ DESTINATION ${TARGETDIR_VER}/config
)
- if(WITH_INTERNATIONAL)
+
+ if(WITH_INTERNATIONAL) # same as linux!, deduplicate
install(
- DIRECTORY ${CMAKE_SOURCE_DIR}/release/bin/.blender/locale/
- DESTINATION ${CMAKE_INSTALL_PREFIX}/share/blender/${BLENDER_VERSION}/datafiles/locale
+ FILES ${CMAKE_SOURCE_DIR}/release/bin/.blender/.Blanguages
+ DESTINATION ${TARGETDIR_VER}/config
+ )
+ install(
+ DIRECTORY ${CMAKE_SOURCE_DIR}/release/bin/.blender/locale
+ DESTINATION ${TARGETDIR_VER}/datafiles/
PATTERN ".svn" EXCLUDE
)
+
+ if(NOT CMAKE_CL_64)
+ install(
+ FILES ${LIBDIR}/gettext/lib/gnu_gettext.dll
+ DESTINATION ${TARGETDIR}/
+ )
+
+ install(
+ FILES ${LIBDIR}/iconv/lib/iconv.dll
+ DESTINATION ${TARGETDIR}/
+ )
+ endif()
endif()
-
- # end "make install"
-
- elseif(WIN32)
- # notice 'xcopy /Y /H' on .bfont.ttf, this is needed when building over samba
- add_custom_command(TARGET blender
- POST_BUILD
- MAIN_DEPENDENCY blender
- COMMAND if not exist \"${TARGETDIR}\\${BLENDER_VERSION}\" mkdir \"${TARGETDIR}\\${BLENDER_VERSION}\"
- COMMAND if not exist \"${TARGETDIR}\\${BLENDER_VERSION}\\scripts\" mkdir \"${TARGETDIR}\\${BLENDER_VERSION}\\scripts\"
- COMMAND if not exist \"${TARGETDIR}\\${BLENDER_VERSION}\\config\" mkdir \"${TARGETDIR}\\${BLENDER_VERSION}\\config\"
- COMMAND if not exist \"${TARGETDIR}\\plugins\" mkdir \"${TARGETDIR}\\plugins\"
- COMMAND xcopy /Y /H \"${CMAKE_SOURCE_DIR}\\release\\bin\\.blender\\.bfont.ttf\" \"${TARGETDIR}\\${BLENDER_VERSION}\\config\\\"
- COMMAND xcopy /E /Y \"${CMAKE_SOURCE_DIR}\\release\\scripts\\*.*\" \"${TARGETDIR}\\${BLENDER_VERSION}\\scripts\\\"
- COMMAND xcopy /E /Y \"${CMAKE_SOURCE_DIR}\\release\\plugins\\*.*\" \"${TARGETDIR}\\${BLENDER_VERSION}\\plugins\\\"
- COMMAND copy /Y \"${CMAKE_SOURCE_DIR}\\release\\text\\*.*\" \"${TARGETDIR}\\\"
+
+ install( # same as linux!, deduplicate
+ DIRECTORY ${CMAKE_SOURCE_DIR}/release/bin/.blender/locale/
+ DESTINATION ${TARGETDIR_VER}/datafiles/locale
+ PATTERN ".svn" EXCLUDE
)
-
+
+ # plugins in blender 2.5 don't work at the moment.
+ #
+ # install(
+ # DIRECTORY ${CMAKE_SOURCE_DIR}/release/plugins
+ # DESTINATION ${TARGETDIR_VER}/
+ # PATTERN ".svn" EXCLUDE
+ # )
+
+ if(WITH_PYTHON)
+ # install(CODE "message(\"copying blender scripts...\")")
+ install( # same as linux!, deduplicate
+ DIRECTORY ${CMAKE_SOURCE_DIR}/release/scripts
+ DESTINATION ${TARGETDIR_VER}/
+ PATTERN ".svn" EXCLUDE
+ PATTERN "__pycache__" EXCLUDE
+ )
+
+ # TODO, multiple targets?
+ install(FILES ${LIBDIR}/python/lib/python32.dll DESTINATION ${TARGETDIR}/ CONFIGURATIONS Release)
+ install(FILES ${LIBDIR}/python/lib/python32.dll DESTINATION ${TARGETDIR}/ CONFIGURATIONS RelWithDebInfo)
+ install(FILES ${LIBDIR}/python/lib/python32.dll DESTINATION ${TARGETDIR}/ CONFIGURATIONS MinSizeRel)
+
+ install(
+ FILES ${LIBDIR}/python/lib/python32_d.dll
+ DESTINATION ${TARGETDIR}/
+ CONFIGURATIONS Debug
+ )
+
+ if(WITH_PYTHON_INSTALL)
+ #~ # note, as far as python is concerned 'RelWithDebInfo' is not debug since its without debug flags.
+
+ # create the directory in multiple steps, so it actually gets created when it doesn't exist yet
+ install(CODE "
+ message(\"creating ${TARGETDIR_VER}/python/lib\")
+ file(MAKE_DIRECTORY ${TARGETDIR_VER}/python/)
+ file(MAKE_DIRECTORY ${TARGETDIR_VER}/python/lib/)
+ message(\"done creating dir\")
+ ")
+
+ install(
+ CODE
+ "
+ execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \"${TARGETDIR_VER}/python/lib/\"
+ \"${CMAKE_COMMAND}\" -E tar xzfv \"${LIBDIR}/release/python32.tar.gz\")
+ "
+ CONFIGURATIONS Release
+ )
+ install(
+ CODE
+ "
+ execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \"${TARGETDIR_VER}/python/lib/\"
+ \"${CMAKE_COMMAND}\" -E tar xzfv \"${LIBDIR}/release/python32.tar.gz\")
+ "
+ CONFIGURATIONS RelWithDebInfo
+ )
+ install(
+ CODE
+ "
+ execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \"${TARGETDIR_VER}/python/lib/\"
+ \"${CMAKE_COMMAND}\" -E tar xzfv \"${LIBDIR}/release/python32.tar.gz\")
+ "
+ CONFIGURATIONS MinSizeRel
+ )
+ install(
+ CODE
+ "
+ execute_process(COMMAND \"${CMAKE_COMMAND}\" -E chdir \"${TARGETDIR_VER}/python/lib/\"
+ \"${CMAKE_COMMAND}\" -E tar xzfv \"${LIBDIR}/release/python32_d.tar.gz\")
+ "
+ CONFIGURATIONS Debug
+ )
+
+ # doesnt work, todo
+ # install(CODE "execute_process(COMMAND find ${TARGETDIR}/${BLENDER_VERSION}/python/lib/ -name '*.so' -exec strip -s {} '\;')")
+ endif()
+ endif()
+
if(CMAKE_CL_64)
# gettext and png are statically linked on win64
- add_custom_command(TARGET blender
- POST_BUILD
- MAIN_DEPENDENCY blender
- COMMAND copy /Y \"${LIBDIR}\\zlib\\lib\\zlib.dll\" \"${TARGETDIR}\\\"
+ install(
+ FILES ${LIBDIR}/zlib/lib/zlib.dll
+ DESTINATION ${TARGETDIR}/
)
else()
- add_custom_command(TARGET blender
- POST_BUILD
- MAIN_DEPENDENCY blender
- COMMAND copy /Y \"${LIBDIR}\\gettext\\lib\\gnu_gettext.dll\" \"${TARGETDIR}\\\"
- COMMAND copy /Y \"${LIBDIR}\\png\\lib\\libpng.dll\" \"${TARGETDIR}\\\"
- COMMAND copy /Y \"${LIBDIR}\\zlib\\lib\\zlib.dll\" \"${TARGETDIR}\\\"
+ install(
+ FILES
+ ${LIBDIR}/png/lib/libpng.dll
+ ${LIBDIR}/zlib/lib/zlib.dll
+ DESTINATION ${TARGETDIR}/
)
endif()
-
-
+
if(MSVC)
- add_custom_command(TARGET blender
- POST_BUILD
- MAIN_DEPENDENCY blender
- COMMAND copy /Y \"${LIBDIR}\\pthreads\\lib\\pthreadVC2.dll\" \"${TARGETDIR}\\\"
+ install(
+ FILES ${LIBDIR}/pthreads/lib/pthreadVC2.dll
+ DESTINATION ${TARGETDIR}/
)
else()
- add_custom_command(TARGET blender
- POST_BUILD
- MAIN_DEPENDENCY blender
- COMMAND copy /Y \"${LIBDIR}\\pthreads\\lib\\pthreadGC2.dll\" \"${TARGETDIR}\\\"
+ install(
+ FILES ${LIBDIR}/pthreads/lib/pthreadGC2.dll
+ DESTINATION ${TARGETDIR}/
)
endif()
- if(WITH_PYTHON)
- # note, as far as python is concerned 'RelWithDebInfo' is not debug since its without debug flags.
- if(NOT CMAKE_BUILD_TYPE) # hack: with multi-configuration generator this is "", so for now copy both python32.dll/zip and python32_d.dll/zip
- add_custom_command(TARGET blender
- POST_BUILD
- MAIN_DEPENDENCY blender
- COMMAND if not exist \"${TARGETDIR}\\${BLENDER_VERSION}\\python\\lib\" mkdir \"${TARGETDIR}\\${BLENDER_VERSION}\\python\\lib\"
- COMMAND if \"$(ConfigurationName)\" == \"\" copy /Y \"${LIBDIR}\\python\\lib\\python32.dll\" \"${TARGETDIR}\\\"
- COMMAND if \"$(ConfigurationName)\" == \"\" xcopy /E /Y \"${LIBDIR}\\release\\python32\\*.*\" \"${TARGETDIR}\\${BLENDER_VERSION}\\python\\lib\\\"
- COMMAND if \"$(ConfigurationName)\" == \"Debug\" copy /Y \"${LIBDIR}\\python\\lib\\python32_d.dll\" \"${TARGETDIR}\\\"
- COMMAND if \"$(ConfigurationName)\" == \"Debug\" xcopy /E /Y \"${LIBDIR}\\release\\python32_d\\*.*\" \"${TARGETDIR}\\${BLENDER_VERSION}\\python\\lib\\\"
- COMMAND if \"$(ConfigurationName)\" == \"RelWithDebInfo\" copy /Y \"${LIBDIR}\\python\\lib\\python32.dll\" \"${TARGETDIR}\\\"
- COMMAND if \"$(ConfigurationName)\" == \"RelWithDebInfo\" xcopy /E /Y \"${LIBDIR}\\release\\python32\\*.*\" \"${TARGETDIR}\\${BLENDER_VERSION}\\python\\lib\\\"
- COMMAND if \"$(ConfigurationName)\" == \"Release\" copy /Y \"${LIBDIR}\\python\\lib\\python32.dll\" \"${TARGETDIR}\\\"
- COMMAND if \"$(ConfigurationName)\" == \"Release\" xcopy /E /Y \"${LIBDIR}\\release\\python32\\*.*\" \"${TARGETDIR}\\${BLENDER_VERSION}\\python\\lib\\\"
- COMMAND if \"$(ConfigurationName)\" == \"MinSizeRel\" copy /Y \"${LIBDIR}\\python\\lib\\python32.dll\" \"${TARGETDIR}\\\"
- COMMAND if \"$(ConfigurationName)\" == \"MinSizeRel\" xcopy /E /Y \"${LIBDIR}\\release\\python32\\*.*\" \"${TARGETDIR}\\${BLENDER_VERSION}\\python\\lib\\\"
- )
- else()
- if(CMAKE_BUILD_TYPE STREQUAL Debug)
- add_custom_command(TARGET blender
- POST_BUILD
- MAIN_DEPENDENCY blender
- COMMAND copy /Y \"${LIBDIR}\\python\\lib\\python32_d.dll\" \"${TARGETDIR}\\\"
- COMMAND xcopy /E /Y \"${LIBDIR}\\release\\python32_d\\*.*\" \"${TARGETDIR}\\${BLENDER_VERSION}\\python\\lib\\\"
- )
- else()
- add_custom_command(TARGET blender
- POST_BUILD
- MAIN_DEPENDENCY blender
- COMMAND copy /Y \"${LIBDIR}\\python\\lib\\python32.dll\" \"${TARGETDIR}\\\"
- COMMAND xcopy /E /Y \"${LIBDIR}\\release\\python32\\*.*\" \"${TARGETDIR}\\${BLENDER_VERSION}\\python\\lib\\\"
- )
- endif()
- endif()
- endif()
-
- if(WITH_INTERNATIONAL)
- if(CMAKE_CL_64)
- # iconv is statically linked on win64
- add_custom_command(TARGET blender
- POST_BUILD
- MAIN_DEPENDENCY blender
- COMMAND if not exist \"${TARGETDIR}\\${BLENDER_VERSION}\\config\\locale\" mkdir \"${TARGETDIR}\\${BLENDER_VERSION}\\config\\locale\"
- COMMAND copy /Y \"${CMAKE_SOURCE_DIR}\\release\\bin\\.blender\\.Blanguages\" \"${TARGETDIR}\\${BLENDER_VERSION}\\config\\\"
- COMMAND xcopy /E /Y \"${CMAKE_SOURCE_DIR}\\release\\bin\\.blender\\locale\\*.*\" \"${TARGETDIR}\\${BLENDER_VERSION}\\config\\locale\\\"
- )
- else()
- add_custom_command(TARGET blender
- POST_BUILD
- MAIN_DEPENDENCY blender
- COMMAND copy /Y \"${LIBDIR}\\iconv\\lib\\iconv.dll\" \"${TARGETDIR}\\\"
- COMMAND if not exist \"${TARGETDIR}\\${BLENDER_VERSION}\\config\\locale\" mkdir \"${TARGETDIR}\\${BLENDER_VERSION}\\config\\locale\"
- COMMAND copy /Y \"${CMAKE_SOURCE_DIR}\\release\\bin\\.blender\\.Blanguages\" \"${TARGETDIR}\\${BLENDER_VERSION}\\config\\\"
- COMMAND xcopy /E /Y \"${CMAKE_SOURCE_DIR}\\release\\bin\\.blender\\locale\\*.*\" \"${TARGETDIR}\\${BLENDER_VERSION}\\config\\locale\\\"
- )
- endif()
- endif()
-
if(WITH_CODEC_FFMPEG)
- add_custom_command(TARGET blender
- POST_BUILD
- MAIN_DEPENDENCY blender
- COMMAND copy /Y \"${LIBDIR}\\ffmpeg\\lib\\avcodec-52.dll\" \"${TARGETDIR}\\\"
- COMMAND copy /Y \"${LIBDIR}\\ffmpeg\\lib\\avformat-52.dll\" \"${TARGETDIR}\\\"
- COMMAND copy /Y \"${LIBDIR}\\ffmpeg\\lib\\avdevice-52.dll\" \"${TARGETDIR}\\\"
- COMMAND copy /Y \"${LIBDIR}\\ffmpeg\\lib\\avutil-50.dll\" \"${TARGETDIR}\\\"
- COMMAND copy /Y \"${LIBDIR}\\ffmpeg\\lib\\swscale-0.dll\" \"${TARGETDIR}\\\"
+ install(
+ FILES
+ ${LIBDIR}/ffmpeg/lib/avcodec-52.dll
+ ${LIBDIR}/ffmpeg/lib/avformat-52.dll
+ ${LIBDIR}/ffmpeg/lib/avdevice-52.dll
+ ${LIBDIR}/ffmpeg/lib/avutil-50.dll
+ ${LIBDIR}/ffmpeg/lib/swscale-0.dll
+ DESTINATION ${TARGETDIR}/
)
+
endif()
if(WITH_CODEC_SNDFILE)
- add_custom_command(TARGET blender
- POST_BUILD
- MAIN_DEPENDENCY blender
- COMMAND copy /Y \"${LIBDIR}\\sndfile\\lib\\libsndfile-1.dll\" \"${TARGETDIR}\\\"
+ install(
+ FILES
+ ${LIBDIR}/sndfile/lib/libsndfile-1.dll
+ DESTINATION ${TARGETDIR}/
)
endif()
if(WITH_OPENAL)
- add_custom_command(TARGET blender
- POST_BUILD
- MAIN_DEPENDENCY blender
- COMMAND copy /Y \"${LIBDIR}\\openal\\lib\\OpenAL32.dll\" \"${TARGETDIR}\\\"
- COMMAND copy /Y \"${LIBDIR}\\openal\\lib\\wrap_oal.dll\" \"${TARGETDIR}\\\"
-
+ install(
+ FILES
+ ${LIBDIR}/openal/lib/OpenAL32.dll
+ ${LIBDIR}/openal/lib/wrap_oal.dll
+ DESTINATION ${TARGETDIR}/
)
endif()
if(WITH_SDL)
if(NOT CMAKE_CL_64)
- add_custom_command(TARGET blender
- POST_BUILD
- MAIN_DEPENDENCY blender
- COMMAND copy /Y \"${LIBDIR}\\sdl\\lib\\SDL.dll\" \"${TARGETDIR}\\\"
+ install(
+ FILES
+ ${LIBDIR}/sdl/lib/SDL.dll
+ DESTINATION ${TARGETDIR}/
)
endif()
endif()
elseif(APPLE)
+ # TODO, APPLE needs a 'make install' target like win32 and unix
+
set(SOURCEDIR ${CMAKE_SOURCE_DIR}/source/darwin/blender.app)
set(SOURCEINFO ${SOURCEDIR}/Contents/Info.plist)
set(TARGETINFO ${TARGETDIR}/blender.app/Contents/Info.plist)
add_custom_command(
TARGET blender POST_BUILD MAIN_DEPENDENCY blender
+ COMMAND cp -R ${CMAKE_SOURCE_DIR}/release/text/* ${TARGETDIR}/
+ )
+
+ add_custom_command(
+ TARGET blender POST_BUILD MAIN_DEPENDENCY blender
COMMAND cp -Rf ${SOURCEINFO} ${TARGETDIR}/blender.app/Contents/
COMMAND cp -Rf ${SOURCEDIR}/Contents/PkgInfo ${TARGETDIR}/blender.app/Contents/
COMMAND cp -Rf ${SOURCEDIR}/Contents/Resources ${TARGETDIR}/blender.app/Contents/
@@ -478,7 +551,7 @@ if(WITH_INSTALL)
COMMAND mkdir ${TARGETDIR}/blender.app/Contents/MacOS/${BLENDER_VERSION}/datafiles/
COMMAND cp ${CMAKE_SOURCE_DIR}/release/bin/.blender/.bfont.ttf ${TARGETDIR}/blender.app/Contents/MacOS/${BLENDER_VERSION}/datafiles/
)
-
+
if(WITH_INTERNATIONAL)
add_custom_command(
TARGET blender POST_BUILD MAIN_DEPENDENCY blender
@@ -486,7 +559,7 @@ if(WITH_INSTALL)
COMMAND cp -Rf ${CMAKE_SOURCE_DIR}/release/bin/.blender/locale ${TARGETDIR}/blender.app/Contents/MacOS/${BLENDER_VERSION}/datafiles/
)
endif()
-
+
if(WITH_PYTHON)
set(PYTHON_ZIP "python_${CMAKE_OSX_ARCHITECTURES}.zip")
add_custom_command(
@@ -497,10 +570,10 @@ if(WITH_INSTALL)
COMMAND find ${TARGETDIR}/blender.app -name '*.py[co]' -prune -exec rm -rf {} '\;'
COMMAND find ${TARGETDIR}/blender.app -name '__pycache__' -exec rmdir {} '+'
)
- endif()
-
+ endif()
+
add_custom_command(
- TARGET blender POST_BUILD MAIN_DEPENDENCY blender
+ TARGET blender POST_BUILD MAIN_DEPENDENCY blender
COMMAND find ${TARGETDIR}/blender.app -name .DS_Store -prune -exec rm -rf {} "\;"
COMMAND find ${TARGETDIR}/blender.app -name .svn -prune -exec rm -rf {} "\;"
COMMAND find ${TARGETDIR}/blender.app -name __MACOSX -prune -exec rm -rf {} "\;"
@@ -563,10 +636,10 @@ endif()
bf_editor_animation
bf_editor_datafiles
- bf_render
- bf_intern_opennl
- bf_python
- bf_python_ext
+ bf_render
+ bf_intern_opennl
+ bf_python
+ bf_python_ext
bf_freestyle
bf_ikplugin
bf_modifiers
@@ -577,44 +650,44 @@ endif()
bf_blenlib
bf_intern_ghost
bf_intern_string
- bf_blenpluginapi
- bf_imbuf
- bf_avi
- bf_imbuf_cineon
- bf_imbuf_openexr
+ bf_blenpluginapi
+ bf_imbuf
+ bf_avi
+ bf_imbuf_cineon
+ bf_imbuf_openexr
bf_imbuf_dds
bf_readblenfile
bf_collada
- bf_intern_bsp
- bf_intern_bop
- bf_gen_system
- bf_intern_decimate
- bf_intern_elbeem
- bf_intern_ik
- bf_intern_memutil
- bf_intern_guardedalloc
- bf_intern_ctr
- ge_blen_routines
- ge_converter
+ bf_intern_bsp
+ bf_intern_bop
+ bf_gen_system
+ bf_intern_decimate
+ bf_intern_elbeem
+ bf_intern_ik
+ bf_intern_memutil
+ bf_intern_guardedalloc
+ bf_intern_ctr
+ ge_blen_routines
+ ge_converter
ge_phys_dummy
- ge_phys_bullet
+ ge_phys_bullet
bf_intern_smoke
extern_minilzo
extern_lzma
- ge_logic_ketsji
+ ge_logic_ketsji
ge_phys_common
- ge_logic
- ge_rasterizer
- ge_oglrasterizer
- ge_logic_expressions
- ge_scenegraph
- ge_logic_network
+ ge_logic
+ ge_rasterizer
+ ge_oglrasterizer
+ ge_logic_expressions
+ ge_scenegraph
+ ge_logic_network
bf_gen_system
bf_python # duplicate for BPY_driver_exec
- ge_logic_ngnetwork
- extern_bullet
- ge_logic_loopbacknetwork
- bf_intern_moto
+ ge_logic_ngnetwork
+ extern_bullet
+ ge_logic_loopbacknetwork
+ bf_intern_moto
extern_glew
extern_openjpeg
extern_redcode
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
index 9dd63fa3089..ded72b45b81 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
@@ -33,7 +33,7 @@
#include "KX_BlenderCanvas.h"
#include "DNA_screen_types.h"
-#include "stdio.h"
+#include <stdio.h>
KX_BlenderCanvas::KX_BlenderCanvas(struct wmWindow *win, RAS_Rect &rect, struct ARegion *ar) :
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
index a98fe87a0ef..0aee105b961 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
@@ -942,7 +942,7 @@ bool KX_BlenderSceneConverter::LinkBlendFileMemory(void *data, int length, const
bool KX_BlenderSceneConverter::LinkBlendFilePath(const char *path, char *group, KX_Scene *scene_merge, char **err_str)
{
- BlendHandle *bpy_openlib = BLO_blendhandle_from_file( (char *)path );
+ BlendHandle *bpy_openlib = BLO_blendhandle_from_file((char *)path, NULL);
// Error checking is done in LinkBlendFile
return LinkBlendFile(bpy_openlib, path, group, scene_merge, err_str);
@@ -984,8 +984,9 @@ bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const cha
/* here appending/linking starts */
main_tmp = BLO_library_append_begin(C, &bpy_openlib, (char *)path);
-
- names = BLO_blendhandle_get_datablock_names( bpy_openlib, idcode);
+
+ int totnames_dummy;
+ names = BLO_blendhandle_get_datablock_names( bpy_openlib, idcode, &totnames_dummy);
int i=0;
LinkNode *n= names;
diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp
index e205ddfda2e..c340d13b3d4 100644
--- a/source/gameengine/Expressions/PyObjectPlus.cpp
+++ b/source/gameengine/Expressions/PyObjectPlus.cpp
@@ -45,8 +45,9 @@
* http://www.python.org/doc/PyCPP.html
*
------------------------------*/
-#include <MT_assert.h>
-#include "stdlib.h"
+#include <stdlib.h>
+#include <stddef.h>
+
#include "PyObjectPlus.h"
#include "STR_String.h"
#include "MT_Vector3.h"
diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp
index be138db620e..d0c1155de96 100644
--- a/source/gameengine/GameLogic/SCA_PythonController.cpp
+++ b/source/gameengine/GameLogic/SCA_PythonController.cpp
@@ -415,11 +415,7 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
excdict= PyDict_Copy(m_pythondictionary);
-#if PY_VERSION_HEX >= 0x03020000
resultobj = PyEval_EvalCode((PyObject *)m_bytecode, excdict, excdict);
-#else
- resultobj = PyEval_EvalCode((PyCodeObject *)m_bytecode, excdict, excdict);
-#endif
/* PyRun_SimpleString(m_scriptText.Ptr()); */
break;
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index 88e178dda19..1b35219a36d 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -38,6 +38,7 @@
#endif //WIN32
#include <iostream>
+#include <stdio.h>
#include "KX_KetsjiEngine.h"
@@ -77,7 +78,6 @@
#include "KX_TimeCategoryLogger.h"
#include "RAS_FramingManager.h"
-#include "stdio.h"
#include "DNA_world_types.h"
#include "DNA_scene_types.h"
diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
index dfaf079f36f..9d0597051ad 100644
--- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
@@ -172,7 +172,7 @@ void KX_PolygonMaterial::DefaultActivate(RAS_IRasterizer* rasty, TCachingInfo& c
cachingInfo = GetCachingInfo();
- if ((m_drawingmode & 4)&& (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED))
+ if ((m_drawingmode & RAS_IRasterizer::KX_TEX)&& (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED))
{
Image *ima = (Image*)m_tface->tpage;
GPU_update_image_time(ima, rasty->GetTime());
diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
index f08fc14c29c..8776bf6fe88 100644
--- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
+++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
@@ -542,6 +542,18 @@ static PyObject* gPyRemoveConstraint(PyObject* self,
Py_RETURN_NONE;
}
+static PyObject* gPyExportBulletFile(PyObject*, PyObject* args)
+{
+ char* filename;
+ if (!PyArg_ParseTuple(args,"s:exportBulletFile",&filename))
+ return NULL;
+
+ if (PHY_GetActiveEnvironment())
+ {
+ PHY_GetActiveEnvironment()->exportFile(filename);
+ }
+ Py_RETURN_NONE;
+}
static struct PyMethodDef physicsconstraints_methods[] = {
{"setGravity",(PyCFunction) gPySetGravity,
@@ -594,6 +606,9 @@ static struct PyMethodDef physicsconstraints_methods[] = {
{"getAppliedImpulse",(PyCFunction) gPyGetAppliedImpulse,
METH_VARARGS, (const char *)gPyGetAppliedImpulse__doc__},
+ {"exportBulletFile",(PyCFunction)gPyExportBulletFile,
+ METH_VARARGS, "export a .bullet file"},
+
//sentinel
{ NULL, (PyCFunction) NULL, 0, NULL }
@@ -664,5 +679,7 @@ PHY_IPhysicsEnvironment* PHY_GetActiveEnvironment()
return g_CurrentActivePhysicsEnvironment;
}
+
+
#endif // WITH_PYTHON
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index 7dfdb67d2c6..171f13e9b9f 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -1457,7 +1457,7 @@ struct OcclusionBuffer
const float face,
const btScalar minarea)
{
- const btScalar a2=cross(b-a,c-a)[2];
+ const btScalar a2=btCross(b-a,c-a)[2];
if((face*a2)<0.f || btFabs(a2)<minarea)
return false;
// further down we are normally going to write to the Zbuffer, mark it so
@@ -2793,3 +2793,17 @@ float CcdPhysicsEnvironment::getAppliedImpulse(int constraintid)
return 0.f;
}
+
+void CcdPhysicsEnvironment::exportFile(const char* filename)
+{
+ btDefaultSerializer* serializer = new btDefaultSerializer();
+ m_dynamicsWorld->serialize(serializer);
+
+ FILE* file = fopen(filename,"wb");
+ if (file)
+ {
+ fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1, file);
+ fclose(file);
+ }
+}
+
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
index 4b97dc95179..586e75d2d00 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
@@ -280,6 +280,8 @@ protected:
bool m_scalingPropagated;
+ virtual void exportFile(const char* filename);
+
#ifdef WITH_CXX_GUARDEDALLOC
public:
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
index e2a9b5e99e4..60da4523dd5 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
+++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
@@ -180,6 +180,7 @@ class PHY_IPhysicsEnvironment
virtual void setConstraintParam(int constraintId,int param,float value,float value1) = 0;
virtual float getConstraintParam(int constraintId,int param) = 0;
+ virtual void exportFile(const char* filename) {};
#ifdef WITH_CXX_GUARDEDALLOC
public:
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
index e8c0a73813e..47f1dcb412a 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
@@ -241,7 +241,7 @@ bool RAS_IPolyMaterial::UsesLighting(RAS_IRasterizer *rasty) const
else if(rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID);
else if(rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW);
else
- dolights = (m_drawingmode & 16)!=0;
+ dolights = (m_drawingmode & RAS_IRasterizer::KX_LIGHT)!=0;
return dolights;
}
diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h
index f76799953a1..305e2bca756 100644
--- a/source/gameengine/Rasterizer/RAS_IRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h
@@ -71,7 +71,7 @@ public:
/**
*/
enum {
- RAS_RENDER_3DPOLYGON_TEXT = 16384
+ RAS_RENDER_3DPOLYGON_TEXT = 16384 /* TF_BMFONT */
};
/**
* Drawing types
@@ -106,7 +106,9 @@ public:
/**
*/
enum {
- KX_TWOSIDE = 512,
+ KX_TEX = 4, /* TF_TEX */
+ KX_LIGHT = 16, /* TF_LIGHT */
+ KX_TWOSIDE = 512, /* TF_TWOSIDE */
KX_LINES = 32768
};
diff --git a/source/tests/pep8.py b/source/tests/pep8.py
index c4c2da3f185..3872d169a9a 100644
--- a/source/tests/pep8.py
+++ b/source/tests/pep8.py
@@ -31,7 +31,7 @@ import os
# in debian install pylint pyflakes pep8 with apt-get/aptitude/etc
#
# on *nix run
-# python release/test/pep8.py > pep8_error.txt 2>&1
+# python source/tests/pep8.py > pep8_error.txt 2>&1
# how many lines to read into the file, pep8 comment
# should be directly after the licence header, ~20 in most cases