diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-01-29 16:00:04 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-01-29 16:00:04 +0400 |
commit | 831f33998060abf76ce1dfa26a08397121210e86 (patch) | |
tree | dfc5e5e5c3e588d0398bb9fa5656ea1dea9432bb /source/blender/blenkernel | |
parent | 12baf364f528f11db8f9c9d139ef97f657145c8f (diff) | |
parent | d4584dfd23ab4880cc6e2f7f6d699ea3c9687d22 (diff) |
Merged changes in the trunk up to revision 43748.
Conflicts resolved:
source/blender/editors/include/UI_resources.h
Diffstat (limited to 'source/blender/blenkernel')
23 files changed, 418 insertions, 214 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 0c47c833cb3..a887412bbf4 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -538,6 +538,15 @@ int sculpt_get_deform_matrices(struct Scene *scene, struct Object *ob, float (**deformmats)[3][3], float (**deformcos)[3]); void weight_to_rgb(float r_rgb[3], const float weight); +/* Update the weight MCOL preview layer. + * If weights are NULL, use object's active vgroup(s). + * Else, weights must be an array of weight float values. + * If indices is NULL, it must be of numVerts length. + * Else, it must be of num length, as indices, which contains vertices' idx to apply weights to. + * (other vertices are assumed zero weight). + */ +void DM_update_weight_mcol(struct Object *ob, struct DerivedMesh *dm, int const draw_flag, + float *weights, int num, const int *indices); /* convert layers requested by a GLSL material to actually available layers in * the DerivedMesh, with both a pointer for arrays and an offset for editmesh */ diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index a89bfbd50b1..11ab981822e 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -86,7 +86,7 @@ int bone_autoside_name (char name[64], int strip_number, short axis, float head, struct Bone *get_named_bone (struct bArmature *arm, const char *name); -float distfactor_to_bone (float vec[3], float b1[3], float b2[3], float rad1, float rad2, float rdist); +float distfactor_to_bone(const float vec[3], const float b1[3], const float b2[3], float rad1, float rad2, float rdist); void where_is_armature (struct bArmature *arm); void where_is_armature_bone(struct Bone *bone, struct Bone *prevbone); diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index f24687e0fc9..50fef032b75 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 261 -#define BLENDER_SUBVERSION 3 +#define BLENDER_SUBVERSION 4 #define BLENDER_MINVERSION 250 #define BLENDER_MINSUBVERSION 0 @@ -51,7 +51,7 @@ extern "C" { /* can be left blank, otherwise a,b,c... etc with no quotes */ #define BLENDER_VERSION_CHAR /* alpha/beta/rc/release, docs use this */ -#define BLENDER_VERSION_CYCLE alpha +#define BLENDER_VERSION_CYCLE beta extern char versionstr[]; /* from blender.c */ diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 62c3df7c6f4..6d42b8dc80b 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -216,7 +216,7 @@ void clmdSetInterruptCallBack ( int ( *f ) ( void ) ); void cloth_free_modifier_extern ( struct ClothModifierData *clmd ); void cloth_free_modifier ( struct ClothModifierData *clmd ); void cloth_init ( struct ClothModifierData *clmd ); -struct DerivedMesh *clothModifier_do ( struct ClothModifierData *clmd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm); +void clothModifier_do ( struct ClothModifierData *clmd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3]); void cloth_update_normals ( ClothVertex *verts, int nVerts, struct MFace *face, int totface ); int cloth_uses_vgroup(struct ClothModifierData *clmd); diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 1af2f014ef4..7ad25ac7e79 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -67,7 +67,7 @@ extern const CustomDataMask CD_MASK_FACECORNERS; #define CD_DUPLICATE 4 /* do a full copy of all layers, only allowed if source has same number of elements */ -#define CD_TYPE_AS_MASK(_type) (CustomDataMask)(1 << (CustomDataMask)(_type)) +#define CD_TYPE_AS_MASK(_type) (CustomDataMask)((CustomDataMask)1 << (CustomDataMask)(_type)) /* initialises a CustomData object with the same layer setup as source. * mask is a bitfield where (mask & (1 << (layer type))) indicates diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 23073a2d8eb..f72bc5b93ec 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -99,7 +99,10 @@ typedef enum { eModifierTypeFlag_Single = (1<<7), /* Some modifier can't be added manually by user */ - eModifierTypeFlag_NoUserAdd = (1<<8) + eModifierTypeFlag_NoUserAdd = (1<<8), + + /* For modifiers that use CD_WEIGHT_MCOL for preview. */ + eModifierTypeFlag_UsesPreview = (1<<9) } ModifierTypeFlag; typedef void (*ObjectWalkFunc)(void *userData, struct Object *ob, struct Object **obpoin); @@ -323,6 +326,7 @@ void modifier_setError(struct ModifierData *md, const char *format, ... __attribute__ ((format (printf, 2, 3))) #endif ; +int modifier_isPreview(struct ModifierData *md); void modifiers_foreachObjectLink(struct Object *ob, ObjectWalkFunc walk, @@ -349,6 +353,7 @@ struct Object *modifiers_isDeformedByLattice(struct Object *ob); int modifiers_usesArmature(struct Object *ob, struct bArmature *arm); int modifiers_isCorrectableDeformed(struct Object *ob); void modifier_freeTemporaryData(struct ModifierData *md); +int modifiers_isPreview(struct Object *ob); int modifiers_indexInObject(struct Object *ob, struct ModifierData *md); @@ -362,6 +367,9 @@ struct LinkNode *modifiers_calcDataMasks(struct Scene *scene, struct ModifierData *md, CustomDataMask dataMask, int required_mode); +struct ModifierData *modifiers_getLastPreview(struct Scene *scene, + struct ModifierData *md, + int required_mode); struct ModifierData *modifiers_getVirtualModifierList(struct Object *ob); /* ensure modifier correctness when changing ob->data */ diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 67de699c7c4..0cccd8a366b 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -523,6 +523,7 @@ struct ShadeResult; #define SH_NODE_VOLUME_ISOTROPIC 162 #define SH_NODE_GAMMA 163 #define SH_NODE_TEX_CHECKER 164 +#define SH_NODE_BRIGHTCONTRAST 165 /* custom defines options for Material node */ #define SH_NODE_MAT_DIFF 1 @@ -556,25 +557,34 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat); /* ************** COMPOSITE NODES *************** */ /* output socket defines */ -#define RRES_OUT_IMAGE 0 -#define RRES_OUT_ALPHA 1 -#define RRES_OUT_Z 2 -#define RRES_OUT_NORMAL 3 -#define RRES_OUT_UV 4 -#define RRES_OUT_VEC 5 -#define RRES_OUT_RGBA 6 -#define RRES_OUT_DIFF 7 -#define RRES_OUT_SPEC 8 -#define RRES_OUT_SHADOW 9 -#define RRES_OUT_AO 10 -#define RRES_OUT_REFLECT 11 -#define RRES_OUT_REFRACT 12 -#define RRES_OUT_INDIRECT 13 -#define RRES_OUT_INDEXOB 14 -#define RRES_OUT_INDEXMA 15 -#define RRES_OUT_MIST 16 -#define RRES_OUT_EMIT 17 -#define RRES_OUT_ENV 18 +#define RRES_OUT_IMAGE 0 +#define RRES_OUT_ALPHA 1 +#define RRES_OUT_Z 2 +#define RRES_OUT_NORMAL 3 +#define RRES_OUT_UV 4 +#define RRES_OUT_VEC 5 +#define RRES_OUT_RGBA 6 +#define RRES_OUT_DIFF 7 +#define RRES_OUT_SPEC 8 +#define RRES_OUT_SHADOW 9 +#define RRES_OUT_AO 10 +#define RRES_OUT_REFLECT 11 +#define RRES_OUT_REFRACT 12 +#define RRES_OUT_INDIRECT 13 +#define RRES_OUT_INDEXOB 14 +#define RRES_OUT_INDEXMA 15 +#define RRES_OUT_MIST 16 +#define RRES_OUT_EMIT 17 +#define RRES_OUT_ENV 18 +#define RRES_OUT_DIFF_DIRECT 19 +#define RRES_OUT_DIFF_INDIRECT 20 +#define RRES_OUT_DIFF_COLOR 21 +#define RRES_OUT_GLOSSY_DIRECT 22 +#define RRES_OUT_GLOSSY_INDIRECT 23 +#define RRES_OUT_GLOSSY_COLOR 24 +#define RRES_OUT_TRANSM_DIRECT 25 +#define RRES_OUT_TRANSM_INDIRECT 26 +#define RRES_OUT_TRANSM_COLOR 27 /* note: types are needed to restore callbacks, don't change values */ #define CMP_NODE_VIEWER 201 diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index d3f297ece86..f720050f59c 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -61,6 +61,7 @@ struct MovieTrackingMarker *BKE_tracking_get_marker(struct MovieTrackingTrack *t struct MovieTrackingMarker *BKE_tracking_ensure_marker(struct MovieTrackingTrack *track, int framenr); struct MovieTrackingMarker *BKE_tracking_exact_marker(struct MovieTrackingTrack *track, int framenr); int BKE_tracking_has_marker(struct MovieTrackingTrack *track, int framenr); +int BKE_tracking_has_enabled_marker(struct MovieTrackingTrack *track, int framenr); void BKE_tracking_free_track(struct MovieTrackingTrack *track); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index b670a360a6a..27aeeb95903 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -722,24 +722,23 @@ void vDM_ColorBand_store(ColorBand *coba) * note that we could save some memory and allocate RGB only but then we'd need to * re-arrange the colors when copying to the face since MCol has odd ordering, * so leave this as is - campbell */ -static unsigned char *calc_weightpaint_vert_array(Object *ob, int const draw_flag, ColorBand *coba) +static unsigned char *calc_weightpaint_vert_array(Object *ob, DerivedMesh *dm, int const draw_flag, ColorBand *coba) { - Mesh *me = ob->data; - unsigned char *wtcol_v = MEM_mallocN (sizeof(unsigned char) * me->totvert * 4, "weightmap_v"); + MDeformVert *dv = DM_get_vert_data_layer(dm, CD_MDEFORMVERT); + int numVerts = dm->getNumVerts(dm); + unsigned char *wtcol_v = MEM_mallocN (sizeof(unsigned char) * numVerts * 4, "weightmap_v"); - if (me->dvert) { + if (dv) { unsigned char *wc = wtcol_v; - MDeformVert *dv= me->dvert; unsigned int i; - /* varisbles for multipaint */ + /* variables for multipaint */ const int defbase_tot = BLI_countlist(&ob->defbase); const int defbase_act = ob->actdef-1; char *dg_flags = MEM_mallocN(defbase_tot * sizeof(char), __func__); const int selected = get_selected_defgroups(ob, dg_flags, defbase_tot); - /* const int unselected = defbase_tot - selected; */ /* UNUSED */ - for (i = me->totvert; i != 0; i--, wc += 4, dv++) { + for (i = numVerts; i != 0; i--, wc += 4, dv++) { calc_weightpaint_vert_color(wc, dv, coba, defbase_tot, defbase_act, dg_flags, selected, draw_flag); } @@ -748,48 +747,94 @@ static unsigned char *calc_weightpaint_vert_array(Object *ob, int const draw_fla else { int col_i; weightpaint_color((unsigned char *)&col_i, coba, 0.0f); - fill_vn_i((int *)wtcol_v, me->totvert, col_i); + fill_vn_i((int *)wtcol_v, numVerts, col_i); } return wtcol_v; } -static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag) +/* return an array of vertex weight colors from given weights, caller must free. + * + * note that we could save some memory and allocate RGB only but then we'd need to + * re-arrange the colors when copying to the face since MCol has odd ordering, + * so leave this as is - campbell */ +static unsigned char *calc_colors_from_weights_array(const int num, float *weights) { - ColorBand *coba= stored_cb; /* warning, not a local var */ + unsigned char *wtcol_v = MEM_mallocN(sizeof(unsigned char) * num * 4, "weightmap_v"); + unsigned char *wc = wtcol_v; + int i; - Mesh *me = ob->data; - unsigned char *wtcol_v = calc_weightpaint_vert_array(ob, draw_flag, coba); - unsigned char *wtcol_f = MEM_mallocN (sizeof(unsigned char) * me->totface*4*4, "weightmap_f"); - unsigned char *wtcol_f_step = wtcol_f; + for (i = 0; i < num; i++, wc += 4, weights++) + weightpaint_color((unsigned char *) wc, NULL, *weights); + + return wtcol_v; +} - MFace *mf = me->mface; +void DM_update_weight_mcol(Object *ob, DerivedMesh *dm, int const draw_flag, + float *weights, int num, const int *indices) +{ + ColorBand *coba= stored_cb; /* warning, not a local var */ + + MFace *mf = dm->getFaceArray(dm); + int numFaces = dm->getNumFaces(dm); + int numVerts = dm->getNumVerts(dm); + unsigned char *wtcol_v; + unsigned char *wtcol_f = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL); int i; - for (i=0; i<me->totface; i++, mf++, wtcol_f_step += (4 * 4)) { + /* If no CD_WEIGHT_MCOL existed yet, add a new one! */ + if (!wtcol_f) + wtcol_f = CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_CALLOC, NULL, numFaces); + + if (wtcol_f) { + unsigned char *wtcol_f_step = wtcol_f; + + /* Weights are given by caller. */ + if (weights) { + float *w = weights; + /* If indices is not NULL, it means we do not have weights for all vertices, + * so we must create them (and set them to zero)... */ + if(indices) { + w = MEM_callocN(sizeof(float)*numVerts, "Temp weight array DM_update_weight_mcol"); + i = num; + while(i--) + w[indices[i]] = weights[i]; + } + + /* Convert float weights to colors. */ + wtcol_v = calc_colors_from_weights_array(numVerts, w); + + if(indices) + MEM_freeN(w); + } + + /* No weights given, take them from active vgroup(s). */ + else + wtcol_v = calc_weightpaint_vert_array(ob, dm, draw_flag, coba); + + /* Now copy colors in all face verts. */ + for (i = 0; i < numFaces; i++, mf++, wtcol_f_step += (4 * 4)) { #if 0 - unsigned int fidx= mf->v4 ? 3:2; + unsigned int fidx= mf->v4 ? 3:2; #else /* better zero out triangles 4th component. else valgrind complains when the buffer's copied */ - unsigned int fidx; - if (mf->v4) { - fidx = 3; - } - else { - fidx = 2; - *(int *)(&wtcol_f_step[3 * 4]) = 0; - } + unsigned int fidx; + if (mf->v4) { + fidx = 3; + } + else { + fidx = 2; + *(int *)(&wtcol_f_step[3 * 4]) = 0; + } #endif - do { - copy_v4_v4_char((char *)&wtcol_f_step[fidx * 4], - (char *)&wtcol_v[4 * (*(&mf->v1 + fidx))]); - } while (fidx--); + do { + copy_v4_v4_char((char *)&wtcol_f_step[fidx * 4], + (char *)&wtcol_v[4 * (*(&mf->v1 + fidx))]); + } while (fidx--); + } + MEM_freeN(wtcol_v); } - - MEM_freeN(wtcol_v); - - CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol_f, dm->numFaceData); } /* new value for useDeform -1 (hack for the gameengine): @@ -803,7 +848,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos int needMapping, CustomDataMask dataMask, int index, int useCache) { Mesh *me = ob->data; - ModifierData *firstmd, *md; + ModifierData *firstmd, *md, *previewmd = NULL; LinkNode *datamasks, *curr; CustomDataMask mask, nextmask, append_mask = 0; float (*deformedVerts)[3] = NULL; @@ -816,8 +861,17 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos int has_multires = mmd != NULL, multires_applied = 0; int sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt; - int draw_flag= ((scene->toolsettings->multipaint ? CALC_WP_MULTIPAINT : 0) | - (scene->toolsettings->auto_normalize ? CALC_WP_AUTO_NORMALIZE : 0)); + const int draw_flag= ((scene->toolsettings->multipaint ? CALC_WP_MULTIPAINT : 0) | + (scene->toolsettings->auto_normalize ? CALC_WP_AUTO_NORMALIZE : 0)); + /* Generic preview only in object mode! */ + const int do_mod_mcol = (ob->mode == OB_MODE_OBJECT); +#if 0 /* XXX Will re-enable this when we have global mod stack options. */ + const int do_final_wmcol = (scene->toolsettings->weights_preview == WP_WPREVIEW_FINAL) && do_wmcol; +#endif + const int do_final_wmcol = FALSE; + int do_init_wmcol = ((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT) && !do_final_wmcol); + /* XXX Same as above... For now, only weights preview in WPaint mode. */ + const int do_mod_wmcol = do_init_wmcol; if(mmd && !mmd->sculptlvl) has_multires = 0; @@ -842,6 +896,14 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode); curr = datamasks; + if(do_mod_wmcol || do_mod_mcol) { + /* Find the last active modifier generating a preview, or NULL if none. */ + /* XXX Currently, DPaint modifier just ignores this. + * Needs a stupid hack... + * The whole "modifier preview" thing has to be (re?)designed, anyway! */ + previewmd = modifiers_getLastPreview(scene, md, required_mode); + } + if(deform_r) *deform_r = NULL; *final_r = NULL; @@ -997,8 +1059,8 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos CDDM_calc_normals(dm); } - if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT)) - add_weight_mcol_dm(ob, dm, draw_flag); + if(do_init_wmcol) + DM_update_weight_mcol(ob, dm, draw_flag, NULL, 0, NULL); /* Constructive modifiers need to have an origindex * otherwise they wont have anywhere to copy the data from. @@ -1085,8 +1147,14 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos } /* in case of dynamic paint, make sure preview mask remains for following modifiers */ + /* XXX Temp and hackish solution! */ if (md->type == eModifierType_DynamicPaint) append_mask |= CD_MASK_WEIGHT_MCOL; + /* In case of active preview modifier, make sure preview mask remains for following modifiers. */ + else if ((md == previewmd) && (do_mod_wmcol)) { + DM_update_weight_mcol(ob, dm, draw_flag, NULL, 0, NULL); + append_mask |= CD_MASK_WEIGHT_MCOL; + } } isPrevDeform= (mti->type == eModifierTypeType_OnlyDeform); @@ -1114,10 +1182,19 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos CDDM_apply_vert_coords(finaldm, deformedVerts); CDDM_calc_normals(finaldm); - if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT)) - add_weight_mcol_dm(ob, finaldm, draw_flag); +#if 0 /* For later nice mod preview! */ + /* In case we need modified weights in CD_WEIGHT_MCOL, we have to re-compute it. */ + if(do_final_wmcol) + DM_update_weight_mcol(ob, finaldm, draw_flag, NULL, 0, NULL); +#endif } else if(dm) { finaldm = dm; + +#if 0 /* For later nice mod preview! */ + /* In case we need modified weights in CD_WEIGHT_MCOL, we have to re-compute it. */ + if(do_final_wmcol) + DM_update_weight_mcol(ob, finaldm, draw_flag, NULL, 0, NULL); +#endif } else { finaldm = CDDM_from_mesh(me, ob); @@ -1126,8 +1203,9 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos CDDM_calc_normals(finaldm); } - if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT)) - add_weight_mcol_dm(ob, finaldm, draw_flag); + /* In this case, we should never have weight-modifying modifiers in stack... */ + if(do_init_wmcol) + DM_update_weight_mcol(ob, finaldm, draw_flag, NULL, 0, NULL); } /* add an orco layer if needed */ diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 4f83bcf7e7f..64ea862477f 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -665,7 +665,7 @@ static void b_bone_deform(bPoseChanDeform *pdef_info, Bone *bone, float *co, Dua } /* using vec with dist to bone b1 - b2 */ -float distfactor_to_bone (float vec[3], float b1[3], float b2[3], float rad1, float rad2, float rdist) +float distfactor_to_bone(const float vec[3], const float b1[3], const float b2[3], float rad1, float rad2, float rdist) { float dist=0.0f; float bdelta[3]; @@ -677,18 +677,18 @@ float distfactor_to_bone (float vec[3], float b1[3], float b2[3], float rad1, fl sub_v3_v3v3(pdelta, vec, b1); - a = bdelta[0]*pdelta[0] + bdelta[1]*pdelta[1] + bdelta[2]*pdelta[2]; - hsqr = ((pdelta[0]*pdelta[0]) + (pdelta[1]*pdelta[1]) + (pdelta[2]*pdelta[2])); + a = dot_v3v3(bdelta, pdelta); + hsqr = dot_v3v3(pdelta, pdelta); - if (a < 0.0F){ + if (a < 0.0f) { /* If we're past the end of the bone, do a spherical field attenuation thing */ - dist= ((b1[0]-vec[0])*(b1[0]-vec[0]) +(b1[1]-vec[1])*(b1[1]-vec[1]) +(b1[2]-vec[2])*(b1[2]-vec[2])) ; + dist = len_squared_v3v3(b1, vec); rad= rad1; } - else if (a > l){ + else if (a > l) { /* If we're past the end of the bone, do a spherical field attenuation thing */ - dist= ((b2[0]-vec[0])*(b2[0]-vec[0]) +(b2[1]-vec[1])*(b2[1]-vec[1]) +(b2[2]-vec[2])*(b2[2]-vec[2])) ; - rad= rad2; + dist = len_squared_v3v3(b2, vec); + rad = rad2; } else { dist= (hsqr - (a*a)); @@ -709,7 +709,7 @@ float distfactor_to_bone (float vec[3], float b1[3], float b2[3], float rad1, fl if(rdist==0.0f || dist >= l) return 0.0f; else { - a= (float)sqrt(dist)-rad; + a = sqrtf(dist)-rad; return 1.0f-( a*a )/( rdist*rdist ); } } diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 73428c889dc..d86fc5c9aef 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -90,7 +90,7 @@ static CM_SOLVER_DEF solvers [] = /* ********** cloth engine ******* */ /* Prototypes for internal functions. */ -static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh *dm); +static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*vertexCos)[3]); static void cloth_from_mesh ( ClothModifierData *clmd, DerivedMesh *dm ); static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr, int first); static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ); @@ -130,6 +130,7 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->presets = 2; /* cotton as start setting */ clmd->sim_parms->timescale = 1.0f; /* speed factor, describes how fast cloth moves */ clmd->sim_parms->reset = 0; + clmd->sim_parms->vel_damping = 1.0f; /* 1.0 = no damping, 0.0 = fully dampened */ clmd->coll_parms->self_friction = 5.0; clmd->coll_parms->friction = 5.0; @@ -428,9 +429,8 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul /************************************************ * clothModifier_do - main simulation function ************************************************/ -DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, DerivedMesh *dm) +void clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, DerivedMesh *dm, float (*vertexCos)[3]) { - DerivedMesh *result; PointCache *cache; PTCacheID pid; float timescale; @@ -440,20 +440,14 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, clmd->scene= scene; /* nice to pass on later :) */ framenr= (int)scene->r.cfra; cache= clmd->point_cache; - result = CDDM_copy(dm); BKE_ptcache_id_from_cloth(&pid, ob, clmd); BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, ×cale); clmd->sim_parms->timescale= timescale; - if(!result) { - BKE_ptcache_invalidate(cache); - return dm; - } - if(clmd->sim_parms->reset || (framenr == (startframe - clmd->sim_parms->preroll) && clmd->sim_parms->preroll != 0) - || (clmd->clothObject && result->getNumVerts(result) != clmd->clothObject->numverts)) + || (clmd->clothObject && dm->getNumVerts(dm) != clmd->clothObject->numverts)) { clmd->sim_parms->reset = 0; cache->flag |= PTCACHE_OUTDATED; @@ -461,7 +455,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, BKE_ptcache_validate(cache, 0); cache->last_exact= 0; cache->flag &= ~PTCACHE_REDO_NEEDED; - return result; + return; } // unused in the moment, calculated separately in implicit.c @@ -473,20 +467,20 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, /* do simulation */ if(!do_init_cloth(ob, clmd, dm, framenr)) - return result; + return; do_step_cloth(ob, clmd, dm, framenr); - cloth_to_object(ob, clmd, result); + cloth_to_object(ob, clmd, vertexCos); clmd->clothObject->last_frame= framenr; - return result; + return; } /* simulation is only active during a specific period */ if(framenr < startframe) { BKE_ptcache_invalidate(cache); - return result; + return; } else if(framenr > endframe) { framenr= endframe; @@ -494,7 +488,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, /* initialize simulation data if it didn't exist already */ if(!do_init_cloth(ob, clmd, dm, framenr)) - return result; + return; if((framenr == startframe) && (clmd->sim_parms->preroll == 0)) { BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); @@ -502,7 +496,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, BKE_ptcache_validate(cache, framenr); cache->flag &= ~PTCACHE_REDO_NEEDED; clmd->clothObject->last_frame= framenr; - return result; + return; } /* try to read from cache */ @@ -510,7 +504,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) { implicit_set_positions(clmd); - cloth_to_object (ob, clmd, result); + cloth_to_object (ob, clmd, vertexCos); BKE_ptcache_validate(cache, framenr); @@ -519,7 +513,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, clmd->clothObject->last_frame= framenr; - return result; + return; } else if(cache_result==PTCACHE_READ_OLD) { implicit_set_positions(clmd); @@ -527,11 +521,11 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, else if( /*ob->id.lib ||*/ (cache->flag & PTCACHE_BAKED)) { /* 2.4x disabled lib, but this can be used in some cases, testing further - campbell */ /* if baked and nothing in cache, do nothing */ BKE_ptcache_invalidate(cache); - return result; + return; } if(framenr!=clmd->clothObject->last_frame+1) - return result; + return; /* if on second frame, write cache for first frame */ if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0)) @@ -548,10 +542,8 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, else BKE_ptcache_write(&pid, framenr); - cloth_to_object (ob, clmd, result); + cloth_to_object (ob, clmd, vertexCos); clmd->clothObject->last_frame= framenr; - - return result; } /* frees all */ @@ -706,24 +698,19 @@ void cloth_free_modifier_extern ( ClothModifierData *clmd ) * cloth_to_object - copies the deformed vertices to the object. * **/ -static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh *dm) +static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*vertexCos)[3]) { unsigned int i = 0; - MVert *mvert = NULL; - unsigned int numverts; Cloth *cloth = clmd->clothObject; if (clmd->clothObject) { /* inverse matrix is not uptodate... */ invert_m4_m4(ob->imat, ob->obmat); - mvert = CDDM_get_verts(dm); - numverts = dm->getNumVerts(dm); - - for (i = 0; i < numverts; i++) + for (i = 0; i < cloth->numverts; i++) { - copy_v3_v3 (mvert[i].co, cloth->verts[i].x); - mul_m4_v3(ob->imat, mvert[i].co); /* cloth is in global coords */ + copy_v3_v3 (vertexCos[i], cloth->verts[i].x); + mul_m4_v3(ob->imat, vertexCos[i]); /* cloth is in global coords */ } } } diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 2bda3066af0..8118cf64429 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -2775,8 +2775,7 @@ static void stretchto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase * /* store Z orientation before destroying obmat */ normalize_v3_v3(zz, cob->matrix[2]); - dist = len_v3v3(cob->matrix[3], ct->matrix[3]); - /* XXX What was all that for??? Makes the constraint buggy with scaled objects, see #29940. */ + /* XXX That makes the constraint buggy with asymmetrically scaled objects, see #29940. */ /* sub_v3_v3v3(vec, cob->matrix[3], ct->matrix[3]);*/ /* vec[0] /= size[0];*/ /* vec[1] /= size[1];*/ @@ -2784,10 +2783,14 @@ static void stretchto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase * /* dist = normalize_v3(vec);*/ + dist = len_v3v3(cob->matrix[3], ct->matrix[3]); + /* Only Y constrained object axis scale should be used, to keep same length when scaling it. */ + dist /= size[1]; + /* data->orglength==0 occurs on first run, and after 'R' button is clicked */ - if (data->orglength == 0) + if (data->orglength == 0) data->orglength = dist; - if (data->bulge == 0) + if (data->bulge == 0) data->bulge = 1.0; scale[1] = dist/data->orglength; diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 17936a44a73..e0f76917368 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -833,6 +833,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba int editmode = (!forRender && cu->editnurb); DerivedMesh *dm= NULL, *ndm; float (*vertCos)[3] = NULL; + int useCache = !forRender; if(forRender) required_mode = eModifierMode_Render; else required_mode = eModifierMode_Realtime; @@ -911,7 +912,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba vertCos= NULL; } - ndm = mti->applyModifier(md, ob, dm, forRender, editmode); + ndm = mti->applyModifier(md, ob, dm, forRender, useCache); if (ndm) { /* Modifier returned a new derived mesh */ diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 6a2207d455c..cdfd5d3562b 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -97,6 +97,10 @@ static int neighY[8] = {0,1,1, 1, 0,-1,-1,-1}; /* brush mesh raycast status */ #define HIT_VOLUME 1 #define HIT_PROXIMITY 2 +/* dynamicPaint_findNeighbourPixel() return codes */ +#define NOT_FOUND -1 +#define ON_MESH_EDGE -2 +#define OUT_OF_TEXTURE -3 /* paint effect default movement per frame in global units */ #define EFF_MOVEMENT_PER_FRAME 0.05f /* initial wave time factor */ @@ -134,10 +138,10 @@ typedef struct Vec3f { float v[3]; } Vec3f; -typedef struct BakeNeighPoint { +typedef struct BakeAdjPoint { float dir[3]; /* vector pointing towards this neighbour */ float dist; /* distance to */ -} BakeNeighPoint; +} BakeAdjPoint; /* Surface data used while processing a frame */ typedef struct PaintBakeNormal { @@ -156,7 +160,7 @@ typedef struct PaintBakeData { Bounds3D mesh_bounds; /* adjacency info */ - BakeNeighPoint *bNeighs; /* current global neighbour distances and directions, if required */ + BakeAdjPoint *bNeighs; /* current global neighbour distances and directions, if required */ double average_dist; /* space partitioning */ VolumeGrid *grid; /* space partitioning grid to optimize brush checks */ @@ -188,13 +192,6 @@ typedef struct ImgSeqFormatData { Vec3f *barycentricWeights; /* b-weights for all pixel samples */ } ImgSeqFormatData; -#if 0 /* UNUSED */ -typedef struct EffVelPoint { - float previous_pos[3]; - float previous_vel[3]; -} EffVelPoint; -#endif - /* adjacency data flags */ #define ADJ_ON_MESH_EDGE (1<<0) @@ -470,19 +467,25 @@ static void object_cacheIgnoreClear(Object *ob, int state) BLI_freelistN(&pidlist); } -static void subframe_updateObject(Scene *scene, Object *ob, int flags, float frame) +static int subframe_updateObject(Scene *scene, Object *ob, int flags, float frame) { DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(ob, eModifierType_DynamicPaint); bConstraint *con; /* if other is dynamic paint canvas, dont update */ if (pmd && pmd->canvas) - return; + return 1; /* if object has parents, update them too */ if (flags & UPDATE_PARENTS) { - if (ob->parent) subframe_updateObject(scene, ob->parent, 0, frame); - if (ob->track) subframe_updateObject(scene, ob->track, 0, frame); + int is_canvas = 0; + if (ob->parent) is_canvas += subframe_updateObject(scene, ob->parent, 0, frame); + if (ob->track) is_canvas += subframe_updateObject(scene, ob->track, 0, frame); + + /* skip subframe if object is parented + * to vertex of a dynamic paint canvas */ + if (is_canvas && (ob->partype == PARVERT1 || ob->partype == PARVERT3)) + return 0; /* also update constraint targets */ for (con = ob->constraints.first; con; con=con->next) { @@ -519,6 +522,8 @@ static void subframe_updateObject(Scene *scene, Object *ob, int flags, float fra } else where_is_object_time(scene, ob, frame); + + return 0; } static void scene_setSubframe(Scene *scene, float subframe) @@ -1222,7 +1227,7 @@ static int surface_usesAdjData(DynamicPaintSurface *surface) static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, int force_init) { PaintSurfaceData *sData = surface->data; - PaintAdjData *ed; + PaintAdjData *ad; int *temp_data; int neigh_points = 0; @@ -1238,17 +1243,17 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, int for if (!neigh_points) return; /* allocate memory */ - ed = sData->adj_data = MEM_callocN(sizeof(PaintAdjData), "Surface Adj Data"); - if (!ed) return; - ed->n_index = MEM_callocN(sizeof(int)*sData->total_points, "Surface Adj Index"); - ed->n_num = MEM_callocN(sizeof(int)*sData->total_points, "Surface Adj Counts"); + ad = sData->adj_data = MEM_callocN(sizeof(PaintAdjData), "Surface Adj Data"); + if (!ad) return; + ad->n_index = MEM_callocN(sizeof(int)*sData->total_points, "Surface Adj Index"); + ad->n_num = MEM_callocN(sizeof(int)*sData->total_points, "Surface Adj Counts"); temp_data = MEM_callocN(sizeof(int)*sData->total_points, "Temp Adj Data"); - ed->n_target = MEM_callocN(sizeof(int)*neigh_points, "Surface Adj Targets"); - ed->flags = MEM_callocN(sizeof(int)*sData->total_points, "Surface Adj Flags"); - ed->total_targets = neigh_points; + ad->n_target = MEM_callocN(sizeof(int)*neigh_points, "Surface Adj Targets"); + ad->flags = MEM_callocN(sizeof(int)*sData->total_points, "Surface Adj Flags"); + ad->total_targets = neigh_points; /* in case of allocation error, free memory */ - if (!ed->n_index || !ed->n_num || !ed->n_target || !temp_data) { + if (!ad->n_index || !ad->n_num || !ad->n_target || !temp_data) { dynamicPaint_freeAdjData(sData); if (temp_data) MEM_freeN(temp_data); setError(surface->canvas, "Not enough free memory."); @@ -1267,14 +1272,15 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, int for /* count number of edges per vertex */ for (i=0; i<numOfEdges; i++) { - ed->n_num[edge[i].v1]++; - ed->n_num[edge[i].v2]++; + ad->n_num[edge[i].v1]++; + ad->n_num[edge[i].v2]++; temp_data[edge[i].v1]++; temp_data[edge[i].v2]++; } - /* to locate points on "mesh edge" */ + /* also add number of vertices to temp_data + * to locate points on "mesh edge" */ for (i=0; i<numOfFaces; i++) { temp_data[face[i].v1]++; temp_data[face[i].v2]++; @@ -1288,7 +1294,7 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, int for for (i=0; i<sData->total_points; i++) { if ((temp_data[i]%2) || temp_data[i] < 4) - ed->flags[i] |= ADJ_ON_MESH_EDGE; + ad->flags[i] |= ADJ_ON_MESH_EDGE; /* reset temp data */ temp_data[i] = 0; @@ -1297,22 +1303,22 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, int for /* order n_index array */ n_pos = 0; for (i=0; i<sData->total_points; i++) { - ed->n_index[i] = n_pos; - n_pos += ed->n_num[i]; + ad->n_index[i] = n_pos; + n_pos += ad->n_num[i]; } /* and now add neighbour data using that info */ for (i=0; i<numOfEdges; i++) { /* first vertex */ int index = edge[i].v1; - n_pos = ed->n_index[index]+temp_data[index]; - ed->n_target[n_pos] = edge[i].v2; + n_pos = ad->n_index[index]+temp_data[index]; + ad->n_target[n_pos] = edge[i].v2; temp_data[index]++; /* second vertex */ index = edge[i].v2; - n_pos = ed->n_index[index]+temp_data[index]; - ed->n_target[n_pos] = edge[i].v1; + n_pos = ad->n_index[index]+temp_data[index]; + ad->n_target[n_pos] = edge[i].v1; temp_data[index]++; } } @@ -1500,10 +1506,11 @@ void dynamicPaint_clearSurface(DynamicPaintSurface *surface) int dynamicPaint_resetSurface(DynamicPaintSurface *surface) { int numOfPoints = dynamicPaint_surfaceNumOfPoints(surface); - /* dont touch image sequence types. they get handled only on bake */ - if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) return 1; - + /* free existing data */ if (surface->data) dynamicPaint_freeSurfaceData(surface); + + /* dont reallocate for image sequence types. they get handled only on bake */ + if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) return 1; if (numOfPoints < 1) return 0; /* allocate memory */ @@ -1574,7 +1581,6 @@ static struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData DynamicPaintSurface *surface = pmd->canvas->surfaces.first; int update_normals = 0; - pmd->canvas->flags &= ~MOD_DPAINT_PREVIEW_READY; /* loop through surfaces */ for (; surface; surface=surface->next) { @@ -1651,7 +1657,6 @@ static struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData } } } - pmd->canvas->flags |= MOD_DPAINT_PREVIEW_READY; } } @@ -1711,29 +1716,7 @@ static struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData if (surface->flags & MOD_DPAINT_PREVIEW) { /* Save preview results to weight layer, to be * able to share same drawing methods */ - MFace *mface = result->getFaceArray(result); - int numOfFaces = result->getNumFaces(result); - int i; - MCol *col = result->getFaceDataArray(result, CD_WEIGHT_MCOL); - if (!col) col = CustomData_add_layer(&result->faceData, CD_WEIGHT_MCOL, CD_CALLOC, NULL, numOfFaces); - - if (col) { - #pragma omp parallel for schedule(static) - for (i=0; i<numOfFaces; i++) { - float temp_color[3]; - int j = (mface[i].v4) ? 4 : 3; - while (j--) { - int index = *((&mface[i].v1)+j); - - weight_to_rgb(temp_color, weight[index]); - col[i*4+j].r = FTOCHAR(temp_color[2]); - col[i*4+j].g = FTOCHAR(temp_color[1]); - col[i*4+j].b = FTOCHAR(temp_color[0]); - col[i*4+j].a = 255; - } - } - pmd->canvas->flags |= MOD_DPAINT_PREVIEW_READY; - } + DM_update_weight_mcol(ob, result, 0, weight, 0, NULL); } /* apply weights into a vertex group, if doesnt exists add a new layer */ @@ -1923,8 +1906,8 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh x = px + neighX[n_index]; y = py + neighY[n_index]; - if (x<0 || x>=w) return -1; - if (y<0 || y>=h) return -1; + if (x<0 || x>=w) return OUT_OF_TEXTURE; + if (y<0 || y>=h) return OUT_OF_TEXTURE; tPoint = &tempPoints[x+w*y]; /* UV neighbour */ cPoint = &tempPoints[px+w*py]; /* Origin point */ @@ -2037,8 +2020,8 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh } } - /* If none found return -1 */ - if (target_face == -1) return -1; + /* If none found pixel is on mesh edge */ + if (target_face == -1) return ON_MESH_EDGE; /* * If target face is connected in UV space as well, just use original index @@ -2076,15 +2059,15 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh final_pixel[1] = (int)floor(pixel[1]); /* If current pixel uv is outside of texture */ - if (final_pixel[0] < 0 || final_pixel[0] >= w) return -1; - if (final_pixel[1] < 0 || final_pixel[1] >= h) return -1; + if (final_pixel[0] < 0 || final_pixel[0] >= w) return OUT_OF_TEXTURE; + if (final_pixel[1] < 0 || final_pixel[1] >= h) return OUT_OF_TEXTURE; final_index = final_pixel[0] + w * final_pixel[1]; /* If we ended up to our origin point ( mesh has smaller than pixel sized faces) */ - if (final_index == (px+w*py)) return -1; + if (final_index == (px+w*py)) return NOT_FOUND; /* If found pixel still lies on wrong face ( mesh has smaller than pixel sized faces) */ - if (tempPoints[final_index].face_index != target_face) return -1; + if (tempPoints[final_index].face_index != target_face) return NOT_FOUND; /* * If final point is an "edge pixel", use it's "real" neighbour instead @@ -2466,11 +2449,14 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface) * If not found, -1 is returned */ int n_target = dynamicPaint_findNeighbourPixel(tempPoints, dm, uvname, w, h, tx, ty, i); - if (n_target != -1) { + if (n_target >= 0) { ed->n_target[n_pos] = final_index[n_target]; ed->n_num[final_index[index]]++; n_pos++; } + else if (n_target == ON_MESH_EDGE || n_target == OUT_OF_TEXTURE) { + ed->flags[final_index[index]] |= ADJ_ON_MESH_EDGE; + } } } } @@ -3171,8 +3157,8 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, mul_m4_v3(brushOb->obmat, mvert[ii].co); boundInsert(&mesh_bb, mvert[ii].co); - /* for project brush calculate average normal */ - if (brush->flags & MOD_DPAINT_PROX_PROJECT) { + /* for proximity project calculate average normal */ + if (brush->flags & MOD_DPAINT_PROX_PROJECT && brush->collision != MOD_DPAINT_COL_VOLUME) { float nor[3]; normal_short_to_float_v3(nor, mvert[ii].no); mul_mat3_m4_v3(brushOb->obmat, nor); @@ -3182,7 +3168,7 @@ static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, } } - if (brush->flags & MOD_DPAINT_PROX_PROJECT) { + if (brush->flags & MOD_DPAINT_PROX_PROJECT && brush->collision != MOD_DPAINT_COL_VOLUME) { mul_v3_fl(avg_brushNor, 1.0f/(float)numOfVerts); /* instead of null vector use positive z */ if (!(MIN3(avg_brushNor[0],avg_brushNor[1],avg_brushNor[2]))) @@ -3566,7 +3552,7 @@ static int dynamicPaint_paintParticles(DynamicPaintSurface *surface, /* Proceed only if particle is active */ if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue; else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue; - else if(pa->flag & PARS_NO_DISP || pa->flag & PARS_UNEXIST) continue; + else if(pa->flag & PARS_UNEXIST) continue; /* for debug purposes check if any NAN particle proceeds * For some reason they get past activity check, this should rule most of them out */ @@ -3879,14 +3865,13 @@ static int dynamicPaint_paintSinglePoint(DynamicPaintSurface *surface, float *po /***************************** Dynamic Paint Step / Baking ******************************/ /* -* Calculate current frame neighbouring point distances -* and direction vectors +* Calculate current frame distances and directions for adjacency data */ -static void dynamicPaint_prepareNeighbourData(DynamicPaintSurface *surface, int force_init) +static void dynamicPaint_prepareAdjacencyData(DynamicPaintSurface *surface, int force_init) { PaintSurfaceData *sData = surface->data; PaintBakeData *bData = sData->bData; - BakeNeighPoint *bNeighs; + BakeAdjPoint *bNeighs; PaintAdjData *adj_data = sData->adj_data; Vec3f *realCoord = bData->realCoord; int index; @@ -3894,7 +3879,7 @@ static void dynamicPaint_prepareNeighbourData(DynamicPaintSurface *surface, int if ((!surface_usesAdjDistance(surface) && !force_init) || !sData->adj_data) return; if (bData->bNeighs) MEM_freeN(bData->bNeighs); - bNeighs = bData->bNeighs = MEM_mallocN(sData->adj_data->total_targets*sizeof(struct BakeNeighPoint),"PaintEffectBake"); + bNeighs = bData->bNeighs = MEM_mallocN(sData->adj_data->total_targets*sizeof(struct BakeAdjPoint),"PaintEffectBake"); if (!bNeighs) return; #pragma omp parallel for schedule(static) @@ -3933,7 +3918,7 @@ static void dynamicPaint_prepareNeighbourData(DynamicPaintSurface *surface, int /* find two adjacency points (closest_id) and influence (closest_d) to move paint towards when affected by a force */ void surface_determineForceTargetPoints(PaintSurfaceData *sData, int index, float force[3], float closest_d[2], int closest_id[2]) { - BakeNeighPoint *bNeighs = sData->bData->bNeighs; + BakeAdjPoint *bNeighs = sData->bData->bNeighs; int numOfNeighs = sData->adj_data->n_num[index]; int i; @@ -4002,7 +3987,7 @@ static void dynamicPaint_doSmudge(DynamicPaintSurface *surface, DynamicPaintBrus { PaintSurfaceData *sData = surface->data; PaintBakeData *bData = sData->bData; - BakeNeighPoint *bNeighs = sData->bData->bNeighs; + BakeAdjPoint *bNeighs = sData->bData->bNeighs; int index, steps, step; float eff_scale, max_velocity = 0.0f; @@ -4161,7 +4146,7 @@ static int dynamicPaint_prepareEffectStep(DynamicPaintSurface *surface, Scene *s static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force, PaintPoint *prevPoint, float timescale, float steps) { PaintSurfaceData *sData = surface->data; - BakeNeighPoint *bNeighs = sData->bData->bNeighs; + BakeAdjPoint *bNeighs = sData->bData->bNeighs; float distance_scale = getSurfaceDimension(sData)/CANVAS_REL_SIZE; int index; timescale /= steps; @@ -4190,7 +4175,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force /* Loop through neighbouring points */ for (i=0; i<numOfNeighs; i++) { int n_index = sData->adj_data->n_index[index]+i; - float w_factor /* , p_alpha = pPoint->e_alpha */ /* UNUSED */; + float w_factor; PaintPoint *ePoint = &prevPoint[sData->adj_data->n_target[n_index]]; float speed_scale = (bNeighs[n_index].dist<eff_scale) ? 1.0f : eff_scale/bNeighs[n_index].dist; float color_mix = (MIN3(ePoint->wetness, pPoint->wetness, 1.0f))*0.25f*surface->color_spread_speed; @@ -4327,7 +4312,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescale) { PaintSurfaceData *sData = surface->data; - BakeNeighPoint *bNeighs = sData->bData->bNeighs; + BakeAdjPoint *bNeighs = sData->bData->bNeighs; int index; int steps, ss; float dt, min_dist, damp_factor; @@ -4760,8 +4745,8 @@ static int dynamicPaint_generateBakeData(DynamicPaintSurface *surface, Scene *sc /* generate surface space partitioning grid */ surfaceGenerateGrid(surface); - /* calculate current frame neighbouring point distances and global dirs */ - dynamicPaint_prepareNeighbourData(surface, 0); + /* calculate current frame adjacency point distances and global dirs */ + dynamicPaint_prepareAdjacencyData(surface, 0); /* Copy current frame vertices to check against in next frame */ copy_m4_m4(bData->prev_obmat, ob->obmat); @@ -4844,7 +4829,7 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su if (!sData->adj_data) dynamicPaint_initAdjacencyData(surface, 1); if (!bData->bNeighs) - dynamicPaint_prepareNeighbourData(surface, 1); + dynamicPaint_prepareAdjacencyData(surface, 1); } /* update object data on this subframe */ diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 00a2de369a3..757d3ddf9ac 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1852,6 +1852,9 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase while(step < tf) { + // damping velocity for artistic reasons + mul_lfvectorS(id->V, id->V, clmd->sim_parms->vel_damping, numverts); + // calculate forces cloth_calc_force(clmd, frame, id->F, id->X, id->V, id->dFdV, id->dFdX, effectors, step, id->M); diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 5a389019519..911d303b4cf 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -142,6 +142,19 @@ int modifier_supportsMapping(ModifierData *md) (mti->flags & eModifierTypeFlag_SupportsMapping)); } +int modifier_isPreview(ModifierData *md) +{ + ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + if (!(mti->flags & eModifierTypeFlag_UsesPreview)) + return FALSE; + + if (md->mode & eModifierMode_Realtime) + return TRUE; + + return FALSE; +} + ModifierData *modifiers_findByType(Object *ob, ModifierType type) { ModifierData *md = ob->modifiers.first; @@ -385,6 +398,21 @@ LinkNode *modifiers_calcDataMasks(struct Scene *scene, Object *ob, ModifierData return dataMasks; } +ModifierData *modifiers_getLastPreview(struct Scene *scene, ModifierData *md, int required_mode) +{ + ModifierData *tmp_md = NULL; + + if (required_mode != eModifierMode_Realtime) + return tmp_md; + + /* Find the latest modifier in stack generating preview. */ + for(; md; md = md->next) { + if(modifier_isEnabled(scene, md, required_mode) && modifier_isPreview(md)) + tmp_md = md; + } + return tmp_md; +} + ModifierData *modifiers_getVirtualModifierList(Object *ob) { /* Kinda hacky, but should be fine since we are never @@ -545,6 +573,20 @@ int modifiers_isCorrectableDeformed(Object *ob) return 0; } +/* Check whether the given object has a modifier in its stack that uses WEIGHT_MCOL CD layer + * to preview something... Used by DynamicPaint and WeightVG currently. */ +int modifiers_isPreview(Object *ob) +{ + ModifierData *md = ob->modifiers.first; + + for (; md; md = md->next) { + if (modifier_isPreview(md)) + return TRUE; + } + + return FALSE; +} + int modifiers_indexInObject(Object *ob, ModifierData *md_seek) { int i= 0; diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index fd184b9def4..12f403d028f 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -1448,9 +1448,17 @@ void BKE_nla_validate_state (AnimData *adt) */ // TODO: 1 solution is to tie this in with auto-blending... if (strip->extendmode != NLASTRIP_EXTEND_NOTHING) { + /* 1) First strip must be set to extend hold, otherwise, stuff before acts dodgy + * 2) Only overwrite extend mode if *not* changing it will most probably result in + * occlusion problems, which will occur iff + * - blendmode = REPLACE + * - all channels the same (this is fiddly to test, so is currently assumed) + * + * Should fix problems such as [#29869] + */ if (strip == fstrip) strip->extendmode= NLASTRIP_EXTEND_HOLD; - else + else if (strip->blendmode == NLASTRIP_MODE_REPLACE) strip->extendmode= NLASTRIP_EXTEND_HOLD_FORWARD; } } @@ -1542,6 +1550,34 @@ short BKE_nla_tweakmode_enter (AnimData *adt) break; } } + + /* There are situations where we may have multiple strips selected and we want to enter tweakmode on all + * of those at once. Usually in those cases, it will usually just be a single strip per AnimData. + * In such cases, compromise and take the last selected track and/or last selected strip [#28468] + */ + if (activeTrack == NULL) { + /* try last selected track for active strip */ + for (nlt = adt->nla_tracks.last; nlt; nlt = nlt->prev) { + if (nlt->flag & NLATRACK_SELECTED) { + /* assume this is the active track */ + activeTrack= nlt; + + /* try to find active strip */ + activeStrip= BKE_nlastrip_find_active(nlt); + break; + } + } + } + if ((activeTrack) && (activeStrip == NULL)) { + /* no active strip in active or last selected track; compromise for first selected (assuming only single)... */ + for (strip = activeTrack->strips.first; strip; strip= strip->next) { + if (strip->flag & (NLASTRIP_FLAG_SELECT|NLASTRIP_FLAG_ACTIVE)) { + activeStrip = strip; + break; + } + } + } + if ELEM3(NULL, activeTrack, activeStrip, activeStrip->act) { if (G.f & G_DEBUG) { printf("NLA tweakmode enter - neither active requirement found \n"); diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 96ee2bd0349..b72abcd79f4 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1881,6 +1881,7 @@ static void registerShaderNodes(bNodeTreeType *ttype) register_node_type_sh_material(ttype); register_node_type_sh_camera(ttype); register_node_type_sh_gamma(ttype); + register_node_type_sh_brightcontrast(ttype); register_node_type_sh_value(ttype); register_node_type_sh_rgb(ttype); register_node_type_sh_mix_rgb(ttype); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 4afe9412786..5a64da7354e 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -1126,6 +1126,9 @@ static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, D fprintf(stderr,"Particle distribution error: Nothing to emit from!\n"); if(dm != finaldm) dm->release(dm); + + BLI_kdtree_free(tree); + return 0; } @@ -3477,6 +3480,7 @@ static void do_hair_dynamics(ParticleSimulationData *sim) int totedge; int k; float hairmat[4][4]; + float (*deformedVerts)[3]; if(!psys->clmd) { psys->clmd = (ClothModifierData*)modifier_new(eModifierType_Cloth); @@ -3570,7 +3574,15 @@ static void do_hair_dynamics(ParticleSimulationData *sim) psys->clmd->point_cache = psys->pointcache; psys->clmd->sim_parms->effector_weights = psys->part->effector_weights; - psys->hair_out_dm = clothModifier_do(psys->clmd, sim->scene, sim->ob, dm); + deformedVerts = MEM_callocN(sizeof(*deformedVerts)*dm->getNumVerts(dm), "do_hair_dynamics vertexCos"); + psys->hair_out_dm = CDDM_copy(dm); + psys->hair_out_dm->getVertCos(psys->hair_out_dm, deformedVerts); + + clothModifier_do(psys->clmd, sim->scene, sim->ob, dm, deformedVerts); + + CDDM_apply_vert_coords(psys->hair_out_dm, deformedVerts); + + MEM_freeN(deformedVerts); psys->clmd->sim_parms->effector_weights = NULL; } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index d6b85b80f20..2aa53e2484d 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -538,6 +538,8 @@ Scene *add_scene(const char *name) sce->gm.recastData.detailsampledist = 6.0f; sce->gm.recastData.detailsamplemaxerror = 1.0f; + sce->gm.exitkey = 218; // Blender key code for ESC + sound_create_scene(sce); return sce; diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 60941ef78a3..424f97f57ed 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -77,6 +77,9 @@ #include "BKE_smoke.h" +/* UNUSED so far, may be enabled later */ +/* #define USE_SMOKE_COLLISION_DM */ + #ifdef WITH_SMOKE #ifdef _WIN32 @@ -617,9 +620,11 @@ static void smokeModifier_freeCollision(SmokeModifierData *smd) smd->coll->bvhtree = NULL; } +#ifdef USE_SMOKE_COLLISION_DM if(smd->coll->dm) smd->coll->dm->release(smd->coll->dm); smd->coll->dm = NULL; +#endif MEM_freeN(smd->coll); smd->coll = NULL; @@ -682,9 +687,11 @@ void smokeModifier_reset(struct SmokeModifierData *smd) smd->coll->bvhtree = NULL; } +#ifdef USE_SMOKE_COLLISION_DM if(smd->coll->dm) smd->coll->dm->release(smd->coll->dm); smd->coll->dm = NULL; +#endif } } @@ -772,7 +779,10 @@ void smokeModifier_createType(struct SmokeModifierData *smd) smd->coll->points = NULL; smd->coll->numpoints = 0; smd->coll->bvhtree = NULL; + +#ifdef USE_SMOKE_COLLISION_DM smd->coll->dm = NULL; +#endif } } } @@ -1339,11 +1349,13 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM { // XXX TODO smd->time = scene->r.cfra; - + +#ifdef USE_SMOKE_COLLISION_DM if(smd->coll->dm) smd->coll->dm->release(smd->coll->dm); smd->coll->dm = CDDM_copy(dm); +#endif // rigid movement support copy_m4_m4(smd->coll->mat_old, smd->coll->mat); diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 8e5cc8c48e3..ba48db588c4 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -808,13 +808,14 @@ static int txt_utf8_len(const char *src) void txt_move_up(Text *text, short sel) { TextLine **linep; - int *charp, old; + int *charp; + /* int old; */ /* UNUSED */ if (!text) return; if(sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; - old= *charp; + /* old= *charp; */ /* UNUSED */ if((*linep)->prev) { int index = txt_utf8_offset_to_index((*linep)->line, *charp); @@ -834,13 +835,14 @@ void txt_move_up(Text *text, short sel) void txt_move_down(Text *text, short sel) { TextLine **linep; - int *charp, old; + int *charp; + /* int old; */ /* UNUSED */ if (!text) return; if(sel) txt_curs_sel(text, &linep, &charp); else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); } if (!*linep) return; - old= *charp; + /* old= *charp; */ /* UNUSED */ if((*linep)->next) { int index = txt_utf8_offset_to_index((*linep)->line, *charp); @@ -1897,6 +1899,10 @@ static unsigned int txt_undo_read_unicode(const char *undo_buf, int *undo_pos, s break; case 4: /* 32-bit unicode symbol */ unicode= txt_undo_read_uint32(undo_buf, undo_pos); + default: + /* should never happen */ + BLI_assert(0); + unicode= 0; } return unicode; diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 73170612ff7..9bff5e3003d 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -242,6 +242,7 @@ MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, ListBase *tr track->margin= settings->default_margin; track->pattern_match= settings->default_pattern_match; track->frames_limit= settings->default_frames_limit; + track->flag= settings->default_flag; memset(&marker, 0, sizeof(marker)); marker.pos[0]= x; @@ -395,6 +396,13 @@ int BKE_tracking_has_marker(MovieTrackingTrack *track, int framenr) return BKE_tracking_exact_marker(track, framenr) != 0; } +int BKE_tracking_has_enabled_marker(MovieTrackingTrack *track, int framenr) +{ + MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); + + return marker && (marker->flag & MARKER_DISABLED) == 0; +} + void BKE_tracking_free_track(MovieTrackingTrack *track) { if(track->markers) MEM_freeN(track->markers); @@ -1062,7 +1070,7 @@ void BKE_tracking_disable_imbuf_channels(ImBuf *ibuf, int disable_red, int disab static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int grayscale) { BKE_tracking_disable_imbuf_channels(ibuf, track->flag&TRACK_DISABLE_RED, - track->flag&TRACK_DISABLE_GREEN, track->flag&TRACK_DISABLE_RED, grayscale); + track->flag&TRACK_DISABLE_GREEN, track->flag&TRACK_DISABLE_BLUE, grayscale); } static ImBuf *get_area_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, @@ -1741,8 +1749,8 @@ static int count_tracks_on_both_keyframes(MovieTracking *tracking, ListBase *tra track= tracksbase->first; while(track) { - if(BKE_tracking_has_marker(track, frame1)) - if(BKE_tracking_has_marker(track, frame2)) + if(BKE_tracking_has_enabled_marker(track, frame1)) + if(BKE_tracking_has_enabled_marker(track, frame2)) tot++; track= track->next; @@ -1758,7 +1766,7 @@ int BKE_tracking_can_reconstruct(MovieTracking *tracking, MovieTrackingObject *o ListBase *tracksbase= BKE_tracking_object_tracks(tracking, object); if(count_tracks_on_both_keyframes(tracking, tracksbase)<8) { - BLI_strncpy(error_msg, "At least 8 tracks on both of keyframes are needed for reconstruction", error_size); + BLI_strncpy(error_msg, "At least 8 common tracks on both of keyframes are needed for reconstruction", error_size); return 0; } @@ -1838,7 +1846,7 @@ MovieReconstructContext* BKE_tracking_reconstruction_context_new(MovieTracking * context->k1= camera->k1; context->k2= camera->k2; - context->k2= camera->k2; + context->k3= camera->k3; return context; } |