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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Eagar <joeedh@gmail.com>2011-05-09 03:43:18 +0400
committerJoseph Eagar <joeedh@gmail.com>2011-05-09 03:43:18 +0400
commit6ef77cf95accc3cb914e7efd964118ce6e9521cf (patch)
tree1d8dbf95355038c93f79f9053a0bf1d55b561ec3 /source/blender/blenkernel/intern
parent3462ddf17f38eb61fc3bb2751d55de15a47455c3 (diff)
parent770119d16f7dbee99a60d19540818892c970c4e2 (diff)
=bmesh= merge from trunk at r36529
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c83
-rw-r--r--source/blender/blenkernel/intern/action.c13
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c64
-rw-r--r--source/blender/blenkernel/intern/armature.c48
-rw-r--r--source/blender/blenkernel/intern/blender.c27
-rw-r--r--source/blender/blenkernel/intern/boids.c2
-rw-r--r--source/blender/blenkernel/intern/brush.c43
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c60
-rw-r--r--source/blender/blenkernel/intern/cloth.c2
-rw-r--r--source/blender/blenkernel/intern/collision.c882
-rw-r--r--source/blender/blenkernel/intern/colortools.c2
-rw-r--r--source/blender/blenkernel/intern/constraint.c4
-rw-r--r--source/blender/blenkernel/intern/context.c11
-rw-r--r--source/blender/blenkernel/intern/curve.c72
-rw-r--r--source/blender/blenkernel/intern/deform.c3
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c22
-rw-r--r--source/blender/blenkernel/intern/displist.c6
-rw-r--r--source/blender/blenkernel/intern/exotic.c2485
-rw-r--r--source/blender/blenkernel/intern/font.c68
-rw-r--r--source/blender/blenkernel/intern/idprop.c56
-rw-r--r--source/blender/blenkernel/intern/image.c175
-rw-r--r--source/blender/blenkernel/intern/image_gen.c18
-rw-r--r--source/blender/blenkernel/intern/implicit.c99
-rw-r--r--source/blender/blenkernel/intern/ipo.c70
-rw-r--r--source/blender/blenkernel/intern/lattice.c23
-rw-r--r--source/blender/blenkernel/intern/library.c4
-rw-r--r--source/blender/blenkernel/intern/material.c38
-rw-r--r--source/blender/blenkernel/intern/mball.c68
-rw-r--r--source/blender/blenkernel/intern/mesh.c67
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c4
-rw-r--r--source/blender/blenkernel/intern/node.c81
-rw-r--r--source/blender/blenkernel/intern/object.c113
-rw-r--r--source/blender/blenkernel/intern/particle.c90
-rw-r--r--source/blender/blenkernel/intern/particle_system.c4
-rw-r--r--source/blender/blenkernel/intern/pointcache.c27
-rw-r--r--source/blender/blenkernel/intern/report.c2
-rw-r--r--source/blender/blenkernel/intern/sca.c12
-rw-r--r--source/blender/blenkernel/intern/scene.c28
-rwxr-xr-xsource/blender/blenkernel/intern/seqcache.c4
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c106
-rw-r--r--source/blender/blenkernel/intern/sequencer.c93
-rw-r--r--source/blender/blenkernel/intern/sketch.c2
-rw-r--r--source/blender/blenkernel/intern/smoke.c20
-rw-r--r--source/blender/blenkernel/intern/softbody.c88
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c58
-rw-r--r--source/blender/blenkernel/intern/text.c54
-rw-r--r--source/blender/blenkernel/intern/texture.c50
-rw-r--r--source/blender/blenkernel/intern/unit.c2
-rw-r--r--source/blender/blenkernel/intern/world.c19
-rw-r--r--source/blender/blenkernel/intern/writeavi.c2
50 files changed, 2063 insertions, 3311 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 421e8a89137..a8617773658 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1173,11 +1173,20 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
modifier_setError(md, "Modifier requires original data, bad stack position.");
continue;
}
- if(sculpt_mode && (!has_multires || multires_applied))
- if(mti->type != eModifierTypeType_OnlyDeform || multires_applied) {
+ if(sculpt_mode && (!has_multires || multires_applied)) {
+ int unsupported= 0;
+
+ if(scene->toolsettings->sculpt->flags & SCULPT_ONLY_DEFORM)
+ unsupported|= mti->type != eModifierTypeType_OnlyDeform;
+
+ unsupported|= md->type == eModifierType_Multires && ((MultiresModifierData*)md)->sculptlvl==0;
+ unsupported|= multires_applied;
+
+ if(unsupported) {
modifier_setError(md, "Not supported in sculpt mode.");
continue;
}
+ }
if(needMapping && !modifier_supportsMapping(md)) continue;
if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue;
@@ -1216,7 +1225,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
* to avoid giving bogus normals to the next modifier see: [#23673] */
if(dm && isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
/* XXX, this covers bug #23673, but we may need normal calc for other types */
- if(dm->type == DM_TYPE_CDDM) {
+ if(dm && dm->type == DM_TYPE_CDDM) {
CDDM_apply_vert_coords(dm, deformedVerts);
CDDM_calc_normals(dm);
}
@@ -1931,9 +1940,8 @@ static void GetPosition(const SMikkTSpaceContext * pContext, float fPos[], const
{
//assert(vert_index>=0 && vert_index<4);
SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData;
- unsigned int indices[] = { pMesh->mface[face_num].v1, pMesh->mface[face_num].v2,
- pMesh->mface[face_num].v3, pMesh->mface[face_num].v4 };
- VECCOPY(fPos, pMesh->mvert[indices[vert_index]].co);
+ const float *co= pMesh->mvert[(&pMesh->mface[face_num].v1)[vert_index]].co;
+ VECCOPY(fPos, co);
}
static void GetTextureCoordinate(const SMikkTSpaceContext * pContext, float fUV[], const int face_num, const int vert_index)
@@ -1941,17 +1949,13 @@ static void GetTextureCoordinate(const SMikkTSpaceContext * pContext, float fUV[
//assert(vert_index>=0 && vert_index<4);
SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData;
- if(pMesh->mtface!=NULL)
- {
+ if(pMesh->mtface!=NULL) {
float * uv = pMesh->mtface[face_num].uv[vert_index];
fUV[0]=uv[0]; fUV[1]=uv[1];
}
- else
- {
- unsigned int indices[] = { pMesh->mface[face_num].v1, pMesh->mface[face_num].v2,
- pMesh->mface[face_num].v3, pMesh->mface[face_num].v4 };
-
- map_to_sphere( &fUV[0], &fUV[1],pMesh->orco[indices[vert_index]][0], pMesh->orco[indices[vert_index]][1], pMesh->orco[indices[vert_index]][2]);
+ else {
+ const float *orco= pMesh->orco[(&pMesh->mface[face_num].v1)[vert_index]];
+ map_to_sphere( &fUV[0], &fUV[1], orco[0], orco[1], orco[2]);
}
}
@@ -1959,38 +1963,30 @@ static void GetNormal(const SMikkTSpaceContext * pContext, float fNorm[], const
{
//assert(vert_index>=0 && vert_index<4);
SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData;
- unsigned int indices[] = { pMesh->mface[face_num].v1, pMesh->mface[face_num].v2,
- pMesh->mface[face_num].v3, pMesh->mface[face_num].v4 };
const int smoothnormal = (pMesh->mface[face_num].flag & ME_SMOOTH);
- if(!smoothnormal) // flat
- {
- if(pMesh->precomputedFaceNormals)
- {
+ if(!smoothnormal) { // flat
+ if(pMesh->precomputedFaceNormals) {
VECCOPY(fNorm, &pMesh->precomputedFaceNormals[3*face_num]);
}
- else
- {
- float nor[3];
- float * p0, * p1, * p2;
- const int iGetNrVerts = pMesh->mface[face_num].v4!=0 ? 4 : 3;
- p0 = pMesh->mvert[indices[0]].co; p1 = pMesh->mvert[indices[1]].co; p2 = pMesh->mvert[indices[2]].co;
- if(iGetNrVerts==4)
- {
- float * p3 = pMesh->mvert[indices[3]].co;
- normal_quad_v3( nor, p0, p1, p2, p3);
+ else {
+ MFace *mf= &pMesh->mface[face_num];
+ float *p0= pMesh->mvert[mf->v1].co;
+ float *p1= pMesh->mvert[mf->v2].co;
+ float *p2= pMesh->mvert[mf->v3].co;
+
+ if(mf->v4) {
+ float *p3 = pMesh->mvert[mf->v4].co;
+ normal_quad_v3(fNorm, p0, p1, p2, p3);
}
else {
- normal_tri_v3(nor, p0, p1, p2);
+ normal_tri_v3(fNorm, p0, p1, p2);
}
- VECCOPY(fNorm, nor);
}
}
- else
- {
- short *no = pMesh->mvert[indices[vert_index]].no;
+ else {
+ const short *no= pMesh->mvert[(&pMesh->mface[face_num].v1)[vert_index]].no;
normal_short_to_float_v3(fNorm, no);
- normalize_v3(fNorm); /* XXX, is this needed */
}
}
static void SetTSpace(const SMikkTSpaceContext * pContext, const float fvTangent[], const float fSign, const int face_num, const int iVert)
@@ -2047,14 +2043,10 @@ void DM_add_tangent_layer(DerivedMesh *dm)
// new computation method
iCalcNewMethod = 1;
- if(iCalcNewMethod!=0)
- {
- SGLSLMeshToTangent mesh2tangent;
- SMikkTSpaceContext sContext;
- SMikkTSpaceInterface sInterface;
- memset(&mesh2tangent, 0, sizeof(SGLSLMeshToTangent));
- memset(&sContext, 0, sizeof(SMikkTSpaceContext));
- memset(&sInterface, 0, sizeof(SMikkTSpaceInterface));
+ if(iCalcNewMethod != 0) {
+ SGLSLMeshToTangent mesh2tangent= {0};
+ SMikkTSpaceContext sContext= {0};
+ SMikkTSpaceInterface sInterface= {0};
mesh2tangent.precomputedFaceNormals = nors;
mesh2tangent.mtface = mtface;
@@ -2077,8 +2069,7 @@ void DM_add_tangent_layer(DerivedMesh *dm)
iCalcNewMethod = genTangSpaceDefault(&sContext);
}
- if(!iCalcNewMethod)
- {
+ if(!iCalcNewMethod) {
/* sum tangents at connected vertices */
for(i=0, tf=mtface, mf=mface; i < totface; mf++, tf++, i++) {
v1= &mvert[mf->v1];
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 5b42948072f..5b49d9a9841 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -95,6 +95,7 @@ bAction *add_empty_action(const char name[])
void make_local_action(bAction *act)
{
// Object *ob;
+ Main *bmain= G.main;
bAction *actn;
int local=0, lib=0;
@@ -102,7 +103,7 @@ void make_local_action(bAction *act)
if (act->id.us==1) {
act->id.lib= NULL;
act->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)act, NULL);
+ new_id(&bmain->action, (ID *)act, NULL);
return;
}
@@ -121,7 +122,7 @@ void make_local_action(bAction *act)
act->id.lib= NULL;
act->id.flag= LIB_LOCAL;
//make_local_action_channels(act);
- new_id(NULL, (ID *)act, NULL);
+ new_id(&bmain->action, (ID *)act, NULL);
}
else if(local && lib) {
actn= copy_action(act);
@@ -419,11 +420,11 @@ bPoseChannel *verify_pose_channel(bPose *pose, const char *name)
return NULL;
/* See if this channel exists */
- for (chan=pose->chanbase.first; chan; chan=chan->next) {
- if (!strcmp (name, chan->name))
- return chan;
+ chan= BLI_findstring(&pose->chanbase, name, offsetof(bPoseChannel, name));
+ if(chan) {
+ return chan;
}
-
+
/* If not, create it and add it */
chan = MEM_callocN(sizeof(bPoseChannel), "verifyPoseChannel");
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 2708239a4c3..5198172c205 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -194,7 +194,7 @@ AnimData *BKE_copy_animdata (AnimData *adt, const short do_action)
dadt= MEM_dupallocN(adt);
/* make a copy of action - at worst, user has to delete copies... */
- if(do_action) {
+ if (do_action) {
dadt->action= copy_action(adt->action);
dadt->tmpact= copy_action(adt->tmpact);
}
@@ -216,11 +216,11 @@ AnimData *BKE_copy_animdata (AnimData *adt, const short do_action)
return dadt;
}
-int BKE_copy_animdata_id(struct ID *id_to, struct ID *id_from, const short do_action)
+int BKE_copy_animdata_id (ID *id_to, ID *id_from, const short do_action)
{
AnimData *adt;
- if((id_to && id_from) && (GS(id_to->name) != GS(id_from->name)))
+ if ((id_to && id_from) && (GS(id_to->name) != GS(id_from->name)))
return 0;
BKE_free_animdata(id_to);
@@ -237,13 +237,13 @@ int BKE_copy_animdata_id(struct ID *id_to, struct ID *id_from, const short do_ac
void BKE_copy_animdata_id_action(struct ID *id)
{
AnimData *adt= BKE_animdata_from_id(id);
- if(adt) {
- if(adt->action) {
- ((ID *)adt->action)->us--;
+ if (adt) {
+ if (adt->action) {
+ id_us_min((ID *)adt->action);
adt->action= copy_action(adt->action);
}
- if(adt->tmpact) {
- ((ID *)adt->tmpact)->us--;
+ if (adt->tmpact) {
+ id_us_min((ID *)adt->tmpact);
adt->tmpact= copy_action(adt->tmpact);
}
}
@@ -1199,6 +1199,39 @@ static void animsys_evaluate_drivers (PointerRNA *ptr, AnimData *adt, float ctim
/* ***************************************** */
/* Actions Evaluation */
+/* strictly not necessary for actual "evaluation", but it is a useful safety check
+ * to reduce the amount of times that users end up having to "revive" wrongly-assigned
+ * actions
+ */
+static void action_idcode_patch_check (ID *id, bAction *act)
+{
+ int idcode = 0;
+
+ /* just in case */
+ if (ELEM(NULL, id, act))
+ return;
+ else
+ idcode = GS(id->name);
+
+ /* the actual checks... hopefully not too much of a performance hit in the long run... */
+ if (act->idroot == 0) {
+ /* use the current root if not set already (i.e. newly created actions and actions from 2.50-2.57 builds)
+ * - this has problems if there are 2 users, and the first one encountered is the invalid one
+ * in which case, the user will need to manually fix this (?)
+ */
+ act->idroot = idcode;
+ }
+ else if (act->idroot != idcode) {
+ /* only report this error if debug mode is enabled (to save performance everywhere else) */
+ if (G.f & G_DEBUG) {
+ printf("AnimSys Safety Check Failed: Action '%s' is not meant to be used from ID-Blocks of type %d such as '%s'\n",
+ act->id.name+2, idcode, id->name);
+ }
+ }
+}
+
+/* ----------------------------------------- */
+
/* Evaluate Action Group */
void animsys_evaluate_action_group (PointerRNA *ptr, bAction *act, bActionGroup *agrp, AnimMapper *remap, float ctime)
{
@@ -1208,6 +1241,8 @@ void animsys_evaluate_action_group (PointerRNA *ptr, bAction *act, bActionGroup
if ELEM(NULL, act, agrp) return;
if ((remap) && (remap->target != act)) remap= NULL;
+ action_idcode_patch_check(ptr->id.data, act);
+
/* if group is muted, don't evaluated any of the F-Curve */
if (agrp->flag & AGRP_MUTED)
return;
@@ -1231,6 +1266,8 @@ void animsys_evaluate_action (PointerRNA *ptr, bAction *act, AnimMapper *remap,
if (act == NULL) return;
if ((remap) && (remap->target != act)) remap= NULL;
+ action_idcode_patch_check(ptr->id.data, act);
+
/* calculate then execute each curve */
animsys_evaluate_fcurves(ptr, &act->curves, remap, ctime);
}
@@ -1630,6 +1667,17 @@ static void nlastrip_evaluate_actionclip (PointerRNA *ptr, ListBase *channels, L
FCurve *fcu;
float evaltime;
+ /* sanity checks for action */
+ if (strip == NULL)
+ return;
+
+ if (strip->act == NULL) {
+ printf("NLA-Strip Eval Error: Strip '%s' has no Action\n", strip->name);
+ return;
+ }
+
+ action_idcode_patch_check(ptr->id.data, strip->act);
+
/* join this strip's modifiers to the parent's modifiers (own modifiers first) */
nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &strip->modifiers, modifiers);
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 6a5cc53ef23..3f361fe6b66 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -138,39 +138,42 @@ void free_armature(bArmature *arm)
void make_local_armature(bArmature *arm)
{
+ Main *bmain= G.main;
int local=0, lib=0;
Object *ob;
- bArmature *newArm;
-
- if (arm->id.lib==NULL)
- return;
+
+ if (arm->id.lib==NULL) return;
if (arm->id.us==1) {
arm->id.lib= NULL;
arm->id.flag= LIB_LOCAL;
- new_id(NULL, (ID*)arm, NULL);
+ new_id(&bmain->armature, (ID*)arm, NULL);
return;
}
-
+
+ for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) {
+ if(ob->data == arm) {
+ if(ob->id.lib) lib= 1;
+ else local= 1;
+ }
+ }
+
if(local && lib==0) {
arm->id.lib= NULL;
arm->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)arm, NULL);
+ new_id(&bmain->armature, (ID *)arm, NULL);
}
else if(local && lib) {
- newArm= copy_armature(arm);
- newArm->id.us= 0;
+ bArmature *armn= copy_armature(arm);
+ armn->id.us= 0;
- ob= G.main->object.first;
- while(ob) {
- if(ob->data==arm) {
-
+ for(ob= bmain->object.first; ob; ob= ob->id.next) {
+ if(ob->data == arm) {
if(ob->id.lib==NULL) {
- ob->data= newArm;
- newArm->id.us++;
+ ob->data= armn;
+ armn->id.us++;
arm->id.us--;
}
}
- ob= ob->id.next;
}
}
}
@@ -215,6 +218,11 @@ bArmature *copy_armature(bArmature *arm)
};
newArm->act_bone= newActBone;
+
+ newArm->edbo= NULL;
+ newArm->act_edbone= NULL;
+ newArm->sketch= NULL;
+
return newArm;
}
@@ -1227,10 +1235,10 @@ void pchan_apply_mat4(bPoseChannel *pchan, float mat[][4], short use_compat)
*/
void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4])
{
- float imat[4][4];
-
- invert_m4_m4(imat, arm_mat);
- mul_m4_m4m4(delta_mat, pose_mat, imat);
+ float imat[4][4];
+
+ invert_m4_m4(imat, arm_mat);
+ mul_m4_m4m4(delta_mat, pose_mat, imat);
}
/* **************** Rotation Mode Conversions ****************************** */
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index c314d476535..29b3bd59e70 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -140,8 +140,12 @@ void initglobals(void)
G.charstart = 0x0000;
G.charmin = 0x0000;
G.charmax = 0xffff;
-
+
+#ifndef WITH_PYTHON_SECURITY /* default */
G.f |= G_SCRIPT_AUTOEXEC;
+#else
+ G.f &= ~G_SCRIPT_AUTOEXEC;
+#endif
}
/***/
@@ -617,24 +621,14 @@ void BKE_reset_undo(void)
/* based on index nr it does a restore */
void BKE_undo_number(bContext *C, int nr)
{
- UndoElem *uel;
- int a=1;
-
- for(uel= undobase.first; uel; uel= uel->next, a++) {
- if(a==nr) break;
- }
- curundo= uel;
+ curundo= BLI_findlink(&undobase, nr - 1);
BKE_undo_step(C, 0);
}
/* go back to the last occurance of name in stack */
void BKE_undo_name(bContext *C, const char *name)
{
- UndoElem *uel;
-
- for(uel= undobase.last; uel; uel= uel->prev)
- if(strcmp(name, uel->name)==0)
- break;
+ UndoElem *uel= BLI_rfindstring(&undobase, name, offsetof(UndoElem, name));
if(uel && uel->prev) {
curundo= uel->prev;
@@ -646,12 +640,7 @@ void BKE_undo_name(bContext *C, const char *name)
int BKE_undo_valid(const char *name)
{
if(name) {
- UndoElem *uel;
-
- for(uel= undobase.last; uel; uel= uel->prev)
- if(strcmp(name, uel->name)==0)
- break;
-
+ UndoElem *uel= BLI_rfindstring(&undobase, name, offsetof(UndoElem, name));
return uel && uel->prev;
}
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index 11ea3384c96..9f808704eee 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -1299,7 +1299,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
bpa->data.mode = eBoidMode_OnLand;
}
/* fly above ground */
- else {
+ else if(bpa->ground) {
pa->state.co[2] = ground_co[2] + pa->size * boids->height;
pa->state.vel[2] = 0.0f;
}
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 96b6ec357f9..fa3b756ae27 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -180,14 +180,20 @@ void free_brush(Brush *brush)
curvemapping_free(brush->curve);
}
+static void extern_local_brush(Brush *brush)
+{
+ id_lib_extern((ID *)brush->mtex.tex);
+}
+
void make_local_brush(Brush *brush)
{
+
/* - only lib users: do nothing
- * - only local users: set flag
- * - mixed: make copy
- */
-
- Brush *brushn;
+ * - only local users: set flag
+ * - mixed: make copy
+ */
+
+ Main *bmain= G.main;
Scene *scene;
int local= 0, lib= 0;
@@ -197,19 +203,22 @@ void make_local_brush(Brush *brush)
/* special case: ima always local immediately */
brush->clone.image->id.lib= NULL;
brush->clone.image->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)brush->clone.image, NULL);
+ new_id(&bmain->brush, (ID *)brush->clone.image, NULL);
+ extern_local_brush(brush);
}
- for(scene= G.main->scene.first; scene; scene=scene->id.next)
+ for(scene= bmain->scene.first; scene && ELEM(0, lib, local); scene=scene->id.next) {
if(paint_brush(&scene->toolsettings->imapaint.paint)==brush) {
if(scene->id.lib) lib= 1;
else local= 1;
}
+ }
if(local && lib==0) {
brush->id.lib= NULL;
brush->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)brush, NULL);
+ new_id(&bmain->brush, (ID *)brush, NULL);
+ extern_local_brush(brush);
/* enable fake user by default */
if (!(brush->id.flag & LIB_FAKEUSER)) {
@@ -218,17 +227,19 @@ void make_local_brush(Brush *brush)
}
}
else if(local && lib) {
- brushn= copy_brush(brush);
+ Brush *brushn= copy_brush(brush);
brushn->id.us= 1; /* only keep fake user */
brushn->id.flag |= LIB_FAKEUSER;
- for(scene= G.main->scene.first; scene; scene=scene->id.next)
- if(paint_brush(&scene->toolsettings->imapaint.paint)==brush)
+ for(scene= bmain->scene.first; scene; scene=scene->id.next) {
+ if(paint_brush(&scene->toolsettings->imapaint.paint)==brush) {
if(scene->id.lib==NULL) {
paint_brush_set(&scene->toolsettings->imapaint.paint, brushn);
brushn->id.us++;
brush->id.us--;
}
+ }
+ }
}
}
@@ -1119,12 +1130,12 @@ float brush_curve_strength_clamp(Brush *br, float p, const float len)
* used for sculpt only */
float brush_curve_strength(Brush *br, float p, const float len)
{
- if(p >= len)
- p= 1.0f;
- else
- p= p/len;
+ if(p >= len)
+ p= 1.0f;
+ else
+ p= p/len;
- return curvemapping_evaluateF(br->curve, 0, p);
+ return curvemapping_evaluateF(br->curve, 0, p);
}
/* TODO: should probably be unified with BrushPainter stuff? */
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index dcbf3898862..210840f00f0 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -193,11 +193,7 @@ static void cdDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
static void cdDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
{
CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
- short *no = cddm->mvert[index].no;
-
- no_r[0] = no[0]/32767.f;
- no_r[1] = no[1]/32767.f;
- no_r[2] = no[2]/32767.f;
+ normal_short_to_float_v3(no_r, cddm->mvert[index].no);
}
static ListBase *cdDM_getFaceMap(Object *ob, DerivedMesh *dm)
@@ -218,8 +214,20 @@ static int can_pbvh_draw(Object *ob, DerivedMesh *dm)
{
CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
Mesh *me= ob->data;
+ int deformed= 0;
+
+ /* active modifiers means extra deformation, which can't be handled correct
+ on bith of PBVH and sculpt "layer" levels, so use PBVH only for internal brush
+ stuff and show final DerivedMesh so user would see actual object shape */
+ deformed|= ob->sculpt->modifiers_active;
+
+ /* as in case with modifiers, we can't synchronize deformation made against
+ PBVH and non-locked keyblock, so also use PBVH only for brushes and
+ final DM to give final result to user */
+ deformed|= ob->sculpt->kb && (ob->shapeflag&OB_SHAPE_LOCK) == 0;
- if(ob->sculpt->modifiers_active) return 0;
+ if(deformed)
+ return 0;
return (cddm->mvert == me->mvert) || ob->sculpt->kb;
}
@@ -244,19 +252,21 @@ static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
this derivedmesh is just original mesh. it's the multires subsurf dm
that this is actually for, to support a pbvh on a modified mesh */
if(!cddm->pbvh && ob->type == OB_MESH) {
+ SculptSession *ss= ob->sculpt;
Mesh *me= ob->data;
cddm->pbvh = BLI_pbvh_new();
cddm->pbvh_draw = can_pbvh_draw(ob, dm);
BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
me->totface, me->totvert);
- if(ob->sculpt->modifiers_active) {
+ if(ss->modifiers_active && ob->derivedDeform) {
+ DerivedMesh *deformdm= ob->derivedDeform;
float (*vertCos)[3];
int totvert;
- totvert= dm->getNumVerts(dm);
+ totvert= deformdm->getNumVerts(deformdm);
vertCos= MEM_callocN(3*totvert*sizeof(float), "cdDM_getPBVH vertCos");
- dm->getVertCos(dm, vertCos);
+ deformdm->getVertCos(deformdm, vertCos);
BLI_pbvh_apply_vertCos(cddm->pbvh, vertCos);
MEM_freeN(vertCos);
}
@@ -589,8 +599,9 @@ static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha
/* there's a conflict here... twosided colors versus culling...? */
/* defined by history, only texture faces have culling option */
/* we need that as mesh option builtin, next to double sided lighting */
- if(col1 && col2)
+ if(col2) {
glEnable(GL_CULL_FACE);
+ }
cdDM_update_normals_from_pbvh(dm);
@@ -606,26 +617,26 @@ static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha
glBegin(glmode = new_glmode);
}
- glColor3ub(cp1[0], cp1[1], cp1[2]);
+ glColor3ubv(cp1+0);
glVertex3fv(mvert[mface->v1].co);
- glColor3ub(cp1[4], cp1[5], cp1[6]);
+ glColor3ubv(cp1+4);
glVertex3fv(mvert[mface->v2].co);
- glColor3ub(cp1[8], cp1[9], cp1[10]);
+ glColor3ubv(cp1+8);
glVertex3fv(mvert[mface->v3].co);
if(mface->v4) {
- glColor3ub(cp1[12], cp1[13], cp1[14]);
+ glColor3ubv(cp1+12);
glVertex3fv(mvert[mface->v4].co);
}
if(useTwoSided) {
- glColor3ub(cp2[8], cp2[9], cp2[10]);
+ glColor3ubv(cp2+8);
glVertex3fv(mvert[mface->v3].co );
- glColor3ub(cp2[4], cp2[5], cp2[6]);
+ glColor3ubv(cp2+4);
glVertex3fv(mvert[mface->v2].co );
- glColor3ub(cp2[0], cp2[1], cp2[2]);
+ glColor3ubv(cp2+0);
glVertex3fv(mvert[mface->v1].co );
if(mface->v4) {
- glColor3ub(cp2[12], cp2[13], cp2[14]);
+ glColor3ubv(cp2+12);
glVertex3fv(mvert[mface->v4].co );
}
}
@@ -782,6 +793,19 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
}
if( !GPU_buffer_legacy(dm) ) {
+ /* warning!, this logic is incorrect, see bug [#27175]
+ * firstly, there are no checks for changes in context, such as texface image.
+ * secondly, drawParams() sets the GL context, so checking if there is a change
+ * from lastFlag is too late once glDrawArrays() runs, since drawing the arrays
+ * will use the modified, OpenGL settings.
+ *
+ * However its tricky to fix this without duplicating the internal logic
+ * of drawParams(), perhaps we need an argument like...
+ * drawParams(..., keep_gl_state_but_return_when_changed) ?.
+ *
+ * We could also just disable VBO's here, since texface may be deprecated - campbell.
+ */
+
glShadeModel( GL_SMOOTH );
lastFlag = 0;
for(i = 0; i < dm->drawObject->nelements/3; i++) {
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 9fabf1d52cf..89e60cc5e0c 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -918,7 +918,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
if(!first)
implicit_set_positions(clmd);
- clmd->clothObject->bvhtree = bvhtree_build_from_cloth ( clmd, clmd->coll_parms->epsilon );
+ clmd->clothObject->bvhtree = bvhtree_build_from_cloth ( clmd, MAX2(clmd->coll_parms->epsilon, clmd->coll_parms->distance_repel) );
for(i = 0; i < dm->getNumVerts(dm); i++)
{
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index 88b6ca296c7..e2a1b0dfb33 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -48,6 +48,9 @@
#include "BLI_math.h"
#include "BLI_edgehash.h"
#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
+#include "BLI_memarena.h"
+#include "BLI_rand.h"
#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
@@ -63,6 +66,10 @@
#include "BLI_kdopbvh.h"
#include "BKE_collision.h"
+#ifdef WITH_ELTOPO
+#include "eltopo-capi.h"
+#endif
+
/***********************************
Collision modifier code start
@@ -486,7 +493,7 @@ DO_INLINE void collision_interpolateOnTriangle ( float to[3], float v1[3], float
VECADDMUL ( to, v3, w3 );
}
-
+#ifndef WITH_ELTOPO
static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end )
{
int result = 0;
@@ -601,12 +608,799 @@ static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionM
}
return result;
}
+#endif /* !WITH_ELTOPO */
+
+#ifdef WITH_ELTOPO
+typedef struct edgepairkey {
+ int a1, a2, b1, b2;
+} edgepairkey;
+
+unsigned int edgepair_hash(void *vkey)
+{
+ edgepairkey *key = vkey;
+ int keys[4] = {key->a1, key->a2, key->b1, key->b2};
+ int i, j;
+
+ for (i=0; i<4; i++) {
+ for (j=0; j<3; j++) {
+ if (keys[j] >= keys[j+1]) {
+ SWAP(int, keys[j], keys[j+1]);
+ }
+ }
+ }
+
+ return keys[0]*101 + keys[1]*72 + keys[2]*53 + keys[3]*34;
+}
+
+int edgepair_cmp(const void *va, const void *vb)
+{
+ edgepairkey *a = va, *b = vb;
+ int keysa[4] = {a->a1, a->a2, a->b1, a->b2};
+ int keysb[4] = {b->a1, b->a2, b->b1, b->b2};
+ int i;
+
+ for (i=0; i<4; i++) {
+ int j, ok=0;
+ for (j=0; j<4; j++) {
+ if (keysa[i] == keysa[j]) {
+ ok = 1;
+ break;
+ }
+ }
+ if (!ok)
+ return -1;
+ }
+
+ return 0;
+}
+
+static void get_edgepairkey(edgepairkey *key, int a1, int a2, int b1, int b2)
+{
+ key->a1 = a1;
+ key->a2 = a2;
+ key->b1 = b1;
+ key->b2 = b2;
+}
+
+/*an immense amount of duplication goes on here. . .a major performance hit, I'm sure*/
+static CollPair* cloth_edge_collision ( ModifierData *md1, ModifierData *md2,
+ BVHTreeOverlap *overlap, CollPair *collpair,
+ GHash *visithash, MemArena *arena)
+{
+ ClothModifierData *clmd = ( ClothModifierData * ) md1;
+ CollisionModifierData *collmd = ( CollisionModifierData * ) md2;
+ MFace *face1=NULL, *face2 = NULL;
+ ClothVertex *verts1 = clmd->clothObject->verts;
+ double distance = 0;
+ edgepairkey *key, tstkey;
+ float epsilon1 = clmd->coll_parms->epsilon;
+ float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree );
+ float no[3], uv[3], t, relnor;
+ int i, i1, i2, i3, i4, i5, i6;
+ Cloth *cloth = clmd->clothObject;
+ float n1[3], n2[3], off[3], v1[2][3], v2[2][3], v3[2][3], v4[2][3], v5[2][3], v6[2][3];
+ void **verts[] = {v1, v2, v3, v4, v5, v6};
+ int j, ret, bp1, bp2, bp3, ap1, ap2, ap3, table[6];
+
+ face1 = & ( clmd->clothObject->mfaces[overlap->indexA] );
+ face2 = & ( collmd->mfaces[overlap->indexB] );
+
+ // check all 4 possible collisions
+ for ( i = 0; i < 4; i++ )
+ {
+ if ( i == 0 )
+ {
+ // fill faceA
+ ap1 = face1->v1;
+ ap2 = face1->v2;
+ ap3 = face1->v3;
+
+ // fill faceB
+ bp1 = face2->v1;
+ bp2 = face2->v2;
+ bp3 = face2->v3;
+ }
+ else if ( i == 1 )
+ {
+ if ( face1->v4 )
+ {
+ // fill faceA
+ ap1 = face1->v1;
+ ap2 = face1->v3;
+ ap3 = face1->v4;
+
+ // fill faceB
+ bp1 = face2->v1;
+ bp2 = face2->v2;
+ bp3 = face2->v3;
+ }
+ else {
+ continue;
+ }
+ }
+ if ( i == 2 )
+ {
+ if ( face2->v4 )
+ {
+ // fill faceA
+ ap1 = face1->v1;
+ ap2 = face1->v2;
+ ap3 = face1->v3;
+
+ // fill faceB
+ bp1 = face2->v1;
+ bp2 = face2->v3;
+ bp3 = face2->v4;
+ }
+ else {
+ continue;
+ }
+ }
+ else if ( i == 3 )
+ {
+ if ( face1->v4 && face2->v4 )
+ {
+ // fill faceA
+ ap1 = face1->v1;
+ ap2 = face1->v3;
+ ap3 = face1->v4;
+
+ // fill faceB
+ bp1 = face2->v1;
+ bp2 = face2->v3;
+ bp3 = face2->v4;
+ }
+ else {
+ continue;
+ }
+ }
+
+ copy_v3_v3(v1[0], cloth->verts[ap1].txold);
+ copy_v3_v3(v1[1], cloth->verts[ap1].tx);
+ copy_v3_v3(v2[0], cloth->verts[ap2].txold);
+ copy_v3_v3(v2[1], cloth->verts[ap2].tx);
+ copy_v3_v3(v3[0], cloth->verts[ap3].txold);
+ copy_v3_v3(v3[1], cloth->verts[ap3].tx);
+
+ copy_v3_v3(v4[0], collmd->current_x[bp1].co);
+ copy_v3_v3(v4[1], collmd->current_xnew[bp1].co);
+ copy_v3_v3(v5[0], collmd->current_x[bp2].co);
+ copy_v3_v3(v5[1], collmd->current_xnew[bp2].co);
+ copy_v3_v3(v6[0], collmd->current_x[bp3].co);
+ copy_v3_v3(v6[1], collmd->current_xnew[bp3].co);
+
+ normal_tri_v3(n2, v4[1], v5[1], v6[1]);
+
+ /*offset new positions a bit, to account for margins*/
+ i1 = ap1; i2 = ap2; i3 = ap3;
+ i4 = bp1; i5 = bp2; i6 = bp3;
+
+ for (j=0; j<3; j++) {
+ int collp1, collp2, k, j2 = (j+1)%3;
+
+ table[0] = ap1; table[1] = ap2; table[2] = ap3;
+ table[3] = bp1; table[4] = bp2; table[5] = bp3;
+ for (k=0; k<3; k++) {
+ float p1[3], p2[3];
+ int k2 = (k+1)%3;
+
+ get_edgepairkey(&tstkey, table[j], table[j2], table[k+3], table[k2+3]);
+ //if (BLI_ghash_haskey(visithash, &tstkey))
+ // continue;
+
+ key = BLI_memarena_alloc(arena, sizeof(edgepairkey));
+ *key = tstkey;
+ BLI_ghash_insert(visithash, key, NULL);
+
+ sub_v3_v3v3(p1, verts[j], verts[j2]);
+ sub_v3_v3v3(p2, verts[k+3], verts[k2+3]);
+
+ cross_v3_v3v3(off, p1, p2);
+ normalize_v3(off);
+
+ if (dot_v3v3(n2, off) < 0.0)
+ negate_v3(off);
+
+ mul_v3_fl(off, epsilon1 + epsilon2 + ALMOST_ZERO);
+ copy_v3_v3(p1, verts[k+3]);
+ copy_v3_v3(p2, verts[k2+3]);
+ add_v3_v3(p1, off);
+ add_v3_v3(p2, off);
+
+ ret = eltopo_line_line_moving_isect_v3v3_f(verts[j], table[j], verts[j2], table[j2],
+ p1, table[k+3], p2, table[k2+3],
+ no, uv, &t, &relnor);
+ /*cloth vert versus coll face*/
+ if (ret) {
+ collpair->ap1 = table[j]; collpair->ap2 = table[j2];
+ collpair->bp1 = table[k+3]; collpair->bp2 = table[k2+3];
+
+ /*I'm not sure if this is correct, but hopefully it's
+ better then simply ignoring back edges*/
+ if (dot_v3v3(n2, no) < 0.0) {
+ negate_v3(no);
+ }
+
+ copy_v3_v3(collpair->normal, no);
+ mul_v3_v3fl(collpair->vector, collpair->normal, relnor);
+ collpair->distance = relnor;
+ collpair->time = t;
+
+ copy_v2_v2(collpair->bary, uv);
+
+ collpair->flag = COLLISION_IS_EDGES;
+ collpair++;
+ }
+ }
+ }
+ }
+
+ return collpair;
+}
+
+static int cloth_edge_collision_response_moving ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end )
+{
+ int result = 0;
+ Cloth *cloth1;
+ float w1, w2;
+ float v1[3], v2[3], relativeVelocity[3];
+ float magrelVel, pimpulse[3];
+
+ cloth1 = clmd->clothObject;
+
+ for ( ; collpair != collision_end; collpair++ )
+ {
+ if (!(collpair->flag & COLLISION_IS_EDGES))
+ continue;
+
+ // was: txold
+ w1 = collpair->bary[0]; w2 = collpair->bary[1];
+
+ // Calculate relative "velocity".
+ VECADDFAC(v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, w1);
+ VECADDFAC(v2, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, w2);
+
+ VECSUB ( relativeVelocity, v2, v1);
+
+ // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal').
+ magrelVel = INPR ( relativeVelocity, collpair->normal );
+
+ // If v_n_mag < 0 the edges are approaching each other.
+ if ( magrelVel > ALMOST_ZERO )
+ {
+ // Calculate Impulse magnitude to stop all motion in normal direction.
+ float magtangent = 0, repulse = 0, d = 0;
+ double impulse = 0.0;
+ float vrel_t_pre[3];
+ float temp[3], spf;
+
+ zero_v3(pimpulse);
+
+ // calculate tangential velocity
+ VECCOPY ( temp, collpair->normal );
+ mul_v3_fl( temp, magrelVel );
+ VECSUB ( vrel_t_pre, relativeVelocity, temp );
+
+ // Decrease in magnitude of relative tangential velocity due to coulomb friction
+ // in original formula "magrelVel" should be the "change of relative velocity in normal direction"
+ magtangent = MIN2 ( clmd->coll_parms->friction * 0.01 * magrelVel,sqrt ( INPR ( vrel_t_pre,vrel_t_pre ) ) );
+
+ // Apply friction impulse.
+ if ( magtangent > ALMOST_ZERO )
+ {
+ normalize_v3( vrel_t_pre );
+
+ impulse = magtangent;
+ VECADDMUL ( pimpulse, vrel_t_pre, impulse);
+ }
+
+ // Apply velocity stopping impulse
+ // I_c = m * v_N / 2.0
+ // no 2.0 * magrelVel normally, but looks nicer DG
+ impulse = magrelVel;
+
+ mul_v3_fl(collpair->normal, 0.5);
+ VECADDMUL ( pimpulse, collpair->normal, impulse);
+
+ // Apply repulse impulse if distance too short
+ // I_r = -min(dt*kd, m(0,1d/dt - v_n))
+ spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
+
+ d = collpair->distance;
+ if ( ( magrelVel < 0.1*d*spf && ( d > ALMOST_ZERO ) ) )
+ {
+ repulse = MIN2 ( d*1.0/spf, 0.1*d*spf - magrelVel );
+
+ // stay on the safe side and clamp repulse
+ if ( impulse > ALMOST_ZERO )
+ repulse = MIN2 ( repulse, 5.0*impulse );
+ repulse = MAX2 ( impulse, repulse );
+
+ impulse = repulse / ( 5.0 ); // original 2.0 / 0.25
+ VECADDMUL ( pimpulse, collpair->normal, impulse);
+ }
+
+ w2 = 1.0f-w1;
+ if (w1 < 0.5)
+ w1 *= 2.0;
+ else
+ w2 *= 2.0;
+
+ VECADDFAC(cloth1->verts[collpair->ap1].impulse, cloth1->verts[collpair->ap1].impulse, pimpulse, w1*2.0);
+ VECADDFAC(cloth1->verts[collpair->ap2].impulse, cloth1->verts[collpair->ap2].impulse, pimpulse, w2*2.0);
+
+ cloth1->verts[collpair->ap1].impulse_count++;
+ cloth1->verts[collpair->ap2].impulse_count++;
+
+ result = 1;
+ }
+ }
+
+ return result;
+}
+
+static int cloth_collision_response_moving ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end )
+{
+ int result = 0;
+ Cloth *cloth1;
+ float w1, w2, w3, u1, u2, u3;
+ float v1[3], v2[3], relativeVelocity[3];
+ float magrelVel;
+ float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree );
+
+ cloth1 = clmd->clothObject;
+
+ for ( ; collpair != collision_end; collpair++ )
+ {
+ if (collpair->flag & COLLISION_IS_EDGES)
+ continue;
+
+ if ( collpair->flag & COLLISION_USE_COLLFACE ) {
+ // was: txold
+ w1 = collpair->bary[0]; w2 = collpair->bary[1]; w3 = collpair->bary[2];
+
+ // Calculate relative "velocity".
+ collision_interpolateOnTriangle ( v1, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, collmd->current_v[collpair->bp3].co, w1, w2, w3);
+
+ VECSUB ( relativeVelocity, v1, cloth1->verts[collpair->collp].tv);
+
+ // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal').
+ magrelVel = INPR ( relativeVelocity, collpair->normal );
+
+ // If v_n_mag < 0 the edges are approaching each other.
+ if ( magrelVel > ALMOST_ZERO )
+ {
+ // Calculate Impulse magnitude to stop all motion in normal direction.
+ float magtangent = 0, repulse = 0, d = 0;
+ double impulse = 0.0;
+ float vrel_t_pre[3];
+ float temp[3], spf;
+
+ // calculate tangential velocity
+ VECCOPY ( temp, collpair->normal );
+ mul_v3_fl( temp, magrelVel );
+ VECSUB ( vrel_t_pre, relativeVelocity, temp );
+
+ // Decrease in magnitude of relative tangential velocity due to coulomb friction
+ // in original formula "magrelVel" should be the "change of relative velocity in normal direction"
+ magtangent = MIN2 ( clmd->coll_parms->friction * 0.01 * magrelVel,sqrt ( INPR ( vrel_t_pre,vrel_t_pre ) ) );
+
+ // Apply friction impulse.
+ if ( magtangent > ALMOST_ZERO )
+ {
+ normalize_v3( vrel_t_pre );
+
+ impulse = magtangent; // 2.0 *
+ VECADDMUL ( cloth1->verts[collpair->collp].impulse, vrel_t_pre, impulse);
+ }
+
+ // Apply velocity stopping impulse
+ // I_c = m * v_N / 2.0
+ // no 2.0 * magrelVel normally, but looks nicer DG
+ impulse = magrelVel/2.0;
+
+ VECADDMUL ( cloth1->verts[collpair->collp].impulse, collpair->normal, impulse);
+ cloth1->verts[collpair->collp].impulse_count++;
+
+ // Apply repulse impulse if distance too short
+ // I_r = -min(dt*kd, m(0,1d/dt - v_n))
+ spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
+
+ d = -collpair->distance;
+ if ( ( magrelVel < 0.1*d*spf ) && ( d > ALMOST_ZERO ) )
+ {
+ repulse = MIN2 ( d*1.0/spf, 0.1*d*spf - magrelVel );
+
+ // stay on the safe side and clamp repulse
+ if ( impulse > ALMOST_ZERO )
+ repulse = MIN2 ( repulse, 5.0*impulse );
+ repulse = MAX2 ( impulse, repulse );
+
+ impulse = repulse / ( 5.0 ); // original 2.0 / 0.25
+ VECADDMUL ( cloth1->verts[collpair->collp].impulse, collpair->normal, impulse);
+ }
+
+ result = 1;
+ }
+ } else {
+ w1 = collpair->bary[0]; w2 = collpair->bary[1]; w3 = collpair->bary[2];
+
+ // Calculate relative "velocity".
+ collision_interpolateOnTriangle ( v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3 );
+
+ VECSUB ( relativeVelocity, collmd->current_v[collpair->collp].co, v1);
+
+ // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal').
+ magrelVel = INPR ( relativeVelocity, collpair->normal );
+
+ // If v_n_mag < 0 the edges are approaching each other.
+ if ( magrelVel > ALMOST_ZERO )
+ {
+ // Calculate Impulse magnitude to stop all motion in normal direction.
+ float magtangent = 0, repulse = 0, d = 0;
+ double impulse = 0.0;
+ float vrel_t_pre[3], pimpulse[3] = {0.0f, 0.0f, 0.0f};
+ float temp[3], spf;
+
+ // calculate tangential velocity
+ VECCOPY ( temp, collpair->normal );
+ mul_v3_fl( temp, magrelVel );
+ VECSUB ( vrel_t_pre, relativeVelocity, temp );
+
+ // Decrease in magnitude of relative tangential velocity due to coulomb friction
+ // in original formula "magrelVel" should be the "change of relative velocity in normal direction"
+ magtangent = MIN2 ( clmd->coll_parms->friction * 0.01 * magrelVel,sqrt ( INPR ( vrel_t_pre,vrel_t_pre ) ) );
+
+ // Apply friction impulse.
+ if ( magtangent > ALMOST_ZERO )
+ {
+ normalize_v3( vrel_t_pre );
+
+ impulse = magtangent; // 2.0 *
+ VECADDMUL ( pimpulse, vrel_t_pre, impulse);
+ }
+
+ // Apply velocity stopping impulse
+ // I_c = m * v_N / 2.0
+ // no 2.0 * magrelVel normally, but looks nicer DG
+ impulse = magrelVel/2.0;
+
+ VECADDMUL ( pimpulse, collpair->normal, impulse);
+
+ // Apply repulse impulse if distance too short
+ // I_r = -min(dt*kd, m(0,1d/dt - v_n))
+ spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
+
+ d = -collpair->distance;
+ if ( ( magrelVel < 0.1*d*spf ) && ( d > ALMOST_ZERO ) )
+ {
+ repulse = MIN2 ( d*1.0/spf, 0.1*d*spf - magrelVel );
+
+ // stay on the safe side and clamp repulse
+ if ( impulse > ALMOST_ZERO )
+ repulse = MIN2 ( repulse, 5.0*impulse );
+ repulse = MAX2 ( impulse, repulse );
+
+ impulse = repulse / ( 2.0 ); // original 2.0 / 0.25
+ VECADDMUL ( pimpulse, collpair->normal, impulse);
+ }
+
+ if (w1 < 0.5) w1 *= 2.0;
+ if (w2 < 0.5) w2 *= 2.0;
+ if (w3 < 0.5) w3 *= 2.0;
+
+ VECADDMUL(cloth1->verts[collpair->ap1].impulse, pimpulse, w1*2.0);
+ VECADDMUL(cloth1->verts[collpair->ap2].impulse, pimpulse, w2*2.0);
+ VECADDMUL(cloth1->verts[collpair->ap3].impulse, pimpulse, w3*2.0);;
+ cloth1->verts[collpair->ap1].impulse_count++;
+ cloth1->verts[collpair->ap2].impulse_count++;
+ cloth1->verts[collpair->ap3].impulse_count++;
+
+ result = 1;
+ }
+ }
+ }
+
+ return result;
+}
+
+
+typedef struct tripairkey {
+ int p, a1, a2, a3;
+} tripairkey;
+
+unsigned int tripair_hash(void *vkey)
+{
+ tripairkey *key = vkey;
+ int keys[4] = {key->p, key->a1, key->a2, key->a3};
+ int i, j;
+
+ for (i=0; i<4; i++) {
+ for (j=0; j<3; j++) {
+ if (keys[j] >= keys[j+1]) {
+ SWAP(int, keys[j], keys[j+1]);
+ }
+ }
+ }
+
+ return keys[0]*101 + keys[1]*72 + keys[2]*53 + keys[3]*34;
+}
+
+int tripair_cmp(const void *va, const void *vb)
+{
+ tripairkey *a = va, *b = vb;
+ int keysa[4] = {a->p, a->a1, a->a2, a->a3};
+ int keysb[4] = {b->p, b->a1, b->a2, b->a3};
+ int i;
+
+ for (i=0; i<4; i++) {
+ int j, ok=0;
+ for (j=0; j<4; j++) {
+ if (keysa[i] == keysa[j]) {
+ ok = 1;
+ break;
+ }
+ }
+ if (!ok)
+ return -1;
+ }
+
+ return 0;
+}
+
+static void get_tripairkey(tripairkey *key, int p, int a1, int a2, int a3)
+{
+ key->a1 = a1;
+ key->a2 = a2;
+ key->a3 = a3;
+ key->p = p;
+}
+
+static int checkvisit(MemArena *arena, GHash *gh, int p, int a1, int a2, int a3)
+{
+ tripairkey key, *key2;
+
+ get_tripairkey(&key, p, a1, a2, a3);
+ if (BLI_ghash_haskey(gh, &key))
+ return 1;
+
+ key2 = BLI_memarena_alloc(arena, sizeof(*key2));
+ *key2 = key;
+ BLI_ghash_insert(gh, key2, NULL);
+
+ return 0;
+}
+
+int cloth_point_tri_moving_v3v3_f(float v1[2][3], int i1, float v2[2][3], int i2,
+ float v3[2][3], int i3, float v4[2][3], int i4,
+ float normal[3], float bary[3], float *t,
+ float *relnor, GHash *gh, MemArena *arena)
+{
+ if (checkvisit(arena, gh, i1, i2, i3, i4))
+ return 0;
+
+ return eltopo_point_tri_moving_v3v3_f(v1, i1, v2, i2, v3, i3, v4, i4, normal, bary, t, relnor);
+}
+
+static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTreeOverlap *overlap,
+ CollPair *collpair, double dt, GHash *gh, MemArena *arena)
+{
+ ClothModifierData *clmd = ( ClothModifierData * ) md1;
+ CollisionModifierData *collmd = ( CollisionModifierData * ) md2;
+ MFace *face1=NULL, *face2 = NULL;
+ ClothVertex *verts1 = clmd->clothObject->verts;
+ double distance = 0;
+ float epsilon1 = clmd->coll_parms->epsilon;
+ float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree );
+ float no[3], uv[3], t, relnor;
+ int i, i1, i2, i3, i4, i5, i6;
+ Cloth *cloth = clmd->clothObject;
+ float n1[3], sdis, p[3], l, n2[3], off[3], v1[2][3], v2[2][3], v3[2][3], v4[2][3], v5[2][3], v6[2][3];
+ int j, ret, bp1, bp2, bp3, ap1, ap2, ap3;
+
+ face1 = & ( clmd->clothObject->mfaces[overlap->indexA] );
+ face2 = & ( collmd->mfaces[overlap->indexB] );
+
+ // check all 4 possible collisions
+ for ( i = 0; i < 4; i++ )
+ {
+ if ( i == 0 )
+ {
+ // fill faceA
+ ap1 = face1->v1;
+ ap2 = face1->v2;
+ ap3 = face1->v3;
+
+ // fill faceB
+ bp1 = face2->v1;
+ bp2 = face2->v2;
+ bp3 = face2->v3;
+ }
+ else if ( i == 1 )
+ {
+ if ( face1->v4 )
+ {
+ // fill faceA
+ ap1 = face1->v1;
+ ap2 = face1->v3;
+ ap3 = face1->v4;
+
+ // fill faceB
+ bp1 = face2->v1;
+ bp2 = face2->v2;
+ bp3 = face2->v3;
+ }
+ else {
+ continue;
+ }
+ }
+ if ( i == 2 )
+ {
+ if ( face2->v4 )
+ {
+ // fill faceA
+ ap1 = face1->v1;
+ ap2 = face1->v2;
+ ap3 = face1->v3;
+
+ // fill faceB
+ bp1 = face2->v1;
+ bp2 = face2->v3;
+ bp3 = face2->v4;
+ }
+ else {
+ continue;
+ }
+ }
+ else if ( i == 3 )
+ {
+ if ( face1->v4 && face2->v4 )
+ {
+ // fill faceA
+ ap1 = face1->v1;
+ ap2 = face1->v3;
+ ap3 = face1->v4;
+
+ // fill faceB
+ bp1 = face2->v1;
+ bp2 = face2->v3;
+ bp3 = face2->v4;
+ }
+ else {
+ continue;
+ }
+ }
+
+ copy_v3_v3(v1[0], cloth->verts[ap1].txold);
+ copy_v3_v3(v1[1], cloth->verts[ap1].tx);
+ copy_v3_v3(v2[0], cloth->verts[ap2].txold);
+ copy_v3_v3(v2[1], cloth->verts[ap2].tx);
+ copy_v3_v3(v3[0], cloth->verts[ap3].txold);
+ copy_v3_v3(v3[1], cloth->verts[ap3].tx);
+
+ copy_v3_v3(v4[0], collmd->current_x[bp1].co);
+ copy_v3_v3(v4[1], collmd->current_xnew[bp1].co);
+ copy_v3_v3(v5[0], collmd->current_x[bp2].co);
+ copy_v3_v3(v5[1], collmd->current_xnew[bp2].co);
+ copy_v3_v3(v6[0], collmd->current_x[bp3].co);
+ copy_v3_v3(v6[1], collmd->current_xnew[bp3].co);
+
+ normal_tri_v3(n2, v4[1], v5[1], v6[1]);
+
+ sdis = clmd->coll_parms->distance_repel + epsilon2 + FLT_EPSILON;
+
+ /*apply a repulsion force, to help the solver along*/
+ copy_v3_v3(off, n2);
+ negate_v3(off);
+ if (isect_ray_plane_v3(v1[1], off, v4[1], v5[1], v6[1], &l, 0)) {
+ if (l >= 0.0 && l < sdis) {
+ mul_v3_fl(off, (l-sdis)*cloth->verts[ap1].mass*dt*clmd->coll_parms->repel_force*0.1);
+
+ add_v3_v3(cloth->verts[ap1].tv, off);
+ add_v3_v3(cloth->verts[ap2].tv, off);
+ add_v3_v3(cloth->verts[ap3].tv, off);
+ }
+ }
+
+ /*offset new positions a bit, to account for margins*/
+ copy_v3_v3(off, n2);
+ mul_v3_fl(off, epsilon1 + epsilon2 + ALMOST_ZERO);
+ add_v3_v3(v4[1], off); add_v3_v3(v5[1], off); add_v3_v3(v6[1], off);
+
+ i1 = ap1; i2 = ap2; i3 = ap3;
+ i4 = bp1+cloth->numverts; i5 = bp2+cloth->numverts; i6 = bp3+cloth->numverts;
+
+ for (j=0; j<6; j++) {
+ int collp;
+
+ switch (j) {
+ case 0:
+ ret = cloth_point_tri_moving_v3v3_f(v1, i1, v4, i4, v5, i5, v6, i6, no, uv, &t, &relnor, gh, arena);
+ collp = ap1;
+ break;
+ case 1:
+ collp = ap2;
+ ret = cloth_point_tri_moving_v3v3_f(v2, i2, v4, i4, v5, i5, v6, i6, no, uv, &t, &relnor, gh, arena);
+ break;
+ case 2:
+ collp = ap3;
+ ret = cloth_point_tri_moving_v3v3_f(v3, i3, v4, i4, v5, i5, v6, i6, no, uv, &t, &relnor, gh, arena);
+ break;
+ case 3:
+ collp = bp1;
+ ret = cloth_point_tri_moving_v3v3_f(v4, i4, v1, i1, v2, i2, v3, i3, no, uv, &t, &relnor, gh, arena);
+ break;
+ case 4:
+ collp = bp2;
+ ret = cloth_point_tri_moving_v3v3_f(v5, i5, v1, i1, v2, i2, v3, i3, no, uv, &t, &relnor, gh, arena);
+ break;
+ case 5:
+ collp = bp3;
+ ret = cloth_point_tri_moving_v3v3_f(v6, i6, v1, i1, v2, i2, v3, i3, no, uv, &t, &relnor, gh, arena);
+ break;
+ }
+
+ /*cloth vert versus coll face*/
+ if (ret && j < 3) {
+ collpair->bp1 = bp1; collpair->bp2 = bp2; collpair->bp3 = bp3;
+ collpair->collp = collp;
+
+ copy_v3_v3(collpair->normal, no);
+ mul_v3_v3fl(collpair->vector, collpair->normal, relnor);
+ collpair->distance = relnor;
+ collpair->time = t;
+
+ copy_v3_v3(collpair->bary, uv);
+
+ collpair->flag = COLLISION_USE_COLLFACE;
+ collpair++;
+ } else if (ret && j >= 3) { /*coll vert versus cloth face*/
+ collpair->ap1 = ap1; collpair->ap2 = ap2; collpair->ap3 = ap3;
+ collpair->collp = collp;
+
+ copy_v3_v3(collpair->normal, no);
+ mul_v3_v3fl(collpair->vector, collpair->normal, relnor);
+ collpair->distance = relnor;
+ collpair->time = t;
+
+ copy_v3_v3(collpair->bary, uv);
+
+ collpair->flag = 0;
+ collpair++;
+ }
+ }
+ }
+
+ return collpair;
+}
+
+static void machine_epsilon_offset(Cloth *cloth) {
+ ClothVertex *cv;
+ int i, j;
+
+ cv = cloth->verts;
+ for (i=0; i<cloth->numverts; i++, cv++) {
+ /*aggrevatingly enough, it's necassary to offset the coordinates
+ by a multiple of the 32-bit floating point epsilon when switching
+ into doubles*/
+ #define RNDSIGN (float)(-1*(BLI_rand()%2==0)|1)
+ for (j=0; j<3; j++) {
+ cv->tx[j] += FLT_EPSILON*30.0f*RNDSIGN;
+ cv->txold[j] += FLT_EPSILON*30.0f*RNDSIGN;
+ cv->tv[j] += FLT_EPSILON*30.0f*RNDSIGN;
+ }
+ }
+}
+
+#else /* !WITH_ELTOPO */
//Determines collisions on overlap, collisions are written to collpair[i] and collision+number_collision_found is returned
-static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTreeOverlap *overlap, CollPair *collpair )
+static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2,
+ BVHTreeOverlap *overlap, CollPair *collpair, float dt )
{
ClothModifierData *clmd = ( ClothModifierData * ) md1;
CollisionModifierData *collmd = ( CollisionModifierData * ) md2;
+ Cloth *cloth = clmd->clothObject;
MFace *face1=NULL, *face2 = NULL;
#ifdef USE_BULLET
ClothVertex *verts1 = clmd->clothObject->verts;
@@ -614,6 +1408,7 @@ static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTree
double distance = 0;
float epsilon1 = clmd->coll_parms->epsilon;
float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree );
+ float n2[3], sdis, l;
int i;
face1 = & ( clmd->clothObject->mfaces[overlap->indexA] );
@@ -685,7 +1480,28 @@ static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTree
else
break;
}
+
+ normal_tri_v3(n2, collmd->current_xnew[collpair->bp1].co,
+ collmd->current_xnew[collpair->bp2].co,
+ collmd->current_xnew[collpair->bp3].co);
+
+ sdis = clmd->coll_parms->distance_repel + epsilon2 + FLT_EPSILON;
+
+ /*apply a repulsion force, to help the solver along.
+ this is kindof crude, it only tests one vert of the triangle*/
+ if (isect_ray_plane_v3(cloth->verts[collpair->ap1].tx, n2, collmd->current_xnew[collpair->bp1].co,
+ collmd->current_xnew[collpair->bp2].co,
+ collmd->current_xnew[collpair->bp3].co, &l, 0))
+ {
+ if (l >= 0.0 && l < sdis) {
+ mul_v3_fl(n2, (l-sdis)*cloth->verts[collpair->ap1].mass*dt*clmd->coll_parms->repel_force*0.1);
+ add_v3_v3(cloth->verts[collpair->ap1].tv, n2);
+ add_v3_v3(cloth->verts[collpair->ap2].tv, n2);
+ add_v3_v3(cloth->verts[collpair->ap3].tv, n2);
+ }
+ }
+
#ifdef USE_BULLET
// calc distance + normal
distance = plNearestPoints (
@@ -741,6 +1557,8 @@ static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTree
}
return collpair;
}
+#endif /* WITH_ELTOPO */
+
#if 0
static int cloth_collision_response_moving( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end )
@@ -856,10 +1674,10 @@ static int cloth_collision_response_moving( ClothModifierData *clmd, CollisionMo
#if 0
static float projectPointOntoLine(float *p, float *a, float *b)
{
- float ba[3], pa[3];
- VECSUB(ba, b, a);
- VECSUB(pa, p, a);
- return INPR(pa, ba) / INPR(ba, ba);
+ float ba[3], pa[3];
+ VECSUB(ba, b, a);
+ VECSUB(pa, p, a);
+ return INPR(pa, ba) / INPR(ba, ba);
}
static void calculateEENormal(float *np1, float *np2, float *np3, float *np4,float *out_normal)
@@ -1446,17 +2264,45 @@ void free_collider_cache(ListBase **colliders)
}
}
-static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap)
+
+static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd,
+ CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap, double dt)
{
int i;
+#ifdef WITH_ELTOPO
+ GHash *visithash = BLI_ghash_new(edgepair_hash, edgepair_cmp, "visthash, collision.c");
+ GHash *tri_visithash = BLI_ghash_new(tripair_hash, tripair_cmp, "tri_visthash, collision.c");
+ MemArena *arena = BLI_memarena_new(1<<16, "edge hash arena, collision.c");
+#endif
- *collisions = ( CollPair* ) MEM_mallocN ( sizeof ( CollPair ) * numresult * 4, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision
+ *collisions = ( CollPair* ) MEM_mallocN ( sizeof ( CollPair ) * numresult * 64, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision
*collisions_index = *collisions;
+
+#ifdef WITH_ELTOPO
+ machine_epsilon_offset(clmd->clothObject);
+
+ for ( i = 0; i < numresult; i++ )
+ {
+ *collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd,
+ overlap+i, *collisions_index, dt, tri_visithash, arena );
+ }
for ( i = 0; i < numresult; i++ )
{
- *collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd, overlap+i, *collisions_index );
+ *collisions_index = cloth_edge_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd,
+ overlap+i, *collisions_index, visithash, arena );
}
+ BLI_ghash_free(visithash, NULL, NULL);
+ BLI_ghash_free(tri_visithash, NULL, NULL);
+ BLI_memarena_free(arena);
+#else /* WITH_ELTOPO */
+ for ( i = 0; i < numresult; i++ )
+ {
+ *collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd,
+ overlap+i, *collisions_index, dt );
+ }
+#endif /* WITH_ELTOPO */
+
}
static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair *collisions, CollPair *collisions_index)
@@ -1481,11 +2327,19 @@ static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, Collision
if ( collmd->bvhtree )
{
+#ifdef WITH_ELTOPO
+ result += cloth_collision_response_moving(clmd, collmd, collisions, collisions_index);
+ result += cloth_edge_collision_response_moving(clmd, collmd, collisions, collisions_index);
+#else
result += cloth_collision_response_static ( clmd, collmd, collisions, collisions_index );
-
+#endif
+#ifdef WITH_ELTOPO
+ {
+#else
// apply impulses in parallel
if ( result )
{
+#endif
for ( i = 0; i < numverts; i++ )
{
// calculate "velocities" (just xnew = xold + v; no dt in v)
@@ -1518,7 +2372,7 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl
if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || cloth_bvh==NULL)
return 0;
-
+
verts = cloth->verts;
numfaces = cloth->numfaces;
numverts = cloth->numverts;
@@ -1557,6 +2411,7 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl
continue;
/* move object to position (step) in time */
+
collision_move_object ( collmd, step + dt, step );
/* search for overlapping collision pairs */
@@ -1565,7 +2420,8 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl
// go to next object if no overlap is there
if( result && overlap ) {
/* check if collisions really happen (costly near check) */
- cloth_bvh_objcollisions_nearcheck ( clmd, collmd, &collisions[i], &collisions_index[i], result, overlap);
+ cloth_bvh_objcollisions_nearcheck ( clmd, collmd, &collisions[i],
+ &collisions_index[i], result, overlap, dt/(float)clmd->coll_parms->loop_count);
// resolve nearby collisions
ret += cloth_bvh_objcollisions_resolve ( clmd, collmd, collisions[i], collisions_index[i]);
@@ -1721,5 +2577,5 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl
if(collobjs)
MEM_freeN(collobjs);
- return MIN2 ( ret, 1 );
+ return 1|MIN2 ( ret, 1 );
}
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 46f3e124bcc..1d7481b365a 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -793,7 +793,7 @@ void curvemapping_evaluate_premulRGBF(CurveMapping *cumap, float *vecout, const
/* basic error handler, if we dont do this blender will exit */
static int ErrorReportingFunction(int ErrorCode, const char *ErrorText)
{
- fprintf(stderr, "%s:%d\n", ErrorText, ErrorCode);
+ fprintf(stderr, "%s:%d\n", ErrorText, ErrorCode);
return 1;
}
#endif
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 7956da5da80..b93362b8676 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -4021,7 +4021,9 @@ bConstraintTypeInfo *constraint_get_typeinfo (bConstraint *con)
/* ---------- Data Management ------- */
-/* Free data of a specific constraint if it has any info */
+/* Free data of a specific constraint if it has any info.
+ * be sure to run BIK_clear_data() when freeing an IK constraint,
+ * unless DAG_scene_sort is called. */
void free_constraint_data (bConstraint *con)
{
if (con->data) {
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 2a44c942865..22646ab3cb5 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -520,11 +520,10 @@ static int ctx_data_get(bContext *C, const char *member, bContextDataResult *res
C->data.recursion= 1;
- for(entry=C->wm.store->entries.first; entry; entry=entry->next) {
- if(strcmp(entry->name, member) == 0) {
- result->ptr= entry->ptr;
- done= 1;
- }
+ entry= BLI_rfindstring(&C->wm.store->entries, member, offsetof(bContextStoreEntry, name));
+ if(entry) {
+ result->ptr= entry->ptr;
+ done= 1;
}
}
if(done!=1 && recursion < 2 && C->wm.region) {
@@ -718,7 +717,7 @@ int CTX_data_equals(const char *member, const char *str)
int CTX_data_dir(const char *member)
{
- return (strcmp(member, "") == 0);
+ return member[0] == '\0';
}
void CTX_data_id_pointer_set(bContextDataResult *result, ID *id)
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index b374727b87c..6d41eb6098b 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -64,7 +64,8 @@
#include "BKE_key.h"
#include "BKE_library.h"
#include "BKE_main.h"
-#include "BKE_object.h"
+#include "BKE_object.h"
+#include "BKE_material.h"
#include "ED_curve.h"
@@ -202,6 +203,7 @@ Curve *copy_curve(Curve *cu)
cun->editnurb= NULL;
cun->editfont= NULL;
+ cun->selboxes= NULL;
#if 0 // XXX old animation system
/* single user ipo too */
@@ -216,10 +218,22 @@ Curve *copy_curve(Curve *cu)
return cun;
}
+static void extern_local_curve(Curve *cu)
+{
+ id_lib_extern((ID *)cu->vfont);
+ id_lib_extern((ID *)cu->vfontb);
+ id_lib_extern((ID *)cu->vfonti);
+ id_lib_extern((ID *)cu->vfontbi);
+
+ if(cu->mat) {
+ extern_local_matarar(cu->mat, cu->totcol);
+ }
+}
+
void make_local_curve(Curve *cu)
{
- Object *ob = NULL;
- Curve *cun;
+ Main *bmain= G.main;
+ Object *ob;
int local=0, lib=0;
/* - when there are only lib users: don't do
@@ -229,47 +243,41 @@ void make_local_curve(Curve *cu)
if(cu->id.lib==NULL) return;
- if(cu->vfont) cu->vfont->id.lib= NULL;
- if(cu->vfontb) cu->vfontb->id.lib= NULL;
- if(cu->vfonti) cu->vfonti->id.lib= NULL;
- if(cu->vfontbi) cu->vfontbi->id.lib= NULL;
-
if(cu->id.us==1) {
cu->id.lib= NULL;
cu->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)cu, NULL);
+
+ new_id(&bmain->curve, (ID *)cu, NULL);
+ extern_local_curve(cu);
return;
}
-
- ob= G.main->object.first;
- while(ob) {
- if(ob->data==cu) {
+
+ for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) {
+ if(ob->data == cu) {
if(ob->id.lib) lib= 1;
else local= 1;
}
- ob= ob->id.next;
}
-
+
if(local && lib==0) {
cu->id.lib= NULL;
cu->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)cu, NULL);
+
+ new_id(&bmain->curve, (ID *)cu, NULL);
+ extern_local_curve(cu);
}
else if(local && lib) {
- cun= copy_curve(cu);
+ Curve *cun= copy_curve(cu);
cun->id.us= 0;
-
- ob= G.main->object.first;
- while(ob) {
+
+ for(ob= bmain->object.first; ob; ob= ob->id.next) {
if(ob->data==cu) {
-
if(ob->id.lib==NULL) {
ob->data= cun;
cun->id.us++;
cu->id.us--;
}
}
- ob= ob->id.next;
}
}
}
@@ -1026,19 +1034,19 @@ void forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int i
rt2= 3.0f*(q0-2.0f*q1+q2)/f;
f*= it;
rt3= (q3-q0+3.0f*(q1-q2))/f;
-
- q0= rt0;
+
+ q0= rt0;
q1= rt1+rt2+rt3;
q2= 2*rt2+6*rt3;
q3= 6*rt3;
-
- for(a=0; a<=it; a++) {
+
+ for(a=0; a<=it; a++) {
*p= q0;
p = (float *)(((char *)p)+stride);
q0+= q1;
- q1+= q2;
- q2+= q3;
- }
+ q1+= q2;
+ q2+= q3;
+ }
}
static void forward_diff_bezier_cotangent(float *p0, float *p1, float *p2, float *p3, float *p, int it, int stride)
@@ -1048,7 +1056,7 @@ static void forward_diff_bezier_cotangent(float *p0, float *p1, float *p2, float
*
* This could also be optimized like forward_diff_bezier */
int a;
- for(a=0; a<=it; a++) {
+ for(a=0; a<=it; a++) {
float t = (float)a / (float)it;
int i;
@@ -1057,7 +1065,7 @@ static void forward_diff_bezier_cotangent(float *p0, float *p1, float *p2, float
}
normalize_v3(p);
p = (float *)(((char *)p)+stride);
- }
+ }
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
@@ -1092,7 +1100,7 @@ float *make_orco_surf(Object *ob)
sizev = nu->pntsv*resolv;
if (nu->flagu & CU_NURB_CYCLIC) sizeu++;
if (nu->flagv & CU_NURB_CYCLIC) sizev++;
- if(nu->pntsv>1) tot+= sizeu * sizev;
+ if(nu->pntsv>1) tot+= sizeu * sizev;
nu= nu->next;
}
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index a0f8a0f13ee..0c4d1d067e6 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -255,7 +255,6 @@ int defgroup_find_index (Object *ob, bDeformGroup *dg)
if (eg == NULL) return -1;
return def_nr;
-
}
/* note, must be freed */
@@ -362,7 +361,7 @@ void flip_side_name (char name[MAX_VGROUP_NAME], const char from_name[MAX_VGROUP
index= strrchr(name, '.'); // last occurrence
if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever!
if(strip_number==0)
- BLI_strncpy(number, index, sizeof(number));
+ BLI_strncpy(number, index, sizeof(number));
*index= 0;
len= BLI_strnlen(name, MAX_VGROUP_NAME);
}
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index ff49c64ebf4..6813d5d18a6 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -492,7 +492,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
}
}
}
-
+
/* softbody collision */
if ((ob->type==OB_MESH) || (ob->type==OB_CURVE) || (ob->type==OB_LATTICE)) {
if(modifiers_isSoftbodyEnabled(ob) || modifiers_isClothEnabled(ob) || ob->particlesystem.first)
@@ -1092,10 +1092,10 @@ void graph_bfs(void)
push_queue(nqueue,itA->node);
}
- else {
+ else {
fprintf(stderr,"bfs not dag tree edge color :%i \n",itA->node->color);
}
-
+
itA = itA->next;
}
@@ -1225,7 +1225,7 @@ DagNodeQueue * graph_dfs(void)
while(nqueue->count) {
//graph_print_queue(nqueue);
- skip = 0;
+ skip = 0;
node = get_top_node_queue(nqueue);
minheight = pos[node->DFS_dist];
@@ -1253,7 +1253,7 @@ DagNodeQueue * graph_dfs(void)
*/
/*if (node->DFS_dist >= itA->node->DFS_dist)
itA->node->DFS_dist = node->DFS_dist + 1;
-
+
fprintf(stderr,"dfs forward or cross edge :%15s %i-%i %15s %i-%i \n",
((ID *) node->ob)->name,
node->DFS_dvtm,
@@ -1287,17 +1287,17 @@ DagNodeQueue * graph_dfs(void)
/*
fprintf(stderr,"DFS node : %20s %i %i %i %i\n",((ID *) node->ob)->name,node->BFS_dist, node->DFS_dist, node->DFS_dvtm, node->DFS_fntm );
*/
- push_stack(retqueue,node);
+ push_stack(retqueue,node);
}
}
}
node = node->next;
} while (node);
-// fprintf(stderr,"i size : %i \n", maxpos);
-
+// fprintf(stderr,"i size : %i \n", maxpos);
+
queue_delete(nqueue);
- return(retqueue);
+ return(retqueue);
}
/* unused */
@@ -1905,7 +1905,9 @@ static void dag_scene_flush_layers(Scene *sce, int lay)
}
/* ensure cameras are set as if they are on a visible layer, because
- they ared still used for rendering or setting the camera view */
+ * they ared still used for rendering or setting the camera view
+ *
+ * XXX, this wont work for local view / unlocked camera's */
if(sce->camera) {
node= dag_get_node(sce->theDag, sce->camera);
node->scelay |= lay;
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index b314264829c..48192546b0f 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -1871,9 +1871,9 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
already applied, thats how it worked for years, so keep for compatibility (sergey) */
copy_displist(&cu->disp, dispbase);
- if (!forRender) {
- tex_space_curve(cu);
- }
+ if (!forRender) {
+ tex_space_curve(cu);
+ }
if(!forOrco) curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal, forRender, originalVerts, deformedVerts);
diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c
deleted file mode 100644
index 53384d790e0..00000000000
--- a/source/blender/blenkernel/intern/exotic.c
+++ /dev/null
@@ -1,2485 +0,0 @@
-/*
- * $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.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- *
- * Contributor(s):
- * - Martin DeMello
- * Added dxf_read_arc, dxf_read_ellipse and dxf_read_lwpolyline
- * Copyright (C) 2004 by Etheract Software Labs
- *
- * - Blender Foundation
- *
- * ***** END GPL LICENSE BLOCK ****
- */
-
-/** \file blender/blenkernel/intern/exotic.c
- * \ingroup bke
- */
-
-
-#include <stddef.h>
-#include "BLI_storage.h"
-
-#include <stdlib.h>
-#include <ctype.h> /* isdigit, isspace */
-#include <math.h>
-#include <stdio.h>
-
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-
-#ifndef _WIN32
-#include <unistd.h>
-#else
-#include <io.h>
-#define open _open
-#define read _read
-#define close _close
-#define write _write
-#endif
-
-#include "MEM_guardedalloc.h"
-
-#include "DNA_object_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_material_types.h"
-#include "DNA_curve_types.h"
-#include "DNA_camera_types.h"
-#include "DNA_scene_types.h"
-
-#include "BLI_blenlib.h"
-#include "BLI_math.h"
-#include "BLI_storage.h"
-#include "BLI_utildefines.h"
-
-
-#include "BKE_blender.h"
-#include "BKE_global.h"
-#include "BKE_main.h"
-#include "BKE_mesh.h"
-#include "BKE_library.h"
-#include "BKE_object.h"
-#include "BKE_material.h"
-#include "BKE_report.h"
-#include "BKE_exotic.h"
-#include "BKE_displist.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_curve.h"
-
-#ifdef WITH_PYTHON
-#include "BPY_extern.h"
-#endif
-
-#include "zlib.h"
-
-static int is_dxf(const char *str);
-static void dxf_read(Scene *scene, const char *filename);
-static int is_stl(const char *str);
-
-static int is_stl_ascii(const char *str)
-{
- FILE *fpSTL;
- char buffer[1000];
- int numread, i;
-
- fpSTL = fopen(str, "rb");
- if ( (numread = fread( (void *) buffer, sizeof(char), 1000, fpSTL)) <= 0 )
- { fclose(fpSTL); return 0; }
-
- for (i=0; i < numread; ++i) {
- /* if bit 8 is set we assume binary */
- if (buffer[i] & 0x80)
- { fclose(fpSTL); return 0; }
- }
-
- buffer[5] = '\0';
- if ( !(strstr(buffer, "solid")) && !(strstr(buffer, "SOLID")) )
- { fclose(fpSTL); return 0; }
-
- fclose(fpSTL);
-
- return 1;
-}
-
-static int is_stl(const char *str)
-{
- int i;
- i = strlen(str) - 3;
- if ( (str[i] !='s') && (str[i] !='S'))
- return 0;
- i++;
- if ( (str[i] !='t') && (str[i] !='T'))
- return 0;
- i++;
- if ( (str[i] !='l') && (str[i] !='L'))
- return 0;
-
- return 1;
-}
-
-#define READSTLVERT { \
- if (fread(mvert->co, sizeof(float), 3, fpSTL) != 3) { \
- char error_msg[255]; \
- MEM_freeN(vertdata); \
- MEM_freeN(facedata); \
- fclose(fpSTL); \
- sprintf(error_msg, "Problems reading face %d!", i); \
- return; \
- } \
- else { \
- if (ENDIAN_ORDER==B_ENDIAN) { \
- SWITCH_INT(mvert->co[0]); \
- SWITCH_INT(mvert->co[1]); \
- SWITCH_INT(mvert->co[2]); \
- } \
- } \
-}
-
-static void simple_vertex_normal_blend(short *no, short *ble)
-{
- if(no[0]==0 && no[1]==0 && no[2]==0) {
- VECCOPY(no, ble);
- }
- else {
- no[0]= (2*no[0] + ble[0])/3;
- no[1]= (2*no[1] + ble[1])/3;
- no[2]= (2*no[2] + ble[2])/3;
- }
-}
-
-static void mesh_add_normals_flags(Mesh *me)
-{
- MVert *v1, *v2, *v3, *v4;
- MFace *mface;
- float nor[3];
- int a;
- short sno[3];
-
- mface= me->mface;
- for(a=0; a<me->totface; a++, mface++) {
- v1= me->mvert+mface->v1;
- v2= me->mvert+mface->v2;
- v3= me->mvert+mface->v3;
- v4= me->mvert+mface->v4;
-
- normal_tri_v3( nor,v1->co, v2->co, v3->co);
- normal_float_to_short_v3(sno, nor);
-
- simple_vertex_normal_blend(v1->no, sno);
- simple_vertex_normal_blend(v2->no, sno);
- simple_vertex_normal_blend(v3->no, sno);
- if(mface->v4) {
- simple_vertex_normal_blend(v4->no, sno);
- }
- mface->edcode= ME_V1V2|ME_V2V3;
- }
-}
-
-static void read_stl_mesh_binary(Scene *scene, const char *str)
-{
- FILE *fpSTL;
- Object *ob;
- Mesh *me;
- MVert *mvert, *vertdata;
- MFace *mface, *facedata;
- unsigned int numfacets = 0, i, j, vertnum;
- unsigned int maxmeshsize, nummesh, lastmeshsize;
- unsigned int totvert, totface;
- ReportList *reports= NULL; /* XXX */
-
- fpSTL= fopen(str, "rb");
- if(fpSTL==NULL) {
- BKE_reportf(reports, RPT_ERROR, "Can't read file: %s.", strerror(errno));
- return;
- }
-
- if(fseek(fpSTL, 80, SEEK_SET) != 0) {
- BKE_reportf(reports, RPT_ERROR, "Failed reading file: %s.", strerror(errno));
- fclose(fpSTL);
- return;
- }
-
- if(fread(&numfacets, 4*sizeof(char), 1, fpSTL) != 1) {
- if(feof(fpSTL))
- BKE_reportf(reports, RPT_ERROR, "Failed reading file: premature end of file.");
- else
- BKE_reportf(reports, RPT_ERROR, "Failed reading file: %s.", strerror(errno));
- fclose(fpSTL);
- return;
- }
- if (ENDIAN_ORDER==B_ENDIAN) {
- SWITCH_INT(numfacets);
- }
-
- maxmeshsize = MESH_MAX_VERTS/3;
-
- nummesh = (numfacets / maxmeshsize) + 1;
- lastmeshsize = numfacets % maxmeshsize;
-
- if (numfacets) {
- for (j=0; j < nummesh; ++j) {
- /* new object */
- if (j == nummesh-1) {
- totface = lastmeshsize;
- }
- else {
- totface = maxmeshsize;
- }
- totvert = 3 * totface;
-
- vertdata = MEM_callocN(totvert*sizeof(MVert), "mverts");
- facedata = MEM_callocN(totface*sizeof(MFace), "mface");
-
- vertnum = 0;
- mvert= vertdata;
- mface = facedata;
- for (i=0; i < totface; i++) {
- fseek(fpSTL, 12, SEEK_CUR); /* skip the face normal */
- READSTLVERT;
- mvert++;
- READSTLVERT;
- mvert++;
- READSTLVERT;
- mvert++;
-
- mface->v1 = vertnum++;
- mface->v2 = vertnum++;
- mface->v3 = vertnum++;
- mface++;
-
- fseek(fpSTL, 2, SEEK_CUR);
- }
-
- ob= add_object(scene, OB_MESH);
- me= ob->data;
- me->totvert = totvert;
- me->totface = totface;
- me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN,
- vertdata, totvert);
- me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN,
- facedata, totface);
-
- mesh_add_normals_flags(me);
- make_edges(me, 0);
- }
- //XXX waitcursor(1);
- }
- fclose(fpSTL);
-
-}
-#undef READSTLVERT
-
-#define STLALLOCERROR { \
- char error_msg[255]; \
- fclose(fpSTL); \
- sprintf(error_msg, "Can't allocate storage for %d faces!", \
- numtenthousand * 10000); \
- return; \
-}
-
-#define STLBAILOUT(message) { \
- char error_msg[255]; \
- fclose(fpSTL); \
- free(vertdata); \
- sprintf(error_msg, "Line %d: %s", linenum, message); \
- return; \
-}
-
-#define STLREADLINE { \
- if (!fgets(buffer, 2048, fpSTL)) STLBAILOUT("Can't read line!"); \
- linenum++; \
-}
-
-#define STLREADVERT { \
- STLREADLINE; \
- if ( !(cp = strstr(buffer, "vertex")) && \
- !(cp = strstr(buffer, "VERTEX")) ) STLBAILOUT("Bad vertex!"); \
- vp = vertdata + 3 * totvert; \
- if (sscanf(cp + 6, "%f %f %f", vp, vp+1, vp+2) != 3) \
- STLBAILOUT("Bad vertex!"); \
- ++totvert; \
-}
-static void read_stl_mesh_ascii(Scene *scene, const char *str)
-{
- FILE *fpSTL;
- char buffer[2048], *cp;
- Object *ob;
- Mesh *me;
- MVert *mvert;
- MFace *mface;
- float *vertdata, *vp;
- unsigned int numtenthousand, linenum;
- unsigned int i, vertnum;
- unsigned int totvert, totface;
- ReportList *reports= NULL; /* XXX */
-
- /* ASCII stl sucks ... we don't really know how many faces there
- are until the file is done, so lets allocate faces 10000 at a time */
-
- fpSTL= fopen(str, "r");
- if(fpSTL==NULL) {
- BKE_reportf(reports, RPT_ERROR, "Can't read file: %s.", strerror(errno));
- return;
- }
-
- /* we'll use the standard malloc/realloc for now ...
- * lets allocate enough storage to hold 10000 triangles,
- * i.e. 30000 verts, i.e., 90000 floats.
- */
- numtenthousand = 1;
- vertdata = malloc(numtenthousand*3*30000*sizeof(float)); // uses realloc!
- if (!vertdata) { STLALLOCERROR; }
-
- linenum = 1;
- /* Get rid of the first line */
- STLREADLINE;
-
- totvert = 0;
- totface = 0;
- while(1) {
- /* Read in the next line */
- STLREADLINE;
-
- /* lets check if this is the end of the file */
- if ( strstr(buffer, "endsolid") || strstr(buffer, "ENDSOLID") )
- break;
-
- /* Well, guess that wasn't the end, so lets make
- * sure we have enough storage for some more faces
- */
- if ( (totface) && ( (totface % 10000) == 0 ) ) {
- float *vertdata_old= vertdata;
- ++numtenthousand;
- vertdata = realloc(vertdata,
- numtenthousand*3*30000*sizeof(float));
- if (!vertdata) {
- if(vertdata_old) {
- free(vertdata_old);
- }
- STLALLOCERROR;
- }
- }
-
- /* Don't read normal, but check line for proper syntax anyway
- */
- if ( !(cp = strstr(buffer, "facet")) &&
- !(cp = strstr(buffer, "FACET")) ) STLBAILOUT("Bad normal line!");
- if ( !(strstr(cp+5, "normal")) &&
- !(strstr(cp+5, "NORMAL")) ) STLBAILOUT("Bad normal line!");
-
- /* Read in what should be the outer loop line
- */
- STLREADLINE;
- if ( !(cp = strstr(buffer, "outer")) &&
- !(cp = strstr(buffer, "OUTER")) ) STLBAILOUT("Bad outer loop!");
- if ( !(strstr(cp+5, "loop")) &&
- !(strstr(cp+5, "LOOP")) ) STLBAILOUT("Bad outer loop!");
-
- /* Read in the face */
- STLREADVERT;
- STLREADVERT;
- STLREADVERT;
-
- /* Read in what should be the endloop line
- */
- STLREADLINE;
- if ( !strstr(buffer, "endloop") && !strstr(buffer, "ENDLOOP") )
- STLBAILOUT("Bad endloop!");
-
- /* Read in what should be the endfacet line
- */
- STLREADLINE;
- if ( !strstr(buffer, "endfacet") && !strstr(buffer, "ENDFACET") )
- STLBAILOUT("Bad endfacet!");
-
- /* Made it this far? Increment face count */
- ++totface;
- }
- fclose(fpSTL);
-
- /* OK, lets create our mesh */
- ob = add_object(scene, OB_MESH);
- me = ob->data;
-
- me->totface = totface;
- me->totvert = totvert;
- me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC,
- NULL, totvert);
- me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC,
- NULL, totface);
-
- /* Copy vert coords and create topology */
- mvert = me->mvert;
- mface = me->mface;
- vertnum = 0;
- for (i=0; i < totface; ++i) {
- memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) );
- mface->v1 = vertnum;
- mvert++;
- vertnum++;
-
- memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) );
- mface->v2 = vertnum;
- mvert++;
- vertnum++;
-
- memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) );
- mface->v3 = vertnum;
- mvert++;
- vertnum++;
-
- mface++;
- }
- free(vertdata);
-
- mesh_add_normals_flags(me);
- make_edges(me, 0);
-
- //XXX waitcursor(1);
-}
-
-#undef STLALLOCERROR
-#undef STLBAILOUT
-#undef STLREADLINE
-#undef STLREADVERT
-
-/* ************************************************************ */
-
-int BKE_read_exotic(Scene *scene, const char *name)
-{
- int len;
- gzFile gzfile;
- char header[7];
- int retval;
-
- // make sure we're not trying to read a directory....
-
- len= strlen(name);
- if (ELEM(name[len-1], '/', '\\')) {
- retval= BKE_READ_EXOTIC_FAIL_PATH;
- }
- else {
- gzfile = gzopen(name,"rb");
-
- if (gzfile == NULL) {
- retval= BKE_READ_EXOTIC_FAIL_OPEN;
- }
- else {
- len= gzread(gzfile, header, sizeof(header));
- gzclose(gzfile);
- if (len == sizeof(header) && strncmp(header, "BLENDER", 7) == 0) {
- retval= BKE_READ_EXOTIC_OK_BLEND;
- }
- else {
- //XXX waitcursor(1);
- if(is_dxf(name)) {
- dxf_read(scene, name);
- retval= BKE_READ_EXOTIC_OK_OTHER;
- }
- else if(is_stl(name)) {
- if (is_stl_ascii(name))
- read_stl_mesh_ascii(scene, name);
- else
- read_stl_mesh_binary(scene, name);
- retval= BKE_READ_EXOTIC_OK_OTHER;
- }
- else {
- retval= BKE_READ_EXOTIC_FAIL_FORMAT;
- }
- //XXX waitcursor(0);
- }
- }
- }
-
- return retval;
-}
-
-
-/* ************************ WRITE ************************** */
-
-static void write_vert_stl(Object *ob, MVert *verts, int index, FILE *fpSTL)
-{
- float vert[3];
-
- VECCOPY(vert, verts[(index)].co);
- mul_m4_v3(ob->obmat, vert);
-
- if (ENDIAN_ORDER==B_ENDIAN) {
- SWITCH_INT(vert[0]);
- SWITCH_INT(vert[1]);
- SWITCH_INT(vert[2]);
- }
-
- fwrite(vert, sizeof(float), 3, fpSTL);
-}
-
-static int write_derivedmesh_stl(FILE *fpSTL, Object *ob, DerivedMesh *dm)
-{
- MVert *mvert = dm->getVertArray(dm);
- MFace *mface = dm->getTessFaceArray(dm);
- int i, numfacets = 0, totface = dm->getNumTessFaces(dm);
- float zero[3] = {0.0f, 0.0f, 0.0f};
-
- for (i=0; i<totface; i++, mface++) {
- fwrite(zero, sizeof(float), 3, fpSTL);
- write_vert_stl(ob, mvert, mface->v1, fpSTL);
- write_vert_stl(ob, mvert, mface->v2, fpSTL);
- write_vert_stl(ob, mvert, mface->v3, fpSTL);
- fprintf(fpSTL, " ");
- numfacets++;
-
- if(mface->v4) { /* quad = 2 tri's */
- fwrite(zero, sizeof(float), 3, fpSTL);
- write_vert_stl(ob, mvert, mface->v1, fpSTL);
- write_vert_stl(ob, mvert, mface->v3, fpSTL);
- write_vert_stl(ob, mvert, mface->v4, fpSTL);
- fprintf(fpSTL, " ");
- numfacets++;
- }
- }
-
- return numfacets;
-}
-
-static int write_object_stl(FILE *fpSTL, Scene *scene, Object *ob)
-{
- int numfacets = 0;
- DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
-
- numfacets += write_derivedmesh_stl(fpSTL, ob, dm);
-
- dm->release(dm);
-
- return numfacets;
-}
-
-void write_stl(Scene *scene, char *str)
-{
- Object *ob;
- Base *base;
- FILE *fpSTL;
- int numfacets = 0;
- ReportList *reports= NULL; /* XXX */
-
- /* XXX, operator needs to manage filename extension */
-
- fpSTL= fopen(str, "wb");
-
- if(fpSTL==NULL) {
- BKE_reportf(reports, RPT_ERROR, "Can't open file: %s.", strerror(errno));
- return;
- }
-
- //XXX waitcursor(1);
-
- /* The header part of the STL */
- /* First 80 characters are a title or whatever you want.
- Lets make the first 32 of those spam and the rest the filename.
- Those first 80 characters will be followed by 4 bytes
- which will be overwritten later with an integer holding
- how many facets are written (we set them to ' ' for now).
- */
- fprintf(fpSTL, "Binary STL output from Blender: %-48.48s ", str);
-
- /* Write all selected mesh objects */
- base= scene->base.first;
- while(base) {
- if (base->flag & SELECT) {
- ob = base->object;
- if (ob->type == OB_MESH) {
- if(ob->data)
- numfacets += write_object_stl(fpSTL, scene, ob);
- }
- }
- base= base->next;
- }
-
- /* time to write the number of facets in the 4 bytes
- starting at byte 81
- */
- fseek(fpSTL, 80, SEEK_SET);
-
- if (ENDIAN_ORDER==B_ENDIAN) {
- SWITCH_INT(numfacets);
- }
- fwrite(&numfacets, 4*sizeof(char), 1, fpSTL);
-
- fclose(fpSTL);
-
- //XXX waitcursor(0);
-}
-
-
-static void replace_chars(char *str1, char *str2)
-{
- int a= strlen(str2);
-
- str1[a]= 0;
- while(a--) {
- if(str2[a]=='.' || str2[a]==' ') str1[a]= '_';
- else str1[a]= str2[a];
- }
-}
-
-/* ******************************* WRITE DXF ***************************** */
-
-#define write_group(id,data) fprintf(fp, "%d\n%s\n", id, data)
-
-/* A completely wacky function to try and make good
-indexed (AutoCAD index) values out of straight rgb
-ones... crazy */
-
-static int rgb_to_dxf_col (float rf, float gf, float bf)
-{
- int r= (int) (rf*255.0f);
- int g= (int) (gf*255.0f);
- int b= (int) (bf*255.0f);
- float h,s,v;
- int ret;
-
- /* Grayscale value */
- if (((int)r/10)==((int)g/10) && ((int)g/10)==((int)b/10)) ret= 250+((int)r/51);
- /* A nice chroma value */
- else {
- rgb_to_hsv (rf,gf,bf,&h,&s,&v);
-
- ret= (int) (10.0f + (h*239.0f));
- CLAMP(ret,10,249);
-
- /* If its whitish make the index odd */
- if (s<.5 || v>.5) if(ret%2) ret++;
- }
-
- return ret;
-}
-
-/* And its completely wacky complement */
-
-static void dxf_col_to_rgb (int cid, float *rf, float *gf, float *bf)
-{
- float h, s, v;
-
- /* Grayscale values */
- if (cid>=250 && cid <= 255) {
- *rf= *gf= *bf= (float) ((cid-250)*51)/255;
- CLAMP(*rf, 0.0, 1.0);
- CLAMP(*gf, 0.0, 1.0);
- CLAMP(*bf, 0.0, 1.0);
-
- /* Pure values */
- } else if (cid<10) {
- switch (cid) {
- case 1:
- *rf=1.0;
- *gf=0.0;
- *bf=0.0;
- break;
- case 2:
- *rf=1.0;
- *gf=1.0;
- *bf=0.0;
- break;
- case 3:
- *gf=1.0;
- *rf=0.0;
- *bf=0.0;
- break;
- case 4:
- *rf=0.0;
- *gf=1.0;
- *bf=1.0;
- break;
- case 5:
- *rf=0.0;
- *gf=0.0;
- *bf=1.0;
- break;
- case 6:
- *rf=1.0;
- *gf=0.0;
- *bf=1.0;
- break;
- case 7:
- default:
- *rf= *gf= *bf= 1.0;
- break;
- }
- } else {
- /* Get chroma values */
-
- h= (float) (cid-10)/239;
- CLAMP(h, 0.0, 1.0);
-
- /* If its odd make it a bit whitish */
- if (cid%2) { s=.75; v= 0.25;
- } else { s= 0.25; v= 0.75;}
-
- hsv_to_rgb (h, s, v, rf, gf, bf);
- }
-}
-
-static void write_mesh_dxf(FILE *fp, Mesh *me)
-{
- Material *ma;
- MVert *mvert;
- MFace *mface;
- int a;
- char str[32];
-
- replace_chars(str, me->id.name+2);
-
- write_group(0, "BLOCK");
-
- write_group(2, str); /* The name */
-
- write_group(8, "Meshes"); /* DXF Layer */
- write_group(70, "64"); /* DXF block flags */
-
- write_group(10, "0.0"); /* X of base */
- write_group(20, "0.0"); /* Y of base */
- write_group(30, "0.0"); /* Z of base */
-
- write_group(3, str); /* The name (again) */
-
- write_group(0, "POLYLINE"); /* Start the mesh */
- write_group(66, "1"); /* Vertices follow flag */
- write_group(8,"Meshes"); /* DXF Layer */
-
- if (me->totcol) {
- ma= me->mat[0];
- if(ma) {
- sprintf(str,"%d",rgb_to_dxf_col(ma->r,ma->g,ma->b));
- write_group(62, str); /* Color index */
- }
- }
-
- write_group(70, "64"); /* Polymesh mesh flag */
-
- fprintf(fp, "71\n%d\n", me->totvert); /* Total vertices */
- fprintf(fp, "72\n%d\n", me->totface); /* Total faces */
-
- /* Write the vertices */
- a= me->totvert;
- mvert= me->mvert;
- while(a--) {
- write_group(0, "VERTEX"); /* Start a new vertex */
- write_group(8, "Meshes"); /* DXF Layer */
- fprintf (fp, "10\n%f\n", mvert->co[0]); /* X cord */
- fprintf (fp, "20\n%f\n", mvert->co[1]); /* Y cord */
- fprintf (fp, "30\n%f\n", mvert->co[2]); /* Z cord */
- write_group(70, "192"); /* Polymesh vertex flag */
-
- mvert++;
- }
-
- /* Write the face entries */
- a= me->totface;
- mface= me->mface;
- while(a--) {
- write_group(0, "VERTEX"); /* Start a new face */
- write_group(8, "Meshes");
-
- /* Write a face color */
- if (me->totcol) {
- ma= me->mat[(int)mface->mat_nr];
- if(ma) {
- sprintf(str,"%d",rgb_to_dxf_col(ma->r,ma->g,ma->b));
- write_group(62, str); /* Color index */
- }
- }
- else write_group(62, "254"); /* Color Index */
-
- /* Not sure what this really corresponds too */
- write_group(10, "0.0"); /* X of base */
- write_group(20, "0.0"); /* Y of base */
- write_group(30, "0.0"); /* Z of base */
-
- write_group(70, "128"); /* Polymesh face flag */
-
- if(mface->v4) {
- fprintf (fp, "71\n%d\n", mface->v1+1);
- fprintf (fp, "72\n%d\n", mface->v2+1);
- fprintf (fp, "73\n%d\n", mface->v3+1);
- fprintf (fp, "74\n%d\n", mface->v4+1);
- } else {
- fprintf (fp, "71\n%d\n", mface->v1+1);
- fprintf (fp, "72\n%d\n", mface->v2+1);
- fprintf (fp, "73\n%d\n", mface->v3+1);
- }
- mface++;
- }
-
- write_group(0, "SEQEND");
-
- write_group(0, "ENDBLK");
-}
-
-static void write_object_dxf(FILE *fp, Object *ob, int layer)
-{
- ID *id;
- char str[32];
-
- id= ob->data;
-
- write_group(0, "INSERT"); /* Start an insert group */
-
- sprintf(str, "%d", layer);
- write_group(8, str);
-
- replace_chars(str, id->name+2);
- write_group(2, str);
-
- fprintf (fp, "10\n%f\n", ob->loc[0]); /* X of base */
- fprintf (fp, "20\n%f\n", ob->loc[1]); /* Y of base */
- fprintf (fp, "30\n%f\n", ob->loc[2]); /* Z of base */
-
- fprintf (fp, "41\n%f\n", ob->size[0]); /* X scale */
- fprintf (fp, "42\n%f\n", ob->size[1]); /* Y scale */
- fprintf (fp, "43\n%f\n", ob->size[2]); /* Z scale */
-
- fprintf (fp, "50\n%f\n", (float) ob->rot[2]*180/M_PI); /* Can only write the Z rot */
-}
-
-void write_dxf(struct Scene *scene, char *str)
-{
- Mesh *me;
- Base *base;
- FILE *fp;
-
- /* XXX, operator needs to handle overwrite & rename */
-
- fp= fopen(str, "w");
-
- if(fp==NULL) {
- //XXX error("Can't write file");
- return;
- }
-
- //XXX waitcursor(1);
-
- /* The header part of the DXF */
-
- write_group(0, "SECTION");
- write_group(2, "HEADER");
- write_group(0, "ENDSEC");
-
- /* The blocks part of the DXF */
-
- write_group(0, "SECTION");
- write_group(2, "BLOCKS");
-
-
- /* only write meshes we're using in this scene */
- flag_listbase_ids(&G.main->mesh, LIB_DOIT, 0);
-
- for(base= scene->base.first; base; base= base->next)
- if(base->object->type== OB_MESH)
- ((ID *)base->object->data)->flag |= LIB_DOIT;
-
- /* Write all the meshes */
- me= G.main->mesh.first;
- while(me) {
- if(me->id.flag & LIB_DOIT) { /* is the mesh used in this scene ? */
- write_mesh_dxf(fp, me);
- }
- me= me->id.next;
- }
-
- write_group(0, "ENDSEC");
-
- /* The entities part of the DXF */
-
- write_group(0, "SECTION");
- write_group(2, "ENTITIES");
-
- /* Write all the mesh objects */
- base= scene->base.first;
- while(base) {
- if(base->object->type== OB_MESH) {
- write_object_dxf(fp, base->object, base->lay);
- }
- base= base->next;
- }
-
- write_group(0, "ENDSEC");
-
- /* Thats all */
-
- write_group(0, "EOF");
- fclose(fp);
-
- //XXX waitcursor(0);
-}
-
-
-static int dxf_line= 0;
-static FILE *dxf_fp= NULL;
-
-/* exotic.c(2863) : note C6311: c:/Program Files/Microsoft Visual
- * Studio/VC98/include\ctype.h(268) : see previous definition of
- * 'iswspace' */
-#define ton_iswspace(c) (c==' '||c=='\n'||c=='\t')
-
-static void clean_wspace (char *str)
-{
- char *from, *to;
- char t;
-
- from= str;
- to=str;
-
- while (*from!=0) {
- t= *from;
- *to= t;
-
- if(!ton_iswspace(*from)) to++;
- from++;
- }
- *to=0;
-}
-
-static int all_wspace(char *str)
-{
- while(*str != 0) {
- if (!ton_iswspace(*str)) return 0;
- str++;
- }
-
- return 1;
-}
-
-static int all_digits(char *str)
-{
- while(*str != 0) {
- if (!isdigit(*str)) return 0;
- str++;
- }
-
- return 1;
-}
-
-static int dxf_get_layer_col(char *UNUSED(layer))
-{
- return 1;
-}
-
-static int dxf_get_layer_num(Scene *scene, char *layer)
-{
- int ret = 0;
-
- if (all_digits(layer) && atoi(layer)<(1<<20)) ret= atoi(layer);
- if (ret == 0) ret = scene->lay;
-
- return ret;
-}
-
-static void dos_clean(char *str)
-{
- while (*str) {
- if (*str == 0x0d) {
- *str='\n';
- *(++str)= 0;
- break;
- }
- str++;
- }
-}
-
-static void myfgets(char *str, int len, FILE *fp)
-{
- char c;
-
- while(len>0 && (c=getc(dxf_fp)) ) {
- *str= c;
- str++;
- len--;
- /* three types of enters, \n \r and \r\n */
- if(c == '\n') break;
- if(c=='\r') {
- c= getc(fp); // read the linefeed from stream
- if(c != 10) ungetc(c, fp); // put back, if it's not one...
- break;
- }
- }
-}
-
-static int read_groupf(char *str)
-{
- short c;
- int ret=-1;
- char tmp[256];
-
- strcpy(str, " ");
-
- while ((c=getc(dxf_fp)) && ton_iswspace(c));
- ungetc(c, dxf_fp);
- if (c==EOF) return -1;
-
- myfgets(tmp, 255, dxf_fp);
-
- dos_clean(tmp);
-
- if(sscanf(tmp, "%d\n", &ret)!=1) return -2;
-
- myfgets(tmp, 255, dxf_fp);
-
- dos_clean(tmp);
-
- if (!all_wspace(tmp)) {
- if (sscanf(tmp, "%s\n", str)!=1) return -2;
- }
-
- clean_wspace(str);
- dxf_line+=2;
-
- return ret;
-}
-
-//XXX error() is now printf until we have a callback error
-#define id_test(id) if(id<0) {char errmsg[128];fclose(dxf_fp); if(id==-1) sprintf(errmsg, "Error inputting dxf, near line %d", dxf_line); else if(id==-2) sprintf(errmsg, "Error reading dxf, near line %d", dxf_line);printf("%s", errmsg); return;}
-
-#define read_group(id,str) {id= read_groupf(str); id_test(id);}
-
-#define group_is(idtst,str) (id==idtst&&strcmp(val,str)==0)
-#define group_isnt(idtst,str) (id!=idtst||strcmp(val,str)!=0)
-#define id_check(idtst,str) if(group_isnt(idtst,str)) { fclose(dxf_fp); printf("Error parsing dxf, near line %d", dxf_line); return;}
-
-static int id;
-static char val[256];
-
-static short error_exit=0;
-static short hasbumped=0;
-
-static int is_dxf(const char *str)
-{
- dxf_line=0;
-
- dxf_fp= fopen(str, "r");
- if (dxf_fp==NULL) return 0;
-
- id= read_groupf(val);
- if ((id==0 && strcmp(val, "SECTION")==0)||id==999) return 1;
-
- fclose(dxf_fp);
-
- return 0;
-}
-
-/* NOTES ON THE READER */
-/*
- --
- It turns out that most DXF writers like (LOVE) to
- write meshes as a long string of 3DFACE entities.
- This means the natural way to read a DXF file
- (every entity corresponds to an object) is completely
- unusable, reading in 10,000 faces each as an
- object just doesn't cut it. Thus the 3DFACE
- entry reader holds state, and only finalizes to
- an object when a) the layer name changes, b) the
- entry type changes, c) we are done reading.
-
- PS... I decided to do the same thing with LINES,
- apparently the same thing happens sometimes as
- well.
-
- PPS... I decided to do the same thing with everything.
- Now it is all really nasty and should be rewritten.
- --
-
- Added circular and elliptical arcs and lwpolylines.
- These are all self-contained and have the size known
- in advance, and so I haven't used the held state. -- martin
-*/
-
-static void dxf_add_mat (Object *ob, Mesh *me, float color[3], char *layer)
-{
- Material *ma;
-
- if (!me) return;
-
- if(ob) {
- ob->mat= MEM_callocN(sizeof(void *)*1, "ob->mat");
- ob->matbits= MEM_callocN(sizeof(char)*1, "ob->matbits");
- ob->actcol= 1;
- }
-
- me->totcol= 1;
- me->mat= MEM_callocN(sizeof(void *)*1, "me->mat");
-
- if (color[0]<0) {
- if (strlen(layer)) dxf_col_to_rgb(dxf_get_layer_col(layer), &color[0], &color[1], &color[2]);
- color[0]= color[1]= color[2]= 0.8f;
- }
-
- ma= G.main->mat.first;
- while(ma) {
- if(ma->mtex[0]==NULL) {
- if(color[0]==ma->r && color[1]==ma->g && color[2]==ma->b) {
- me->mat[0]= ma;
- ma->id.us++;
- break;
- }
- }
- ma= ma->id.next;
- }
- if(ma==NULL) {
- ma= add_material("ext");
- me->mat[0]= ma;
- ma->r= color[0];
- ma->g= color[1];
- ma->b= color[2];
- automatname(ma);
- }
-}
-
- /* General DXF vars */
-static float cent[3]={0.0, 0.0, 0.0};
-static char layname[32]="";
-static char entname[32]="";
-static float color[3]={-1.0, -1.0, -1.0};
-static float *vcenter;
-static float zerovec[3]= {0.0, 0.0, 0.0};
-
-#define reset_vars cent[0]= cent[1]= cent[2]=0.0; strcpy(layname, ""); color[0]= color[1]= color[2]= -1.0
-
-
-static void dxf_get_mesh(Scene *scene, Mesh** m, Object** o, int noob)
-{
- Mesh *me = NULL;
- Object *ob;
-
- if (!noob) {
- *o = add_object(scene, OB_MESH);
- ob = *o;
-
- if (entname[0]) new_id(&G.main->object, (ID *)ob, entname);
- else if (layname[0]) new_id(&G.main->object, (ID *)ob, layname);
-
- if (layname[0]) ob->lay= dxf_get_layer_num(scene, layname);
- else ob->lay= scene->lay;
- // not nice i know... but add_object() sets active base, which needs layer setting too (ton)
- scene->basact->lay= ob->lay;
-
- *m = ob->data;
- me= *m;
-
- vcenter= ob->loc;
- }
- else {
- *o = NULL;
- *m = add_mesh("Mesh");
-
- me = *m;
- ob = *o;
-
- ((ID *)me)->us=0;
-
- if (entname[0]) new_id(&G.main->mesh, (ID *)me, entname);
- else if (layname[0]) new_id(&G.main->mesh, (ID *)me, layname);
-
- vcenter = zerovec;
- }
- me->totvert=0;
- me->totface=0;
- me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, 0);
- me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
-}
-
-static void dxf_read_point(Scene *scene, int noob) {
- /* Blender vars */
- Object *ob;
- Mesh *me;
- MVert *mvert;
-
- reset_vars;
-
- read_group(id, val);
- while(id!=0) {
- if (id==8) {
- BLI_strncpy(layname, val, sizeof(layname));
- } else if (id==10) {
- cent[0]= (float) atof(val);
- } else if (id==20) {
- cent[1]= (float) atof(val);
- } else if (id==30) {
- cent[2]= (float) atof(val);
- } else if (id==60) {
- /* short invisible= atoi(val); */
- } else if (id==62) {
- int colorid= atoi(val);
-
- CLAMP(colorid, 1, 255);
- dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
- }
- read_group(id, val);
- }
-
- dxf_get_mesh(scene, &me, &ob, noob);
- me->totvert= 1;
- me->mvert= MEM_callocN(me->totvert*sizeof(MVert), "mverts");
- CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
-
- dxf_add_mat (ob, me, color, layname);
-
- mvert= me->mvert;
- mvert->co[0]= mvert->co[1]= mvert->co[2]= 0;
-
- if (ob) VECCOPY(ob->loc, cent);
-
- hasbumped=1;
-}
-
- /* Line state vars */
-static Object *linehold=NULL;
-static Mesh *linemhold=NULL;
-
-static char oldllay[32];
-static short lwasline=0; /* last was face 3d? */
-
-static void dxf_close_line(void)
-{
- linemhold=NULL;
- if (linehold==NULL) return;
-
- linehold=NULL;
-}
-
-static void dxf_read_line(Scene *scene, int noob) {
- /* Entity specific vars */
- float epoint[3]={0.0, 0.0, 0.0};
- short vspace=0; /* Whether or not coords are relative */
-
- /* Blender vars */
- Object *ob;
- Mesh *me;
- MVert *mvert, *vtmp;
- MFace *mface, *ftmp;
-
- reset_vars;
-
- read_group(id, val);
- while(id!=0) {
- if (id==8) {
- BLI_strncpy(layname, val, sizeof(layname));
- } else if (id==10) {
- cent[0]= (float) atof(val);
- } else if (id==20) {
- cent[1]= (float) atof(val);
- } else if (id==30) {
- cent[2]= (float) atof(val);
- } else if (id==11) {
- epoint[0]= (float) atof(val);
- } else if (id==21) {
- epoint[1]= (float) atof(val);
- } else if (id==31) {
- epoint[2]= (float) atof(val);
- } else if (id==60) {
- /* short invisible= atoi(val); */
- } else if (id==62) {
- int colorid= atoi(val);
-
- CLAMP(colorid, 1, 255);
- dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
- } else if (id==67) {
- vspace= atoi(val);
- }
- read_group(id, val);
- }
-
- /* Check to see if we need to make a new object */
-
- if(!lwasline || strcmp(layname, oldllay)!=0)
- dxf_close_line();
- if(linemhold != NULL && linemhold->totvert>MESH_MAX_VERTS)
- dxf_close_line();
-
- if (linemhold==NULL) {
- dxf_get_mesh(scene, &me, &ob, noob);
-
- if(ob) VECCOPY(ob->loc, cent);
-
- dxf_add_mat (ob, me, color, layname);
-
- linehold= ob;
- linemhold= me;
- } else {
- ob= linehold;
- me= linemhold;
- }
-
- me->totvert+= 2;
- me->totface++;
-
- vtmp= MEM_callocN(me->totvert*sizeof(MVert), "mverts");
- ftmp= MEM_callocN(me->totface*sizeof(MFace), "mface");
-
- if(me->mvert) {
- memcpy(vtmp, me->mvert, (me->totvert-2)*sizeof(MVert));
- MEM_freeN(me->mvert);
- }
- me->mvert= CustomData_set_layer(&me->vdata, CD_MVERT, vtmp);
- vtmp=NULL;
-
- if(me->mface) {
- memcpy(ftmp, me->mface, (me->totface-1)*sizeof(MFace));
- MEM_freeN(me->mface);
- }
- me->mface= CustomData_set_layer(&me->fdata, CD_MFACE, ftmp);
- ftmp=NULL;
-
- mvert= &me->mvert[(me->totvert-2)];
-
- sub_v3_v3v3(mvert->co, cent, vcenter);
- mvert++;
- if (vspace) { VECCOPY(mvert->co, epoint);
- } else sub_v3_v3v3(mvert->co, epoint, vcenter);
-
- mface= &(((MFace*)me->mface)[me->totface-1]);
- mface->v1= me->totvert-2;
- mface->v2= me->totvert-1;
- mface->mat_nr= 0;
-
- hasbumped=1;
-}
-
- /* 2D Polyline state vars */
-static Object *p2dhold=NULL;
-static Mesh *p2dmhold=NULL;
-static char oldplay[32];
-static short lwasp2d=0;
-
-static void dxf_close_2dpoly(void)
-{
- p2dmhold= NULL;
- if (p2dhold==NULL) return;
-
- p2dhold=NULL;
-}
-
-static void dxf_read_ellipse(Scene *scene, int noob)
-{
-
- /*
- * The Parameter option of the ELLIPSE command uses the following equation to define an elliptical arc.
- *
- * p(u)=c+a*cos(u)+b*sin(u)
- *
- * The variables a, b, c are determined when you select the endpoints for the
- * first axis and the distance for the second axis. a is the negative of 1/2
- * of the major axis length, b is the negative of 1/2 the minor axis length,
- * and c is the center point (2-D) of the ellipse.
- *
- * Because this is actually a vector equation and the variable c is actually
- * a point with X and Y values, it really should be written as:
- *
- * p(u)=(Cx+a*cos(u))*i+(Cy+b*sin(u))*j
- *
- * where
- *
- * Cx is the X value of the point c
- * Cy is the Y value of the point c
- * a is -(1/2 of the major axis length)
- * b is -(1/2 of the minor axis length)
- * i and j represent unit vectors in the X and Y directions
- *
- * http://astronomy.swin.edu.au/~pbourke/geomformats/dxf2000/ellipse_command39s_parameter_option_dxf_06.htm
- * (reproduced with permission)
- *
- * NOTE: The start and end angles ('parameters') are in radians, whereas those for the circular arc are
- * in degrees. The 'sense' of u appears to be determined by the extrusion direction (see more detailed comment
- * in the code)
- *
- * TODO: The code is specific to ellipses in the x-y plane right now.
- *
- */
-
- /* Entity specific vars */
- float epoint[3]={0.0, 0.0, 0.0};
- float center[3]={0.0, 0.0, 0.0};
- float extrusion[3]={0.0, 0.0, 1.0};
- float axis_endpoint[3] = {0.0, 0.0, 0.0}; /* major axis endpoint */
- short vspace=0; /* Whether or not coords are relative */
- float a, b, x, y, z;
- float phid = 0.0f, phi = 0.0f, theta = 0.0f;
- float start_angle = 0.0f;
- float end_angle = 2*M_PI;
- float axis_ratio = 1.0f;
- float temp;
- int v, tot;
- int isArc=0;
- /* Blender vars */
- Object *ob;
- Mesh *me;
- MVert *mvert;
- MFace *mface;
-
- reset_vars;
- read_group(id, val);
- while(id!=0) {
- if (id==8) {
- BLI_strncpy(layname, val, sizeof(layname));
- } else if (id==10) {
- center[0]= (float) atof(val);
- } else if (id==20) {
- center[1]= (float) atof(val);
- } else if (id==30) {
- center[2]= (float) atof(val);
- } else if (id==11) {
- axis_endpoint[0]= (float) atof(val);
- } else if (id==21) {
- axis_endpoint[1]= (float) atof(val);
- } else if (id==31) {
- axis_endpoint[2]= (float) atof(val);
- } else if (id==40) {
- axis_ratio = (float) atof(val);
- } else if (id==41) {
- printf("dxf: start = %f", atof(val) * 180/M_PI);
- start_angle = -atof(val) + M_PI_2;
- } else if (id==42) {
- printf("dxf: end = %f", atof(val) * 180/M_PI);
- end_angle = -atof(val) + M_PI_2;
- } else if (id==62) {
- int colorid= atoi(val);
- CLAMP(colorid, 1, 255);
- dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
- } else if (id==67) {
- vspace= atoi(val);
- } else if (id==100) {
- isArc = 1;
- } else if (id==210) {
- extrusion[0] = atof(val);
- } else if (id==220) {
- extrusion[1] = atof(val);
- } else if (id==230) {
- extrusion[2] = atof(val);
- }
- read_group(id, val);
- }
-
- if(!lwasline || strcmp(layname, oldllay)!=0) dxf_close_line();
- if(linemhold != NULL && linemhold->totvert>MESH_MAX_VERTS)
- dxf_close_line();
-
- /* The 'extrusion direction' seems akin to a face normal,
- * insofar as it determines the direction of increasing phi.
- * This is again x-y plane specific; it should be fixed at
- * some point. */
-
- if (extrusion[2] < 0) {
- temp = start_angle;
- start_angle = M_PI - end_angle;
- end_angle = M_PI - temp;
- }
-
- if(end_angle > start_angle)
- end_angle -= 2 * M_PI;
-
- phi = start_angle;
-
- x = axis_endpoint[0];
- y = axis_endpoint[1];
- z = axis_endpoint[2];
- a = sqrt(x*x + y*y + z*z);
- b = a * axis_ratio;
-
- theta = atan2(y, x);
-
- x = a * sin(phi);
- y = b * cos(phi);
-
-#ifndef DEBUG_CENTER
- epoint[0] = center[0] + x*cos(theta) - y*sin(theta);
- epoint[1] = center[1] + x*sin(theta) + y*cos(theta);
- epoint[2] = center[2];
-
-
- cent[0]= epoint[0];
- cent[1]= epoint[1];
- cent[2]= epoint[2];
-#else
- cent[0]= center[0];
- cent[1]= center[1];
- cent[2]= center[2];
-#endif
-
- dxf_get_mesh(scene, &me, &ob, noob);
- strcpy(oldllay, layname);
- if(ob) VECCOPY(ob->loc, cent);
- dxf_add_mat (ob, me, color, layname);
-
- tot = 32; /* # of line segments to divide the arc into */
-
- phid = (end_angle - start_angle)/tot;
-
- me->totvert += tot+1;
- me->totface += tot+1;
-
- me->mvert = (MVert*) MEM_callocN(me->totvert*sizeof(MVert), "mverts");
- me->mface = (MFace*) MEM_callocN(me->totface*sizeof(MVert), "mface");
-
- CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
- CustomData_set_layer(&me->fdata, CD_MFACE, me->mface);
-
- printf("vertex and face buffers allocated\n");
-
- for(v = 0; v <= tot; v++) {
-
- x = a * sin(phi);
- y = b * cos(phi);
- epoint[0] = center[0] + x*cos(theta) - y*sin(theta);
- epoint[1] = center[1] + x*sin(theta) + y*cos(theta);
- epoint[2] = center[2];
-
- mvert= &me->mvert[v];
-
- if (vspace) {
- VECCOPY(mvert->co, epoint);
- } else {
- sub_v3_v3v3(mvert->co, epoint, vcenter);
- }
-
- if (v > 0) {
- mface= &(((MFace*)me->mface)[v-1]);
- mface->v1 = v-1;
- mface->v2 = v;
- mface->mat_nr = 0;
- }
-
- hasbumped = 1;
-
- VECCOPY(cent, epoint);
- phi+=phid;
- }
-}
-
-static void dxf_read_arc(Scene *scene, int noob)
-{
- /* Entity specific vars */
- float epoint[3]={0.0, 0.0, 0.0};
- float center[3]={0.0, 0.0, 0.0};
- float extrusion[3]={0.0, 0.0, 1.0};
- short vspace=0; /* Whether or not coords are relative */
- float dia = 0.0f;
- float phid = 0.0f, phi = 0.0f;
- float start_angle = 0.0f;
- float end_angle = 2*M_PI;
- float temp;
- int v, tot = 32;
- int isArc=0;
- /* Blender vars */
- Object *ob;
- Mesh *me;
- MVert *mvert;
- MFace *mface;
-
- reset_vars;
- read_group(id, val);
- while(id!=0) {
- if (id==8) {
- BLI_strncpy(layname, val, sizeof(layname));
- } else if (id==10) {
- center[0]= (float) atof(val);
- } else if (id==20) {
- center[1]= (float) atof(val);
- } else if (id==30) {
- center[2]= (float) atof(val);
- } else if (id==40) {
- dia = (float) atof(val);
- } else if (id==62) {
- int colorid= atoi(val);
-
- CLAMP(colorid, 1, 255);
- dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
- } else if (id==67) {
- vspace= atoi(val);
- } else if (id==100) {
- isArc = 1;
- } else if (id==50) {
- start_angle = (90 - atoi(val)) * M_PI/180.0;
- } else if (id==51) {
- end_angle = (90 - atoi(val)) * M_PI/180.0;
- } else if (id==210) {
- extrusion[0] = atof(val);
- } else if (id==220) {
- extrusion[1] = atof(val);
- } else if (id==230) {
- extrusion[2] = atof(val);
- }
- read_group(id, val);
- }
-
- if(!lwasline || strcmp(layname, oldllay)!=0) dxf_close_line();
- if(linemhold != NULL && linemhold->totvert>MESH_MAX_VERTS)
- dxf_close_line();
-
- /* Same xy-plane-specific extrusion direction code as in read_ellipse
- * (read_arc and read_ellipse should ideally be rewritten to share code)
- */
-
- if (extrusion[2] < 0) {
- temp = start_angle;
- start_angle = M_PI - end_angle;
- end_angle = M_PI - temp;
- }
-
- phi = start_angle;
- if(end_angle > start_angle)
- end_angle -= 2 * M_PI;
-
- cent[0]= center[0]+dia*sin(phi);
- cent[1]= center[1]+dia*cos(phi);
- cent[2]= center[2];
-
- dxf_get_mesh(scene, &me, &ob, noob);
- BLI_strncpy(oldllay, layname, sizeof(oldllay));
- if(ob) VECCOPY(ob->loc, cent);
- dxf_add_mat (ob, me, color, layname);
-
- tot = 32; /* # of line segments to divide the arc into */
- phid = (end_angle - start_angle)/tot; /* fix so that arcs have the same 'resolution' as circles? */
-
- me->totvert += tot+1;
- me->totface += tot+1;
-
- me->mvert = (MVert*) MEM_callocN(me->totvert*sizeof(MVert), "mverts");
- me->mface = (MFace*) MEM_callocN(me->totface*sizeof(MVert), "mface");
-
- CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
- CustomData_set_layer(&me->fdata, CD_MFACE, me->mface);
-
- for(v = 0; v <= tot; v++) {
-
- epoint[0]= center[0]+dia*sin(phi);
- epoint[1]= center[1]+dia*cos(phi);
- epoint[2]= center[2];
-
- mvert= &me->mvert[v];
-
- if (vspace) {
- VECCOPY(mvert->co, epoint);
- } else {
- sub_v3_v3v3(mvert->co, epoint, vcenter);
- }
-
- if (v > 0) {
- mface= &(((MFace*)me->mface)[v-1]);
- mface->v1 = v-1;
- mface->v2 = v;
- mface->mat_nr = 0;
- }
-
- hasbumped=1;
-
- VECCOPY(cent, epoint);
- phi+=phid;
- }
-}
-
-static void dxf_read_polyline(Scene *scene, int noob) {
- /* Entity specific vars */
- short vspace=0; /* Whether or not coords are relative */
- int flag=0;
- int vflags=0;
- int vids[4];
- int nverts;
-
- /* Blender vars */
- Object *ob;
- Mesh *me;
- float vert[3] = {0};
-
- MVert *mvert, *vtmp;
- MFace *mface, *ftmp;
-
- reset_vars;
-
- read_group(id, val);
- while(id!=0) {
- if (id==8) {
- BLI_strncpy(layname, val, sizeof(layname));
- } else if (id==10) {
- cent[0]= (float) atof(val);
- } else if (id==20) {
- cent[1]= (float) atof(val);
- } else if (id==30) {
- cent[2]= (float) atof(val);
- } else if (id==60) {
- /* short invisible= atoi(val); */
- } else if (id==62) {
- int colorid= atoi(val);
-
- CLAMP(colorid, 1, 255);
- dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
- } else if (id==67) {
- vspace= atoi(val);
- } else if (id==70) {
- flag= atoi(val);
- }
- read_group(id, val);
- }
-
- if (flag & 9) { // 1= closed curve, 8= 3d curve
- if(!lwasp2d || strcmp(layname, oldplay)!=0) dxf_close_2dpoly();
- if(p2dmhold != NULL && p2dmhold->totvert>MESH_MAX_VERTS)
- dxf_close_2dpoly();
-
- if (p2dmhold==NULL) {
- dxf_get_mesh(scene, &me, &ob, noob);
-
- strcpy(oldplay, layname);
-
- if(ob) VECCOPY(ob->loc, cent);
-
- dxf_add_mat (ob, me, color, layname);
-
- p2dhold= ob;
- p2dmhold= me;
- }
- else {
- ob= p2dhold;
- me= p2dmhold;
- }
-
- nverts=0;
- while (group_is(0, "VERTEX")) {
- read_group(id, val);
- while(id!=0) {
- if (id==10) {
- vert[0]= (float) atof(val);
- } else if (id==20) {
- vert[1]= (float) atof(val);
- } else if (id==30) {
- vert[2]= (float) atof(val);
- }
- read_group(id, val);
- }
- nverts++;
- me->totvert++;
-
- vtmp= MEM_callocN(me->totvert*sizeof(MVert), "mverts");
-
- if (me->mvert) {
- memcpy (vtmp, me->mvert, (me->totvert-1)*sizeof(MVert));
- MEM_freeN(me->mvert);
- }
- me->mvert= CustomData_set_layer(&me->vdata, CD_MVERT, vtmp);
- vtmp= NULL;
-
- mvert= &me->mvert[me->totvert-1];
-
- if (vspace) { VECCOPY(mvert->co, vert);
- } else sub_v3_v3v3(mvert->co, vert, vcenter);
- }
-
- /* make edges */
- if(nverts>1) {
- int a, oldtotface;
-
- oldtotface= me->totface;
- me->totface+= nverts-1;
-
- ftmp= MEM_callocN(me->totface*sizeof(MFace), "mface");
-
- if(me->mface) {
- memcpy(ftmp, me->mface, oldtotface*sizeof(MFace));
- MEM_freeN(me->mface);
- }
- me->mface= CustomData_set_layer(&me->fdata, CD_MFACE, ftmp);
- ftmp=NULL;
-
- mface= me->mface;
- mface+= oldtotface;
-
- for(a=1; a<nverts; a++, mface++) {
- mface->v1= (me->totvert-nverts)+a-1;
- mface->v2= (me->totvert-nverts)+a;
- mface->mat_nr= 0;
- }
- }
-
- lwasp2d=1;
- }
- else if (flag&64) {
- dxf_get_mesh(scene, &me, &ob, noob);
-
- if(ob) VECCOPY(ob->loc, cent);
-
- dxf_add_mat (ob, me, color, layname);
-
- while (group_is(0, "VERTEX")) {
- vflags= 0;
- vids[0]= vids[1]= vids[2]= vids[3]= 0;
-
- vflags=0;
- read_group(id, val);
- while(id!=0) {
- if(id==8) {
- ; /* Layer def, skip */
- } else if (id==10) {
- vert[0]= (float) atof(val);
- } else if (id==20) {
- vert[1]= (float) atof(val);
- } else if (id==30) {
- vert[2]= (float) atof(val);
- } else if (id==70) {
- vflags= atoi(val);
- } else if (id==71) {
- vids[0]= abs(atoi(val));
- } else if (id==72) {
- vids[1]= abs(atoi(val));
- } else if (id==73) {
- vids[2]= abs(atoi(val));
- } else if (id==74) {
- vids[3]= abs(atoi(val));
- }
- read_group(id, val);
- }
-
- if (vflags & 128 && vflags & 64) {
- me->totvert++;
-
- /* If we are nearing the limit scan to the next entry */
- if(me->totvert > MESH_MAX_VERTS)
- while(group_isnt(0, "SEQEND")) read_group(id, val);
-
- vtmp= MEM_callocN(me->totvert*sizeof(MVert), "mverts");
-
- if(me->mvert) {
- memcpy(vtmp, me->mvert, (me->totvert-1)*sizeof(MVert));
- MEM_freeN(me->mvert);
- }
- me->mvert= CustomData_set_layer(&me->vdata, CD_MVERT, vtmp);
- vtmp=NULL;
-
- mvert= &me->mvert[(me->totvert-1)];
-
- if (vspace) { VECCOPY(mvert->co, vert);
- } else sub_v3_v3v3(mvert->co, vert, vcenter);
-
- } else if (vflags & 128) {
- if(vids[2]==0) {
- //XXX error("(PL) Error parsing dxf, not enough vertices near line %d", dxf_line);
-
- error_exit=1;
- fclose(dxf_fp);
- return;
- }
-
- me->totface++;
-
- ftmp= MEM_callocN(me->totface*sizeof(MFace), "mfaces");
-
- if(me->mface) {
- memcpy(ftmp, me->mface, (me->totface-1)*sizeof(MFace));
- MEM_freeN(me->mface);
- }
- me->mface= CustomData_set_layer(&me->fdata, CD_MFACE, ftmp);
- ftmp=NULL;
-
- mface= &(((MFace*)me->mface)[me->totface-1]);
- mface->v1= vids[0]-1;
- mface->v2= vids[1]-1;
- mface->v3= vids[2]-1;
-
- if(vids[3] && vids[3]!=vids[0]) {
- mface->v4= vids[3]-1;
- test_index_face(mface, NULL, 0, 4);
- }
- else test_index_face(mface, NULL, 0, 3);
-
- mface->mat_nr= 0;
-
- } else {
- //XXX error("Error parsing dxf, unknown polyline information near %d", dxf_line);
-
- error_exit=1;
- fclose(dxf_fp);
- return;
- }
-
- }
- }
-}
-
-static void dxf_read_lwpolyline(Scene *scene, int noob) {
- /* Entity specific vars */
- short vspace=0; /* Whether or not coords are relative */
- int flag=0;
- int nverts=0;
- int v;
-
- /* Blender vars */
- Object *ob;
- Mesh *me;
- float vert[3] = {0};
-
- MVert *mvert;
- MFace *mface;
-
- reset_vars;
-
- id = -1;
-
- /* block structure is
- * {...}
- * 90 => nverts
- * 70 => flags
- * nverts.times { 10 => x, 20 => y }
- */
- while(id!=70) {
- read_group(id, val);
- if (id==8) {
- BLI_strncpy(layname, val, sizeof(layname));
- } else if (id==38) {
- vert[2]= (float) atof(val);
- } else if (id==60) {
- /* short invisible= atoi(val); */
- } else if (id==62) {
- int colorid= atoi(val);
-
- CLAMP(colorid, 1, 255);
- dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
- } else if (id==67) {
- vspace= atoi(val);
- } else if (id==70) {
- flag= atoi(val);
- } else if (id==90) {
- nverts= atoi(val);
- }
- }
- printf("nverts %d\n", nverts);
- if (nverts == 0)
- return;
-
- dxf_get_mesh(scene, &me, &ob, noob);
- strcpy(oldllay, layname);
- if(ob) VECCOPY(ob->loc, cent);
- dxf_add_mat (ob, me, color, layname);
-
- me->totvert += nverts;
- me->totface += nverts;
-
- me->mvert = (MVert*) MEM_callocN(me->totvert*sizeof(MVert), "mverts");
- me->mface = (MFace*) MEM_callocN(me->totface*sizeof(MVert), "mface");
-
- CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
- CustomData_set_layer(&me->fdata, CD_MFACE, me->mface);
-
- for (v = 0; v < nverts; v++) {
- read_group(id,val);
- if (id == 10) {
- vert[0]= (float) atof(val);
- } else {
- //XXX error("Error parsing dxf, expected (10, <x>) at line %d", dxf_line);
- }
-
- read_group(id,val);
- if (id == 20) {
- vert[1]= (float) atof(val);
- } else {
- //XXX error("Error parsing dxf, expected (20, <y>) at line %d", dxf_line);
- }
-
- mvert = &me->mvert[v];
-
- if (vspace) {
- VECCOPY(mvert->co, vert);
- } else {
- sub_v3_v3v3(mvert->co, vert, vcenter);
- }
-
- if (v > 0) {
- mface= &(((MFace*)me->mface)[v-1]);
- mface->v1 = v-1;
- mface->v2 = v;
- mface->mat_nr = 0;
- }
- }
-
- /* flag & 1 -> closed polyline
- * TODO: give the polyline actual 2D faces if it is closed */
-
- if (flag&1) {
- if(me->mface) {
- mface= &(((MFace*)me->mface)[nverts - 1]);
- mface->v1 = nverts-1;
- mface->v2 = 0;
- mface->mat_nr = 0;
- }
- }
-}
-
-
- /* 3D Face state vars */
-static Object *f3dhold=NULL;
-static Mesh *f3dmhold=NULL;
-static char oldflay[32];
-static short lwasf3d=0; /* last was face 3d? */
-
-/* how can this function do anything useful (ton)? */
-static void dxf_close_3dface(void)
-{
- f3dmhold= NULL;
- if (f3dhold==NULL) return;
-
- f3dhold=NULL;
-}
-
-static void dxf_read_3dface(Scene *scene, int noob)
-{
- /* Entity specific vars */
- float vert2[3]={0.0, 0.0, 0.0};
- float vert3[3]={0.0, 0.0, 0.0};
- float vert4[3]={0.0, 0.0, 0.0};
- short vspace=0;
-
- int nverts=0;
-
- /* Blender vars */
- Object *ob;
- Mesh *me;
- MVert *mvert, *vtmp;
- MFace *mface, *ftmp;
-
- reset_vars;
-
- read_group(id, val);
- while(id!=0) {
- if (id==8) {
- BLI_strncpy(layname, val, sizeof(layname));
-
- /* First vert/origin */
- } else if (id==10) {
- cent[0]= (float) atof(val);
- if (nverts<1)nverts++;
- } else if (id==20) {
- cent[1]= (float) atof(val);
- if (nverts<1)nverts++;
- } else if (id==30) {
- cent[2]= (float) atof(val);
- if (nverts<1)nverts++;
-
- /* Second vert */
- } else if (id==11) {
- vert2[0]= (float) atof(val);
- if (nverts<2)nverts++;
- } else if (id==21) {
- vert2[1]= (float) atof(val);
- if (nverts<2)nverts++;
- } else if (id==31) {
- vert2[2]= (float) atof(val);
- if (nverts<2)nverts++;
-
- /* Third vert */
- } else if (id==12) {
- vert3[0]= (float) atof(val);
- if (nverts<3)nverts++;
- } else if (id==22) {
- vert3[1]= (float) atof(val);
- if (nverts<3)nverts++;
- } else if (id==32) {
- vert3[2]= (float) atof(val);
- if (nverts<3)nverts++;
-
- /* Fourth vert */
- } else if (id==13) {
- vert4[0]= (float) atof(val);
- if (nverts<4)nverts++;
- } else if (id==23) {
- vert4[1]= (float) atof(val);
- if (nverts<4)nverts++;
- } else if (id==33) {
- vert4[2]= (float) atof(val);
- if (nverts<4)nverts++;
-
- /* Other */
- } else if (id==60) {
- /* short invisible= atoi(val); */
- } else if (id==62) {
- int colorid= atoi(val);
-
- CLAMP(colorid, 1, 255);
- dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
- } else if (id==67) {
- vspace= atoi(val);
- }
- read_group(id, val);
- }
-
- /* Check to see if we need to make a new object */
-
- if(!lwasf3d || strcmp(layname, oldflay)!=0) dxf_close_3dface();
- if(f3dmhold != NULL && f3dmhold->totvert>MESH_MAX_VERTS)
- dxf_close_3dface();
-
- if(nverts<3) {
- //XXX error("(3DF) Error parsing dxf, not enough vertices near line %d", dxf_line);
-
- error_exit=1;
- fclose(dxf_fp);
- return;
- }
-
- if (f3dmhold==NULL) {
- dxf_get_mesh(scene, &me, &ob, noob);
-
- strcpy(oldflay, layname);
-
- if(ob) VECCOPY(ob->loc, cent);
-
- dxf_add_mat (ob, me, color, layname);
-
- f3dhold= ob;
- f3dmhold= me;
- } else {
- ob= f3dhold;
- me= f3dmhold;
- }
-
- me->totvert+= nverts;
- me->totface++;
-
- vtmp= MEM_callocN(me->totvert*sizeof(MVert), "mverts");
- ftmp= MEM_callocN(me->totface*sizeof(MFace), "mface");
-
- if(me->mvert) {
- memcpy(vtmp, me->mvert, (me->totvert-nverts)*sizeof(MVert));
- MEM_freeN(me->mvert);
- }
- me->mvert= CustomData_set_layer(&me->vdata, CD_MVERT, vtmp);
- vtmp=NULL;
-
- if(me->mface) {
- memcpy(ftmp, me->mface, (me->totface-1)*sizeof(MFace));
- MEM_freeN(me->mface);
- }
- me->mface= CustomData_set_layer(&me->fdata, CD_MFACE, ftmp);
- ftmp=NULL;
-
- mvert= &me->mvert[(me->totvert-nverts)];
- sub_v3_v3v3(mvert->co, cent, vcenter);
-
- mvert++;
- if (vspace) { VECCOPY(mvert->co, vert2);
- } else sub_v3_v3v3(mvert->co, vert2, vcenter);
-
- mvert++;
- if (vspace) { VECCOPY(mvert->co, vert3);
- } else sub_v3_v3v3(mvert->co, vert3, vcenter);
-
- if (nverts==4) {
- mvert++;
- if (vspace) { VECCOPY(mvert->co, vert4);
- } else sub_v3_v3v3(mvert->co, vert4, vcenter);
- }
-
- mface= &(((MFace*)me->mface)[me->totface-1]);
- mface->v1= (me->totvert-nverts)+0;
- mface->v2= (me->totvert-nverts)+1;
- mface->v3= (me->totvert-nverts)+2;
-
- if (nverts==4)
- mface->v4= (me->totvert-nverts)+3;
-
- mface->mat_nr= 0;
-
- test_index_face(mface, NULL, 0, nverts);
-
- hasbumped=1;
-}
-
-static void dxf_read(Scene *scene, const char *filename)
-{
- Mesh *lastMe = G.main->mesh.last;
-
- /* clear ugly global variables, that can hang because on error the code
- below returns... tsk (ton) */
- dxf_line=0;
- dxf_close_3dface();
- dxf_close_2dpoly();
- dxf_close_line();
-
- dxf_fp= fopen(filename, "r");
- if (dxf_fp==NULL) return;
-
- while (1) {
- read_group(id, val);
- if (group_is(0, "EOF")) break;
-
- if (id==999) continue;
- id_check(0, "SECTION");
-
- read_group(id, val);
- if (group_is(2, "HEADER")) {
- } else if (group_is(2, "TABLES")) {
- } else if (group_is(2, "OBJECTS")) {
- } else if (group_is(2, "CLASSES")) {
- } else if (group_is(2, "BLOCKS")) {
- while(1) {
- read_group(id, val);
- if (group_is(0, "BLOCK")) {
- while(group_isnt(0, "ENDBLK")) {
- read_group(id, val);
-
- if(id==2) {
- BLI_strncpy(entname, val, sizeof(entname));
- } else if (id==3) {
- /* Now the object def should follow */
- if(strlen(entname)==0) {
- //XXX error("Error parsing dxf, no mesh name near %d", dxf_line);
- fclose(dxf_fp);
- return;
- }
-
- /* Now the object def should follow */
- while(group_isnt(0, "ENDBLK")) {
- read_group(id, val);
-
- if(group_is(0, "POLYLINE")) {
- dxf_read_polyline(scene, 1);
- if(error_exit) return;
- lwasf3d=0;
- lwasline=0;
-
- while(group_isnt(0, "SEQEND")) read_group(id, val);
-
- } else if(group_is(0, "LWPOLYLINE")) {
- dxf_read_lwpolyline(scene, 1);
- if(error_exit) return;
- lwasf3d=0;
- lwasline=0;
-
- while(group_isnt(0, "SEQEND")) read_group(id, val);
- } else if(group_is(0, "ATTRIB")) {
- while(group_isnt(0, "SEQEND")) read_group(id, val);
- lwasf3d=0;
- lwasp2d=0;
- lwasline=0;
- } else if(group_is(0, "POINT")) {
- dxf_read_point(scene, 1);
- if(error_exit) return;
- lwasf3d=0;
- lwasp2d=0;
- lwasline=0;
- } else if(group_is(0, "LINE")) {
- dxf_read_line(scene, 1);
- if(error_exit) return;
- lwasline=1;
- lwasp2d=0;
- lwasf3d=0;
- } else if(group_is(0, "3DFACE")) {
- dxf_read_3dface(scene, 1);
- if(error_exit) return;
- lwasf3d=1;
- lwasp2d=0;
- lwasline=0;
- } else if (group_is(0, "CIRCLE")) {
- dxf_read_arc(scene, 1);
- } else if (group_is(0, "ELLIPSE")) {
- dxf_read_ellipse(scene, 1);
- } else if (group_is(0, "ENDBLK")) {
- break;
- }
- }
- } else if (group_is(0, "ENDBLK")) {
- break;
- }
- }
- while(id!=0) read_group(id, val);
-
- } else if(group_is(0, "ENDSEC")) {
- break;
- }
- }
- } else if (group_is(2, "ENTITIES")) {
- while(group_isnt(0, "ENDSEC")) {
- char obname[32]="";
- char layname[32]="";
- float cent[3]={0.0, 0.0, 0.0};
- float obsize[3]={1.0, 1.0, 1.0};
- float obrot[3]={0.0, 0.0, 0.0};
-
- if(!hasbumped) read_group(id, val);
- hasbumped=0;
- if (group_is(0, "INSERT")) {
- Base *base;
- Object *ob;
- void *obdata;
-
- read_group(id, val);
-
- while(id!=0) {
- if(id==2) {
- BLI_strncpy(obname, val, sizeof(obname));
- } else if (id==8) {
- BLI_strncpy(layname, val, sizeof(layname));
- } else if (id==10) {
- cent[0]= (float) atof(val);
- } else if (id==20) {
- cent[1]= (float) atof(val);
- } else if (id==30) {
- cent[2]= (float) atof(val);
- } else if (id==41) {
- obsize[0]= (float) atof(val);
- } else if (id==42) {
- obsize[1]= (float) atof(val);
- } else if (id==43) {
- obsize[2]= (float) atof(val);
- } else if (id==50) {
- obrot[2]= (float) (atof(val)*M_PI/180.0);
- } else if (id==60) {
- /* short invisible= atoi(val); */
- }
-
- read_group(id, val);
-
- }
-
- if(strlen(obname)==0) {
- //XXX error("Error parsing dxf, no object name near %d", dxf_line);
- fclose(dxf_fp);
- return;
- }
-
- obdata= find_id("ME", obname);
-
- if (obdata) {
- ob= alloc_libblock(&G.main->object, ID_OB, obname);
-
- ob->type= OB_MESH;
-
- ob->dt= OB_TEXTURE;
-
- ob->trackflag= OB_POSY;
- ob->upflag= OB_POSZ;
-
- ob->ipoflag = OB_OFFS_OB+OB_OFFS_PARENT;
-
- ob->dupon= 1; ob->dupoff= 0;
- ob->dupsta= 1; ob->dupend= 100;
- ob->recalc= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; /* needed because of weird way of adding libdata directly */
-
- ob->data= obdata;
- ((ID*)ob->data)->us++;
-
- VECCOPY(ob->loc, cent);
- VECCOPY(ob->size, obsize);
- VECCOPY(ob->rot, obrot);
-
- ob->mat= MEM_callocN(sizeof(void *)*1, "ob->mat");
- ob->matbits= MEM_callocN(sizeof(char)*1, "ob->matbits");
- ob->totcol= (unsigned char) ((Mesh*)ob->data)->totcol;
- ob->actcol= 1;
-
- /* note: materials are either linked to mesh or object, if both then
- you have to increase user counts. below line is not needed.
- I leave it commented out here as warning (ton) */
- //for (i=0; i<ob->totcol; i++) ob->mat[i]= ((Mesh*)ob->data)->mat[i];
-
- if (layname[0]) ob->lay= dxf_get_layer_num(scene, layname);
- else ob->lay= scene->lay;
-
- /* link to scene */
- base= MEM_callocN( sizeof(Base), "add_base");
- BLI_addhead(&scene->base, base);
-
- base->lay= ob->lay;
-
- base->object= ob;
- }
-
- hasbumped=1;
-
- lwasf3d=0;
- lwasp2d=0;
- lwasline=0;
- } else if(group_is(0, "POLYLINE")) {
- dxf_read_polyline(scene, 0);
- if(error_exit) return;
- lwasf3d=0;
- lwasline=0;
-
- while(group_isnt(0, "SEQEND")) read_group(id, val);
-
- } else if(group_is(0, "LWPOLYLINE")) {
- dxf_read_lwpolyline(scene, 0);
- if(error_exit) return;
- lwasf3d=0;
- lwasline=0;
- //while(group_isnt(0, "SEQEND")) read_group(id, val);
-
- } else if(group_is(0, "ATTRIB")) {
- while(group_isnt(0, "SEQEND")) read_group(id, val);
- lwasf3d=0;
- lwasp2d=0;
- lwasline=0;
- } else if(group_is(0, "POINT")) {
- dxf_read_point(scene, 0);
- if(error_exit) return;
- lwasf3d=0;
- lwasp2d=0;
- lwasline=0;
- } else if(group_is(0, "LINE")) {
- dxf_read_line(scene, 0);
- if(error_exit) return;
- lwasline=1;
- lwasp2d=0;
- lwasf3d=0;
- } else if(group_is(0, "3DFACE")) {
- dxf_read_3dface(scene, 0);
- if(error_exit) return;
- lwasline=0;
- lwasp2d=0;
- lwasf3d=1;
- } else if (group_is(0, "CIRCLE") || group_is(0, "ARC")) {
- dxf_read_arc(scene, 0);
- } else if (group_is(0, "ELLIPSE")) {
- dxf_read_ellipse(scene, 0);
- } else if(group_is(0, "ENDSEC")) {
- break;
- }
- }
- }
-
- while(group_isnt(0, "ENDSEC")) read_group(id, val);
- }
- id_check(0, "EOF");
-
- fclose (dxf_fp);
-
- /* Close any remaining state held stuff */
- dxf_close_3dface();
- dxf_close_2dpoly();
- dxf_close_line();
-
- if (lastMe) {
- lastMe = lastMe->id.next;
- } else {
- lastMe = G.main->mesh.first;
- }
- for (; lastMe; lastMe=lastMe->id.next) {
- mesh_add_normals_flags(lastMe);
- make_edges(lastMe, 0);
- }
-}
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index f8003c656bf..1931946f0cf 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -67,69 +67,61 @@
static ListBase ttfdata= {NULL, NULL};
/* UTF-8 <-> wchar transformations */
-void
-chtoutf8(unsigned long c, char *o)
+size_t chtoutf8(const unsigned long c, char o[4])
{
// Variables and initialization
-/* memset(o, 0, 16); */
+/* memset(o, 0, 4); */
// Create the utf-8 string
- if (c < 0x80)
- {
+ if (c < 0x80) {
o[0] = (char) c;
+ return 1;
}
- else if (c < 0x800)
- {
+ else if (c < 0x800) {
o[0] = (0xC0 | (c>>6));
o[1] = (0x80 | (c & 0x3f));
+ return 2;
}
- else if (c < 0x10000)
- {
+ else if (c < 0x10000) {
o[0] = (0xe0 | (c >> 12));
o[1] = (0x80 | (c >>6 & 0x3f));
o[2] = (0x80 | (c & 0x3f));
+ return 3;
}
- else if (c < 0x200000)
- {
- o[0] = (0xf0 | (c>>18));
- o[1] = (0x80 | (c >>12 & 0x3f));
- o[2] = (0x80 | (c >> 6 & 0x3f));
- o[3] = (0x80 | (c & 0x3f));
+ else if (c < 0x200000) {
+ o[0] = (0xf0 | (c>>18));
+ o[1] = (0x80 | (c >>12 & 0x3f));
+ o[2] = (0x80 | (c >> 6 & 0x3f));
+ o[3] = (0x80 | (c & 0x3f));
+ return 4;
}
+
+ /* should we assert here? */
+ return 0;
}
-void
-wcs2utf8s(char *dst, wchar_t *src)
+void wcs2utf8s(char *dst, const wchar_t *src)
{
- /* NULL terminator not needed */
- char ch[4];
-
- while(*src)
- {
- memset(ch, 0, sizeof(ch));
- chtoutf8(*src++, ch);
- dst= strncat(dst, ch, sizeof(ch));
+ while(*src) {
+ dst += chtoutf8(*src++, dst);
}
+
+ *dst= '\0';
}
-int
-wcsleninu8(wchar_t *src)
+size_t wcsleninu8(wchar_t *src)
{
- char ch[16];
- int len = 0;
+ char ch_dummy[4];
+ size_t len = 0;
- while(*src)
- {
- memset(ch, 0, 16);
- chtoutf8(*src++, ch);
- len = len + strlen(ch);
+ while(*src) {
+ len += chtoutf8(*src++, ch_dummy);
}
return len;
}
-static int
-utf8slen(const char *strc)
+static size_t utf8slen(const char *strc)
{
int len=0;
@@ -172,7 +164,7 @@ only a single input character is consumed.
*/
-int utf8towchar(wchar_t *w, char *c)
+size_t utf8towchar(wchar_t *w, const char *c)
{
int len=0;
@@ -394,7 +386,7 @@ VFont *load_vfont(const char *name)
vfont->data = vfd;
/* if there's a font name, use it for the ID name */
- if (strcmp(vfd->name, "")!=0) {
+ if (vfd->name[0] != '\0') {
BLI_strncpy(vfont->id.name+2, vfd->name, sizeof(vfont->id.name)-2);
}
BLI_strncpy(vfont->name, name, sizeof(vfont->name));
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 67be3e71101..04fc41e41cc 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -78,9 +78,12 @@ IDProperty *IDP_NewIDPArray(const char *name)
IDProperty *IDP_CopyIDPArray(IDProperty *array)
{
- IDProperty *narray = MEM_dupallocN(array), *tmp;
+ /* dont use MEM_dupallocN because this may be part of an array */
+ IDProperty *narray = MEM_mallocN(sizeof(IDProperty), "IDP_CopyIDPArray"), *tmp;
int i;
-
+
+ *narray= *array;
+
narray->data.pointer = MEM_dupallocN(array->data.pointer);
for (i=0; i<narray->len; i++) {
/*ok, the copy functions always allocate a new structure,
@@ -423,35 +426,30 @@ static IDProperty *IDP_CopyGroup(IDProperty *prop)
* When values name and types match, copy the values, else ignore */
void IDP_SyncGroupValues(IDProperty *dest, IDProperty *src)
{
- IDProperty *loop, *prop;
+ IDProperty *other, *prop;
for (prop=src->data.group.first; prop; prop=prop->next) {
- for (loop=dest->data.group.first; loop; loop=loop->next) {
- if (strcmp(loop->name, prop->name)==0) {
- if(prop->type==loop->type) {
-
- switch (prop->type) {
- case IDP_INT:
- case IDP_FLOAT:
- case IDP_DOUBLE:
- loop->data= prop->data;
- break;
- case IDP_GROUP:
- IDP_SyncGroupValues(loop, prop);
- break;
- default:
- {
- IDProperty *tmp= loop;
- IDProperty *copy= IDP_CopyProperty(prop);
-
- BLI_insertlinkafter(&dest->data.group, loop, copy);
- BLI_remlink(&dest->data.group, tmp);
-
- IDP_FreeProperty(tmp);
- MEM_freeN(tmp);
- }
- }
+ other= BLI_findstring(&dest->data.group, prop->name, offsetof(IDProperty, name));
+ if (other && prop->type==other->type) {
+ switch (prop->type) {
+ case IDP_INT:
+ case IDP_FLOAT:
+ case IDP_DOUBLE:
+ other->data= prop->data;
+ break;
+ case IDP_GROUP:
+ IDP_SyncGroupValues(other, prop);
+ break;
+ default:
+ {
+ IDProperty *tmp= other;
+ IDProperty *copy= IDP_CopyProperty(prop);
+
+ BLI_insertlinkafter(&dest->data.group, other, copy);
+ BLI_remlink(&dest->data.group, tmp);
+
+ IDP_FreeProperty(tmp);
+ MEM_freeN(tmp);
}
- break;
}
}
}
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index c44634fed34..22d19c5484f 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -675,8 +675,10 @@ void BKE_image_all_free_anim_ibufs(int cfra)
int BKE_imtype_to_ftype(int imtype)
{
- if(imtype==0)
+ if(imtype==R_TARGA)
return TGA;
+ else if(imtype==R_RAWTGA)
+ return RAWTGA;
else if(imtype== R_IRIS)
return IMAGIC;
#ifdef WITH_HDR
@@ -703,10 +705,6 @@ int BKE_imtype_to_ftype(int imtype)
else if (imtype==R_DPX)
return DPX;
#endif
- else if (imtype==R_TARGA)
- return TGA;
- else if(imtype==R_RAWTGA)
- return RAWTGA;
#ifdef WITH_OPENJPEG
else if(imtype==R_JP2)
return JP2;
@@ -880,7 +878,7 @@ typedef struct StampData {
char rendertime[64];
} StampData;
-static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix)
+static void stampdata(Scene *scene, Object *camera, StampData *stamp_data, int do_prefix)
{
char text[256];
struct tm *tl;
@@ -959,14 +957,14 @@ static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix)
}
if (scene->r.stamp & R_STAMP_CAMERA) {
- BLI_snprintf(stamp_data->camera, sizeof(stamp_data->camera), do_prefix ? "Camera %s":"%s", scene->camera ? scene->camera->id.name+2 : "<none>");
+ BLI_snprintf(stamp_data->camera, sizeof(stamp_data->camera), do_prefix ? "Camera %s":"%s", camera ? camera->id.name+2 : "<none>");
} else {
stamp_data->camera[0] = '\0';
}
if (scene->r.stamp & R_STAMP_CAMERALENS) {
- if (scene->camera && scene->camera->type == OB_CAMERA) {
- BLI_snprintf(text, sizeof(text), "%.2f", ((Camera *)scene->camera->data)->lens);
+ if (camera && camera->type == OB_CAMERA) {
+ BLI_snprintf(text, sizeof(text), "%.2f", ((Camera *)camera->data)->lens);
}
else strcpy(text, "<none>");
@@ -1006,18 +1004,21 @@ static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix)
}
}
-void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, int height, int channels)
+void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rectf, int width, int height, int channels)
{
struct StampData stamp_data;
float w, h, pad;
- int x, y;
+ int x, y, y_ofs;
float h_fixed;
const int mono= blf_mono_font_render; // XXX
-
+
+#define BUFF_MARGIN_X 2
+#define BUFF_MARGIN_Y 1
+
if (!rect && !rectf)
return;
- stampdata(scene, &stamp_data, 1);
+ stampdata(scene, camera, &stamp_data, 1);
/* TODO, do_versions */
if(scene->r.stamp_font_id < 8)
@@ -1028,15 +1029,11 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i
BLF_buffer(mono, rectf, rect, width, height, channels);
BLF_buffer_col(mono, scene->r.fg_stamp[0], scene->r.fg_stamp[1], scene->r.fg_stamp[2], 1.0);
- pad= BLF_width(mono, "--");
+ pad= BLF_width_max(mono);
/* use 'h_fixed' rather then 'h', aligns better */
- // BLF_width_and_height(mono, "^|/_AgPpJjlYy", &w, &h_fixed);
- {
- rctf box;
- BLF_boundbox(mono, "^|/_AgPpJjlYy", &box);
- h_fixed= box.ymax - box.ymin;
- }
+ h_fixed= BLF_height_max(mono);
+ y_ofs = -BLF_descender(mono);
x= 0;
y= height;
@@ -1047,14 +1044,14 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i
y -= h;
/* also a little of space to the background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y-3, w+3, y+h+2);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-BUFF_MARGIN_X, y-BUFF_MARGIN_Y, w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y);
/* and draw the text. */
- BLF_position(mono, x, y, 0.0);
+ BLF_position(mono, x, y + y_ofs, 0.0);
BLF_draw_buffer(mono, stamp_data.file);
/* the extra pixel for background. */
- y -= 4;
+ y -= BUFF_MARGIN_Y * 2;
}
/* Top left corner, below File */
@@ -1063,13 +1060,13 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i
y -= h;
/* and space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-3, w+3, y+h+2);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-BUFF_MARGIN_Y, w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y);
- BLF_position(mono, x, y+1, 0.0);
+ BLF_position(mono, x, y + y_ofs, 0.0);
BLF_draw_buffer(mono, stamp_data.note);
/* the extra pixel for background. */
- y -= 4;
+ y -= BUFF_MARGIN_Y * 2;
}
/* Top left corner, below File (or Note) */
@@ -1078,13 +1075,13 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i
y -= h;
/* and space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-3, w+3, y+h+2);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-BUFF_MARGIN_Y, w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y);
- BLF_position(mono, x, y, 0.0);
+ BLF_position(mono, x, y + y_ofs, 0.0);
BLF_draw_buffer(mono, stamp_data.date);
/* the extra pixel for background. */
- y -= 4;
+ y -= BUFF_MARGIN_Y * 2;
}
/* Top left corner, below File, Date or Note */
@@ -1093,9 +1090,9 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i
y -= h;
/* and space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-3, w+3, y+h+2);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-BUFF_MARGIN_Y, w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y);
- BLF_position(mono, x, y, 0.0);
+ BLF_position(mono, x, y + y_ofs, 0.0);
BLF_draw_buffer(mono, stamp_data.rendertime);
}
@@ -1107,10 +1104,10 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i
BLF_width_and_height(mono, stamp_data.marker, &w, &h); h= h_fixed;
/* extra space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, w+2, y+h+2);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-BUFF_MARGIN_X, y-BUFF_MARGIN_Y, w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y);
/* and pad the text. */
- BLF_position(mono, x, y+3, 0.0);
+ BLF_position(mono, x, y + y_ofs, 0.0);
BLF_draw_buffer(mono, stamp_data.marker);
/* space width. */
@@ -1122,10 +1119,10 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i
BLF_width_and_height(mono, stamp_data.time, &w, &h); h= h_fixed;
/* extra space for background */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+2, y+h+2);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-BUFF_MARGIN_X, y, x+w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y);
/* and pad the text. */
- BLF_position(mono, x, y+3, 0.0);
+ BLF_position(mono, x, y + y_ofs, 0.0);
BLF_draw_buffer(mono, stamp_data.time);
/* space width. */
@@ -1136,10 +1133,10 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i
BLF_width_and_height(mono, stamp_data.frame, &w, &h); h= h_fixed;
/* extra space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+2, y+h+2);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-BUFF_MARGIN_X, y-BUFF_MARGIN_Y, x+w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y);
/* and pad the text. */
- BLF_position(mono, x, y+3, 0.0);
+ BLF_position(mono, x, y + y_ofs, 0.0);
BLF_draw_buffer(mono, stamp_data.frame);
/* space width. */
@@ -1150,8 +1147,8 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i
BLF_width_and_height(mono, stamp_data.camera, &w, &h); h= h_fixed;
/* extra space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+2, y+h+2);
- BLF_position(mono, x, y+3, 0.0);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-BUFF_MARGIN_X, y-BUFF_MARGIN_Y, x+w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y);
+ BLF_position(mono, x, y + y_ofs, 0.0);
BLF_draw_buffer(mono, stamp_data.camera);
/* space width. */
@@ -1162,8 +1159,8 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i
BLF_width_and_height(mono, stamp_data.cameralens, &w, &h); h= h_fixed;
/* extra space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+2, y+h+2);
- BLF_position(mono, x, y+3, 0.0);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-BUFF_MARGIN_X, y-BUFF_MARGIN_Y, x+w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y);
+ BLF_position(mono, x, y + y_ofs, 0.0);
BLF_draw_buffer(mono, stamp_data.cameralens);
}
@@ -1174,10 +1171,10 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i
x= width - w - 2;
/* extra space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+3, y+h+2);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-BUFF_MARGIN_X, y-BUFF_MARGIN_Y, x+w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y);
/* and pad the text. */
- BLF_position(mono, x, y+3, 0.0);
+ BLF_position(mono, x, y+y_ofs, 0.0);
BLF_draw_buffer(mono, stamp_data.scene);
}
@@ -1189,24 +1186,27 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i
y= height - h;
/* extra space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y-3, x+w+pad, y+h+2);
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-BUFF_MARGIN_X, y-BUFF_MARGIN_Y, x+w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y);
- BLF_position(mono, x, y, 0.0);
+ BLF_position(mono, x, y + y_ofs, 0.0);
BLF_draw_buffer(mono, stamp_data.strip);
}
/* cleanup the buffer. */
BLF_buffer(mono, NULL, NULL, 0, 0, 0);
+
+#undef BUFF_MARGIN_X
+#undef BUFF_MARGIN_Y
}
-void BKE_stamp_info(Scene *scene, struct ImBuf *ibuf)
+void BKE_stamp_info(Scene *scene, Object *camera, struct ImBuf *ibuf)
{
struct StampData stamp_data;
if (!ibuf) return;
/* fill all the data values, no prefix */
- stampdata(scene, &stamp_data, 0);
+ stampdata(scene, camera, &stamp_data, 0);
if (stamp_data.file[0]) IMB_metadata_change_field (ibuf, "File", stamp_data.file);
if (stamp_data.note[0]) IMB_metadata_change_field (ibuf, "Note", stamp_data.note);
@@ -1244,7 +1244,7 @@ int BKE_alphatest_ibuf(ImBuf *ibuf)
return FALSE;
}
-int BKE_write_ibuf(Scene *scene, ImBuf *ibuf, const char *name, int imtype, int subimtype, int quality)
+int BKE_write_ibuf(ImBuf *ibuf, const char *name, int imtype, int subimtype, int quality)
{
int ok;
(void)subimtype; /* quies unused warnings */
@@ -1339,9 +1339,6 @@ int BKE_write_ibuf(Scene *scene, ImBuf *ibuf, const char *name, int imtype, int
}
BLI_make_existing_file(name);
-
- if(scene && scene->r.stamp & R_STAMP_ALL)
- BKE_stamp_info(scene, ibuf);
ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
if (ok == 0) {
@@ -1351,6 +1348,14 @@ int BKE_write_ibuf(Scene *scene, ImBuf *ibuf, const char *name, int imtype, int
return(ok);
}
+int BKE_write_ibuf_stamp(Scene *scene, struct Object *camera, ImBuf *ibuf, const char *name, int imtype, int subimtype, int quality)
+{
+ if(scene && scene->r.stamp & R_STAMP_ALL)
+ BKE_stamp_info(scene, camera, ibuf);
+
+ return BKE_write_ibuf(ibuf, name, imtype, subimtype, quality);
+}
+
void BKE_makepicstring(char *string, const char *base, int frame, int imtype, const short use_ext, const short use_frames)
{
@@ -1660,8 +1665,15 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
/* read ibuf */
ibuf = IMB_loadiffname(name, flag);
- if(G.f & G_DEBUG) printf("loaded %s\n", name);
-
+
+#if 0
+ if(ibuf) {
+ printf(AT" loaded %s\n", name);
+ } else {
+ printf(AT" missed %s\n", name);
+ }
+#endif
+
if (ibuf) {
#ifdef WITH_OPENEXR
/* handle multilayer case, don't assign ibuf. will be handled in BKE_image_get_ibuf */
@@ -2217,21 +2229,19 @@ void BKE_image_release_ibuf(Image *ima, void *lock)
/* warning, this can allocate generated images */
ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
{
+ /* here (+fie_ima/2-1) makes sure that division happens correctly */
return BKE_image_acquire_ibuf(ima, iuser, NULL);
}
-void BKE_image_user_calc_frame(ImageUser *iuser, int cfra, int fieldnr)
+int BKE_image_user_get_frame(const ImageUser *iuser, int cfra, int fieldnr)
{
- int len;
-
- /* here (+fie_ima/2-1) makes sure that division happens correctly */
- len= (iuser->fie_ima*iuser->frames)/2;
-
+ const int len= (iuser->fie_ima*iuser->frames)/2;
+
if(len==0) {
- iuser->framenr= 0;
+ return 0;
}
else {
- int imanr;
+ int framenr;
cfra= cfra - iuser->sfra+1;
/* cyclic */
@@ -2240,31 +2250,38 @@ void BKE_image_user_calc_frame(ImageUser *iuser, int cfra, int fieldnr)
if(cfra < 0) cfra+= len;
if(cfra==0) cfra= len;
}
-
+
if(cfra<0) cfra= 0;
else if(cfra>len) cfra= len;
-
+
/* convert current frame to current field */
cfra= 2*(cfra);
if(fieldnr) cfra++;
-
+
/* transform to images space */
- imanr= (cfra+iuser->fie_ima-2)/iuser->fie_ima;
- if(imanr>iuser->frames) imanr= iuser->frames;
- imanr+= iuser->offset;
-
+ framenr= (cfra+iuser->fie_ima-2)/iuser->fie_ima;
+ if(framenr>iuser->frames) framenr= iuser->frames;
+ framenr+= iuser->offset;
+
if(iuser->cycl) {
- imanr= ( (imanr) % len );
- while(imanr < 0) imanr+= len;
- if(imanr==0) imanr= len;
+ framenr= ( (framenr) % len );
+ while(framenr < 0) framenr+= len;
+ if(framenr==0) framenr= len;
}
-
- /* allows image users to handle redraws */
- if(iuser->flag & IMA_ANIM_ALWAYS)
- if(imanr!=iuser->framenr)
- iuser->flag |= IMA_ANIM_REFRESHED;
-
- iuser->framenr= imanr;
- if(iuser->ok==0) iuser->ok= 1;
+
+ return framenr;
}
}
+
+void BKE_image_user_calc_frame(ImageUser *iuser, int cfra, int fieldnr)
+{
+ const int framenr= BKE_image_user_get_frame(iuser, cfra, fieldnr);
+
+ /* allows image users to handle redraws */
+ if(iuser->flag & IMA_ANIM_ALWAYS)
+ if(framenr!=iuser->framenr)
+ iuser->flag |= IMA_ANIM_REFRESHED;
+
+ iuser->framenr= framenr;
+ if(iuser->ok==0) iuser->ok= 1;
+}
diff --git a/source/blender/blenkernel/intern/image_gen.c b/source/blender/blenkernel/intern/image_gen.c
index 8f6408f1939..5b237665290 100644
--- a/source/blender/blenkernel/intern/image_gen.c
+++ b/source/blender/blenkernel/intern/image_gen.c
@@ -80,10 +80,10 @@ void BKE_image_buf_fill_checker(unsigned char *rect, float *rect_float, int widt
int checkerwidth= 32, dark= 1;
int x, y;
-
+
unsigned char *rect_orig= rect;
float *rect_float_orig= rect_float;
-
+
float h=0.0, hoffs=0.0, hue=0.0, s=0.9, v=0.9, r, g, b;
@@ -191,7 +191,7 @@ static void checker_board_color_fill(unsigned char *rect, float *rect_float, int
for(y= 0; y < height; y++)
{
-
+
val= 0.1 + (y * (0.4 / height)); /* use a number lower then 1.0 else its too bright */
for(x= 0; x < width; x++)
{
@@ -316,17 +316,17 @@ static void checker_board_text(unsigned char *rect, float *rect_float, int width
BLF_size(mono, 54, 72); /* hard coded size! */
BLF_buffer(mono, rect_float, rect, width, height, 4);
-
+
for(y= 0; y < height; y+=step)
{
text[1]= '1';
-
+
for(x= 0; x < width; x+=step)
{
/* hard coded offset */
pen_x = x + 33;
pen_y = y + 44;
-
+
/* terribly crappy outline font! */
BLF_buffer_col(mono, 1.0, 1.0, 1.0, 1.0);
@@ -338,7 +338,7 @@ static void checker_board_text(unsigned char *rect, float *rect_float, int width
BLF_draw_buffer(mono, text);
BLF_position(mono, pen_x, pen_y+outline, 0.0);
BLF_draw_buffer(mono, text);
-
+
BLF_position(mono, pen_x-outline, pen_y-outline, 0.0);
BLF_draw_buffer(mono, text);
BLF_position(mono, pen_x+outline, pen_y+outline, 0.0);
@@ -351,12 +351,12 @@ static void checker_board_text(unsigned char *rect, float *rect_float, int width
BLF_buffer_col(mono, 0.0, 0.0, 0.0, 1.0);
BLF_position(mono, pen_x, pen_y, 0.0);
BLF_draw_buffer(mono, text);
-
+
text[1]++;
}
text[0]++;
}
-
+
/* cleanup the buffer. */
BLF_buffer(mono, NULL, NULL, 0, 0, 0);
}
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index 7f0292b2f22..099661f7914 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -50,7 +50,7 @@
#include "BKE_global.h"
-#define CLOTH_OPENMP_LIMIT 25
+#define CLOTH_OPENMP_LIMIT 512
#ifdef _WIN32
#include <windows.h>
@@ -939,7 +939,7 @@ static int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z
s = dot_lfvector(r, r, numverts);
starget = s * sqrt(conjgrad_epsilon);
- while((s>starget && conjgrad_loopcount < conjgrad_looplimit))
+ while(s>starget && conjgrad_loopcount < conjgrad_looplimit)
{
// Mul(q,A,d); // q = A*d;
mul_bfmatrix_lfvector(q, lA, d);
@@ -1749,15 +1749,93 @@ static void simulate_implicit_euler(lfVector *Vnew, lfVector *UNUSED(lX), lfVect
del_lfvector(dFdXmV);
}
+/*computes where the cloth would be if it were subject to perfectly stiff edges
+ (edge distance constraints) in a lagrangian solver. then add forces to help
+ guide the implicit solver to that state. this function is called after
+ collisions*/
+int cloth_calc_helper_forces(Object *UNUSED(ob), ClothModifierData * clmd, float (*initial_cos)[3], float UNUSED(step), float dt)
+{
+ Cloth *cloth= clmd->clothObject;
+ float (*cos)[3] = MEM_callocN(sizeof(float)*3*cloth->numverts, "cos cloth_calc_helper_forces");
+ float *masses = MEM_callocN(sizeof(float)*cloth->numverts, "cos cloth_calc_helper_forces");
+ LinkNode *node;
+ ClothSpring *spring;
+ ClothVertex *cv;
+ int i, steps;
+
+ cv = cloth->verts;
+ for (i=0; i<cloth->numverts; i++, cv++) {
+ copy_v3_v3(cos[i], cv->tx);
+
+ if (cv->goal == 1.0f || len_v3v3(initial_cos[i], cv->tx) != 0.0) {
+ masses[i] = 1e+10;
+ } else {
+ masses[i] = cv->mass;
+ }
+ }
+
+ steps = 55;
+ for (i=0; i<steps; i++) {
+ for (node=cloth->springs; node; node=node->next) {
+ ClothVertex *cv1, *cv2;
+ int v1, v2;
+ float len, c, l, vec[3];
+
+ spring = node->link;
+ if (spring->type != CLOTH_SPRING_TYPE_STRUCTURAL && spring->type != CLOTH_SPRING_TYPE_SHEAR)
+ continue;
+
+ v1 = spring->ij; v2 = spring->kl;
+ cv1 = cloth->verts + v1;
+ cv2 = cloth->verts + v2;
+ len = len_v3v3(cos[v1], cos[v2]);
+
+ sub_v3_v3v3(vec, cos[v1], cos[v2]);
+ normalize_v3(vec);
+
+ c = (len - spring->restlen);
+ if (c == 0.0)
+ continue;
+
+ l = c / ((1.0/masses[v1]) + (1.0/masses[v2]));
+
+ mul_v3_fl(vec, -(1.0/masses[v1])*l);
+ add_v3_v3(cos[v1], vec);
+
+ sub_v3_v3v3(vec, cos[v2], cos[v1]);
+ normalize_v3(vec);
+
+ mul_v3_fl(vec, -(1.0/masses[v2])*l);
+ add_v3_v3(cos[v2], vec);
+ }
+ }
+
+ cv = cloth->verts;
+ for (i=0; i<cloth->numverts; i++, cv++) {
+ float vec[3];
+
+ /*compute forces*/
+ sub_v3_v3v3(vec, cos[i], cv->tx);
+ mul_v3_fl(vec, cv->mass*dt*20.0);
+ add_v3_v3(cv->tv, vec);
+ //copy_v3_v3(cv->tx, cos[i]);
+ }
+
+ MEM_freeN(cos);
+ MEM_freeN(masses);
+
+ return 1;
+}
int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors)
{
unsigned int i=0;
float step=0.0f, tf=clmd->sim_parms->timescale;
Cloth *cloth = clmd->clothObject;
- ClothVertex *verts = cloth->verts;
+ ClothVertex *verts = cloth->verts, *cv;
unsigned int numverts = cloth->numverts;
float dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame;
float spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
+ float (*initial_cos)[3] = MEM_callocN(sizeof(float)*3*cloth->numverts, "initial_cos implicit.c");
Implicit_Data *id = cloth->implicit;
int do_extra_solve;
@@ -1817,15 +1895,26 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
VECCOPY(verts[i].v, verts[i].tv);
}
+ for (i=0, cv=cloth->verts; i<cloth->numverts; i++, cv++) {
+ copy_v3_v3(initial_cos[i], cv->tx);
+ }
+
// call collision function
// TODO: check if "step" or "step+dt" is correct - dg
do_extra_solve = cloth_bvh_objcollision(ob, clmd, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);
-
+
// copy corrected positions back to simulation
for(i = 0; i < numverts; i++)
{
// correct velocity again, just to be sure we had to change it due to adaptive collisions
VECSUB(verts[i].tv, verts[i].tx, id->X[i]);
+ }
+
+ //if (do_extra_solve)
+ // cloth_calc_helper_forces(ob, clmd, initial_cos, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);
+
+ for(i = 0; i < numverts; i++)
+ {
if(do_extra_solve)
{
@@ -1886,6 +1975,8 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
}
}
+ MEM_freeN(initial_cos);
+
return 1;
}
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 08e0ad4f3ff..4f921f005f4 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -1372,7 +1372,7 @@ static void icu_to_fcurves (ID *id, ListBase *groups, ListBase *list, IpoCurve *
* This does not assume that any ID or AnimData uses it, but does assume that
* it is given two lists, which it will perform driver/animation-data separation.
*/
-static void ipo_to_animato (ID *id, Ipo *ipo, char actname[], char constname[], Sequence * seq, ListBase *animgroups, ListBase *anim, ListBase *drivers)
+static void ipo_to_animato (ID *id, Ipo *ipo, char actname[], char constname[], Sequence *seq, ListBase *animgroups, ListBase *anim, ListBase *drivers)
{
IpoCurve *icu;
@@ -1416,8 +1416,7 @@ static void ipo_to_animato (ID *id, Ipo *ipo, char actname[], char constname[],
/* if this IPO block doesn't have any users after this one, free... */
ipo->id.us--;
- if ( (ipo->id.us == 0) || ((ipo->id.us == 1) && (ipo->id.flag & LIB_FAKEUSER)) )
- {
+ if (ID_REAL_USERS(ipo) <= 0) {
IpoCurve *icn;
for (icu= ipo->curve.first; icu; icu= icn) {
@@ -1668,7 +1667,6 @@ void do_versions_ipos_to_animato(Main *main)
{
ListBase drivers = {NULL, NULL};
ID *id;
- AnimData *adt;
if (main == NULL) {
printf("Argh! Main is NULL in do_versions_ipos_to_animato() \n");
@@ -1697,7 +1695,7 @@ void do_versions_ipos_to_animato(Main *main)
/* check if object has any animation data */
if (ob->nlastrips.first) {
/* Add AnimData block */
- adt= BKE_id_add_animdata(id);
+ BKE_id_add_animdata(id);
/* IPO first to take into any non-NLA'd Object Animation */
if (ob->ipo) {
@@ -1720,7 +1718,7 @@ void do_versions_ipos_to_animato(Main *main)
}
else if ((ob->ipo) || (ob->action)) {
/* Add AnimData block */
- adt= BKE_id_add_animdata(id);
+ AnimData *adt= BKE_id_add_animdata(id);
/* Action first - so that Action name get conserved */
if (ob->action) {
@@ -1804,6 +1802,13 @@ void do_versions_ipos_to_animato(Main *main)
BLI_freelinkN(&ob->constraintChannels, conchan);
}
}
+
+ /* object's action will always be object-rooted */
+ {
+ AnimData *adt= BKE_animdata_from_id(id);
+ if (adt && adt->action)
+ adt->action->idroot = ID_OB;
+ }
}
/* shapekeys */
@@ -1818,10 +1823,14 @@ void do_versions_ipos_to_animato(Main *main)
*/
if (key->ipo) {
/* Add AnimData block */
- adt= BKE_id_add_animdata(id);
+ AnimData *adt= BKE_id_add_animdata(id);
/* Convert Shapekey data... */
ipo_to_animdata(id, key->ipo, NULL, NULL, NULL);
+
+ if (adt->action)
+ adt->action->idroot = key->ipo->blocktype;
+
key->ipo->id.us--;
key->ipo= NULL;
}
@@ -1836,10 +1845,14 @@ void do_versions_ipos_to_animato(Main *main)
/* we're only interested in the IPO */
if (ma->ipo) {
/* Add AnimData block */
- adt= BKE_id_add_animdata(id);
+ AnimData *adt= BKE_id_add_animdata(id);
/* Convert Material data... */
ipo_to_animdata(id, ma->ipo, NULL, NULL, NULL);
+
+ if (adt->action)
+ adt->action->idroot = ma->ipo->blocktype;
+
ma->ipo->id.us--;
ma->ipo= NULL;
}
@@ -1854,10 +1867,14 @@ void do_versions_ipos_to_animato(Main *main)
/* we're only interested in the IPO */
if (wo->ipo) {
/* Add AnimData block */
- adt= BKE_id_add_animdata(id);
+ AnimData *adt= BKE_id_add_animdata(id);
/* Convert World data... */
ipo_to_animdata(id, wo->ipo, NULL, NULL, NULL);
+
+ if (adt->action)
+ adt->action->idroot = wo->ipo->blocktype;
+
wo->ipo->id.us--;
wo->ipo= NULL;
}
@@ -1870,7 +1887,7 @@ void do_versions_ipos_to_animato(Main *main)
if (ed && ed->seqbasep) {
Sequence * seq;
- adt= BKE_id_add_animdata(id);
+ AnimData *adt= BKE_id_add_animdata(id);
SEQ_BEGIN(ed, seq) {
IpoCurve *icu = (seq->ipo) ? seq->ipo->curve.first : NULL;
@@ -1904,6 +1921,10 @@ void do_versions_ipos_to_animato(Main *main)
/* convert IPO */
ipo_to_animdata((ID *)scene, seq->ipo, NULL, NULL, seq);
+
+ if (adt->action)
+ adt->action->idroot = ID_SCE; /* scene-rooted */
+
seq->ipo->id.us--;
seq->ipo = NULL;
}
@@ -1921,10 +1942,14 @@ void do_versions_ipos_to_animato(Main *main)
/* we're only interested in the IPO */
if (te->ipo) {
/* Add AnimData block */
- adt= BKE_id_add_animdata(id);
+ AnimData *adt= BKE_id_add_animdata(id);
/* Convert Texture data... */
ipo_to_animdata(id, te->ipo, NULL, NULL, NULL);
+
+ if (adt->action)
+ adt->action->idroot = te->ipo->blocktype;
+
te->ipo->id.us--;
te->ipo= NULL;
}
@@ -1939,10 +1964,14 @@ void do_versions_ipos_to_animato(Main *main)
/* we're only interested in the IPO */
if (ca->ipo) {
/* Add AnimData block */
- adt= BKE_id_add_animdata(id);
+ AnimData *adt= BKE_id_add_animdata(id);
/* Convert Camera data... */
ipo_to_animdata(id, ca->ipo, NULL, NULL, NULL);
+
+ if (adt->action)
+ adt->action->idroot = ca->ipo->blocktype;
+
ca->ipo->id.us--;
ca->ipo= NULL;
}
@@ -1957,10 +1986,14 @@ void do_versions_ipos_to_animato(Main *main)
/* we're only interested in the IPO */
if (la->ipo) {
/* Add AnimData block */
- adt= BKE_id_add_animdata(id);
+ AnimData *adt= BKE_id_add_animdata(id);
/* Convert Lamp data... */
ipo_to_animdata(id, la->ipo, NULL, NULL, NULL);
+
+ if (adt->action)
+ adt->action->idroot = la->ipo->blocktype;
+
la->ipo->id.us--;
la->ipo= NULL;
}
@@ -1975,10 +2008,14 @@ void do_versions_ipos_to_animato(Main *main)
/* we're only interested in the IPO */
if (cu->ipo) {
/* Add AnimData block */
- adt= BKE_id_add_animdata(id);
+ AnimData *adt= BKE_id_add_animdata(id);
/* Convert Curve data... */
ipo_to_animdata(id, cu->ipo, NULL, NULL, NULL);
+
+ if (adt->action)
+ adt->action->idroot = cu->ipo->blocktype;
+
cu->ipo->id.us--;
cu->ipo= NULL;
}
@@ -2001,6 +2038,10 @@ void do_versions_ipos_to_animato(Main *main)
if (G.f & G_DEBUG) printf("\tconverting action %s \n", id->name+2);
+ /* if old action, it will be object-only... */
+ if (act->chanbase.first)
+ act->idroot = ID_OB;
+
/* be careful! some of the actions we encounter will be converted ones... */
action_to_animato(NULL, act, &act->groups, &act->curves, &drivers);
}
@@ -2018,6 +2059,7 @@ void do_versions_ipos_to_animato(Main *main)
/* add a new action for this, and convert all data into that action */
new_act= add_empty_action("ConvIPO_Action"); // XXX need a better name...
ipo_to_animato(NULL, ipo, NULL, NULL, NULL, NULL, &new_act->curves, &drivers);
+ new_act->idroot = ipo->blocktype;
}
/* clear fake-users, and set user-count to zero to make sure it is cleared on file-save */
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index a32ae68efdd..fece1b8fb02 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -220,7 +220,9 @@ Lattice *copy_lattice(Lattice *lt)
ltn->dvert = MEM_mallocN (sizeof (MDeformVert)*tot, "Lattice MDeformVert");
copy_dverts(ltn->dvert, lt->dvert, tot);
}
-
+
+ ltn->editlatt= NULL;
+
return ltn;
}
@@ -248,8 +250,8 @@ void free_lattice(Lattice *lt)
void make_local_lattice(Lattice *lt)
{
+ Main *bmain= G.main;
Object *ob;
- Lattice *ltn;
int local=0, lib=0;
/* - only lib users: do nothing
@@ -261,39 +263,34 @@ void make_local_lattice(Lattice *lt)
if(lt->id.us==1) {
lt->id.lib= NULL;
lt->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)lt, NULL);
+ new_id(&bmain->latt, (ID *)lt, NULL);
return;
}
- ob= G.main->object.first;
- while(ob) {
+ for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) {
if(ob->data==lt) {
if(ob->id.lib) lib= 1;
else local= 1;
}
- ob= ob->id.next;
}
if(local && lib==0) {
lt->id.lib= NULL;
lt->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)lt, NULL);
+ new_id(&bmain->latt, (ID *)lt, NULL);
}
else if(local && lib) {
- ltn= copy_lattice(lt);
+ Lattice *ltn= copy_lattice(lt);
ltn->id.us= 0;
-
- ob= G.main->object.first;
- while(ob) {
+
+ for(ob= bmain->object.first; ob; ob= ob->id.next) {
if(ob->data==lt) {
-
if(ob->id.lib==NULL) {
ob->data= ltn;
ltn->id.us++;
lt->id.us--;
}
}
- ob= ob->id.next;
}
}
}
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index e3b0a342b3a..ad853915470 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -1157,7 +1157,7 @@ static int check_for_dupid(ListBase *lb, ID *id, char *name)
int new_id(ListBase *lb, ID *id, const char *tname)
{
int result;
- char name[22];
+ char name[MAX_ID_NAME-2];
/* if library, don't rename */
if(id->lib) return 0;
@@ -1381,7 +1381,7 @@ void text_idbutton(struct ID *id, char *text)
if(id) {
if(GS(id->name)==ID_SCE)
strcpy(text, "SCE: ");
- else if(GS(id->name)==ID_SCE)
+ else if(GS(id->name)==ID_SCR)
strcpy(text, "SCR: ");
else if(GS(id->name)==ID_MA && ((Material*)id)->use_nodes)
strcpy(text, "NT: ");
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index fa7709e3b33..fd58dc2dfc0 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -267,6 +267,14 @@ Material *localize_material(Material *ma)
return man;
}
+static void extern_local_material(Material *ma)
+{
+ int i;
+ for(i=0; i < MAX_MTEX; i++) {
+ if(ma->mtex[i]) id_lib_extern((ID *)ma->mtex[i]->tex);
+ }
+}
+
void make_local_material(Material *ma)
{
Main *bmain= G.main;
@@ -286,11 +294,9 @@ void make_local_material(Material *ma)
if(ma->id.us==1) {
ma->id.lib= NULL;
ma->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)ma, NULL);
- for(a=0; a<MAX_MTEX; a++) {
- if(ma->mtex[a]) id_lib_extern((ID *)ma->mtex[a]->tex);
- }
-
+
+ new_id(&bmain->mat, (ID *)ma, NULL);
+ extern_local_material(ma);
return;
}
@@ -350,12 +356,9 @@ void make_local_material(Material *ma)
if(local && lib==0) {
ma->id.lib= NULL;
ma->id.flag= LIB_LOCAL;
-
- for(a=0; a<MAX_MTEX; a++) {
- if(ma->mtex[a]) id_lib_extern((ID *)ma->mtex[a]->tex);
- }
-
- new_id(NULL, (ID *)ma, NULL);
+
+ new_id(&bmain->mat, (ID *)ma, NULL);
+ extern_local_material(ma);
}
else if(local && lib) {
@@ -429,6 +432,15 @@ void make_local_material(Material *ma)
}
}
+/* for curve, mball, mesh types */
+void extern_local_matarar(struct Material **matar, short totcol)
+{
+ short i;
+ for(i= 0; i < totcol; i++) {
+ id_lib_extern((ID *)matar[i]);
+ }
+}
+
Material ***give_matarar(Object *ob)
{
Mesh *me;
@@ -1314,12 +1326,12 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col)
case MA_RAMP_SOFT:
if (g){
float scr, scg, scb;
-
+
/* first calculate non-fac based Screen mix */
scr = 1.0f - (1.0f - col[0]) * (1.0f - *r);
scg = 1.0f - (1.0f - col[1]) * (1.0f - *g);
scb = 1.0f - (1.0f - col[2]) * (1.0f - *b);
-
+
*r = facm*(*r) + fac*(((1.0f - *r) * col[0] * (*r)) + (*r * scr));
*g = facm*(*g) + fac*(((1.0f - *g) * col[1] * (*g)) + (*g * scg));
*b = facm*(*b) + fac*(((1.0f - *b) * col[2] * (*b)) + (*b * scb));
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index e6e32be9634..555d35726bc 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -67,6 +67,7 @@
#include "BKE_displist.h"
#include "BKE_mball.h"
#include "BKE_object.h"
+#include "BKE_material.h"
/* Global variables */
@@ -132,14 +133,24 @@ MetaBall *copy_mball(MetaBall *mb)
id_us_plus((ID *)mbn->mat[a]);
}
mbn->bb= MEM_dupallocN(mb->bb);
+
+ mbn->editelems= NULL;
+ mbn->lastelem= NULL;
return mbn;
}
+static void extern_local_mball(MetaBall *mb)
+{
+ if(mb->mat) {
+ extern_local_matarar(mb->mat, mb->totcol);
+ }
+}
+
void make_local_mball(MetaBall *mb)
{
+ Main *bmain= G.main;
Object *ob;
- MetaBall *mbn;
int local=0, lib=0;
/* - only lib users: do nothing
@@ -151,43 +162,44 @@ void make_local_mball(MetaBall *mb)
if(mb->id.us==1) {
mb->id.lib= NULL;
mb->id.flag= LIB_LOCAL;
+ new_id(&bmain->mball, (ID *)mb, NULL);
+ extern_local_mball(mb);
+
return;
}
-
- ob= G.main->object.first;
- while(ob) {
- if(ob->data==mb) {
+
+ for(ob= G.main->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) {
+ if(ob->data == mb) {
if(ob->id.lib) lib= 1;
else local= 1;
}
- ob= ob->id.next;
}
if(local && lib==0) {
mb->id.lib= NULL;
mb->id.flag= LIB_LOCAL;
+
+ new_id(&bmain->mball, (ID *)mb, NULL);
+ extern_local_mball(mb);
}
else if(local && lib) {
- mbn= copy_mball(mb);
+ MetaBall *mbn= copy_mball(mb);
mbn->id.us= 0;
-
- ob= G.main->object.first;
- while(ob) {
- if(ob->data==mb) {
-
+
+ for(ob= G.main->object.first; ob; ob= ob->id.next) {
+ if(ob->data == mb) {
if(ob->id.lib==NULL) {
ob->data= mbn;
mbn->id.us++;
mb->id.us--;
}
}
- ob= ob->id.next;
}
}
}
/* most simple meta-element adding function
- * dont do context menipulation here (rna uses) */
+ * don't do context manipulation here (rna uses) */
MetaElem *add_metaball_element(MetaBall *mb, const int type)
{
MetaElem *ml= MEM_callocN(sizeof(MetaElem), "metaelem");
@@ -237,14 +249,14 @@ MetaElem *add_metaball_element(MetaBall *mb, const int type)
/** Compute bounding box of all MetaElems/MetaBalls.
*
* Bounding box is computed from polygonized surface. Object *ob is
- * basic MetaBall (usaualy with name Meta). All other MetaBalls (whith
+ * basic MetaBall (usually with name Meta). All other MetaBalls (with
* names Meta.001, Meta.002, etc) are included in this Bounding Box.
*/
void tex_space_mball(Object *ob)
{
DispList *dl;
BoundBox *bb;
- float *data, min[3], max[3], loc[3], size[3];
+ float *data, min[3], max[3] /*, loc[3], size[3] */;
int tot, doit=0;
if(ob->bb==NULL) ob->bb= MEM_callocN(sizeof(BoundBox), "mb boundbox");
@@ -272,7 +284,7 @@ void tex_space_mball(Object *ob)
min[0] = min[1] = min[2] = -1.0f;
max[0] = max[1] = max[2] = 1.0f;
}
-
+ /*
loc[0]= (min[0]+max[0])/2.0f;
loc[1]= (min[1]+max[1])/2.0f;
loc[2]= (min[2]+max[2])/2.0f;
@@ -280,7 +292,7 @@ void tex_space_mball(Object *ob)
size[0]= (max[0]-min[0])/2.0f;
size[1]= (max[1]-min[1])/2.0f;
size[2]= (max[2]-min[2])/2.0f;
-
+ */
boundbox_set_from_min_max(bb, min, max);
}
@@ -320,14 +332,14 @@ float *make_orco_mball(Object *ob, ListBase *dispbase)
}
/* Note on mball basis stuff 2.5x (this is a can of worms)
- * This really needs a rewrite/refactorm its totally broken in anything other then basic cases
+ * This really needs a rewrite/refactor its totally broken in anything other then basic cases
* Multiple Scenes + Set Scenes & mixing mball basis SHOULD work but fails to update the depsgraph on rename
* and linking into scenes or removal of basis mball. so take care when changing this code.
*
* Main idiot thing here is that the system returns find_basis_mball() objects which fail a is_basis_mball() test.
*
- * Not only that but the depsgraph and ther areas depend on this behavior!, so making small fixes here isnt worth it.
- * - campbell
+ * Not only that but the depsgraph and their areas depend on this behavior!, so making small fixes here isn't worth it.
+ * - Campbell
*/
@@ -725,7 +737,7 @@ void accum_mballfaces(int i1, int i2, int i3, int i4)
cur= indices+4*curindex;
- /* diplists now support array drawing, we treat trias as fake quad */
+ /* displists now support array drawing, we treat tri's as fake quad */
cur[0]= i1;
cur[1]= i2;
@@ -1315,7 +1327,7 @@ void converge (MB_POINT *p1, MB_POINT *p2, float v1, float v2,
dy = pos.y - neg.y;
dz = pos.z - neg.z;
-/* Aproximation by linear interpolation is faster then binary subdivision,
+/* Approximation by linear interpolation is faster then binary subdivision,
* but it results sometimes (mb->thresh < 0.2) into the strange results */
if((mb->thresh > 0.2f) && (f==1)){
if((dy == 0.0f) && (dz == 0.0f)){
@@ -1373,7 +1385,7 @@ void converge (MB_POINT *p1, MB_POINT *p2, float v1, float v2,
p->x = 0.5f*(pos.x + neg.x);
p->y = 0.5f*(pos.y + neg.y);
p->z = 0.5f*(pos.z + neg.z);
-
+
if (i++ == RES) return;
if ((function(p->x, p->y, p->z)) > 0.0f){
@@ -1625,7 +1637,7 @@ float init_meta(Scene *scene, Object *ob) /* return totsize */
}
}
- /* when metaball object hase zero scale, then MetaElem ot this MetaBall
+ /* when metaball object has zero scale, then MetaElem to this MetaBall
* will not be put to mainb array */
if(bob->size[0]==0.0f || bob->size[1]==0.0f || bob->size[2]==0.0f) {
zero_size= 1;
@@ -1688,11 +1700,11 @@ float init_meta(Scene *scene, Object *ob) /* return totsize */
mul_m4_m4m4(temp2, bob->obmat, obinv);
/* MetaBall transformation */
mul_m4_m4m4(mat, temp1, temp2);
-
+
invert_m4_m4(imat,mat);
-
+
mainb[a]->rad2= ml->rad*ml->rad;
-
+
mainb[a]->mat= (float*) mat;
mainb[a]->imat= (float*) imat;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index e51aa4624b9..8c9240bb0f8 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -336,7 +336,7 @@ static void mesh_ensure_tesselation_customdata(Mesh *me)
/*this ensures grouped customdata (e.g. mtexpoly and mloopuv and mtface, or
mloopcol and mcol) have the same relative active/render/clone/mask indices.*/
-void mesh_update_linked_customdata(Mesh *me)
+static void mesh_update_linked_customdata(Mesh *me)
{
int act;
@@ -558,6 +558,8 @@ Mesh *copy_mesh(Mesh *me)
}
men->mselect= NULL;
+ men->edit_btmesh= NULL;
+ men->pv= NULL; /* looks like this is no-longer supported but NULL just incase */
men->bb= MEM_dupallocN(men->bb);
@@ -579,7 +581,7 @@ BMesh *BKE_mesh_to_bmesh(Mesh *me, Object *ob)
return bm;
}
-void make_local_tface(Mesh *me)
+static void make_local_tface(Main *bmain, Mesh *me)
{
MTFace *tface;
MTexPoly *txface;
@@ -615,7 +617,7 @@ void make_local_tface(Mesh *me)
if(ima->id.lib) {
ima->id.lib= NULL;
ima->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)ima, NULL);
+ new_id(&bmain->image, (ID *)ima, NULL);
}
}
}
@@ -624,58 +626,65 @@ void make_local_tface(Mesh *me)
}
+static void expand_local_mesh(Main *bmain, Mesh *me)
+{
+ id_lib_extern((ID *)me->texcomesh);
+
+ if(me->mtface) {
+ /* why is this an exception? - should not really make local when extern'ing - campbell */
+ make_local_tface(bmain, me);
+ }
+
+ if(me->mat) {
+ extern_local_matarar(me->mat, me->totcol);
+ }
+}
+
void make_local_mesh(Mesh *me)
{
Main *bmain= G.main;
Object *ob;
- Mesh *men;
int local=0, lib=0;
/* - only lib users: do nothing
- * - only local users: set flag
- * - mixed: make copy
- */
-
+ * - only local users: set flag
+ * - mixed: make copy
+ */
+
if(me->id.lib==NULL) return;
if(me->id.us==1) {
me->id.lib= NULL;
me->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)me, NULL);
-
- if(me->mtface) make_local_tface(me);
-
+
+ new_id(&bmain->mesh, (ID *)me, NULL);
+ expand_local_mesh(bmain, me);
return;
}
-
- ob= bmain->object.first;
- while(ob) {
- if( me==get_mesh(ob) ) {
+
+ for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) {
+ if(me == ob->data) {
if(ob->id.lib) lib= 1;
else local= 1;
}
- ob= ob->id.next;
}
-
+
if(local && lib==0) {
me->id.lib= NULL;
me->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)me, NULL);
-
- if(me->mtface) make_local_tface(me);
-
+
+ new_id(&bmain->mesh, (ID *)me, NULL);
+ expand_local_mesh(bmain, me);
}
else if(local && lib) {
- men= copy_mesh(me);
+ Mesh *men= copy_mesh(me);
men->id.us= 0;
-
- ob= bmain->object.first;
- while(ob) {
- if( me==get_mesh(ob) ) {
+
+ for(ob= bmain->object.first; ob; ob= ob->id.next) {
+ if(me == ob->data) {
if(ob->id.lib==NULL) {
set_mesh(ob, men);
}
}
- ob= ob->id.next;
}
}
}
@@ -2108,7 +2117,7 @@ void create_vert_edge_map(ListBase **map, IndexNode **mem, const MEdge *medge, c
(*map) = MEM_callocN(sizeof(ListBase) * totvert, "vert edge map");
(*mem) = MEM_callocN(sizeof(IndexNode) * totedge * 2, "vert edge map mem");
node = *mem;
-
+
/* Find the users */
for(i = 0; i < totedge; ++i){
for(j = 0; j < 2; ++j, ++node) {
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index 70928ab7bbb..46bf47b13f5 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -307,7 +307,9 @@ int BKE_mesh_validate_arrays(Mesh *me, MVert *UNUSED(mverts), unsigned int totve
int BKE_mesh_validate(Mesh *me, int do_verbose)
{
- printf("MESH: %s\n", me->id.name+2);
+ if(do_verbose) {
+ printf("MESH: %s\n", me->id.name+2);
+ }
return BKE_mesh_validate_arrays(me, me->mvert, me->totvert, me->medge, me->totedge, me->mface, me->totface, do_verbose, TRUE);
}
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 03fdcdd0c91..ae90d3df3e4 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -56,7 +56,6 @@
#include "BKE_fcurve.h"
#include "BKE_node.h"
#include "BKE_utildefines.h"
-#include "BKE_node.h"
#include "PIL_time.h"
@@ -968,6 +967,11 @@ bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup, ID *id)
} else
ntype= node_get_type(ntree, type, id);
+ if(ntype == NULL) {
+ printf("nodeAddNodeType() error: '%d' type invalid\n", type);
+ return NULL;
+ }
+
node= MEM_callocN(sizeof(bNode), "new node");
BLI_addtail(&ntree->nodes, node);
node->typeinfo= ntype;
@@ -1189,7 +1193,9 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree)
newtree= MEM_dupallocN(ntree);
copy_libblock_data(&newtree->id, &ntree->id, TRUE); /* copy animdata and ID props */
}
-
+
+ id_us_plus((ID *)newtree->gpd);
+
/* in case a running nodetree is copied */
newtree->init &= ~(NTREE_EXEC_INIT);
newtree->threadstack= NULL;
@@ -1431,6 +1437,8 @@ void ntreeFreeTree(bNodeTree *ntree)
BKE_free_animdata((ID *)ntree);
+ id_us_min((ID *)ntree->gpd);
+
BLI_freelistN(&ntree->links); /* do first, then unlink_node goes fast */
for(node= ntree->nodes.first; node; node= next) {
@@ -1998,11 +2006,23 @@ static void node_group_execute(bNodeStack *stack, void *data, bNode *gnode, bNod
if (ntree->type==NTREE_COMPOSIT) {
bNodeSocket *sock;
bNodeStack *ns;
+
+ /* clear hasoutput on all local stack data,
+ * only the group output will be used from now on
+ */
+ for (node=ntree->nodes.first; node; node=node->next) {
+ for (sock=node->outputs.first; sock; sock=sock->next) {
+ if (sock->stack_type==SOCK_STACK_LOCAL) {
+ ns= get_socket_stack(stack, sock, in);
+ ns->hasoutput = 0;
+ }
+ }
+ }
+ /* use the hasoutput flag to tag external sockets */
for (sock=ntree->outputs.first; sock; sock=sock->next) {
- /* use the hasoutput flag to tag external sockets */
if (sock->stack_type==SOCK_STACK_LOCAL) {
ns= get_socket_stack(stack, sock, in);
- ns->hasoutput = 0;
+ ns->hasoutput = 1;
}
}
/* now free all stacks that are not used from outside */
@@ -2010,11 +2030,9 @@ static void node_group_execute(bNodeStack *stack, void *data, bNode *gnode, bNod
for (sock=node->outputs.first; sock; sock=sock->next) {
if (sock->stack_type==SOCK_STACK_LOCAL ) {
ns= get_socket_stack(stack, sock, in);
- if (ns->hasoutput!=0 && ns->data) {
+ if (ns->hasoutput==0 && ns->data) {
free_compbuf(ns->data);
ns->data = NULL;
- /* reset the flag */
- ns->hasoutput = 1;
}
}
}
@@ -2230,9 +2248,37 @@ static void group_tag_used_outputs(bNode *gnode, bNodeStack *stack, bNodeStack *
}
}
+ /* non-composite trees do all nodes by default */
+ if (ntree->type!=NTREE_COMPOSIT)
+ node->need_exec = 1;
+
+ for(sock= node->inputs.first; sock; sock= sock->next) {
+ bNodeStack *ns = get_socket_stack(stack, sock, gin);
+ if (ns) {
+ ns->hasoutput = 1;
+
+ /* sock type is needed to detect rgba or value or vector types */
+ if(sock->link && sock->link->fromsock)
+ ns->sockettype= sock->link->fromsock->type;
+ else
+ sock->ns.sockettype= sock->type;
+ }
+
+ if(sock->link) {
+ bNodeLink *link= sock->link;
+ /* this is the test for a cyclic case */
+ if(link->fromnode && link->tonode) {
+ if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF);
+ else {
+ node->need_exec= 0;
+ }
+ }
+ }
+ }
+
/* set stack types (for local stack entries) */
for(sock= node->outputs.first; sock; sock= sock->next) {
- bNodeStack *ns = get_socket_stack(stack, sock, NULL);
+ bNodeStack *ns = get_socket_stack(stack, sock, gin);
if (ns)
ns->sockettype = sock->type;
}
@@ -2282,13 +2328,18 @@ static void tex_end_exec(bNodeTree *ntree)
bNodeStack *ns;
int th, a;
- if(ntree->threadstack)
- for(th=0; th<BLENDER_MAX_THREADS; th++)
- for(nts=ntree->threadstack[th].first; nts; nts=nts->next)
- for(ns= nts->stack, a=0; a<ntree->stacksize; a++, ns++)
- if(ns->data)
+ if(ntree->threadstack) {
+ for(th=0; th<BLENDER_MAX_THREADS; th++) {
+ for(nts=ntree->threadstack[th].first; nts; nts=nts->next) {
+ for(ns= nts->stack, a=0; a<ntree->stacksize; a++, ns++) {
+ if(ns->data) {
MEM_freeN(ns->data);
-
+ ns->data= NULL;
+ }
+ }
+ }
+ }
+ }
}
void ntreeBeginExecTree(bNodeTree *ntree)
@@ -2321,7 +2372,7 @@ void ntreeBeginExecTree(bNodeTree *ntree)
for(node= ntree->nodes.first; node; node= node->next) {
bNodeSocket *sock;
- /* composite has own need_exec tag handling */
+ /* non-composite trees do all nodes by default */
if(ntree->type!=NTREE_COMPOSIT)
node->need_exec= 1;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index c761e9852bd..eb796b073d8 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -98,6 +98,7 @@
#include "BKE_scene.h"
#include "BKE_sequencer.h"
#include "BKE_softbody.h"
+#include "BKE_material.h"
#include "LBM_fluidsim.h"
@@ -209,8 +210,8 @@ void object_link_modifiers(struct Object *ob, struct Object *from)
BLI_addtail(&ob->modifiers, nmd);
}
- copy_object_particlesystems(from, ob);
- copy_object_softbody(from, ob);
+ copy_object_particlesystems(ob, from);
+ copy_object_softbody(ob, from);
// TODO: smoke?, cloth?
}
@@ -737,51 +738,45 @@ void make_local_camera(Camera *cam)
{
Main *bmain= G.main;
Object *ob;
- Camera *camn;
int local=0, lib=0;
/* - only lib users: do nothing
- * - only local users: set flag
- * - mixed: make copy
- */
+ * - only local users: set flag
+ * - mixed: make copy
+ */
if(cam->id.lib==NULL) return;
if(cam->id.us==1) {
cam->id.lib= NULL;
cam->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)cam, NULL);
+ new_id(&bmain->camera, (ID *)cam, NULL);
return;
}
- ob= bmain->object.first;
- while(ob) {
+ for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) {
if(ob->data==cam) {
if(ob->id.lib) lib= 1;
else local= 1;
}
- ob= ob->id.next;
}
if(local && lib==0) {
cam->id.lib= NULL;
cam->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)cam, NULL);
+ new_id(&bmain->camera, (ID *)cam, NULL);
}
else if(local && lib) {
- camn= copy_camera(cam);
+ Camera *camn= copy_camera(cam);
camn->id.us= 0;
- ob= bmain->object.first;
- while(ob) {
- if(ob->data==cam) {
-
+ for(ob= bmain->object.first; ob; ob= ob->id.next) {
+ if(ob->data == cam) {
if(ob->id.lib==NULL) {
ob->data= camn;
camn->id.us++;
cam->id.us--;
}
}
- ob= ob->id.next;
}
}
}
@@ -898,7 +893,7 @@ void make_local_lamp(Lamp *la)
if(la->id.us==1) {
la->id.lib= NULL;
la->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)la, NULL);
+ new_id(&bmain->lamp, (ID *)la, NULL);
return;
}
@@ -914,7 +909,7 @@ void make_local_lamp(Lamp *la)
if(local && lib==0) {
la->id.lib= NULL;
la->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)la, NULL);
+ new_id(&bmain->lamp, (ID *)la, NULL);
}
else if(local && lib) {
lan= copy_lamp(la);
@@ -1367,11 +1362,10 @@ Object *copy_object(Object *ob)
return obn;
}
-void expand_local_object(Object *ob)
+static void extern_local_object(Object *ob)
{
//bActionStrip *strip;
ParticleSystem *psys;
- int a;
#if 0 // XXX old animation system
id_lib_extern((ID *)ob->action);
@@ -1379,10 +1373,11 @@ void expand_local_object(Object *ob)
#endif // XXX old animation system
id_lib_extern((ID *)ob->data);
id_lib_extern((ID *)ob->dup_group);
-
- for(a=0; a<ob->totcol; a++) {
- id_lib_extern((ID *)ob->mat[a]);
- }
+ id_lib_extern((ID *)ob->poselib);
+ id_lib_extern((ID *)ob->gpd);
+
+ extern_local_matarar(ob->mat, ob->totcol);
+
#if 0 // XXX old animation system
for (strip=ob->nlastrips.first; strip; strip=strip->next) {
id_lib_extern((ID *)strip->act);
@@ -1395,16 +1390,15 @@ void expand_local_object(Object *ob)
void make_local_object(Object *ob)
{
Main *bmain= G.main;
- Object *obn;
Scene *sce;
Base *base;
int local=0, lib=0;
/* - only lib users: do nothing
- * - only local users: set flag
- * - mixed: make copy
- */
-
+ * - only local users: set flag
+ * - mixed: make copy
+ */
+
if(ob->id.lib==NULL) return;
ob->proxy= ob->proxy_from= NULL;
@@ -1412,31 +1406,23 @@ void make_local_object(Object *ob)
if(ob->id.us==1) {
ob->id.lib= NULL;
ob->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)ob, NULL);
-
+ new_id(&bmain->object, (ID *)ob, NULL);
}
else {
- sce= bmain->scene.first;
- while(sce) {
- base= sce->base.first;
- while(base) {
- if(base->object==ob) {
- if(sce->id.lib) lib++;
- else local++;
- break;
- }
- base= base->next;
+ for(sce= bmain->scene.first; sce && ELEM(0, lib, local); sce= sce->id.next) {
+ if(object_in_scene(ob, sce)) {
+ if(sce->id.lib) lib= 1;
+ else local= 1;
}
- sce= sce->id.next;
}
-
+
if(local && lib==0) {
ob->id.lib= NULL;
ob->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)ob, NULL);
+ new_id(&bmain->object, (ID *)ob, NULL);
}
else if(local && lib) {
- obn= copy_object(ob);
+ Object *obn= copy_object(ob);
obn->id.us= 0;
sce= bmain->scene.first;
@@ -1457,7 +1443,7 @@ void make_local_object(Object *ob)
}
}
- expand_local_object(ob);
+ extern_local_object(ob);
}
/*
@@ -1565,7 +1551,10 @@ void object_make_proxy(Object *ob, Object *target, Object *gob)
ob->rotmode= target->rotmode;
mul_m4_m4m4(ob->obmat, target->obmat, gob->obmat);
if(gob->dup_group) { /* should always be true */
- sub_v3_v3(ob->obmat[3], gob->dup_group->dupli_ofs);
+ float tvec[3];
+ copy_v3_v3(tvec, gob->dup_group->dupli_ofs);
+ mul_mat3_m4_v3(ob->obmat, tvec);
+ sub_v3_v3(ob->obmat[3], tvec);
}
object_apply_mat4(ob, ob->obmat, FALSE, TRUE);
}
@@ -1615,6 +1604,10 @@ void object_make_proxy(Object *ob, Object *target, Object *gob)
armature_set_id_extern(ob);
}
+ else if (target->type == OB_EMPTY) {
+ ob->empty_drawtype = target->empty_drawtype;
+ ob->empty_drawsize = target->empty_drawsize;
+ }
/* copy IDProperties */
if(ob->id.properties) {
@@ -2284,7 +2277,7 @@ void what_does_parent(Scene *scene, Object *ob, Object *workob)
workob->constraints.first = ob->constraints.first;
workob->constraints.last = ob->constraints.last;
- strcpy(workob->parsubstr, ob->parsubstr);
+ BLI_strncpy(workob->parsubstr, ob->parsubstr, sizeof(workob->parsubstr));
where_is_object(scene, workob);
}
@@ -2832,6 +2825,16 @@ int object_insert_ptcache(Object *ob)
return i;
}
+void object_camera_mode(RenderData *rd, Object *camera)
+{
+ rd->mode &= ~(R_ORTHO|R_PANORAMA);
+ if(camera && camera->type==OB_CAMERA) {
+ Camera *cam= camera->data;
+ if(cam->type == CAM_ORTHO) rd->mode |= R_ORTHO;
+ if(cam->flag & CAM_PANORAMA) rd->mode |= R_PANORAMA;
+ }
+}
+
/* 'lens' may be set for envmap only */
void object_camera_matrix(
RenderData *rd, Object *camera, int winx, int winy, short field_second,
@@ -2841,8 +2844,7 @@ void object_camera_matrix(
Camera *cam=NULL;
float pixsize;
float shiftx=0.0, shifty=0.0, winside, viewfac;
-
- rd->mode &= ~(R_ORTHO|R_PANORAMA);
+ short is_ortho= FALSE;
/* question mark */
(*ycor)= rd->yasp / rd->xasp;
@@ -2852,8 +2854,9 @@ void object_camera_matrix(
if(camera->type==OB_CAMERA) {
cam= camera->data;
- if(cam->type==CAM_ORTHO) rd->mode |= R_ORTHO;
- if(cam->flag & CAM_PANORAMA) rd->mode |= R_PANORAMA;
+ if(cam->type == CAM_ORTHO) {
+ is_ortho= TRUE;
+ }
/* solve this too... all time depending stuff is in convertblender.c?
* Need to update the camera early because it's used for projection matrices
@@ -2893,7 +2896,7 @@ void object_camera_matrix(
}
/* ortho only with camera available */
- if(cam && rd->mode & R_ORTHO) {
+ if(cam && is_ortho) {
if(rd->xasp*winx >= rd->yasp*winy) {
viewfac= winx;
}
@@ -2936,7 +2939,7 @@ void object_camera_matrix(
(*viewdx)= pixsize;
(*viewdy)= (*ycor) * pixsize;
- if(rd->mode & R_ORTHO)
+ if(is_ortho)
orthographic_m4(winmat, viewplane->xmin, viewplane->xmax, viewplane->ymin, viewplane->ymax, *clipsta, *clipend);
else
perspective_m4(winmat, viewplane->xmin, viewplane->xmax, viewplane->ymin, viewplane->ymax, *clipsta, *clipend);
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index e5d77355d5d..b603c1ec54b 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -266,17 +266,10 @@ static void psys_create_frand(ParticleSystem *psys)
int psys_check_enabled(Object *ob, ParticleSystem *psys)
{
ParticleSystemModifierData *psmd;
- Mesh *me;
if(psys->flag & PSYS_DISABLED || psys->flag & PSYS_DELETE || !psys->part)
return 0;
- if(ob->type == OB_MESH) {
- me= (Mesh*)ob->data;
- if(me->mr && me->mr->current != 1)
- return 0;
- }
-
psmd= psys_get_modifier(ob, psys);
if(psys->renderdata || G.rendering) {
if(!(psmd->modifier.mode & eModifierMode_Render))
@@ -3039,7 +3032,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
psys->totcached = totpart;
- if(psys && psys->lattice){
+ if(psys->lattice){
end_latt_deform(psys->lattice);
psys->lattice= NULL;
}
@@ -3598,28 +3591,38 @@ ParticleSettings *psys_copy_settings(ParticleSettings *part)
return partn;
}
+static void expand_local_particlesettings(ParticleSettings *part)
+{
+ int i;
+ id_lib_extern((ID *)part->dup_group);
+
+ for(i=0; i<MAX_MTEX; i++) {
+ if(part->mtex[i]) id_lib_extern((ID *)part->mtex[i]->tex);
+ }
+}
+
void make_local_particlesettings(ParticleSettings *part)
{
+ Main *bmain= G.main;
Object *ob;
- ParticleSettings *par;
int local=0, lib=0;
/* - only lib users: do nothing
- * - only local users: set flag
- * - mixed: make copy
- */
+ * - only local users: set flag
+ * - mixed: make copy
+ */
if(part->id.lib==0) return;
if(part->id.us==1) {
part->id.lib= 0;
part->id.flag= LIB_LOCAL;
- new_id(0, (ID *)part, 0);
+ new_id(&bmain->particle, (ID *)part, 0);
+ expand_local_particlesettings(part);
return;
}
-
+
/* test objects */
- ob= G.main->object.first;
- while(ob) {
+ for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) {
ParticleSystem *psys=ob->particlesystem.first;
for(; psys; psys=psys->next){
if(psys->part==part) {
@@ -3627,31 +3630,28 @@ void make_local_particlesettings(ParticleSettings *part)
else local= 1;
}
}
- ob= ob->id.next;
}
if(local && lib==0) {
part->id.lib= 0;
part->id.flag= LIB_LOCAL;
- new_id(0, (ID *)part, 0);
+ new_id(&bmain->particle, (ID *)part, 0);
+ expand_local_particlesettings(part);
}
else if(local && lib) {
-
- par= psys_copy_settings(part);
- par->id.us= 0;
+ ParticleSettings *partn= psys_copy_settings(part);
+ partn->id.us= 0;
/* do objects */
- ob= G.main->object.first;
- while(ob) {
- ParticleSystem *psys=ob->particlesystem.first;
- for(; psys; psys=psys->next){
+ for(ob= bmain->object.first; ob; ob= ob->id.next) {
+ ParticleSystem *psys;
+ for(psys= ob->particlesystem.first; psys; psys=psys->next){
if(psys->part==part && ob->id.lib==0) {
- psys->part= par;
- par->id.us++;
+ psys->part= partn;
+ partn->id.us++;
part->id.us--;
}
}
- ob= ob->id.next;
}
}
}
@@ -4373,7 +4373,7 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa
float loc[3], nor[3], vec[3], side[3], len, obrotmat[4][4], qmat[4][4];
float xvec[3] = {-1.0, 0.0, 0.0}, q[4], nmat[3][3];
- sub_v3_v3v3(vec, (cache+cache->steps-1)->co, cache->co);
+ sub_v3_v3v3(vec, (cache+cache->steps)->co, cache->co);
len= normalize_v3(vec);
if(psys->part->rotmode) {
@@ -4433,22 +4433,22 @@ void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3]
xvec[0] = 1.0f; xvec[1] = 0.0f; xvec[2] = 0.0f;
yvec[0] = 0.0f; yvec[1] = 1.0f; yvec[2] = 0.0f;
- /* can happen with bad pointcache or physics calculation
- * since this becomes geometry, nan's and inf's crash raytrace code.
- * better not allow this. */
- if( !finite(bb->vec[0]) || !finite(bb->vec[1]) || !finite(bb->vec[2]) ||
- !finite(bb->vel[0]) || !finite(bb->vel[1]) || !finite(bb->vel[2]) )
- {
- zero_v3(bb->vec);
- zero_v3(bb->vel);
-
- zero_v3(xvec);
- zero_v3(yvec);
- zero_v3(zvec);
- zero_v3(center);
-
- return;
- }
+ /* can happen with bad pointcache or physics calculation
+ * since this becomes geometry, nan's and inf's crash raytrace code.
+ * better not allow this. */
+ if( !finite(bb->vec[0]) || !finite(bb->vec[1]) || !finite(bb->vec[2]) ||
+ !finite(bb->vel[0]) || !finite(bb->vel[1]) || !finite(bb->vel[2]) )
+ {
+ zero_v3(bb->vec);
+ zero_v3(bb->vel);
+
+ zero_v3(xvec);
+ zero_v3(yvec);
+ zero_v3(zvec);
+ zero_v3(center);
+
+ return;
+ }
if(bb->align < PART_BB_VIEW)
onevec[bb->align]=1.0f;
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index dbf2803ec18..701a34d1794 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -644,7 +644,7 @@ static void hammersley_create(float *out, int n, int seed, float amount)
for (p = 0.5, kk = k; kk; p *= 0.5, kk >>= 1)
if (kk & 1) /* kk mod 2 = 1 */
t += p;
-
+
out[2*k + 0]= fmod((double)k/(double)n + offs[0], 1.0);
out[2*k + 1]= fmod(t + offs[1], 1.0);
}
@@ -2552,7 +2552,7 @@ static void basic_integrate(ParticleSimulationData *sim, int p, float dfra, floa
/* damp affects final velocity */
if(part->dampfac != 0.f)
- mul_v3_fl(pa->state.vel, 1.f - part->dampfac * efdata.ptex.damp);
+ mul_v3_fl(pa->state.vel, 1.f - part->dampfac * efdata.ptex.damp * 25.f * dtime);
//VECCOPY(pa->state.ave, states->ave);
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index a8447e2a12a..64893bb0b5b 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -938,7 +938,7 @@ static int ptcache_filename(PTCacheID *pid, char *filename, int cfra, short do_p
len = ptcache_path(pid, filename);
newname += len;
}
- if(strcmp(pid->cache->name, "")==0 && (pid->cache->flag & PTCACHE_EXTERNAL)==0) {
+ if(pid->cache->name[0] == '\0' && (pid->cache->flag & PTCACHE_EXTERNAL)==0) {
idname = (pid->ob->id.name+2);
/* convert chars to hex so they are always a valid filename */
while('\0' != *idname) {
@@ -1003,15 +1003,15 @@ static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra)
fp = fopen(filename, "rb+");
}
- if (!fp)
- return NULL;
-
+ if (!fp)
+ return NULL;
+
pf= MEM_mallocN(sizeof(PTCacheFile), "PTCacheFile");
pf->fp= fp;
pf->old_format = 0;
pf->frame = cfra;
-
- return pf;
+
+ return pf;
}
static void ptcache_file_close(PTCacheFile *pf)
{
@@ -1308,8 +1308,8 @@ static void ptcache_data_copy(void *from[], void *to[])
{
int i;
for(i=0; i<BPHYS_TOT_DATA; i++) {
- /* note, durian file 03.4b_comp crashes if to[i] is not tested
- * its NULL, not sure if this should be fixed elsewhere but for now its needed */
+ /* note, durian file 03.4b_comp crashes if to[i] is not tested
+ * its NULL, not sure if this should be fixed elsewhere but for now its needed */
if(from[i] && to[i])
memcpy(to[i], from[i], ptcache_data_size[i]);
}
@@ -1373,14 +1373,16 @@ static void ptcache_find_frames_around(PTCacheID *pid, unsigned int frame, int *
while(pm->next && pm->next->frame < frame)
pm= pm->next;
- if(pm2 && pm2->frame < frame)
+ if(pm2->frame < frame) {
pm2 = NULL;
+ }
else {
- while(pm2->prev && pm2->prev->frame > frame)
+ while(pm2->prev && pm2->prev->frame > frame) {
pm2= pm2->prev;
+ }
}
- if(pm && !pm2) {
+ if(!pm2) {
*fra1 = 0;
*fra2 = pm->frame;
}
@@ -1842,7 +1844,8 @@ static int ptcache_write(PTCacheID *pid, int cfra, int overwrite)
if(cache->flag & PTCACHE_DISK_CACHE) {
error += !ptcache_mem_frame_to_disk(pid, pm);
- if(pm) {
+ // if(pm) /* pm is always set */
+ {
ptcache_data_free(pm);
ptcache_extra_free(pm);
MEM_freeN(pm);
diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c
index ed3739e897d..f84d98a31b4 100644
--- a/source/blender/blenkernel/intern/report.c
+++ b/source/blender/blenkernel/intern/report.c
@@ -101,7 +101,7 @@ void BKE_report(ReportList *reports, ReportType type, const char *message)
Report *report;
int len;
- /* in background mode always print otherwise there are cases the errors wont be displayed,
+ /* in background mode always print otherwise there are cases the errors wont be displayed,
* but still add to the report list since this is used for python exception handling */
if(G.background || !reports || ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))) {
printf("%s: %s\n", report_type_str(type), message);
diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index ceafb06fce6..4ee7ee501e1 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -333,12 +333,12 @@ void free_actuator(bActuator *act)
if(act->data) {
switch (act->type) {
- case ACT_SOUND:
- sa = (bSoundActuator *) act->data;
- if(sa->sound)
- id_us_min((ID *) sa->sound);
- break;
- }
+ case ACT_SOUND:
+ sa = (bSoundActuator *) act->data;
+ if(sa->sound)
+ id_us_min((ID *) sa->sound);
+ break;
+ }
MEM_freeN(act->data);
}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index c4eefb16348..791d572d385 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1080,23 +1080,23 @@ float get_render_aosss_error(RenderData *r, float error)
/* helper function for the SETLOOPER macro */
Base *_setlooper_base_step(Scene **sce_iter, Base *base)
{
- if(base && base->next) {
- /* common case, step to the next */
- return base->next;
- }
+ if(base && base->next) {
+ /* common case, step to the next */
+ return base->next;
+ }
else if(base==NULL && (*sce_iter)->base.first) {
- /* first time looping, return the scenes first base */
+ /* first time looping, return the scenes first base */
return (Base *)(*sce_iter)->base.first;
- }
- else {
- /* reached the end, get the next base in the set */
+ }
+ else {
+ /* reached the end, get the next base in the set */
while((*sce_iter= (*sce_iter)->set)) {
base= (Base *)(*sce_iter)->base.first;
- if(base) {
- return base;
- }
- }
- }
+ if(base) {
+ return base;
+ }
+ }
+ }
- return NULL;
+ return NULL;
}
diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c
index 42beb055140..6f329433580 100755
--- a/source/blender/blenkernel/intern/seqcache.c
+++ b/source/blender/blenkernel/intern/seqcache.c
@@ -237,9 +237,7 @@ void seq_stripelem_cache_put(
key->cfra = cfra - seq->start;
key->type = type;
- /* Normally we want our own version, but start and end stills are duplicates of the original. */
- if(ELEM(type, SEQ_STRIPELEM_IBUF_STARTSTILL, SEQ_STRIPELEM_IBUF_ENDSTILL)==0)
- IMB_refImBuf(i);
+ IMB_refImBuf(i);
e = (seqCacheEntry*) BLI_mempool_alloc(entrypool);
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 3dfef2e9d78..6f49155c0fd 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -37,7 +37,7 @@
#include <stdlib.h>
#include "MEM_guardedalloc.h"
-#include "PIL_dynlib.h"
+#include "BLI_dynlib.h"
#include "BLI_math.h" /* windows needs for M_PI */
#include "BLI_utildefines.h"
@@ -138,18 +138,18 @@ static void open_plugin_seq(PluginSeq *pis, const char *seqname)
pis->instance_private_data = NULL;
/* clear the error list */
- PIL_dynlib_get_error_as_string(NULL);
+ BLI_dynlib_get_error_as_string(NULL);
- /* if(pis->handle) PIL_dynlib_close(pis->handle); */
+ /* if(pis->handle) BLI_dynlib_close(pis->handle); */
/* pis->handle= 0; */
/* open the needed object */
- pis->handle= PIL_dynlib_open(pis->name);
+ pis->handle= BLI_dynlib_open(pis->name);
if(test_dlerr(pis->name, pis->name)) return;
if (pis->handle != NULL) {
/* find the address of the version function */
- version= (int (*)(void))PIL_dynlib_find_symbol(pis->handle, "plugin_seq_getversion");
+ version= (int (*)(void))BLI_dynlib_find_symbol(pis->handle, "plugin_seq_getversion");
if (test_dlerr(pis->name, "plugin_seq_getversion")) return;
if (version != NULL) {
@@ -158,7 +158,7 @@ static void open_plugin_seq(PluginSeq *pis, const char *seqname)
int (*info_func)(PluginInfo *);
PluginInfo *info= (PluginInfo*) MEM_mallocN(sizeof(PluginInfo), "plugin_info");
- info_func= (int (*)(PluginInfo *))PIL_dynlib_find_symbol(pis->handle, "plugin_getinfo");
+ info_func= (int (*)(PluginInfo *))BLI_dynlib_find_symbol(pis->handle, "plugin_getinfo");
if(info_func == NULL) error("No info func");
else {
@@ -176,21 +176,21 @@ static void open_plugin_seq(PluginSeq *pis, const char *seqname)
}
MEM_freeN(info);
- cp= PIL_dynlib_find_symbol(pis->handle, "seqname");
+ cp= BLI_dynlib_find_symbol(pis->handle, "seqname");
if(cp) strncpy(cp, seqname, 21);
} else {
printf ("Plugin returned unrecognized version number\n");
return;
}
}
- alloc_private = (void* (*)(void))PIL_dynlib_find_symbol(
+ alloc_private = (void* (*)(void))BLI_dynlib_find_symbol(
pis->handle, "plugin_seq_alloc_private_data");
if (alloc_private) {
pis->instance_private_data = alloc_private();
}
pis->current_private_data = (void**)
- PIL_dynlib_find_symbol(
+ BLI_dynlib_find_symbol(
pis->handle, "plugin_private_data");
}
}
@@ -229,12 +229,12 @@ static void free_plugin_seq(PluginSeq *pis)
{
if(pis==NULL) return;
- /* no PIL_dynlib_close: same plugin can be opened multiple times with 1 handle */
+ /* no BLI_dynlib_close: same plugin can be opened multiple times with 1 handle */
if (pis->instance_private_data) {
void (*free_private)(void *);
- free_private = (void (*)(void *))PIL_dynlib_find_symbol(
+ free_private = (void (*)(void *))BLI_dynlib_find_symbol(
pis->handle, "plugin_seq_free_private_data");
if (free_private) {
free_private(pis->instance_private_data);
@@ -301,7 +301,7 @@ static struct ImBuf * do_plugin_effect(
if(seq->plugin->cfra)
*(seq->plugin->cfra)= cfra;
- cp = PIL_dynlib_find_symbol(
+ cp = BLI_dynlib_find_symbol(
seq->plugin->handle, "seqname");
if(cp) strncpy(cp, seq->name+2, 22);
@@ -1675,15 +1675,15 @@ float hyp3,hyp4,b4,b5
output = in_band(wipezone,width,hyp,facf0,1,1);
else
output = in_band(wipezone,width,hyp,facf0,0,1);
- }
+ }
else {
if(b1 < b2)
output = in_band(wipezone,width,hyp,facf0,0,1);
else
output = in_band(wipezone,width,hyp,facf0,1,1);
- }
+ }
break;
-
+
case DO_DOUBLE_WIPE:
if(!wipe->forward)
facf0 = 1.0f-facf0; // Go the other direction
@@ -1726,45 +1726,45 @@ float hyp3,hyp4,b4,b5
output = in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1);
}
if(!wipe->forward)output = 1-output;
- break;
- case DO_CLOCK_WIPE:
+ break;
+ case DO_CLOCK_WIPE:
/*
temp1: angle of effect center in rads
temp2: angle of line through (halfx,halfy) and (x,y) in rads
temp3: angle of low side of blur
temp4: angle of high side of blur
*/
- output = 1.0f - facf0;
- widthf = wipe->edgeWidth*2.0f*(float)M_PI;
- temp1 = 2.0f * (float)M_PI * facf0;
-
- if(wipe->forward){
- temp1 = 2.0f*(float)M_PI - temp1;
- }
-
- x = x - halfx;
- y = y - halfy;
-
- temp2 = asin(abs(y)/sqrt(x*x + y*y));
- if(x <= 0 && y >= 0) temp2 = (float)M_PI - temp2;
- else if(x<=0 && y <= 0) temp2 += (float)M_PI;
- else if(x >= 0 && y <= 0) temp2 = 2.0f*(float)M_PI - temp2;
-
- if(wipe->forward){
- temp3 = temp1-(widthf*0.5f)*facf0;
- temp4 = temp1+(widthf*0.5f)*(1-facf0);
- } else{
- temp3 = temp1-(widthf*0.5f)*(1-facf0);
- temp4 = temp1+(widthf*0.5f)*facf0;
+ output = 1.0f - facf0;
+ widthf = wipe->edgeWidth*2.0f*(float)M_PI;
+ temp1 = 2.0f * (float)M_PI * facf0;
+
+ if(wipe->forward){
+ temp1 = 2.0f*(float)M_PI - temp1;
+ }
+
+ x = x - halfx;
+ y = y - halfy;
+
+ temp2 = asin(abs(y)/sqrt(x*x + y*y));
+ if(x <= 0 && y >= 0) temp2 = (float)M_PI - temp2;
+ else if(x<=0 && y <= 0) temp2 += (float)M_PI;
+ else if(x >= 0 && y <= 0) temp2 = 2.0f*(float)M_PI - temp2;
+
+ if(wipe->forward){
+ temp3 = temp1-(widthf*0.5f)*facf0;
+ temp4 = temp1+(widthf*0.5f)*(1-facf0);
+ } else{
+ temp3 = temp1-(widthf*0.5f)*(1-facf0);
+ temp4 = temp1+(widthf*0.5f)*facf0;
}
- if (temp3 < 0) temp3 = 0;
- if (temp4 > 2.0f*(float)M_PI) temp4 = 2.0f*(float)M_PI;
-
-
- if(temp2 < temp3) output = 0;
- else if (temp2 > temp4) output = 1;
- else output = (temp2-temp3)/(temp4-temp3);
- if(x == 0 && y == 0) output = 1;
+ if (temp3 < 0) temp3 = 0;
+ if (temp4 > 2.0f*(float)M_PI) temp4 = 2.0f*(float)M_PI;
+
+
+ if(temp2 < temp3) output = 0;
+ else if (temp2 > temp4) output = 1;
+ else output = (temp2-temp3)/(temp4-temp3);
+ if(x == 0 && y == 0) output = 1;
if(output != output) output = 1;
if(wipe->forward) output = 1 - output;
break;
@@ -1840,12 +1840,12 @@ float hyp3,hyp4,b4,b5
hwidth = width*0.5f;
temp1 = (halfx-(halfx)*facf0);
- pointdist = sqrt(temp1*temp1 + temp1*temp1);
-
- temp2 = sqrt((halfx-x)*(halfx-x) + (halfy-y)*(halfy-y));
- if(temp2 > pointdist) output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,0,1);
- else output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,1,1);
-
+ pointdist = sqrt(temp1*temp1 + temp1*temp1);
+
+ temp2 = sqrt((halfx-x)*(halfx-x) + (halfy-y)*(halfy-y));
+ if(temp2 > pointdist) output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,0,1);
+ else output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,1,1);
+
if(!wipe->forward) output = 1-output;
break;
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 7a6eb1adc9f..e3639dd1c51 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -845,7 +845,7 @@ typedef struct SeqUniqueInfo {
/*
static void seqbase_unique_name(ListBase *seqbasep, Sequence *seq)
{
- BLI_uniquename(seqbasep, seq, "Sequence", '.', offsetof(Sequence, name), SEQ_NAME_MAXSTR);
+ BLI_uniquename(seqbasep, seq, "Sequence", '.', offsetof(Sequence, name), SEQ_NAME_MAXSTR);
}*/
static void seqbase_unique_name(ListBase *seqbasep, SeqUniqueInfo *sui)
@@ -1720,16 +1720,25 @@ static ImBuf * copy_from_ibuf_still(SeqRenderData context, Sequence * seq,
static void copy_to_ibuf_still(SeqRenderData context, Sequence * seq, float nr,
ImBuf * ibuf)
{
- if (nr == 0) {
- seq_stripelem_cache_put(
- context, seq, seq->start,
- SEQ_STRIPELEM_IBUF_STARTSTILL, IMB_dupImBuf(ibuf));
- }
+ if (nr == 0 || nr == seq->len - 1) {
+ /* we have to store a copy, since the passed ibuf
+ could be preprocessed afterwards (thereby silently
+ changing the cached image... */
+ ibuf = IMB_dupImBuf(ibuf);
- if (nr == seq->len - 1) {
- seq_stripelem_cache_put(
- context, seq, seq->start,
- SEQ_STRIPELEM_IBUF_ENDSTILL, IMB_dupImBuf(ibuf));
+ if (nr == 0) {
+ seq_stripelem_cache_put(
+ context, seq, seq->start,
+ SEQ_STRIPELEM_IBUF_STARTSTILL, ibuf);
+ }
+
+ if (nr == seq->len - 1) {
+ seq_stripelem_cache_put(
+ context, seq, seq->start,
+ SEQ_STRIPELEM_IBUF_ENDSTILL, ibuf);
+ }
+
+ IMB_freeImBuf(ibuf);
}
}
@@ -1849,7 +1858,7 @@ static ImBuf * seq_render_scene_strip_impl(
ImBuf * ibuf = NULL;
float frame= seq->sfra + nr + seq->anim_startofs;
float oldcfra;
- Object *oldcamera;
+ Object *camera;
ListBase oldmarkers;
/* Old info:
@@ -1887,59 +1896,65 @@ static ImBuf * seq_render_scene_strip_impl(
int doseq;
int doseq_gl= G.rendering ? /*(scene->r.seq_flag & R_SEQ_GL_REND)*/ 0 : /*(scene->r.seq_flag & R_SEQ_GL_PREV)*/ 1;
int have_seq= FALSE;
- Scene *sce= seq->scene; /* dont refer to seq->scene above this point!, it can be NULL */
- int sce_valid= FALSE;
+ Scene *scene;
- if(sce) {
- have_seq= (sce->r.scemode & R_DOSEQ) && sce->ed && sce->ed->seqbase.first;
- sce_valid= (sce->camera || have_seq);
+ /* dont refer to seq->scene above this point!, it can be NULL */
+ if(seq->scene == NULL) {
+ return NULL;
}
- if (!sce_valid)
- return NULL;
+ scene= seq->scene;
- oldcfra= seq->scene->r.cfra;
- oldcamera= seq->scene->camera;
+ have_seq= (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first;
+
+ oldcfra= scene->r.cfra;
+ scene->r.cfra= frame;
+
+ if(seq->scene_camera)
+ camera= seq->scene_camera;
+ else {
+ scene_camera_switch_update(scene);
+ camera= scene->camera;
+ }
+
+ if(have_seq==FALSE && camera==NULL) {
+ scene->r.cfra= oldcfra;
+ return NULL;
+ }
/* prevent eternal loop */
doseq= context.scene->r.scemode & R_DOSEQ;
context.scene->r.scemode &= ~R_DOSEQ;
- seq->scene->r.cfra= frame;
- if(seq->scene_camera)
- seq->scene->camera= seq->scene_camera;
- else
- scene_camera_switch_update(seq->scene);
-
#ifdef DURIAN_CAMERA_SWITCH
/* stooping to new low's in hackyness :( */
- oldmarkers= seq->scene->markers;
- seq->scene->markers.first= seq->scene->markers.last= NULL;
+ oldmarkers= scene->markers;
+ scene->markers.first= scene->markers.last= NULL;
#endif
- if(sequencer_view3d_cb && BLI_thread_is_main() && doseq_gl && (seq->scene == context.scene || have_seq==0) && seq->scene->camera) {
+ if(sequencer_view3d_cb && BLI_thread_is_main() && doseq_gl && (scene == context.scene || have_seq==0) && 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, err_out);
+ scene_update_for_newframe(context.bmain, scene, scene->lay);
+ ibuf= sequencer_view3d_cb(scene, camera, 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);
+ Render *re = RE_GetRender(scene->id.name);
RenderResult rres;
/* XXX: this if can be removed when sequence preview rendering uses the job system */
- if(rendering || context.scene != sce) {
+ if(rendering || context.scene != scene) {
if(re==NULL)
- re= RE_NewRender(sce->id.name);
+ re= RE_NewRender(scene->id.name);
- RE_BlenderFrame(re, context.bmain, sce, NULL, sce->lay, frame, FALSE);
+ RE_BlenderFrame(re, context.bmain, scene, NULL, camera, scene->lay, frame, FALSE);
/* restore previous state after it was toggled on & off by RE_BlenderFrame */
G.rendering = rendering;
@@ -1972,14 +1987,14 @@ static ImBuf * seq_render_scene_strip_impl(
/* restore */
context.scene->r.scemode |= doseq;
- seq->scene->r.cfra = oldcfra;
- seq->scene->camera= oldcamera;
+ scene->r.cfra = oldcfra;
+
if(frame != oldcfra)
- scene_update_for_newframe(context.bmain, seq->scene, seq->scene->lay);
+ scene_update_for_newframe(context.bmain, scene, scene->lay);
#ifdef DURIAN_CAMERA_SWITCH
/* stooping to new low's in hackyness :( */
- seq->scene->markers= oldmarkers;
+ scene->markers= oldmarkers;
#endif
return ibuf;
diff --git a/source/blender/blenkernel/intern/sketch.c b/source/blender/blenkernel/intern/sketch.c
index 6e234a9d115..ec0f5d1316b 100644
--- a/source/blender/blenkernel/intern/sketch.c
+++ b/source/blender/blenkernel/intern/sketch.c
@@ -543,7 +543,7 @@ int sk_stroke_filtermval(SK_DrawData *dd)
return retval;
}
-void sk_initDrawData(SK_DrawData *dd, short mval[2])
+void sk_initDrawData(SK_DrawData *dd, const short mval[2])
{
dd->mval[0] = mval[0];
dd->mval[1] = mval[1];
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index fbde1aeae22..814ad92e6e9 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -1470,20 +1470,20 @@ static float calc_voxel_transp(float *result, float *input, int res[3], int *pix
long long smoke_get_mem_req(int xres, int yres, int zres, int amplify)
{
- int totalCells = xres * yres * zres;
- int amplifiedCells = totalCells * amplify * amplify * amplify;
+ int totalCells = xres * yres * zres;
+ int amplifiedCells = totalCells * amplify * amplify * amplify;
- // print out memory requirements
- long long int coarseSize = sizeof(float) * totalCells * 22 +
- sizeof(unsigned char) * totalCells;
+ // print out memory requirements
+ long long int coarseSize = sizeof(float) * totalCells * 22 +
+ sizeof(unsigned char) * totalCells;
- long long int fineSize = sizeof(float) * amplifiedCells * 7 + // big grids
- sizeof(float) * totalCells * 8 + // small grids
- sizeof(float) * 128 * 128 * 128; // noise tile
+ long long int fineSize = sizeof(float) * amplifiedCells * 7 + // big grids
+ sizeof(float) * totalCells * 8 + // small grids
+ sizeof(float) * 128 * 128 * 128; // noise tile
- long long int totalMB = (coarseSize + fineSize) / (1024 * 1024);
+ long long int totalMB = (coarseSize + fineSize) / (1024 * 1024);
- return totalMB;
+ return totalMB;
}
static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, float *tRay, bresenham_callback cb, float *result, float *input, int res[3], float correct)
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index c44136f523d..23c0d875dee 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -1649,12 +1649,12 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow,
static void scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow)
{
- SoftBody *sb = ob->soft;
- ListBase *do_effector = NULL;
+ SoftBody *sb = ob->soft;
+ ListBase *do_effector = NULL;
- do_effector = pdInitEffectors(scene, ob, NULL, sb->effector_weights);
- _scan_for_ext_spring_forces(scene, ob, timenow, 0, sb->totspring, do_effector);
- pdEndEffectors(&do_effector);
+ do_effector = pdInitEffectors(scene, ob, NULL, sb->effector_weights);
+ _scan_for_ext_spring_forces(scene, ob, timenow, 0, sb->totspring, do_effector);
+ pdEndEffectors(&do_effector);
}
static void *exec_scan_for_ext_spring_forces(void *data)
@@ -2217,50 +2217,50 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo
/* naive ball self collision */
/* needs to be done if goal snaps or not */
if(do_selfcollision){
- int attached;
- BodyPoint *obp;
- BodySpring *bs;
- int c,b;
- float velcenter[3],dvel[3],def[3];
- float distance;
- float compare;
- float bstune = sb->ballstiff;
-
- for(c=sb->totpoint, obp= sb->bpoint; c>=ifirst+bb; c--, obp++) {
- compare = (obp->colball + bp->colball);
- sub_v3_v3v3(def, bp->pos, obp->pos);
- /* rather check the AABBoxes before ever calulating the real distance */
- /* mathematically it is completly nuts, but performace is pretty much (3) times faster */
- if ((ABS(def[0]) > compare) || (ABS(def[1]) > compare) || (ABS(def[2]) > compare)) continue;
- distance = normalize_v3(def);
- if (distance < compare ){
- /* exclude body points attached with a spring */
- attached = 0;
- for(b=obp->nofsprings;b>0;b--){
- bs = sb->bspring + obp->springs[b-1];
- if (( ilast-bb == bs->v2) || ( ilast-bb == bs->v1)){
- attached=1;
- continue;}
- }
- if (!attached){
- float f = bstune/(distance) + bstune/(compare*compare)*distance - 2.0f*bstune/compare ;
+ int attached;
+ BodyPoint *obp;
+ BodySpring *bs;
+ int c,b;
+ float velcenter[3],dvel[3],def[3];
+ float distance;
+ float compare;
+ float bstune = sb->ballstiff;
+
+ for(c=sb->totpoint, obp= sb->bpoint; c>=ifirst+bb; c--, obp++) {
+ compare = (obp->colball + bp->colball);
+ sub_v3_v3v3(def, bp->pos, obp->pos);
+ /* rather check the AABBoxes before ever calulating the real distance */
+ /* mathematically it is completly nuts, but performace is pretty much (3) times faster */
+ if ((ABS(def[0]) > compare) || (ABS(def[1]) > compare) || (ABS(def[2]) > compare)) continue;
+ distance = normalize_v3(def);
+ if (distance < compare ){
+ /* exclude body points attached with a spring */
+ attached = 0;
+ for(b=obp->nofsprings;b>0;b--){
+ bs = sb->bspring + obp->springs[b-1];
+ if (( ilast-bb == bs->v2) || ( ilast-bb == bs->v1)){
+ attached=1;
+ continue;}
+ }
+ if (!attached){
+ float f = bstune/(distance) + bstune/(compare*compare)*distance - 2.0f*bstune/compare ;
- mid_v3_v3v3(velcenter, bp->vec, obp->vec);
- sub_v3_v3v3(dvel,velcenter,bp->vec);
- mul_v3_fl(dvel,_final_mass(ob,bp));
+ mid_v3_v3v3(velcenter, bp->vec, obp->vec);
+ sub_v3_v3v3(dvel,velcenter,bp->vec);
+ mul_v3_fl(dvel,_final_mass(ob,bp));
- Vec3PlusStVec(bp->force,f*(1.0f-sb->balldamp),def);
- Vec3PlusStVec(bp->force,sb->balldamp,dvel);
+ Vec3PlusStVec(bp->force,f*(1.0f-sb->balldamp),def);
+ Vec3PlusStVec(bp->force,sb->balldamp,dvel);
- /* exploit force(a,b) == -force(b,a) part2/2 */
- sub_v3_v3v3(dvel,velcenter,obp->vec);
- mul_v3_fl(dvel,_final_mass(ob,bp));
+ /* exploit force(a,b) == -force(b,a) part2/2 */
+ sub_v3_v3v3(dvel,velcenter,obp->vec);
+ mul_v3_fl(dvel,_final_mass(ob,bp));
- Vec3PlusStVec(obp->force,sb->balldamp,dvel);
- Vec3PlusStVec(obp->force,-f*(1.0f-sb->balldamp),def);
- }
+ Vec3PlusStVec(obp->force,sb->balldamp,dvel);
+ Vec3PlusStVec(obp->force,-f*(1.0f-sb->balldamp),def);
}
}
+ }
}
/* naive ball self collision done */
@@ -2931,7 +2931,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float *
/* now we have individual masses */
/* claim a minimum mass for vertex */
if (_final_mass(ob,bp) > 0.009999f) timeovermass = forcetime/_final_mass(ob,bp);
- else timeovermass = forcetime/0.009999f;
+ else timeovermass = forcetime/0.009999f;
if(_final_goal(ob,bp) < SOFTGOALSNAP){
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 13748bf10ca..2c0428b8597 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -79,6 +79,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
int drawInteriorEdges,
int useSubsurfUv,
DerivedMesh *dm);
+static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm);
///
@@ -1392,7 +1393,7 @@ static void ccgDM_drawVerts(DerivedMesh *dm) {
static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
{
- if(ccgdm->pbvh) {
+ if(ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) {
CCGFace **faces;
int totface;
@@ -1777,8 +1778,10 @@ static void cgdm_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha
}
glShadeModel(GL_SMOOTH);
- if(col1 && col2)
+
+ if(col2) {
glEnable(GL_CULL_FACE);
+ }
glBegin(GL_QUADS);
for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
@@ -2541,10 +2544,22 @@ static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm)
return ccgdm->fmap;
}
+static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm)
+{
+ MultiresModifierData *mmd= ccgdm->multires.mmd;
+
+ /* both of multires and subsurm modifiers are CCG, but
+ grids should only be used when sculpting on multires */
+ if(!mmd)
+ return 0;
+
+ return 1;
+}
+
static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
{
CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
- int gridSize, numGrids;
+ int gridSize, numGrids, grid_pbvh;
if(!ob) {
ccgdm->pbvh= NULL;
@@ -2554,13 +2569,17 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
if(!ob->sculpt)
return NULL;
+ grid_pbvh= ccgDM_use_grid_pbvh(ccgdm);
+
if(ob->sculpt->pbvh) {
- /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
- but this can be freed on ccgdm release, this updates the pointers
- when the ccgdm gets remade, the assumption is that the topology
- does not change. */
- ccgdm_create_grids(dm);
- BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces);
+ if(grid_pbvh) {
+ /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
+ but this can be freed on ccgdm release, this updates the pointers
+ when the ccgdm gets remade, the assumption is that the topology
+ does not change. */
+ ccgdm_create_grids(dm);
+ BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces);
+ }
ccgdm->pbvh = ob->sculpt->pbvh;
}
@@ -2571,14 +2590,21 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
/* no pbvh exists yet, we need to create one. only in case of multires
we build a pbvh over the modified mesh, in other cases the base mesh
is being sculpted, so we build a pbvh from that. */
- ccgdm_create_grids(dm);
+ if(grid_pbvh) {
+ ccgdm_create_grids(dm);
- gridSize = ccgDM_getGridSize(dm);
- numGrids = ccgDM_getNumGrids(dm);
+ gridSize = ccgDM_getGridSize(dm);
+ numGrids = ccgDM_getNumGrids(dm);
- ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
- BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
- numGrids, gridSize, (void**)ccgdm->gridFaces);
+ ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
+ BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
+ numGrids, gridSize, (void**)ccgdm->gridFaces);
+ } else if(ob->type == OB_MESH) {
+ Mesh *me= ob->data;
+ ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
+ BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
+ me->totface, me->totvert);
+ }
return ccgdm->pbvh;
}
@@ -3108,7 +3134,7 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3])
int numFaces = ccgSubSurf_getVertNumFaces(v);
float *co;
int i;
-
+
edge_sum[0]= edge_sum[1]= edge_sum[2]= 0.0;
face_sum[0]= face_sum[1]= face_sum[2]= 0.0;
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 376f3fb031f..ba5d4282416 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -1348,9 +1348,19 @@ char *txt_sel_to_buf (Text *text)
return buf;
}
+static void txt_shift_markers(Text *text, int lineno, int count)
+{
+ TextMarker *marker;
+
+ for (marker=text->markers.first; marker; marker= marker->next)
+ if (marker->lineno>=lineno) {
+ marker->lineno+= count;
+ }
+}
+
void txt_insert_buf(Text *text, const char *in_buffer)
{
- int i=0, l=0, j, u, len;
+ int i=0, l=0, j, u, len, lineno= -1, count= 0;
TextLine *add;
if (!text) return;
@@ -1365,7 +1375,7 @@ void txt_insert_buf(Text *text, const char *in_buffer)
/* Read the first line (or as close as possible */
while (in_buffer[i] && in_buffer[i]!='\n') {
- txt_add_char(text, in_buffer[i]);
+ txt_add_raw_char(text, in_buffer[i]);
i++;
}
@@ -1375,6 +1385,7 @@ void txt_insert_buf(Text *text, const char *in_buffer)
/* Read as many full lines as we can */
len= strlen(in_buffer);
+ lineno= txt_get_span(text->lines.first, text->curl);
while (i<len) {
l=0;
@@ -1387,14 +1398,25 @@ void txt_insert_buf(Text *text, const char *in_buffer)
add= txt_new_linen(in_buffer +(i-l), l);
BLI_insertlinkbefore(&text->lines, text->curl, add);
i++;
+ count++;
} else {
+ if(count) {
+ txt_shift_markers(text, lineno, count);
+ count= 0;
+ }
+
for (j= i-l; j<i && j<(int)strlen(in_buffer); j++) {
- txt_add_char(text, in_buffer[j]);
+ txt_add_raw_char(text, in_buffer[j]);
}
break;
}
}
-
+
+ if(count) {
+ txt_shift_markers(text, lineno, count);
+ count= 0;
+ }
+
undoing= u;
}
@@ -2046,6 +2068,7 @@ void txt_do_redo(Text *text)
linep= linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
linep= linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++;
linep= linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++;
+ (void)linep;
break;
case UNDO_INDENT:
@@ -2375,7 +2398,7 @@ static void txt_convert_tab_to_spaces (Text *text)
txt_insert_buf(text, sb);
}
-int txt_add_char (Text *text, char add)
+static int txt_add_char_intern (Text *text, char add, int replace_tabs)
{
int len, lineno;
char *tmp;
@@ -2390,7 +2413,7 @@ int txt_add_char (Text *text, char add)
}
/* insert spaces rather then tabs */
- if (add == '\t' && text->flags & TXT_TABSTOSPACES) {
+ if (add == '\t' && replace_tabs) {
txt_convert_tab_to_spaces(text);
return 1;
}
@@ -2428,6 +2451,16 @@ int txt_add_char (Text *text, char add)
return 1;
}
+int txt_add_char (Text *text, char add)
+{
+ return txt_add_char_intern(text, add, text->flags & TXT_TABSTOSPACES);
+}
+
+int txt_add_raw_char (Text *text, char add)
+{
+ return txt_add_char_intern(text, add, 0);
+}
+
void txt_delete_selected(Text *text)
{
txt_delete_sel(text);
@@ -2595,7 +2628,7 @@ void comment(Text *text)
if (!text) return;
if (!text->curl) return;
- if (!text->sell) return;// Need to change this need to check if only one line is selected ot more then one
+ if (!text->sell) return;// Need to change this need to check if only one line is selected to more then one
num = 0;
while (TRUE)
@@ -2719,11 +2752,12 @@ int setcurr_tab_spaces (Text *text, int space)
int a, indent = 0;
for(a=0; (a < text->curc) && (text->curl->line[a] != '\0'); a++)
{
- if (text->curl->line[a]=='#') {
+ char ch= text->curl->line[a];
+ if (ch=='#') {
break;
- } else if (text->curl->line[a]==':') {
+ } else if (ch==':') {
indent = 1;
- } else if (text->curl->line[a]==']') {
+ } else if (ch==']' || ch=='}' || ch=='"' || ch=='\'') {
indent = 0;
}
}
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index a5412c6269e..9cd07de31dc 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -41,9 +41,8 @@
#include "MEM_guardedalloc.h"
-#include "PIL_dynlib.h"
-
#include "BLI_blenlib.h"
+#include "BLI_dynlib.h"
#include "BLI_math.h"
#include "BLI_kdopbvh.h"
#include "BLI_utildefines.h"
@@ -73,7 +72,7 @@
#include "BKE_icons.h"
#include "BKE_node.h"
#include "BKE_animsys.h"
-
+#include "BKE_colortools.h"
/* ------------------------------------------------------------------------- */
@@ -82,7 +81,7 @@ int test_dlerr(const char *name, const char *symbol)
{
char *err;
- err= PIL_dynlib_get_error_as_string(NULL);
+ err= BLI_dynlib_get_error_as_string(NULL);
if(err) {
printf("var1: %s, var2: %s, var3: %s\n", name, symbol, err);
return 1;
@@ -108,19 +107,19 @@ void open_plugin_tex(PluginTex *pit)
pit->instance_init= NULL;
/* clear the error list */
- PIL_dynlib_get_error_as_string(NULL);
+ BLI_dynlib_get_error_as_string(NULL);
- /* no PIL_dynlib_close! multiple opened plugins... */
- /* if(pit->handle) PIL_dynlib_close(pit->handle); */
+ /* no BLI_dynlib_close! multiple opened plugins... */
+ /* if(pit->handle) BLI_dynlib_close(pit->handle); */
/* pit->handle= 0; */
/* open the needed object */
- pit->handle= PIL_dynlib_open(pit->name);
+ pit->handle= BLI_dynlib_open(pit->name);
if(test_dlerr(pit->name, pit->name)) return;
if (pit->handle != NULL) {
/* find the address of the version function */
- version= (int (*)(void)) PIL_dynlib_find_symbol(pit->handle, "plugin_tex_getversion");
+ version= (int (*)(void)) BLI_dynlib_find_symbol(pit->handle, "plugin_tex_getversion");
if (test_dlerr(pit->name, "plugin_tex_getversion")) return;
if (version != NULL) {
@@ -129,7 +128,7 @@ void open_plugin_tex(PluginTex *pit)
int (*info_func)(PluginInfo *);
PluginInfo *info= (PluginInfo*) MEM_mallocN(sizeof(PluginInfo), "plugin_info");
- info_func= (int (*)(PluginInfo *))PIL_dynlib_find_symbol(pit->handle, "plugin_getinfo");
+ info_func= (int (*)(PluginInfo *))BLI_dynlib_find_symbol(pit->handle, "plugin_getinfo");
if (!test_dlerr(pit->name, "plugin_getinfo")) {
info->instance_init = NULL;
@@ -200,7 +199,7 @@ void free_plugin_tex(PluginTex *pit)
{
if(pit==NULL) return;
- /* no PIL_dynlib_close: same plugin can be opened multiple times, 1 handle */
+ /* no BLI_dynlib_close: same plugin can be opened multiple times, 1 handle */
MEM_freeN(pit);
}
@@ -762,9 +761,8 @@ Tex *copy_texture(Tex *tex)
if(texn->coba) texn->coba= MEM_dupallocN(texn->coba);
if(texn->env) texn->env= BKE_copy_envmap(texn->env);
- if(texn->pd) texn->pd= MEM_dupallocN(texn->pd);
+ if(texn->pd) texn->pd= BKE_copy_pointdensity(texn->pd);
if(texn->vd) texn->vd= MEM_dupallocN(texn->vd);
-
if(tex->preview) texn->preview = BKE_previewimg_copy(tex->preview);
if(tex->nodetree) {
@@ -795,14 +793,7 @@ Tex *localize_texture(Tex *tex)
texn->env= BKE_copy_envmap(texn->env);
id_us_min(&texn->env->ima->id);
}
- if(texn->pd) {
- texn->pd= MEM_dupallocN(texn->pd);
- if(texn->pd->coba) {
- texn->pd->point_tree = NULL;
- texn->pd->coba= MEM_dupallocN(texn->pd->coba);
- }
-
- }
+ if(texn->pd) texn->pd= BKE_copy_pointdensity(texn->pd);
if(texn->vd) {
texn->vd= MEM_dupallocN(texn->vd);
if(texn->vd->dataset)
@@ -843,13 +834,13 @@ void make_local_texture(Tex *tex)
if(tex->ima) {
tex->ima->id.lib= NULL;
tex->ima->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)tex->ima, NULL);
+ new_id(&bmain->image, (ID *)tex->ima, NULL);
}
if(tex->id.us==1) {
tex->id.lib= NULL;
tex->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)tex, NULL);
+ new_id(&bmain->tex, (ID *)tex, NULL);
return;
}
@@ -906,7 +897,7 @@ void make_local_texture(Tex *tex)
if(local && lib==0) {
tex->id.lib= NULL;
tex->id.flag= LIB_LOCAL;
- new_id(NULL, (ID *)tex, NULL);
+ new_id(&bmain->tex, (ID *)tex, NULL);
}
else if(local && lib) {
texn= copy_texture(tex);
@@ -1367,6 +1358,13 @@ PointDensity *BKE_add_pointdensity(void)
pd->object = NULL;
pd->psys = 0;
pd->psys_cache_space= TEX_PD_WORLDSPACE;
+ pd->falloff_curve = curvemapping_add(1, 0, 0, 1, 1);
+
+ pd->falloff_curve->preset = CURVE_PRESET_LINE;
+ pd->falloff_curve->cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
+ curvemap_reset(pd->falloff_curve->cm, &pd->falloff_curve->clipr, pd->falloff_curve->preset, CURVEMAP_SLOPE_POSITIVE);
+ curvemapping_changed(pd->falloff_curve, 0);
+
return pd;
}
@@ -1378,7 +1376,7 @@ PointDensity *BKE_copy_pointdensity(PointDensity *pd)
pdn->point_tree = NULL;
pdn->point_data = NULL;
if(pdn->coba) pdn->coba= MEM_dupallocN(pdn->coba);
-
+ pdn->falloff_curve = curvemapping_copy(pdn->falloff_curve); /* can be NULL */
return pdn;
}
@@ -1396,6 +1394,8 @@ void BKE_free_pointdensitydata(PointDensity *pd)
MEM_freeN(pd->coba);
pd->coba = NULL;
}
+
+ curvemapping_free(pd->falloff_curve); /* can be NULL */
}
void BKE_free_pointdensity(PointDensity *pd)
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index 37e604fa0cb..b89e576a562 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -95,7 +95,7 @@ typedef struct bUnitDef {
/* define a single unit */
typedef struct bUnitCollection {
struct bUnitDef *units;
- int base_unit; /* basic unit index (when user desn't specify unit explicitly) */
+ int base_unit; /* basic unit index (when user doesn't specify unit explicitly) */
int flag; /* options for this system */
int length; /* to quickly find the last item */
} bUnitCollection;
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index ff58e8bd0a4..7a76e61c17b 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -43,6 +43,8 @@
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
+#include "BLI_utildefines.h"
+
#include "BKE_world.h"
#include "BKE_library.h"
#include "BKE_animsys.h"
@@ -134,7 +136,6 @@ void make_local_world(World *wrld)
{
Main *bmain= G.main;
Scene *sce;
- World *wrldn;
int local=0, lib=0;
/* - only lib users: do nothing
@@ -150,34 +151,30 @@ void make_local_world(World *wrld)
return;
}
- sce= bmain->scene.first;
- while(sce) {
- if(sce->world==wrld) {
+ for(sce= bmain->scene.first; sce && ELEM(0, lib, local); sce= sce->id.next) {
+ if(sce->world == wrld) {
if(sce->id.lib) lib= 1;
else local= 1;
}
- sce= sce->id.next;
}
-
+
if(local && lib==0) {
wrld->id.lib= NULL;
wrld->id.flag= LIB_LOCAL;
new_id(NULL, (ID *)wrld, NULL);
}
else if(local && lib) {
- wrldn= copy_world(wrld);
+ World *wrldn= copy_world(wrld);
wrldn->id.us= 0;
- sce= bmain->scene.first;
- while(sce) {
- if(sce->world==wrld) {
+ for(sce= bmain->scene.first; sce; sce= sce->id.next) {
+ if(sce->world == wrld) {
if(sce->id.lib==NULL) {
sce->world= wrldn;
wrldn->id.us++;
wrld->id.us--;
}
}
- sce= sce->id.next;
}
}
}
diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c
index 73e23bd2a05..ba7f9bdd415 100644
--- a/source/blender/blenkernel/intern/writeavi.c
+++ b/source/blender/blenkernel/intern/writeavi.c
@@ -158,7 +158,7 @@ static int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportL
avi = MEM_mallocN (sizeof(AviMovie), "avimovie");
/* RPW 11-21-2002
- if (rd->imtype != AVI_FORMAT_MJPEG) format = AVI_FORMAT_AVI_RGB;
+ if (rd->imtype != AVI_FORMAT_MJPEG) format = AVI_FORMAT_AVI_RGB;
*/
if (rd->imtype != R_AVIJPEG ) format = AVI_FORMAT_AVI_RGB;
else format = AVI_FORMAT_MJPEG;